Refactored tcdbinfo.sh to be based on `jq`

This commit is contained in:
Lockszmith 2023-07-12 00:46:12 -04:00
parent 121ac483ca
commit fc0115f8cb
1 changed files with 144 additions and 23 deletions

View File

@ -1,28 +1,149 @@
#!/bin/bash
#! /usr/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
USER_HOME=$HOME
[[ -n "${SUDO_USER}" ]] && USER_HOME="$(eval "echo ~${SUDO_USER}")"
. ${SHRC_D:-$SCRIPT_DIR}/01_util.functions
# get namespaces
namespaces=$(k3s kubectl get secrets -A | grep -E "dbcreds|cnpg-main-urls" | awk '{print $1, $2}')
set -e
# iterate over namespaces
( printf "Application | Username | Password | Address | Port\n"
echo "$namespaces" | while read ns secret; do
# extract application name
app_name=$(echo "$ns" | sed 's/^ix-//')
if [ "$secret" = "dbcreds" ]; then
creds=$(k3s kubectl get secret/$secret --namespace "$ns" -o jsonpath='{.data.url}' | base64 -d)
else
creds=$(k3s kubectl get secret/$secret --namespace "$ns" -o jsonpath='{.data.std}' | base64 -d)
JSON=0
if [[ $# -gt 0 && "$1" =~ ^-- ]]; then
if [[ "$1" == "--help" ]]; then
cat <<USAGE
Usage:
./tcdbinfo.sh --help
sudo ./tcdbinfo.sh [--json|--cols=<columns>] [app1] [app...]
Description:
When running the script (as root) without any arguments, it will list
all TrueChart apps with database credential secrets.
The scope can be narrowed by passing app name arguments.
The FIRST argument, however, will affect the output:
--help - Display this usage text.
--json - Output all fields in JSON format
--cols=<columns> - Where <columns> can be empty, a preset name or
a comma delimited list of columns.
An empty string will show the default preset.
Presets:
default - The default preset
safe - Similar to the default, but without
the password column
debug - Full connection URL with password
masked with asterisks ('******')
Columns:
name - App name, preceding with ix-
raw_url - DB connection URL as it is stored
in kubernetes secrets.
This can only be used within the
same pod
url - Fully formed URL.
safeurl - Same as url, with password masked.
protocol - Connection protocol.
username - DB Username
password - Password
pwd_len - Password length
host - Hostname
port - Conection Port
dbname - DB name
When '--cols' is not specified, default behavious can be overridden
by exporting the TCDBCOLS envrionment variable.
--cols takes presedence, and overrides any behavior dictated by the
environment variable
USAGE
exit 0
elif [[ "$1" == "--json" ]]; then
JSON=1
elif [[ "$1" =~ ^--cols ]]; then
[[ "$1" =~ ^--cols= ]] || shift
TCDBCOLS="${1#--cols=}"
fi
shift
fi
TCDBCOLS="${TCDBCOLS:-default}"
case "$TCDBCOLS" in
'default' )
TCDBCOLS='name,protocol,username,password,pwd_len,host,port,dbname'
;;
'safe' )
TCDBCOLS='name,protocol,username,pwd_len,host,port,dbname'
;;
'debug' )
TCDBCOLS='name,safeurl'
;;
esac
# get username, password, addresspart, and port
username=$(echo "$creds" | awk -F '//' '{print $2}' | awk -F ':' '{print $1}')
password=$(echo "$creds" | awk -F ':' '{print $3}' | awk -F '@' '{print $1}')
addresspart=$(echo "$creds" | awk -F '@' '{print $2}' | awk -F ':' '{print $1}')
port=$(echo "$creds" | awk -F ':' '{print $4}' | awk -F '/' '{print $1}')
require_root
# construct full address
full_address="${addresspart}.${ns}.svc.cluster.local"
QUERY_NAMESPACE=' -A'
[[ $# -eq 0 ]] || QUERY_NAMESPACE=$( printf -- ' --namespace=ix-%s' "${@}" )
jqcode='
.items[] | select(.metadata.name|test("(dbcreds|cnpg-main-urls)$$"))
| {
"name": .metadata.namespace,
"app": .metadata.labels."app.kubernetes.io/instance",
"url": (if .data.url != null then .data.url else .data.std end) | @base64d,
"data": (
(if .data.url != null then .data.url else .data.std end) |
@base64d |
match("(.*)://(.+):(.+)@([^:]+)(:(\\d+))?/(.*)$") | .captures | {
"protocol": .[0].string,
"username": .[1].string,
"password": .[2].string,
"passwordlen": .[2].string | length,
"host": .[3].string,
"safeport": .[4].string,
"port": .[5].string,
"dbname": .[6].string,
}
)
} | {
"name": .name,
"raw_url": .url,
"url": "\(.data.protocol)://\(.data.username)@\(.data.password):\(.data.host).\(.name).svc.cluster.local\(.data.safeport)/\(.data.dbname)",
"safeurl": "\(.data.protocol)://\(.data.username)@*******:\(.data.host).\(.name).svc.cluster.local\(.data.safeport)/\(.data.dbname)",
"protocol": .data.protocol,
"username": .data.username,
"password": .data.password,
"pwd_len": .data.passwordlen,
"host": "\(.data.host).\(.name).svc.cluster.local",
"port": .data.port,
"dbname": .data.dbname
}
'
json_results=$(
<<<"${QUERY_NAMESPACE}" \
xargs -n1 k3s kubectl \
get secrets \
--output json \
| jq "$jqcode"
)
[[ "$JSON" -eq 1 ]] && echo "$json_results" && exit 0
JQ_COLS="[$( <<<"\"$TCDBCOLS\"" \
jq -r '. | split(",") | map( "\"\(.)\"" ) | join(",")'
)]"
JQ_COLS_REGEX="$( <<<"$JQ_COLS" \
jq -r '. | map ( ".\(.)" ) | join(",")'
)"
jqcode='
['"${JQ_COLS^^}"'] + [.[] |
['"$JQ_COLS_REGEX"']
] | .[] | join("|")
'
<<<"$json_results" jq -s '.' | jq -r "$jqcode" | column -t -s "|"
exit 0
# print results with aligned columns
printf "%s | %s | %s | %s | %s\n" "$app_name" "$username" "$password" "$full_address" "$port"
done ) | column -t -s "|"