Both wrong assessments (#249 openbao 'sealed', #250 three untested hypotheses while one 'kubectl logs' showed the 401) share one root cause: the agents diagnose blind, so they narrate plausible fiction. Labeling unverified claims (previous commit) treats the symptom; this gives them the means to verify: - kubernetes/apps/monitoring/ci-diagnostics-rbac.yaml: ServiceAccount ci-diagnostics with a read-only ClusterRole (workloads, events, pods/log, Flux/ESO/cert-manager/monitoring/ceph CRDs — NO secrets) plus a namespaced services/proxy Role for the Prometheus and Alertmanager HTTP APIs. - scripts/ci/make-diag-kubeconfig.sh: mints a 1h token per run from the admin kubeconfig (no new long-lived secret), builds .ci-diag/kubeconfig, copies the static kubectl binary for the jq-only ci-claude image, smoke-tests with the restricted identity, and degrades to snapshot-only mode when the SA isn't reconciled. - alert-monitor.yml / issue-fix.yml: agents get exactly one extra tool, Bash(./.ci-diag/kubectl:*) — prefix match forbids pipes and any other binary; RBAC forbids mutation and secret reads. - prompts: verification is now mandatory, not aspirational — 'a hypothesis you could have settled with one read-only command but didn't is a defect in your output'; fix agent must test the issue's claims before building on them; minimal-quote rule against dumping logs into public issues. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NV7bZzZLeoFUEdAeCSLEei
43 lines
2.0 KiB
Bash
Executable File
43 lines
2.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build .ci-diag/ in the CI workspace: a short-lived, least-privilege
|
|
# kubeconfig (ServiceAccount monitoring/ci-diagnostics, RBAC in
|
|
# kubernetes/apps/monitoring/ci-diagnostics-rbac.yaml) plus a copy of the
|
|
# kubectl binary, so a later ci-claude step (which ships no kubectl) can run
|
|
# read-only live diagnostics as ./.ci-diag/kubectl.
|
|
#
|
|
# Requires the admin kubeconfig at ~/.kube/config (fetch-kubeconfig.sh).
|
|
# Degrades gracefully: if the ServiceAccount does not exist yet (RBAC not
|
|
# reconciled), it prints a warning and exits 0 — agents then run in
|
|
# snapshot-only mode.
|
|
set -euo pipefail
|
|
|
|
DIAG_DIR=".ci-diag"
|
|
mkdir -p "$DIAG_DIR"
|
|
|
|
if ! TOKEN=$(kubectl -n monitoring create token ci-diagnostics --duration=1h 2>/dev/null); then
|
|
echo "WARNING: could not mint a ci-diagnostics token (ServiceAccount missing" \
|
|
"or no permission) — no $DIAG_DIR/kubeconfig, agents run snapshot-only."
|
|
exit 0
|
|
fi
|
|
|
|
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
|
|
kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' \
|
|
| base64 -d > "$DIAG_DIR/ca.crt"
|
|
|
|
KC="$DIAG_DIR/kubeconfig"
|
|
kubectl --kubeconfig="$KC" config set-cluster homelab \
|
|
--server="$SERVER" --certificate-authority="$DIAG_DIR/ca.crt" --embed-certs=true >/dev/null
|
|
kubectl --kubeconfig="$KC" config set-credentials ci-diagnostics --token="$TOKEN" >/dev/null
|
|
kubectl --kubeconfig="$KC" config set-context diag --cluster=homelab --user=ci-diagnostics >/dev/null
|
|
kubectl --kubeconfig="$KC" config use-context diag >/dev/null
|
|
chmod 600 "$KC"
|
|
rm -f "$DIAG_DIR/ca.crt"
|
|
|
|
cp "$(command -v kubectl)" "$DIAG_DIR/kubectl"
|
|
|
|
# Smoke-test with the restricted identity so a broken RBAC surfaces HERE,
|
|
# in the pipeline log, not as a confusing tool failure inside the agent.
|
|
KUBECONFIG="$KC" "$DIAG_DIR/kubectl" get ns >/dev/null \
|
|
&& echo "diag kubeconfig OK (SA ci-diagnostics, 1h token)" \
|
|
|| { echo "WARNING: diag kubeconfig smoke test failed — removing it; agents run snapshot-only."; rm -f "$KC"; }
|