197 lines
5.1 KiB
Bash
Executable File
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} $@
|