Skip to content

Commit

Permalink
Merge pull request #11970 from johngmyers/complete-delete
Browse files Browse the repository at this point in the history
Implement completion for delete commands
  • Loading branch information
k8s-ci-robot committed Jul 11, 2021
2 parents 655a70a + ea8cd3b commit 3a68dd6
Show file tree
Hide file tree
Showing 12 changed files with 274 additions and 195 deletions.
4 changes: 4 additions & 0 deletions cmd/kops/create_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,11 +866,15 @@ func completeKubernetesVersion(cmd *cobra.Command, args []string, toComplete str
}

// Remove pre-release versions that have a subsequent stable version.
// Also remove the non-useful -rc.0 versions.
for _, version := range versions.UnsortedList() {
split := strings.Split(version, "-")
if len(split) > 1 && versions.Has(split[0]) {
versions.Delete(version)
}
if strings.HasSuffix(version, "-rc.0") {
versions.Delete(version)
}
}

return versions.List(), cobra.ShellCompDirectiveNoFileComp
Expand Down
48 changes: 14 additions & 34 deletions cmd/kops/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"k8s.io/kops/pkg/sshcredentials"
"k8s.io/kops/util/pkg/text"
"k8s.io/kops/util/pkg/vfs"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)
Expand All @@ -41,59 +40,40 @@ type DeleteOptions struct {
}

var (
deleteLong = templates.LongDesc(i18n.T(`
Delete Kubernetes clusters, instancegroups, instances, and secrets, or a combination of the before mentioned.
`))

deleteExample = templates.Examples(i18n.T(`
# Delete an instance
kops delete instance i-0a5ed581b862d3425
# Delete a cluster using a manifest file
kops delete -f my-cluster.yaml
# Delete a cluster using a pasted manifest file from stdin.
pbpaste | kops delete -f -
# Delete a cluster in AWS.
kops delete cluster --name=k8s.example.com --state=s3://my-state-store
# 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
`))

deleteShort = i18n.T("Delete clusters, instancegroups, instances, or secrets.")
deleteShort = i18n.T("Delete clusters, instancegroups, instances, and secrets.")
)

