mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Make kubectl bash completion namespace aware and add noun aliases
- add namespace filtering to bash completion - add --namespace flag bash completion - add bash completion noun aliases - adapt to new cobra package structure
This commit is contained in:
		@@ -21,7 +21,7 @@ import (
 | 
				
			|||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra/doc"
 | 
				
			||||||
	"k8s.io/kubernetes/cmd/genutils"
 | 
						"k8s.io/kubernetes/cmd/genutils"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubectl/cmd"
 | 
						"k8s.io/kubernetes/pkg/kubectl/cmd"
 | 
				
			||||||
	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
 | 
						cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
 | 
				
			||||||
@@ -48,5 +48,5 @@ func main() {
 | 
				
			|||||||
	os.Setenv("HOME", "/home/username")
 | 
						os.Setenv("HOME", "/home/username")
 | 
				
			||||||
	// TODO os.Stdin should really be something like ioutil.Discard, but a Reader
 | 
						// TODO os.Stdin should really be something like ioutil.Discard, but a Reader
 | 
				
			||||||
	kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
 | 
						kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
 | 
				
			||||||
	cobra.GenMarkdownTree(kubectl, outDir)
 | 
						doc.GenMarkdownTree(kubectl, outDir)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra/doc"
 | 
				
			||||||
	"k8s.io/kubernetes/cmd/genutils"
 | 
						"k8s.io/kubernetes/cmd/genutils"
 | 
				
			||||||
	apiservapp "k8s.io/kubernetes/cmd/kube-apiserver/app"
 | 
						apiservapp "k8s.io/kubernetes/cmd/kube-apiserver/app"
 | 
				
			||||||
	cmapp "k8s.io/kubernetes/cmd/kube-controller-manager/app"
 | 
						cmapp "k8s.io/kubernetes/cmd/kube-controller-manager/app"
 | 
				
			||||||
@@ -51,23 +51,23 @@ func main() {
 | 
				
			|||||||
	case "kube-apiserver":
 | 
						case "kube-apiserver":
 | 
				
			||||||
		// generate docs for kube-apiserver
 | 
							// generate docs for kube-apiserver
 | 
				
			||||||
		apiserver := apiservapp.NewAPIServerCommand()
 | 
							apiserver := apiservapp.NewAPIServerCommand()
 | 
				
			||||||
		cobra.GenMarkdownTree(apiserver, outDir)
 | 
							doc.GenMarkdownTree(apiserver, outDir)
 | 
				
			||||||
	case "kube-controller-manager":
 | 
						case "kube-controller-manager":
 | 
				
			||||||
		// generate docs for kube-controller-manager
 | 
							// generate docs for kube-controller-manager
 | 
				
			||||||
		controllermanager := cmapp.NewControllerManagerCommand()
 | 
							controllermanager := cmapp.NewControllerManagerCommand()
 | 
				
			||||||
		cobra.GenMarkdownTree(controllermanager, outDir)
 | 
							doc.GenMarkdownTree(controllermanager, outDir)
 | 
				
			||||||
	case "kube-proxy":
 | 
						case "kube-proxy":
 | 
				
			||||||
		// generate docs for kube-proxy
 | 
							// generate docs for kube-proxy
 | 
				
			||||||
		proxy := proxyapp.NewProxyCommand()
 | 
							proxy := proxyapp.NewProxyCommand()
 | 
				
			||||||
		cobra.GenMarkdownTree(proxy, outDir)
 | 
							doc.GenMarkdownTree(proxy, outDir)
 | 
				
			||||||
	case "kube-scheduler":
 | 
						case "kube-scheduler":
 | 
				
			||||||
		// generate docs for kube-scheduler
 | 
							// generate docs for kube-scheduler
 | 
				
			||||||
		scheduler := schapp.NewSchedulerCommand()
 | 
							scheduler := schapp.NewSchedulerCommand()
 | 
				
			||||||
		cobra.GenMarkdownTree(scheduler, outDir)
 | 
							doc.GenMarkdownTree(scheduler, outDir)
 | 
				
			||||||
	case "kubelet":
 | 
						case "kubelet":
 | 
				
			||||||
		// generate docs for kubelet
 | 
							// generate docs for kubelet
 | 
				
			||||||
		kubelet := kubeletapp.NewKubeletCommand()
 | 
							kubelet := kubeletapp.NewKubeletCommand()
 | 
				
			||||||
		cobra.GenMarkdownTree(kubelet, outDir)
 | 
							doc.GenMarkdownTree(kubelet, outDir)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		fmt.Fprintf(os.Stderr, "Module %s is not supported", module)
 | 
							fmt.Fprintf(os.Stderr, "Module %s is not supported", module)
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,12 +30,47 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	bash_completion_func = `# call kubectl get $1,
 | 
						bash_completion_func = `# call kubectl get $1,
 | 
				
			||||||
 | 
					__kubectl_namespace_flag()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local ret two_word_ns
 | 
				
			||||||
 | 
					    ret=""
 | 
				
			||||||
 | 
					    two_word_ns=false
 | 
				
			||||||
 | 
					    for w in "${words[@]}"; do
 | 
				
			||||||
 | 
					        if [ "$two_word_ns" = true ]; then
 | 
				
			||||||
 | 
					            ret="--namespace=${w}"
 | 
				
			||||||
 | 
					            two_word_ns=false
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        case "${w}" in
 | 
				
			||||||
 | 
					            --namespace=*)
 | 
				
			||||||
 | 
					                ret=${w}
 | 
				
			||||||
 | 
					                ;;
 | 
				
			||||||
 | 
					            --namespace)
 | 
				
			||||||
 | 
					                two_word_ns=true
 | 
				
			||||||
 | 
					                ;;
 | 
				
			||||||
 | 
					            --all-namespaces)
 | 
				
			||||||
 | 
					                ret=${w}
 | 
				
			||||||
 | 
					                ;;
 | 
				
			||||||
 | 
					        esac
 | 
				
			||||||
 | 
					    done
 | 
				
			||||||
 | 
					    echo $ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__kubectl_get_namespaces()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    local template kubectl_out
 | 
				
			||||||
 | 
					    template="{{ range .items  }}{{ .metadata.name }} {{ end }}"
 | 
				
			||||||
 | 
					    if kubectl_out=$(kubectl get -o template --template="${template}" namespace 2>/dev/null); then
 | 
				
			||||||
 | 
					        COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__kubectl_parse_get()
 | 
					__kubectl_parse_get()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local template
 | 
					    local template
 | 
				
			||||||
    template="{{ range .items  }}{{ .metadata.name }} {{ end }}"
 | 
					    template="{{ range .items  }}{{ .metadata.name }} {{ end }}"
 | 
				
			||||||
    local kubectl_out
 | 
					    local kubectl_out
 | 
				
			||||||
    if kubectl_out=$(kubectl get -o template --template="${template}" "$1" 2>/dev/null); then
 | 
					    if kubectl_out=$(kubectl get $(__kubectl_namespace_flag) -o template --template="${template}" "$1" 2>/dev/null); then
 | 
				
			||||||
        COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
 | 
					        COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -71,7 +106,7 @@ __kubectl_get_containers()
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
    local last=${nouns[${len} -1]}
 | 
					    local last=${nouns[${len} -1]}
 | 
				
			||||||
    local kubectl_out
 | 
					    local kubectl_out
 | 
				
			||||||
    if kubectl_out=$(kubectl get -o template --template="${template}" pods "${last}" 2>/dev/null); then
 | 
					    if kubectl_out=$(kubectl get $(__kubectl_namespace_flag) -o template --template="${template}" pods "${last}" 2>/dev/null); then
 | 
				
			||||||
        COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
 | 
					        COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -196,6 +231,14 @@ Find more information at https://github.com/kubernetes/kubernetes.`,
 | 
				
			|||||||
	cmds.AddCommand(NewCmdExplain(f, out))
 | 
						cmds.AddCommand(NewCmdExplain(f, out))
 | 
				
			||||||
	cmds.AddCommand(NewCmdConvert(f, out))
 | 
						cmds.AddCommand(NewCmdConvert(f, out))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if cmds.Flag("namespace").Annotations == nil {
 | 
				
			||||||
 | 
							cmds.Flag("namespace").Annotations = map[string][]string{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cmds.Flag("namespace").Annotations[cobra.BashCompCustom] = append(
 | 
				
			||||||
 | 
							cmds.Flag("namespace").Annotations[cobra.BashCompCustom],
 | 
				
			||||||
 | 
							"__kubectl_get_namespaces",
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return cmds
 | 
						return cmds
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,11 +71,12 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
	options := &DeleteOptions{}
 | 
						options := &DeleteOptions{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// retrieve a list of handled resources from printer as valid args
 | 
						// retrieve a list of handled resources from printer as valid args
 | 
				
			||||||
	validArgs := []string{}
 | 
						validArgs, argAliases := []string{}, []string{}
 | 
				
			||||||
	p, err := f.Printer(nil, false, false, false, false, false, false, []string{})
 | 
						p, err := f.Printer(nil, false, false, false, false, false, false, []string{})
 | 
				
			||||||
	cmdutil.CheckErr(err)
 | 
						cmdutil.CheckErr(err)
 | 
				
			||||||
	if p != nil {
 | 
						if p != nil {
 | 
				
			||||||
		validArgs = p.HandledResources()
 | 
							validArgs = p.HandledResources()
 | 
				
			||||||
 | 
							argAliases = kubectl.ResourceAliases(validArgs)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := &cobra.Command{
 | 
						cmd := &cobra.Command{
 | 
				
			||||||
@@ -89,6 +90,7 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
			cmdutil.CheckErr(err)
 | 
								cmdutil.CheckErr(err)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		ValidArgs:  validArgs,
 | 
							ValidArgs:  validArgs,
 | 
				
			||||||
 | 
							ArgAliases: argAliases,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	usage := "Filename, directory, or URL to a file containing the resource to delete."
 | 
						usage := "Filename, directory, or URL to a file containing the resource to delete."
 | 
				
			||||||
	kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
 | 
						kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,6 +74,9 @@ kubectl describe pods frontend`
 | 
				
			|||||||
func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
					func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			||||||
	options := &DescribeOptions{}
 | 
						options := &DescribeOptions{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						validArgs := kubectl.DescribableResources()
 | 
				
			||||||
 | 
						argAliases := kubectl.ResourceAliases(validArgs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := &cobra.Command{
 | 
						cmd := &cobra.Command{
 | 
				
			||||||
		Use:     "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)",
 | 
							Use:     "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)",
 | 
				
			||||||
		Short:   "Show details of a specific resource or group of resources",
 | 
							Short:   "Show details of a specific resource or group of resources",
 | 
				
			||||||
@@ -83,7 +86,8 @@ func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
			err := RunDescribe(f, out, cmd, args, options)
 | 
								err := RunDescribe(f, out, cmd, args, options)
 | 
				
			||||||
			cmdutil.CheckErr(err)
 | 
								cmdutil.CheckErr(err)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		ValidArgs: kubectl.DescribableResources(),
 | 
							ValidArgs:  validArgs,
 | 
				
			||||||
 | 
							ArgAliases: argAliases,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	usage := "Filename, directory, or URL to a file containing the resource to describe"
 | 
						usage := "Filename, directory, or URL to a file containing the resource to describe"
 | 
				
			||||||
	kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
 | 
						kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,11 +74,12 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
	options := &GetOptions{}
 | 
						options := &GetOptions{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// retrieve a list of handled resources from printer as valid args
 | 
						// retrieve a list of handled resources from printer as valid args
 | 
				
			||||||
	validArgs := []string{}
 | 
						validArgs, argAliases := []string{}, []string{}
 | 
				
			||||||
	p, err := f.Printer(nil, false, false, false, false, false, false, []string{})
 | 
						p, err := f.Printer(nil, false, false, false, false, false, false, []string{})
 | 
				
			||||||
	cmdutil.CheckErr(err)
 | 
						cmdutil.CheckErr(err)
 | 
				
			||||||
	if p != nil {
 | 
						if p != nil {
 | 
				
			||||||
		validArgs = p.HandledResources()
 | 
							validArgs = p.HandledResources()
 | 
				
			||||||
 | 
							argAliases = kubectl.ResourceAliases(validArgs)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := &cobra.Command{
 | 
						cmd := &cobra.Command{
 | 
				
			||||||
@@ -91,6 +92,7 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
			cmdutil.CheckErr(err)
 | 
								cmdutil.CheckErr(err)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		ValidArgs:  validArgs,
 | 
							ValidArgs:  validArgs,
 | 
				
			||||||
 | 
							ArgAliases: argAliases,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cmdutil.AddPrinterFlags(cmd)
 | 
						cmdutil.AddPrinterFlags(cmd)
 | 
				
			||||||
	cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
 | 
						cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,11 +73,12 @@ func NewCmdLabel(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
	options := &LabelOptions{}
 | 
						options := &LabelOptions{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// retrieve a list of handled resources from printer as valid args
 | 
						// retrieve a list of handled resources from printer as valid args
 | 
				
			||||||
	validArgs := []string{}
 | 
						validArgs, argAliases := []string{}, []string{}
 | 
				
			||||||
	p, err := f.Printer(nil, false, false, false, false, false, false, []string{})
 | 
						p, err := f.Printer(nil, false, false, false, false, false, false, []string{})
 | 
				
			||||||
	cmdutil.CheckErr(err)
 | 
						cmdutil.CheckErr(err)
 | 
				
			||||||
	if p != nil {
 | 
						if p != nil {
 | 
				
			||||||
		validArgs = p.HandledResources()
 | 
							validArgs = p.HandledResources()
 | 
				
			||||||
 | 
							argAliases = kubectl.ResourceAliases(validArgs)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := &cobra.Command{
 | 
						cmd := &cobra.Command{
 | 
				
			||||||
@@ -90,6 +91,7 @@ func NewCmdLabel(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
			cmdutil.CheckErr(err)
 | 
								cmdutil.CheckErr(err)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		ValidArgs:  validArgs,
 | 
							ValidArgs:  validArgs,
 | 
				
			||||||
 | 
							ArgAliases: argAliases,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cmdutil.AddPrinterFlags(cmd)
 | 
						cmdutil.AddPrinterFlags(cmd)
 | 
				
			||||||
	cmd.Flags().Bool("overwrite", false, "If true, allow labels to be overwritten, otherwise reject label updates that overwrite existing labels.")
 | 
						cmd.Flags().Bool("overwrite", false, "If true, allow labels to be overwritten, otherwise reject label updates that overwrite existing labels.")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -175,6 +175,35 @@ func expandResourceShortcut(resource unversioned.GroupVersionResource) unversion
 | 
				
			|||||||
	return resource
 | 
						return resource
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ResourceAliases returns the resource shortcuts and plural forms for the given resources.
 | 
				
			||||||
 | 
					func ResourceAliases(rs []string) []string {
 | 
				
			||||||
 | 
						as := make([]string, 0, len(rs))
 | 
				
			||||||
 | 
						plurals := make(map[string]struct{}, len(rs))
 | 
				
			||||||
 | 
						for _, r := range rs {
 | 
				
			||||||
 | 
							var plural string
 | 
				
			||||||
 | 
							switch {
 | 
				
			||||||
 | 
							case r == "endpoints":
 | 
				
			||||||
 | 
								plural = r // exception. "endpoint" does not exist. Why?
 | 
				
			||||||
 | 
							case strings.HasSuffix(r, "y"):
 | 
				
			||||||
 | 
								plural = r[0:len(r)-1] + "ies"
 | 
				
			||||||
 | 
							case strings.HasSuffix(r, "s"):
 | 
				
			||||||
 | 
								plural = r + "es"
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								plural = r + "s"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							as = append(as, plural)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							plurals[plural] = struct{}{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for sf, r := range shortForms {
 | 
				
			||||||
 | 
							if _, found := plurals[r]; found {
 | 
				
			||||||
 | 
								as = append(as, sf)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return as
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// parseFileSource parses the source given. Acceptable formats include:
 | 
					// parseFileSource parses the source given. Acceptable formats include:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// 1.  source-path: the basename will become the key name
 | 
					// 1.  source-path: the basename will become the key name
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user