mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
Refactor completion code into its own package
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
This commit is contained in:
parent
cf66f5c3cb
commit
c4f8c57b43
@ -38,7 +38,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/templates"
|
||||
)
|
||||
@ -135,7 +135,7 @@ func NewCmdAnnotate(parent string, f cmdutil.Factory, ioStreams genericclioption
|
||||
Short: i18n.T("Update the annotations on a resource"),
|
||||
Long: annotateLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
||||
Example: annotateExample,
|
||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -17,11 +17,8 @@ limitations under the License.
|
||||
package apiresources
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@ -278,38 +275,3 @@ func (s sortableResource) compareValues(i, j int) (string, string) {
|
||||
}
|
||||
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"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/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"),
|
||||
Long: applyEditLastAppliedLong,
|
||||
Example: applyEditLastAppliedExample,
|
||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, args, cmd))
|
||||
cmdutil.CheckErr(o.Run())
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
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/templates"
|
||||
"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"),
|
||||
Long: applyViewLastAppliedLong,
|
||||
Example: applyViewLastAppliedExample,
|
||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(options.Complete(cmd, f, args))
|
||||
cmdutil.CheckErr(options.Validate(cmd))
|
||||
|
@ -35,7 +35,7 @@ import (
|
||||
"k8s.io/kubectl/pkg/cmd/util/podcmd"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/templates"
|
||||
)
|
||||
@ -105,7 +105,7 @@ func NewCmdAttach(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra
|
||||
Short: i18n.T("Attach to a running container"),
|
||||
Long: i18n.T("Attach to a process that is already running inside an existing container."),
|
||||
Example: attachExample,
|
||||
ValidArgsFunction: util.PodResourceNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.PodResourceNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/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"),
|
||||
Long: autoscaleLong,
|
||||
Example: autoscaleExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -70,7 +70,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/cmd/version"
|
||||
"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/templates"
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
@ -319,6 +319,11 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
|
||||
proxyCmd.PreRun = func(cmd *cobra.Command, args []string) {
|
||||
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{
|
||||
{
|
||||
Message: "Basic Commands (Beginner):",
|
||||
@ -333,7 +338,7 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
|
||||
Message: "Basic Commands (Intermediate):",
|
||||
Commands: []*cobra.Command{
|
||||
explain.NewCmdExplain("kubectl", f, o.IOStreams),
|
||||
get.NewCmdGet("kubectl", f, o.IOStreams),
|
||||
getCmd,
|
||||
edit.NewCmdEdit(f, o.IOStreams),
|
||||
delete.NewCmdDelete(f, o.IOStreams),
|
||||
},
|
||||
@ -404,7 +409,7 @@ func NewKubectlCommand(o KubectlOptions) *cobra.Command {
|
||||
|
||||
templates.ActsAsRootCommand(cmds, filters, groups...)
|
||||
|
||||
util.SetFactoryForCompletion(f)
|
||||
utilcomp.SetFactoryForCompletion(f)
|
||||
registerCompletionFuncForGlobalFlags(cmds, f)
|
||||
|
||||
cmds.AddCommand(alpha)
|
||||
@ -474,21 +479,21 @@ func registerCompletionFuncForGlobalFlags(cmd *cobra.Command, f cmdutil.Factory)
|
||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||
"namespace",
|
||||
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(
|
||||
"context",
|
||||
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(
|
||||
"cluster",
|
||||
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(
|
||||
"user",
|
||||
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"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
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/templates"
|
||||
)
|
||||
@ -42,7 +42,7 @@ func NewCmdConfigDeleteCluster(out io.Writer, configAccess clientcmd.ConfigAcces
|
||||
Short: i18n.T("Delete the specified cluster from the kubeconfig"),
|
||||
Long: i18n.T("Delete the specified cluster from the kubeconfig."),
|
||||
Example: deleteClusterExample,
|
||||
ValidArgsFunction: util.ClusterCompletionFunc,
|
||||
ValidArgsFunction: completion.ClusterCompletionFunc,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(runDeleteCluster(out, configAccess, cmd))
|
||||
},
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
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/templates"
|
||||
)
|
||||
@ -42,7 +42,7 @@ func NewCmdConfigDeleteContext(out, errOut io.Writer, configAccess clientcmd.Con
|
||||
Short: i18n.T("Delete the specified context from the kubeconfig"),
|
||||
Long: i18n.T("Delete the specified context from the kubeconfig."),
|
||||
Example: deleteContextExample,
|
||||
ValidArgsFunction: util.ContextCompletionFunc,
|
||||
ValidArgsFunction: completion.ContextCompletionFunc,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(runDeleteContext(out, errOut, configAccess, cmd))
|
||||
},
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
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/templates"
|
||||
)
|
||||
@ -65,7 +65,7 @@ func NewCmdConfigDeleteUser(streams genericclioptions.IOStreams, configAccess cl
|
||||
Short: i18n.T("Delete the specified user from the kubeconfig"),
|
||||
Long: i18n.T("Delete the specified user from the kubeconfig."),
|
||||
Example: deleteUserExample,
|
||||
ValidArgsFunction: util.UserCompletionFunc,
|
||||
ValidArgsFunction: completion.UserCompletionFunc,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
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/templates"
|
||||
)
|
||||
@ -68,7 +68,7 @@ func NewCmdConfigRenameContext(out io.Writer, configAccess clientcmd.ConfigAcces
|
||||
Short: renameContextShort,
|
||||
Long: renameContextLong,
|
||||
Example: renameContextExample,
|
||||
ValidArgsFunction: util.ContextCompletionFunc,
|
||||
ValidArgsFunction: completion.ContextCompletionFunc,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(options.Complete(cmd, args, out))
|
||||
cmdutil.CheckErr(options.Validate())
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
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/templates"
|
||||
)
|
||||
@ -62,7 +62,7 @@ func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess)
|
||||
Short: i18n.T("Set a context entry in kubeconfig"),
|
||||
Long: setContextLong,
|
||||
Example: setContextExample,
|
||||
ValidArgsFunction: util.ContextCompletionFunc,
|
||||
ValidArgsFunction: completion.ContextCompletionFunc,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(options.complete(cmd))
|
||||
name, exists, err := options.run()
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
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/templates"
|
||||
)
|
||||
@ -53,7 +53,7 @@ func NewCmdConfigUseContext(out io.Writer, configAccess clientcmd.ConfigAccess)
|
||||
Aliases: []string{"use"},
|
||||
Long: `Set the current-context in a kubeconfig file.`,
|
||||
Example: useContextExample,
|
||||
ValidArgsFunction: util.ContextCompletionFunc,
|
||||
ValidArgsFunction: completion.ContextCompletionFunc,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(options.complete(cmd))
|
||||
cmdutil.CheckErr(options.run())
|
||||
|
@ -32,8 +32,8 @@ import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/kubectl/pkg/cmd/exec"
|
||||
"k8s.io/kubectl/pkg/cmd/get"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/util/completion"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"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 strings.IndexAny(toComplete, "/.~") == 0 {
|
||||
// Looks like a path, do nothing
|
||||
} else if strings.Index(toComplete, ":") != -1 {
|
||||
} else if strings.Contains(toComplete, ":") {
|
||||
// TODO: complete remote files in the pod
|
||||
} else if idx := strings.Index(toComplete, "/"); idx > 0 {
|
||||
// complete <namespace>/<pod>
|
||||
namespace := toComplete[:idx]
|
||||
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 {
|
||||
// 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))
|
||||
}
|
||||
// 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))
|
||||
}
|
||||
|
||||
|
@ -29,10 +29,10 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
rbacclientv1 "k8s.io/client-go/kubernetes/typed/rbac/v1"
|
||||
"k8s.io/kubectl/pkg/cmd/get"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/templates"
|
||||
)
|
||||
@ -109,7 +109,7 @@ func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, ioStreams genericclioptio
|
||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||
"clusterrole",
|
||||
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
|
||||
|
@ -33,7 +33,7 @@ import (
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/term"
|
||||
"k8s.io/utils/pointer"
|
||||
@ -115,7 +115,7 @@ func NewCmdCreateToken(f cmdutil.Factory, ioStreams genericclioptions.IOStreams)
|
||||
Short: "Request a service account token",
|
||||
Long: tokenLong,
|
||||
Example: tokenExample,
|
||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "serviceaccount"),
|
||||
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "serviceaccount"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := o.Complete(f, cmd, args); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
|
@ -36,7 +36,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
cmdwait "k8s.io/kubectl/pkg/cmd/wait"
|
||||
"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/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"),
|
||||
Long: deleteLong,
|
||||
Example: deleteExample,
|
||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
o, err := deleteFlags.ToOptions(nil, streams)
|
||||
cmdutil.CheckErr(err)
|
||||
|
@ -30,7 +30,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/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"),
|
||||
Long: describeLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
||||
Example: describeExample,
|
||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Run())
|
||||
|
@ -34,7 +34,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/drain"
|
||||
"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/templates"
|
||||
)
|
||||
@ -69,7 +69,7 @@ func NewCmdCordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cob
|
||||
Short: i18n.T("Mark node as unschedulable"),
|
||||
Long: cordonLong,
|
||||
Example: cordonExample,
|
||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "node"),
|
||||
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "node"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
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"),
|
||||
Long: uncordonLong,
|
||||
Example: uncordonExample,
|
||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "node"),
|
||||
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "node"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
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"),
|
||||
Long: drainLong,
|
||||
Example: drainExample,
|
||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "node"),
|
||||
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "node"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.RunDrain())
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/templates"
|
||||
)
|
||||
@ -77,7 +77,7 @@ func NewCmdEdit(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra
|
||||
Short: i18n.T("Edit a resource on the server"),
|
||||
Long: editLong,
|
||||
Example: editExample,
|
||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, args, cmd))
|
||||
cmdutil.CheckErr(o.Run())
|
||||
|
@ -37,7 +37,7 @@ import (
|
||||
"k8s.io/kubectl/pkg/cmd/util/podcmd"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/interrupt"
|
||||
"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"),
|
||||
Long: i18n.T("Execute a command in a container."),
|
||||
Example: execExample,
|
||||
ValidArgsFunction: util.PodResourceNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.PodResourceNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
argsLenAtDash := cmd.ArgsLenAtDash()
|
||||
cmdutil.CheckErr(options.Complete(f, cmd, args, argsLenAtDash))
|
||||
@ -101,7 +101,7 @@ func NewCmdExec(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
|
||||
cmdutil.AddJsonFilenameFlag(cmd.Flags(), &options.FilenameOptions.Filenames, "to use to exec into the resource")
|
||||
// TODO support UID
|
||||
cmdutil.AddContainerVarFlags(cmd, &options.ContainerName, options.ContainerName)
|
||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc("container", util.ContainerCompletionFunc(f)))
|
||||
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.TTY, "tty", "t", options.TTY, "Stdin is a TTY")
|
||||
|
@ -38,6 +38,7 @@ import (
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/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"),
|
||||
Long: exposeLong,
|
||||
Example: exposeExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd))
|
||||
cmdutil.CheckErr(o.RunExpose(cmd, args))
|
||||
|
@ -17,14 +17,11 @@ limitations under the License.
|
||||
package get
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@ -45,7 +42,6 @@ import (
|
||||
kubernetesscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
watchtools "k8s.io/client-go/tools/watch"
|
||||
"k8s.io/kubectl/pkg/cmd/apiresources"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/rawhttp"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
@ -163,7 +159,7 @@ func NewCmdGet(parent string, f cmdutil.Factory, streams genericclioptions.IOStr
|
||||
Short: i18n.T("Display one or many resources"),
|
||||
Long: getLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
|
||||
Example: getExample,
|
||||
ValidArgsFunction: ResourceTypeAndNameCompletionFunc(f, nil, true),
|
||||
// ValidArgsFunction is set when this function is called so that we have access to the util package
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate(cmd))
|
||||
@ -851,140 +847,3 @@ func multipleGVKsRequested(infos []*resource.Info) bool {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 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 = apiresources.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 := apiresources.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
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/templates"
|
||||
)
|
||||
@ -139,7 +139,7 @@ func NewCmdLabel(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobr
|
||||
Short: i18n.T("Update the labels on a resource"),
|
||||
Long: fmt.Sprintf(labelLong, validation.LabelValueMaxLength),
|
||||
Example: labelExample,
|
||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -37,6 +37,7 @@ import (
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/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"),
|
||||
Long: logsLong,
|
||||
Example: logsExample,
|
||||
ValidArgsFunction: util.PodResourceNameAndContainerCompletionFunc(f),
|
||||
ValidArgsFunction: completion.PodResourceNameAndContainerCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -39,7 +39,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/templates"
|
||||
)
|
||||
@ -115,7 +115,7 @@ func NewCmdPatch(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobr
|
||||
Short: i18n.T("Update fields of a resource"),
|
||||
Long: patchLong,
|
||||
Example: patchExample,
|
||||
ValidArgsFunction: util.ResourceTypeAndNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.ResourceTypeAndNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -41,6 +41,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"k8s.io/kubectl/pkg/util"
|
||||
"k8s.io/kubectl/pkg/util/completion"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"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"),
|
||||
Long: portforwardLong,
|
||||
Example: portforwardExample,
|
||||
ValidArgsFunction: util.PodResourceNameCompletionFunc(f),
|
||||
ValidArgsFunction: completion.PodResourceNameCompletionFunc(f),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(opts.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(opts.Validate())
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/templates"
|
||||
)
|
||||
@ -84,7 +84,7 @@ func NewCmdRolloutHistory(f cmdutil.Factory, streams genericclioptions.IOStreams
|
||||
Short: i18n.T("View rollout history"),
|
||||
Long: historyLong,
|
||||
Example: historyExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -30,7 +30,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/templates"
|
||||
)
|
||||
@ -84,7 +84,7 @@ func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams)
|
||||
Short: i18n.T("Mark the provided resource as paused"),
|
||||
Long: pauseLong,
|
||||
Example: pauseExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/templates"
|
||||
)
|
||||
@ -91,7 +91,7 @@ func NewCmdRolloutRestart(f cmdutil.Factory, streams genericclioptions.IOStreams
|
||||
Short: i18n.T("Restart a resource"),
|
||||
Long: restartLong,
|
||||
Example: restartExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -30,7 +30,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/templates"
|
||||
)
|
||||
@ -88,7 +88,7 @@ func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams)
|
||||
Short: i18n.T("Resume a paused resource"),
|
||||
Long: resumeLong,
|
||||
Example: resumeExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -37,7 +37,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/interrupt"
|
||||
"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"),
|
||||
Long: statusLong,
|
||||
Example: statusExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"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/templates"
|
||||
)
|
||||
@ -88,7 +88,7 @@ func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) *
|
||||
Short: i18n.T("Undo a previous rollout"),
|
||||
Long: undoLong,
|
||||
Example: undoExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -31,7 +31,7 @@ import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/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"),
|
||||
Long: scaleLong,
|
||||
Example: scaleExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate(cmd))
|
||||
|
@ -24,7 +24,6 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubectl/pkg/explain"
|
||||
"k8s.io/kubectl/pkg/util"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
@ -38,6 +37,7 @@ import (
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util/completion"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"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"),
|
||||
Long: fmt.Sprintf(taintLong, validation.DNS1123SubdomainMaxLength, validation.LabelValueMaxLength),
|
||||
Example: taintExample,
|
||||
ValidArgsFunction: util.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
ValidArgsFunction: completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(options.Validate())
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/templates"
|
||||
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"),
|
||||
Long: topNodeLong,
|
||||
Example: topNodeExample,
|
||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "node"),
|
||||
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "node"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -30,7 +30,7 @@ import (
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"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/templates"
|
||||
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"),
|
||||
Long: topPodLong,
|
||||
Example: topPodExample,
|
||||
ValidArgsFunction: util.ResourceNameCompletionFunc(f, "pod"),
|
||||
ValidArgsFunction: completion.ResourceNameCompletionFunc(f, "pod"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
|
@ -14,14 +14,21 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
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"
|
||||
@ -30,7 +37,7 @@ import (
|
||||
|
||||
var factory cmdutil.Factory
|
||||
|
||||
// SetFactoryForCompletion Store the factory which is needed by the completion functions
|
||||
// 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
|
||||
@ -39,22 +46,21 @@ func SetFactoryForCompletion(f cmdutil.Factory) {
|
||||
// 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) {
|
||||
// The logic is in the 'get' package because the 'get' command must be able to call it also
|
||||
return get.ResourceTypeAndNameCompletionFunc(f, nil, true)
|
||||
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 get.ResourceTypeAndNameCompletionFunc(f, allowedTypes, true)
|
||||
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 get.ResourceTypeAndNameCompletionFunc(f, allowedTypes, false)
|
||||
return resourceTypeAndNameCompletionFunc(f, allowedTypes, false)
|
||||
}
|
||||
|
||||
// ResourceNameCompletionFunc Returns a completion function that completes as a first argument
|
||||
@ -66,7 +72,7 @@ func ResourceNameCompletionFunc(f cmdutil.Factory, resourceType string) func(*co
|
||||
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)
|
||||
comps = CompGetResource(f, cmd, resourceType, toComplete)
|
||||
}
|
||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
@ -98,7 +104,7 @@ func PodResourceNameAndContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Co
|
||||
comps, directive = doPodResourceCompletion(f, cmd, toComplete)
|
||||
} else if len(args) == 1 {
|
||||
podName := convertResourceNameToPodName(f, args[0])
|
||||
comps = get.CompGetContainers(f, cmd, podName, toComplete)
|
||||
comps = CompGetContainers(f, cmd, podName, toComplete)
|
||||
}
|
||||
return comps, directive
|
||||
}
|
||||
@ -114,7 +120,7 @@ func ContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, s
|
||||
// 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 = get.CompGetContainers(f, cmd, podName, toComplete)
|
||||
comps = CompGetContainers(f, cmd, podName, toComplete)
|
||||
}
|
||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
@ -147,6 +153,64 @@ func UserCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([
|
||||
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()
|
||||
@ -192,6 +256,120 @@ func ListUsersInConfig(toComplete string) []string {
|
||||
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
|
||||
@ -201,7 +379,7 @@ func doPodResourceCompletion(f cmdutil.Factory, cmd *cobra.Command, toComplete s
|
||||
slashIdx := strings.Index(toComplete, "/")
|
||||
if slashIdx == -1 {
|
||||
// Standard case, complete pod names
|
||||
comps = get.CompGetResource(f, cmd, "pod", toComplete)
|
||||
comps = CompGetResource(f, cmd, "pod", toComplete)
|
||||
|
||||
// Also include resource choices for the <type>/<name> form,
|
||||
// but only for resources that contain pods
|
||||
@ -230,7 +408,7 @@ func doPodResourceCompletion(f cmdutil.Factory, cmd *cobra.Command, toComplete s
|
||||
// Dealing with the <type>/<name> form, use the specified resource type
|
||||
resourceType := toComplete[:slashIdx]
|
||||
toComplete = toComplete[slashIdx+1:]
|
||||
nameComps := get.CompGetResource(f, cmd, resourceType, toComplete)
|
||||
nameComps := CompGetResource(f, cmd, resourceType, toComplete)
|
||||
for _, c := range nameComps {
|
||||
comps = append(comps, fmt.Sprintf("%s/%s", resourceType, c))
|
||||
}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
package completion
|
||||
|
||||
import (
|
||||
"net/http"
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -2150,6 +2150,7 @@ k8s.io/kubectl/pkg/scale
|
||||
k8s.io/kubectl/pkg/scheme
|
||||
k8s.io/kubectl/pkg/util
|
||||
k8s.io/kubectl/pkg/util/certificate
|
||||
k8s.io/kubectl/pkg/util/completion
|
||||
k8s.io/kubectl/pkg/util/deployment
|
||||
k8s.io/kubectl/pkg/util/event
|
||||
k8s.io/kubectl/pkg/util/fieldpath
|
||||
|
Loading…
Reference in New Issue
Block a user