mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 09:49:50 +00:00
Merge pull request #108493 from VilledeMontreal/feat/compForCompositeNames
Support shell completion for the type/name form
This commit is contained in:
commit
a2a774d3d1
@ -38,7 +38,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -135,7 +135,7 @@ func NewCmdAnnotate(parent string, f cmdutil.Factory, ioStreams genericclioption
|
|||||||
Short: i18n.T("Update the annotations on a resource"),
|
Short: i18n.T("Update the annotations on a resource"),
|
||||||
Long: annotateLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
Long: annotateLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
||||||
Example: annotateExample,
|
Example: annotateExample,
|
||||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -17,11 +17,8 @@ limitations under the License.
|
|||||||
package apiresources
|
package apiresources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -278,38 +275,3 @@ func (s sortableResource) compareValues(i, j int) (string, string) {
|
|||||||
}
|
}
|
||||||
return s.resources[i].APIGroup, s.resources[j].APIGroup
|
return s.resources[i].APIGroup, s.resources[j].APIGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompGetResourceList returns the list of api resources which begin with `toComplete`.
|
|
||||||
func CompGetResourceList(f cmdutil.Factory, cmd *cobra.Command, toComplete string) []string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
streams := genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: ioutil.Discard}
|
|
||||||
o := NewAPIResourceOptions(streams)
|
|
||||||
|
|
||||||
// Get the list of resources
|
|
||||||
o.Output = "name"
|
|
||||||
o.Cached = true
|
|
||||||
o.Verbs = []string{"get"}
|
|
||||||
// TODO:Should set --request-timeout=5s
|
|
||||||
|
|
||||||
// Ignore errors as the output may still be valid
|
|
||||||
o.RunAPIResources(cmd, f)
|
|
||||||
|
|
||||||
// Resources can be a comma-separated list. The last element is then
|
|
||||||
// the one we should complete. For example if toComplete=="pods,secre"
|
|
||||||
// we should return "pods,secrets"
|
|
||||||
prefix := ""
|
|
||||||
suffix := toComplete
|
|
||||||
lastIdx := strings.LastIndex(toComplete, ",")
|
|
||||||
if lastIdx != -1 {
|
|
||||||
prefix = toComplete[0 : lastIdx+1]
|
|
||||||
suffix = toComplete[lastIdx+1:]
|
|
||||||
}
|
|
||||||
var comps []string
|
|
||||||
resources := strings.Split(buf.String(), "\n")
|
|
||||||
for _, res := range resources {
|
|
||||||
if res != "" && strings.HasPrefix(res, suffix) {
|
|
||||||
comps = append(comps, fmt.Sprintf("%s%s", prefix, res))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return comps
|
|
||||||
}
|
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/cmd/util/editor"
|
"k8s.io/kubectl/pkg/cmd/util/editor"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -67,7 +67,7 @@ func NewCmdApplyEditLastApplied(f cmdutil.Factory, ioStreams genericclioptions.I
|
|||||||
Short: i18n.T("Edit latest last-applied-configuration annotations of a resource/object"),
|
Short: i18n.T("Edit latest last-applied-configuration annotations of a resource/object"),
|
||||||
Long: applyEditLastAppliedLong,
|
Long: applyEditLastAppliedLong,
|
||||||
Example: applyEditLastAppliedExample,
|
Example: applyEditLastAppliedExample,
|
||||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, args, cmd))
|
cmdutil.CheckErr(o.Complete(f, args, cmd))
|
||||||
cmdutil.CheckErr(o.Run())
|
cmdutil.CheckErr(o.Run())
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/cli-runtime/pkg/resource"
|
"k8s.io/cli-runtime/pkg/resource"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util"
|
||||||
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
@ -77,7 +78,7 @@ func NewCmdApplyViewLastApplied(f cmdutil.Factory, ioStreams genericclioptions.I
|
|||||||
Short: i18n.T("View the latest last-applied-configuration annotations of a resource/object"),
|
Short: i18n.T("View the latest last-applied-configuration annotations of a resource/object"),
|
||||||
Long: applyViewLastAppliedLong,
|
Long: applyViewLastAppliedLong,
|
||||||
Example: applyViewLastAppliedExample,
|
Example: applyViewLastAppliedExample,
|
||||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.Complete(cmd, f, args))
|
cmdutil.CheckErr(options.Complete(cmd, f, args))
|
||||||
cmdutil.CheckErr(options.Validate(cmd))
|
cmdutil.CheckErr(options.Validate(cmd))
|
||||||
|
@ -35,7 +35,7 @@ import (
|
|||||||
"k8s.io/kubectl/pkg/cmd/util/podcmd"
|
"k8s.io/kubectl/pkg/cmd/util/podcmd"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -105,7 +105,7 @@ func NewCmdAttach(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra
|
|||||||
Short: i18n.T("Attach to a running container"),
|
Short: i18n.T("Attach to a running container"),
|
||||||
Long: i18n.T("Attach to a process that is already running inside an existing container."),
|
Long: i18n.T("Attach to a process that is already running inside an existing container."),
|
||||||
Example: attachExample,
|
Example: attachExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "pod"),
|
ValidArgsFunction: completion.PodResourceNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util"
|
||||||
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -107,7 +108,7 @@ func NewCmdAutoscale(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *
|
|||||||
Short: i18n.T("Auto-scale a deployment, replica set, stateful set, or replication controller"),
|
Short: i18n.T("Auto-scale a deployment, replica set, stateful set, or replication controller"),
|
||||||
Long: autoscaleLong,
|
Long: autoscaleLong,
|
||||||
Example: autoscaleExample,
|
Example: autoscaleExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -70,7 +70,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/cmd/version"
|
"k8s.io/kubectl/pkg/cmd/version"
|
||||||
"k8s.io/kubectl/pkg/cmd/wait"
|
"k8s.io/kubectl/pkg/cmd/wait"
|
||||||
"k8s.io/kubectl/pkg/util"
|
utilcomp "k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
"k8s.io/kubectl/pkg/util/term"
|
"k8s.io/kubectl/pkg/util/term"
|
||||||
@ -319,6 +319,11 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
|
|||||||
proxyCmd.PreRun = func(cmd *cobra.Command, args []string) {
|
proxyCmd.PreRun = func(cmd *cobra.Command, args []string) {
|
||||||
kubeConfigFlags.WrapConfigFn = nil
|
kubeConfigFlags.WrapConfigFn = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid import cycle by setting ValidArgsFunction here instead of in NewCmdGet()
|
||||||
|
getCmd := get.NewCmdGet("kubectl", f, o.IOStreams)
|
||||||
|
getCmd.ValidArgsFunction = utilcomp.ResourceTypeAndNameCompletionFunc(f)
|
||||||
|
|
||||||
groups := templates.CommandGroups{
|
groups := templates.CommandGroups{
|
||||||
{
|
{
|
||||||
Message: "Basic Commands (Beginner):",
|
Message: "Basic Commands (Beginner):",
|
||||||
@ -333,7 +338,7 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
|
|||||||
Message: "Basic Commands (Intermediate):",
|
Message: "Basic Commands (Intermediate):",
|
||||||
Commands: []*cobra.Command{
|
Commands: []*cobra.Command{
|
||||||
explain.NewCmdExplain("kubectl", f, o.IOStreams),
|
explain.NewCmdExplain("kubectl", f, o.IOStreams),
|
||||||
get.NewCmdGet("kubectl", f, o.IOStreams),
|
getCmd,
|
||||||
edit.NewCmdEdit(f, o.IOStreams),
|
edit.NewCmdEdit(f, o.IOStreams),
|
||||||
delete.NewCmdDelete(f, o.IOStreams),
|
delete.NewCmdDelete(f, o.IOStreams),
|
||||||
},
|
},
|
||||||
@ -404,7 +409,7 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
|
|||||||
|
|
||||||
templates.ActsAsRootCommand(cmds, filters, groups...)
|
templates.ActsAsRootCommand(cmds, filters, groups...)
|
||||||
|
|
||||||
util.SetFactoryForCompletion(f)
|
utilcomp.SetFactoryForCompletion(f)
|
||||||
registerCompletionFuncForGlobalFlags(cmds, f)
|
registerCompletionFuncForGlobalFlags(cmds, f)
|
||||||
|
|
||||||
cmds.AddCommand(alpha)
|
cmds.AddCommand(alpha)
|
||||||
@ -474,21 +479,21 @@ func registerCompletionFuncForGlobalFlags(cmd *cobra.Command, f cmdutil.Factory)
|
|||||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||||
"namespace",
|
"namespace",
|
||||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
return get.CompGetResource(f, cmd, "namespace", toComplete), cobra.ShellCompDirectiveNoFileComp
|
return utilcomp.CompGetResource(f, cmd, "namespace", toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||||
}))
|
}))
|
||||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||||
"context",
|
"context",
|
||||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
return util.ListContextsInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
return utilcomp.ListContextsInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||||
}))
|
}))
|
||||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||||
"cluster",
|
"cluster",
|
||||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
return util.ListClustersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
return utilcomp.ListClustersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||||
}))
|
}))
|
||||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||||
"user",
|
"user",
|
||||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
return util.ListUsersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
return utilcomp.ListUsersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -42,7 +42,7 @@ func NewCmdConfigDeleteCluster(out io.Writer, configAccess clientcmd.ConfigAcces
|
|||||||
Short: i18n.T("Delete the specified cluster from the kubeconfig"),
|
Short: i18n.T("Delete the specified cluster from the kubeconfig"),
|
||||||
Long: i18n.T("Delete the specified cluster from the kubeconfig."),
|
Long: i18n.T("Delete the specified cluster from the kubeconfig."),
|
||||||
Example: deleteClusterExample,
|
Example: deleteClusterExample,
|
||||||
ValidArgsFunction: util.ClusterCompletionFunc,
|
ValidArgsFunction: completion.ClusterCompletionFunc,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(runDeleteCluster(out, configAccess, cmd))
|
cmdutil.CheckErr(runDeleteCluster(out, configAccess, cmd))
|
||||||
},
|
},
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -42,7 +42,7 @@ func NewCmdConfigDeleteContext(out, errOut io.Writer, configAccess clientcmd.Con
|
|||||||
Short: i18n.T("Delete the specified context from the kubeconfig"),
|
Short: i18n.T("Delete the specified context from the kubeconfig"),
|
||||||
Long: i18n.T("Delete the specified context from the kubeconfig."),
|
Long: i18n.T("Delete the specified context from the kubeconfig."),
|
||||||
Example: deleteContextExample,
|
Example: deleteContextExample,
|
||||||
ValidArgsFunction: util.ContextCompletionFunc,
|
ValidArgsFunction: completion.ContextCompletionFunc,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(runDeleteContext(out, errOut, configAccess, cmd))
|
cmdutil.CheckErr(runDeleteContext(out, errOut, configAccess, cmd))
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -65,7 +65,7 @@ func NewCmdConfigDeleteUser(streams genericclioptions.IOStreams, configAccess cl
|
|||||||
Short: i18n.T("Delete the specified user from the kubeconfig"),
|
Short: i18n.T("Delete the specified user from the kubeconfig"),
|
||||||
Long: i18n.T("Delete the specified user from the kubeconfig."),
|
Long: i18n.T("Delete the specified user from the kubeconfig."),
|
||||||
Example: deleteUserExample,
|
Example: deleteUserExample,
|
||||||
ValidArgsFunction: util.UserCompletionFunc,
|
ValidArgsFunction: completion.UserCompletionFunc,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(cmd, args))
|
cmdutil.CheckErr(o.Complete(cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -68,7 +68,7 @@ func NewCmdConfigRenameContext(out io.Writer, configAccess clientcmd.ConfigAcces
|
|||||||
Short: renameContextShort,
|
Short: renameContextShort,
|
||||||
Long: renameContextLong,
|
Long: renameContextLong,
|
||||||
Example: renameContextExample,
|
Example: renameContextExample,
|
||||||
ValidArgsFunction: util.ContextCompletionFunc,
|
ValidArgsFunction: completion.ContextCompletionFunc,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.Complete(cmd, args, out))
|
cmdutil.CheckErr(options.Complete(cmd, args, out))
|
||||||
cmdutil.CheckErr(options.Validate())
|
cmdutil.CheckErr(options.Validate())
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
cliflag "k8s.io/component-base/cli/flag"
|
cliflag "k8s.io/component-base/cli/flag"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -62,7 +62,7 @@ func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess)
|
|||||||
Short: i18n.T("Set a context entry in kubeconfig"),
|
Short: i18n.T("Set a context entry in kubeconfig"),
|
||||||
Long: setContextLong,
|
Long: setContextLong,
|
||||||
Example: setContextExample,
|
Example: setContextExample,
|
||||||
ValidArgsFunction: util.ContextCompletionFunc,
|
ValidArgsFunction: completion.ContextCompletionFunc,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.complete(cmd))
|
cmdutil.CheckErr(options.complete(cmd))
|
||||||
name, exists, err := options.run()
|
name, exists, err := options.run()
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -53,7 +53,7 @@ func NewCmdConfigUseContext(out io.Writer, configAccess clientcmd.ConfigAccess)
|
|||||||
Aliases: []string{"use"},
|
Aliases: []string{"use"},
|
||||||
Long: `Set the current-context in a kubeconfig file.`,
|
Long: `Set the current-context in a kubeconfig file.`,
|
||||||
Example: useContextExample,
|
Example: useContextExample,
|
||||||
ValidArgsFunction: util.ContextCompletionFunc,
|
ValidArgsFunction: completion.ContextCompletionFunc,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.complete(cmd))
|
cmdutil.CheckErr(options.complete(cmd))
|
||||||
cmdutil.CheckErr(options.run())
|
cmdutil.CheckErr(options.run())
|
||||||
|
@ -32,8 +32,8 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubectl/pkg/cmd/exec"
|
"k8s.io/kubectl/pkg/cmd/exec"
|
||||||
"k8s.io/kubectl/pkg/cmd/get"
|
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -102,20 +102,20 @@ func NewCmdCp(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.C
|
|||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
if strings.IndexAny(toComplete, "/.~") == 0 {
|
if strings.IndexAny(toComplete, "/.~") == 0 {
|
||||||
// Looks like a path, do nothing
|
// Looks like a path, do nothing
|
||||||
} else if strings.Index(toComplete, ":") != -1 {
|
} else if strings.Contains(toComplete, ":") {
|
||||||
// TODO: complete remote files in the pod
|
// TODO: complete remote files in the pod
|
||||||
} else if idx := strings.Index(toComplete, "/"); idx > 0 {
|
} else if idx := strings.Index(toComplete, "/"); idx > 0 {
|
||||||
// complete <namespace>/<pod>
|
// complete <namespace>/<pod>
|
||||||
namespace := toComplete[:idx]
|
namespace := toComplete[:idx]
|
||||||
template := "{{ range .items }}{{ .metadata.namespace }}/{{ .metadata.name }}: {{ end }}"
|
template := "{{ range .items }}{{ .metadata.namespace }}/{{ .metadata.name }}: {{ end }}"
|
||||||
comps = get.CompGetFromTemplate(&template, f, namespace, cmd, []string{"pod"}, toComplete)
|
comps = completion.CompGetFromTemplate(&template, f, namespace, cmd, []string{"pod"}, toComplete)
|
||||||
} else {
|
} else {
|
||||||
// Complete namespaces followed by a /
|
// Complete namespaces followed by a /
|
||||||
for _, ns := range get.CompGetResource(f, cmd, "namespace", toComplete) {
|
for _, ns := range completion.CompGetResource(f, cmd, "namespace", toComplete) {
|
||||||
comps = append(comps, fmt.Sprintf("%s/", ns))
|
comps = append(comps, fmt.Sprintf("%s/", ns))
|
||||||
}
|
}
|
||||||
// Complete pod names followed by a :
|
// Complete pod names followed by a :
|
||||||
for _, pod := range get.CompGetResource(f, cmd, "pod", toComplete) {
|
for _, pod := range completion.CompGetResource(f, cmd, "pod", toComplete) {
|
||||||
comps = append(comps, fmt.Sprintf("%s:", pod))
|
comps = append(comps, fmt.Sprintf("%s:", pod))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ import (
|
|||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
"k8s.io/cli-runtime/pkg/resource"
|
"k8s.io/cli-runtime/pkg/resource"
|
||||||
rbacclientv1 "k8s.io/client-go/kubernetes/typed/rbac/v1"
|
rbacclientv1 "k8s.io/client-go/kubernetes/typed/rbac/v1"
|
||||||
"k8s.io/kubectl/pkg/cmd/get"
|
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util"
|
||||||
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -109,7 +109,7 @@ func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, ioStreams genericclioptio
|
|||||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||||
"clusterrole",
|
"clusterrole",
|
||||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
return get.CompGetResource(f, cmd, "clusterrole", toComplete), cobra.ShellCompDirectiveNoFileComp
|
return completion.CompGetResource(f, cmd, "clusterrole", toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -33,7 +33,7 @@ import (
|
|||||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
"k8s.io/kubectl/pkg/util/term"
|
"k8s.io/kubectl/pkg/util/term"
|
||||||
"k8s.io/utils/pointer"
|
"k8s.io/utils/pointer"
|
||||||
@ -115,7 +115,7 @@ func NewCmdCreateToken(f cmdutil.Factory, ioStreams genericclioptions.IOStreams)
|
|||||||
Short: "Request a service account token",
|
Short: "Request a service account token",
|
||||||
Long: tokenLong,
|
Long: tokenLong,
|
||||||
Example: tokenExample,
|
Example: tokenExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "serviceaccount"),
|
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "serviceaccount"),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if err := o.Complete(f, cmd, args); err != nil {
|
if err := o.Complete(f, cmd, args); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
|
@ -36,7 +36,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
cmdwait "k8s.io/kubectl/pkg/cmd/wait"
|
cmdwait "k8s.io/kubectl/pkg/cmd/wait"
|
||||||
"k8s.io/kubectl/pkg/rawhttp"
|
"k8s.io/kubectl/pkg/rawhttp"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -141,7 +141,7 @@ func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra
|
|||||||
Short: i18n.T("Delete resources by file names, stdin, resources and names, or by resources and label selector"),
|
Short: i18n.T("Delete resources by file names, stdin, resources and names, or by resources and label selector"),
|
||||||
Long: deleteLong,
|
Long: deleteLong,
|
||||||
Example: deleteExample,
|
Example: deleteExample,
|
||||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
o, err := deleteFlags.ToOptions(nil, streams)
|
o, err := deleteFlags.ToOptions(nil, streams)
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
"k8s.io/cli-runtime/pkg/resource"
|
"k8s.io/cli-runtime/pkg/resource"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/describe"
|
"k8s.io/kubectl/pkg/describe"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -107,7 +107,7 @@ func NewCmdDescribe(parent string, f cmdutil.Factory, streams genericclioptions.
|
|||||||
Short: i18n.T("Show details of a specific resource or group of resources"),
|
Short: i18n.T("Show details of a specific resource or group of resources"),
|
||||||
Long: describeLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
Long: describeLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
||||||
Example: describeExample,
|
Example: describeExample,
|
||||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Run())
|
cmdutil.CheckErr(o.Run())
|
||||||
|
@ -34,7 +34,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/drain"
|
"k8s.io/kubectl/pkg/drain"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -69,7 +69,7 @@ func NewCmdCordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cob
|
|||||||
Short: i18n.T("Mark node as unschedulable"),
|
Short: i18n.T("Mark node as unschedulable"),
|
||||||
Long: cordonLong,
|
Long: cordonLong,
|
||||||
Example: cordonExample,
|
Example: cordonExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "node"),
|
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "node"),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.RunCordonOrUncordon(true))
|
cmdutil.CheckErr(o.RunCordonOrUncordon(true))
|
||||||
@ -98,7 +98,7 @@ func NewCmdUncordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *c
|
|||||||
Short: i18n.T("Mark node as schedulable"),
|
Short: i18n.T("Mark node as schedulable"),
|
||||||
Long: uncordonLong,
|
Long: uncordonLong,
|
||||||
Example: uncordonExample,
|
Example: uncordonExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "node"),
|
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "node"),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.RunCordonOrUncordon(false))
|
cmdutil.CheckErr(o.RunCordonOrUncordon(false))
|
||||||
@ -184,7 +184,7 @@ func NewCmdDrain(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobr
|
|||||||
Short: i18n.T("Drain node in preparation for maintenance"),
|
Short: i18n.T("Drain node in preparation for maintenance"),
|
||||||
Long: drainLong,
|
Long: drainLong,
|
||||||
Example: drainExample,
|
Example: drainExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "node"),
|
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "node"),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.RunDrain())
|
cmdutil.CheckErr(o.RunDrain())
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/cmd/util/editor"
|
"k8s.io/kubectl/pkg/cmd/util/editor"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -80,7 +80,7 @@ func NewCmdEdit(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra
|
|||||||
Short: i18n.T("Edit a resource on the server"),
|
Short: i18n.T("Edit a resource on the server"),
|
||||||
Long: editLong,
|
Long: editLong,
|
||||||
Example: editExample,
|
Example: editExample,
|
||||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, args, cmd))
|
cmdutil.CheckErr(o.Complete(f, args, cmd))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -37,7 +37,7 @@ import (
|
|||||||
"k8s.io/kubectl/pkg/cmd/util/podcmd"
|
"k8s.io/kubectl/pkg/cmd/util/podcmd"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/interrupt"
|
"k8s.io/kubectl/pkg/util/interrupt"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
@ -89,7 +89,7 @@ func NewCmdExec(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
|
|||||||
Short: i18n.T("Execute a command in a container"),
|
Short: i18n.T("Execute a command in a container"),
|
||||||
Long: i18n.T("Execute a command in a container."),
|
Long: i18n.T("Execute a command in a container."),
|
||||||
Example: execExample,
|
Example: execExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "pod"),
|
ValidArgsFunction: completion.PodResourceNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
argsLenAtDash := cmd.ArgsLenAtDash()
|
argsLenAtDash := cmd.ArgsLenAtDash()
|
||||||
cmdutil.CheckErr(options.Complete(f, cmd, args, argsLenAtDash))
|
cmdutil.CheckErr(options.Complete(f, cmd, args, argsLenAtDash))
|
||||||
@ -101,6 +101,8 @@ func NewCmdExec(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
|
|||||||
cmdutil.AddJsonFilenameFlag(cmd.Flags(), &options.FilenameOptions.Filenames, "to use to exec into the resource")
|
cmdutil.AddJsonFilenameFlag(cmd.Flags(), &options.FilenameOptions.Filenames, "to use to exec into the resource")
|
||||||
// TODO support UID
|
// TODO support UID
|
||||||
cmdutil.AddContainerVarFlags(cmd, &options.ContainerName, options.ContainerName)
|
cmdutil.AddContainerVarFlags(cmd, &options.ContainerName, options.ContainerName)
|
||||||
|
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc("container", completion.ContainerCompletionFunc(f)))
|
||||||
|
|
||||||
cmd.Flags().BoolVarP(&options.Stdin, "stdin", "i", options.Stdin, "Pass stdin to the container")
|
cmd.Flags().BoolVarP(&options.Stdin, "stdin", "i", options.Stdin, "Pass stdin to the container")
|
||||||
cmd.Flags().BoolVarP(&options.TTY, "tty", "t", options.TTY, "Stdin is a TTY")
|
cmd.Flags().BoolVarP(&options.TTY, "tty", "t", options.TTY, "Stdin is a TTY")
|
||||||
cmd.Flags().BoolVarP(&options.Quiet, "quiet", "q", options.Quiet, "Only print output from the remote session")
|
cmd.Flags().BoolVarP(&options.Quiet, "quiet", "q", options.Quiet, "Only print output from the remote session")
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util"
|
||||||
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -137,7 +138,7 @@ func NewCmdExposeService(f cmdutil.Factory, streams genericclioptions.IOStreams)
|
|||||||
Short: i18n.T("Take a replication controller, service, deployment or pod and expose it as a new Kubernetes service"),
|
Short: i18n.T("Take a replication controller, service, deployment or pod and expose it as a new Kubernetes service"),
|
||||||
Long: exposeLong,
|
Long: exposeLong,
|
||||||
Example: exposeExample,
|
Example: exposeExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd))
|
cmdutil.CheckErr(o.Complete(f, cmd))
|
||||||
cmdutil.CheckErr(o.RunExpose(cmd, args))
|
cmdutil.CheckErr(o.RunExpose(cmd, args))
|
||||||
|
@ -17,14 +17,11 @@ limitations under the License.
|
|||||||
package get
|
package get
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -45,7 +42,6 @@ import (
|
|||||||
kubernetesscheme "k8s.io/client-go/kubernetes/scheme"
|
kubernetesscheme "k8s.io/client-go/kubernetes/scheme"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
watchtools "k8s.io/client-go/tools/watch"
|
watchtools "k8s.io/client-go/tools/watch"
|
||||||
"k8s.io/kubectl/pkg/cmd/apiresources"
|
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/rawhttp"
|
"k8s.io/kubectl/pkg/rawhttp"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
@ -170,18 +166,7 @@ func NewCmdGet(parent string, f cmdutil.Factory, streams genericclioptions.IOStr
|
|||||||
Short: i18n.T("Display one or many resources"),
|
Short: i18n.T("Display one or many resources"),
|
||||||
Long: getLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
Long: getLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
||||||
Example: getExample,
|
Example: getExample,
|
||||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
// ValidArgsFunction is set when this function is called so that we have access to the util package
|
||||||
var comps []string
|
|
||||||
if len(args) == 0 {
|
|
||||||
comps = apiresources.CompGetResourceList(f, cmd, toComplete)
|
|
||||||
} else {
|
|
||||||
comps = CompGetResource(f, cmd, args[0], toComplete)
|
|
||||||
if len(args) > 1 {
|
|
||||||
comps = cmdutil.Difference(comps, args[1:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
|
||||||
},
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate(cmd))
|
cmdutil.CheckErr(o.Validate(cmd))
|
||||||
@ -874,61 +859,3 @@ func multipleGVKsRequested(infos []*resource.Info) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompGetResource gets the list of the resource specified which begin with `toComplete`.
|
|
||||||
func CompGetResource(f cmdutil.Factory, cmd *cobra.Command, resourceName string, toComplete string) []string {
|
|
||||||
template := "{{ range .items }}{{ .metadata.name }} {{ end }}"
|
|
||||||
return CompGetFromTemplate(&template, f, "", cmd, []string{resourceName}, toComplete)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompGetContainers gets the list of containers of the specified pod which begin with `toComplete`.
|
|
||||||
func CompGetContainers(f cmdutil.Factory, cmd *cobra.Command, podName string, toComplete string) []string {
|
|
||||||
template := "{{ range .spec.initContainers }}{{ .name }} {{end}}{{ range .spec.containers }}{{ .name }} {{ end }}"
|
|
||||||
return CompGetFromTemplate(&template, f, "", cmd, []string{"pod", podName}, toComplete)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompGetFromTemplate executes a Get operation using the specified template and args and returns the results
|
|
||||||
// which begin with `toComplete`.
|
|
||||||
func CompGetFromTemplate(template *string, f cmdutil.Factory, namespace string, cmd *cobra.Command, args []string, toComplete string) []string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
streams := genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: ioutil.Discard}
|
|
||||||
o := NewGetOptions("kubectl", streams)
|
|
||||||
|
|
||||||
// Get the list of names of the specified resource
|
|
||||||
o.PrintFlags.TemplateFlags.GoTemplatePrintFlags.TemplateArgument = template
|
|
||||||
format := "go-template"
|
|
||||||
o.PrintFlags.OutputFormat = &format
|
|
||||||
|
|
||||||
// Do the steps Complete() would have done.
|
|
||||||
// We cannot actually call Complete() or Validate() as these function check for
|
|
||||||
// the presence of flags, which, in our case won't be there
|
|
||||||
if namespace != "" {
|
|
||||||
o.Namespace = namespace
|
|
||||||
o.ExplicitNamespace = true
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
o.Namespace, o.ExplicitNamespace, err = f.ToRawKubeConfigLoader().Namespace()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
o.ToPrinter = func(mapping *meta.RESTMapping, outputObjects *bool, withNamespace bool, withKind bool) (printers.ResourcePrinterFunc, error) {
|
|
||||||
printer, err := o.PrintFlags.ToPrinter()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return printer.PrintObj, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
o.Run(f, cmd, args)
|
|
||||||
|
|
||||||
var comps []string
|
|
||||||
resources := strings.Split(buf.String(), " ")
|
|
||||||
for _, res := range resources {
|
|
||||||
if res != "" && strings.HasPrefix(res, toComplete) {
|
|
||||||
comps = append(comps, res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return comps
|
|
||||||
}
|
|
||||||
|
@ -39,7 +39,7 @@ import (
|
|||||||
"k8s.io/cli-runtime/pkg/resource"
|
"k8s.io/cli-runtime/pkg/resource"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -139,7 +139,7 @@ func NewCmdLabel(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobr
|
|||||||
Short: i18n.T("Update the labels on a resource"),
|
Short: i18n.T("Update the labels on a resource"),
|
||||||
Long: fmt.Sprintf(labelLong, validation.LabelValueMaxLength),
|
Long: fmt.Sprintf(labelLong, validation.LabelValueMaxLength),
|
||||||
Example: labelExample,
|
Example: labelExample,
|
||||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util"
|
||||||
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -152,7 +153,7 @@ func NewCmdLogs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
|
|||||||
Short: i18n.T("Print the logs for a container in a pod"),
|
Short: i18n.T("Print the logs for a container in a pod"),
|
||||||
Long: logsLong,
|
Long: logsLong,
|
||||||
Example: logsExample,
|
Example: logsExample,
|
||||||
ValidArgsFunction: util.PodResourceNameAndContainerCompletionFunc(f),
|
ValidArgsFunction: completion.PodResourceNameAndContainerCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -39,7 +39,7 @@ import (
|
|||||||
"k8s.io/cli-runtime/pkg/resource"
|
"k8s.io/cli-runtime/pkg/resource"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/slice"
|
"k8s.io/kubectl/pkg/util/slice"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
@ -122,7 +122,7 @@ func NewCmdPatch(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobr
|
|||||||
Short: i18n.T("Update fields of a resource"),
|
Short: i18n.T("Update fields of a resource"),
|
||||||
Long: patchLong,
|
Long: patchLong,
|
||||||
Example: patchExample,
|
Example: patchExample,
|
||||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -41,6 +41,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util"
|
||||||
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -109,7 +110,7 @@ func NewCmdPortForward(f cmdutil.Factory, streams genericclioptions.IOStreams) *
|
|||||||
Short: i18n.T("Forward one or more local ports to a pod"),
|
Short: i18n.T("Forward one or more local ports to a pod"),
|
||||||
Long: portforwardLong,
|
Long: portforwardLong,
|
||||||
Example: portforwardExample,
|
Example: portforwardExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "pod"),
|
ValidArgsFunction: completion.PodResourceNameCompletionFunc(f),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(opts.Complete(f, cmd, args))
|
cmdutil.CheckErr(opts.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(opts.Validate())
|
cmdutil.CheckErr(opts.Validate())
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -84,7 +84,7 @@ func NewCmdRolloutHistory(f cmdutil.Factory, streams genericclioptions.IOStreams
|
|||||||
Short: i18n.T("View rollout history"),
|
Short: i18n.T("View rollout history"),
|
||||||
Long: historyLong,
|
Long: historyLong,
|
||||||
Example: historyExample,
|
Example: historyExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -84,7 +84,7 @@ func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams)
|
|||||||
Short: i18n.T("Mark the provided resource as paused"),
|
Short: i18n.T("Mark the provided resource as paused"),
|
||||||
Long: pauseLong,
|
Long: pauseLong,
|
||||||
Example: pauseExample,
|
Example: pauseExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -29,7 +29,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -91,7 +91,7 @@ func NewCmdRolloutRestart(f cmdutil.Factory, streams genericclioptions.IOStreams
|
|||||||
Short: i18n.T("Restart a resource"),
|
Short: i18n.T("Restart a resource"),
|
||||||
Long: restartLong,
|
Long: restartLong,
|
||||||
Example: restartExample,
|
Example: restartExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -88,7 +88,7 @@ func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams)
|
|||||||
Short: i18n.T("Resume a paused resource"),
|
Short: i18n.T("Resume a paused resource"),
|
||||||
Long: resumeLong,
|
Long: resumeLong,
|
||||||
Example: resumeExample,
|
Example: resumeExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -37,7 +37,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/interrupt"
|
"k8s.io/kubectl/pkg/util/interrupt"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
@ -103,7 +103,7 @@ func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams)
|
|||||||
Short: i18n.T("Show the status of the rollout"),
|
Short: i18n.T("Show the status of the rollout"),
|
||||||
Long: statusLong,
|
Long: statusLong,
|
||||||
Example: statusExample,
|
Example: statusExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, args))
|
cmdutil.CheckErr(o.Complete(f, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -88,7 +88,7 @@ func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) *
|
|||||||
Short: i18n.T("Undo a previous rollout"),
|
Short: i18n.T("Undo a previous rollout"),
|
||||||
Long: undoLong,
|
Long: undoLong,
|
||||||
Example: undoExample,
|
Example: undoExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -31,7 +31,7 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/scale"
|
"k8s.io/kubectl/pkg/scale"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -114,7 +114,7 @@ func NewCmdScale(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobr
|
|||||||
Short: i18n.T("Set a new size for a deployment, replica set, or replication controller"),
|
Short: i18n.T("Set a new size for a deployment, replica set, or replication controller"),
|
||||||
Long: scaleLong,
|
Long: scaleLong,
|
||||||
Example: scaleExample,
|
Example: scaleExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate(cmd))
|
cmdutil.CheckErr(o.Validate(cmd))
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"k8s.io/kubectl/pkg/explain"
|
"k8s.io/kubectl/pkg/explain"
|
||||||
"k8s.io/kubectl/pkg/util"
|
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
@ -38,6 +37,7 @@ import (
|
|||||||
"k8s.io/cli-runtime/pkg/resource"
|
"k8s.io/cli-runtime/pkg/resource"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/scheme"
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
)
|
)
|
||||||
@ -109,7 +109,7 @@ func NewCmdTaint(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.
|
|||||||
Short: i18n.T("Update the taints on one or more nodes"),
|
Short: i18n.T("Update the taints on one or more nodes"),
|
||||||
Long: fmt.Sprintf(taintLong, validation.DNS1123SubdomainMaxLength, validation.LabelValueMaxLength),
|
Long: fmt.Sprintf(taintLong, validation.DNS1123SubdomainMaxLength, validation.LabelValueMaxLength),
|
||||||
Example: taintExample,
|
Example: taintExample,
|
||||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(options.Validate())
|
cmdutil.CheckErr(options.Validate())
|
||||||
|
@ -29,7 +29,7 @@ import (
|
|||||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/metricsutil"
|
"k8s.io/kubectl/pkg/metricsutil"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
metricsapi "k8s.io/metrics/pkg/apis/metrics"
|
metricsapi "k8s.io/metrics/pkg/apis/metrics"
|
||||||
@ -82,7 +82,7 @@ func NewCmdTopNode(f cmdutil.Factory, o *TopNodeOptions, streams genericclioptio
|
|||||||
Short: i18n.T("Display resource (CPU/memory) usage of nodes"),
|
Short: i18n.T("Display resource (CPU/memory) usage of nodes"),
|
||||||
Long: topNodeLong,
|
Long: topNodeLong,
|
||||||
Example: topNodeExample,
|
Example: topNodeExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "node"),
|
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "node"),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
"k8s.io/kubectl/pkg/metricsutil"
|
"k8s.io/kubectl/pkg/metricsutil"
|
||||||
"k8s.io/kubectl/pkg/util"
|
"k8s.io/kubectl/pkg/util/completion"
|
||||||
"k8s.io/kubectl/pkg/util/i18n"
|
"k8s.io/kubectl/pkg/util/i18n"
|
||||||
"k8s.io/kubectl/pkg/util/templates"
|
"k8s.io/kubectl/pkg/util/templates"
|
||||||
metricsapi "k8s.io/metrics/pkg/apis/metrics"
|
metricsapi "k8s.io/metrics/pkg/apis/metrics"
|
||||||
@ -100,7 +100,7 @@ func NewCmdTopPod(f cmdutil.Factory, o *TopPodOptions, streams genericclioptions
|
|||||||
Short: i18n.T("Display resource (CPU/memory) usage of pods"),
|
Short: i18n.T("Display resource (CPU/memory) usage of pods"),
|
||||||
Long: topPodLong,
|
Long: topPodLong,
|
||||||
Example: topPodExample,
|
Example: topPodExample,
|
||||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "pod"),
|
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "pod"),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
|
@ -1,186 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2021 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"k8s.io/kubectl/pkg/cmd/apiresources"
|
|
||||||
"k8s.io/kubectl/pkg/cmd/get"
|
|
||||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var factory cmdutil.Factory
|
|
||||||
|
|
||||||
// SetFactoryForCompletion Store the factory which is needed by the completion functions
|
|
||||||
// Not all commands have access to the factory, so cannot pass it to the completion functions.
|
|
||||||
func SetFactoryForCompletion(f cmdutil.Factory) {
|
|
||||||
factory = f
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceTypeAndNameCompletionFunc Returns a completion function that completes as a first argument
|
|
||||||
// the resource types that match the toComplete prefix, and all following arguments as resource names that match
|
|
||||||
// the toComplete prefix.
|
|
||||||
func ResourceTypeAndNameCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
var comps []string
|
|
||||||
if len(args) == 0 {
|
|
||||||
comps = apiresources.CompGetResourceList(f, cmd, toComplete)
|
|
||||||
} else {
|
|
||||||
comps = get.CompGetResource(f, cmd, args[0], toComplete)
|
|
||||||
if len(args) > 1 {
|
|
||||||
comps = cmdutil.Difference(comps, args[1:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SpecifiedResourceTypeAndNameCompletionFunc Returns a completion function that completes as a first
|
|
||||||
// argument the resource types that match the toComplete prefix and are limited to the allowedTypes,
|
|
||||||
// and all following arguments as resource names that match the toComplete prefix.
|
|
||||||
func SpecifiedResourceTypeAndNameCompletionFunc(f cmdutil.Factory, allowedTypes []string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
return doSpecifiedResourceTypeAndNameComp(f, allowedTypes, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SpecifiedResourceTypeAndNameNoRepeatCompletionFunc Returns a completion function that completes as a first
|
|
||||||
// argument the resource types that match the toComplete prefix and are limited to the allowedTypes, and as
|
|
||||||
// a second argument a resource name that match the toComplete prefix.
|
|
||||||
func SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(f cmdutil.Factory, allowedTypes []string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
return doSpecifiedResourceTypeAndNameComp(f, allowedTypes, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func doSpecifiedResourceTypeAndNameComp(f cmdutil.Factory, allowedTypes []string, repeat bool) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
var comps []string
|
|
||||||
if len(args) == 0 {
|
|
||||||
for _, comp := range allowedTypes {
|
|
||||||
if strings.HasPrefix(comp, toComplete) {
|
|
||||||
comps = append(comps, comp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if repeat || len(args) == 1 {
|
|
||||||
comps = get.CompGetResource(f, cmd, args[0], toComplete)
|
|
||||||
if repeat && len(args) > 1 {
|
|
||||||
comps = cmdutil.Difference(comps, args[1:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceNameCompletionFunc Returns a completion function that completes as a first argument
|
|
||||||
// the resource names specified by the resourceType parameter, and which match the toComplete prefix.
|
|
||||||
func ResourceNameCompletionFunc(f cmdutil.Factory, resourceType string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
var comps []string
|
|
||||||
if len(args) == 0 {
|
|
||||||
comps = get.CompGetResource(f, cmd, resourceType, toComplete)
|
|
||||||
}
|
|
||||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PodResourceNameAndContainerCompletionFunc Returns a completion function that completes as a first
|
|
||||||
// argument pod names that match the toComplete prefix, and as a second argument the containers
|
|
||||||
// within the specified pod.
|
|
||||||
func PodResourceNameAndContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
var comps []string
|
|
||||||
if len(args) == 0 {
|
|
||||||
comps = get.CompGetResource(f, cmd, "pod", toComplete)
|
|
||||||
} else if len(args) == 1 {
|
|
||||||
comps = get.CompGetContainers(f, cmd, args[0], toComplete)
|
|
||||||
}
|
|
||||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContextCompletionFunc is a completion function that completes as a first argument the
|
|
||||||
// context names that match the toComplete prefix
|
|
||||||
func ContextCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
return ListContextsInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClusterCompletionFunc is a completion function that completes as a first argument the
|
|
||||||
// cluster names that match the toComplete prefix
|
|
||||||
func ClusterCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
return ListClustersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserCompletionFunc is a completion function that completes as a first argument the
|
|
||||||
// user names that match the toComplete prefix
|
|
||||||
func UserCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
return ListUsersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListContextsInConfig returns a list of context names which begin with `toComplete`
|
|
||||||
func ListContextsInConfig(toComplete string) []string {
|
|
||||||
config, err := factory.ToRawKubeConfigLoader().RawConfig()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var ret []string
|
|
||||||
for name := range config.Contexts {
|
|
||||||
if strings.HasPrefix(name, toComplete) {
|
|
||||||
ret = append(ret, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListClustersInConfig returns a list of cluster names which begin with `toComplete`
|
|
||||||
func ListClustersInConfig(toComplete string) []string {
|
|
||||||
config, err := factory.ToRawKubeConfigLoader().RawConfig()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var ret []string
|
|
||||||
for name := range config.Clusters {
|
|
||||||
if strings.HasPrefix(name, toComplete) {
|
|
||||||
ret = append(ret, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListUsersInConfig returns a list of user names which begin with `toComplete`
|
|
||||||
func ListUsersInConfig(toComplete string) []string {
|
|
||||||
config, err := factory.ToRawKubeConfigLoader().RawConfig()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var ret []string
|
|
||||||
for name := range config.AuthInfos {
|
|
||||||
if strings.HasPrefix(name, toComplete) {
|
|
||||||
ret = append(ret, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
453
staging/src/k8s.io/kubectl/pkg/util/completion/completion.go
Normal file
453
staging/src/k8s.io/kubectl/pkg/util/completion/completion.go
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package completion
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
|
"k8s.io/cli-runtime/pkg/printers"
|
||||||
|
"k8s.io/kubectl/pkg/cmd/apiresources"
|
||||||
|
"k8s.io/kubectl/pkg/cmd/get"
|
||||||
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||||
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
|
"k8s.io/kubectl/pkg/scheme"
|
||||||
|
)
|
||||||
|
|
||||||
|
var factory cmdutil.Factory
|
||||||
|
|
||||||
|
// SetFactoryForCompletion Store the factory which is needed by the completion functions.
|
||||||
|
// Not all commands have access to the factory, so cannot pass it to the completion functions.
|
||||||
|
func SetFactoryForCompletion(f cmdutil.Factory) {
|
||||||
|
factory = f
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceTypeAndNameCompletionFunc Returns a completion function that completes resource types
|
||||||
|
// and resource names that match the toComplete prefix. It supports the <type>/<name> form.
|
||||||
|
func ResourceTypeAndNameCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return resourceTypeAndNameCompletionFunc(f, nil, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SpecifiedResourceTypeAndNameCompletionFunc Returns a completion function that completes resource
|
||||||
|
// types limited to the specified allowedTypes, and resource names that match the toComplete prefix.
|
||||||
|
// It allows for multiple resources. It supports the <type>/<name> form.
|
||||||
|
func SpecifiedResourceTypeAndNameCompletionFunc(f cmdutil.Factory, allowedTypes []string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return resourceTypeAndNameCompletionFunc(f, allowedTypes, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SpecifiedResourceTypeAndNameNoRepeatCompletionFunc Returns a completion function that completes resource
|
||||||
|
// types limited to the specified allowedTypes, and resource names that match the toComplete prefix.
|
||||||
|
// It only allows for one resource. It supports the <type>/<name> form.
|
||||||
|
func SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(f cmdutil.Factory, allowedTypes []string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return resourceTypeAndNameCompletionFunc(f, allowedTypes, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceNameCompletionFunc Returns a completion function that completes as a first argument
|
||||||
|
// the resource names specified by the resourceType parameter, and which match the toComplete prefix.
|
||||||
|
// This function does NOT support the <type>/<name> form: it is meant to be used by commands
|
||||||
|
// that don't support that form. For commands that apply to pods and that support the <type>/<name>
|
||||||
|
// form, please use PodResourceNameCompletionFunc()
|
||||||
|
func ResourceNameCompletionFunc(f cmdutil.Factory, resourceType string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
var comps []string
|
||||||
|
if len(args) == 0 {
|
||||||
|
comps = CompGetResource(f, cmd, resourceType, toComplete)
|
||||||
|
}
|
||||||
|
return comps, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PodResourceNameCompletionFunc Returns a completion function that completes:
|
||||||
|
// 1- pod names that match the toComplete prefix
|
||||||
|
// 2- resource types containing pods which match the toComplete prefix
|
||||||
|
func PodResourceNameCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
var comps []string
|
||||||
|
directive := cobra.ShellCompDirectiveNoFileComp
|
||||||
|
if len(args) == 0 {
|
||||||
|
comps, directive = doPodResourceCompletion(f, cmd, toComplete)
|
||||||
|
}
|
||||||
|
return comps, directive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PodResourceNameAndContainerCompletionFunc Returns a completion function that completes, as a first argument:
|
||||||
|
// 1- pod names that match the toComplete prefix
|
||||||
|
// 2- resource types containing pods which match the toComplete prefix
|
||||||
|
// and as a second argument the containers within the specified pod.
|
||||||
|
func PodResourceNameAndContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
var comps []string
|
||||||
|
directive := cobra.ShellCompDirectiveNoFileComp
|
||||||
|
if len(args) == 0 {
|
||||||
|
comps, directive = doPodResourceCompletion(f, cmd, toComplete)
|
||||||
|
} else if len(args) == 1 {
|
||||||
|
podName := convertResourceNameToPodName(f, args[0])
|
||||||
|
comps = CompGetContainers(f, cmd, podName, toComplete)
|
||||||
|
}
|
||||||
|
return comps, directive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerCompletionFunc Returns a completion function that completes the containers within the
|
||||||
|
// pod specified by the first argument. The resource containing the pod can be specified in
|
||||||
|
// the <type>/<name> form.
|
||||||
|
func ContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
var comps []string
|
||||||
|
// We need the pod name to be able to complete the container names, it must be in args[0].
|
||||||
|
// That first argument can also be of the form <type>/<name> so we need to convert it.
|
||||||
|
if len(args) > 0 {
|
||||||
|
podName := convertResourceNameToPodName(f, args[0])
|
||||||
|
comps = CompGetContainers(f, cmd, podName, toComplete)
|
||||||
|
}
|
||||||
|
return comps, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextCompletionFunc is a completion function that completes as a first argument the
|
||||||
|
// context names that match the toComplete prefix
|
||||||
|
func ContextCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return ListContextsInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClusterCompletionFunc is a completion function that completes as a first argument the
|
||||||
|
// cluster names that match the toComplete prefix
|
||||||
|
func ClusterCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return ListClustersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserCompletionFunc is a completion function that completes as a first argument the
|
||||||
|
// user names that match the toComplete prefix
|
||||||
|
func UserCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return ListUsersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompGetResource gets the list of the resource specified which begin with `toComplete`.
|
||||||
|
func CompGetResource(f cmdutil.Factory, cmd *cobra.Command, resourceName string, toComplete string) []string {
|
||||||
|
template := "{{ range .items }}{{ .metadata.name }} {{ end }}"
|
||||||
|
return CompGetFromTemplate(&template, f, "", cmd, []string{resourceName}, toComplete)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompGetContainers gets the list of containers of the specified pod which begin with `toComplete`.
|
||||||
|
func CompGetContainers(f cmdutil.Factory, cmd *cobra.Command, podName string, toComplete string) []string {
|
||||||
|
template := "{{ range .spec.initContainers }}{{ .name }} {{end}}{{ range .spec.containers }}{{ .name }} {{ end }}"
|
||||||
|
return CompGetFromTemplate(&template, f, "", cmd, []string{"pod", podName}, toComplete)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompGetFromTemplate executes a Get operation using the specified template and args and returns the results
|
||||||
|
// which begin with `toComplete`.
|
||||||
|
func CompGetFromTemplate(template *string, f cmdutil.Factory, namespace string, cmd *cobra.Command, args []string, toComplete string) []string {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
streams := genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: ioutil.Discard}
|
||||||
|
o := get.NewGetOptions("kubectl", streams)
|
||||||
|
|
||||||
|
// Get the list of names of the specified resource
|
||||||
|
o.PrintFlags.TemplateFlags.GoTemplatePrintFlags.TemplateArgument = template
|
||||||
|
format := "go-template"
|
||||||
|
o.PrintFlags.OutputFormat = &format
|
||||||
|
|
||||||
|
// Do the steps Complete() would have done.
|
||||||
|
// We cannot actually call Complete() or Validate() as these function check for
|
||||||
|
// the presence of flags, which, in our case won't be there
|
||||||
|
if namespace != "" {
|
||||||
|
o.Namespace = namespace
|
||||||
|
o.ExplicitNamespace = true
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
o.Namespace, o.ExplicitNamespace, err = f.ToRawKubeConfigLoader().Namespace()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
o.ToPrinter = func(mapping *meta.RESTMapping, outputObjects *bool, withNamespace bool, withKind bool) (printers.ResourcePrinterFunc, error) {
|
||||||
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return printer.PrintObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
o.Run(f, cmd, args)
|
||||||
|
|
||||||
|
var comps []string
|
||||||
|
resources := strings.Split(buf.String(), " ")
|
||||||
|
for _, res := range resources {
|
||||||
|
if res != "" && strings.HasPrefix(res, toComplete) {
|
||||||
|
comps = append(comps, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comps
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListContextsInConfig returns a list of context names which begin with `toComplete`
|
||||||
|
func ListContextsInConfig(toComplete string) []string {
|
||||||
|
config, err := factory.ToRawKubeConfigLoader().RawConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var ret []string
|
||||||
|
for name := range config.Contexts {
|
||||||
|
if strings.HasPrefix(name, toComplete) {
|
||||||
|
ret = append(ret, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListClustersInConfig returns a list of cluster names which begin with `toComplete`
|
||||||
|
func ListClustersInConfig(toComplete string) []string {
|
||||||
|
config, err := factory.ToRawKubeConfigLoader().RawConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var ret []string
|
||||||
|
for name := range config.Clusters {
|
||||||
|
if strings.HasPrefix(name, toComplete) {
|
||||||
|
ret = append(ret, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListUsersInConfig returns a list of user names which begin with `toComplete`
|
||||||
|
func ListUsersInConfig(toComplete string) []string {
|
||||||
|
config, err := factory.ToRawKubeConfigLoader().RawConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var ret []string
|
||||||
|
for name := range config.AuthInfos {
|
||||||
|
if strings.HasPrefix(name, toComplete) {
|
||||||
|
ret = append(ret, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// compGetResourceList returns the list of api resources which begin with `toComplete`.
|
||||||
|
func compGetResourceList(f cmdutil.Factory, cmd *cobra.Command, toComplete string) []string {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
streams := genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: ioutil.Discard}
|
||||||
|
o := apiresources.NewAPIResourceOptions(streams)
|
||||||
|
|
||||||
|
// Get the list of resources
|
||||||
|
o.Output = "name"
|
||||||
|
o.Cached = true
|
||||||
|
o.Verbs = []string{"get"}
|
||||||
|
// TODO:Should set --request-timeout=5s
|
||||||
|
|
||||||
|
// Ignore errors as the output may still be valid
|
||||||
|
o.RunAPIResources(cmd, f)
|
||||||
|
|
||||||
|
// Resources can be a comma-separated list. The last element is then
|
||||||
|
// the one we should complete. For example if toComplete=="pods,secre"
|
||||||
|
// we should return "pods,secrets"
|
||||||
|
prefix := ""
|
||||||
|
suffix := toComplete
|
||||||
|
lastIdx := strings.LastIndex(toComplete, ",")
|
||||||
|
if lastIdx != -1 {
|
||||||
|
prefix = toComplete[0 : lastIdx+1]
|
||||||
|
suffix = toComplete[lastIdx+1:]
|
||||||
|
}
|
||||||
|
var comps []string
|
||||||
|
resources := strings.Split(buf.String(), "\n")
|
||||||
|
for _, res := range resources {
|
||||||
|
if res != "" && strings.HasPrefix(res, suffix) {
|
||||||
|
comps = append(comps, fmt.Sprintf("%s%s", prefix, res))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comps
|
||||||
|
}
|
||||||
|
|
||||||
|
// resourceTypeAndNameCompletionFunc Returns a completion function that completes resource types
|
||||||
|
// and resource names that match the toComplete prefix. It supports the <type>/<name> form.
|
||||||
|
func resourceTypeAndNameCompletionFunc(f cmdutil.Factory, allowedTypes []string, allowRepeat bool) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
var comps []string
|
||||||
|
directive := cobra.ShellCompDirectiveNoFileComp
|
||||||
|
|
||||||
|
if len(args) > 0 && !strings.Contains(args[0], "/") {
|
||||||
|
// The first argument is of the form <type> (e.g., pods)
|
||||||
|
// All following arguments should be a resource name.
|
||||||
|
if allowRepeat || len(args) == 1 {
|
||||||
|
comps = CompGetResource(f, cmd, args[0], toComplete)
|
||||||
|
|
||||||
|
// Remove choices already on the command-line
|
||||||
|
if len(args) > 1 {
|
||||||
|
comps = cmdutil.Difference(comps, args[1:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slashIdx := strings.Index(toComplete, "/")
|
||||||
|
if slashIdx == -1 {
|
||||||
|
if len(args) == 0 {
|
||||||
|
// We are completing the first argument. We default to the normal
|
||||||
|
// <type> form (not the form <type>/<name>).
|
||||||
|
// So we suggest resource types and let the shell add a space after
|
||||||
|
// the completion.
|
||||||
|
if len(allowedTypes) == 0 {
|
||||||
|
comps = compGetResourceList(f, cmd, toComplete)
|
||||||
|
} else {
|
||||||
|
for _, c := range allowedTypes {
|
||||||
|
if strings.HasPrefix(c, toComplete) {
|
||||||
|
comps = append(comps, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Here we know the first argument contains a / (<type>/<name>).
|
||||||
|
// All other arguments must also use that form.
|
||||||
|
if allowRepeat {
|
||||||
|
// Since toComplete does not already contain a / we know we are completing a
|
||||||
|
// resource type. Disable adding a space after the completion, and add the /
|
||||||
|
directive |= cobra.ShellCompDirectiveNoSpace
|
||||||
|
|
||||||
|
if len(allowedTypes) == 0 {
|
||||||
|
typeComps := compGetResourceList(f, cmd, toComplete)
|
||||||
|
for _, c := range typeComps {
|
||||||
|
comps = append(comps, fmt.Sprintf("%s/", c))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, c := range allowedTypes {
|
||||||
|
if strings.HasPrefix(c, toComplete) {
|
||||||
|
comps = append(comps, fmt.Sprintf("%s/", c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We are completing an argument of the form <type>/<name>
|
||||||
|
// and since the / is already present, we are completing the resource name.
|
||||||
|
if allowRepeat || len(args) == 0 {
|
||||||
|
resourceType := toComplete[:slashIdx]
|
||||||
|
toComplete = toComplete[slashIdx+1:]
|
||||||
|
nameComps := CompGetResource(f, cmd, resourceType, toComplete)
|
||||||
|
for _, c := range nameComps {
|
||||||
|
comps = append(comps, fmt.Sprintf("%s/%s", resourceType, c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove choices already on the command-line.
|
||||||
|
if len(args) > 0 {
|
||||||
|
comps = cmdutil.Difference(comps, args[0:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comps, directive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// doPodResourceCompletion Returns completions of:
|
||||||
|
// 1- pod names that match the toComplete prefix
|
||||||
|
// 2- resource types containing pods which match the toComplete prefix
|
||||||
|
func doPodResourceCompletion(f cmdutil.Factory, cmd *cobra.Command, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
var comps []string
|
||||||
|
directive := cobra.ShellCompDirectiveNoFileComp
|
||||||
|
slashIdx := strings.Index(toComplete, "/")
|
||||||
|
if slashIdx == -1 {
|
||||||
|
// Standard case, complete pod names
|
||||||
|
comps = CompGetResource(f, cmd, "pod", toComplete)
|
||||||
|
|
||||||
|
// Also include resource choices for the <type>/<name> form,
|
||||||
|
// but only for resources that contain pods
|
||||||
|
resourcesWithPods := []string{
|
||||||
|
"daemonsets",
|
||||||
|
"deployments",
|
||||||
|
"pods",
|
||||||
|
"jobs",
|
||||||
|
"replicasets",
|
||||||
|
"replicationcontrollers",
|
||||||
|
"services",
|
||||||
|
"statefulsets"}
|
||||||
|
|
||||||
|
if len(comps) == 0 {
|
||||||
|
// If there are no pods to complete, we will only be completing
|
||||||
|
// <type>/. We should disable adding a space after the /.
|
||||||
|
directive |= cobra.ShellCompDirectiveNoSpace
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, resource := range resourcesWithPods {
|
||||||
|
if strings.HasPrefix(resource, toComplete) {
|
||||||
|
comps = append(comps, fmt.Sprintf("%s/", resource))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Dealing with the <type>/<name> form, use the specified resource type
|
||||||
|
resourceType := toComplete[:slashIdx]
|
||||||
|
toComplete = toComplete[slashIdx+1:]
|
||||||
|
nameComps := CompGetResource(f, cmd, resourceType, toComplete)
|
||||||
|
for _, c := range nameComps {
|
||||||
|
comps = append(comps, fmt.Sprintf("%s/%s", resourceType, c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comps, directive
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertResourceNameToPodName Converts a resource name to a pod name.
|
||||||
|
// If the resource name is of the form <type>/<name>, we use
|
||||||
|
// polymorphichelpers.AttachablePodForObjectFn(), if not, the resource name
|
||||||
|
// is already a pod name.
|
||||||
|
func convertResourceNameToPodName(f cmdutil.Factory, resourceName string) string {
|
||||||
|
var podName string
|
||||||
|
if !strings.Contains(resourceName, "/") {
|
||||||
|
// When we don't have the <type>/<name> form, the resource name is the pod name
|
||||||
|
podName = resourceName
|
||||||
|
} else {
|
||||||
|
// if the resource name is of the form <type>/<name>, we need to convert it to a pod name
|
||||||
|
ns, _, err := f.ToRawKubeConfigLoader().Namespace()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceWithPod, err := f.NewBuilder().
|
||||||
|
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
|
||||||
|
ContinueOnError().
|
||||||
|
NamespaceParam(ns).DefaultNamespace().
|
||||||
|
ResourceNames("pods", resourceName).
|
||||||
|
Do().Object()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// For shell completion, use a short timeout
|
||||||
|
forwardablePod, err := polymorphichelpers.AttachablePodForObjectFn(f, resourceWithPod, 100*time.Millisecond)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
podName = forwardablePod.Name
|
||||||
|
}
|
||||||
|
return podName
|
||||||
|
}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package util
|
package completion
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -127,6 +127,25 @@ func TestResourceTypeAndNameCompletionFuncRepeating(t *testing.T) {
|
|||||||
checkCompletion(t, comps, []string{"foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
checkCompletion(t, comps, []string{"foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResourceTypeAndNameCompletionFuncJointForm(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := ResourceTypeAndNameCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "pod/b")
|
||||||
|
checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResourceTypeAndNameCompletionFuncJointFormRepeating(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := ResourceTypeAndNameCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{"pod/bar"}, "pod/")
|
||||||
|
// The other pods should be completed, but not the already specified ones
|
||||||
|
checkCompletion(t, comps, []string{"pod/foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
func TestSpecifiedResourceTypeAndNameCompletionFuncNoArgs(t *testing.T) {
|
func TestSpecifiedResourceTypeAndNameCompletionFuncNoArgs(t *testing.T) {
|
||||||
tf, cmd := prepareCompletionTest()
|
tf, cmd := prepareCompletionTest()
|
||||||
addPodsToFactory(tf)
|
addPodsToFactory(tf)
|
||||||
@ -155,6 +174,24 @@ func TestSpecifiedResourceTypeAndNameCompletionFuncRepeating(t *testing.T) {
|
|||||||
checkCompletion(t, comps, []string{"foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
checkCompletion(t, comps, []string{"foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSpecifiedResourceTypeAndNameCompletionFuncJointFormOneArg(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := SpecifiedResourceTypeAndNameCompletionFunc(tf, []string{"pod"})
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "pod/b")
|
||||||
|
checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSpecifiedResourceTypeAndNameCompletionFuncJointFormRepeating(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := SpecifiedResourceTypeAndNameCompletionFunc(tf, []string{"pod"})
|
||||||
|
comps, directive := compFunc(cmd, []string{"pod/bar"}, "pod/")
|
||||||
|
// The other pods should be completed, but not the already specified ones
|
||||||
|
checkCompletion(t, comps, []string{"pod/foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncOneArg(t *testing.T) {
|
func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncOneArg(t *testing.T) {
|
||||||
tf, cmd := prepareCompletionTest()
|
tf, cmd := prepareCompletionTest()
|
||||||
addPodsToFactory(tf)
|
addPodsToFactory(tf)
|
||||||
@ -174,6 +211,25 @@ func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncMultiArg(t *testing.T
|
|||||||
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncJointFormOneArg(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(tf, []string{"pod"})
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "pod/b")
|
||||||
|
checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncJointFormMultiArg(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(tf, []string{"pod"})
|
||||||
|
comps, directive := compFunc(cmd, []string{"pod/bar"}, "pod/")
|
||||||
|
// There should not be any more pods shown as this function should not repeat the completion
|
||||||
|
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
func TestResourceNameCompletionFuncNoArgs(t *testing.T) {
|
func TestResourceNameCompletionFuncNoArgs(t *testing.T) {
|
||||||
tf, cmd := prepareCompletionTest()
|
tf, cmd := prepareCompletionTest()
|
||||||
addPodsToFactory(tf)
|
addPodsToFactory(tf)
|
||||||
@ -192,7 +248,65 @@ func TestResourceNameCompletionFuncTooManyArgs(t *testing.T) {
|
|||||||
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPodResourceNameAndContainerCompletionFuncNoArgs(t *testing.T) {
|
func TestResourceNameCompletionFuncJointFormNoArgs(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := ResourceNameCompletionFunc(tf, "pod")
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "pod/b")
|
||||||
|
// The <type>/<name> should NOT be supported by this function
|
||||||
|
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameCompletionFuncNoArgsPodName(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := PodResourceNameCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "b")
|
||||||
|
checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameCompletionFuncNoArgsResources(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := PodResourceNameCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "d")
|
||||||
|
checkCompletion(
|
||||||
|
t, comps, []string{"daemonsets/", "deployments/"},
|
||||||
|
directive, cobra.ShellCompDirectiveNoFileComp|cobra.ShellCompDirectiveNoSpace)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameCompletionFuncTooManyArgs(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := PodResourceNameCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{"pod-name"}, "")
|
||||||
|
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameCompletionFuncJointFormNoArgs(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := PodResourceNameCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "pod/b")
|
||||||
|
// The <type>/<name> SHOULD be supported by this function
|
||||||
|
checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameCompletionFuncJointFormTooManyArgs(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := PodResourceNameCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{"pod/name"}, "pod/b")
|
||||||
|
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameAndContainerCompletionFuncNoArgsPodName(t *testing.T) {
|
||||||
tf, cmd := prepareCompletionTest()
|
tf, cmd := prepareCompletionTest()
|
||||||
addPodsToFactory(tf)
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
@ -201,6 +315,18 @@ func TestPodResourceNameAndContainerCompletionFuncNoArgs(t *testing.T) {
|
|||||||
checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameAndContainerCompletionFuncNoArgsResources(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := PodResourceNameAndContainerCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "s")
|
||||||
|
checkCompletion(
|
||||||
|
t, comps, []string{"services/", "statefulsets/"},
|
||||||
|
directive, cobra.ShellCompDirectiveNoFileComp|cobra.ShellCompDirectiveNoSpace)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestPodResourceNameAndContainerCompletionFuncTooManyArgs(t *testing.T) {
|
func TestPodResourceNameAndContainerCompletionFuncTooManyArgs(t *testing.T) {
|
||||||
tf, cmd := prepareCompletionTest()
|
tf, cmd := prepareCompletionTest()
|
||||||
addPodsToFactory(tf)
|
addPodsToFactory(tf)
|
||||||
@ -210,6 +336,24 @@ func TestPodResourceNameAndContainerCompletionFuncTooManyArgs(t *testing.T) {
|
|||||||
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameAndContainerCompletionFuncJointFormNoArgs(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := PodResourceNameAndContainerCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{}, "pod/b")
|
||||||
|
checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodResourceNameAndContainerCompletionFuncJointFormTooManyArgs(t *testing.T) {
|
||||||
|
tf, cmd := prepareCompletionTest()
|
||||||
|
addPodsToFactory(tf)
|
||||||
|
|
||||||
|
compFunc := PodResourceNameAndContainerCompletionFunc(tf)
|
||||||
|
comps, directive := compFunc(cmd, []string{"pod/pod-name", "container-name"}, "")
|
||||||
|
checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
|
||||||
|
}
|
||||||
|
|
||||||
func setMockFactory(config api.Config) {
|
func setMockFactory(config api.Config) {
|
||||||
clientConfig := clientcmd.NewDefaultClientConfig(config, nil)
|
clientConfig := clientcmd.NewDefaultClientConfig(config, nil)
|
||||||
testFactory := cmdtesting.NewTestFactory().WithClientConfig(clientConfig)
|
testFactory := cmdtesting.NewTestFactory().WithClientConfig(clientConfig)
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -2151,6 +2151,7 @@ k8s.io/kubectl/pkg/scale
|
|||||||
k8s.io/kubectl/pkg/scheme
|
k8s.io/kubectl/pkg/scheme
|
||||||
k8s.io/kubectl/pkg/util
|
k8s.io/kubectl/pkg/util
|
||||||
k8s.io/kubectl/pkg/util/certificate
|
k8s.io/kubectl/pkg/util/certificate
|
||||||
|
k8s.io/kubectl/pkg/util/completion
|
||||||
k8s.io/kubectl/pkg/util/deployment
|
k8s.io/kubectl/pkg/util/deployment
|
||||||
k8s.io/kubectl/pkg/util/event
|
k8s.io/kubectl/pkg/util/event
|
||||||
k8s.io/kubectl/pkg/util/fieldpath
|
k8s.io/kubectl/pkg/util/fieldpath
|
||||||
|
Loading…
Reference in New Issue
Block a user