init-kubels
This commit is contained in:
parent
4458af7964
commit
94919337b7
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,4 +5,4 @@
|
||||
|
||||
# Folders
|
||||
_output
|
||||
|
||||
release
|
||||
|
29
Makefile
29
Makefile
@ -5,18 +5,27 @@ SHELL=/bin/bash
|
||||
###################################################
|
||||
|
||||
|
||||
APPNAME ?= kubectl-plslogs
|
||||
APPNAME ?= kubectl-plugins
|
||||
APPVERSION ?= v0.1.0
|
||||
PKGNAME ?= $(APPNAME)-$(APPVERSION).tar.gz
|
||||
|
||||
BUILD_DIR = $(shell pwd)
|
||||
TEMP_OUTPUT_DIR = $(shell pwd)/_output/$(APPNAME)
|
||||
PLUGINS=ls
|
||||
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:
|
||||
make release -C src/plslogs/
|
||||
all: release
|
||||
|
||||
clean:
|
||||
make clean -C src/plslogs/
|
||||
build: $(PLUGINS_BUILD)
|
||||
clean: $(PLUGINS_CLEAN)
|
||||
release: $(PLUGINS_RELEASE)
|
||||
|
||||
|
||||
build-%:
|
||||
make build -C src/$*/
|
||||
|
||||
release-%:
|
||||
make release -C src/$*/
|
||||
|
||||
clean-%:
|
||||
make clean -C src/$*/
|
||||
|
@ -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: "."
|
@ -5,13 +5,14 @@ SHELL=/bin/bash
|
||||
###################################################
|
||||
|
||||
|
||||
APPNAME ?= kubectl-plslogs
|
||||
APPNAME ?= kubels
|
||||
APPVERSION ?= v0.1.0
|
||||
PKGNAME ?= $(APPNAME)-$(APPVERSION).tar.gz
|
||||
|
||||
BUILD_DIR = $(shell pwd)
|
||||
TEMP_OUTPUT_DIR = $(shell pwd)/_output/$(APPNAME)-$(APPVERSION)
|
||||
|
||||
|
||||
build:
|
||||
@echo -e "======\033[44m start to build binary... \033[0m"
|
||||
@echo -e "BUILD do NOTHING"
|
||||
@ -25,7 +26,7 @@ package:
|
||||
mkdir -p $(TEMP_OUTPUT_DIR)/ >/dev/null 2>&1
|
||||
echo -e "clean old output directory done"
|
||||
@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)/
|
||||
@echo -e "copy files to \"$(TEMP_OUTPUT_DIR)\" done"
|
||||
@echo -e "======\033[34m start to package tar...\033[0m"
|
188
src/ls/kubels
Executable file
188
src/ls/kubels
Executable 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} $@
|
@ -12,12 +12,16 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: "plslogs"
|
||||
shortDesc: "Get logs for a pod from list"
|
||||
name: "kubels"
|
||||
shortDesc: "List and Select pods/svc/cm to do something"
|
||||
longDesc: >
|
||||
Display list of all pods to select from.
|
||||
If pod has multiple containers, another list is shown to choose from.
|
||||
Display the list of all pods to select 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:
|
||||
kubectl plugin plslogs
|
||||
kubectl plugin plslogs -n kube-system
|
||||
command: ./plslogs.sh
|
||||
kubels get pod
|
||||
kubels get pod -n kube-system
|
||||
kubels exec -it -- bash
|
||||
kubels logs --tail 100
|
||||
command: ./kubels
|
@ -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} $@
|
Loading…
Reference in New Issue
Block a user