1 changed files with 196 additions and 0 deletions
@ -0,0 +1,196 @@ |
|||||||
|
#!/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/>. |
||||||
|
# |
||||||
|
|
||||||
|
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() { |
||||||
|
echo -e "$(basename "$0") is a wrapper for \`kubectl proxy' command which shows links to resources.\n" |
||||||
|
echo -e "USAGE: $(basename "$0" | tr '-' ' ') [all|pods|services] [standard kubectl selectors]\n" |
||||||
|
|
||||||
|
echo -e "Command line arguments:" |
||||||
|
echo -e " -h --help show this help" |
||||||
|
echo -e " -hl --hyperlinks use terminal emulator's hyperlinks feature" |
||||||
|
|
||||||
|
echo |
||||||
|
echo -e "Basic selectors:" |
||||||
|
echo -e " all pods and services" |
||||||
|
echo -e " po pod pods pods" |
||||||
|
echo -e " svc service services services" |
||||||
|
|
||||||
|
echo |
||||||
|
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 |
||||||
|
|
Loading…
Reference in new issue