Commit Graph
57 Commits
Author SHA1 Message Date
jakman85andClaude Opus 4.8 95e3eafac6 iac: harden node lifecycle — tofu for_each + self-contained ansible rejoin
Implements T-1.5 findings F1/F2 (author-first, no cluster change).

F1 (tofu): refactor libvirt node resources count -> for_each keyed by
node name so single-node -replace/destroy cannot cascade to siblings.
Add ordered-list/primary helper locals; update outputs.tf off the map;
add moved.tf (12 moved blocks). tofu plan proves a pure state-address
migration: 0 to add, 0 to change, 0 to destroy (all 12 'has moved to').
State-persist via a 0-change apply is operator-permission-gated.

F2 (ansible): k3s_server secondary fetches the join token via
delegate_to the primary (published fact as fast path), so a single-node
rejoin with --limit k3s-dev-N is self-contained and no longer depends on
a fact an earlier play had to set. Syntax-check + CI gate green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-16 19:42:12 -05:00
jakman85andClaude Opus 4.8 1eeb754bee docs(t-1.5): log destroy/rebuild proof outcome + IaC findings
T-1.5 destructive IaC-validity test PASSED: dev cluster torn down and
reconstituted from IaC + preserved disks + Flux git source with zero
state loss (3/3 Ready, Cilium OK, Flux READY=True). Post-rebuild
conformance L2 R-NET-01 + R-NET-02 both PASS.

Two IaC-hardening findings for Phase 2:
- F1: tofu destroy -target on a count-indexed resource over-destroyed
  all 3 domains; refactor libvirt_domain.node count -> for_each keyed by
  node name; never use destroy -target for single-node lifecycle.
- F2: single-node ansible rejoin needs the primary in --limit to publish
  the k3s join-token fact; make the join self-contained via delegate_to
  the primary so --limit k3s-dev-N is hands-off.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-16 19:35:01 -05:00
jakman85andClaude Opus 4.8 e20f17b896 K2 DONE: L2 network behavior tests pass against the live cluster
R-NET-01 default-deny + R-NET-02 deny-undeclared PASS via run.sh (JUnit+coverage,
exit 0). Fixed 3 real bugs found by running them:
- chainsaw strict list-matching: assert scalar 'phase: Running' not a conditions[] element.
- default-deny blocks the kubelet readiness probe -> drop probes (dest pods just need to run).
- chainsaw report path ../_artifacts resolved to repo-root -> fix to _artifacts (was exit 1).
- swap agnhost->busybox httpd listeners (cached everywhere; cache-timing-proof).
Logged the kubelet-probe finding for WS-NET's T-2.2 default-deny baseline design.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-16 15:46:00 -05:00
jakman85andClaude Opus 4.8 53e7fbcefc docs: mark K1 resolved in decision log
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-16 15:17:36 -05:00
jakman85andClaude Opus 4.8 ab0a7977bf Phase 1 T-1.4 DONE: Flux reconciling clusters/dev from host Gitea
host-prereqs.yml opened the firewall (via the operator's ansible-vault become
password); Flux GitRepository READY=True (main@sha1:a2f3bdc). Commit the
encrypted hypervisor vault (ansible_become_password) so rebuild is fully
hands-off; passphrase stays out-of-repo. platform/apps still not reconciled.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-16 15:14:09 -05:00
jakman85andClaude Opus 4.8 3df5071bd1 Codify host firewall + Gitea bootstrap as IaC (hands-off rebuild)
Per operator: the firewalld rule (VM->host:3000 for the Flux<-Gitea source) must be
IaC, not a manual command (R-ENV-01, R-PLAT-04).
- infra/ansible/playbooks/host-prereqs.yml: idempotent firewalld open on the libvirt
  zone (localhost play, become; no extra collection).
- bootstrap/gitea/bootstrap-gitea.sh: now fully automates admin + public repo + push
  (was manual instructions) — idempotent; creds stay 0600 on host, never committed.
Applying host-prereqs still needs host sudo (I lack non-interactive sudo); with
passwordless become a destroy/rebuild is fully unattended.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-16 14:52:08 -05:00
jakman85andClaude Opus 4.8 cc89b4b830 Autonomous session: Phase-2 platform authoring + Flux bootstrap progress
Author-only Phase-2 components (platform suspended; cluster untouched):
- platform/longhorn: 3-replica SC + bulk external-mount indirection (R-STATE)
- platform/monitoring: kube-prometheus-stack + Loki + Alloy (dev-trimmed) + 8 alert rules (R-OBS)
- platform/cilium: parity fix (k8sServiceHost=10.73.0.11 + masquerade) safe to adopt Phase 2
- conformance: partial L2 tests (worker hit session limit; incomplete — see DECISIONS-LOG K2)
- bootstrap/gitea: fix rootless-podman perms (host bind-mount -> named volume)

Flux installed on the cluster; host Gitea up + repo pushed; GitRepository BLOCKED by
host firewalld (VM->10.73.0.1:3000) — needs one operator sudo command (DECISIONS-LOG).
Known issue K1: cluster-vars substitution-var case mismatch (fix before un-suspend).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-16 14:32:47 -05:00