From 25c985cf660e60a0548c1751afc73e4ab70dd289 Mon Sep 17 00:00:00 2001 From: TessaIO Date: Mon, 20 May 2024 14:44:54 +0200 Subject: [PATCH] fix: add namespace autocompletion for kubectl config set-context command Signed-off-by: TessaIO Kubernetes-commit: 62be85249e27e58a92ab3a1caf672159dc3cfd7f --- pkg/cmd/cmd.go | 2 +- pkg/cmd/config/config.go | 5 +++-- pkg/cmd/config/config_test.go | 6 +++++- pkg/cmd/config/set_context.go | 9 ++++++++- pkg/cmd/config/set_context_test.go | 10 +++++++--- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 53359d58..a3bac47f 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -480,7 +480,7 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command { registerCompletionFuncForGlobalFlags(cmds, f) cmds.AddCommand(alpha) - cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), o.IOStreams)) + cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), o.IOStreams)) cmds.AddCommand(plugin.NewCmdPlugin(o.IOStreams)) cmds.AddCommand(version.NewCmdVersion(f, o.IOStreams)) cmds.AddCommand(apiresources.NewCmdAPIVersions(f, o.IOStreams)) diff --git a/pkg/cmd/config/config.go b/pkg/cmd/config/config.go index b8bbf8a7..75534328 100644 --- a/pkg/cmd/config/config.go +++ b/pkg/cmd/config/config.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" + "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericiooptions" "k8s.io/client-go/tools/clientcmd" cmdutil "k8s.io/kubectl/pkg/cmd/util" @@ -31,7 +32,7 @@ import ( ) // NewCmdConfig creates a command object for the "config" action, and adds all child commands to it. -func NewCmdConfig(pathOptions *clientcmd.PathOptions, streams genericiooptions.IOStreams) *cobra.Command { +func NewCmdConfig(restClientGetter genericclioptions.RESTClientGetter, pathOptions *clientcmd.PathOptions, streams genericiooptions.IOStreams) *cobra.Command { if len(pathOptions.ExplicitFileFlag) == 0 { pathOptions.ExplicitFileFlag = clientcmd.RecommendedConfigPathFlag } @@ -58,7 +59,7 @@ func NewCmdConfig(pathOptions *clientcmd.PathOptions, streams genericiooptions.I cmd.AddCommand(NewCmdConfigView(streams, pathOptions)) cmd.AddCommand(NewCmdConfigSetCluster(streams.Out, pathOptions)) cmd.AddCommand(NewCmdConfigSetCredentials(streams.Out, pathOptions)) - cmd.AddCommand(NewCmdConfigSetContext(streams.Out, pathOptions)) + cmd.AddCommand(NewCmdConfigSetContext(restClientGetter, streams.Out, pathOptions)) cmd.AddCommand(NewCmdConfigSet(streams.Out, pathOptions)) cmd.AddCommand(NewCmdConfigUnset(streams.Out, pathOptions)) cmd.AddCommand(NewCmdConfigCurrentContext(streams.Out, pathOptions)) diff --git a/pkg/cmd/config/config_test.go b/pkg/cmd/config/config_test.go index a4bac0fa..5ec8ff59 100644 --- a/pkg/cmd/config/config_test.go +++ b/pkg/cmd/config/config_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" utiltesting "k8s.io/client-go/util/testing" + cmdtesting "k8s.io/kubectl/pkg/cmd/testing" cmdutil "k8s.io/kubectl/pkg/cmd/util" ) @@ -948,8 +949,11 @@ func testConfigCommand(args []string, startingConfig clientcmdapi.Config, t *tes argsToUse = append(argsToUse, "--kubeconfig="+fakeKubeFile.Name()) argsToUse = append(argsToUse, args...) + tf := cmdtesting.NewTestFactory().WithNamespace("test") + defer tf.Cleanup() + streams, _, buf, _ := genericiooptions.NewTestIOStreams() - cmd := NewCmdConfig(clientcmd.NewDefaultPathOptions(), streams) + cmd := NewCmdConfig(tf, clientcmd.NewDefaultPathOptions(), streams) // "context" is a global flag, inherited from base kubectl command in the real world cmd.PersistentFlags().String("context", "", "The name of the kubeconfig context to use") cmd.SetArgs(argsToUse) diff --git a/pkg/cmd/config/set_context.go b/pkg/cmd/config/set_context.go index 1590bb5d..671820a7 100644 --- a/pkg/cmd/config/set_context.go +++ b/pkg/cmd/config/set_context.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" + "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" cliflag "k8s.io/component-base/cli/flag" @@ -53,7 +54,7 @@ var ( ) // NewCmdConfigSetContext returns a Command instance for 'config set-context' sub command -func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { +func NewCmdConfigSetContext(restClientGetter genericclioptions.RESTClientGetter, out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { options := &setContextOptions{configAccess: configAccess} cmd := &cobra.Command{ @@ -79,6 +80,12 @@ func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess) cmd.Flags().Var(&options.cluster, clientcmd.FlagClusterName, clientcmd.FlagClusterName+" for the context entry in kubeconfig") cmd.Flags().Var(&options.authInfo, clientcmd.FlagAuthInfoName, clientcmd.FlagAuthInfoName+" for the context entry in kubeconfig") cmd.Flags().Var(&options.namespace, clientcmd.FlagNamespace, clientcmd.FlagNamespace+" for the context entry in kubeconfig") + cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc( + "namespace", + func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return completion.CompGetResource(cmdutil.NewFactory(restClientGetter), "namespace", toComplete), cobra.ShellCompDirectiveNoFileComp + }, + )) return cmd } diff --git a/pkg/cmd/config/set_context_test.go b/pkg/cmd/config/set_context_test.go index 1aaeffe1..5369d631 100644 --- a/pkg/cmd/config/set_context_test.go +++ b/pkg/cmd/config/set_context_test.go @@ -21,10 +21,10 @@ import ( "os" "testing" - utiltesting "k8s.io/client-go/util/testing" - "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + utiltesting "k8s.io/client-go/util/testing" + cmdtesting "k8s.io/kubectl/pkg/cmd/testing" ) type setContextTest struct { @@ -122,7 +122,11 @@ func (test setContextTest) run(t *testing.T) { pathOptions.GlobalFile = fakeKubeFile.Name() pathOptions.EnvVar = "" buf := bytes.NewBuffer([]byte{}) - cmd := NewCmdConfigSetContext(buf, pathOptions) + + tf := cmdtesting.NewTestFactory().WithNamespace("test") + defer tf.Cleanup() + + cmd := NewCmdConfigSetContext(tf, buf, pathOptions) cmd.SetArgs(test.args) cmd.Flags().Parse(test.flags) if err := cmd.Execute(); err != nil {