Files
kubernetes/contrib/completions/bash/kubectl
Eric Paris f6878aed3c Add bash completion custom functions
These functions call out to kubectl to get information about running
resources.  They give us completions which are kubernetes aware and thus
obviously better than just cobra subcommands and flags.
2015-04-13 18:49:28 -04:00

898 lines
18 KiB
Bash

#!/bin/bash
__debug()
{
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
echo "$*" >> ${BASH_COMP_DEBUG_FILE}
fi
}
__index_of_word()
{
local w word=$1
shift
index=0
for w in "$@"; do
[[ $w = "$word" ]] && return
index=$((index+1))
done
index=-1
}
__contains_word()
{
local w word=$1; shift
for w in "$@"; do
[[ $w = "$word" ]] && return
done
return 1
}
__handle_reply()
{
__debug "${FUNCNAME}"
case $cur in
-*)
compopt -o nospace
local allflags
if [ ${#must_have_one_flag[@]} -ne 0 ]; then
allflags=("${must_have_one_flag[@]}")
else
allflags=("${flags[*]} ${two_word_flags[*]}")
fi
COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
[[ $COMPREPLY == *= ]] || compopt +o nospace
return 0;
;;
esac
# check if we are handling a flag with special work handling
local index
__index_of_word "${prev}" "${flags_with_completion[@]}"
if [[ ${index} -ge 0 ]]; then
${flags_completion[${index}]}
return
fi
# we are parsing a flag and don't have a special handler, no completion
if [[ ${cur} != "${words[cword]}" ]]; then
return
fi
local completions
if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
completions=("${must_have_one_flag[@]}")
elif [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
completions=("${must_have_one_noun[@]}")
else
completions=("${commands[@]}")
fi
COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
declare -F __custom_func >/dev/null && __custom_func
fi
}
__handle_flag()
{
__debug "${FUNCNAME}: c is $c words[c] is ${words[c]}"
# if a command required a flag, and we found it, unset must_have_one_flag()
local flagname=${words[c]}
# if the word contained an =
if [[ ${words[c]} == *"="* ]]; then
flagname=${flagname%=*} # strip everything after the =
flagname="${flagname}=" # but put the = back
fi
__debug "${FUNCNAME}: looking for ${flagname}"
if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then
must_have_one_flag=()
fi
# skip the argument to a two word flag
if __contains_word "${words[c]}" "${two_word_flags[@]}"; then
c=$((c+1))
# if we are looking for a flags value, don't show commands
if [[ $c -eq $cword ]]; then
commands=()
fi
fi
# skip the flag itself
c=$((c+1))
}
__handle_noun()
{
__debug "${FUNCNAME}: c is $c words[c] is ${words[c]}"
if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
must_have_one_noun=()
fi
nouns+=("${words[c]}")
c=$((c+1))
}
__handle_command()
{
__debug "${FUNCNAME}: c is $c words[c] is ${words[c]}"
local next_command
if [[ -n ${last_command} ]]; then
next_command="_${last_command}_${words[c]}"
else
next_command="_${words[c]}"
fi
c=$((c+1))
__debug "${FUNCNAME}: looking for ${next_command}"
declare -F $next_command >/dev/null && $next_command
}
__handle_word()
{
if [[ $c -ge $cword ]]; then
__handle_reply
return
fi
__debug "${FUNCNAME}: c is $c words[c] is ${words[c]}"
if [[ "${words[c]}" == -* ]]; then
__handle_flag
elif __contains_word "${words[c]}" "${commands[@]}"; then
__handle_command
else
__handle_noun
fi
__handle_word
}
# call kubectl get $1,
# use the first column in compgen
# we could use templates, but then would need a template per resource
__kubectl_parse_get()
{
local kubectl_output out
if kubectl_output=$(kubectl get --no-headers "$1" 2>/dev/null); then
out=($(echo "${kubectl_output}" | awk '{print $1}'))
COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) )
fi
}
__kubectl_get_resource()
{
if [[ ${#nouns[@]} -eq 0 ]]; then
return 1
fi
__kubectl_parse_get ${nouns[${#nouns[@]} -1]}
if [[ $? -eq 0 ]]; then
return 0
fi
}
# $1 is the name of the pod we want to get the list of containers inside
__kubectl_get_containers()
{
local template
template="{{ range .desiredState.manifest.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 -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_stop)
__kubectl_get_resource
return
;;
kubectl_log)
__kubectl_require_pod_and_container
return
;;
*)
;;
esac
}
_kubectl_get()
{
last_command="kubectl_get"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
flags+=("--no-headers")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--selector=")
two_word_flags+=("-l")
flags+=("--template=")
two_word_flags+=("-t")
flags+=("--watch")
flags+=("-w")
flags+=("--watch-only")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_describe()
{
last_command="kubectl_describe"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_create()
{
last_command="kubectl_create"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--filename=")
two_word_flags+=("-f")
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_update()
{
last_command="kubectl_update"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--filename=")
two_word_flags+=("-f")
flags+=("--help")
flags+=("-h")
flags+=("--patch=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_delete()
{
last_command="kubectl_delete"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--all")
flags+=("--filename=")
two_word_flags+=("-f")
flags+=("--help")
flags+=("-h")
flags+=("--selector=")
two_word_flags+=("-l")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_namespace()
{
last_command="kubectl_namespace"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_log()
{
last_command="kubectl_log"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--follow")
flags+=("-f")
flags+=("--help")
flags+=("-h")
flags+=("--interactive")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_rolling-update()
{
last_command="kubectl_rolling-update"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--filename=")
two_word_flags+=("-f")
flags+=("--help")
flags+=("-h")
flags+=("--poll-interval=")
flags+=("--timeout=")
flags+=("--update-period=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_resize()
{
last_command="kubectl_resize"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--current-replicas=")
flags+=("--help")
flags+=("-h")
flags+=("--replicas=")
flags+=("--resource-version=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_exec()
{
last_command="kubectl_exec"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--container=")
two_word_flags+=("-c")
flags+=("--help")
flags+=("-h")
flags+=("--pod=")
two_word_flags+=("-p")
flags+=("--stdin")
flags+=("-i")
flags+=("--tty")
flags+=("-t")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_port-forward()
{
last_command="kubectl_port-forward"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
flags+=("--pod=")
two_word_flags+=("-p")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_proxy()
{
last_command="kubectl_proxy"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--api-prefix=")
flags+=("--help")
flags+=("-h")
flags+=("--port=")
two_word_flags+=("-p")
flags+=("--www=")
two_word_flags+=("-w")
flags+=("--www-prefix=")
two_word_flags+=("-P")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_run-container()
{
last_command="kubectl_run-container"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--dry-run")
flags+=("--generator=")
flags+=("--help")
flags+=("-h")
flags+=("--image=")
flags+=("--labels=")
two_word_flags+=("-l")
flags+=("--no-headers")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--overrides=")
flags+=("--port=")
flags+=("--replicas=")
two_word_flags+=("-r")
flags+=("--template=")
two_word_flags+=("-t")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_stop()
{
last_command="kubectl_stop"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--all")
flags+=("--filename=")
two_word_flags+=("-f")
flags+=("--help")
flags+=("-h")
flags+=("--selector=")
two_word_flags+=("-l")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_expose()
{
last_command="kubectl_expose"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--container-port=")
flags+=("--create-external-load-balancer")
flags+=("--dry-run")
flags+=("--generator=")
flags+=("--help")
flags+=("-h")
flags+=("--labels=")
two_word_flags+=("-l")
flags+=("--no-headers")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--overrides=")
flags+=("--port=")
flags+=("--protocol=")
flags+=("--public-ip=")
flags+=("--selector=")
flags+=("--service-name=")
flags+=("--target-port=")
flags+=("--template=")
two_word_flags+=("-t")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_label()
{
last_command="kubectl_label"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--all")
flags+=("--help")
flags+=("-h")
flags+=("--no-headers")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--overwrite")
flags+=("--resource-version=")
flags+=("--selector=")
two_word_flags+=("-l")
flags+=("--template=")
two_word_flags+=("-t")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_config_view()
{
last_command="kubectl_config_view"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
flags+=("--merge")
flags+=("--no-headers")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--template=")
two_word_flags+=("-t")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_config_set-cluster()
{
last_command="kubectl_config_set-cluster"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--api-version=")
flags+=("--certificate-authority=")
flags+=("--embed-certs")
flags+=("--help")
flags+=("-h")
flags+=("--insecure-skip-tls-verify")
flags+=("--server=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_config_set-credentials()
{
last_command="kubectl_config_set-credentials"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--auth-path=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--embed-certs")
flags+=("--help")
flags+=("-h")
flags+=("--password=")
flags+=("--token=")
flags+=("--username=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_config_set-context()
{
last_command="kubectl_config_set-context"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--cluster=")
flags+=("--help")
flags+=("-h")
flags+=("--namespace=")
flags+=("--user=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_config_set()
{
last_command="kubectl_config_set"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_config_unset()
{
last_command="kubectl_config_unset"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_config_use-context()
{
last_command="kubectl_config_use-context"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_config()
{
last_command="kubectl_config"
commands=()
commands+=("view")
commands+=("set-cluster")
commands+=("set-credentials")
commands+=("set-context")
commands+=("set")
commands+=("unset")
commands+=("use-context")
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--envvar")
flags+=("--global")
flags+=("--help")
flags+=("-h")
flags+=("--kubeconfig=")
flags+=("--local")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_cluster-info()
{
last_command="kubectl_cluster-info"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_api-versions()
{
last_command="kubectl_api-versions"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_version()
{
last_command="kubectl_version"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--client")
flags+=("-c")
flags+=("--help")
flags+=("-h")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl()
{
last_command="kubectl"
commands=()
commands+=("get")
commands+=("describe")
commands+=("create")
commands+=("update")
commands+=("delete")
commands+=("namespace")
commands+=("log")
commands+=("rolling-update")
commands+=("resize")
commands+=("exec")
commands+=("port-forward")
commands+=("proxy")
commands+=("run-container")
commands+=("stop")
commands+=("expose")
commands+=("label")
commands+=("config")
commands+=("cluster-info")
commands+=("api-versions")
commands+=("version")
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--auth-path=")
two_word_flags+=("-a")
flags+=("--certificate-authority=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--cluster=")
flags+=("--context=")
flags+=("--help")
flags+=("-h")
flags+=("--insecure-skip-tls-verify")
flags+=("--kubeconfig=")
flags+=("--log_backtrace_at=")
flags+=("--log_dir=")
flags+=("--log_flush_frequency=")
flags+=("--logtostderr")
flags+=("--match-server-version")
flags+=("--namespace=")
flags+=("--password=")
flags+=("--server=")
two_word_flags+=("-s")
flags+=("--stderrthreshold=")
flags+=("--token=")
flags+=("--user=")
flags+=("--username=")
flags+=("--v=")
flags+=("--validate")
flags+=("--vmodule=")
must_have_one_flag=()
must_have_one_noun=()
}
__start_kubectl()
{
local cur prev words cword split
_init_completion -s || return
local completions_func
local c=0
local flags=()
local two_word_flags=()
local flags_with_completion=()
local flags_completion=()
local commands=("kubectl")
local must_have_one_flag=()
local must_have_one_noun=()
local last_command
local nouns=()
__handle_word
}
complete -F __start_kubectl kubectl
# ex: ts=4 sw=4 et filetype=sh