From f52379814146e6ad5b0dc86727a534dafe42abd8 Mon Sep 17 00:00:00 2001 From: stefanSpectro Date: Tue, 16 Jun 2026 08:55:56 -0600 Subject: [PATCH] rbac check on namespaces when gathering bundle --- support-bundle/support-bundle-infra.sh | 98 ++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/support-bundle/support-bundle-infra.sh b/support-bundle/support-bundle-infra.sh index 3c3daf1..a034281 100755 --- a/support-bundle/support-bundle-infra.sh +++ b/support-bundle/support-bundle-infra.sh @@ -283,6 +283,103 @@ function techo() { echo "$(timestamp): $*" } +function can-list-pods-in-namespace() { + local NS="$1" + [[ "$(kubectl auth can-i list pods -n "$NS" 2>/dev/null)" == "yes" ]] +} + +function rbac-error-message() { + local NS_LIST="$*" + cat </dev/null 2>&1; then + techo "ERROR: Cannot list namespaces — check ClusterRole/Role attached to the user running the script." + techo "Action: Ensure the user can list namespaces (verbs: get, list on resource namespaces)." + cleanup + exit 1 + fi + + for NS in "${SYSTEM_NAMESPACES[@]}"; do + if ! kubectl get ns "$NS" >/dev/null 2>&1; then + SKIPPED_NAMESPACES+=("${NS}|namespace not found") + continue + fi + + if ! can-list-pods-in-namespace "$NS"; then + RBAC_FAILURES+=("$NS") + continue + fi + + COLLECT_NAMESPACES+=("$NS") + done + + { + echo "Namespace Coverage Summary" + echo "Generated: $(timestamp)" + echo "" + printf "%-12s %-40s %s\n" "STATUS" "NAMESPACE" "NOTES" + printf "%-12s %-40s %s\n" "------" "---------" "-----" + for NS in "${COLLECT_NAMESPACES[@]}"; do + printf "%-12s %-40s %s\n" "COLLECT" "$NS" "accessible" + done + for ENTRY in "${SKIPPED_NAMESPACES[@]}"; do + NS="${ENTRY%%|*}" + REASON="${ENTRY#*|}" + printf "%-12s %-40s %s\n" "SKIP" "$NS" "$REASON" + done + for NS in "${RBAC_FAILURES[@]}"; do + printf "%-12s %-40s %s\n" "DENIED" "$NS" "cannot list pods (RBAC)" + done + echo "" + echo "Namespaces to collect: ${#COLLECT_NAMESPACES[@]}" + echo "Namespaces skipped: ${#SKIPPED_NAMESPACES[@]}" + if [[ ${#RBAC_FAILURES[@]} -gt 0 ]]; then + echo "Namespaces denied: ${#RBAC_FAILURES[@]}" + fi + } | tee "${TMPDIR}/namespace-coverage.txt" + + techo "Namespace coverage summary written to namespace-coverage.txt" + + if [[ ${#RBAC_FAILURES[@]} -gt 0 ]]; then + rbac-error-message "${RBAC_FAILURES[*]}" + cleanup + exit 1 + fi + + if [[ ${#COLLECT_NAMESPACES[@]} -eq 0 ]]; then + techo "ERROR: No namespaces available for collection after coverage validation." + techo "Action: Verify cluster access and that at least one targeted namespace exists and is accessible." + cleanup + exit 1 + fi + + SYSTEM_NAMESPACES=("${COLLECT_NAMESPACES[@]}") +} + function setup() { TMPDIR_BASE=$(mktemp -d $MKTEMP_BASEDIR) || { techo 'Creating temporary directory failed, please check options'; exit 1; } techo "Created temporary directory: $TMPDIR_BASE" @@ -374,6 +471,7 @@ done is-kubeconfig-set || { echo "KUBECONFIG is not set. Unable to collect Kubernetes logs."; cleanup; exit 1; } spectro-k8s-defaults setup +validate-namespace-coverage k8s-resources mongo-status archive