kubectl-plugins/src/ls/kubels
2024-06-05 23:24:12 +08:00

197 lines
5.1 KiB
Bash
Executable File

#!/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 <<EOF
USAGE:
$SELF <kubectl-cmdargs...>: 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} $@