diff --git a/fubectl.source b/fubectl.source index f08654d..b1f05e8 100755 --- a/fubectl.source +++ b/fubectl.source @@ -14,7 +14,7 @@ else # hack for Msys2 shell, where fzf doesn't support mintty alias _inline_fzf_nh="fzf --multi --ansi -i -1 --reverse -0 --inline-info" fi -_isClusterSpaceObject() { +function _isClusterSpaceObject() { # caller is responsible for assuring non-empty "$1" obj="$1" kubectl api-resources --namespaced=false \ @@ -45,13 +45,13 @@ alias kwall="watch kubectl get pods --all-namespaces" alias kp="xdg-open 'http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/' & kubectl proxy" # [kwatchn] watch a resource of KIND in current namespace, usage: kwatchn [KIND] - if KIND is empty then pod is used -kwatchn() { +function kwatchn() { local kind="${1:-pod}" kubectl get "${kind}" | _inline_fzf | awk '{print $1}' | xargs -r watch kubectl get "${kind}" } # [kwatch] watch a resource of KIND in cluster, usage: kwatch [KIND] - if KIND is empty then pod is used -kwatch() { +function kwatch() { local kind="${1:-pod}" if _isClusterSpaceObject "$kind" ; then kubectl get "${kind}" | _inline_fzf | awk '{print $1}' | xargs -r watch kubectl get "${kind}" @@ -61,7 +61,7 @@ kwatch() { } # [kcmd] create a pod from IMAGE (ubuntu by default) and execute CMD (bash by default), usage: kcmd [CMD] [IMAGE] -kcmd() { +function kcmd() { local cmd="$1" local image="${2:-ubuntu}" local ns="$(kubectl get ns | _inline_fzf | awk '{print $1}')" @@ -73,25 +73,25 @@ kcmd() { } # [kube_ctx_name] get the current context -kube_ctx_name() { +function kube_ctx_name() { kubectl config current-context } # [kube_ctx_namespace] get current namespace -kube_ctx_namespace() { +function kube_ctx_namespace() { local default_ns="$(kubectl config view --minify|grep namespace: |sed 's/namespace: //g'|tr -d ' ')" default_ns="${default_ns:-default}" echo "$default_ns" } # [kgetn] get resource of KIND from current namespace, usage: kgetn [KIND] - if KIND is empty then pod is used -kgetn() { +function kgetn() { local kind="${1:-pod}" kubectl get "$kind" | _inline_fzf | awk '{print $1}' | xargs -r kubectl get -o yaml "$kind" } # [kget] get resource of KIND from cluster, usage: kget [KIND] - if KIND is empty then pod is used -kget() { +function kget() { local kind="${1:-pod}" if _isClusterSpaceObject "$kind" ; then kubectl get "$kind" | _inline_fzf | awk '{print $1}' | xargs -r kubectl get -o yaml "$kind" @@ -101,7 +101,7 @@ kget() { } # [kexp] as former `--export` field removes unwanted metadata - usage: COMMAND | kexp -kexp() { +function kexp() { if [ -t 0 ]; then echo "kexp has no piped input!" echo "usage: COMMAND | kexp" @@ -112,18 +112,18 @@ kexp() { } # [kget-exp] get a resource by its YAML as former `--export` flag -kget-exp() { +function kget-exp() { kget "$@" | kexp } # [kedn] edit resource of KIND from current namespace, usage: kedn [KIND] - if KIND is empty then pod is used -kedn() { +function kedn() { local kind="${1:-pod}" kubectl edit "${kind}" "$(kubectl get "${kind}" | _inline_fzf | awk '{print $1}')" } # [ked] edit resource of KIND from cluster, usage: ked [KIND] - if KIND is empty then pod is used -ked() { +function ked() { local kind="${1:-pod}" local edit_args if _isClusterSpaceObject $kind ; then @@ -135,13 +135,13 @@ ked() { } # [kdesn] describe resource of KIND in current namespace, usage: kdesn [KIND] - if KIND is empty then pod is used -kdesn() { +function kdesn() { local kind="${1:-pod}" kubectl get "$kind" | _inline_fzf | awk '{print $1}' | xargs -r kubectl describe "$kind" } # [kdes] describe resource of KIND in cluster, usage: kdes [KIND] - if KIND is empty then pod is used -kdes() { +function kdes() { local kind="${1:-pod}" if _isClusterSpaceObject "$kind" ; then kubectl get "$kind" | _inline_fzf | awk '{print $1}' | xargs -r kubectl describe "$kind" @@ -151,13 +151,13 @@ kdes() { } # [kdeln] delete resource of KIND in current namespace, usage: kdeln [KIND] - if KIND is empty then pod is used -kdeln() { +function kdeln() { local kind="${1:-pod}" kubectl get "$kind" | _inline_fzf | awk '{print $1}' | xargs -r -p kubectl delete "$kind" } # [kdel] delete resource of KIND in cluster, usage: kdel [KIND] - if KIND is empty then pod is used -kdel() { +function kdel() { local kind="${1:-pod}" if _isClusterSpaceObject "$kind" ; then kubectl get "$kind" | _inline_fzf | awk '{print $1}' | xargs -r -p kubectl delete "$kind" @@ -166,7 +166,7 @@ kdel() { fi } -_klog_usage() { +function _klog_usage() { cat <<'EOF' Usage: klog[n] [LINECOUNT] [options] @@ -176,7 +176,7 @@ EOF } # [klogn] fetch log from container in current namespace -klogn() { +function klogn() { [ "$1" = "--help" ] && _klog_usage && return local line_count=10 if [[ $1 =~ ^[-]{0,1}[0-9]+$ ]]; then @@ -192,7 +192,7 @@ klogn() { } # [klog] fetch log from container in the cluster -klog() { +function klog() { [ "$1" = "--help" ] && _klog_usage && return local line_count=10 if [[ $1 =~ ^[-]{0,1}[0-9]+$ ]]; then @@ -208,7 +208,7 @@ klog() { } # [kkonfig] select a file in current directory and set it as $KUBECONFIG -kkonfig() { +function kkonfig() { local kubeconfig kubeconfig=$(_inline_fzf_nh) || return export KUBECONFIG=$PWD/$kubeconfig @@ -216,7 +216,7 @@ kkonfig() { } # [kexn] execute command in container from current namespace, usage: kexn CMD [ARGS] -kexn() { +function kexn() { [ -z "$1" ] && printf "kexn: missing argument(s).\nUsage: kexn CMD [ARGS]\n" && return 255 local arg_pair=$(kubectl get po | _inline_fzf | awk '{print $1}') [ -z "$arg_pair" ] && printf "kexn: no pods found. no execution.\n" && return @@ -226,7 +226,7 @@ kexn() { } # [kex] execute command in container from cluster, usage: kex CMD [ARGS] -kex() { +function kex() { [ -z "$1" ] && printf "kex: missing argument(s).\nUsage: kex CMD [ARGS]\n" && return 255 local arg_pair=$(kubectl get po --all-namespaces | _inline_fzf | awk '{print $1, $2}') [ -z "$arg_pair" ] && printf "kex: no pods found. no execution.\n" && return @@ -236,7 +236,7 @@ kex() { } # [kforn] port-forward a container port from current namesapce, usage: kforn LOCAL_PORT:CONTAINER_PORT -kforn() { +function kforn() { local port="$1" [ -z "$port" ] && printf "kforn: missing argument.\nUsage: kforn LOCAL_PORT:CONTAINER_PORT\n" && return 255 local arg_pair="$(kubectl get po | _inline_fzf | awk '{print $1}')" @@ -245,7 +245,7 @@ kforn() { } # [kfor] port-forward a container port from cluster, usage: kfor LOCAL_PORT:CONTAINER_PORT -kfor() { +function kfor() { local port="$1" [ -z "$port" ] && printf "kfor: missing argument.\nUsage: kfor LOCAL_PORT:CONTAINER_PORT\n" && return 255 local arg_pair="$(kubectl get po --all-namespaces | _inline_fzf | awk '{print $1, $2}')" @@ -254,7 +254,7 @@ kfor() { } # [ksearch] search for string in resources -ksearch() { +function ksearch() { local search_query="$1" [ -z "$search_query" ] && printf "ksearch: missing argument.\nUsage: ksearch SEARCH_QUERY\n" && return 255 for ns in $(kubectl get --export -o=json ns | jq -r '.items[] | .metadata.name'); do @@ -271,13 +271,13 @@ ksearch() { alias kcl='kubectl config get-contexts' # [kcs] context set -kcs() { +function kcs() { local context="$(kubectl config get-contexts | _inline_fzf | cut -b4- | awk '{print $1}')" kubectl config set current-context "${context}" } # [kcns] context set default namespace -kcns() { +function kcns() { local ns="$1" if [ -z "$ns" ]; then ns="$(kubectl get ns | _inline_fzf | awk '{print $1}')" @@ -287,14 +287,14 @@ kcns() { } # [kwns] watch pods in a namespace -kwns() { +function kwns() { local ns=$(kubectl get ns | _inline_fzf | awk '{print $1}') [ -z "$ns" ] && printf "kcns: no namespace selected/found.\nUsage: kwns\n" && return watch kubectl get pod -n "$ns" } # [ktreen] prints a tree of k8s objects from current namespace, usage: ktreen [KIND] -ktreen() { +function ktreen() { local kind="$1" if [ -z "$kind" ]; then local kind="$(kubectl api-resources -o name | _inline_fzf | awk '{print $1}')" @@ -303,7 +303,7 @@ ktreen() { } # [ktree] prints a tree of k8s objects from cluster, usage: ktree [KIND] -ktree() { +function ktree() { local kind="$1" if [ -z "$kind" ]; then local kind="$(kubectl api-resources -o name | _inline_fzf | awk '{print $1}')" @@ -316,7 +316,7 @@ ktree() { } # [konsole] create root shell on a node -konsole() { +function konsole() { local node_hostname="$(kubectl get node --label-columns=kubernetes.io/hostname | _inline_fzf | awk '{print $6}')" local ns="$(kubectl get ns | _inline_fzf | awk '{print $1}')" local name=shell-$RANDOM @@ -367,14 +367,14 @@ konsole() { } # [ksecn] decode a value from a secret in current namespace, usage: ksecn -ksecn() { +function ksecn() { local secret=$(kubectl get secret | _inline_fzf | awk '{print $1}') local key=$(kubectl get secret "${secret}" -o go-template='{{- range $k,$v := .data -}}{{- printf "%s\n" $k -}}{{- end -}}' | _inline_fzf_nh) kubectl get secret "${secret}" -o go-template='{{ index .data "'$key'" | base64decode }}' } # [ksec] decode a value from a secret in cluster, usage: ksec -ksec() { +function ksec() { local ns=$(kubectl get ns | _inline_fzf | awk '{print $1}') local secret=$(kubectl get secret -n "$ns" | _inline_fzf | awk '{print $1}') local key=$(kubectl get secret -n "$ns" "$secret" -o go-template='{{- range $k,$v := .data -}}{{- printf "%s\n" $k -}}{{- end -}}' | _inline_fzf_nh) @@ -382,18 +382,18 @@ ksec() { } # [kinstall] Install the required kubectl plugins -kinstall() { +function kinstall() { kubectl krew install tree kubectl krew install neat } # [kupdate] Updates kubectl plugins -kupdate() { +function kupdate() { kubectl krew upgrade } #### Kubermatic KKP specific # [kkp-cluster] Kubermatic KKP - extracts kubeconfig of user cluster and connects it in a new bash -kkp-cluster() { +function kkp-cluster() { TMP_KUBECONFIG=$(mktemp) local cluster="$(kubectl get cluster | _inline_fzf | awk '{print $1}')" kubectl get secret admin-kubeconfig -n cluster-$cluster -o go-template='{{ index .data "kubeconfig" | base64decode }}' > $TMP_KUBECONFIG @@ -401,7 +401,7 @@ kkp-cluster() { } # [khelp] show this help message -khelp() { +function khelp() { echo "Usage of fubectl" echo echo "Reduces repetitive interactions with kubectl"