Last active
May 5, 2020 12:23
-
-
Save wagnst/8268789f85958f397f892a7d8c8ebbae to your computer and use it in GitHub Desktop.
kubectl completion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ -f ~/.kubectl_aliases ] && source ~/.kubectl_aliases | |
function alias_completion() { | |
local namespace="alias_completion" | |
# parse function based completion definitions, where capture group 2 => function and 3 => trigger | |
local compl_regex='complete( +[^ ]+)* -F ([^ ]+) ("[^"]+"|[^ ]+)' | |
# parse alias definitions, where capture group 1 => trigger, 2 => command, 3 => command arguments | |
local alias_regex="alias ([^=]+)='(\"[^\"]+\"|[^ ]+)(( +[^ ]+)*)'" | |
# create array of function completion triggers, keeping multi-word triggers together | |
eval "local completions=($(complete -p | sed -Ene "/$compl_regex/s//'\3'/p"))" | |
(( ${#completions[@]} == 0 )) && return 0 | |
# create temporary file for wrapper functions and completions | |
rm -f "/tmp/${namespace}-*.tmp" # preliminary cleanup | |
local tmp_file; tmp_file="$(mktemp "/tmp/${namespace}-${RANDOM}XXX.tmp")" || return 1 | |
local completion_loader; completion_loader="$(complete -p -D 2>/dev/null | sed -Ene 's/.* -F ([^ ]*).*/\1/p')" | |
# read in "<alias> '<aliased command>' '<command args>'" lines from defined aliases | |
local line; while read line; do | |
eval "local alias_tokens; alias_tokens=($line)" 2>/dev/null || continue # some alias arg patterns cause an eval parse error | |
local alias_name="${alias_tokens[0]}" alias_cmd="${alias_tokens[1]}" alias_args="${alias_tokens[2]# }" | |
# skip aliases to pipes, boolean control structures and other command lists | |
# (leveraging that eval errs out if $alias_args contains unquoted shell metacharacters) | |
eval "local alias_arg_words; alias_arg_words=($alias_args)" 2>/dev/null || continue | |
# avoid expanding wildcards | |
read -a alias_arg_words <<< "$alias_args" | |
# skip alias if there is no completion function triggered by the aliased command | |
if [[ ! " ${completions[*]} " =~ " $alias_cmd " ]]; then | |
if [[ -n "$completion_loader" ]]; then | |
# force loading of completions for the aliased command | |
eval "$completion_loader $alias_cmd" | |
# 124 means completion loader was successful | |
[[ $? -eq 124 ]] || continue | |
completions+=($alias_cmd) | |
else | |
continue | |
fi | |
fi | |
local new_completion="$(complete -p "$alias_cmd")" | |
# create a wrapper inserting the alias arguments if any | |
if [[ -n $alias_args ]]; then | |
local compl_func="${new_completion/#* -F /}"; compl_func="${compl_func%% *}" | |
# avoid recursive call loops by ignoring our own functions | |
if [[ "${compl_func#_$namespace::}" == $compl_func ]]; then | |
local compl_wrapper="_${namespace}::${alias_name}" | |
echo "function $compl_wrapper { | |
(( COMP_CWORD += ${#alias_arg_words[@]} )) | |
COMP_WORDS=($alias_cmd $alias_args \${COMP_WORDS[@]:1}) | |
(( COMP_POINT -= \${#COMP_LINE} )) | |
COMP_LINE=\${COMP_LINE/$alias_name/$alias_cmd $alias_args} | |
(( COMP_POINT += \${#COMP_LINE} )) | |
$compl_func | |
}" >> "$tmp_file" | |
new_completion="${new_completion/ -F $compl_func / -F $compl_wrapper }" | |
fi | |
fi | |
# replace completion trigger by alias | |
new_completion="${new_completion% *} $alias_name" | |
echo "$new_completion" >> "$tmp_file" | |
done < <(alias -p | sed -Ene "s/$alias_regex/\1 '\2' '\3'/p") | |
source "$tmp_file" && rm -f "$tmp_file" | |
} | |
function kc() { | |
if [ $# -eq 0 ]; then | |
echo "KUBECONFIG=$KUBECONFIG" | |
return 0 | |
fi | |
if [ $# -ne 1 ]; then | |
echo "Pass path to kubeconfig file as argument" | |
return 1 | |
fi | |
if [[ ! -f $1 ]]; then | |
echo "$1 does not exist" | |
return 1 | |
fi | |
export KUBECONFIG=$(realpath $1) | |
echo "KUBECONFIG=$KUBECONFIG" | |
} | |
_kube_namespaces() | |
{ | |
local curr_arg; | |
curr_arg=${COMP_WORDS[COMP_CWORD]} | |
COMPREPLY=( $(compgen -W "- $(/usr/bin/kubectl get namespaces -o=jsonpath='{range .items[*].metadata.name}{@}{"\n"}{end}')" -- $curr_arg ) ); | |
} | |
complete -F _kube_namespaces kubens kns | |
_kube_contexts() | |
{ | |
local curr_arg; | |
curr_arg=${COMP_WORDS[COMP_CWORD]} | |
COMPREPLY=( $(compgen -W "- $(/usr/bin/kubectl config get-contexts --output='name')" -- $curr_arg ) ); | |
} | |
complete -F _kube_contexts kubectx kctx | |
function kubectxadd() { | |
if [ -f "$1" ]; then | |
KUBECONFIG=~/.kube/config:$1 kubectl config view --flatten=true > ~/.kube/config.new | |
rm ~/.kube/config.old | |
mv ~/.kube/config ~/.kube/config.old | |
mv ~/.kube/config.new ~/.kube/config | |
else | |
echo "$1: no such file or directory" | |
return 1 | |
fi | |
} | |
alias kns='kubens' | |
alias kx='kubectx' | |
alias kw='echo -e "Context: $(kx -c)\nNamespace: $(kns -c)"' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Additionally install https://github.com/ahmetb/kubectl-aliases