func NewCmdDelete(f *util.Factory, out io.Writer) *cobra.Command {
options := &DeleteOptions{}

cmd := &cobra.Command{
Use: "delete -f FILENAME [--yes]",
Use: "delete {-f FILENAME}...",
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
SuggestFor: []string{"rm"},
Run: func(cmd *cobra.Command, args []string) {
ctx := context.TODO()
if len(options.Filenames) == 0 {
cmd.Help()
return
}
cmdutil.CheckErr(RunDelete(ctx, f, out, options))
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return RunDelete(context.TODO(), f, out, options)
},
}

cmd.Flags().StringSliceVarP(&options.Filenames, "filename", "f", options.Filenames, "Filename to use to delete the resource")
cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Specify --yes to delete the resource")
cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Specify --yes to immediately delete the resource")
cmd.MarkFlagRequired("filename")

// create subcommands
cmd.AddCommand(NewCmdDeleteCluster(f, out))
cmd.AddCommand(NewCmdDeleteInstance(f, out))
cmd.AddCommand(NewCmdDeleteInstanceGroup(f, out))
cmd.AddCommand(NewCmdDeleteSecret(f, out))
cmd.AddCommand(NewCmdDeleteInstance(f, out))

return cmd
}
Expand All @@ -108,20 +88,20 @@ func RunDelete(ctx context.Context, factory *util.Factory, out io.Writer, d *Del
if f == "-" {
contents, err = ConsumeStdin()
if err != nil {
return fmt.Errorf("error reading from stdin: %v", err)
return fmt.Errorf("reading from stdin: %v", err)
}
} else {
contents, err = vfs.Context.ReadFile(f)
if err != nil {
return fmt.Errorf("error reading file %q: %v", f, err)
return fmt.Errorf("reading file %q: %v", f, err)
}
}

sections := text.SplitContentToSections(contents)
for _, section := range sections {
o, gvk, err := kopscodecs.Decode(section, nil)
if err != nil {
return fmt.Errorf("error parsing file %q: %v", f, err)
return fmt.Errorf("parsing file %q: %v", f, err)
}

switch v := o.(type) {
Expand All @@ -132,7 +112,7 @@ func RunDelete(ctx context.Context, factory *util.Factory, out io.Writer, d *Del
}
err = RunDeleteCluster(ctx, factory, out, options)
if err != nil {
exitWithError(err)
return err
}
deletedClusters.Insert(v.ObjectMeta.Name)
case *kopsapi.InstanceGroup:
Expand All @@ -150,7 +130,7 @@ func RunDelete(ctx context.Context, factory *util.Factory, out io.Writer, d *Del

err := RunDeleteInstanceGroup(ctx, factory, out, options)
if err != nil {
exitWithError(err)
return err
}
case *kopsapi.SSHCredential:
fingerprint, err := sshcredentials.Fingerprint(v.Spec.PublicKey)
Expand All @@ -167,11 +147,11 @@ func RunDelete(ctx context.Context, factory *util.Factory, out io.Writer, d *Del

err = RunDeleteSecret(ctx, factory, out, options)
if err != nil {
exitWithError(err)
return err
}
default:
klog.V(2).Infof("Type of object was %T", v)
return fmt.Errorf("Unhandled kind %q in %s", gvk, f)
return fmt.Errorf("unhandled kind %q in %s", gvk, f)
}
}
}
Expand Down
39 changes: 18 additions & 21 deletions cmd/kops/delete_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"k8s.io/klog/v2"
"k8s.io/kops/cmd/kops/util"
kopsapi "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/commands/commandutils"
"k8s.io/kops/pkg/kubeconfig"
"k8s.io/kops/pkg/resources"
resourceops "k8s.io/kops/pkg/resources/ops"
Expand All @@ -48,7 +49,7 @@ type DeleteClusterOptions struct {
var (
deleteClusterLong = templates.LongDesc(i18n.T(`
Deletes a Kubernetes cluster and all associated resources. Resources include instancegroups,
secrets and the state store. There is no "UNDO" for this command.
secrets, and the state store. There is no "UNDO" for this command.
`))

deleteClusterExample = templates.Examples(i18n.T(`
Expand All @@ -65,33 +66,24 @@ func NewCmdDeleteCluster(f *util.Factory, out io.Writer) *cobra.Command {
options := &DeleteClusterOptions{}

cmd := &cobra.Command{
Use: "cluster CLUSTERNAME [--yes]",
Short: deleteClusterShort,
Long: deleteClusterLong,
Example: deleteClusterExample,
Run: func(cmd *cobra.Command, args []string) {
ctx := context.TODO()

err := rootCommand.ProcessArgs(args)
if err != nil {
exitWithError(err)
}

// Note _not_ ClusterName(); we only want the --name flag
options.ClusterName = rootCommand.clusterName

err = RunDeleteCluster(ctx, f, out, options)
if err != nil {
exitWithError(err)
}
Use: "cluster [CLUSTER]",
Short: deleteClusterShort,
Long: deleteClusterLong,
Example: deleteClusterExample,
Args: rootCommand.clusterNameArgsNoKubeconfig(&options.ClusterName),
ValidArgsFunction: commandutils.CompleteClusterName(&rootCommand, true),
RunE: func(cmd *cobra.Command, args []string) error {
return RunDeleteCluster(context.TODO(), f, out, options)
},
}

cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Specify --yes to delete the cluster")
cmd.Flags().BoolVar(&options.Unregister, "unregister", options.Unregister, "Don't delete cloud resources, just unregister the cluster")
cmd.Flags().BoolVar(&options.External, "external", options.External, "Delete an external cluster")

cmd.Flags().StringVar(&options.Region, "region", options.Region, "region")
cmd.Flags().StringVar(&options.Region, "region", options.Region, "External cluster's cloud region")
cmd.RegisterFlagCompletionFunc("region", completeRegion)

return cmd
}

Expand Down Expand Up @@ -214,3 +206,8 @@ func RunDeleteCluster(ctx context.Context, f *util.Factory, out io.Writer, optio
fmt.Fprintf(out, "\nDeleted cluster: %q\n", clusterName)
return nil
}

func completeRegion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// TODO call into cloud provider(s) to get list of valid regions
return nil, cobra.ShellCompDirectiveNoFileComp
}
Loading

0 comments on commit 3a68dd6

Please sign in to comment.