Configure OIDC, make idempotent, fix bugs. Claude.ai

This commit is contained in:
2026-02-25 13:20:12 -05:00
parent 995b7c4070
commit d981b69669
23 changed files with 2269 additions and 760 deletions

101
CLAUDE.md
View File

@@ -1,87 +1,42 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Session Start
## Running Playbooks and Commands
Read the latest handoff in docs/summaries/ if one exists. Load only the files that handoff references — not all summaries. If no handoff exists, ask: what is the project, what type of work, what is the target deliverable.
All Ansible execution happens inside a container-based Execution Environment (EE) via `ansible-navigator`. **Never run `ansible-playbook` or `ansible-lint` directly** — they either fail (missing collections/modules) or produce false results compared to the EE.
Before starting work, state: what you understand the project state to be, what you plan to do this session, and any open questions.
**Required Python venv:** Always activate before any ansible command:
```bash
source /home/ptoal/.venv/ansible/bin/activate
```
## Identity
**Full run command:**
```bash
op run --env-file=/home/ptoal/.ansible.zshenv -- ansible-navigator run playbooks/<playbook>.yml
```
You work with Pat, a Senior Solutions Architect at Red Hat building automation for a HomeLab.
**Syntax check:**
```bash
ansible-navigator run playbooks/<playbook>.yml --syntax-check --mode stdout
```
## Rules
**Lint** is enforced via pre-commit (gitleaks, yamllint, ansible-lint). Run manually:
```bash
pre-commit run --all-files
```
1. Do not mix unrelated project contexts in one session.
2. Write state to disk, not conversation. After completing meaningful work, write a summary to docs/summaries/ using templates from templates/claude-templates.md. Include: decisions with rationale, exact numbers, file paths, open items.
3. Before compaction or session end, write to disk: every number, every decision with rationale, every open question, every file path, exact next action.
4. When switching work types (research → writing → review), write a handoff to docs/summaries/handoff-[date]-[topic].md and suggest a new session.
5. Do not silently resolve open questions. Mark them OPEN or ASSUMED.
6. Do not bulk-read documents. Process one at a time: read, summarize to disk, release from context before reading next. For the detailed protocol, read docs/context/processing-protocol.md.
7. Sub-agent returns must be structured, not free-form prose. Use output contracts from templates/claude-templates.md.
The `op run` wrapper injects 1Password secrets (vault password, API tokens) from `~/.ansible.zshenv` into the EE container environment. The vault password itself is retrieved from 1Password by `vault-id-from-op-client.sh`, which looks up `<vault-id> vault key` in the `LabSecrets` 1Password vault.
## Where Things Live
## Architecture
- templates/claude-templates.md — summary, handoff, decision, analysis, task, output contract templates (read on demand)
- docs/summaries/ — active session state (latest handoff + project brief + decision records + source summaries)
- docs/context/ — reusable domain knowledge, loaded only when relevant to the current task
- processing-protocol.md — full document processing steps
- archive-rules.md — summary lifecycle and file archival rules
- playbooks/ -- Main ansible playbooks
- roles/ -- Both custom, and external Ansible roles
- collections/ -- should only contain requirements.yml
- docs/archive/ — processed raw files. Do not read unless explicitly told.
- output/deliverables/ — final outputs
### Execution Model
- **EE image:** `aap.toal.ca/ee-demo:latest` (Ansible 2.16 inside)
- Collections bundled in the EE are authoritative. Project-local collections under `collections/` are volume-mounted into the EE at `/runner/project/collections`, overlaying the EE's bundled versions.
- The kubeconfig for SNO OpenShift is mounted from `~/Dev/sno-openshift/kubeconfig``/root/.kube/config` inside the EE.
## Error Recovery
### Inventory
External inventory at `/home/ptoal/Dev/inventories/toallab-inventory` (outside this repo). Key inventory groups and hosts:
- `openshift` group — `sno.openshift.toal.ca` (SNO cluster, `connection: local`)
- `proxmox_api` — Proxmox API endpoint (`ansible_host: proxmox.lab.toal.ca`, port 443)
- `proxmox_host` — Proxmox SSH host (`pve1.lab.toal.ca`)
- `opnsense` group — `gate.toal.ca` (OPNsense firewall, `connection: local`)
If context degrades or auto-compact fires unexpectedly: write current state to docs/summaries/recovery-[date].md, tell the user what may have been lost, suggest a fresh session.
Host-specific variables (cluster names, IPs, API keys) live in that external inventory's `host_vars/`.
## Before Delivering Output
### Secrets and Vault
- All vaulted variables use the `vault_` prefix (e.g. `vault_ocp_pull_secret`, `vault_keycloak_admin_password`)
- Vault password is retrieved per-vault-id from 1Password via `vault-id-from-op-client.sh`
- The 1Password SSH agent socket is mounted into the EE so the script can reach it
### Local Roles (`roles/`)
- `proxmox_sno_vm` — Creates SNO VM on Proxmox (UEFI/q35, VirtIO NIC, configurable VLAN)
- `opnsense_dns_override` — Manages OPNsense Unbound DNS host overrides and domain forwards
- `dnsmadeeasy_record` — Manages DNS records in DNS Made Easy
Third-party roles (geerlingguy, oatakan, ikke_t, sage905) are excluded from linting.
## Key Playbooks
| Playbook | Purpose |
|---|---|
| `deploy_openshift.yml` | End-to-end SNO deployment: Proxmox VM → OPNsense DNS → public DNS → agent ISO → install |
| `configure_sno_oidc.yml` | Configure Keycloak OIDC on SNO (Play 1: Keycloak client; Play 2: OpenShift OAuth) |
| `opnsense.yml` | OPNsense firewall configuration (DHCP, ACME, services) |
| `create_gitea.yml` | Deploy Gitea with DNS and OPNsense service integration |
| `site.yml` | General site configuration |
`deploy_openshift.yml` has tag-based plays that must run in order: `proxmox``opnsense``dns``sno`. DNS plays must complete before VM boot.
## Conventions
- Internal variables use double-underscore prefix: `__prefix_varname` (e.g. `__oidc_oc`, `__oidc_tmpdir`, `__proxmox_sno_vm_net0`)
- `module_defaults` at play level is used to set shared auth parameters for API-based modules
- Tags match play names: run individual phases with `--tags proxmox`, `--tags sno`, etc.
- `oc` CLI is available in the EE PATH — no need to specify a binary path
- OpenShift manifests are written to a `tempfile` directory and cleaned up at play end
- Always use fully qualified collection names (FQCN)
- Tasks must be idempotent; avoid shell/command unless no alternative
- Use roles for anything reused across playbooks
- Always include handlers for service restarts
- Tag every task with role name and action type
## Project Structure
- roles/ — all reusable roles
- playbooks/ — top-level playbooks
- rulebooks/ -- Event Driven Ansible rulebooks
Verify: exact numbers preserved, open questions marked OPEN, output matches what was requested (not assumed), claims backed by specific data, output consistent with stored decisions in docs/context/, summary written to disk for this session's work.