123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- /*
- Copyright 2014 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 cmd
- import (
- "fmt"
- "io"
- "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
- cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config"
- "k8s.io/kubernetes/pkg/kubectl/cmd/rollout"
- "k8s.io/kubernetes/pkg/kubectl/cmd/set"
- "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
- cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
- "k8s.io/kubernetes/pkg/util/flag"
- "github.com/golang/glog"
- "github.com/spf13/cobra"
- )
- const (
- bash_completion_func = `# call kubectl get $1,
- __kubectl_override_flag_list=(kubeconfig cluster user context namespace server)
- __kubectl_override_flags()
- {
- local ${__kubectl_override_flag_list[*]} two_word_of of
- for w in "${words[@]}"; do
- if [ -n "${two_word_of}" ]; then
- eval "${two_word_of}=\"--${two_word_of}=\${w}\""
- two_word_of=
- continue
- fi
- for of in "${__kubectl_override_flag_list[@]}"; do
- case "${w}" in
- --${of}=*)
- eval "${of}=\"${w}\""
- ;;
- --${of})
- two_word_of="${of}"
- ;;
- esac
- done
- if [ "${w}" == "--all-namespaces" ]; then
- namespace="--all-namespaces"
- fi
- done
- for of in "${__kubectl_override_flag_list[@]}"; do
- if eval "test -n \"\$${of}\""; then
- eval "echo \${${of}}"
- fi
- done
- }
- __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()
- {
- local template
- template="{{ range .items }}{{ .metadata.name }} {{ end }}"
- local kubectl_out
- if kubectl_out=$(kubectl get $(__kubectl_override_flags) -o template --template="${template}" "$1" 2>/dev/null); then
- COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
- fi
- }
- __kubectl_get_resource()
- {
- if [[ ${#nouns[@]} -eq 0 ]]; then
- return 1
- fi
- __kubectl_parse_get "${nouns[${#nouns[@]} -1]}"
- }
- __kubectl_get_resource_pod()
- {
- __kubectl_parse_get "pod"
- }
- __kubectl_get_resource_rc()
- {
- __kubectl_parse_get "rc"
- }
- __kubectl_get_resource_node()
- {
- __kubectl_parse_get "node"
- }
- # $1 is the name of the pod we want to get the list of containers inside
- __kubectl_get_containers()
- {
- local template
- template="{{ range .spec.containers }}{{ .name }} {{ end }}"
- __debug "${FUNCNAME} nouns are ${nouns[*]}"
- local len="${#nouns[@]}"
- if [[ ${len} -ne 1 ]]; then
- return
- fi
- local last=${nouns[${len} -1]}
- local kubectl_out
- if kubectl_out=$(kubectl get $(__kubectl_override_flags) -o template --template="${template}" pods "${last}" 2>/dev/null); then
- COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
- fi
- }
- # Require both a pod and a container to be specified
- __kubectl_require_pod_and_container()
- {
- if [[ ${#nouns[@]} -eq 0 ]]; then
- __kubectl_parse_get pods
- return 0
- fi;
- __kubectl_get_containers
- return 0
- }
- __custom_func() {
- case ${last_command} in
- kubectl_get | kubectl_describe | kubectl_delete | kubectl_label | kubectl_stop | kubectl_edit | kubectl_patch |\
- kubectl_annotate | kubectl_expose | kubectl_scale | kubectl_autoscale | kubectl_taint | kubectl_rollout_*)
- __kubectl_get_resource
- return
- ;;
- kubectl_logs | kubectl_attach)
- __kubectl_require_pod_and_container
- return
- ;;
- kubectl_exec | kubectl_port-forward | kubectl_top_pod)
- __kubectl_get_resource_pod
- return
- ;;
- kubectl_rolling-update)
- __kubectl_get_resource_rc
- return
- ;;
- kubectl_cordon | kubectl_uncordon | kubectl_drain | kubectl_top_node)
- __kubectl_get_resource_node
- return
- ;;
- *)
- ;;
- esac
- }
- `
- // If you add a resource to this list, please also take a look at pkg/kubectl/kubectl.go
- // and add a short forms entry in expandResourceShortcut() when appropriate.
- // TODO: This should be populated using the discovery information from apiserver.
- valid_resources = `Valid resource types include:
- * clusters (valid only for federation apiservers)
- * componentstatuses (aka 'cs')
- * configmaps (aka 'cm')
- * daemonsets (aka 'ds')
- * deployments (aka 'deploy')
- * events (aka 'ev')
- * endpoints (aka 'ep')
- * horizontalpodautoscalers (aka 'hpa')
- * ingress (aka 'ing')
- * jobs
- * limitranges (aka 'limits')
- * nodes (aka 'no')
- * namespaces (aka 'ns')
- * petsets (alpha feature, may be unstable)
- * pods (aka 'po')
- * persistentvolumes (aka 'pv')
- * persistentvolumeclaims (aka 'pvc')
- * quota
- * resourcequotas (aka 'quota')
- * replicasets (aka 'rs')
- * replicationcontrollers (aka 'rc')
- * secrets
- * serviceaccounts (aka 'sa')
- * services (aka 'svc')
- `
- usage_template = `{{if gt .Aliases 0}}
- Aliases:
- {{.NameAndAliases}}{{end}}{{if .HasExample}}
- Examples:
- {{ .Example }}{{end}}{{ if .HasAvailableSubCommands}}
- Available Sub-commands:{{range .Commands}}{{if .IsAvailableCommand}}
- {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasLocalFlags}}
- Flags:
- {{.LocalFlags.FlagUsages | trimRightSpace}}{{end}}{{ if .HasInheritedFlags}}
- Global Flags:
- {{.InheritedFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasHelpSubCommands}}
- Additional help topics:{{range .Commands}}{{if .IsHelpCommand}}
- {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}
- Usage:{{if .Runnable}}
- {{if .HasFlags}}{{appendIfNotPresent .UseLine "[flags]"}}{{else}}{{.UseLine}}{{end}}{{end}}{{ if .HasSubCommands }}
- {{ .CommandPath}} [command]
- Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
- `
- help_template = `{{with or .Long .Short }}{{. | trim}}{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
- )
- // NewKubectlCommand creates the `kubectl` command and its nested children.
- func NewKubectlCommand(f *cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
- // Parent command to which all subcommands are added.
- cmds := &cobra.Command{
- Use: "kubectl",
- Short: "kubectl controls the Kubernetes cluster manager",
- Long: `kubectl controls the Kubernetes cluster manager.
- Find more information at https://github.com/kubernetes/kubernetes.`,
- Run: runHelp,
- BashCompletionFunction: bash_completion_func,
- }
- f.BindFlags(cmds.PersistentFlags())
- f.BindExternalFlags(cmds.PersistentFlags())
- // From this point and forward we get warnings on flags that contain "_" separators
- cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)
- groups := templates.CommandGroups{
- {
- Message: "Basic Commands (Beginner):",
- Commands: []*cobra.Command{
- NewCmdCreate(f, out),
- NewCmdExposeService(f, out),
- NewCmdRun(f, in, out, err),
- set.NewCmdSet(f, out),
- },
- },
- {
- Message: "Basic Commands (Intermediate):",
- Commands: []*cobra.Command{
- NewCmdGet(f, out, err),
- NewCmdExplain(f, out, err),
- NewCmdEdit(f, out, err),
- NewCmdDelete(f, out),
- },
- },
- {
- Message: "Deploy Commands:",
- Commands: []*cobra.Command{
- rollout.NewCmdRollout(f, out),
- NewCmdRollingUpdate(f, out),
- NewCmdScale(f, out),
- NewCmdAutoscale(f, out),
- },
- },
- {
- Message: "Cluster Management Commands:",
- Commands: []*cobra.Command{
- NewCmdClusterInfo(f, out),
- NewCmdTop(f, out),
- NewCmdCordon(f, out),
- NewCmdUncordon(f, out),
- NewCmdDrain(f, out),
- NewCmdTaint(f, out),
- },
- },
- {
- Message: "Troubleshooting and Debugging Commands:",
- Commands: []*cobra.Command{
- NewCmdDescribe(f, out, err),
- NewCmdLogs(f, out),
- NewCmdAttach(f, in, out, err),
- NewCmdExec(f, in, out, err),
- NewCmdPortForward(f, out, err),
- NewCmdProxy(f, out),
- },
- },
- {
- Message: "Advanced Commands:",
- Commands: []*cobra.Command{
- NewCmdApply(f, out),
- NewCmdPatch(f, out),
- NewCmdReplace(f, out),
- NewCmdConvert(f, out),
- },
- },
- {
- Message: "Settings Commands:",
- Commands: []*cobra.Command{
- NewCmdLabel(f, out),
- NewCmdAnnotate(f, out),
- NewCmdCompletion(f, out),
- },
- },
- }
- groups.Add(cmds)
- filters := []string{
- "options",
- Deprecated("kubectl", "delete", cmds, NewCmdStop(f, out)),
- Deprecated("kubectl", "config set-context", cmds, NewCmdNamespace(out)),
- }
- templates.ActsAsRootCommand(cmds, filters, groups...)
- if cmds.Flag("namespace") != nil {
- 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",
- )
- }
- cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), out))
- cmds.AddCommand(NewCmdVersion(f, out))
- cmds.AddCommand(NewCmdApiVersions(f, out))
- cmds.AddCommand(NewCmdOptions(out))
- return cmds
- }
- func runHelp(cmd *cobra.Command, args []string) {
- cmd.Help()
- }
- func printDeprecationWarning(command, alias string) {
- glog.Warningf("%s is DEPRECATED and will be removed in a future version. Use %s instead.", alias, command)
- }
- func Deprecated(baseName, to string, parent, cmd *cobra.Command) string {
- cmd.Long = fmt.Sprintf("Deprecated: This command is deprecated, all its functionalities are covered by \"%s %s\"", baseName, to)
- cmd.Short = fmt.Sprintf("Deprecated: %s", to)
- parent.AddCommand(cmd)
- return cmd.Name()
- }
|