kubernetes/contrib/completions/bash/kubectl
Stef Walter f6da3fdbe1 kubectl: Add proxy --unix-socket=/file/path option
Proxies on a TCP port are accessible outside the current security
context (eg: uid). Add support for having the proxy listen on a
unix socket, which has permissions applied to it.

We make sure the socket starts its life only accessible by the
current user using Umask.

This is useful for applications like Cockpit and other tools which
want the help of kubectl to handle authentication, configuration and
transport security, but also want to not make that accessible to
all users on a multi-user system.
2015-08-06 11:56:47 +02:00

1074 lines
22 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
}
# The arguments should be in the form "ext1|ext2|extn"
__handle_filename_extension_flag()
{
local ext="$1"
_filedir "@(${ext})"
}
__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,
__kubectl_parse_get()
{
local template
template="{{ range .items }}{{ .metadata.name }} {{ end }}"
local kubectl_out
if kubectl_out=$(kubectl get -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]}"
}
# $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 -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_get_resource
return
;;
kubectl_logs)
__kubectl_require_pod_and_container
return
;;
*)
;;
esac
}
_kubectl_get()
{
last_command="kubectl_get"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--all-namespaces")
flags+=("--help")
flags+=("-h")
flags+=("--label-columns=")
two_word_flags+=("-L")
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=()
must_have_one_noun+=("componentstatus")
must_have_one_noun+=("endpoints")
must_have_one_noun+=("event")
must_have_one_noun+=("limitrange")
must_have_one_noun+=("namespace")
must_have_one_noun+=("node")
must_have_one_noun+=("persistentvolume")
must_have_one_noun+=("persistentvolumeclaim")
must_have_one_noun+=("pod")
must_have_one_noun+=("podtemplate")
must_have_one_noun+=("replicationcontroller")
must_have_one_noun+=("resourcequota")
must_have_one_noun+=("secret")
must_have_one_noun+=("service")
must_have_one_noun+=("serviceaccount")
}
_kubectl_describe()
{
last_command="kubectl_describe"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
flags+=("--selector=")
two_word_flags+=("-l")
must_have_one_flag=()
must_have_one_noun=()
must_have_one_noun+=("limitrange")
must_have_one_noun+=("minion")
must_have_one_noun+=("namespace")
must_have_one_noun+=("node")
must_have_one_noun+=("persistentvolume")
must_have_one_noun+=("persistentvolumeclaim")
must_have_one_noun+=("pod")
must_have_one_noun+=("replicationcontroller")
must_have_one_noun+=("resourcequota")
must_have_one_noun+=("secret")
must_have_one_noun+=("service")
must_have_one_noun+=("serviceaccount")
}
_kubectl_create()
{
last_command="kubectl_create"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--filename=")
flags_with_completion+=("--filename")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
two_word_flags+=("-f")
flags_with_completion+=("-f")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
flags+=("--help")
flags+=("-h")
flags+=("--output=")
two_word_flags+=("-o")
must_have_one_flag=()
must_have_one_flag+=("--filename=")
must_have_one_flag+=("-f")
must_have_one_noun=()
}
_kubectl_replace()
{
last_command="kubectl_replace"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--cascade")
flags+=("--filename=")
flags_with_completion+=("--filename")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
two_word_flags+=("-f")
flags_with_completion+=("-f")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
flags+=("--force")
flags+=("--grace-period=")
flags+=("--help")
flags+=("-h")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--timeout=")
must_have_one_flag=()
must_have_one_flag+=("--filename=")
must_have_one_flag+=("-f")
must_have_one_noun=()
}
_kubectl_patch()
{
last_command="kubectl_patch"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--help")
flags+=("-h")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--patch=")
two_word_flags+=("-p")
must_have_one_flag=()
must_have_one_flag+=("--patch=")
must_have_one_flag+=("-p")
must_have_one_noun=()
}
_kubectl_delete()
{
last_command="kubectl_delete"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--all")
flags+=("--cascade")
flags+=("--filename=")
flags_with_completion+=("--filename")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
two_word_flags+=("-f")
flags_with_completion+=("-f")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
flags+=("--grace-period=")
flags+=("--help")
flags+=("-h")
flags+=("--ignore-not-found")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--selector=")
two_word_flags+=("-l")
flags+=("--timeout=")
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_logs()
{
last_command="kubectl_logs"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--container=")
two_word_flags+=("-c")
flags+=("--follow")
flags+=("-f")
flags+=("--help")
flags+=("-h")
flags+=("--interactive")
flags+=("--previous")
flags+=("-p")
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+=("--deployment-label-key=")
flags+=("--dry-run")
flags+=("--filename=")
two_word_flags+=("-f")
flags+=("--help")
flags+=("-h")
flags+=("--image=")
flags+=("--no-headers")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--poll-interval=")
flags+=("--rollback")
flags+=("--template=")
two_word_flags+=("-t")
flags+=("--timeout=")
flags+=("--update-period=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_scale()
{
last_command="kubectl_scale"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--current-replicas=")
flags+=("--help")
flags+=("-h")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--replicas=")
flags+=("--resource-version=")
flags+=("--timeout=")
must_have_one_flag=()
must_have_one_flag+=("--replicas=")
must_have_one_noun=()
}
_kubectl_attach()
{
last_command="kubectl_attach"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--container=")
two_word_flags+=("-c")
flags+=("--help")
flags+=("-h")
flags+=("--stdin")
flags+=("-i")
flags+=("--tty")
flags+=("-t")
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_flag+=("--pod=")
must_have_one_flag+=("-p")
must_have_one_noun=()
}
_kubectl_proxy()
{
last_command="kubectl_proxy"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--accept-hosts=")
flags+=("--accept-paths=")
flags+=("--api-prefix=")
flags+=("--disable-filter")
flags+=("--help")
flags+=("-h")
flags+=("--port=")
two_word_flags+=("-p")
flags+=("--reject-methods=")
flags+=("--reject-paths=")
flags+=("--unix-socket=")
two_word_flags+=("-u")
flags+=("--www=")
two_word_flags+=("-w")
flags+=("--www-prefix=")
two_word_flags+=("-P")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_run()
{
last_command="kubectl_run"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--dry-run")
flags+=("--generator=")
flags+=("--help")
flags+=("-h")
flags+=("--hostport=")
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_flag+=("--image=")
must_have_one_noun=()
}
_kubectl_stop()
{
last_command="kubectl_stop"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--all")
flags+=("--filename=")
flags_with_completion+=("--filename")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
two_word_flags+=("-f")
flags_with_completion+=("-f")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
flags+=("--grace-period=")
flags+=("--help")
flags+=("-h")
flags+=("--ignore-not-found")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--selector=")
two_word_flags+=("-l")
flags+=("--timeout=")
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+=("--name=")
flags+=("--no-headers")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--overrides=")
flags+=("--port=")
flags+=("--protocol=")
flags+=("--public-ip=")
flags+=("--selector=")
flags+=("--session-affinity=")
flags+=("--target-port=")
flags+=("--template=")
two_word_flags+=("-t")
flags+=("--type=")
must_have_one_flag=()
must_have_one_flag+=("--port=")
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_annotate()
{
last_command="kubectl_annotate"
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+=("--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+=("--flatten")
flags+=("--help")
flags+=("-h")
flags+=("--merge")
flags+=("--minify")
flags+=("--no-headers")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--raw")
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+=("--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+=("--help")
flags+=("-h")
flags+=("--kubeconfig=")
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+=("replace")
commands+=("patch")
commands+=("delete")
commands+=("namespace")
commands+=("logs")
commands+=("rolling-update")
commands+=("scale")
commands+=("attach")
commands+=("exec")
commands+=("port-forward")
commands+=("proxy")
commands+=("run")
commands+=("stop")
commands+=("expose")
commands+=("label")
commands+=("annotate")
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+=("--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
_init_completion -s || return
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