Implement completion for "kops export kubeconfig"

This commit is contained in:
John Gardiner Myers 2021-07-12 20:14:39 -07:00
parent 3091b76ffc
commit 0167f689e3
9 changed files with 66 additions and 63 deletions

2
cmd/kops/BUILD.bazel generated
View File

@ -26,7 +26,7 @@ go_library(
"edit_cluster.go", "edit_cluster.go",
"edit_instancegroup.go", "edit_instancegroup.go",
"export.go", "export.go",
"export_kubecfg.go", "export_kubeconfig.go",
"gen_help_docs.go", "gen_help_docs.go",
"get.go", "get.go",
"get_assets.go", "get_assets.go",

View File

@ -36,7 +36,7 @@ func NewCmdExport(f *util.Factory, out io.Writer) *cobra.Command {
} }
// create subcommands // create subcommands
cmd.AddCommand(NewCmdExportKubecfg(f, out)) cmd.AddCommand(NewCmdExportKubeconfig(f, out))
return cmd return cmd
} }

View File

@ -35,27 +35,27 @@ import (
) )
var ( var (
exportKubecfgLong = templates.LongDesc(i18n.T(` exportKubeconfigLong = templates.LongDesc(i18n.T(`
Export a kubecfg file for a cluster from the state store. By default the configuration Export a kubeconfig file for a cluster from the state store. By default the configuration
will be saved into a users $HOME/.kube/config file. Kops will respect the KUBECONFIG environment variable will be saved into a users $HOME/.kube/config file.
if the --kubeconfig flag is not set.
`)) `))
exportKubecfgExample = templates.Examples(i18n.T(` exportKubeconfigExample = templates.Examples(i18n.T(`
# export a kubeconfig file with the cluster admin user (make sure you keep this user safe!) # export a kubeconfig file with the cluster admin user (make sure you keep this user safe!)
kops export kubecfg k8s-cluster.example.com --admin kops export kubeconfig k8s-cluster.example.com --admin
# export using a user already existing in the kubeconfig file # export using a user already existing in the kubeconfig file
kops export kubecfg k8s-cluster.example.com --user my-oidc-user kops export kubeconfig k8s-cluster.example.com --user my-oidc-user
# export using the internal DNS name, bypassing the cloud load balancer # export using the internal DNS name, bypassing the cloud load balancer
kops export kubecfg k8s-cluster.example.com --internal kops export kubeconfig k8s-cluster.example.com --internal
`)) `))
exportKubecfgShort = i18n.T(`Export kubecfg.`) exportKubeconfigShort = i18n.T(`Export kubeconfig.`)
) )
type ExportKubecfgOptions struct { type ExportKubeconfigOptions struct {
ClusterName string
KubeConfigPath string KubeConfigPath string
all bool all bool
admin time.Duration admin time.Duration
@ -66,47 +66,50 @@ type ExportKubecfgOptions struct {
UseKopsAuthenticationPlugin bool UseKopsAuthenticationPlugin bool
} }
func NewCmdExportKubecfg(f *util.Factory, out io.Writer) *cobra.Command { func NewCmdExportKubeconfig(f *util.Factory, out io.Writer) *cobra.Command {
options := &ExportKubecfgOptions{} options := &ExportKubeconfigOptions{}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "kubecfg CLUSTERNAME", Use: "kubeconfig [CLUSTER | --all]",
Short: exportKubecfgShort, Aliases: []string{"kubecfg"},
Long: exportKubecfgLong, Short: exportKubeconfigShort,
Example: exportKubecfgExample, Long: exportKubeconfigLong,
Run: func(cmd *cobra.Command, args []string) { Example: exportKubeconfigExample,
ctx := context.TODO() Args: func(cmd *cobra.Command, args []string) error {
err := RunExportKubecfg(ctx, f, out, options, args) if options.all {
if err != nil { if len(args) != 0 {
exitWithError(err) return fmt.Errorf("cannot use both --all flag and positional arguments")
}
} }
if options.admin != 0 && options.user != "" {
return fmt.Errorf("cannot use both --admin and --user")
}
return rootCommand.clusterNameArgs(&options.ClusterName)(cmd, args)
},
ValidArgsFunction: commandutils.CompleteClusterName(&rootCommand, true),
RunE: func(cmd *cobra.Command, args []string) error {
return RunExportKubeconfig(context.TODO(), f, out, options, args)
}, },
} }
cmd.Flags().StringVar(&options.KubeConfigPath, "kubeconfig", options.KubeConfigPath, "the location of the kubeconfig file to create.") cmd.Flags().StringVar(&options.KubeConfigPath, "kubeconfig", options.KubeConfigPath, "Filename of the kubeconfig to create")
cmd.Flags().BoolVar(&options.all, "all", options.all, "export all clusters from the kOps state store") cmd.Flags().BoolVar(&options.all, "all", options.all, "Export all clusters from the kOps state store")
cmd.Flags().DurationVar(&options.admin, "admin", options.admin, "export a cluster admin user credential with the given lifetime and add it to the cluster context") 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().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.") cmd.Flags().StringVar(&options.user, "user", options.user, "Existing user in kubeconfig file to use")
cmd.Flags().BoolVar(&options.internal, "internal", options.internal, "use the cluster's internal DNS name") cmd.RegisterFlagCompletionFunc("user", completeKubecfgUser)
cmd.Flags().BoolVar(&options.UseKopsAuthenticationPlugin, "auth-plugin", options.UseKopsAuthenticationPlugin, "use the kOps authentication plugin") cmd.Flags().BoolVar(&options.internal, "internal", options.internal, "Use the cluster's internal DNS name")
cmd.Flags().BoolVar(&options.UseKopsAuthenticationPlugin, "auth-plugin", options.UseKopsAuthenticationPlugin, "Use the kOps authentication plugin")
return cmd return cmd
} }
func RunExportKubecfg(ctx context.Context, f *util.Factory, out io.Writer, options *ExportKubecfgOptions, args []string) error { func RunExportKubeconfig(ctx context.Context, f *util.Factory, out io.Writer, options *ExportKubeconfigOptions, args []string) error {
clientset, err := rootCommand.Clientset() clientset, err := rootCommand.Clientset()
if err != nil { if err != nil {
return err return err
} }
if options.all {
if len(args) != 0 {
return fmt.Errorf("cannot use both --all flag and positional arguments")
}
}
if options.admin != 0 && options.user != "" {
return fmt.Errorf("cannot use both --admin and --user")
}
var clusterList []*kopsapi.Cluster var clusterList []*kopsapi.Cluster
if options.all { if options.all {
@ -166,7 +169,7 @@ func RunExportKubecfg(ctx context.Context, f *util.Factory, out io.Writer, optio
return nil return nil
} }
func buildPathOptions(options *ExportKubecfgOptions) *clientcmd.PathOptions { func buildPathOptions(options *ExportKubeconfigOptions) *clientcmd.PathOptions {
pathOptions := clientcmd.NewDefaultPathOptions() pathOptions := clientcmd.NewDefaultPathOptions()
if len(options.KubeConfigPath) > 0 { if len(options.KubeConfigPath) > 0 {

View File

@ -122,7 +122,7 @@ func NewCmdUpdateCluster(f *util.Factory, out io.Writer) *cobra.Command {
cmd.Flags().BoolVar(&options.CreateKubecfg, "create-kube-config", options.CreateKubecfg, "Will control automatically creating the kube config file on your local filesystem") 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().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().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.Flags().StringVar(&options.user, "user", options.user, "Existing user in kubeconfig file to use. Implies --create-kube-config")
cmd.RegisterFlagCompletionFunc("user", completeKubecfgUser) 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.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().BoolVar(&options.AllowKopsDowngrade, "allow-kops-downgrade", options.AllowKopsDowngrade, "Allow an older version of kOps to update the cluster than last used")
@ -323,7 +323,7 @@ func RunUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Up
} }
firstRun = !hasKubecfg firstRun = !hasKubecfg
klog.Infof("Exporting kubecfg for cluster") klog.Infof("Exporting kubeconfig for cluster")
// TODO: Another flag? // TODO: Another flag?
useKopsAuthenticationPlugin := false useKopsAuthenticationPlugin := false
@ -347,7 +347,7 @@ func RunUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Up
} }
if c.admin == 0 && c.user == "" { if c.admin == 0 && c.user == "" {
klog.Warningf("Exported kubecfg with no user authentication; use --admin, --user or --auth-plugin flags with `kops export kubecfg`") klog.Warningf("Exported kubeconfig with no user authentication; use --admin, --user or --auth-plugin flags with `kops export kubeconfig`")
} }
} }

View File

@ -35,5 +35,5 @@ Export configuration.
### SEE ALSO ### SEE ALSO
* [kops](kops.md) - kOps is Kubernetes Operations. * [kops](kops.md) - kOps is Kubernetes Operations.
* [kops export kubecfg](kops_export_kubecfg.md) - Export kubecfg. * [kops export kubeconfig](kops_export_kubeconfig.md) - Export kubeconfig.

View File

@ -1,41 +1,41 @@
<!--- This file is automatically generated by make gen-cli-docs; changes should be made in the go CLI command code (under cmd/kops) --> <!--- This file is automatically generated by make gen-cli-docs; changes should be made in the go CLI command code (under cmd/kops) -->
## kops export kubecfg ## kops export kubeconfig
Export kubecfg. Export kubeconfig.
### Synopsis ### Synopsis
Export a kubecfg file for a cluster from the state store. By default the configuration will be saved into a users $HOME/.kube/config file. Kops will respect the KUBECONFIG environment variable if the --kubeconfig flag is not set. Export a kubeconfig file for a cluster from the state store. By default the configuration will be saved into a users $HOME/.kube/config file.
``` ```
kops export kubecfg CLUSTERNAME [flags] kops export kubeconfig [CLUSTER | --all] [flags]
``` ```
### Examples ### Examples
``` ```
# export a kubeconfig file with the cluster admin user (make sure you keep this user safe!) # export a kubeconfig file with the cluster admin user (make sure you keep this user safe!)
kops export kubecfg k8s-cluster.example.com --admin kops export kubeconfig k8s-cluster.example.com --admin
# export using a user already existing in the kubeconfig file # export using a user already existing in the kubeconfig file
kops export kubecfg k8s-cluster.example.com --user my-oidc-user kops export kubeconfig k8s-cluster.example.com --user my-oidc-user
# export using the internal DNS name, bypassing the cloud load balancer # export using the internal DNS name, bypassing the cloud load balancer
kops export kubecfg k8s-cluster.example.com --internal kops export kubeconfig k8s-cluster.example.com --internal
``` ```
### Options ### Options
``` ```
--admin duration[=18h0m0s] export a cluster admin user credential with the given lifetime and add it to the cluster context --admin duration[=18h0m0s] Also export a cluster admin user credential with the specified lifetime and add it to the cluster context
--all export all clusters from the kOps state store --all Export all clusters from the kOps state store
--auth-plugin use the kOps authentication plugin --auth-plugin Use the kOps authentication plugin
-h, --help help for kubecfg -h, --help help for kubeconfig
--internal use the cluster's internal DNS name --internal Use the cluster's internal DNS name
--kubeconfig string the location of the kubeconfig file to create. --kubeconfig string Filename of the kubeconfig to create
--user string re-use an existing user in kubeconfig. Value must specify an existing user block in your kubeconfig file. --user string Existing user in kubeconfig file to use
``` ```
### Options inherited from parent commands ### Options inherited from parent commands

View File

@ -35,7 +35,7 @@ kops update cluster [CLUSTER] [flags]
--phase string Subset of tasks to run: cluster, network, security --phase string Subset of tasks to run: cluster, network, security
--ssh-public-key string SSH public key to use (deprecated: use kops create secret instead) --ssh-public-key string SSH public key to use (deprecated: use kops create secret instead)
--target string Target - direct, terraform, cloudformation (default "direct") --target string Target - direct, terraform, cloudformation (default "direct")
--user string Re-use an existing user in kubeconfig. Value must specify an existing user block in your kubeconfig file. Implies --create-kube-config --user string Existing user in kubeconfig file to use. Implies --create-kube-config
-y, --yes Create cloud resources, without --yes update is in dry run mode -y, --yes Create cloud resources, without --yes update is in dry run mode
``` ```

View File

@ -50,7 +50,7 @@ kops validate cluster my-cluster.example.com
kops delete cluster my-cluster.example.com --yes kops delete cluster my-cluster.example.com --yes
# to export kubecfg # to export kubecfg
* follow steps as mentioned [here](https://kops.sigs.k8s.io/cli/kops_export_kubecfg/#examples). * follow steps as mentioned [here](https://kops.sigs.k8s.io/cli/kops_export_kubeconfig/#examples).
# to update a cluster # to update a cluster
* follow steps as mentioned [here](https://kops.sigs.k8s.io/operations/updates_and_upgrades/#manual-update) * follow steps as mentioned [here](https://kops.sigs.k8s.io/operations/updates_and_upgrades/#manual-update)

View File

@ -3,14 +3,14 @@
When you run `kops update cluster` during cluster creation, you automatically get a kubectl configuration for accessing the cluster. This configuration gives you full admin access to the cluster. When you run `kops update cluster` during cluster creation, you automatically get a kubectl configuration for accessing the cluster. This configuration gives you full admin access to the cluster.
If you want to create this configuration on other machine, you can run the following as long as you have access to the kOps state store. If you want to create this configuration on other machine, you can run the following as long as you have access to the kOps state store.
To create the kubecfg configuration settings for use with kubectl: To create the kubeconfig configuration settings for use with kubectl:
``` ```
export KOPS_STATE_STORE=<location of the kops state store> export KOPS_STATE_STORE=<location of the kops state store>
NAME=<kubernetes.mydomain.com> NAME=<kubernetes.mydomain.com>
kops export kubecfg ${NAME} kops export kubeconfig ${NAME}
``` ```
Warning: Note that the exported configuration gives you full admin privileges using TLS certificates that are not easy to rotate. For regular kubectl usage, you should consider using another method for authenticating to the cluster. Warning: Note that the exported configuration gives you full admin privileges using TLS certificates that are not easy to rotate. For regular kubectl usage, you should consider using another method for authenticating to the cluster.
If you are using kops >= 1.19.0, kops export kubecfg will also require passing either the --admin or --user flag if the context does not already exist. For more information, see the [release notes](https://kops.sigs.k8s.io/releases/1.19-notes/#changes-to-kubernetes-config-export). If you are using kops >= 1.19.0, `kops export kubeconfig` will also require passing either the `--admin` or `--user` flag if the context does not already exist. For more information, see the [release notes](https://kops.sigs.k8s.io/releases/1.19-notes/#changes-to-kubernetes-config-export).