#!/usr/bin/env bash ####################################################### # ####################################################### [[ -n ${DEBUG} ]] && set -x set -eou pipefail KUBECTL=kubectl usage() { local SELF SELF="kubels" if [[ "$(basename "$0")" == kubectl-* ]]; then # invoked as plugin SELF="kubectl ls" fi cat <: list & select pods/svc/cm to do something, for example: $SELF get pod $SELF get pod -n kube-system $SELF exec -it -- bash $SELF logs --tail 100 $SELF -h,--help : show this message EOF } exit_err() { echo >&2 "${1}" exit 1 } function main() { _kube_parse_args "$@" local act=${1-""} local res=${2-""} if [[ "$act" =~ -h|--help|help ]]; then usage exit 0 elif [[ "$act $res" == "logs " ]]; then _kube_list_pods "$cur_ns_arg" shift 1 $KUBECTL "$act" "$sel_pod" --tail 100 -f elif [[ "$act $res" == "exec " ]]; then _kube_list_pods "$cur_ns_arg" shift 1 $KUBECTL "$act" "$sel_pod" -it -- sh elif [[ "$act" =~ logs|exec|describe ]]; then _kube_list_pods "$cur_ns_arg" shift 1 $KUBECTL "$act" "$sel_pod" $@ elif [[ "$act $res" =~ "get pod" ]]; then _kube_list_pods "$cur_ns_arg" shift 2 $KUBECTL get pod "$sel_pod" $@; else usage exit 1 fi } function _kube_parse_args() { local ns="" local ns_arg="" local opt="${@}" local args=$(getopt -o ':n:A' -l ':namespace:all-namespaces:' -- "${@}") || exit eval "set -- ${args}" while true; do case "${1}" in -A) ns="" ns_arg="-A" shift 1 ;; -n|--namespace) ns=${2} ns_arg="-n $ns" shift 2 ;; --all-namespace) ns="" ns_arg="-A" shift 2 ;; --) shift break ;; esac done eval "set -- ${opt}" export cur_ns=${ns:=$(_kube_current_namespace)} export cur_ns_arg=${ns_arg:="-n $cur_ns"} } function _kube_list_pods() { local NS_ARG=$1 local GO_TPL="" GO_TPL="$GO_TPL"'{{range .items}}' GO_TPL="$GO_TPL"""'{{.metadata.name}}:' GO_TPL="$GO_TPL"""'{{.metadata.namespace}}:' GO_TPL="$GO_TPL"""'{{.status.phase}}' GO_TPL="$GO_TPL"""'({{range $index, $element := .status.containerStatuses}}' GO_TPL="$GO_TPL"""""'{{if $index}}&{{end}}' GO_TPL="$GO_TPL"""""'{{if .state.waiting}}{{.state.waiting.reason}}{{end}}' GO_TPL="$GO_TPL"""""'{{if .state.running}}Runing{{end}}' GO_TPL="$GO_TPL"""'{{end}})' GO_TPL="$GO_TPL"""'{{"\n"}}' GO_TPL="$GO_TPL"'{{end}}' local pods=(`kubectl get pods $NS_ARG -o go-template="$GO_TPL" | sort -k 2 -k 1 -t:`) local lines=$( local index=1 for p in ${pods[@]}; do IFS=":" read -ra TOKS <<< "${p}" printf " $index) ${TOKS[0]}\t${TOKS[1]}\t${TOKS[2]}\n" ((index=index+1)) done | column -t ) local count=$(echo "$lines" | wc -l) if [ $count -eq 0 ]; then echo "Find $count pods in namespace '$cur_ns', exit." >&2 sel_pod="_NO_POD_FOUNT_" exit 0 elif [ $count -eq 1 ]; then echo "Find $count pods in namespace '$cur_ns', auto select it." >&2 echo "$lines" >&2 sel_pod="${pods[0]%%:*}" return 0 fi echo "Find $count pods in namespace '$cur_ns', please select:" >&2 echo "$lines" >&2 local sel=0 while [[ $sel -lt 1 || $sel -gt $count ]]; do read -p "Select a Pod: " sel >&2 done sel_pod="${pods[(sel-1)]%%:*}" } function _kube_list_pod_containers() { POD=$1 NAMESPACE=$2 IFS=';' read -ra items <<< "$(kubectl get pod ${POD} -n ${NAMESPACE} -o go-template='{{range .spec.containers}}{{.name}}{{"\n"}}{{end}}' | tr '\n' ';')" local count=1 lines=$(for i in ${items[@]}; do printf " $count) ${i}\n" ((count=count+1)) done | column -t) count=$(echo "$lines" | wc -l) if [[ $count -gt 1 ]]; then printf "\nPod has multiple containers:\n" >&2 echo "$lines" >&2 local sel=0 while [[ $sel -lt 1 || $sel -gt $count ]]; do read -p "Select a Container: " sel >&2 done fi echo "${items[(sel-1)]}" } function _kube_current_namespace() { local cur_ctx local command="$KUBECTL config current-context" cur_ctx=$($command) || exit_err "error getting current context" ns="$($KUBECTL config view -o=jsonpath="{.contexts[?(@.name==\"${cur_ctx}\")].context.namespace}")" \ || exit_err "error getting current namespace" if [[ -z "${ns}" ]]; then echo "default" else echo "${ns}" fi } main ${@} ################################################################ ### ### SEL=$(_kube_list_pods) ### IFS=":" read -ra POD <<< "${SEL}" ### ### if [[ ${POD[2]} != Running* ]]; then ### echo "Status:${POD[2]}" >&2 ### echo "ERROR: Pod ${POD[0]} is not running" >&2 ### exit 1 ### fi ### ### SEL=$(_kube_list_pod_containers ${POD[0]} ${POD[1]}) ### ### kubectl -n ${POD[1]} logs --tail 100 "${POD[0]}" -c ${SEL} $@