Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: clusteradm delete clusterset #154

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/cmd/clusterset/bind/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ func (o *Options) run() (err error) {

_, err = clusterClient.ClusterV1beta1().ManagedClusterSetBindings(o.Namespace).Create(context.TODO(), binding, metav1.CreateOptions{})
if errors.IsAlreadyExists(err) {
fmt.Fprintf(o.Streams.Out, "Clusterset %s is already bound to Clusterset %s\n", o.Namespace, o.Clusterset)
fmt.Fprintf(o.Streams.Out, "Clusterset %s is already bound to Namespace %s\n", o.Clusterset, o.Namespace)
return nil
}

if err != nil {
return err
}

fmt.Fprintf(o.Streams.Out, "Clusterset %s is bound to Clusterset %s\n", o.Namespace, o.Clusterset)
fmt.Fprintf(o.Streams.Out, "Clusterset %s is bound to Namespace %s\n", o.Clusterset, o.Namespace)
return nil
}
2 changes: 1 addition & 1 deletion pkg/cmd/create/clusterset/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (o *Options) runWithClient(clusterClient clusterclientset.Interface,

_, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), clusterset, metav1.GetOptions{})
if err == nil {
fmt.Fprintf(o.Streams.Out, "Clusterset %s is created already\n", clusterset)
fmt.Fprintf(o.Streams.Out, "Clusterset %s is already created\n", clusterset)
return nil
}

Expand Down
49 changes: 49 additions & 0 deletions pkg/cmd/delete/clusterset/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright Contributors to the Open Cluster Management project
package clusterset

import (
"fmt"

genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
clusteradmhelpers "open-cluster-management.io/clusteradm/pkg/helpers"

"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
)

var example = `
# delete a clusterset.
%[1]s delete clusterset clusterset1
`

// NewCmd...
func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *cobra.Command {
o := newOptions(clusteradmFlags, streams)

cmd := &cobra.Command{
Use: "clusterset",
Short: "delete a clusterset",
Example: fmt.Sprintf(example, clusteradmhelpers.GetExampleHeader()),
SilenceUsage: true,
PreRunE: func(c *cobra.Command, args []string) error {
clusteradmhelpers.DryRunMessage(clusteradmFlags.DryRun)

return nil
},
RunE: func(c *cobra.Command, args []string) error {
if err := o.complete(c, args); err != nil {
return err
}
if err := o.validate(); err != nil {
return err
}
if err := o.run(); err != nil {
return err
}

return nil
},
}

return cmd
}
108 changes: 108 additions & 0 deletions pkg/cmd/delete/clusterset/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright Contributors to the Open Cluster Management project
package clusterset

import (
"context"
"fmt"

"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
clusterclientset "open-cluster-management.io/api/client/cluster/clientset/versioned"
"open-cluster-management.io/clusteradm/pkg/helpers"
)

func (o *Options) complete(cmd *cobra.Command, args []string) (err error) {

o.Clustersets = args

return nil
}

func (o *Options) validate() (err error) {
if len(o.Clustersets) == 0 {
return fmt.Errorf("the name of the clusterset must be specified")
}
if len(o.Clustersets) > 1 {
return fmt.Errorf("only one clusterset can be deleted")
}
return nil
}

func (o *Options) run() (err error) {
restConfig, err := o.ClusteradmFlags.KubectlFactory.ToRESTConfig()
if err != nil {
return err
}
clusterClient, err := clusterclientset.NewForConfig(restConfig)
if err != nil {
return err
}

clusterSetName := o.Clustersets[0]

return o.runWithClient(clusterClient, o.ClusteradmFlags.DryRun, clusterSetName)
}

// check unband first

func (o *Options) runWithClient(clusterClient clusterclientset.Interface,
dryRun bool,
clusterset string) error {

// check existing
_, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), clusterset, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
fmt.Fprintf(o.Streams.Out, "Clusterset %s is already deleted\n", clusterset)
return nil
}
return err
}

// check binding
list, err := clusterClient.ClusterV1beta1().ManagedClusterSetBindings(metav1.NamespaceAll).List(context.TODO(), metav1.ListOptions{
FieldSelector: fmt.Sprintf("metadata.name=%s", clusterset),
})
// if exist, return
if err == nil && len(list.Items) != 0 {
fmt.Fprintf(o.Streams.Out, "Clusterset %s still bind to a namespace! Please unbind before deleted.\n", clusterset)
return nil
}
if err != nil && !errors.IsNotFound(err) {
return err
}

// start a goroutine to watch the delete event
errChannel := make(chan error)
go func(c chan<- error) {
// watch until clusterset is removed
e := helpers.WatchUntil(
func() (watch.Interface, error) {
return clusterClient.ClusterV1beta1().ManagedClusterSets().Watch(context.TODO(), metav1.ListOptions{
FieldSelector: fmt.Sprintf("metadata.name=%s", clusterset),
})
},
func(event watch.Event) bool {
return event.Type == watch.Deleted
},
)
c <- e

}(errChannel)

// delete
err = clusterClient.ClusterV1beta1().ManagedClusterSets().Delete(context.TODO(), clusterset, metav1.DeleteOptions{})
if err != nil {
return err
}

// handle the error of watch function
if err = <-errChannel; err != nil {
return err
}

fmt.Fprintf(o.Streams.Out, "Clusterset %s is deleted\n", clusterset)
return nil
}
24 changes: 24 additions & 0 deletions pkg/cmd/delete/clusterset/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright Contributors to the Open Cluster Management project
package clusterset

import (
"k8s.io/cli-runtime/pkg/genericclioptions"
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
)

type Options struct {
//ClusteradmFlags: The generic optiosn from the clusteradm cli-runtime.
ClusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags

Streams genericclioptions.IOStreams

Clustersets []string
}

func newOptions(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *Options {
return &Options{
ClusteradmFlags: clusteradmFlags,
Streams: streams,
Clustersets: []string{},
}
}
2 changes: 2 additions & 0 deletions pkg/cmd/delete/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package get
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"open-cluster-management.io/clusteradm/pkg/cmd/delete/clusterset"
"open-cluster-management.io/clusteradm/pkg/cmd/delete/token"
"open-cluster-management.io/clusteradm/pkg/cmd/delete/work"
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
Expand All @@ -18,6 +19,7 @@ func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, stream

cmd.AddCommand(token.NewCmd(clusteradmFlags, streams))
cmd.AddCommand(work.NewCmd(clusteradmFlags, streams))
cmd.AddCommand(clusterset.NewCmd(clusteradmFlags, streams))

return cmd
}