init-kubels
This commit is contained in:
parent
4458af7964
commit
94919337b7
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,4 +5,4 @@
|
|||||||
|
|
||||||
# Folders
|
# Folders
|
||||||
_output
|
_output
|
||||||
|
release
|
||||||
|
29
Makefile
29
Makefile
@ -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/$*/
|
||||||
|
@ -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
|
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"
|
||||||
@ -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
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
|
# 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
|
@ -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