#!/usr/bin/env bash # Mint a read-only kubeconfig for the cluster-inspector agent. # # Usage: make-kubeconfig.sh [options] # cluster name, e.g. lab-mgmt or lab1 -> kubeconfigs/.kubeconfig # --admin-kubeconfig PATH admin kubeconfig used to apply RBAC / mint the token (default: $KUBECONFIG or ~/.kube/config) # --context CTX context inside the admin kubeconfig # --capi-cluster [NS/]NAME workload cluster: --admin-kubeconfig is the management cluster; the workload # admin kubeconfig is read from Secret NS/NAME-kubeconfig (NS default: default) # into a temp file that is removed on exit # --server URL override API server URL (k3s.yaml says https://127.0.0.1:6443) # --duration DUR token lifetime (default 168h); re-run the script to refresh # --apply-rbac kubectl apply rbac.yaml first (needed once per cluster) set -euo pipefail here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" name=""; admin="${KUBECONFIG:-$HOME/.kube/config}"; ctx=""; capi=""; server=""; duration="168h"; apply=0 while [[ $# -gt 0 ]]; do case "$1" in --admin-kubeconfig) admin="$2"; shift 2 ;; --context) ctx="$2"; shift 2 ;; --capi-cluster) capi="$2"; shift 2 ;; --server) server="$2"; shift 2 ;; --duration) duration="$2"; shift 2 ;; --apply-rbac) apply=1; shift ;; -h|--help) sed -n '2,13p' "$0"; exit 0 ;; -*) echo "unknown option $1" >&2; exit 1 ;; *) name="$1"; shift ;; esac done [[ -n "$name" ]] || { sed -n '2,13p' "$0" >&2; exit 1; } k=(kubectl --kubeconfig "$admin") [[ -n "$ctx" ]] && k+=(--context "$ctx") if [[ -n "$capi" ]]; then ns="default"; cluster="$capi" [[ "$capi" == */* ]] && { ns="${capi%%/*}"; cluster="${capi#*/}"; } workload="$(mktemp)" # mktemp creates it 0600 trap 'rm -f "$workload"' EXIT "${k[@]}" -n "$ns" get secret "$cluster-kubeconfig" -o jsonpath='{.data.value}' | base64 -d > "$workload" [[ -s "$workload" ]] || { echo "Secret $ns/$cluster-kubeconfig is empty or missing" >&2; exit 1; } k=(kubectl --kubeconfig "$workload") fi if (( apply )); then "${k[@]}" apply -f "$here/rbac.yaml"; fi token="$("${k[@]}" -n kube-system create token readonly-inspector --duration "$duration")" [[ -n "$server" ]] || server="$("${k[@]}" config view --raw --minify --flatten -o jsonpath='{.clusters[0].cluster.server}')" ca="$("${k[@]}" config view --raw --minify --flatten -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')" [[ -n "$ca" ]] || { echo "no certificate-authority-data in admin kubeconfig" >&2; exit 1; } mkdir -p "$here/kubeconfigs" out="$here/kubeconfigs/$name.kubeconfig" umask 077 cat > "$out" </dev/null || true)" done