From 26224ce371b3ce21ad0d02b799516cdada0fbfed Mon Sep 17 00:00:00 2001 From: chrislovecnm Date: Sat, 17 Jun 2017 22:19:35 -0600 Subject: [PATCH] Work on deletes; no error without "--yes", fixed delete.go deleting ig that does not exist, doc updates. --- cmd/kops/delete.go | 57 +++++++++++++++++--------------- cmd/kops/delete_cluster.go | 13 ++++---- cmd/kops/delete_instancegroup.go | 14 ++++---- docs/cli/kops_delete.md | 8 +++-- docs/cli/kops_delete_cluster.md | 7 ++-- 5 files changed, 52 insertions(+), 47 deletions(-) diff --git a/cmd/kops/delete.go b/cmd/kops/delete.go index 5e28f830ab..0a603db7f7 100644 --- a/cmd/kops/delete.go +++ b/cmd/kops/delete.go @@ -21,10 +21,10 @@ import ( "io" "bytes" - "github.com/golang/glog" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/kops/cmd/kops/util" kopsapi "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops/v1alpha1" @@ -42,16 +42,22 @@ type DeleteOptions struct { var ( delete_long = templates.LongDesc(i18n.T(` - Delete clusters, instancegroups, or secrets. + Delete Kubernetes clusters, instancegroups, and or secrets. `)) delete_example = templates.Examples(i18n.T(` - # Create a cluster using a file + # Create a cluster using a manifest file kops delete -f my-cluster.yaml # Delete a cluster in AWS. kops delete cluster --name=k8s.example.com --state=s3://kops-state-1234 + + # Delete an instancegroup for the k8s-cluster.example.com cluster. + # The --yes option runs the command immediately. + kops delete ig --name=k8s-cluster.example.com node-example --yes `)) + + delete_short = i18n.T("Delete clusters,instancegroups, or secrets.") ) func NewCmdDelete(f *util.Factory, out io.Writer) *cobra.Command { @@ -59,7 +65,7 @@ func NewCmdDelete(f *util.Factory, out io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "delete -f FILENAME [--yes]", - Short: i18n.T("Delete clusters,instancegroups, or secrets."), + Short: delete_short, Long: delete_long, Example: delete_example, SuggestFor: []string{"rm"}, @@ -86,12 +92,11 @@ func NewCmdDelete(f *util.Factory, out io.Writer) *cobra.Command { func RunDelete(factory *util.Factory, out io.Writer, d *DeleteOptions) error { // Codecs provides access to encoding and decoding for the scheme - codecs := kopsapi.Codecs //serializer.NewCodecFactory(scheme) + codec := kopsapi.Codecs.UniversalDecoder(kopsapi.SchemeGroupVersion) - codec := codecs.UniversalDecoder(kopsapi.SchemeGroupVersion) + // We could have more than one cluster in a manifest so we are using a set + deletedClusters := sets.NewString() - var sb bytes.Buffer - fmt.Fprintf(&sb, "\n") for _, f := range d.Filenames { contents, err := vfs.Context.ReadFile(f) if err != nil { @@ -111,40 +116,38 @@ func RunDelete(factory *util.Factory, out io.Writer, d *DeleteOptions) error { switch v := o.(type) { case *kopsapi.Cluster: - options := &DeleteClusterOptions{} - options.ClusterName = v.ObjectMeta.Name - options.Yes = d.Yes + options := &DeleteClusterOptions{ + ClusterName: v.ObjectMeta.Name, + Yes: d.Yes, + } err = RunDeleteCluster(factory, out, options) if err != nil { exitWithError(err) } - if d.Yes { - fmt.Fprintf(&sb, "Deleted cluster/%s\n", v.ObjectMeta.Name) - } + deletedClusters.Insert(v.ObjectMeta.Name) case *kopsapi.InstanceGroup: - options := &DeleteInstanceGroupOptions{} - options.GroupName = v.ObjectMeta.Name - options.ClusterName = v.ObjectMeta.Labels[kopsapi.LabelClusterName] - options.Yes = d.Yes + options := &DeleteInstanceGroupOptions{ + GroupName: v.ObjectMeta.Name, + ClusterName: v.ObjectMeta.Labels[kopsapi.LabelClusterName], + Yes: d.Yes, + } + + // If the cluster has been already deleted we cannot delete the ig + if deletedClusters.Has(options.ClusterName) { + glog.V(4).Infof("Skipping instance group %q because cluster %q has been deleted", v.ObjectMeta.Name, options.ClusterName) + continue + } + err := RunDeleteInstanceGroup(factory, out, options) if err != nil { exitWithError(err) } - if d.Yes { - fmt.Fprintf(&sb, "Deleted instancegroup/%s\n", v.ObjectMeta.Name) - } default: glog.V(2).Infof("Type of object was %T", v) return fmt.Errorf("Unhandled kind %q in %s", gvk, f) } } } - { - _, err := out.Write(sb.Bytes()) - if err != nil { - return fmt.Errorf("error writing to output: %v", err) - } - } return nil } diff --git a/cmd/kops/delete_cluster.go b/cmd/kops/delete_cluster.go index 8a31679ae5..0f69ee4e28 100644 --- a/cmd/kops/delete_cluster.go +++ b/cmd/kops/delete_cluster.go @@ -46,17 +46,15 @@ type DeleteClusterOptions struct { var ( delete_cluster_long = templates.LongDesc(i18n.T(` - Deletes a Kubneretes cluster and all associated resources. Resources include instancegroups, and - the state store. There is no "UNDO" for this command. + Deletes a Kubernetes cluster and all associated resources. Resources include instancegroups, + secrets and the state store. There is no "UNDO" for this command. `)) delete_cluster_example = templates.Examples(i18n.T(` # Delete a cluster. + # The --yes option runs the command immediately. kops delete cluster --name=k8s.cluster.site --yes - # Delete an instancegroup for the k8s-cluster.example.com cluster. - # The --yes option runs the command immediately. - kops delete ig --name=k8s-cluster.example.com node-example --yes `)) delete_cluster_short = i18n.T("Delete a cluster.") @@ -176,7 +174,8 @@ func RunDeleteCluster(f *util.Factory, out io.Writer, options *DeleteClusterOpti } if !options.Yes { - return fmt.Errorf("Must specify --yes to delete") + fmt.Fprintf(out, "\nMust specify --yes to delete cluster\n") + return nil } fmt.Fprintf(out, "\n") @@ -210,6 +209,6 @@ func RunDeleteCluster(f *util.Factory, out io.Writer, options *DeleteClusterOpti glog.Warningf("error removing kube config: %v", err) } - fmt.Fprintf(out, "\nCluster deleted\n") + fmt.Fprintf(out, "\nDeleted cluster: %q\n", clusterName) return nil } diff --git a/cmd/kops/delete_instancegroup.go b/cmd/kops/delete_instancegroup.go index dd78f733f2..6d1d417ca8 100644 --- a/cmd/kops/delete_instancegroup.go +++ b/cmd/kops/delete_instancegroup.go @@ -119,11 +119,6 @@ func RunDeleteInstanceGroup(f *util.Factory, out io.Writer, options *DeleteInsta return fmt.Errorf("ClusterName is required") } - if !options.Yes { - // Just for sanity / safety - return fmt.Errorf("Yes must be specified") - } - cluster, err := GetCluster(f, clusterName) if err != nil { return err @@ -147,6 +142,13 @@ func RunDeleteInstanceGroup(f *util.Factory, out io.Writer, options *DeleteInsta return err } + fmt.Fprintf(out, "InstanceGroup %q found for deletion\n", groupName) + + if !options.Yes { + fmt.Fprintf(out, "\nMust specify --yes to delete instancegroup\n") + return nil + } + d := &instancegroups.DeleteInstanceGroup{} d.Cluster = cluster d.Cloud = cloud @@ -157,7 +159,7 @@ func RunDeleteInstanceGroup(f *util.Factory, out io.Writer, options *DeleteInsta return err } - fmt.Fprintf(out, "InstanceGroup %q deleted\n", group.ObjectMeta.Name) + fmt.Fprintf(out, "\nDeleted InstanceGroup: %q\n", group.ObjectMeta.Name) return nil } diff --git a/docs/cli/kops_delete.md b/docs/cli/kops_delete.md index e12d0e33a5..dfd8fa796b 100644 --- a/docs/cli/kops_delete.md +++ b/docs/cli/kops_delete.md @@ -5,7 +5,7 @@ Delete clusters,instancegroups, or secrets. ### Synopsis -Delete clusters, instancegroups, or secrets. +Delete Kubernetes clusters, instancegroups, and or secrets. ``` kops delete -f FILENAME [--yes] @@ -14,11 +14,15 @@ kops delete -f FILENAME [--yes] ### Examples ``` - # Create a cluster using a file + # Create a cluster using a manifest file kops delete -f my-cluster.yaml # Delete a cluster in AWS. kops delete cluster --name=k8s.example.com --state=s3://kops-state-1234 + + # Delete an instancegroup for the k8s-cluster.example.com cluster. + # The --yes option runs the command immediately. + kops delete ig --name=k8s-cluster.example.com node-example --yes ``` ### Options diff --git a/docs/cli/kops_delete_cluster.md b/docs/cli/kops_delete_cluster.md index d5d0c897bd..669226d9c5 100644 --- a/docs/cli/kops_delete_cluster.md +++ b/docs/cli/kops_delete_cluster.md @@ -5,7 +5,7 @@ Delete a cluster. ### Synopsis -Deletes a Kubneretes cluster and all associated resources. Resources include instancegroups, and the state store. There is no "UNDO" for this command. +Deletes a Kubernetes cluster and all associated resources. Resources include instancegroups, secrets and the state store. There is no "UNDO" for this command. ``` kops delete cluster CLUSTERNAME [--yes] @@ -15,11 +15,8 @@ kops delete cluster CLUSTERNAME [--yes] ``` # Delete a cluster. - kops delete cluster --name=k8s.cluster.site --yes - - # Delete an instancegroup for the k8s-cluster.example.com cluster. # The --yes option runs the command immediately. - kops delete ig --name=k8s-cluster.example.com node-example --yes + kops delete cluster --name=k8s.cluster.site --yes ``` ### Options