cluster-inspector: read-only kubeconfig for lab1, workload-aware triage

The agent could only reach lab-mgmt, so it couldn't verify nodes, CNI or
system pods on lab1. It correctly refused the admin ~/.kube/lab1.kubeconfig
when the owner's permission was relayed through the main session.

Workload kubeconfigs:
- make-kubeconfig.sh: new --capi-cluster [NS/]NAME. --admin-kubeconfig
  is then the management cluster. The workload admin kubeconfig is read
  from Secret NS/NAME-kubeconfig into a mktemp file, removed on exit, so
  no admin file for the workload cluster lands on disk.
- ansible/mgmt.yml --tags inspector now also mints kubeconfigs for every
  cluster in the new inspector_workload_clusters (group_vars: lab1).
  Clusters without a <name>-kubeconfig Secret are skipped. The tag is now
  the single weekly token refresh; tasks stay changed_when: false, so the
  playbook's changed=0 rule still holds.
- Owner ran --tags inspector: kubeconfigs/lab1.kubeconfig (lab1-ro)
  minted, can-i checks as expected.

Agent prompt:
- Cluster map: what to inspect on lab-mgmt vs the workload cluster.
  Machine -> Node -> VM via nodeRef, providerID and
  ProxmoxMachine.spec.virtualMachineID (checked on live objects).
- New triage step: scale-down blockers (non-DaemonSet kube-system pods
  without PDB, local storage, bare pods, PDBs at 0, safe-to-evict /
  scale-down-disabled).
- Refuses admin kubeconfigs even when a caller relays permission; points
  the owner to --tags inspector on missing file or 401.
- Verb before --kubeconfig so commands match the kubectl get/describe/logs
  allow rules; single-quote jsonpath/custom-columns for zsh.
- Report format: abnormal first, then health summary, then unverified.

settings.json: allow kubectl describe/logs/events and clusterctl describe.
All four are read-only, and the RO kubeconfigs enforce read-only anyway.

Checked: bash -n on the script; ansible-playbook --syntax-check and
ansible-lint --profile production pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 09:23:41 +02:00
co-authored by Claude Opus 5.5
parent 1d0b669d07
commit 49c548e296
7 changed files with 134 additions and 35 deletions
+29
View File
@@ -259,3 +259,32 @@
become: false
changed_when: false
tags: [inspector]
- name: Workload clusters that have a CAPI kubeconfig Secret
ansible.builtin.command: >-
kubectl --kubeconfig {{ lookup('env', 'HOME') }}/.kube/lab-mgmt.kubeconfig
-n {{ item.namespace }} get secret {{ item.name }}-kubeconfig -o name
loop: "{{ inspector_workload_clusters }}"
loop_control:
label: "{{ item.namespace }}/{{ item.name }}"
register: workload_kubeconfig_secrets
delegate_to: localhost
become: false
changed_when: false
failed_when: false
tags: [inspector]
- name: Read-only kubeconfigs for workload clusters (skips clusters that don't exist yet)
ansible.builtin.command: >-
{{ playbook_dir }}/../.claude/cluster-inspector/make-kubeconfig.sh {{ item.item.name }}
--admin-kubeconfig {{ lookup('env', 'HOME') }}/.kube/lab-mgmt.kubeconfig
--capi-cluster {{ item.item.namespace }}/{{ item.item.name }}
--apply-rbac
loop: "{{ workload_kubeconfig_secrets.results }}"
loop_control:
label: "{{ item.item.namespace }}/{{ item.item.name }}"
when: item.rc == 0
delegate_to: localhost
become: false
changed_when: false
tags: [inspector]