init-kubels

This commit is contained in:
bryan 2024-06-04 19:41:39 +08:00
parent 4458af7964
commit 94919337b7
8 changed files with 223 additions and 156 deletions

2
.gitignore vendored
View File

@ -5,4 +5,4 @@
# Folders # Folders
_output _output
release

View File

@ -5,18 +5,27 @@ SHELL=/bin/bash
################################################### ###################################################
APPNAME ?= kubectl-plslogs APPNAME ?= kubectl-plugins
APPVERSION ?= v0.1.0 APPVERSION ?= v0.1.0
PKGNAME ?= $(APPNAME)-$(APPVERSION).tar.gz
BUILD_DIR = $(shell pwd) PLUGINS=ls
TEMP_OUTPUT_DIR = $(shell pwd)/_output/$(APPNAME) PLUGINS_BUILD=$(foreach plugin, $(PLUGINS), build-${plugin})
PLUGINS_CLEAN=$(foreach plugin, $(PLUGINS), clean-${plugin})
PLUGINS_RELEASE=$(foreach plugin, $(PLUGINS), release-${plugin})
build-plslogs:
make build -C src/plslogs/
release-plslogs: all: release
make release -C src/plslogs/
clean: build: $(PLUGINS_BUILD)
make clean -C src/plslogs/ clean: $(PLUGINS_CLEAN)
release: $(PLUGINS_RELEASE)
build-%:
make build -C src/$*/
release-%:
make release -C src/$*/
clean-%:
make clean -C src/$*/

View File

@ -1,28 +0,0 @@
apiVersion: krew.googlecontainertools.github.com/v1alpha2
kind: Plugin
metadata:
name: plslogs
spec:
homepage: https://git.qoobing.com/opensource/kubernetes/kubectl-plugins.git
shortDescription: "pls(pod list select) and then logs(kubectl logs)"
version: "v0.1.0"
description: |
Provide a simple tools for logs pod without 'copy' pod name.
It show a pod list first and after you choose one,
and it will execute 'kubectl logs --tail 100 -f $selectpod'
platforms:
- selector:
matchExpressions:
- key: "os"
operator: "In"
values:
- darwin
- linux
uri: https://github.com/morningspace/kubeassert/archive/v0.2.0.tar.gz
sha256: a35b62a111212a74c954f2991fdfa7b4cad8e92b9318773f87c9ff8c12a5ea52
bin: kubectl-assert.sh
files:
- from: "/kubeassert-*/kubectl-assert.sh"
to: "."
- from: "/kubeassert-*/LICENSE"
to: "."

View File

@ -5,14 +5,15 @@ SHELL=/bin/bash
################################################### ###################################################
APPNAME ?= kubectl-plslogs APPNAME ?= kubels
APPVERSION ?= v0.1.0 APPVERSION ?= v0.1.0
PKGNAME ?= $(APPNAME)-$(APPVERSION).tar.gz PKGNAME ?= $(APPNAME)-$(APPVERSION).tar.gz
BUILD_DIR = $(shell pwd) BUILD_DIR = $(shell pwd)
TEMP_OUTPUT_DIR = $(shell pwd)/_output/$(APPNAME)-$(APPVERSION) TEMP_OUTPUT_DIR = $(shell pwd)/_output/$(APPNAME)-$(APPVERSION)
build:
build:
@echo -e "======\033[44m start to build binary... \033[0m" @echo -e "======\033[44m start to build binary... \033[0m"
@echo -e "BUILD do NOTHING" @echo -e "BUILD do NOTHING"
@echo -e "\033[42mbuild binary done\033[0m" @echo -e "\033[42mbuild binary done\033[0m"
@ -25,7 +26,7 @@ package:
mkdir -p $(TEMP_OUTPUT_DIR)/ >/dev/null 2>&1 mkdir -p $(TEMP_OUTPUT_DIR)/ >/dev/null 2>&1
echo -e "clean old output directory done" echo -e "clean old output directory done"
@echo -e "======\033[44m start to copy files to output directory...\033[0m" @echo -e "======\033[44m start to copy files to output directory...\033[0m"
cp -rL $(BUILD_DIR)/plslogs.sh $(TEMP_OUTPUT_DIR)/ cp -rL $(BUILD_DIR)/kubels $(TEMP_OUTPUT_DIR)/
cp -rL $(BUILD_DIR)/LICENSE $(TEMP_OUTPUT_DIR)/ cp -rL $(BUILD_DIR)/LICENSE $(TEMP_OUTPUT_DIR)/
@echo -e "copy files to \"$(TEMP_OUTPUT_DIR)\" done" @echo -e "copy files to \"$(TEMP_OUTPUT_DIR)\" done"
@echo -e "======\033[34m start to package tar...\033[0m" @echo -e "======\033[34m start to package tar...\033[0m"

188
src/ls/kubels Executable file
View File

@ -0,0 +1,188 @@
#!/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" =~ 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} $@

View File

@ -12,12 +12,16 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
name: "plslogs" name: "kubels"
shortDesc: "Get logs for a pod from list" shortDesc: "List and Select pods/svc/cm to do something"
longDesc: > longDesc: >
Display list of all pods to select from. Display the list of all pods to select from.
If pod has multiple containers, another list is shown to choose from. If have no pod, exit directly.
If only one pod, auth select it then do kubectl command.
If more than one pod, show a select promt first.
Example: Example:
kubectl plugin plslogs kubels get pod
kubectl plugin plslogs -n kube-system kubels get pod -n kube-system
command: ./plslogs.sh kubels exec -it -- bash
kubels logs --tail 100
command: ./kubels

View File

@ -1,107 +0,0 @@
#!/usr/bin/env bash
function _kube_parse_args() {
# We use "${@}" instead of "${*}" to preserve argument-boundary information
options=''
args=$(getopt --options ':n:f:' --longoptions ':namespace:,tail:' -- "${@}") || exit
eval "set -- ${args}"
while true; do
case "${1}" in
(-v | --verbose)
((verbose++))
shift
;;
(-a | --article)
article=${2}
shift 2
;;
(-l | --lang | --language)
# handle optional: getopt normalizes it into an empty string
if [[ -n ${2} ]] ; then
lang=${2}
fi
shift 2
;;
(--)
shift
break
;;
(*)
exit 1 # error
;;
esac
done
remaining_args=("${@}")
}
function _kube_list_pods() {
NS_ARG="" #"--all-namespaces"
[[ -n "$1" ]] && NS_ARG="-n ${1}"
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}}'
IFS=';'
read -ra pods <<< "$(kubectl get pods $NS_ARG -o go-template="$GO_TPL" | sort -k 2 -k 1 -t: | tr '\n' ';')"
local count=1
lines=$(for i in ${pods[@]}; do
IFS=":" read -ra TOKS <<< "${i}"
printf " $count) ${TOKS[0]}\t${TOKS[1]}\t${TOKS[2]}\n"
((count=count+1))
done | column -t)
count=$(echo "$lines" | wc -l)
echo "$lines" >&2
local sel=0
while [[ $sel -lt 1 || $sel -gt $count ]]; do
read -p "Select a Pod: " sel >&2
done
echo "${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)]}"
}
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} $@