mirror of https://github.com/kubernetes/kops.git
Merge pull request #11926 from johngmyers/complete-update
Implement completion for "kops update cluster"
This commit is contained in:
commit
a5533a058e
|
@ -662,12 +662,13 @@ func RunCreateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Cr
|
|||
updateClusterOptions.Target = c.Target
|
||||
updateClusterOptions.OutDir = c.OutDir
|
||||
updateClusterOptions.admin = kubeconfig.DefaultKubecfgAdminLifetime
|
||||
updateClusterOptions.ClusterName = cluster.Name
|
||||
updateClusterOptions.CreateKubecfg = true
|
||||
|
||||
// SSHPublicKey has already been mapped
|
||||
updateClusterOptions.SSHPublicKey = ""
|
||||
|
||||
_, err := RunUpdateCluster(ctx, f, cluster.Name, out, updateClusterOptions)
|
||||
_, err := RunUpdateCluster(ctx, f, out, updateClusterOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"k8s.io/client-go/tools/clientcmd"
|
||||
"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/upup/pkg/fi/cloudup"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
|
@ -176,3 +177,19 @@ func buildPathOptions(options *ExportKubecfgOptions) *clientcmd.PathOptions {
|
|||
|
||||
return pathOptions
|
||||
}
|
||||
|
||||
func completeKubecfgUser(cmd *cobra.Command, args []string, complete string) ([]string, cobra.ShellCompDirective) {
|
||||
pathOptions := clientcmd.NewDefaultPathOptions()
|
||||
|
||||
config, err := pathOptions.GetStartingConfig()
|
||||
if err != nil {
|
||||
return commandutils.CompletionError("reading kubeconfig", err)
|
||||
}
|
||||
|
||||
var users []string
|
||||
for user := range config.AuthInfos {
|
||||
users = append(users, user)
|
||||
}
|
||||
|
||||
return users, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
|
|
@ -104,9 +104,10 @@ func RunGetAssets(ctx context.Context, f *util.Factory, out io.Writer, options *
|
|||
return fmt.Errorf("--name is required")
|
||||
}
|
||||
|
||||
updateClusterResults, err := RunUpdateCluster(ctx, f, clusterName, out, &UpdateClusterOptions{
|
||||
Target: cloudup.TargetDryRun,
|
||||
GetAssets: true,
|
||||
updateClusterResults, err := RunUpdateCluster(ctx, f, out, &UpdateClusterOptions{
|
||||
Target: cloudup.TargetDryRun,
|
||||
GetAssets: true,
|
||||
ClusterName: clusterName,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -599,10 +599,10 @@ func (i *integrationTest) runTest(t *testing.T, h *testutils.IntegrationTestHarn
|
|||
|
||||
// We don't test it here, and it adds a dependency on kubectl
|
||||
options.CreateKubecfg = false
|
||||
|
||||
options.ClusterName = i.clusterName
|
||||
options.LifecycleOverrides = i.lifecycleOverrides
|
||||
|
||||
_, err := RunUpdateCluster(ctx, factory, i.clusterName, &stdout, options)
|
||||
_, err := RunUpdateCluster(ctx, factory, &stdout, options)
|
||||
if err != nil {
|
||||
t.Fatalf("error running update cluster %q: %v", i.clusterName, err)
|
||||
}
|
||||
|
@ -1008,9 +1008,10 @@ func (i *integrationTest) runTestCloudformation(t *testing.T) {
|
|||
|
||||
// We don't test it here, and it adds a dependency on kubectl
|
||||
options.CreateKubecfg = false
|
||||
options.ClusterName = i.clusterName
|
||||
options.LifecycleOverrides = i.lifecycleOverrides
|
||||
|
||||
_, err := RunUpdateCluster(ctx, factory, i.clusterName, &stdout, options)
|
||||
_, err := RunUpdateCluster(ctx, factory, &stdout, options)
|
||||
if err != nil {
|
||||
t.Fatalf("error running update cluster %q: %v", i.clusterName, err)
|
||||
}
|
||||
|
|
|
@ -502,8 +502,9 @@ func updateEnsureNoChanges(ctx context.Context, t *testing.T, factory *util.Fact
|
|||
|
||||
// We don't test it here, and it adds a dependency on kubectl
|
||||
options.CreateKubecfg = false
|
||||
options.ClusterName = clusterName
|
||||
|
||||
_, err := RunUpdateCluster(ctx, factory, clusterName, &stdout, options)
|
||||
_, err := RunUpdateCluster(ctx, factory, &stdout, options)
|
||||
if err != nil {
|
||||
t.Fatalf("error running update cluster %q: %v", clusterName, err)
|
||||
}
|
||||
|
@ -517,8 +518,9 @@ func updateEnsureNoChanges(ctx context.Context, t *testing.T, factory *util.Fact
|
|||
|
||||
// We don't test it here, and it adds a dependency on kubectl
|
||||
options.CreateKubecfg = false
|
||||
options.ClusterName = clusterName
|
||||
|
||||
results, err := RunUpdateCluster(ctx, factory, clusterName, &stdout, options)
|
||||
results, err := RunUpdateCluster(ctx, factory, &stdout, options)
|
||||
if err != nil {
|
||||
t.Fatalf("error running update cluster %q: %v", clusterName, err)
|
||||
}
|
||||
|
|
|
@ -22,28 +22,16 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"k8s.io/kops/cmd/kops/util"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
)
|
||||
|
||||
var (
|
||||
updateLong = templates.LongDesc(i18n.T(`
|
||||
Creates or updates cloud resources to match cluster desired configuration.
|
||||
`))
|
||||
|
||||
updateExample = templates.Examples(i18n.T(`
|
||||
# After cluster has been created, configure it with:
|
||||
kops update cluster k8s-cluster.example.com --yes --state=s3://my-state-store
|
||||
`))
|
||||
|
||||
updateShort = i18n.T("Update a cluster.")
|
||||
)
|
||||
|
||||
func NewCmdUpdate(f *util.Factory, out io.Writer) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: updateShort,
|
||||
Long: updateLong,
|
||||
Example: updateExample,
|
||||
Use: "update",
|
||||
Short: updateShort,
|
||||
}
|
||||
|
||||
// subcommands
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"k8s.io/kops/cmd/kops/util"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/assets"
|
||||
"k8s.io/kops/pkg/commands/commandutils"
|
||||
"k8s.io/kops/pkg/kubeconfig"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup"
|
||||
|
@ -44,16 +45,16 @@ import (
|
|||
|
||||
var (
|
||||
updateClusterLong = templates.LongDesc(i18n.T(`
|
||||
Create or update cloud or cluster resources to match current cluster state. If the cluster or cloud resources already
|
||||
exist this command may modify those resources.
|
||||
Create or update cloud or cluster resources to match the current cluster and instance group definitions.
|
||||
If the cluster or cloud resources already exist this command may modify those resources.
|
||||
|
||||
If nodes need updating such as during a Kubernetes upgrade, a rolling-update may
|
||||
be required as well.
|
||||
If, such as during a Kubernetes upgrade, nodes need updating, a rolling-update may
|
||||
be subsequently required.
|
||||
`))
|
||||
|
||||
updateClusterExample = templates.Examples(i18n.T(`
|
||||
# After cluster has been edited or upgraded, configure it with:
|
||||
kops update cluster k8s-cluster.example.com --yes --state=s3://my-state-store --yes --admin
|
||||
# After the cluster has been edited or upgraded, update the cloud resources with:
|
||||
kops update cluster k8s-cluster.example.com --yes --state=s3://my-state-store --yes
|
||||
`))
|
||||
|
||||
updateClusterShort = i18n.T("Update a cluster.")
|
||||
|
@ -69,6 +70,8 @@ type UpdateClusterOptions struct {
|
|||
// GetAssets is whether this is invoked from the CmdGetAssets.
|
||||
GetAssets bool
|
||||
|
||||
ClusterName string
|
||||
|
||||
CreateKubecfg bool
|
||||
admin time.Duration
|
||||
user string
|
||||
|
@ -98,40 +101,41 @@ func NewCmdUpdateCluster(f *util.Factory, out io.Writer) *cobra.Command {
|
|||
options.InitDefaults()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "cluster",
|
||||
Short: updateClusterShort,
|
||||
Long: updateClusterLong,
|
||||
Example: updateClusterExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
ctx := context.TODO()
|
||||
|
||||
err := rootCommand.ProcessArgs(args)
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
|
||||
clusterName := rootCommand.ClusterName(true)
|
||||
|
||||
if _, err := RunUpdateCluster(ctx, f, clusterName, out, options); err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
Use: "cluster [CLUSTER]",
|
||||
Short: updateClusterShort,
|
||||
Long: updateClusterLong,
|
||||
Example: updateClusterExample,
|
||||
Args: rootCommand.clusterNameArgs(&options.ClusterName),
|
||||
ValidArgsFunction: commandutils.CompleteClusterName(&rootCommand, true),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
_, err := RunUpdateCluster(context.TODO(), f, out, options)
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Create cloud resources, without --yes update is in dry run mode")
|
||||
cmd.Flags().StringVar(&options.Target, "target", options.Target, "Target - direct, terraform, cloudformation")
|
||||
cmd.RegisterFlagCompletionFunc("target", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return []string{cloudup.TargetDirect, cloudup.TargetDryRun, cloudup.TargetTerraform, cloudup.TargetCloudformation}, cobra.ShellCompDirectiveNoFileComp
|
||||
})
|
||||
cmd.Flags().StringVar(&options.SSHPublicKey, "ssh-public-key", options.SSHPublicKey, "SSH public key to use (deprecated: use kops create secret instead)")
|
||||
cmd.Flags().StringVar(&options.OutDir, "out", options.OutDir, "Path to write any local output")
|
||||
cmd.MarkFlagDirname("out")
|
||||
cmd.Flags().BoolVar(&options.CreateKubecfg, "create-kube-config", options.CreateKubecfg, "Will control automatically creating the kube config file on your local filesystem")
|
||||
cmd.Flags().DurationVar(&options.admin, "admin", options.admin, "Also export a cluster admin user credential with the specified lifetime and add it to the cluster context")
|
||||
cmd.Flags().Lookup("admin").NoOptDefVal = kubeconfig.DefaultKubecfgAdminLifetime.String()
|
||||
cmd.Flags().StringVar(&options.user, "user", options.user, "Re-use an existing user in kubeconfig. Value must specify an existing user block in your kubeconfig file. Implies --create-kube-config")
|
||||
cmd.RegisterFlagCompletionFunc("user", completeKubecfgUser)
|
||||
cmd.Flags().BoolVar(&options.internal, "internal", options.internal, "Use the cluster's internal DNS name. Implies --create-kube-config")
|
||||
cmd.Flags().BoolVar(&options.AllowKopsDowngrade, "allow-kops-downgrade", options.AllowKopsDowngrade, "Allow an older version of kOps to update the cluster than last used")
|
||||
cmd.Flags().StringVar(&options.Phase, "phase", options.Phase, "Subset of tasks to run: "+strings.Join(cloudup.Phases.List(), ", "))
|
||||
cmd.RegisterFlagCompletionFunc("phase", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return cloudup.Phases.List(), cobra.ShellCompDirectiveNoFileComp
|
||||
})
|
||||
cmd.Flags().StringSliceVar(&options.LifecycleOverrides, "lifecycle-overrides", options.LifecycleOverrides, "comma separated list of phase overrides, example: SecurityGroups=Ignore,InternetGateway=ExistsAndWarnIfChanges")
|
||||
viper.BindPFlag("lifecycle-overrides", cmd.Flags().Lookup("lifecycle-overrides"))
|
||||
viper.BindEnv("lifecycle-overrides", "KOPS_LIFECYCLE_OVERRIDES")
|
||||
cmd.RegisterFlagCompletionFunc("lifecycle-overrides", completeLifecycleOverrides)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -151,7 +155,7 @@ type UpdateClusterResults struct {
|
|||
Cluster *kops.Cluster
|
||||
}
|
||||
|
||||
func RunUpdateCluster(ctx context.Context, f *util.Factory, clusterName string, out io.Writer, c *UpdateClusterOptions) (*UpdateClusterResults, error) {
|
||||
func RunUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *UpdateClusterOptions) (*UpdateClusterResults, error) {
|
||||
results := &UpdateClusterResults{}
|
||||
|
||||
isDryrun := false
|
||||
|
@ -198,7 +202,7 @@ func RunUpdateCluster(ctx context.Context, f *util.Factory, clusterName string,
|
|||
}
|
||||
}
|
||||
|
||||
cluster, err := GetCluster(ctx, f, clusterName)
|
||||
cluster, err := GetCluster(ctx, f, c.ClusterName)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
@ -368,7 +372,7 @@ func RunUpdateCluster(ctx context.Context, f *util.Factory, clusterName string,
|
|||
fmt.Fprintf(sb, "Cloudformation output has been placed into %s\n", c.OutDir)
|
||||
|
||||
if firstRun {
|
||||
cfName := "kubernetes-" + strings.Replace(clusterName, ".", "-", -1)
|
||||
cfName := "kubernetes-" + strings.Replace(c.ClusterName, ".", "-", -1)
|
||||
cfPath := filepath.Join(c.OutDir, "kubernetes.json")
|
||||
fmt.Fprintf(sb, "Run this command to apply the configuration:\n")
|
||||
fmt.Fprintf(sb, " aws cloudformation create-stack --capabilities CAPABILITY_NAMED_IAM --stack-name %s --template-body file://%s\n", cfName, cfPath)
|
||||
|
@ -465,3 +469,21 @@ func hasKubecfg(contextName string) (bool, error) {
|
|||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func completeLifecycleOverrides(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
split := strings.SplitAfter(toComplete, "=")
|
||||
|
||||
if len(split) < 2 {
|
||||
// providing completion for task names is too complicated
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
if len(split) > 2 {
|
||||
return commandutils.CompletionError("too many = characters", nil)
|
||||
}
|
||||
|
||||
var completions []string
|
||||
for lifecycle := range fi.LifecycleNameMap {
|
||||
completions = append(completions, split[0]+lifecycle)
|
||||
}
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
|
|
@ -45,16 +45,16 @@ func NewCmdVersion(f *util.Factory, out io.Writer) *cobra.Command {
|
|||
Short: versionShort,
|
||||
Long: versionLong,
|
||||
Example: versionExample,
|
||||
Args: cobra.NoArgs,
|
||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return commands.RunVersion(f, out, options)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Run = func(cmd *cobra.Command, args []string) {
|
||||
err := commands.RunVersion(f, out, options)
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(&options.Short, "short", options.Short, "only print the main kOps version, useful for scripting")
|
||||
cmd.Flags().BoolVar(&options.Short, "short", options.Short, "only print the main kOps version. Useful for scripting.")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -5,17 +5,6 @@
|
|||
|
||||
Update a cluster.
|
||||
|
||||
### Synopsis
|
||||
|
||||
Creates or updates cloud resources to match cluster desired configuration.
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# After cluster has been created, configure it with:
|
||||
kops update cluster k8s-cluster.example.com --yes --state=s3://my-state-store
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
|
|
|
@ -7,19 +7,19 @@ Update a cluster.
|
|||
|
||||
### Synopsis
|
||||
|
||||
Create or update cloud or cluster resources to match current cluster state. If the cluster or cloud resources already exist this command may modify those resources.
|
||||
Create or update cloud or cluster resources to match the current cluster and instance group definitions. If the cluster or cloud resources already exist this command may modify those resources.
|
||||
|
||||
If nodes need updating such as during a Kubernetes upgrade, a rolling-update may be required as well.
|
||||
If, such as during a Kubernetes upgrade, nodes need updating, a rolling-update may be subsequently required.
|
||||
|
||||
```
|
||||
kops update cluster [flags]
|
||||
kops update cluster [CLUSTER] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# After cluster has been edited or upgraded, configure it with:
|
||||
kops update cluster k8s-cluster.example.com --yes --state=s3://my-state-store --yes --admin
|
||||
# After the cluster has been edited or upgraded, update the cloud resources with:
|
||||
kops update cluster k8s-cluster.example.com --yes --state=s3://my-state-store --yes
|
||||
```
|
||||
|
||||
### Options
|
||||
|
|
|
@ -23,7 +23,7 @@ kops version [flags]
|
|||
|
||||
```
|
||||
-h, --help help for version
|
||||
--short only print the main kOps version, useful for scripting
|
||||
--short only print the main kOps version. Useful for scripting.
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
|
|
@ -53,14 +53,16 @@ nav:
|
|||
- kops create: "cli/kops_create.md"
|
||||
- kops delete: "cli/kops_delete.md"
|
||||
- kops describe: "cli/kops_describe.md"
|
||||
- kops distrust: "cli/kops_distrust.md"
|
||||
- kops edit: "cli/kops_edit.md"
|
||||
- kops export: "cli/kops_export.md"
|
||||
- kops get: "cli/kops_get.md"
|
||||
- kops import: "cli/kops_import.md"
|
||||
- kops promote: "cli/kops_promote.md"
|
||||
- kops replace: "cli/kops_replace.md"
|
||||
- kops rolling-update: "cli/kops_rolling-update.md"
|
||||
- kops set: "cli/kops_set.md"
|
||||
- kops toolbox: "cli/kops_toolbox.md"
|
||||
- kops unset: "cli/kops_unset.md"
|
||||
- kops update: "cli/kops_update.md"
|
||||
- kops upgrade: "cli/kops_upgrade.md"
|
||||
- kops validate: "cli/kops_validate.md"
|
||||
|
|
Loading…
Reference in New Issue