Various Kubernetes-related scenarios to use as kubectl plug-ins.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
5.2 KiB

#!/usr/bin/env bash
#
# Copyright (C) 2020, Maxim Lihachev, <envrm@yandex.ru>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
: <<'MAN'
=head1 NAME
kubectl-http is a wrapper for I<`kubectl proxy'> command which shows links to resources.
=head1 USAGE
kubectl http [all|pods|services] [standard kubectl selectors]
=head1 OPTIONS
-h --help = show this help
-hl --hyperlinks = use terminal emulator's hyperlinks feature
Basic selectors:
all pods and services
po pod pods pods
svc service services services
=head1 BUGS
If you find a bug, please report it at B<L<https://code.envrm.info/src/scripts-kubernetes>>.
=head1 AUTHORS
envrm B<L<https://code.envrm.info>>.
=cut
MAN
rstc="\033[00m"
blue="\033[1;36m"
green="\033[1;32m"
magenta="\033[1;35m"
red="\033[1;31m"
yellow="\033[1;33m"
USE_HYPERLINKS=false
# Default resource's type to query
TYPE=svc
# Default kubectl's proxy endpoint
PROXY_URL="http://127.0.0.1:8001"
shortname() {
local name_length=${2:-30}
host=${1/:*}
port=${1/*:}
if [ "${#1}" -gt "$name_length" ]; then
echo "$(head -c "$name_length" <<<"$host")~:$port"
else
echo "$1"
fi
}
# Print horizontal rule
hr() {
echo -e -n "$magenta"
printf "%${COLS}s" | sed 's/ /─/g'
echo -e "$rstc"
}
usage() {
sed -E -n '/^.*MAN/,/^MAN$/{//!p;}; /^MAN$/q' "$0" | sed -E 's/=head. |[LIBC]<|\b>*//g; /=cut/d'
exit "${1:-0}"
}
footer() {
>&2 echo
>&2 hr
>&2 echo -e " ${magenta}The index page with the links to resources: ${blue}${PROXY_URL}/index"
>&2 hr
>&2 echo
}
# Remove temporary directory
cleanup() {
rm -rf "$WWW_DIRECTORY"
}
kubectl_get() {
local resource=${1:-svc}
shift
[ $# -eq 0 ] && local filter="-A"
case "$resource" in
all) { kubectl_get pods "$@"; kubectl_get svc "$@"; };;
svc) eval kubectl get svc "$@" "$filter" --no-headers=true \
-o=custom-columns=NAME:.metadata.selfLink,PORTS:.spec.ports[*].port;;
pods) eval kubectl get pod "$@" "$filter" --no-headers=true \
-o=custom-columns=NAME:.metadata.selfLink,PORTS:.spec.containers[*].ports[*].containerPort;;
esac | grep -v '<none>' | sed -E 's/[[:space:]]+/,/g'
}
die() {
>&2 echo -e "${red}ERROR: ${*}${rstc}"
exit 1
}
# Clean up temporary files on exit
trap cleanup EXIT SIGINT SIGHUP SIGQUIT
KUBECTL_ARGS=()
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-h|--help) usage 0;;
-hl|--hyperlinks) USE_HYPERLINKS=true; shift;;
all) TYPE=all; shift;;
po|pod|pods) TYPE=pods; shift;;
svc|service|services) TYPE=svc; shift;;
*) KUBECTL_ARGS+=("$1"); shift;;
esac
done
set -- "${KUBECTL_ARGS[@]}"
# Temporary directory for index.html file
WWW_DIRECTORY=$(mktemp -d --tmpdir=/tmp KUBE_PROXY.XXXXXXXX)
COLS=$(tput cols)
declare -a SERVICES
declare -A URLS
mapfile -t SERVICES <<<"$(kubectl_get "$TYPE" "$@")"
[ "${#SERVICES}" -eq 0 ] && die "No resource found"
for service in "${SERVICES[@]}"; do
svc_url=${service//,*/}
ports=${service#*,}
IFS=','
for port in $ports; do
id="$(cut -d '/' -f 5,6,7 <<<"$svc_url"):${port}"
URLS["$id"]="${PROXY_URL}${svc_url}:${port}/proxy"
done
done
mapfile -d '' SORTED_URLS < <(printf '%s\0' "${!URLS[@]}" | sort -z)
echo
MAX_VAL_LENGTH=$(printf '%s\n' "${URLS[@]}" \
| awk '{ print length }' \
| sort -n -r \
| head -n 1)
MAX_KEY_LENGTH=$(printf '%s\n' "${!URLS[@]}" \
| sed -E 's/\/[^\/]+$//' \
| awk '{ print length }' \
| sort -n -r \
| head -n 1)
# ~ ' - ' + ':' + 5-digit of port + spaces
MAX_NAME_LENGTH=$(( COLS - MAX_KEY_LENGTH - MAX_VAL_LENGTH - 15 ))
for key in "${SORTED_URLS[@]}"; do
printf '<li><a href="%s">%s</a></li>\n' "${URLS[$key]}" "$key" >> "${WWW_DIRECTORY}/index.html"
IFS='/' read -r ns rs name <<<"$key"
if [ "$USE_HYPERLINKS" == "true" ]; then
# Address under hyperlink
echo -e -n "- \e]8;;${URLS[$key]}\e\\\\"
echo -e -n "${magenta}${ns}${rstc}/" # namespace
echo -e -n "${yellow}${rs}${rstc}/" # resource's type
echo -e "${green}${name}${rstc}\e]8;;\e\\" # resource's name
else
# - namespace/service http://127.0.0.1:8001/api/.../service:port/proxy
echo -e -n " - ${magenta}${ns}${rstc}/" # namespace
echo -e -n "${yellow}${rs}${rstc}/" # resource's type
if [ "$MAX_NAME_LENGTH" -gt 10 ]; then
echo -e -n "${green}$(shortname "$name" "$MAX_NAME_LENGTH") " # short resource's name
else
echo -e -n "${green}${name}\n - " # resource's name on the its own line
fi
echo -e "${blue}${URLS[$key]}${rstc}" # API URL
fi
done | column -t
footer
>&2 kubectl proxy --www="$WWW_DIRECTORY" --www-prefix=/index