diff --git a/docs/architecture/networking.md b/docs/architecture/networking.md index 68834017..7a5e8aed 100644 --- a/docs/architecture/networking.md +++ b/docs/architecture/networking.md @@ -416,7 +416,7 @@ Containerd on all K8s nodes uses `hosts.toml` to redirect pulls to the local cac ### Ingress Returns 502 Bad Gateway -**Symptoms**: Cloudflared tunnel is up, Traefik logs show `dial tcp: lookup on 10.0.20.101:53: no such host`. +**Symptoms**: Cloudflared tunnel is up, Traefik logs show `dial tcp: lookup on 10.0.20.201:53: no such host`. **Diagnosis**: DNS resolution failed. Check: 1. Is Technitium pod running? `kubectl get pod -n technitium` diff --git a/docs/architecture/security.md b/docs/architecture/security.md index f2e31f49..6a6286ae 100644 --- a/docs/architecture/security.md +++ b/docs/architecture/security.md @@ -181,7 +181,7 @@ Beads epic: `code-8ywc`. **Status: partially live as of 2026-05-18.** | W1.4 Kyverno security policies → Enforce | **LIVE** — 3 policies in Enforce mode with 35-namespace exclude list. | | W1.5 Kyverno trusted-registries → Enforce | **LIVE** — explicit allowlist (15 registries + 6 DockerHub library bare names + 56 DockerHub user repos). Verified by admission dry-run: `evilcorp.example/malware:v1` BLOCKED, `alpine:3.20` and `docker.io/library/alpine:3.20` ALLOWED. | | W1.6 Calico observe-phase (pilot: recruiter-responder) | **LIVE** (2026-05-19) — GlobalNetworkPolicy `wave1-egress-observe-recruiter-responder` with rules `[action:Log, action:Allow]`. FelixConfiguration.flowLogsFileEnabled approach abandoned (Calico Enterprise-only field, rejected by OSS v3.26). Log action emits iptables LOG with prefix `calico-packet: ` → kernel → journald → Alloy → Loki. Verified: `{job="node-journal"} \|~ "calico-packet"` returns real packet metadata (SRC/DST/PROTO). Expand to more namespaces by adding to `namespaceSelector`. | -| W1.7 NetworkPolicy phased enforce | **PENDING** — needs ~1 week of W1.6 observation, then build empirical allowlist from Loki queries, flip GNP rules from `[Log, Allow]` to `[Allow specific dests, Deny rest]`. | +| W1.7 NetworkPolicy phased enforce | **PARTIAL ANALYSIS** — first observation snapshot at `docs/architecture/wave1-egress-observation-2026-05-22.md` (36 source namespaces seen so far, 29 thin-profile candidates). Recommend continuing observation through 2026-05-29 (full week) before any enforce flip. Pilot enforce target: `recruiter-responder` (2 destinations only). `servarr` stays in Log+Allow indefinitely (BitTorrent P2P incompatible with static enforce). | The block below documents the locked design. diff --git a/docs/architecture/vpn.md b/docs/architecture/vpn.md index 5d2f22ad..82491f99 100644 --- a/docs/architecture/vpn.md +++ b/docs/architecture/vpn.md @@ -86,7 +86,7 @@ sequenceDiagram | Authentik | OIDC provider | K8s | SSO authentication for Headscale | | DERP Relay | Embedded in Headscale | K8s (region 999) | Relay for NAT traversal | | AdGuard DNS | Container | K8s | Global DNS resolver with ad-blocking | -| Technitium DNS | Container | K8s (10.0.20.101) | Internal .lan domain resolver | +| Technitium DNS | Container | K8s (10.0.20.201) | Internal .lan domain resolver | ## How It Works @@ -224,7 +224,7 @@ dns_config: - Google: `8.8.8.8`, `8.8.4.4` **Conditional forwarding**: -- `viktorbarzin.lan` → `10.0.20.101` (Technitium) +- `viktorbarzin.lan` → `10.0.20.201` (Technitium) **Ad-blocking lists**: - AdGuard DNS filter @@ -377,7 +377,7 @@ dns_config: **Steps**: 1. Verify AdGuard is running: `kubectl get pod -n adguard` 2. Check AdGuard conditional forwarding: Query AdGuard directly: `nslookup nextcloud.viktorbarzin.lan ` -3. Check Technitium: `nslookup nextcloud.viktorbarzin.lan 10.0.20.101` +3. Check Technitium: `nslookup nextcloud.viktorbarzin.lan 10.0.20.201` **Common causes**: 1. **AdGuard not forwarding .lan**: Conditional forwarding rule missing or misconfigured. diff --git a/docs/architecture/wave1-egress-observation-2026-05-22.md b/docs/architecture/wave1-egress-observation-2026-05-22.md new file mode 100644 index 00000000..1fc00a3f --- /dev/null +++ b/docs/architecture/wave1-egress-observation-2026-05-22.md @@ -0,0 +1,141 @@ +# Wave 1 W1.6/W1.7 — Egress Observation Snapshot (2026-05-22) + +First analysis pass over the Calico GNP `wave1-egress-observe-tier34` data +captured in Loki via `{job="node-journal"} |~ "calico-packet"`. + +**Data scope:** ~10000 flow log lines pulled from Loki over ~6h+24h windows. +Loki caps queries at 5000 records so longer windows are sample-capped. + +**Coverage:** 36 source namespaces observed making egress (out of 82 selected +by `tier in {3-edge, 4-aux}`). Namespaces missing from data are either idle, +scaled to 0, or producing only intra-namespace traffic (which Calico Log +captures from-workload but most pods in those namespaces talk locally). + +## Egress fan-out per namespace + +| Namespace | dests | pod-ns | svc | external | +|---|---:|---:|---:|---:| +| affine | 3 | 2 | 1 | 0 | +| beads-server | 4 | 3 | 1 | 0 | +| cyberchef | 2 | 1 | 1 | 0 | +| dawarich | 3 | 2 | 1 | 0 | +| default | 1 | 0 | 0 | 1 | +| ebooks | 3 | 2 | 1 | 0 | +| f1-stream | 16 | 2 | 1 | 13 | +| forgejo | 2 | 1 | 1 | 0 | +| hackmd | 2 | 1 | 1 | 0 | +| homepage | 2 | 1 | 1 | 0 | +| isponsorblocktv | 2 | 0 | 1 | 1 | +| jsoncrack | 2 | 1 | 1 | 0 | +| kms | 2 | 1 | 1 | 0 | +| mailserver | 2 | 0 | 1 | 1 | +| meshcentral | 2 | 2 | 0 | 0 | +| n8n | 2 | 1 | 1 | 0 | +| nextcloud | 5 | 2 | 1 | 2 | +| onlyoffice | 2 | 1 | 1 | 0 | +| openclaw | 18 | 4 | 1 | 13 | +| paperless-ngx | 3 | 2 | 1 | 0 | +| phpipam | 3 | 2 | 1 | 0 | +| poison-fountain | 2 | 1 | 1 | 0 | +| postiz | 9 | 8 | 1 | 0 | +| realestate-crawler | 2 | 1 | 1 | 0 | +| recruiter-responder | 2 | 0 | 1 | 1 | +| rybbit | 2 | 1 | 1 | 0 | +| send | 2 | 1 | 1 | 0 | +| servarr | 134 | 2 | 2 | 130 | +| speedtest | 2 | 1 | 1 | 0 | +| status-page | 10 | 2 | 1 | 7 | +| tandoor | 2 | 1 | 1 | 0 | +| technitium | 5 | 2 | 1 | 2 | +| trading-bot | 5 | 2 | 1 | 2 | +| url | 2 | 1 | 1 | 0 | +| website | 2 | 1 | 1 | 0 | +| woodpecker | 8 | 2 | 1 | 5 | + +## Common patterns + +**Universal baseline** (every observed namespace makes these): +- `kube-system/kube-dns` UDP/53 — DNS resolution +- Often `dbaas` TCP/3306 (MySQL) or TCP/5432 (Postgres) +- Often `redis` TCP/6379 + +**Per-namespace specifics** (the part that varies): +- External HTTPS to specific IPs (CDNs, APIs) +- Internal pod-to-pod for service-specific clients + +## W1.7 rollout candidates (sorted by simplicity) + +**Tier A — trivial egress (recommend first wave):** + +`recruiter-responder` has the simplest profile of all observed: +- `kube-system/kube-dns` :53/UDP +- `99.83.136.103` :443/TCP (Telegram API) + +That's it. Two destinations. Perfect first enforce candidate. + +**Tier B — small egress (≤3 external + ≤5 internal, 29 namespaces):** + +affine, beads-server, cyberchef, dawarich, ebooks, forgejo, hackmd, homepage, +isponsorblocktv, jsoncrack, kms, mailserver, meshcentral, n8n, nextcloud, +onlyoffice, paperless-ngx, phpipam, poison-fountain, realestate-crawler, +rybbit, send, speedtest, tandoor, technitium, trading-bot, url, website. + +These can be enforce'd in batches of 3-5/day after the recruiter-responder +pilot proves out. + +**Tier C — moderate egress (5–18 external):** + +f1-stream (13 ext), openclaw (13 ext), woodpecker (5 ext), status-page (7 ext). +Need per-IP allowlist or domain-based selectors. + +**Tier D — broad egress (do NOT enforce statically):** + +`servarr` has 130+ external IPs because it runs BitTorrent peer-to-peer. +Static IP enforcement won't work; either leave in Log+Allow mode permanently +or use a port-only allowlist (TCP+UDP 6881+random high ports outbound). + +## Important caveats before flipping to enforce + +1. **Observation horizon is too short.** Only ~6h of dense data and ~24h + total. CronJobs that run weekly, periodic Vault token rotations (7d), + external service maintenance windows, Keel auto-rollouts pulling new + image versions — all missed. Recommend collecting **at least 7 days** + before declaring an allowlist complete. + +2. **`servarr`** is fundamentally incompatible with static enforce — keep + in Log+Allow (or explicit deny for known-bad CIDRs only). + +3. **External IPs are dynamic.** Cloudflare-fronted services rotate IPs. + The recruiter-responder external IP `99.83.136.103` is one of Telegram's + API endpoints — Telegram has a CIDR range. Allowing single IPs will break + when DNS resolves to a different IP. Prefer Calico's `domains:` selector + (Calico OSS supports DNS-based egress allowlists via `dns_policy_resolver`) + OR allow the full Cloudflare/AWS CIDR range OR use a per-app egress + gateway. + +4. **The observation didn't capture intra-namespace traffic** by design — + the Calico Log rule fires on egress from workload endpoint, but + pod-to-same-namespace-pod traffic on the same node may bypass the + filter chain (varies). Real-world testing needed after enforce flip. + +## Suggested next-session sequencing + +1. **Continue observation for at least 7 days** before any enforce flip. + Compare data on 2026-05-29 vs today; if no new destinations show up, + the allowlist is stable. +2. **First enforce: recruiter-responder.** GNP with allowlist = + {kube-dns, telegram CIDR, vault svc, eso svc}. Watch for breakage. +3. **Tier B batch rollout** at 3-5 namespaces/day per Keel-style phased + rollout pattern (memory id=1972). +4. **Tier C requires per-namespace investigation** — what are those + external IPs? Map to known services first. +5. **servarr stays in Log+Allow** indefinitely (or migrate to dedicated + egress proxy). + +## Source data location + +- Loki LogQL: `{job="node-journal"} |~ "calico-packet"` +- Pod IP → namespace map at observation time saved at + `/tmp/pod-ip-map.txt` on the analysis host (ephemeral). +- Analysis scripts: `/tmp/analyze_flows2.py`, `/tmp/build_allowlist.py`. +- Tracked under beads `code-8ywc` (W1.7). diff --git a/docs/plans/2026-02-22-talos-linux-migration-evaluation.md b/docs/plans/2026-02-22-talos-linux-migration-evaluation.md index 699a8762..87afe1fb 100644 --- a/docs/plans/2026-02-22-talos-linux-migration-evaluation.md +++ b/docs/plans/2026-02-22-talos-linux-migration-evaluation.md @@ -106,7 +106,7 @@ machine: - network: 0.0.0.0/0 gateway: 10.0.20.1 nameservers: - - 10.0.20.101 # Technitium + - 10.0.20.201 # Technitium - 1.1.1.1 registries: mirrors: diff --git a/docs/plans/2026-05-21-ha-control-plane-design.md b/docs/plans/2026-05-21-ha-control-plane-design.md index 11535457..c89ae0ee 100644 --- a/docs/plans/2026-05-21-ha-control-plane-design.md +++ b/docs/plans/2026-05-21-ha-control-plane-design.md @@ -1,9 +1,32 @@ # HA Control Plane (3 masters) — Design -**Date**: 2026-05-21 -**Status**: Drafted, NOT scheduled -**Beads**: code-n0ow -**Trigger**: today's k8s 1.34.7→1.34.8 autonomous-upgrade session repeatedly hit a storm cascade rooted in single-master apiserver outages +**Date**: 2026-05-21 (decisions locked 2026-05-22; **deferred 2026-05-23**) +**Status**: **DEFERRED** — design + plan complete, NOT scheduled. Awaiting either PVE host capacity expansion OR a separate right-sizing pass on the existing master before this becomes affordable. Paired plan: `2026-05-21-ha-control-plane-plan.md`. +**Beads**: code-n0ow (open, deferred — see `bd show code-n0ow`) +**Trigger**: 2026-05-21 k8s 1.34.7→1.34.8 autonomous-upgrade session repeatedly hit a storm cascade rooted in single-master apiserver outages + +## Why deferred (2026-05-23) + +Measured during the locking pass: + +- **k8s-master uses 4.6 GB of 32 GB allocated** (kube-apiserver 2.6 GB + etcd 660 MB + cm 360 MB + ~1 GB everything else). The 32 GB sizing is ~5-6× oversized vs working set. +- **PVE host is already 98% RAM-committed** — 262 GB allocated to VMs against 267 GB physical, with 1.5 GB of active swap. The planned 3 × 32 GB control plane (+64 GB net) would push allocation to 326 GB → OOM on the host. +- **Software-only HA on a single PVE host has bounded value** — a hypervisor crash still loses all 3 masters. The big resilience wins (kubeadm upgrades, cert rotation, planned reboots) are real but the disaster-recovery angle is limited until a second PVE host exists. + +### Revisit triggers — any of: + +1. **Second PVE host added** to the lab. Hardware HA becomes possible; HA control plane becomes the natural follow-up. Spread the 3 masters across 2 hosts (2+1). +2. **Cluster-wide right-sizing pass** that frees enough headroom for the original 3 × 32 GB plan, OR pre-agreed amendment to provision 16 GB masters (right-sized to actual usage; 3-4× current working-set headroom). +3. **Storm cascade burns enough hours** that the operational cost outweighs the memory cost — track minutes spent manually nursing kubeadm upgrades; if cumulative > ~10h over a few months, revisit. + +### What's still good + +The design + plan in this directory remain authoritative. When we revisit: + +- All 14 locked decisions stand. +- Challenger amendments (cloud-init template bump, rbac multi-master refactor, HTTPS `/readyz` health check, expanded blast radius, etcd-backup nodeSelector, chain extension as Phase 7) are baked in. +- Only the sizing decision needs revisiting — likely 16 GB per master instead of 32 GB. +- Adding `k8s_master_hosts` list-based refactor to the rbac stack (Phase 1.5) is a **standalone win** that could be done independently of HA — it would future-proof the cluster against the day HA lands. Consider lifting that as its own task. ## Problem statement @@ -50,18 +73,24 @@ The k8s upgrade chain doesn't need to be aware of *any* of this — the underlying availability of apiserver makes the chain's gates naturally pass on each iteration. -## Decisions (proposed — to be confirmed) +## Decisions (locked 2026-05-22) | # | Decision | Notes | |---|----------|-------| | 1 | **3 masters** (not 5) | Quorum tolerates 1 failure, sufficient for home-lab. 5 would tolerate 2 but doubles etcd write amplification. | -| 2 | **Sizing**: match current `k8s-master` (8 vCPU, 32GB RAM, ~64 GB disk) for all 3 | Symmetric. New VMs `k8s-master-2`, `k8s-master-3` on Proxmox. | -| 3 | **Apiserver LB**: **pfSense HAProxy** (existing pattern, see mailserver-pfsense-haproxy.md) over keepalived+haproxy-on-each-master | Pros: no per-node moving parts, mirrors the mailserver layout already in production. Cons: pfSense becomes more SPoF — but it's already SPoF for everything else (DNS, gateway, ingress). | -| 4 | **VIP**: pick an unused IP on the cluster VLAN, e.g. `10.0.20.99`, point all kubeconfigs + kubelet `--server` at it | Internal-only VIP; external API access stays via Cloudflared. | -| 5 | **etcd**: kubeadm-managed (existing); just `kubeadm join --control-plane` brings new members into the etcd cluster automatically | Avoids running etcd separately. | -| 6 | **kured-sentinel-gate**: extend "quorum-safe" check to verify ≥2 control-plane nodes Ready before allowing a reboot | Otherwise kured could reboot 2 masters at once and break quorum. | -| 7 | **etcd backup**: today's `etcd-backup` CronJob already takes a snapshot from one member; that's still sufficient (etcd snapshot is a consistent point-in-time). No new work needed. | | -| 8 | **Migration order**: add masters one at a time, run smoke (kubectl from each), then cut over kubeconfigs | Each `kubeadm join --control-plane` is reversible (just `kubeadm reset` + remove from etcd member list). | +| 2 | **Sizing**: match current `k8s-master` (8 vCPU, 32GB RAM, ~64 GB disk) for all 3 | Symmetric. New VMs `k8s-master-2` (VMID 205, 10.0.20.110), `k8s-master-3` (VMID 206, 10.0.20.111). | +| 3 | **Apiserver LB**: **pfSense HAProxy** — new TCP frontend on `10.0.20.99:6443` mirroring the mailserver pattern. Idempotent via `scripts/pfsense-haproxy-bootstrap.php`. | Pros: no per-node moving parts, mirrors existing mailserver layout. Cons: pfSense becomes more SPoF — but it's already SPoF for everything else (gateway/DNS/ingress). | +| 4 | **VIP**: `10.0.20.99` (one below current master `.100`, well clear of MetalLB pool `.200-.220`). Internal-only — external API access stays via Cloudflared. | All kubeconfigs + kubelet.conf entries flip from `10.0.20.100:6443` → `10.0.20.99:6443`. | +| 5 | **etcd**: kubeadm-managed stacked; `kubeadm join --control-plane` brings new members into the etcd cluster automatically | Avoids running etcd separately. | +| 6 | **kured-sentinel-gate**: extend the bash loop in `stacks/kured/main.tf` with a "≥2 control-plane nodes Ready" check between the existing all-nodes-Ready and calico-Ready checks | Otherwise kured could reboot 2 masters at once and break quorum. | +| 7 | **etcd backup**: `etcdctl snapshot save` from any member is a consistent point-in-time of the full quorum state — but the existing CronJob is pinned `node_name = "k8s-master"`. Phase 4.5 flips this to a control-plane label + toleration so backups don't silently skip when master-1 is drained. | Snapshot CORRECTNESS unchanged; SCHEDULING needs fixing. | +| 8 | **Migration order**: Phase 0 (retrofit existing cluster) → Phase 1 (LB up, single backend, HTTPS health check) → Phase 1.5 (rbac stack refactor) → Phase 2 (cloud-init bump + master-2 join + add to LB) → Phase 3 (master-3 join + add to LB) → Phase 4 (flip clients + workers to VIP) → Phase 4.5 (etcd-backup CronJob fix) → Phase 5 (kured-sentinel-gate quorum check) → Phase 6 (E2E validation) → Phase 7 (k8s-version-upgrade chain extension) | Each kubeadm join is reversible (`kubeadm reset` + `etcdctl member remove`). | +| 9 | **VM provisioning**: cloud-init via `create-template-vm` module, **but the template needs an apt-source bump first** (v1.32 → v1.34) and a control-plane gate on `k8s_join_command` so master VMs don't auto-join as workers. Existing master stays as the legacy manual VM (not rebuilt). | The repo has zero VMs using cloud-init for provisioning today — we're the first user. Update template first, then use it. | +| 10 | **Cert SAN + controlPlaneEndpoint retrofit**: Phase 0, before any new master joins. Patch `kubeadm-config` via `kubeadm init phase upload-config kubeadm --config ` (kubeadm-owned write, future-proof against `kubeadm upgrade apply`), regen `apiserver.crt` via `kubeadm init phase certs apiserver`, restart the kube-apiserver pod (~30s outage on the existing master only). | Standard kubeadm retrofit path; `kubeadm join --control-plane` requires controlPlaneEndpoint to be set. | +| 11 | **Multi-master config propagation (Phase 1.5)**: refactor `stacks/rbac/modules/rbac/{apiserver-oidc,audit-policy,etcd-tuning}.tf` to loop over a list of master hosts. Apply BEFORE master-2/3 join so they boot with OIDC, audit policy, and etcd tuning already in place. | Today these stacks SSH into a single master and sed into `kube-apiserver.yaml` — if not propagated, Authentik login flaps depending on which master the LB lands on. | +| 12 | **k8s-version-upgrade chain extension (Phase 7)**: extend `stacks/k8s-version-upgrade/scripts/upgrade-step.sh` to discover and iterate over all control-plane nodes (drain → upgrade → uncordon, gated by quorum check). | Without this, chain only upgrades master-1; masters 2/3 drift behind one version per upgrade. Original autonomous-upgrades goal unmet. | +| 13 | **LB health check**: HTTPS `GET /readyz` (with `verify none` for self-signed apiserver cert), NOT plain TCP. | Plain TCP misses apiserver-NotReady states (etcd unreachable, controller-manager flapping). | +| 14 | **VIP DNS name**: add `k8s-apiserver IN A 10.0.20.99` to `config.tfvars` BEFORE Phase 4. Delete stale `kubernetes IN A 10.0.20.100`. Consumers reference the FQDN, not the bare IP — future renumbering is then a single record change. | | ## Out of scope @@ -74,12 +103,15 @@ naturally pass on each iteration. | Risk | Mitigation | |---|---| +| Phase 0 cert regen on existing master triggers a brief apiserver outage (~30s) | Already a known cluster behaviour during static-pod restart. Schedule during a low-activity window. Tigera/operators will crash-loop briefly but recover — same blast radius as today's k8s upgrade. **Once HA is up, future restarts won't have this surface at all.** | | etcd quorum split-brain during member join | kubeadm join is atomic; if it fails, the new member doesn't join the quorum. Existing etcd stays healthy. | -| LB misconfiguration → all kubectl breaks | Smoke-test from each master before flipping clients. Keep a kubeconfig pointing directly at one master as fallback. | -| Existing kubeconfigs (dev VM, agents, woodpecker) need updating | List all consumers, update in a single TF apply. | -| New masters get scheduled some workload pods unintentionally | Verify control-plane taint is applied at join time. | -| Cluster-wide cert rotation might be needed | kubeadm join handles certs automatically using the `--certificate-key` from `kubeadm init phase upload-certs`. | -| 32GB per master × 3 = 96GB RAM used for control plane alone | Proxmox host has headroom; not blocking. | +| LB misconfiguration → all kubectl breaks | Smoke-test from each master directly (bypass LB) before flipping clients. Keep a kubeconfig pointing at `10.0.20.100:6443` as fallback. | +| Existing kubeconfigs (Woodpecker pipelines, agents, dev VM, in-cluster RBAC default) need updating | Single Terraform apply touches `stacks/rbac/modules/rbac/apiserver-oidc.tf` (default), `.woodpecker/*.yml` (committed kubeconfigs). Worker `kubelet.conf` files patched in Phase 4 via ssh loop. | +| New masters get scheduled workload pods unintentionally | Verify `node-role.kubernetes.io/control-plane:NoSchedule` taint is applied at join time (default with `--control-plane`). | +| Cert rotation propagation | kubeadm join uses the `--certificate-key` from `kubeadm init phase upload-certs` to fetch existing CA materials. Single short-lived secret in `kube-system/kubeadm-certs` (**2h TTL** — Phases 2 + 3 must complete within the window, or re-upload between them). | +| 32GB per master × 3 = 96GB RAM used for control plane alone | PVE host has 272GB total, 176GB allocated to cluster pre-HA. Post-HA: 240GB allocated, 32GB headroom. Sufficient. | +| Pre-existing kubeadm-config does NOT have `controlPlaneEndpoint` set | Phase 0 patches it. Verify: `kubectl -n kube-system get cm kubeadm-config -o yaml \| grep controlPlaneEndpoint` (absent → `10.0.20.99:6443` post-Phase 0). | +| Existing master cert SANs are `[k8s-master, 10.96.0.1, 10.0.20.100]` only — missing VIP | Phase 0 regens with `--apiserver-cert-extra-sans 10.0.20.99` after patching kubeadm-config. | ## Verification @@ -91,12 +123,23 @@ kubectl get nodes -l node-role.kubernetes.io/control-plane= # etcd quorum healthy kubectl -n kube-system exec etcd-k8s-master -- etcdctl \ - --endpoints=https://10.0.20.100:2379,https://10.0.20.X:2379,https://10.0.20.Y:2379 \ + --endpoints=https://10.0.20.100:2379,https://10.0.20.110:2379,https://10.0.20.111:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ + --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ endpoint health --cluster +# Kubeconfig points at VIP +kubectl --kubeconfig ~/.kube/config config view --minify -o jsonpath='{.clusters[0].cluster.server}' +# Expect: https://10.0.20.99:6443 + +# Worker kubelet.conf points at VIP +for n in k8s-node{1,2,3,4}; do + ssh wizard@$n.viktorbarzin.lan "sudo grep -E '^\s+server:' /etc/kubernetes/kubelet.conf" +done +# Expect: server: https://10.0.20.99:6443 on every node + # Failover test: cordon master-1, reboot it, observe kubectl still works through LB kubectl drain k8s-master --delete-emptydir-data --ignore-daemonsets ssh wizard@k8s-master.viktorbarzin.lan sudo reboot @@ -110,7 +153,7 @@ kubectl -n k8s-upgrade create job --from=cronjob/k8s-version-check ha-validation - 2× VMs at 8 vCPU + 32GB RAM each = +64GB RAM on Proxmox host - ~+128GB disk usage (2× 64GB master disks) -- ~2-4 hours of operator time end-to-end (VM provisioning + kubeadm join + LB config + smoke) +- **~5-7 hours of operator time end-to-end** (cloud-init template bump + Phase 0 retrofit + LB + Phase 1.5 rbac refactor + 2× kubeadm join + Phase 4 cutover + Phase 4.5 etcd-backup fix + Phase 5 kured-gate + Phase 6 validation + Phase 7 chain extension). Phases 0–6 can land in one session; Phase 7 can be deferred a few days if needed. ## What's already in place from today's work diff --git a/docs/plans/2026-05-21-ha-control-plane-plan.md b/docs/plans/2026-05-21-ha-control-plane-plan.md new file mode 100644 index 00000000..9a61875d --- /dev/null +++ b/docs/plans/2026-05-21-ha-control-plane-plan.md @@ -0,0 +1,325 @@ +# HA Control Plane (3 masters) — Plan + +**Date**: 2026-05-21 (locked + revised 2026-05-22 after challenger pass) +**Status**: Drafted, awaiting approval +**Pairs with**: `2026-05-21-ha-control-plane-design.md` +**Beads**: `code-n0ow` + +## Goal + +Migrate the single-master cluster to a 3-master HA control plane behind +a pfSense HAProxy VIP (`10.0.20.99:6443`), enabling autonomous k8s +upgrades without storm-cascade manual nursing. + +## Topology — before / after + +``` +Before After + ┌──────────────────────┐ + │ pfSense HAProxy │ + │ 10.0.20.99:6443 │ + │ TCP, /readyz health │ + └──┬───────┬───────┬───┘ +┌───────────────┐ │ │ │ +│ k8s-master │ ▼ ▼ ▼ +│ 10.0.20.100 │ ┌──────────────┐ ┌────────────┐ ┌────────────┐ +│ apiserver+etcd│ │k8s-master │ │k8s-master-2│ │k8s-master-3│ +│ + workers join│ │10.0.20.100 │ │10.0.20.110 │ │10.0.20.111 │ +│ directly │ │(VMID 200) │ │(VMID 205) │ │(VMID 206) │ +└───────────────┘ │apiserver+etcd│ │apiserver+e.│ │apiserver+e.│ + └──────────────┘ └────────────┘ └────────────┘ + ▲ ▲ ▲ + └────────────────┼────────────────┘ + │ + etcd quorum (3 members, tolerates 1 down) +``` + +## Research decisions (locked — see design doc for full table) + +| Decision | Value | +|---|---| +| LB strategy | pfSense HAProxy, TCP mode, HTTPS `/readyz` health check | +| VIP | `10.0.20.99` (FQDN `k8s-apiserver.viktorbarzin.lan`) | +| New master IPs | `10.0.20.110`, `10.0.20.111` | +| New master VMIDs | `205`, `206` | +| Master sizing | 8 vCPU, 32 GB RAM, 64 GB disk (matches existing) | +| VM provisioning | cloud-init via `create-template-vm` (template bumped v1.32 → v1.34 first; `k8s_join_command = ""` for masters) | +| etcd | stacked (kubeadm-managed) | +| Multi-master apiserver flags | rbac stack refactored to loop over master list (Phase 1.5) | +| controlPlaneEndpoint + cert SAN retrofit | Phase 0, before any new master joins | +| k8s-version-upgrade chain | extended to multi-master in Phase 7 | + +## Callers / blast radius + +| Surface | Path | Phase | +|---|---|---| +| Worker `/etc/kubernetes/kubelet.conf` × 4 | nodes 1-4 | 4.2 | +| `/home/wizard/code/infra/config` (root kubeconfig used by every `tg apply`) | repo root | 4.1 | +| `config.tfvars:115` (`kubernetes IN A 10.0.20.100` zone-file record) | repo root | 1.1 (delete) | +| `config.tfvars:231` (`k8s_join_command` for cloud-init template) | repo root | 4.1 (flip to VIP) | +| `stacks/rbac/modules/rbac/{apiserver-oidc,audit-policy,etcd-tuning}.tf` | `var.k8s_master_host` defaults | 1.5 (refactor to list) | +| `.woodpecker/{default,drift-detection,renew-tls,provision-user}.yml` (4 files × 2 refs each — kubeconfig `server:` AND `curl` lines) | repo root | 4.1 | +| `stacks/k8s-portal/.../files/src/routes/{download,setup/script}/+server.ts` (`CLUSTER_SERVER` const used to generate user kubeconfigs) | k8s-portal module | 4.1 | +| `stacks/k8s-version-upgrade/scripts/upgrade-step.sh` (hard-coded `k8s-master` in phase_master) | stack | 7.1 | +| `stacks/infra-maintenance/.../main.tf` lines 98 + 218 (`node_name = "k8s-master"` on etcd-backup + defrag-etcd CronJobs) | stack | 4.5 | +| `kured-sentinel-gate` bash loop | `stacks/kured/main.tf` | 5.1 | +| `docs/architecture/compute.md`, `.claude/skills/uptime-kuma/SKILL.md`, runbooks | docs | 6.3 | +| **No-op surfaces** (confirmed clean): Vault (uses `kubernetes.default.svc`), Cloudflared (no apiserver tunnel), in-cluster `kubernetes.default.svc` / `10.96.0.1`, etcd-backup CORRECTNESS (snapshot is cluster-wide), kubeadm-managed etcd peer certs (auto-generated on join) | | — | + +## Edge cases + +- **Phase 0 apiserver restart (~30s)** = same blast radius as today's k8s upgrade (tigera/cnpg/gpu-operator briefly crash). The LB doesn't help here because the new cert isn't yet trusted by clients. Accept the brief outage. Schedule during a low-activity window. +- **`kubeadm-certs` secret TTL = 2h** (NOT 24h as initially stated). Phase 2 + 3 must complete within the window, or re-upload between them. +- **pfSense haproxy bootstrap = reset-to-declared-state** on each run (lines 155-158 of the script). Adding master-2 means the apiserver pool is briefly torn down + rebuilt. TCP frontends bounce. Long-poll connections from kubelets break + reconnect. Expect ~2-5s of "kubectl: unable to connect" during pool rewrites. +- **TCP health check is too lax** for apiserver (listener up ≠ ready). Phase 1 uses HTTPS `GET /readyz` with `verify none` — catches NotReady (etcd unreachable, controller-manager flapping). +- **Worker kubelet.conf flip**: kubelet TLS bootstrap re-auths against new endpoint on restart. Expect 5-10s NotReady per node during the Phase 4.2 loop. +- **VIP cannot be the existing master IP**: confirmed `.99` is free (no grep matches, no MetalLB pool conflict — pool is .200-.220). +- **pfSense reboot windows**: pre-Phase-4 OK (clients still on direct IP), post-Phase-4 breaks everything. Don't migrate near a pfSense maintenance window. + +## Phased plan + +Reversible up to Phase 4. Phase 4+ reverse via the rollback section. + +### Phase 0 — Retrofit existing cluster (~30 min, ~30s of apiserver outage) + +- [ ] **0.1 Pre-flight** + - [ ] Cluster healthy: `kubectl get nodes` (all Ready), `kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded` empty + - [ ] Recent etcd backup valid: `ls -lh /srv/nfs/etcd-backup/ | tail -5` + - [ ] Proxmox VM snapshot of `k8s-master`: `ssh root@192.168.1.127 qm snapshot 200 pre-ha-retrofit` + - [ ] IPs free: `for ip in 99 110 111; do ping -c1 -W1 10.0.20.$ip && echo "BUSY $ip" || echo "free $ip"; done` +- [ ] **0.2 Patch `kubeadm-config` ConfigMap via kubeadm (NOT kubectl apply)** + - [ ] On master: `sudo kubeadm config print init-defaults --component-configs=KubeletConfiguration > /tmp/kubeadm-new.yaml` + - [ ] Hand-edit /tmp/kubeadm-new.yaml: take the existing CM as base, add `controlPlaneEndpoint: 10.0.20.99:6443` under ClusterConfiguration, add `apiServer.certSANs: [10.0.20.99, k8s-apiserver.viktorbarzin.lan]` + - [ ] Apply via kubeadm (kubeadm-owned, future `kubeadm upgrade apply` won't overwrite): `sudo kubeadm init phase upload-config kubeadm --config /tmp/kubeadm-new.yaml` + - [ ] Verify: `kubectl -n kube-system get cm kubeadm-config -o yaml | grep -E 'controlPlaneEndpoint|certSANs'` +- [ ] **0.3 Regen apiserver cert** + - [ ] On master: `sudo mkdir -p /tmp/apiserver-backup && sudo mv /etc/kubernetes/pki/apiserver.{crt,key} /tmp/apiserver-backup/` + - [ ] `sudo kubeadm init phase certs apiserver` (reads patched kubeadm-config) + - [ ] Verify: `sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep -A2 'Subject Alternative'` — expect `IP Address:10.0.20.99` PLUS existing SANs (kubeadm adds, doesn't replace) +- [ ] **0.4 Restart kube-apiserver static pod** + - [ ] On master: `sudo kubectl -n kube-system delete pod kube-apiserver-k8s-master --force --grace-period=0` + - [ ] Wait: `kubectl wait --for=condition=Ready pod/kube-apiserver-k8s-master -n kube-system --timeout=180s` + - [ ] Verify: `kubectl get nodes` works (apiserver alive on direct IP) +- [ ] **0.5 Panic-mode rollback procedure (DOCUMENTED ONLY — only run if 0.4 fails)** + - [ ] `sudo cp /tmp/apiserver-backup/apiserver.{crt,key} /etc/kubernetes/pki/` + - [ ] `sudo systemctl restart kubelet` (forces static pod re-read) + - [ ] Wait for apiserver Ready; revert kubeadm-config edits via the file backup +- [ ] **0.6 Verify operators recovered from brief outage** + - [ ] `kubectl get pods -n calico-system -l app=tigera-operator -o wide` — Running, restart count incremented by 1 max + - [ ] `kubectl get pods -n gpu-operator -o wide` — same + - [ ] `kubectl get pods -n cnpg-system -o wide` — same + +### Phase 1 — pfSense HAProxy + DNS (~30 min) + +- [ ] **1.1 Reserve VIP `10.0.20.99` + DNS** + - [ ] Add Virtual IP on pfSense (Firewall → Virtual IPs → IP Alias on VLAN20, `10.0.20.99/24`) + - [ ] Add `k8s-apiserver-vip → 10.0.20.99` host alias (Firewall → Aliases → Hosts) + - [ ] phpIPAM: register `10.0.20.99` under section "K8s cluster" + - [ ] Add DNS A record `k8s-apiserver IN A 10.0.20.99` to `config.tfvars` (and **delete** stale `kubernetes IN A 10.0.20.100` on line 115) + - [ ] `scripts/tg apply -target=module.technitium` — confirm zone reload +- [ ] **1.2 Extend `infra/scripts/pfsense-haproxy-bootstrap.php` for apiserver pool with HTTPS health check** + - [ ] Add `build_pool_https()` helper variant (or add `$use_https_readyz` param to existing `build_pool()`) that emits `check_type='HTTP'`, `monitor_uri='/readyz'`, `httpchk_method='GET'`, `ssl='yes'`, `sslverify='no'` + - [ ] Add `'apiserver_nodes'` to `$POOL_NAMES`; `'apiserver_proxy_6443'` to `$FRONTEND_NAMES` + - [ ] `build_pool_https('apiserver_nodes', '6443', [['k8s-master', '10.0.20.100']])` + - [ ] `build_frontend('apiserver_proxy_6443', 'K8s apiserver VIP', '10.0.20.99', '6443', 'apiserver_nodes')` +- [ ] **1.3 Deploy + validate** + - [ ] `scp infra/scripts/pfsense-haproxy-bootstrap.php admin@10.0.20.1:/tmp/ && ssh admin@10.0.20.1 'php /tmp/pfsense-haproxy-bootstrap.php'` + - [ ] `ssh admin@10.0.20.1 'sockstat -l | grep 10.0.20.99:6443'` — expect haproxy listening + - [ ] `ssh admin@10.0.20.1 "echo 'show servers state' | socat /tmp/haproxy.socket stdio" | grep apiserver` — backend UP (op_state=2) +- [ ] **1.4 Smoke via VIP** + - [ ] From devvm: `curl --cacert /etc/kubernetes/pki/ca.crt https://10.0.20.99:6443/readyz` — expect `ok` + - [ ] Build a transient kubeconfig pointing at VIP, run `kubectl get nodes` — succeeds + - [ ] **If TLS validation fails: STOP — Phase 0 cert regen didn't include VIP**, rollback Phase 1 and retry Phase 0 + +### Phase 1.5 — Refactor rbac stack for multi-master (~45 min) + +- [ ] **1.5.1 Refactor `stacks/rbac/modules/rbac/{apiserver-oidc,audit-policy,etcd-tuning}.tf`** + - [ ] Replace `var.k8s_master_host = "10.0.20.100"` with `var.k8s_master_hosts = list(string)` (default `["10.0.20.100"]`) + - [ ] Wrap each `null_resource` / `provisioner "remote-exec"` block in `for_each = toset(var.k8s_master_hosts)` so the same sed runs on every master + - [ ] In `stacks/rbac/main.tf` set `k8s_master_hosts = ["10.0.20.100"]` (still single-master in this phase — variable is forward-looking, no behaviour change yet) +- [ ] **1.5.2 `scripts/tg apply` rbac stack** — confirm zero diff against today (no-op refactor) +- [ ] **1.5.3 Verify** — sanity: `ssh wizard@k8s-master 'sudo grep oidc-issuer-url /etc/kubernetes/manifests/kube-apiserver.yaml | wc -l'` — expect `1`. Cluster healthy. + +### Phase 2 — Cloud-init template bump + master-2 (~75 min) + +- [ ] **2.0 Bump cloud-init template (one-time)** + - [ ] Edit `infra/modules/create-template-vm/cloud_init.yaml`: + - line 49: apt source `pkgs.k8s.io/core:/stable:/v1.32/deb/` → `pkgs.k8s.io/core:/stable:/v1.34/deb/` + - line 135: wrap `${k8s_join_command}` in a conditional via cloud-init `if:` template logic, or simpler: add `${k8s_join_command_or_noop}` and let the module pass `""` for masters and the real worker join command for workers (default) + - [ ] Update `infra/modules/create-template-vm/main.tf` to add `variable "k8s_join_command" { default = "" }` and a conditional in the templatefile to skip the runcmd line when empty + - [ ] Rebuild the template: `scripts/tg apply -target=module.k8s_template` (or whatever the existing template-build target name is in `stacks/infra/main.tf`) + - [ ] Verify new template registered in Proxmox at the same template_id +- [ ] **2.1 Add master-2 VM to Terraform** + - [ ] In `stacks/infra/main.tf`: add `module "k8s-master-2"` using `create-vm` from the (now-v1.34) k8s template, with master sizing (8 vCPU / 32GB / 64GB), VMID 205, IP `10.0.20.110`, unique MAC, `vmbr1/vlan 20`, `use_cloud_init = true`, and explicitly pass `k8s_join_command = ""` (so first-boot does NOT auto-join as worker) + - [ ] `scripts/tg apply -target=module.k8s-master-2` + - [ ] Verify VM booted: `ssh wizard@k8s-master-2.viktorbarzin.lan uname -a` (expect Ubuntu 26.04 LTS, kernel 7.0.x) +- [ ] **2.2 Prep master-2 for kubeadm join** + - [ ] Confirm versions: `ssh wizard@k8s-master-2.viktorbarzin.lan 'kubeadm version; containerd --version'` — expect kubeadm v1.34.x, containerd 2.2.2+ + - [ ] DNS resolves: `getent hosts k8s-master-2.viktorbarzin.lan` +- [ ] **2.3 Upload certs on existing master** + - [ ] `sudo kubeadm init phase upload-certs --upload-certs` → records `--certificate-key ` + - [ ] **2h TTL** — Phase 2 + 3 must complete within window or re-upload +- [ ] **2.4 Generate join command** + - [ ] `sudo kubeadm token create --print-join-command` → `kubeadm join 10.0.20.99:6443 --token --discovery-token-ca-cert-hash sha256:` + - [ ] Append `--control-plane --certificate-key ` +- [ ] **2.5 Run join on master-2** + - [ ] `ssh wizard@k8s-master-2.viktorbarzin.lan` → run sudo join command from 2.4 + - [ ] Wait for "This node has joined the cluster" +- [ ] **2.6 Update rbac stack to include master-2 (propagates OIDC/audit/etcd tuning to it)** + - [ ] Edit `stacks/rbac/main.tf`: `k8s_master_hosts = ["10.0.20.100", "10.0.20.110"]` + - [ ] `scripts/tg apply` rbac stack + - [ ] Verify: `ssh wizard@k8s-master-2 'sudo grep -c oidc-issuer-url /etc/kubernetes/manifests/kube-apiserver.yaml'` — expect `1` +- [ ] **2.7 Smoke** + - [ ] `kubectl get nodes` — 6 nodes, master-2 Ready control-plane + - [ ] `kubectl -n kube-system get pods -o wide | grep k8s-master-2` — 4 static pods Running + - [ ] etcd member list shows 2 members + - [ ] `kubectl --server=https://10.0.20.110:6443 get nodes` — direct probe works +- [ ] **2.8 Add master-2 to LB pool** + - [ ] Edit `pfsense-haproxy-bootstrap.php`: pool now `[['k8s-master', '10.0.20.100'], ['k8s-master-2', '10.0.20.110']]` + - [ ] Deploy + verify both backends UP + +### Phase 3 — master-3 (~45 min) — same pattern as Phase 2 + +- [ ] **3.1 Add `module.k8s-master-3` to Terraform** (VMID 206, IP `10.0.20.111`, same template, `k8s_join_command = ""`) +- [ ] **3.2 Prep verify** +- [ ] **3.3 Re-upload certs if >2h since Phase 2.3, refresh `--certificate-key`** +- [ ] **3.4 Generate fresh join command** +- [ ] **3.5 Run join on master-3** +- [ ] **3.6 Update rbac stack: `k8s_master_hosts = [".100", ".110", ".111"]`, apply, verify master-3 has OIDC flag** +- [ ] **3.7 Smoke (7 nodes, 3 control-plane, etcd quorum 3/3)** +- [ ] **3.8 Add master-3 to LB pool — all three backends UP** + +### Phase 4 — Cut over clients and workers to VIP (~45 min) + +- [ ] **4.1 Update in-repo kubeconfig consumers (single commit)** + - [ ] `/home/wizard/code/infra/config` — flip `server:` to `https://10.0.20.99:6443` + - [ ] `config.tfvars:231` — `k8s_join_command` to `kubeadm join 10.0.20.99:6443 ...` + - [ ] `stacks/rbac/modules/rbac/apiserver-oidc.tf` — variable `default = "10.0.20.99"` (or whatever the multi-master refactor needs) + - [ ] `.woodpecker/default.yml` — flip server: AND curl URL + - [ ] `.woodpecker/drift-detection.yml` — flip server: AND curl URL + - [ ] `.woodpecker/renew-tls.yml` — flip curl URL (line 18) + - [ ] `.woodpecker/provision-user.yml` — flip curl URL (line 41) + - [ ] `stacks/k8s-portal/modules/k8s-portal/files/src/routes/download/+server.ts` — `CLUSTER_SERVER` const + - [ ] `stacks/k8s-portal/modules/k8s-portal/files/src/routes/setup/script/+server.ts` — same + - [ ] Final sweep: `cd /home/wizard/code/infra && grep -rn '10.0.20.100:6443' --include='*.tf' --include='*.yml' --include='*.yaml' --include='*.ts' --include='*.php' --include='*.sh'` — handle anything remaining + - [ ] `scripts/tg apply` for rbac + k8s-portal (and any other stacks touched) + - [ ] Commit + push (single conventional commit referencing `code-n0ow`) +- [ ] **4.2 Worker `kubelet.conf` flip (one at a time, with 5-10s expected NotReady)** + ```bash + for n in k8s-node1 k8s-node2 k8s-node3 k8s-node4; do + echo "=== $n ===" + ssh wizard@$n.viktorbarzin.lan "sudo sed -i.bak 's|server: https://10.0.20.100:6443|server: https://10.0.20.99:6443|' /etc/kubernetes/kubelet.conf" + ssh wizard@$n.viktorbarzin.lan "sudo systemctl restart kubelet" + kubectl wait --for=condition=Ready node/$n --timeout=180s + echo "$n Ready" + sleep 15 + done + ``` +- [ ] **4.3 Existing master's `kubelet.conf`** — same sed + restart on `k8s-master` +- [ ] **4.4 Verify master-2 + master-3 kubelet.conf already at VIP** (cloud-init join used VIP via controlPlaneEndpoint) +- [ ] **4.5 Verify everything** + - [ ] `kubectl get nodes` — all 7 Ready + - [ ] `kubectl --kubeconfig ~/.kube/config config view --minify -o jsonpath='{.clusters[0].cluster.server}'` → `https://10.0.20.99:6443` + - [ ] Worker loop: `for n in k8s-{master,node1,node2,node3,node4,master-2,master-3}; do ssh wizard@$n.viktorbarzin.lan "sudo grep server: /etc/kubernetes/kubelet.conf"; done` — all show VIP + - [ ] Trigger a no-op Woodpecker pipeline (commit a typo fix in a runbook) — verify the kubeconfig path through the new VIP + +### Phase 4.5 — Fix etcd-backup CronJob node pinning (~15 min) + +- [ ] **4.5.1 Edit `stacks/infra-maintenance/modules/infra-maintenance/main.tf`** + - [ ] backup-etcd (line 98): replace `node_name = "k8s-master"` with `nodeSelector { "node-role.kubernetes.io/control-plane" = "" }` + the corresponding toleration block + - [ ] defrag-etcd (line 218): same change +- [ ] **4.5.2 `scripts/tg apply` infra-maintenance** +- [ ] **4.5.3 Verify backup runs** — trigger a manual job-from-cronjob, confirm it lands on one of the 3 masters and produces a valid snapshot + +### Phase 5 — kured-sentinel-gate quorum check (~15 min) + +- [ ] **5.1 Edit `infra/stacks/kured/main.tf`** (insert into the bash heredoc in the sentinel-gate ConfigMap, between all-nodes-Ready and calico-Ready checks) + ```bash + # Check 3b: control-plane quorum safety (HA invariant) + CP_READY=$(kubectl get nodes -l node-role.kubernetes.io/control-plane= --no-headers | grep ' Ready ' | wc -l | tr -d ' ') + if [ "$CP_READY" -lt 2 ]; then + echo " BLOCKED: Only $CP_READY control-plane node(s) Ready (need ≥2 for HA)" + rm -f /host/var-run/gated-reboot-required + sleep 300 + continue + fi + echo " Control-plane quorum safe ($CP_READY Ready)" + ``` +- [ ] **5.2 `scripts/tg apply` kured** +- [ ] **5.3 Verify** + - [ ] `kubectl -n kured logs ds/kured-sentinel-gate | tail -50` — expect "Control-plane quorum safe (3 Ready)" line + - [ ] Negative test: cordon `k8s-master-2`, wait for the gate to re-evaluate, confirm block message. Restore. + +### Phase 6 — E2E validation (~30 min) + +- [ ] **6.1 Failover test** + - [ ] `kubectl drain k8s-master --delete-emptydir-data --ignore-daemonsets` + - [ ] `ssh wizard@k8s-master.viktorbarzin.lan sudo reboot` + - [ ] During the 50-90s reboot: tight loop `while true; do kubectl get nodes -o name | wc -l; sleep 2; done` from devvm — line count never drops to 0 (LB transparent) + - [ ] After boot: `kubectl uncordon k8s-master`, verify apiserver static pod re-registers in LB pool (op_state=2) +- [ ] **6.2 All-masters apiserver flag parity** + - [ ] `for h in k8s-master k8s-master-2 k8s-master-3; do echo "=== $h ==="; ssh wizard@$h.viktorbarzin.lan 'sudo grep -E "oidc-issuer-url|audit-policy|auto-compaction-retention|snapshot-count" /etc/kubernetes/manifests/{kube-apiserver,etcd}.yaml | sort'; done` + - [ ] Expect identical flag set across all 3 masters +- [ ] **6.3 Update documentation** + - [ ] Add `docs/architecture/control-plane.md` — HA topology, etcd member list, LB config location + - [ ] Update `.claude/reference/proxmox-inventory.md` — add VMIDs 205, 206 + - [ ] Add `docs/runbooks/control-plane-add-remove-master.md` + - [ ] Update `docs/runbooks/restore-etcd.md` to cover 3-member quorum restore (was single-master only) + - [ ] Cross-link `docs/runbooks/mailserver-pfsense-haproxy.md` with the new apiserver_proxy_6443 pool + +### Phase 7 — Extend k8s-version-upgrade chain to multi-master (~60 min) + +- [ ] **7.1 Edit `stacks/k8s-version-upgrade/scripts/upgrade-step.sh`** + - [ ] phase_master: discover masters dynamically — `MASTERS=$($KUBECTL get nodes -l node-role.kubernetes.io/control-plane= -o name | sed 's|node/||')` + - [ ] Wrap drain → `update_k8s.sh` → uncordon → wait-ready in a `for m in $MASTERS; do ... done` loop + - [ ] Between masters: quorum check — `READY=$($KUBECTL get nodes -l node-role.kubernetes.io/control-plane= --no-headers | grep ' Ready ' | wc -l); [ $READY -ge 2 ] || { slack "ABORT quorum lost"; exit 1; }` + - [ ] Update line 9 + 17 comment block to reflect multi-master phase + - [ ] Update line 326-340 containerd-bump section to loop over masters +- [ ] **7.2 Edit `phase_preflight` and the master phase pin** + - [ ] Line 209-210 (scheduling_block): allow any control-plane node to be the target + - [ ] Line 285 (`kubeadm upgrade plan` check): run against the first master in the list, not specifically `k8s-master` +- [ ] **7.3 `scripts/tg apply` k8s-version-upgrade** +- [ ] **7.4 Dry-run test** + - [ ] `kubectl -n k8s-upgrade create job --from=cronjob/k8s-version-check ha-validation-$(date +%s)` (no actual upgrade pending — chain should noop the upgrade phase but exercise the discovery loop) + - [ ] Verify logs show 3 masters discovered in correct order +- [ ] **7.5 (Real test on next patch release)** — when 1.34.8 ships: + - [ ] Watch the chain execute drain → upgrade → uncordon across all 3 masters in turn + - [ ] Confirm no manual intervention needed + +### Phase 8 — Close out + +- [ ] **8.1 Update beads** — `bd close code-n0ow` once all 6 acceptance criteria met (see below) + +## Rollback plan + +### Before Phase 4 (no clients flipped) + +- **Phase 0**: restore apiserver cert/key from `/tmp/apiserver-backup/`, edit kubeadm-config back, restart kubelet on master. +- **Phase 1**: remove `apiserver_proxy_6443` + `apiserver_nodes` from `pfsense-haproxy-bootstrap.php`, re-run; revert DNS A record in config.tfvars. +- **Phase 1.5**: revert rbac stack to single `k8s_master_host` var; apply. +- **Phase 2/3**: on failed master `sudo kubeadm reset --force`; from a surviving master `etcdctl member remove `; `tg destroy -target=module.k8s-master-N`. + +### After Phase 4 (clients flipped) + +- Revert all the Phase 4.1 file changes (single revert commit). +- Reverse the kubelet.conf sed loop (VIP → direct IP) on all 7 nodes. +- Phase 0 controlPlaneEndpoint can stay — harmless even on full rollback. + +### Worst case (etcd corruption / multi-master split-brain) + +- Restore from latest etcd snapshot via `etcdctl snapshot restore` to a single master. +- Rebuild master VM from the Proxmox snapshot taken in Phase 0.1. +- Cluster back to single-master. + +## Acceptance criteria (beads `code-n0ow`) + +- [ ] 1. Design doc + plan doc written ✓ (this commit) +- [ ] 2. Plan approved by user +- [ ] 3. 3 masters online, etcd quorum healthy, apiserver LB working +- [ ] 4. k8s upgrade chain runs end-to-end across **all 3 masters** without manual intervention (Phase 7) +- [ ] 5. kured-sentinel-gate respects quorum (Phase 5) +- [ ] 6. etcd backup runs from any control-plane node (Phase 4.5) + +## Open questions + +None — all locked via 2026-05-22 decision pass + challenger amendment pass. diff --git a/scripts/update_k8s.sh b/scripts/update_k8s.sh index f98ea30a..6e01d654 100755 --- a/scripts/update_k8s.sh +++ b/scripts/update_k8s.sh @@ -89,17 +89,26 @@ if [[ "$ROLE" == "master" ]]; then # sync latency post-master-reboot can exceed it). The etcd image IS # actually updated by then, so a 2nd attempt sees etcd already on # target and skips it. Up to 3 attempts with a 30s delay between. + # First attempt: full kubeadm upgrade (incl. etcd). On the static-pod- + # hash 5min-timeout failure, retry with --etcd-upgrade=false. The + # timeout happens reliably for patch upgrades where etcd's image + # doesn't change (kubeadm writes identical manifest → hash doesn't + # change → kubeadm waits forever for a change that will never come). + # Skipping the etcd phase on retry is safe IF etcd is already on the + # right version (which is the only case where this timeout fires). attempt=1 - while ! sudo kubeadm upgrade apply "v$RELEASE" -y; do + extra_flags="" + while ! sudo kubeadm upgrade apply "v$RELEASE" -y $extra_flags; do if (( attempt >= 3 )); then echo "ERROR: kubeadm upgrade apply failed after 3 attempts" >&2 exit 1 fi - echo "==> kubeadm apply attempt $attempt failed (likely static-pod-hash 5m timeout). Sleeping 30s then retrying — the previous attempt's manifest writes usually take hold on the 2nd try." + echo "==> kubeadm apply attempt $attempt failed. Retrying with --etcd-upgrade=false (etcd image is unchanged for patch upgrades; kubeadm's static-pod-hash watch is the only thing failing)." + extra_flags="--etcd-upgrade=false" sleep 30 attempt=$(( attempt + 1 )) done - echo "==> kubeadm upgrade apply succeeded on attempt $attempt" + echo "==> kubeadm upgrade apply succeeded on attempt $attempt (flags: '$extra_flags')" else echo "==> Worker path: kubeadm upgrade node" sudo kubeadm upgrade node diff --git a/secrets/fullchain.pem b/secrets/fullchain.pem index 915a1c2d..6a978c8f 100644 Binary files a/secrets/fullchain.pem and b/secrets/fullchain.pem differ diff --git a/secrets/privkey.pem b/secrets/privkey.pem index 0f920600..6436c083 100644 Binary files a/secrets/privkey.pem and b/secrets/privkey.pem differ diff --git a/stacks/blog/main.tf b/stacks/blog/main.tf index a8193789..3cea7e1e 100644 --- a/stacks/blog/main.tf +++ b/stacks/blog/main.tf @@ -150,19 +150,6 @@ module "ingress" { } } -module "ingress-www" { - source = "../../modules/kubernetes/ingress_factory" - auth = "none" # Anubis-fronted; PoW challenge gates bots, no Authentik - namespace = kubernetes_namespace.website.metadata[0].name - name = "blog-www" - service_name = module.anubis.service_name - port = module.anubis.service_port - extra_middlewares = ["traefik-x402@kubernetescrd"] - full_host = "www.viktorbarzin.me" - tls_secret_name = var.tls_secret_name - anti_ai_scraping = false -} - # CI retrigger 2026-05-16T13:42:57+00:00 — bulk enrollment apply (pipeline #689 killed) # CI retrigger v2 2026-05-16T13:46:35+00:00 diff --git a/stacks/broker-sync/main.tf b/stacks/broker-sync/main.tf index 59cbcdb1..b27c4eb9 100644 --- a/stacks/broker-sync/main.tf +++ b/stacks/broker-sync/main.tf @@ -271,10 +271,20 @@ resource "kubernetes_cron_job_v1" "imap" { } spec { restart_policy = "OnFailure" + # The broker image's user is uid=10001 gid=999, but the shared + # data PVC's /data root was created with gid=10001 (legacy from + # an earlier image build). Without fsGroup the pod can't write + # to the directory — sqlite3 can't create the journal next to + # sync.db, hits 'attempt to write a readonly database'. + # fsGroup=10001 adds the matching gid to the pod's supplemental + # groups so writes succeed. + security_context { + fs_group = 10001 + } container { name = "broker-sync" image = local.broker_sync_image - command = ["broker-sync", "imap"] + command = ["broker-sync", "imap-ingest"] env { name = "BROKER_SYNC_DATA_DIR" diff --git a/stacks/claude-agent-service/main.tf b/stacks/claude-agent-service/main.tf index 7001c79d..2187f52f 100644 --- a/stacks/claude-agent-service/main.tf +++ b/stacks/claude-agent-service/main.tf @@ -454,10 +454,10 @@ resource "kubernetes_deployment" "claude_agent" { resources { requests = { cpu = "500m" - memory = "2Gi" + memory = "1Gi" } limits = { - memory = "4Gi" + memory = "2Gi" } } } diff --git a/stacks/cloudflared/modules/cloudflared/cloudflare.tf b/stacks/cloudflared/modules/cloudflared/cloudflare.tf index 05afd6b6..b5eb0490 100644 --- a/stacks/cloudflared/modules/cloudflared/cloudflare.tf +++ b/stacks/cloudflared/modules/cloudflared/cloudflare.tf @@ -145,16 +145,6 @@ resource "cloudflare_record" "mail_mx" { } -resource "cloudflare_record" "mail_domainkey" { - content = "\"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIDLB8mhAHNqs1s6GeZMQHOxWweoNKIrqo5tqRM3yFilgfPUX34aTIXNZg9xAmlK+2S/xXO1ymt127ZGMjnoFKOEP8/uZ54iHTCnioHaPZWMfJ7o6TYIXjr+9ShKfoJxZLv7lHJ2wKQK3yOw4lg4cvja5nxQ6fNoGRwo+mQ/mgJQIDAQAB\"" - name = "s1._domainkey.viktorbarzin.me" - proxied = false - ttl = 1 - type = "TXT" - priority = 1 - zone_id = var.cloudflare_zone_id -} - resource "cloudflare_record" "mail_spf" { # Brevo replaced Mailgun as the outbound relay on 2026-04-12 (see docs/architecture/mailserver.md). # Soft-fail (~all) is intentional during cutover — revisit once relay delivery is stable. diff --git a/stacks/cnpg/modules/cnpg/main.tf b/stacks/cnpg/modules/cnpg/main.tf index 8f16262f..c6b9a595 100644 --- a/stacks/cnpg/modules/cnpg/main.tf +++ b/stacks/cnpg/modules/cnpg/main.tf @@ -47,6 +47,16 @@ resource "helm_release" "cnpg" { memory = "256Mi" } } + + # Tune webhook-cert renewal threshold. CNPG default is 7 days remaining, + # which leaves no buffer when the cluster-health check (#22) flags + # certs at <30d. Bump to 30 days so the operator rotates well before + # external monitoring notices. Cert lifetime stays at chart default 90d. + config = { + data = { + EXPIRING_CHECK_THRESHOLD = "30" + } + } })] } diff --git a/stacks/crowdsec/modules/crowdsec/values.yaml b/stacks/crowdsec/modules/crowdsec/values.yaml index 385ae4a7..452caab8 100644 --- a/stacks/crowdsec/modules/crowdsec/values.yaml +++ b/stacks/crowdsec/modules/crowdsec/values.yaml @@ -5,7 +5,7 @@ agent: resources: requests: cpu: 25m - memory: 64Mi + memory: 128Mi limits: memory: 512Mi priorityClassName: "tier-1-cluster" diff --git a/stacks/k8s-version-upgrade/main.tf b/stacks/k8s-version-upgrade/main.tf index 530db98e..e91592aa 100644 --- a/stacks/k8s-version-upgrade/main.tf +++ b/stacks/k8s-version-upgrade/main.tf @@ -172,11 +172,22 @@ resource "kubernetes_cluster_role" "k8s_upgrade_job" { # --ignore-daemonsets` can classify each pod's owner. Without daemonsets # GET permission, drain bails with "cannot delete daemonsets ... is # forbidden" for every daemonset-managed pod on the node. (2026-05-20) + # + # `patch` on deployments added 2026-05-23: phase_master scales tigera-operator + # to 0 before drain (operator crashloops during apiserver static-pod swaps, + # generates I/O storm that breaks kubeadm's 5-min watch) and back to 1 + # after master is upgraded. Until HA control plane lands (beads code-n0ow), + # this is how we keep autonomous upgrades unblocked. rule { api_groups = ["apps"] resources = ["daemonsets", "statefulsets", "replicasets", "deployments"] verbs = ["get", "list"] } + rule { + api_groups = ["apps"] + resources = ["deployments", "deployments/scale"] + verbs = ["patch", "update"] + } # Chain dispatch — create the next Job; reconcile via apply on retry. # In `default` ns to also create the etcd-snapshot Job from cronjob/backup-etcd. rule { @@ -359,11 +370,17 @@ resource "kubernetes_cron_job_v1" "k8s_version_check" { exit 0 fi - # 1. Detect running version + # 1. Detect running version — use the OLDEST kubelet across + # all nodes so partial chains (e.g. master upgraded but + # workers still pending) don't trick the chain into + # thinking the upgrade is complete. Was `.items[0]` (master + # only) which made the chain skip when workers were behind. + # Fixed 2026-05-23 after node4-only chain failure. RUNNING=$(/usr/local/bin/kubectl get nodes \ - -o jsonpath='{.items[0].status.nodeInfo.kubeletVersion}' | tr -d v) + -o jsonpath='{range .items[*]}{.status.nodeInfo.kubeletVersion}{"\n"}{end}' \ + | tr -d v | sort -V | head -1) RUNNING_MINOR=$(echo "$RUNNING" | awk -F. '{print $1"."$2}') - echo "Running version: v$RUNNING (minor $RUNNING_MINOR)" + echo "Running version (oldest kubelet): v$RUNNING (minor $RUNNING_MINOR)" # 2. Latest patch within current minor (refresh master's apt cache) LATEST_PATCH=$($SSH wizard@k8s-master.viktorbarzin.lan \ diff --git a/stacks/k8s-version-upgrade/scripts/upgrade-step.sh b/stacks/k8s-version-upgrade/scripts/upgrade-step.sh index 74c93bc7..b10b395d 100644 --- a/stacks/k8s-version-upgrade/scripts/upgrade-step.sh +++ b/stacks/k8s-version-upgrade/scripts/upgrade-step.sh @@ -94,18 +94,41 @@ push() { halt_on_alert_query() { local extra_ignore="${1:-}" - local regex='^(Watchdog|RebootRequired|KuredNodeWasNotDrained|InfoInhibitor' - [ -n "$extra_ignore" ] && regex="$regex|$extra_ignore" - regex="$regex)$" + # ALLOWLIST design (refactored 2026-05-23 from a denylist): halt only on + # alerts with severity=critical. Any warning/info-level alert is treated + # as informational and doesn't block the chain. + # + # Why this is the right model: + # - The cluster has long-running warning-level alerts that are NOT + # blockers for a k8s patch (e.g. GPU operator crashloop on the GPU + # node, ingress latency spikes, IO-wait warnings). + # - Maintaining a denylist of every "noisy" alert is a losing battle. + # - Critical alerts are the only ones that should actually stop us + # mid-chain (apiserver down, etcd down, node not ready, etc.). + # + # `extra_ignore` is now mostly historical — kept for backwards compat with + # `halt_on_alert_query "RecentNodeReboot|IngressTTFBCritical"`-style calls. With severity-based + # filtering, RecentNodeReboot (severity=info) is filtered automatically. + # We still build the regex for any critical alert the caller wants to + # explicitly ignore (e.g. a known-broken thing we're aware of). + local ignore_regex="" + [ -n "$extra_ignore" ] && ignore_regex="^($extra_ignore)\$" - # `grep -vE` returns 1 when nothing matches, which under `set -o pipefail` - # bubbles up and (via the caller's `alerts=$(...)`) aborts the whole script. - # Trailing `|| true` keeps a no-alerts-firing cluster from looking like a - # script error. Discovered 2026-05-19 when the chain wouldn't fire on a - # genuinely-clean cluster (every alert was Watchdog/RebootRequired/etc.). - curl -sf "$PROM/api/v1/alerts" \ - | jq -r '.data.alerts[] | select(.state == "firing") | .labels.alertname' \ - | { grep -vE "$regex" || true; } | sort -u + # `grep` returns 1 when nothing matches → under `set -o pipefail` that + # bubbles up and aborts the script via the caller's `alerts=$(...)`. + # Trailing `|| true` on each grep handles the no-matches case. + local critical_firing + critical_firing=$(curl -sf "$PROM/api/v1/alerts" \ + | jq -r '.data.alerts[] + | select(.state == "firing" and .labels.severity == "critical") + | .labels.alertname' 2>/dev/null \ + | sort -u || true) + + if [ -n "$ignore_regex" ]; then + echo "$critical_firing" | { grep -vE "$ignore_regex" || true; } + else + echo "$critical_firing" + fi } wait_for_node_ready() { @@ -257,7 +280,7 @@ phase_preflight() { # is set, often daily). Now skipped — check 3 is the single source of truth # for "is the cluster quiet enough to upgrade". local alerts - alerts=$(halt_on_alert_query RecentNodeReboot) + alerts=$(halt_on_alert_query "RecentNodeReboot|IngressTTFBCritical") if [ -n "$alerts" ]; then slack "ABORT preflight — firing alerts:\n$alerts" exit 1 @@ -357,15 +380,46 @@ phase_preflight() { } phase_master() { + # Idempotency: skip the whole phase if k8s-master is already on target. + # The chain can re-run after a partial failure (e.g. workers got cut + # short); without this short-circuit we re-drain and re-kubeadm an + # already-upgraded master for no reason. Added 2026-05-23. + local current_v + current_v=$($KUBECTL get node k8s-master -o jsonpath='{.status.nodeInfo.kubeletVersion}' 2>/dev/null | tr -d v) + if [ "$current_v" = "$TARGET_VERSION" ]; then + slack "k8s-master already on v$TARGET_VERSION (kubelet=$current_v) — skipping master phase" + echo "k8s-master already on v$TARGET_VERSION — skipping" + return 0 + fi + slack "Draining k8s-master" # Re-check halt-on-alert before drain. Always ignore RecentNodeReboot — # the chain itself causes node reboots, so this alert firing is expected # mid-chain (e.g. master was already upgraded+rebooted before this phase). local alerts - alerts=$(halt_on_alert_query RecentNodeReboot) + alerts=$(halt_on_alert_query "RecentNodeReboot|IngressTTFBCritical") [ -n "$alerts" ] && { slack "ABORT master — alerts firing pre-drain: $alerts"; exit 1; } + # Quiesce noisy operators that crashloop when apiserver briefly disappears + # during the static-pod manifest swaps. The crashloop generates a disk-I/O + # storm (~500 MB/s observed from tigera-operator alone) that slows the + # apiserver↔kubelet status sync past kubeadm's hardcoded 5-min watch on + # `kubernetes.io/config.hash`, causing kubeadm to roll back the upgrade. + # + # The data plane (calico-node DaemonSet, calico-typha, calico-kube-controllers) + # keeps running unchanged — only the OPERATOR (a config reconciler) goes away + # briefly. Restored at the end of the phase below. + # + # If the chain dies between quiesce and restore (e.g. kubeadm fails), + # manually restore with: + # kubectl -n tigera-operator scale deploy tigera-operator --replicas=1 + # + # Long-term fix: HA control plane (3 masters) so apiserver never goes down + # — see docs/plans/2026-05-21-ha-control-plane-{design,plan}.md (beads code-n0ow). + echo "Quiescing tigera-operator before master upgrade (it crashes on apiserver outage)" + $KUBECTL -n tigera-operator scale deploy tigera-operator --replicas=0 2>&1 || true + drain_node k8s-master slack "Running update_k8s.sh on k8s-master (--role master --release $TARGET_VERSION)" @@ -387,21 +441,37 @@ phase_master() { exit 1 fi - alerts=$(halt_on_alert_query RecentNodeReboot) + alerts=$(halt_on_alert_query "RecentNodeReboot|IngressTTFBCritical") [ -n "$alerts" ] && { slack "ABORT master — alerts firing post-upgrade: $alerts"; exit 1; } + # Restore tigera-operator (quiesced before drain). It reconciles in seconds. + echo "Restoring tigera-operator" + $KUBECTL -n tigera-operator scale deploy tigera-operator --replicas=1 2>&1 || true + slack "Master on v$TARGET_VERSION, control-plane Running. Dispatching worker chain." } phase_worker() { [ -z "$TARGET_NODE" ] && { echo "ERROR: worker phase requires TARGET_NODE"; exit 2; } + + # Idempotency: skip if target node is already on target version. Same + # rationale as phase_master — chains re-running after partial completion + # shouldn't re-drain an already-upgraded worker. Added 2026-05-23. + local current_v + current_v=$($KUBECTL get node "$TARGET_NODE" -o jsonpath='{.status.nodeInfo.kubeletVersion}' 2>/dev/null | tr -d v) + if [ "$current_v" = "$TARGET_VERSION" ]; then + slack "$TARGET_NODE already on v$TARGET_VERSION (kubelet=$current_v) — skipping worker phase" + echo "$TARGET_NODE already on v$TARGET_VERSION — skipping" + return 0 + fi + slack "Draining $TARGET_NODE" # Halt-on-alert wait (up to 30 min). Ignore RecentNodeReboot — the chain # just rebooted a node, that's the cause and is expected. local attempt alerts for attempt in $(seq 1 30); do - alerts=$(halt_on_alert_query RecentNodeReboot) + alerts=$(halt_on_alert_query "RecentNodeReboot|IngressTTFBCritical") [ -z "$alerts" ] && break echo "Waiting for alerts to clear (attempt $attempt/30): $alerts" sleep 60 @@ -432,7 +502,7 @@ phase_worker() { # 10-min soak with halt-on-alert (RecentNodeReboot ignored — we know we restarted it) echo "Soaking $TARGET_NODE for 10 min..." for i in $(seq 1 10); do - alerts=$(halt_on_alert_query RecentNodeReboot) + alerts=$(halt_on_alert_query "RecentNodeReboot|IngressTTFBCritical") [ -n "$alerts" ] && { slack "ABORT $TARGET_NODE mid-soak — alerts: $alerts"; exit 1; } sleep 60 done @@ -458,7 +528,7 @@ phase_postflight() { # No alerts firing. Ignore RecentNodeReboot — by definition we just # rebooted every node; this alert clears naturally in <1h. local alerts - alerts=$(halt_on_alert_query RecentNodeReboot) + alerts=$(halt_on_alert_query "RecentNodeReboot|IngressTTFBCritical") [ -n "$alerts" ] && slack "Postflight WARN — alerts still firing (cluster on target, please check):\n$alerts" # Pod-ready ratio diff --git a/stacks/kyverno/modules/kyverno/security-policies.tf b/stacks/kyverno/modules/kyverno/security-policies.tf index 7f11007d..163031ec 100644 --- a/stacks/kyverno/modules/kyverno/security-policies.tf +++ b/stacks/kyverno/modules/kyverno/security-policies.tf @@ -328,25 +328,35 @@ resource "kubectl_manifest" "policy_require_trusted_registries" { "docker.n8n.io/*", "registry.gitlab.com/*", # Private "forgejo.viktorbarzin.me/*", "10.0.20.10*", + # Legacy private registry (decommissioned 2026-05-07 per CLAUDE.md + # but council-complaints still references — migrate to Forgejo). + "registry.viktorbarzin.me/*", # DockerHub library (bare image names without slash) "alpine*", "busybox*", "kong*", "mysql*", "nginx*", "postgres*", "python*", # DockerHub user repos (no registry prefix, has slash) — - # enumerated from current cluster state. - "actualbudget/*", "afadil/*", "binwiederhier/*", "bitnami/*", + # enumerated from current cluster state. New entries added + # 2026-05-22 after Enforce caught these as unallowlisted: + # amruthpillai (resume), athomasson2 (ebook2audiobook), + # netboxcommunity (netbox), nousresearch (hermes-agent), + # opentripplanner (osm-routing), rhasspy (whisper/piper). + "actualbudget/*", "afadil/*", "amruthpillai/*", "athomasson2/*", + "binwiederhier/*", "bitnami/*", "clickhouse/*", "cloudflare/*", "coturn/*", "crowdsecurity/*", "curlimages/*", "deluan/*", "dgtlmoon/*", "dolthub/*", "dpage/*", "dperson/*", "edoburu/*", "esanchezm/*", "freikin/*", "freshrss/*", "hackmdio/*", "hashicorp/*", "headscale/*", "jhonderson/*", "kebe/*", "library/*", "lissy93/*", "louislam/*", "matrixdotorg/*", "mendhak/*", - "mghee/*", "mindflavor/*", "mpepping/*", "netsampler/*", - "nvidia/*", "onlyoffice/*", "openresty/*", "owntracks/*", + "mghee/*", "mindflavor/*", "mpepping/*", "netboxcommunity/*", + "netsampler/*", "nousresearch/*", "nvidia/*", "onlyoffice/*", + "openresty/*", "opentripplanner/*", "owntracks/*", "phpipam/*", "phpmyadmin/*", "privatebin/*", "prom/*", - "prompve/*", "rancher/*", "roundcube/*", "sclevine/*", + "prompve/*", "rancher/*", "rhasspy/*", "roundcube/*", "sclevine/*", "shadowsocks/*", "shlinkio/*", "stirlingtools/*", "technitium/*", "teddysun/*", "temporalio/*", "typhonragewind/*", "tzahi12345/*", "vabene1111/*", - "vaultwarden/*", "viktorbarzin/*", "viren070/*", "zelest/*", + "vaultwarden/*", "viktorbarzin/*", "viren070/*", + "woodpeckerci/*", "zelest/*", ]) }] } diff --git a/stacks/llama-cpp/main.tf b/stacks/llama-cpp/main.tf index 13b3cb3b..3d3c5ac4 100644 --- a/stacks/llama-cpp/main.tf +++ b/stacks/llama-cpp/main.tf @@ -373,10 +373,22 @@ resource "kubernetes_deployment" "llama_swap" { lifecycle { ignore_changes = [ spec[0].template[0].spec[0].dns_config, # KYVERNO_LIFECYCLE_V1 + metadata[0].annotations["keel.sh/match-tag"], metadata[0].annotations["keel.sh/policy"], metadata[0].annotations["keel.sh/trigger"], metadata[0].annotations["keel.sh/pollSchedule"], # KYVERNO_LIFECYCLE_V2 spec[0].template[0].spec[0].container[0].image, # KEEL_IGNORE_IMAGE + # KEEL_LIFECYCLE_V1 — stop the apply→keel fight: every keel digest + # update patches `keel.sh/update-time` on the pod template and + # `kubernetes.io/change-cause` + bumps the K8s rollout revision on + # the Deployment. Without these ignore_changes, every `tg apply` + # reverts those, forcing a rollout, which keel then re-patches on + # the next 1h poll → llama-swap was rolling several times a day + # (~10s model-load downtime each). Upstream :cuda nightly cadence + # still triggers a legitimate daily rollout. + metadata[0].annotations["kubernetes.io/change-cause"], + metadata[0].annotations["deployment.kubernetes.io/revision"], + spec[0].template[0].metadata[0].annotations["keel.sh/update-time"], ] } diff --git a/stacks/mailserver/modules/mailserver/main.tf b/stacks/mailserver/modules/mailserver/main.tf index cd502cf2..df193048 100644 --- a/stacks/mailserver/modules/mailserver/main.tf +++ b/stacks/mailserver/modules/mailserver/main.tf @@ -3,7 +3,7 @@ variable "tier" { type = string } variable "mailserver_accounts" {} variable "postfix_account_aliases" {} variable "opendkim_key" {} -variable "sasl_passwd" {} # For sendgrid i.e relayhost +variable "sasl_passwd" {} # SMTP relay (Brevo) SASL credentials variable "nfs_server" { type = string } # Build the virtual-alias map, dropping aliases where BOTH the source and # target are real mailboxes in var.mailserver_accounts (and are different). @@ -83,7 +83,6 @@ resource "kubernetes_config_map" "mailserver_env_config" { POSTFIX_MESSAGE_SIZE_LIMIT = 1024 * 1024 * 200 # 200 MB POSTFIX_REJECT_UNKNOWN_CLIENT_HOSTNAME = "1" # TLS_LEVEL = "intermediate" - # DEFAULT_RELAY_HOST = "[smtp.sendgrid.net]:587" DEFAULT_RELAY_HOST = "[smtp-relay.brevo.com]:587" SPOOF_PROTECTION = "1" SSL_TYPE = "manual" diff --git a/stacks/mailserver/modules/mailserver/variables.tf b/stacks/mailserver/modules/mailserver/variables.tf index 72d8f308..29d6665c 100644 --- a/stacks/mailserver/modules/mailserver/variables.tf +++ b/stacks/mailserver/modules/mailserver/variables.tf @@ -2,7 +2,6 @@ # see defaults - https://github.com/docker-mailserver/docker-mailserver/blob/master/target/postfix/main.cf variable "postfix_cf" { default = <50% drop vs. 10m ago, sustained for 5m. + # Absolute-count threshold removed 2026-05-18: routine drains + # routinely drop 10-30 containers and tripped the old `< -10` + # rule; only a >50% drop that persists 5m+ indicates a real + # node-level fault (kubelet hang, runtime crash, mass eviction). + expr: | + ( + (kubelet_running_containers{container_state="running"} - kubelet_running_containers{container_state="running"} offset 10m) + / kubelet_running_containers{container_state="running"} offset 10m + ) < -0.5 for: 5m labels: severity: critical annotations: - summary: "Running containers on {{ $labels.instance }} dropped by {{ $value | printf \"%.0f\" }} in 10m" + summary: "Running containers on {{ $labels.instance }} dropped >50% in 10m ({{ $value | printf \"%.2f\" }} ratio)" - alert: CalicoNodeNotReady expr: kube_daemonset_status_number_ready{namespace="calico-system", daemonset="calico-node"} < kube_daemonset_status_desired_number_scheduled{namespace="calico-system", daemonset="calico-node"} for: 5m @@ -1934,8 +1943,11 @@ serverFiles: annotations: summary: "Node {{ $labels.node }} kubelet started {{ $value | humanizeDuration }} ago — 1h settle window halts further reboots" - alert: MysqlStandaloneDown + # Single-replica StatefulSet: brief drain re-scheduling routinely + # takes 1-3 min during k8s upgrades. 3m suppresses those blips; + # real outages persist longer. Raised from 2m on 2026-05-18. expr: kube_statefulset_status_replicas_ready{statefulset="mysql-standalone"} < 1 - for: 2m + for: 3m labels: severity: critical annotations: @@ -2178,6 +2190,9 @@ serverFiles: annotations: summary: "Critically slow ingress on {{ $labels.service }}: avg latency {{ $value | printf \"%.2f\" }}s (threshold: 3s for 5m)" - alert: IngressErrorRate5xxHigh + # Rolling upgrades / pod migrations cause brief 5xx spikes that + # clear within 1-2 min. Only persistent 5xx indicates a real + # problem. Raised from 5m to 10m on 2026-05-18. expr: | ( sum(rate(traefik_service_requests_total{code=~"5..", service!~".*nextcloud.*"}[5m])) by (service) @@ -2186,11 +2201,11 @@ serverFiles: ) > 5 and sum(rate(traefik_service_requests_total{service!~".*nextcloud.*"}[5m])) by (service) > 0.1 and on() (time() - process_start_time_seconds{job="prometheus"}) > 900 - for: 5m + for: 10m labels: severity: critical annotations: - summary: "5xx rate on {{ $labels.service }}: {{ $value | printf \"%.1f\" }}% (threshold: 5% for 5m)" + summary: "5xx rate on {{ $labels.service }}: {{ $value | printf \"%.1f\" }}% (threshold: 5% for 10m)" - alert: AnubisChallengeStoreErrors # Anubis exposes only Go-runtime metrics on :9090 (no anubis_* / # challenge_* counters), so we proxy via Traefik 5xx on services @@ -2227,12 +2242,23 @@ serverFiles: annotations: summary: "Cloudflared: {{ $value | printf \"%.0f\" }} replica(s) unavailable" - alert: MetalLBSpeakerDown + # kubelet restart during k8s upgrade briefly takes the speaker + # pod down; typical recovery is 30-45s. The full drain+kubeadm+ + # apt+kubelet-restart+uncordon cycle in the chain's worker phase + # can take a single node out of MetalLB rotation for 5-7 min in + # the worst case (depending on PDB stickiness). 10m suppresses + # those upgrade-induced blips while still catching genuine + # speaker-down conditions. + # Reverted from 2m → 10m on 2026-05-23 after node4 upgrade + # tripped it mid-soak and aborted the chain. Previous value was + # 5m (set 2026-05-18) which was already correct; a brief patch + # had tightened it. expr: | ( kube_daemonset_status_desired_number_scheduled{namespace="metallb-system", daemonset="metallb-speaker"} - on(namespace, daemonset) kube_daemonset_status_number_ready{namespace="metallb-system", daemonset="metallb-speaker"} ) > 0 - for: 5m + for: 10m labels: severity: critical annotations: @@ -2337,6 +2363,30 @@ serverFiles: severity: warning annotations: summary: "Email round-trip monitor never reported - check CronJob in mailserver namespace" + - alert: ViktorBarzinApexDrift + expr: viktorbarzin_apex_correct{job="viktorbarzin-apex-probe"} == 0 + for: 10m + labels: + severity: critical + annotations: + summary: "viktorbarzin.me apex A drifted from expected 10.0.20.200" + description: "Technitium serves the split-horizon apex for ~80 *.viktorbarzin.me CNAMEs. If this is wrong, every internal service (auth, vault, immich, ha-sofia, ...) breaks. Check Technitium primary zone records via API or web console." + - alert: ViktorBarzinApexProbeStale + expr: (time() - viktorbarzin_apex_last_correct_timestamp{job="viktorbarzin-apex-probe"}) > 900 + for: 5m + labels: + severity: warning + annotations: + summary: "viktorbarzin.me apex probe has not seen a correct result in >15 min" + description: "Probe may be failing intermittently or apex may be drifting. Check CronJob `viktorbarzin-apex-probe` in `technitium` namespace." + - alert: ViktorBarzinApexProbeNeverRun + expr: absent(viktorbarzin_apex_correct{job="viktorbarzin-apex-probe"}) + for: 30m + labels: + severity: warning + annotations: + summary: "viktorbarzin.me apex probe never reported" + description: "Check `kubectl -n technitium get cronjob viktorbarzin-apex-probe` and the most recent job pod logs." - alert: AIOStreamsStreamCountLow expr: aiostreams_stream_count{job="aiostreams-stream-probe"} < 50 for: 30m diff --git a/stacks/n8n/main.tf b/stacks/n8n/main.tf index 97e5da2f..d0a6b076 100644 --- a/stacks/n8n/main.tf +++ b/stacks/n8n/main.tf @@ -228,7 +228,7 @@ resource "kubernetes_deployment" "n8n" { service_account_name = kubernetes_service_account.n8n.metadata[0].name container { name = "n8n" - image = "docker.n8n.io/n8nio/n8n:1.80.0" + image = "docker.n8n.io/n8nio/n8n:1.80.5" env { name = "N8N_PORT" value = "5678" @@ -352,10 +352,10 @@ resource "kubernetes_deployment" "n8n" { resources { requests = { cpu = "25m" - memory = "1Gi" + memory = "512Mi" } limits = { - memory = "1Gi" + memory = "512Mi" } } } diff --git a/stacks/nvidia/modules/nvidia/values.yaml b/stacks/nvidia/modules/nvidia/values.yaml index 5d115695..7e345e59 100644 --- a/stacks/nvidia/modules/nvidia/values.yaml +++ b/stacks/nvidia/modules/nvidia/values.yaml @@ -37,7 +37,7 @@ driver: resources: requests: cpu: "50m" - memory: "256Mi" + memory: "822Mi" limits: memory: "2Gi" diff --git a/stacks/openclaw/main.tf b/stacks/openclaw/main.tf index 4ef5e382..3b573db0 100644 --- a/stacks/openclaw/main.tf +++ b/stacks/openclaw/main.tf @@ -132,24 +132,29 @@ resource "kubernetes_config_map" "openclaw_config" { mode = "off" } model = { - # ChatGPT Plus OAuth via openai-codex plugin (account: - # ancaelena98@gmail.com). gpt-5.4-mini is the only mini - # variant the Codex backend accepts for Plus tier; - # gpt-5-mini / gpt-5.1-codex-mini return model_not_found - # / "not supported with ChatGPT account". Plus rate-card: - # 1,200–7,000 local msgs / 5h on gpt-5.4-mini. - # - # If you see "No API key found for provider openai-codex" - # / "OAuth refresh failed" in logs, the OAuth token has - # expired. Re-auth: - # kubectl -n openclaw exec -it $(kubectl -n openclaw \ - # get pods -l app=openclaw -o jsonpath='{.items[0].metadata.name}') \ - # -c openclaw -- node /app/openclaw.mjs models auth login \ - # --provider openai-codex - # Follow the OAuth URL+code prompt. Tokens persist on the - # openclaw-home PVC so it sticks across pod restarts. - primary = "openai-codex/gpt-5.4-mini" - fallbacks = ["openai-codex/gpt-5.5", "modelrelay/auto-fastest", "nim/qwen/qwen3-coder-480b-a35b-instruct"] + # 2026-05-22: switched primary to nim/meta/llama-3.1-70b-instruct. + # Verified end-to-end with tool calls (sub-second responses, + # proper tool_calls in API response). Auth audit on this date: + # - openai-codex OAuth: EXPIRED (ancaelena98@gmail.com, + # ChatGPT Plus). Re-auth requires interactive TTY: + # kubectl -n openclaw exec -it $(kubectl -n openclaw \ + # get pods -l app=openclaw -o jsonpath='{.items[0].metadata.name}') \ + # -c openclaw -- node /app/openclaw.mjs models auth \ + # login --provider openai-codex + # - secret/openclaw → openai_api_key (sk-svcacct…): + # insufficient_quota (billing exhausted) + # - openrouter_api_key: "Key limit exceeded" + # - llama_api_key: region-blocked + # - anthropic_api_key: sk-ant-oat-… (OAuth refresh token, + # NOT a real x-api-key — won't auth) + # - nvidia_api_key: WORKS. nim/meta/llama-3.1-70b-instruct + # and nim/meta/llama-4-maverick-17b-128e-instruct both + # tool-call reliably. + # Keep codex as a fallback so it auto-promotes once + # re-authed; modelrelay last because it routes to a + # small model that hallucinates instead of tool-calling. + primary = "nim/meta/llama-3.1-70b-instruct" + fallbacks = ["nim/meta/llama-4-maverick-17b-128e-instruct", "openai-codex/gpt-5.4-mini", "modelrelay/auto-fastest"] } models = { "modelrelay/auto-fastest" = {} @@ -159,6 +164,8 @@ resource "kubernetes_config_map" "openclaw_config" { "nim/qwen/qwen3-coder-480b-a35b-instruct" = {} "nim/nvidia/llama-3.1-nemotron-ultra-253b-v1" = {} "nim/z-ai/glm5" = {} + "nim/meta/llama-3.1-70b-instruct" = {} + "nim/meta/llama-4-maverick-17b-128e-instruct" = {} "llama-as-openai/Llama-4-Maverick-17B-128E-Instruct-FP8" = {} "llama-as-openai/Llama-4-Scout-17B-16E-Instruct-FP8" = {} "openrouter/stepfun/step-3.5-flash:free" = {} @@ -244,6 +251,8 @@ resource "kubernetes_config_map" "openclaw_config" { { id = "qwen/qwen3-coder-480b-a35b-instruct", name = "Qwen 3 Coder", reasoning = false, input = ["text"], contextWindow = 262000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, { id = "nvidia/llama-3.1-nemotron-ultra-253b-v1", name = "Nemotron Ultra 253B", reasoning = true, input = ["text"], contextWindow = 128000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, { id = "z-ai/glm5", name = "GLM-5", reasoning = false, input = ["text"], contextWindow = 128000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, + { id = "meta/llama-3.1-70b-instruct", name = "Llama 3.1 70B Instruct", reasoning = false, input = ["text"], contextWindow = 128000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, + { id = "meta/llama-4-maverick-17b-128e-instruct", name = "Llama 4 Maverick (NIM)", reasoning = false, input = ["text"], contextWindow = 1000000, maxTokens = 16384, cost = { input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } }, ] } openrouter = { @@ -1110,7 +1119,7 @@ resource "kubernetes_deployment" "openclaw" { # at /home/node/.openclaw/.ssh (set up by init 5). ln -sfn /home/node/.openclaw/.ssh /home/node/.ssh node openclaw.mjs doctor --fix 2>/dev/null - node openclaw.mjs models set openai-codex/gpt-5.4-mini 2>/dev/null + node openclaw.mjs models set nim/meta/llama-3.1-70b-instruct 2>/dev/null node openclaw.mjs mcp set ha "{\"url\":\"$HA_SOFIA_MCP_URL\",\"transport\":\"streamable-http\"}" 2>/dev/null node openclaw.mjs mcp set context7 '{"command":"npx","args":["-y","@upstash/context7-mcp"]}' 2>/dev/null node openclaw.mjs mcp set playwright '{"url":"http://localhost:3000/mcp","transport":"streamable-http"}' 2>/dev/null diff --git a/stacks/postiz/modules/postiz/main.tf b/stacks/postiz/modules/postiz/main.tf index 16910440..63f436c9 100644 --- a/stacks/postiz/modules/postiz/main.tf +++ b/stacks/postiz/modules/postiz/main.tf @@ -207,10 +207,10 @@ resource "helm_release" "postiz" { resources = { requests = { cpu = "100m" - memory = "512Mi" + memory = "2Gi" } limits = { - memory = "4Gi" + memory = "3Gi" } } diff --git a/stacks/proxmox-csi/modules/proxmox-csi/main.tf b/stacks/proxmox-csi/modules/proxmox-csi/main.tf index b4e08069..55c57f66 100644 --- a/stacks/proxmox-csi/modules/proxmox-csi/main.tf +++ b/stacks/proxmox-csi/modules/proxmox-csi/main.tf @@ -83,11 +83,13 @@ resource "helm_release" "proxmox_csi" { } } - # LUKS2 Argon2id key derivation needs ~1GiB memory + # LUKS2 Argon2id key derivation needs ~1GiB memory (memory id=712). + # Request bumped from 64Mi → 1024Mi (2026-05-23) so the pod is reserved + # for the unlock burst instead of risking OOM under node pressure. node = { plugin = { resources = { - requests = { cpu = "10m", memory = "64Mi" } + requests = { cpu = "10m", memory = "1024Mi" } limits = { memory = "1280Mi" } } } diff --git a/stacks/technitium/modules/technitium/ha.tf b/stacks/technitium/modules/technitium/ha.tf index 8da1712e..0d3cf3ab 100644 --- a/stacks/technitium/modules/technitium/ha.tf +++ b/stacks/technitium/modules/technitium/ha.tf @@ -123,10 +123,10 @@ resource "kubernetes_deployment" "technitium_secondary" { resources { requests = { cpu = "100m" - memory = "2Gi" + memory = "512Mi" } limits = { - memory = "2Gi" + memory = "512Mi" } } port { @@ -285,10 +285,10 @@ resource "kubernetes_deployment" "technitium_tertiary" { resources { requests = { cpu = "100m" - memory = "2Gi" + memory = "512Mi" } limits = { - memory = "2Gi" + memory = "512Mi" } } port { diff --git a/stacks/technitium/modules/technitium/main.tf b/stacks/technitium/modules/technitium/main.tf index e113bf29..d134b587 100644 --- a/stacks/technitium/modules/technitium/main.tf +++ b/stacks/technitium/modules/technitium/main.tf @@ -179,10 +179,10 @@ resource "kubernetes_deployment" "technitium" { resources { requests = { cpu = "100m" - memory = "2Gi" + memory = "1Gi" } limits = { - memory = "2Gi" + memory = "1Gi" } } port { @@ -696,3 +696,106 @@ resource "kubernetes_cron_job_v1" "technitium_dns_optimization" { } } +# viktorbarzin.me apex DNS drift probe +# Resolves `viktorbarzin.me A` against the Technitium LoadBalancer IP every +# 5 min and pushes a Pushgateway gauge. Backstop for the entire +# split-horizon zone: every internal `*.viktorbarzin.me` CNAME chains through +# this apex, so if it drifts (ISP rollover, accidental edit), this is the +# canary. Alerts: ViktorBarzinApexDrift, ApexProbeStale, ApexProbeNeverRun +# in stacks/monitoring/. +resource "kubernetes_cron_job_v1" "viktorbarzin_apex_probe" { + metadata { + name = "viktorbarzin-apex-probe" + namespace = kubernetes_namespace.technitium.metadata[0].name + } + spec { + concurrency_policy = "Replace" + schedule = "*/5 * * * *" + successful_jobs_history_limit = 1 + failed_jobs_history_limit = 3 + job_template { + metadata {} + spec { + backoff_limit = 1 + ttl_seconds_after_finished = 300 + template { + metadata {} + spec { + container { + name = "probe" + image = "docker.io/library/python:3.12-alpine" + resources { + requests = { + cpu = "10m" + memory = "48Mi" + } + limits = { + memory = "96Mi" + } + } + command = ["/bin/sh", "-c", <<-EOT + pip install --quiet --disable-pip-version-check dnspython requests && python3 -c ' +import dns.resolver, requests, time, sys + +EXPECTED = {"10.0.20.200"} +NAMESERVER = "10.0.20.201" # Technitium LB IP +NAME = "viktorbarzin.me" +PUSHGATEWAY = "http://prometheus-prometheus-pushgateway.monitoring:9091/metrics/job/viktorbarzin-apex-probe" + +resolver = dns.resolver.Resolver(configure=False) +resolver.nameservers = [NAMESERVER] +resolver.timeout = 5 +resolver.lifetime = 8 + +correct = 0 +observed = "unknown" +try: + answer = resolver.resolve(NAME, "A") + ips = sorted(str(r) for r in answer) + observed = ",".join(ips) + correct = 1 if set(ips) <= EXPECTED and ips else 0 + print(f"apex {NAME} -> {observed} (expected one of {EXPECTED}); correct={correct}") +except Exception as e: + observed = f"error:{type(e).__name__}" + print(f"resolve error: {e}", file=sys.stderr) + +metric_lines = [ + "# HELP viktorbarzin_apex_correct 1 if viktorbarzin.me apex resolves to expected IP, 0 otherwise", + "# TYPE viktorbarzin_apex_correct gauge", + f"viktorbarzin_apex_correct {correct}", +] +if correct: + metric_lines += [ + "# HELP viktorbarzin_apex_last_correct_timestamp Unix time of last correct resolution", + "# TYPE viktorbarzin_apex_last_correct_timestamp gauge", + f"viktorbarzin_apex_last_correct_timestamp {int(time.time())}", + ] +metrics = "\n".join(metric_lines) + "\n" +try: + r = requests.post(PUSHGATEWAY, data=metrics, timeout=10) + print(f"pushgateway: {r.status_code}") +except Exception as e: + print(f"pushgateway error: {e}", file=sys.stderr) +sys.exit(0 if correct else 1) +' + EOT + ] + } + dns_config { + option { + name = "ndots" + value = "2" + } + } + restart_policy = "OnFailure" + } + } + } + } + } + lifecycle { + # KYVERNO_LIFECYCLE_V1: Kyverno admission webhook mutates dns_config with ndots=2 + ignore_changes = [spec[0].job_template[0].spec[0].template[0].spec[0].dns_config] + } +} + diff --git a/stacks/trading-bot/main.tf b/stacks/trading-bot/main.tf index 315fb967..8f9a272e 100644 --- a/stacks/trading-bot/main.tf +++ b/stacks/trading-bot/main.tf @@ -24,7 +24,10 @@ locals { TRADING_CORS_ORIGINS = "[\"https://trading.viktorbarzin.me\"]" TRADING_MEET_KEVIN_POLL_INTERVAL_SECONDS = "10800" TRADING_MEET_KEVIN_DAILY_COST_CAP_USD = "5" - TRADING_MEET_KEVIN_LLM_MODEL = "anthropic/claude-sonnet-4.5" + # Haiku-4-5 used in v1 because sk-ant-oat01 OAuth quota on Enterprise + # trips a sticky multi-hour 429 on Sonnet after 5-10 burst calls. + # Switch to "claude-sonnet-4-5" if/when the Enterprise quota allows. + TRADING_MEET_KEVIN_LLM_MODEL = "claude-haiku-4-5-20251001" TRADING_MEET_KEVIN_PROMPT_VERSION = "v1" } } @@ -71,7 +74,7 @@ resource "kubernetes_manifest" "external_secret" { TRADING_ALPHA_VANTAGE_API_KEY = "{{ .alpha_vantage_api_key }}" TRADING_FMP_API_KEY = "{{ .fmp_api_key }}" DBAAS_ROOT_PASSWORD = "{{ .dbaas_root_password }}" - TRADING_OPENROUTER_API_KEY = "{{ .openrouter_api_key }}" + TRADING_ANTHROPIC_OAUTH_TOKEN = "{{ .anthropic_oauth_token }}" TRADING_MEET_KEVIN_CHANNEL_ID = "{{ .meet_kevin_channel_id }}" } } @@ -85,7 +88,7 @@ resource "kubernetes_manifest" "external_secret" { { secretKey = "alpha_vantage_api_key", remoteRef = { key = "trading-bot", property = "alpha_vantage_api_key" } }, { secretKey = "fmp_api_key", remoteRef = { key = "trading-bot", property = "fmp_api_key" } }, { secretKey = "dbaas_root_password", remoteRef = { key = "trading-bot", property = "dbaas_root_password" } }, - { secretKey = "openrouter_api_key", remoteRef = { key = "trading-bot", property = "openrouter_api_key" } }, + { secretKey = "anthropic_oauth_token", remoteRef = { key = "trading-bot", property = "anthropic_oauth_token" } }, { secretKey = "meet_kevin_channel_id", remoteRef = { key = "trading-bot", property = "meet_kevin_channel_id" } }, ] } @@ -507,16 +510,59 @@ resource "kubernetes_deployment" "trading-bot-workers" { } } } + container { + name = "kevin-signal-bridge" + image = "viktorbarzin/trading-bot-service:latest" + image_pull_policy = "Always" + command = ["python", "-m", "services.kevin_signal_bridge.main"] + dynamic "env" { + for_each = local.common_env + content { + name = env.key + value = env.value + } + } + env { + name = "TRADING_OTEL_METRICS_PORT" + value = "9098" + } + # Kill-switch off in Phase 1 — bridge writes audit rows only, + # never publishes to signals:generated. + env { + name = "TRADING_KEVIN_ENABLE_TRADING" + value = "false" + } + env_from { + secret_ref { + name = "trading-bot-secrets" + } + } + env_from { + secret_ref { + name = "trading-bot-db-creds" + } + } + resources { + requests = { + cpu = "10m" + memory = "128Mi" + } + limits = { + memory = "256Mi" + } + } + } } } } lifecycle { - # DRIFT_WORKAROUND: CI pipeline owns image tags for all 4 worker containers. Reviewed 2026-05-22. + # DRIFT_WORKAROUND: CI pipeline owns image tags for all 5 worker containers. Reviewed 2026-05-24. ignore_changes = [ spec[0].template[0].spec[0].container[0].image, spec[0].template[0].spec[0].container[1].image, spec[0].template[0].spec[0].container[2].image, spec[0].template[0].spec[0].container[3].image, + spec[0].template[0].spec[0].container[4].image, spec[0].template[0].spec[0].dns_config, # KYVERNO_LIFECYCLE_V1: Kyverno admission webhook mutates dns_config with ndots=2 ] } diff --git a/stacks/traefik/modules/traefik/main.tf b/stacks/traefik/modules/traefik/main.tf index 8aed7b91..b3ba958b 100644 --- a/stacks/traefik/modules/traefik/main.tf +++ b/stacks/traefik/modules/traefik/main.tf @@ -688,6 +688,14 @@ resource "kubernetes_config_map" "auth_proxy_config" { server { listen 9000; + # Browsers accumulate one authentik_proxy_ cookie per Authentik + # Proxy Provider on the parent domain. With 30+ services under + # viktorbarzin.me the combined Cookie header exceeds nginx's default + # 4 x 8k large_client_header_buffers and trips "Too big request header" + # (431). Bump to 8 x 64k so the auth check accepts the pile. + client_header_buffer_size 8k; + large_client_header_buffers 8 64k; + location /outpost.goauthentik.io/auth/traefik { proxy_pass http://authentik; proxy_connect_timeout 3s; diff --git a/stacks/url/main.tf b/stacks/url/main.tf index e5a5927e..99823ebd 100644 --- a/stacks/url/main.tf +++ b/stacks/url/main.tf @@ -226,11 +226,11 @@ resource "kubernetes_deployment" "shlink" { # } resources { limits = { - memory = "960Mi" + memory = "512Mi" } requests = { cpu = "25m" - memory = "960Mi" + memory = "512Mi" } } port { diff --git a/stacks/xray/modules/xray/main.tf b/stacks/xray/modules/xray/main.tf index 903eaabd..37e9ecb3 100644 --- a/stacks/xray/modules/xray/main.tf +++ b/stacks/xray/modules/xray/main.tf @@ -91,10 +91,6 @@ resource "kubernetes_deployment" "xray" { image = "teddysun/xray" name = "xray" image_pull_policy = "IfNotPresent" - port { - container_port = 6443 // vless - protocol = "TCP" - } port { container_port = 7443 // reality protocol = "TCP" @@ -174,19 +170,16 @@ resource "kubernetes_service" "xray" { app = "xray" } port { - name = "vless" - port = 6443 - protocol = "TCP" + name = "websocket" + port = 8443 + target_port = 8443 + protocol = "TCP" } port { - name = "websocket" - port = 8443 - protocol = "TCP" - } - port { - name = "grpc" - port = 9443 - protocol = "TCP" + name = "grpc" + port = 9443 + target_port = 9443 + protocol = "TCP" } } } @@ -249,16 +242,3 @@ module "ingress_grpc" { } } -module "ingress_vless" { - source = "../../../../modules/kubernetes/ingress_factory" - # VPN protocol (VLESS) — native xray clients, not browsers. - # auth = "none": VPN protocol (VLESS) — native xray clients, not browsers; forward-auth incompatible. - auth = "none" - dns_type = "proxied" - namespace = kubernetes_namespace.xray.metadata[0].name - name = "xray-vless" - service_name = "xray" - host = "xray-vless" - port = 6443 - tls_secret_name = var.tls_secret_name -} diff --git a/state/stacks/cnpg/terraform.tfstate.enc b/state/stacks/cnpg/terraform.tfstate.enc index 08bff176..dee63ae5 100644 --- a/state/stacks/cnpg/terraform.tfstate.enc +++ b/state/stacks/cnpg/terraform.tfstate.enc @@ -1,151 +1,254 @@ { - "version": "ENC[AES256_GCM,data:MQ==,iv:QUQYOO92o2pBGy/DJ4hEESP6UfYjce9JL63qLnkdtMQ=,tag:fP/7WSX9YlwJbeM5IeOgtQ==,type:float]", - "terraform_version": "ENC[AES256_GCM,data:ktCT3/k=,iv:yx4gN8DhL/8qE3+DJJseu+tWfCDoD0F6BkVPe75fR4k=,tag:hUvsTunzCuGi92O0m/9VVw==,type:str]", - "serial": "ENC[AES256_GCM,data:IQ==,iv:KdVmdeJBXVZPO/scFpHDDkq0q5LLQDbYcDZy0k2QjbA=,tag:hBeYX4YT9X4FGjEqRXUS8w==,type:float]", - "lineage": "ENC[AES256_GCM,data:VvYbo2gYJiKI3+EnqOYJDRbMuDCiOWZBLapMnoi3qQ9QSmuI,iv:U/AyaSmtXK08Yp5PmngjpV8KFX4orPY/0eNbo04opqA=,tag:+bsJbLRe7FAmLdefVqvyZA==,type:str]", + "version": "ENC[AES256_GCM,data:1g==,iv:Q2aO4H/PtfPeGnnmy7jPzh5q0gO/RaVhZCnqnPrKf6E=,tag:CyjbEwIOsMmC56b7nnHn0Q==,type:float]", + "terraform_version": "ENC[AES256_GCM,data:c34oygcf,iv:hvY95FOeEE7WFuIWsFinKLjWExJOt0n6joKX6OJPWQo=,tag:p8qxkKUhVo92EUCbqZvsVA==,type:str]", + "serial": "ENC[AES256_GCM,data:2g==,iv:OkZ1qXBkODDOk6i7gBpLfVvm9lMkKhVaMNtXYD4LmBU=,tag:FdozZufpQGdYRMpH/0OUKQ==,type:float]", + "lineage": "ENC[AES256_GCM,data:tAoxYJmVxXEX1PiAdYor8ud6YMFIazrU64MKKma61c00n4Om,iv:9+sPrUXeyPFbjdQeD04yyc4akG9cIfDqFg7PKWcvRlc=,tag:L2sEDcX4WVrt1EHAufl+wQ==,type:str]", "outputs": {}, "resources": [ { - "module": "ENC[AES256_GCM,data:ItKH934ngU6oFwo=,iv:8WxixpD9EbWvXNwUiwafseqNc4dA+/ZboCwMuIxl8Kg=,tag:5om966EOv91RMSdtfXBr9w==,type:str]", - "mode": "ENC[AES256_GCM,data:hsR44W6yeQ==,iv:p1QLk44D4dOoAdoOLc6x+yfnLl8g6+43Os1r+6E+/yE=,tag:sl3roeSNSmtw4+aSkqn7Pw==,type:str]", - "type": "ENC[AES256_GCM,data:FRPYvPSZ9bA7blLa,iv:YZ5kv8sSsWInm05zjMl6HIldQ2c/lHoPmIXWRot7D3c=,tag:yeBfMDBfXE3ys3SK7mDc/g==,type:str]", - "name": "ENC[AES256_GCM,data:I2f9pg==,iv:X/hvUiy5G559era2L5tpd1tudh/U0yY+2c6nvauSMFg=,tag:wHNBfmSIT2w3CLYuBRLf2w==,type:str]", - "provider": "ENC[AES256_GCM,data:vw3BAhoadVouaTeLZIz3C1GbG/lKmNVPUKwqA8dIWdQ6JPH6VEPZig/KqrGM7MLt,iv:4saDM8Xzc9h6ZqG8E8Ta+4XznvzueE8heH3+UyMKIuc=,tag:MZ1t30xN74GOd2cN26WBNQ==,type:str]", + "mode": "ENC[AES256_GCM,data:snV8UA==,iv:xN3OzeGqEsXje9SJD3x7uYssGkJLw8qZJu9peUwZquQ=,tag:WkYOw8WnPCjKzajl81L+og==,type:str]", + "type": "ENC[AES256_GCM,data:xwb4OQNgzIGM8pQVqxX2U8Yb,iv:LSlMYfezcY3r42ooszu4GVs/X/KpwBfKngH4k5n5IFk=,tag:r1fl5sMPgEMjRt9iy7v1lw==,type:str]", + "name": "ENC[AES256_GCM,data:mCN6o/X0Jha4i8Q=,iv:HYyeqiAHPvji146keQGznHTLzYyCpSmG5rGSKSfTF8s=,tag:vsm/P75Xk4dhTmS0ROBeFA==,type:str]", + "provider": "ENC[AES256_GCM,data:vvZR9d+GRpQmK9sBwfUyOSThsCJk3UqN2bhzbVG5Dbk7iy6uMgvyza85GumvPndjtw==,iv:jG99oETlYGyLDoKVtwbkBpTEjOxyH+c4nmtdjB9muL8=,tag:U4Yq3vbZBuNCIZYTcrhFEA==,type:str]", "instances": [ { - "schema_version": "ENC[AES256_GCM,data:XA==,iv:vbpdSpca6JmvJGcbBhyy48IEEdiNx1GZabsxNqxEWHM=,tag:7B1nDDAJCymxRFpS3G5u4A==,type:float]", + "schema_version": "ENC[AES256_GCM,data:eg==,iv:ZQStmmDC4HwDIc0slbIknK+aLDUQYrqCoLu92bWEsTI=,tag:SqAowufns8i5F/TMJ3g7pg==,type:float]", "attributes": { - "atomic": "ENC[AES256_GCM,data:dvcM0Q==,iv:6Gk0p2NWz2tIb1OZYqqZH1sCILzaWk1gwU6PsYHoxjk=,tag:isjg7rubtAMDm+uveS0LAg==,type:bool]", - "chart": "ENC[AES256_GCM,data:lTkZPoQbgOAG1jthkb4=,iv:F+naKEXwot1cN1ViYspRUpEZ6mkw++fwDlxggvi1iS8=,tag:BI3PevEuLdlykRjILGSN9A==,type:str]", - "cleanup_on_fail": "ENC[AES256_GCM,data:NbJW09Y=,iv:bDyX2btazL7g/DCle5GzE2Aon/wLTJkNa7vY7jnMQ1s=,tag:RMNVNbRLqPWacySJuGvY6g==,type:bool]", - "create_namespace": "ENC[AES256_GCM,data:n6eOB3Y=,iv:4oTuiZl2bels2tr+7xyW7AhL4+aF2pLtsmYHdODWV2E=,tag:FddKAkuEw/zUcCW+f9IMAg==,type:bool]", - "dependency_update": "ENC[AES256_GCM,data:gPkk6W4=,iv:WVZ5VGfPGcIXFTGFMTljuMOZeCtTqASuh4OiyYtfk2Y=,tag:M/XVt3grmkpb76RkF0Pfnw==,type:bool]", - "description": "ENC[AES256_GCM,data:5q9zo3DtTzOnUAe1Ru2Daw==,iv:GE3nmomP27V78wKGAuXO1J9gyyR/hdX+D0mPyqhNCPA=,tag:4zlld4Is/MZ1MHUhdQp+FQ==,type:str]", - "devel": null, - "disable_crd_hooks": "ENC[AES256_GCM,data:zvy1tak=,iv:w9ShOMLQ92b+pz7bJYu+0TA6GUDaIVpCIzUEJgSFq+g=,tag:3DZ+1PNVWxsY4V+BQ6kpgA==,type:bool]", - "disable_openapi_validation": "ENC[AES256_GCM,data:Dy7jLss=,iv:CMhXxjzNIe7cTk5DXNfryjwZrQI4f2NZRlGD3kQVmEY=,tag:C1czy/+NieoN/SqrDmRrng==,type:bool]", - "disable_webhooks": "ENC[AES256_GCM,data:JYeSiYc=,iv:8DNOsjlNRcDeyqiuUb6QXxXuUxxVL+0xLYfGQSK7b9M=,tag:ESYkUxLGsqgzaVvOMH2bhg==,type:bool]", - "force_update": "ENC[AES256_GCM,data:Jbfus8o=,iv:NWnd0ewZrujQwoIqmPHw1F+3FkdHNZ5ZYeUr191t/2k=,tag:n64KWQeoMx4Rr8iso6s/gg==,type:bool]", - "id": "ENC[AES256_GCM,data:RC5zXg==,iv:lPf8EQYhRtcW2ElckLmERodpgzDW+57lVyP3SeknEcg=,tag:BEeqAGbyhyTlUx0tlhTJeA==,type:str]", - "keyring": null, - "lint": "ENC[AES256_GCM,data:AU/UgKQ=,iv:yi8bIYetXdo1s+S0ES0x2D+tyYrjAA3f1nCVaovmxuM=,tag:aR9XIG0nZo53bXVQB7fahg==,type:bool]", - "manifest": null, - "max_history": "ENC[AES256_GCM,data:DA==,iv:uMlX+32v7vr7fna0S9cdDNYquJJ7ZvWsHG7T3nn2+rA=,tag:Jxz3pnxMY56xctkZ/jBs6A==,type:float]", - "metadata": { - "app_version": "ENC[AES256_GCM,data:TsmEEjT1,iv:XaqO2eSZNJLrEFlLcggwYmNluoHh94VNT74rxI6L2Lk=,tag:TS+splNRJl/9CofD72Yi4w==,type:str]", - "chart": "ENC[AES256_GCM,data:Fdn2peJf3wphYXRkqlE=,iv:gFS+Yh3XIS002xUCXR16gFgWMibKM4bfZ+mP9Fc2rZk=,tag:20VvN+d8pjukk3YxyfHYYQ==,type:str]", - "first_deployed": "ENC[AES256_GCM,data:vS76+Duh76A5ug==,iv:A2OpCQDaJMjAljFaD5dTj2VyD50XYFe6JQtO8H4dFPw=,tag:hJWHUr3N5S2duDduBHbDJA==,type:float]", - "last_deployed": "ENC[AES256_GCM,data:JzKRYrNoiKnO5w==,iv:BW/AhSZgdkz+OIb575X1oZk0g6BMRd9jJWFaVaiMj5k=,tag:Gem92JLWPbzHF8pKe9JDmA==,type:float]", - "name": "ENC[AES256_GCM,data:zqa9JQ==,iv:T2lEHBSPNiZfZpSg9U35YBawq1vGrbzye0xkI92HdIg=,tag:uTHSx/vfTyVRPw6bDDLa8Q==,type:str]", - "namespace": "ENC[AES256_GCM,data:h71lasBvfL6uyWw=,iv:qHjTKuuO8oorZHqabUJ8+/1698AYdjbZIC0lUDZAn6I=,tag:yXk6epu6ANCFH2v5KEwi0A==,type:str]", - "notes": "ENC[AES256_GCM,data:vrFla40Wn+H6fLMDje/DFE7VCrBhGdnbyX2o+tPu+UOZr7vuad2BBoi+8FEmJjJEXo5uXSDmsSHsWCCRirXkY+QTIUmXY1OT5Rvv339g7CccxxajDtLAbmsaeqCbpBuaUHmWDSZcYY67KeXHwzJ4jmSs95WIGIBN+y+KDh0+NrbCIKo4fjoTKKv0BVQoIaNFdsW4lU7hIPEdaI52vaYCEhQWq2NUC3fImCZt2DYmOWm24GjFpeq5F64NqbppYzho84ZnGo280GEBPHq3RS94+Ur9Fg3cv55ZAn3d1pnVyohTFfvk4VWpwtX5FRyb1UugnRXcjoNIi6sAL64vdrBcBHtHA1JX2Ogq6V7a2w1L9/q+qiW1gVCJhVSlecm068hcVoq0WaMGxs/Myt/sti+D5cIQO+4fdPbHRS6TKR3sbkuyAfh4j0SPAC7NXoAHbSl2g6P0utvcjt3TzRHtAgojPq4wpRM1NjbF5A==,iv:qzRNjVXLKuD0gHSKAqTBNjjqw5BVmuVYrk0QkHi5ZWk=,tag:qx09f2P/qzhCG7hIhWwrPA==,type:str]", - "revision": "ENC[AES256_GCM,data:0g==,iv:MUy986ajLCU4IZPQKTgtt2MS5aAIDToGlNFN2e676xk=,tag:A6P/oG4dwkntXLhYeSCCbw==,type:float]", - "values": "ENC[AES256_GCM,data:rBAKYnL0Vyo4JkEZHf+Zx1zmTI6uDHkXM9dM/xyjg8qphj8pT+i4rkyGjI1MWNuNpETBm6QbnVjB6q3q+jZHSSlH4+E522Cjrb3i6h66Ygq9JdLUOsvSsjBRKnn+e91nkP0VyAlZkBLlRoiE10z9Q+g4Fm51nbHTxlar1k2e,iv:z+6MyW3dtQt5vBUprrOz2BQBzMyIMhrvcpJmEN6HKwg=,tag:h+bIdsOg6XcuXcZFMiXvnw==,type:str]", - "version": "ENC[AES256_GCM,data:qajxxF+l,iv:086TYy3gfctuhRC4c3wqP5VR4qKp/Tk6vpodekyWp04=,tag:dpKYNuqMFBcfRT1ZvQLZiA==,type:str]" + "created_time": "ENC[AES256_GCM,data:goLOLlYa75tbRm+uf0ZAkES75DDeD4zE3NV+5n20,iv:JprjYA9JvPxKidFRgK9R0nDNmJ2TOgETC5EzjqzZ2Yg=,tag:VLZ74lwKvbVFO3PgNUimmA==,type:str]", + "custom_metadata": null, + "data": { + "alertmanager_account_password": "ENC[AES256_GCM,data:o0KdSX3aB5i0lCjZKeAVLSVBgmI=,iv:tVyYI32v7utz+xzbEo4Y1Oudf52/HLj0Jp1a+l/R5ZM=,tag:3VF20zZyy3Ci12hQJaN7kA==,type:str]", + "alertmanager_slack_api_url": "ENC[AES256_GCM,data:ion4XsWiPPte1MAn4khQgczB+B6cR7zVeWLZnaBK4HHZkkeRSHuzg6sNtPtHLt3xP8O/6zclKZAYIllUNHuoGem4Zz5niD/jn3nA8whQ55Sa,iv:cPjMUI/RhvOVC01C4CBHS4MNiRW3CeiyyWA490/6EJ8=,tag:Mo/Ae29gruKFA+8+63X6mg==,type:str]", + "auth_fallback_htpasswd": "ENC[AES256_GCM,data:93SjiL6UCYi64Oq7v6IGj8HM3rNe68A1tUCxb577Tss8UJ66SMfvGoSo7EbRTMY9A6dPefaX0QnKcdFitXnMHy8l,iv:JhJVvHTRZ+2yFuaUMIsGHe0NSdcAX5tRYGwd/jqR8k0=,tag:9xrOyDQBZEJfAHASRjJnJg==,type:str]", + "authentik_postgres_password": "ENC[AES256_GCM,data:G1G72RQygQm3REHzLJYLGw==,iv:YcW+x6kQAbjpQQjyF870fwXa5mpIbsEULIr8mtycoDg=,tag:IXHJ8lSzRcXP0fX5RMCS5w==,type:str]", + "authentik_secret_key": "ENC[AES256_GCM,data:n/tUYi4INuVCaJ5A+49gogkTh5DaYrzQbbWFIIG/7Gv7QsNslT+dGTluBv+THxa9Bn5s,iv:p98sYBCVtXFIl92IF6fHYIdsdhHtOkF69wFbqVEr0Do=,tag:rHpxxNIywr781mtQdc9Mdg==,type:str]", + "cloudflare_api_key": "ENC[AES256_GCM,data:R3a+poUB9Ebq58npn6ugoMDh2g/+CVqfWCD4Zywk9M+DGsMC7A==,iv:eYM+u7HiSdA/HcVMy0xHxo0CXKya7UrADfgR/Nex4zQ=,tag:Fk4G7+0Whr8DcqbTPWY6IQ==,type:str]", + "cloudflare_tunnel_token": "ENC[AES256_GCM,data:oKs77UlWVf4gyndxU2MudvX/LRYBtYKLr80jaixITiPHGKGArDgubF+6cU3nyVQmcsmDI6fVxI+bvhLdzRk0/dlqgAsvniSccH8BW2VP+i3naw8pv02h4Ce94qiOq3cSx3V9jsJzK269WAMp3GLx4cEnqZ5WnuDs2DnyDVisNGfy/i8UwpmOdZrRu6A03TGCsVCfkLuDR/+eeD3OLZCphR1CBGDrYRClsleZ/xUJxWJRZLQaXrrMSA==,iv:y/POvYSoeUJtU9lx3j5gc99I4i7oGY7IGdMV1VVxgi0=,tag:Lt2sCVl6G2PB5p1Zqew6dw==,type:str]", + "crowdsec_dash_api_key": "ENC[AES256_GCM,data:3Ew8B6zGu1JMd11DXg30T6fjiGb2eIAPx23X8JZSvQJOrtq2Y6K1qJiXbA==,iv:MUrjP7FPNgJRkKmhqdlvBBO2schFlov/2NsBGrPyMHk=,tag:ACYUKJf5CBUy8dBOOimblg==,type:str]", + "crowdsec_dash_machine_id": "ENC[AES256_GCM,data:6MCXR4T0GOnKE0snc+BneSylaWgqU4G99mgTe58=,iv:OHGyJ46+v4lK4uHK6L8CXd4BNHxA/9ljHgjTXdab+r4=,tag:GHhfWdwI7cOuJLVCmjpRRw==,type:str]", + "crowdsec_dash_machine_password": "ENC[AES256_GCM,data:q2KYTz3gER1wLieyH7IEZYjfrB0FTq7IIMdTpYsFX2yPdPx2i5uQVw3buvWCIBYYqdbLFVAKWxCLF9/UzBchvQ==,iv:KRMIaqhEFi21kln0PLFizA6wH/t7MnZWlT5TBb7F1PY=,tag:3dI9rYgvhCITHEynII6BYw==,type:str]", + "crowdsec_db_password": "ENC[AES256_GCM,data:mcjq2bgeuhTItVRfH8k=,iv:bG8we4iP5JIOEqh+gtZjGjP8bHoK0O2LmIE03QB/Lps=,tag:mf0LmnrSvJJ7KWA0EFvnng==,type:str]", + "crowdsec_enroll_key": "ENC[AES256_GCM,data:6/8LqHygpGHhHoyqNbJB30eihxpylP0LEA==,iv:bTzscqkXvSi2g1stMpqZdFaXbKiSJ5gJeQYRmm5cDF8=,tag:SRutOCQsQXvDh09viCITSQ==,type:str]", + "dbaas_pgadmin_password": "ENC[AES256_GCM,data:UpbV7QAOe2/IGcQq3rxNfbBPPEYkmca7KxuM1Suhm1M=,iv:OjpKLyyMpsn54kEKasO3thsdzNLjmv9WDn4UM1YjaKk=,tag:LANurU22a3mMxr6DmUIt/w==,type:str]", + "dbaas_postgresql_root_password": "ENC[AES256_GCM,data:wJAyvhfxdnmA2JOJsNKotLiqeXeoGY+fxtY=,iv:eREre5qd16yXZgljBNcvImuDc2YXsa53DzQN8DuCq3w=,tag:YC58mlgbIPQ1dyDPWGN9pw==,type:str]", + "dbaas_root_password": "ENC[AES256_GCM,data:M2UepNs/+/Rqvq0men+Gw+got2sXy4ymS2uXBA==,iv:mN9HL+yPxqc+v7jkD9BWgP5dVg8b+xniQiNI9lkgTwE=,tag:mQ6+okHV2YrYPsUCGnxZ8w==,type:str]", + "grafana_admin_password": "ENC[AES256_GCM,data:aT+2e2jI/q+6uoto77K9dvtz4cI=,iv:f/r/tRBJBntadjoLFIvCnVONeKipdA1Q/E7pACTsVxw=,tag:0FaDQZFVGYC47SPc6Ib21A==,type:str]", + "grafana_db_password": "ENC[AES256_GCM,data:GfTHxPU8fhZ3XlIDoYaZ3fbFRSmh,iv:UwvztZMazob8MKZs+zgRCr7emNEY8bS2/K/kHTzHATc=,tag:O8V4OvAajQ3yG+AhnO6R/Q==,type:str]", + "haos_api_token": "ENC[AES256_GCM,data:si7VqrAfI+L8+yR2HnkNwIsYO15xkP7QB5mNLxegQn2bfyIgIRcS63/00d4q21shiZmfKsTko9CDeXdQSQOtiBIKAd9P6nkNW+rZ2C3wI+AecqssDAwi0aV9haXHD9FhTm2siIyuYYTy8BITyIgQvclOAE1BrBRZUR3kV59YQKhmxuofsHVBReSBGWW+nIV+5XY0uxtILWn2c2U915WehgWlvfZBQw+dFWAe/J6NT3LF28/NaXB3,iv:ivf+EPaVx0hZvj8rIMwSoIbLj32L0IHj9I/60jHGPfA=,tag:cAPbR+5otRMtuEbuk5Rh7w==,type:str]", + "headscale_acl": "ENC[AES256_GCM,data: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,iv:AmZaqjDjA05yylzn//9fIJJs2OR0kM4vtSU8lm8wJpY=,tag:+22BPpE5SrRd9PnhRnoACw==,type:str]", + "headscale_config": "ENC[AES256_GCM,data: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,iv:fpK+bvAgUW9OIXO8OY/zKjP1hifGqaPOc2lU/XLuJIY=,tag:xoXrG40mcC7mIiT2h8mavg==,type:str]", + "headscale_derp_map": "ENC[AES256_GCM,data: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,iv:LxSDk7N9vXpYAcWMgro0kfvAE5RT3rga/Z/0DH8ZMDA=,tag:SDM48TSbL3Qh9IOBVYiT9w==,type:str]", + "headscale_ui_api_key": "ENC[AES256_GCM,data:6aHeuvsiHMhnHVLuIhr9mLR4Xp/bq99L/BqDzsCpMaluiOQcIvEo8oAKDIEDvY2c89QP5vc3ONEXGhAqDZo+Ng==,iv:pnCjO87Ue9GRI4tEEdZWA4RUntJWq0WDQxagndBfbTc=,tag:Q4ZvRD1+4g6lUFHt7I9QkA==,type:str]", + "headscale_ui_cookie_secret": "ENC[AES256_GCM,data:ZQu+aYTJPYcdSjEOF7Ghy2T+iSYdvN0JSrTPV2wW5H2uucA3oKASaih9nrzSEbXJnozBeeEuq7ppLV/y56BT4g==,iv:1gvAD3QQsA4b7pmmSwkYQkRzmTNt5zFhnJbDUhKGUF4=,tag:lAJrTnd50uLUAxWftOqNzQ==,type:str]", + "homepage_credentials": "ENC[AES256_GCM,data:yo/yvo82J+PWowM5r1WZEbU6XqJkve7j5WovVG9mvcEJpCKA8TZiP5xiw1B1RJbKGAEn7rat1/6awVknS+98N5+QTr6swbZnsVTAcxoKMqrrwYXORNqXok2r/9mmkxWjMFgVZq1y18pGGFLgUXx2uTyY/u0AU+ZPgJQzQRnEPN4zIUPV4sZUpLrCjxzFBcL4oDPLDMMZc0B6pGOago28fyP+IFzCSUs/q7OLuHLpZNbbvy7Lxs6gECAnwv0B3lneZO+4+PUQWDdtOUAQxWv7+IfC73fVqF+2rnceAibOzyvugf+lFRqHI2fuLEQ7prhEELUi30x3kOJWduhBiP6la+eKABfCdm5LqvEnjp9ITae8jdqIWbTnvqHGtw8Kj+dsRxEE+RiRbj96IabDoFDwTcmxhwLjD0nmSLjfImTjdPQKMpkqHAnZYQ5iznYdVFW36Xes/V7yXLI34isQyXvcqRFOuNZEo7eRvxiUGaB4rT/Rer420DIHA6wWpYYAfFyq36eSnAtcik7pJq8ZoXsdNspcLv4ropEnrZt+9UIkf3LdaNW61VKYXxjt74D6C2F66znaJmR1W4sy/pq1LYgEhzXuz3mF7niInY/wPgaiYMOT73oFSATFjtxbdBVUa7JJ+E+kIBSIKuYEa7xOd7Ok7EpYCdVV8PifLitpurWA3pDeTQBtIogyDF4zTQPiEiMbdswuw4nS82CP0iJnAglvIHyN5257yVvUMInAVtem0NvAPqJS/5Jo0wIllmx/HZ/KEpxDM7bsHc7JXG7BeiK7Y3h4GFG3eE0L1pPJckswwF8PsJXNScqj62+vsTowEphGP7VCnMfXdEXF9w1ngDo4RKUQoxbM5BmoGYCrORgEzq0hATSErJ5Z4I1sTFse0i1TIzn/Gfz9BFhTOkHSzXbtePWS/fDjlmRfGRfD47h1lXw90UnJmi4Z1ZDhbZirlDTUVFavEH0ym+Kd6loH2l1nD9ULw5H1yUhd2ucTSVltcsOKiPeyk03y3pw7xaN5Uwyqp1s8bEopOwQAoUKr2OFoHsgG95MgWO4lEZyZ6ZIxYgb8r9VHIPeHM/U1MzQbue+mLDgV0jFGC5jhnlA3HxvYBduMdolhApU52vDb4PJaMRynf3tisAGqzxfWmMKMtN7B3njDbbH+JAKO5OMrxlLPS4VoPsaJTi4DMt57ZQTHcBd9ebpAjaPeDpV1p20pCNYoA/Bs8gPHd8jum17JWCH59iDr5aS062VbTx4sNSs/+7xcquiTndTiR1dlJ3WkDc9KBxcJ5I8MesYOHDVzZtf7c5njKNNHvzCNUjCUisUBTztKbhgW6XdA4ZTCLFIev7LKcquL9GuEKrKb4bgvAXY+4bxTb6LdI6oa6fCyzS2/vo04dil/XvHrBEWW6F28fpYNG9eE67VM/xJM6nHcrTNV2/Ijvdez5Qr+M4NtP4ZMkOqDYWNe71zVnO1w5HDOdQ4ta0hZC31TtnLldGFOvC90vXo4/Axx4Zybl3tlZGpIuSpwO90RLsvGgIKwinEQ1tcOUyoDf4wgPsfv6aq/bKgOs7CUyB3uX/RAN8qbKCEJ9/iVFCQc2Twv0iXe7LXFD82WA4Fd6Ms3RVfLICgUy581IWDqqfhzHreAGIuVvQ4m31gTTvQxmtNk0RUQ/O6QIEWMn9PuLo3ZhPxWxrzMCzu0f9wGA1PHzMEhOOGm0IV2eAYCYH0328fNUB2F38YYvN5oXQtT7a7KeR1YieNjLi7H8UiEInQFiIahAnu+QUsrK7Lqr8EBM0svFHffWYiPxDbIl/WpaxC/1RJVZE7TN7zlVvol3CtVHdL7Qmi+QtuF0oyT8wD5FwdVgp30OuDqRdIhgiVT9BziKD9yCIwbJW9H/lc6BTVFWubPCU2Gb9q0cKg4zEnSgpljqFcjtINfi4BptlrPh+ZGnbPJZY1eZEzVk4yosKXz9AA+UKM/MqOX3ylQjrTdBXE2gkni9XEM7X9HeTu3Z66MZjKcoGCvTcpUayABaEKL/8EWXiHO11nx8O+EqK8muZgAM8Fy7d1J1v54rh8P5uN0A2G346fNR0Me6ouvr47lH5GC3ni9UxK3QvHBYpJhs9Zm+Ty4iPRCTa/qmIc846WsGivTd8VMGN1JQEn2CocWPFv9qryqmWNnwpRYwlpm4cboIRRsFP5QV3goPnEC09h6SdQNBi9z/QqRRm3mbVFRXAbKsbaPmFAKQsuk1XnYnMWcAJsFz4hAiRbMMVVZNUi5dNPyQw7Rt9jAqZmvZlVXHeMct0Qip+iZqIjCQ9MX0oz8dHncDeVW1jslP0jQ0fysWlcOY3MoZg9W4tsoffsk/mfLh2thzIc/ypjBzKaRQN900QK866WmOxwsgKh3bcTHeBfwptwWJbvs9KPW8EvMX5jC5Rx08HibLgQDZb+8iCUJtQ3nxmMaF4wsfXx+iPc0eLbk+5/jgKfh+/Q+BKkVQYPcl8Yltew6923quGdILKiU9377psPpn7lLFOMQARS+KoYTfQRUIjgOdekgKZHdpmavQnV+4Kvc8i+Og+UfLhGyiUFPeR0h3z3yrDLTyb0WlRfh503OJmk8CzceRnsuHPYVjAhFoaTWxf2k0PRAcG81W3zxT+QOrqjEGXAX5I25j8Ysktt/2O3Ks+DHmnBVkEGCCoO0p7NCKgcddXU1vj5wrHaatlKc+EZhIDn+4Y7qQUdUnns3XkJPlSDEkkGZxZwnqW41Dg3X7JMYQgP3Oxrv/ZDv7Ct/82oNp8E=,iv:8rfOF4krmOYUbvrlOafuDey/x9U2uaxeKnw0Qp/reFo=,tag:oJ7fsSy0KtGiIDzRWFp5Jg==,type:str]", + "ingress_crowdsec_api_key": "ENC[AES256_GCM,data:HHZjP6R2ceFOnAOjk+OfN6OGZiejSnntz7kbLgZZ43g7u637kafEUmJEnQ==,iv:75PXPUrG65QNKUGs4jCnTfRTmb/DBB06a3jYErv0OtQ=,tag:lcKn5UvD1QZ2LwS4zSrhFA==,type:str]", + "k8s_users": "ENC[AES256_GCM,data:UuIPx/3GFSGvhBjNBskvTELqw3pHejqOwZmFoSG258A6WTwdkckW9zCp5Iy3ypBxf2oUWT1BI6jYzfuoudsUIR36xMhkaucGjIyR0lwz6arwaCdGS+Xok6n4t125n1RC7+AEHryR4tQFbaKpXdckQY4m4tCHZgvDRjDeYh4OiMAeOvLqqaYwg0FKPQaTd6z0FR3tVwXLO9Q+PbBIJEUVRYVbi6ZsA/UfVC9238LHTVRj9VoiQrI/YwuKffeM90z2nFRnTKXBb8F5WEU14m9OuvnoFGNh1KyCCg7At6vuWoshDtRG6Ao/E36AqqL6+H6QykdO8hG919MgQWgF2pvcWDv0o7N2XYQAsgMiBmoctaUUyAL0Emq1na2clNxMRvmQbAA1ydb3oW+6a7JDf8uCiqJm5wEIHeaoY+sm4tL9muCWANX6LNbnB+FQFWQy3AsuMazr8NX5SiM3vrR1xC9mMBAMrA7spRO3XX8CEcd6zytKy6RZQ9eTxGp8IEfCXAJxXduq7odeb3aBWC0UwcyV7Q/wCPX9csnOineCuiy90JSrQ2apDygVlQol3w3lN0LX3tdYEZNb6LRjtQ7joMplGDd9bG/mS+W4Sso8BghFsKAkFeLYZ40Q1Lyk9GVUF6L0PH17eaWjHLSsoyv+oOVYjpcSm3ZKA5UnIaLVeglG3EzXg+A=,iv:+xXnchjnqsSqD7Czi0l7h9ALuyG0X8fvGAoIdmE4D5s=,tag:JAFmPcaouC1HBrMXRr5G3w==,type:str]", + "mailserver_accounts": "ENC[AES256_GCM,data:UCppEkUPL8IADyrhCnQ7primxecgqBXnz7teJXP6DsW1TZVJfZgEwotHDJsW4/aJvtoDgIJ0zVkgLypXty8xgvnHI1O2eHK2/7blercJcMgK34aoIftHLKCigDQJFCuCnJuf1hgbHG4wmIYSjGoGiB6ldT5P9RTVfQfJcHGeVfgPQgSgpPln5LZn4d9z84uTINttCspN2vEXMHfHxtACYopKSF1Vk7wH7+HEQLzmgMyHcI7Jg6hPVsWR00w3PMvo52kMH096avbTCRVh5hTnb6AH0m4aDebHiKdqXOLORtelLoOEIVqu8GSP6xZtO8mCcZIUOo6MnnzOMGAuqFYCyESoaAn4ZgiTeuTJKjfEfb6L+9O6vr8+5mnO8onV5f8VcrgWkRYXUfEoYODnz3UNgk6IW6mYITnHh5WTfMUr1+J+pyiV1S4wCUmfmj24a5slnaigilcrlbZFqz2cYtJ+J4LFTIwhUhlknzIvCgeugwBabC/hxLyOim5CRjLR9pyUkI6CSleOCrZQp3TDx5FHb9LFQVQzVgKiRTAPMKYPRedZJsCSzghSh8gGn1eT6DKgfEAjg4Ny8FbRQvCJ3ucKRhJO4iV1V7pCrd/Avw1mH2hmywYv56EO6Ri3I3d6D3RVCi+5UUL4RkOUKm/YyaNWMDS79Z7P1dTLlisq7HmijIuKMxWYSi7G7gYxFhW5xwI4KgC8SHfxO1ONIchCXcyS2LPdHNz4CT4zO3zcm7yIFBxiYuUVh4dtClsanUWuPTPrrcZMm0N0k0zBbJTYqQZCgG/IEayeHYwPilHc5FYskeAj3nSY8azjbEyvtXO2KRemo2QY7rbZjwVtAf9e85F7kmVgzxkDLrYBkKGjab4xyQQSwwsgdZwo4iuDfPixdQiEVRkL+LT2RMv5cOhv4HjO,iv:L6DULGVMVujxYFEqEp5JcEDcswsFK+owwJwFTLpx0ds=,tag:ISICKF+ixBT2AZmz+z6QzA==,type:str]", + "mailserver_aliases": "ENC[AES256_GCM,data:8g2TAKItQlgZYrBq5S4vxC+VfX1ER1uvRolrV5LTU+uoaNyZpKFGpaDpPu0kyRGuXDqM84H+Nkkl0OhhudqdD4wUw2JFw4VbjDxssSXKRDpII+dgRyAE4DFDjSKt6HPSuC9OGQ3XBm4ZJ5SeFFhG+BMkIfzwR+w/HJxDBHO1s21A3Y9k2Lm+6JGzkOmOZrZ1M8hHZCYdGwc2gHhrj357LnIbVURYQji1Yqp2fuMX2/jJojVJVKi/Lw4Caz1b31AHOcxuZjHGNd8i7X/Cr4w4ysrw3ehr6JWTTEVobforJhCb8QSJwy8EEFyMVBSEVmdfvd6DJKtsf/c/HpaULgt+NZfAfhGC1crKKM2JwJvKnI70WI/aq5dLXkq8NGsPdWDcf2ISAmm/Vehp2C48zojR5JHrAisna4CRiDv0Mj/uqeqdsE3RyXj4HsyaVMKIfiI4qRyDDCYaHISAIIiq1PDisbRu6Nxwu7zWW0GI2qhmflY8qLLF+CI3w42LSEYcQ1ISVgXom4JEBuCy//7V0qb+fxU7Sgih0XdRm1MQKZDOj0ktXTUKMK3EXq3CHOkyQs6eQNGO7QrgbC9BLPh2U2xf8nyw7O5k,iv:4pdTTXKpkoUiRDI4w3LEbza9eSAJyDCYXn+IPTwbWaM=,tag:unH3UgWnRFUTNUBPTEzU6A==,type:str]", + "mailserver_opendkim_key": "ENC[AES256_GCM,data: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,iv:BN+219E/E9RhA35p8RNazBHiOerdrvNj14vjbFy341I=,tag:AugeIsi9KwjTihoBL6ZFyA==,type:str]", + "mailserver_roundcubemail_db_password": "ENC[AES256_GCM,data:XfIwjf9A52PQjMlVKgc=,iv:7NWAkP3eEk6B/0LHQpwtgCIuyijjruXvxI1gWUHgfKc=,tag:wrFO1Er+sw1vGdPt5Z5Fug==,type:str]", + "mailserver_sasl_passwd": "ENC[AES256_GCM,data:KyD8rCGbzMP2lbzBza6Zy9NTUrf9XoyXryxwCbx+EwsvacNIjt6A/hEyckZybbyG7GE4coBXoY5NAe/Tw/PGU8KZRWz920z/rpWPkL/YcpT6gyTw0R1SThStgLaw9VL5V38Zu+kpRz076Q8OS9QkzbpWdKPhHAwXU02HiUF2iD0eDTwohMWtrsqywoSgOOCTHrE=,iv:384awfhFpKDWu8HXeMSGKqA1mq+CFHPYhf6mhEv2/AA=,tag:oupClh5GwdNHSTlS1CiznA==,type:str]", + "monitoring_idrac_password": "ENC[AES256_GCM,data:C4bR97Kh,iv:9fRpDNHcUSxvmvBOTygwU0QLnPeP+YYhbjHZdbuSJY8=,tag:cpLKRTLA96Wun+kLwdODow==,type:str]", + "pve_password": "ENC[AES256_GCM,data:4hfT4zi5VZ5lTIvoO2mYt1Ptc4APb+RFA5v7IA==,iv:TPURcnaH8IKLsVl4tirbw69tLTyZ/CCH0hMb2RHAfrU=,tag:VmETY4ArlLf9VHawuC53cg==,type:str]", + "technitium_db_password": "ENC[AES256_GCM,data:i2nSqaDGOOeMXBLPu/c=,iv:ZWPMjccjG66gfejQYe6lmFmG7OT312VCJ68Fo0DIJqU=,tag:XQ/PfQclgwWP04GLJlM8Fg==,type:str]", + "technitium_password": "ENC[AES256_GCM,data:xYh6bOvHgpANekUFG2kbha05cv3mhiM=,iv:br5/3nBpgDb5ANUgsJ+QpPOPTzfAwLCB6PmnvC+s0ts=,tag:6fRCB5Ag8SwqsfKsnLQzug==,type:str]", + "technitium_username": "ENC[AES256_GCM,data:12WwnlU=,iv:3RSBTvXwPGykT2XhHGdEX09ffqBm+QDyK5H8C/L0+io=,tag:lDh8N8PEh/f52DsXVRdjPg==,type:str]", + "tiny_tuya_service_secret": "ENC[AES256_GCM,data:ccG9xEfR4RNq9ItfdEiP53OR6xamzw==,iv:WVg11WACS+3obfqYgBriUSzZyKBZUfix/VrgZLBSATQ=,tag:5PAxnGp4/xCsiHUpC/Jq5w==,type:str]", + "truenas_api_key": "ENC[AES256_GCM,data:QaPgCxkpOVuOLNpjhArdLfxNdHfpIylyrO9NsSTAhe7s5KtasI1QVt1PLpKRRH/2GXyr6sfPb7b1nqtDvUIlkdT8,iv:F9uQM0B5XqKFTbZxJPocIcvHI/ZYd0W0AzgV03xtLlU=,tag:0Hsb0H0CCMy5ilEsDWtuIg==,type:str]", + "truenas_ssh_private_key": "ENC[AES256_GCM,data:1P7OGLqMBphG25t+hqE1YMH6VkHAwZ0epHuR+Gp9wynWm7iLylyuD11mPMWYVMp/obMiOqjx5YOcmpDSBIBTAeTqx9XVmXq05ihHdeGze3y3E2vXY3U3zTxw29LTBWRj2CDhpeU7AtKg8Fh+DZMY4EXd7DMTNgdEett+3w6qp2fBGAgUszJpRzIj+yLdQA0kq29P3iOHdYv10fHlgY+Xh4zDVXRGjEQb9KNIdupXLo4SitlMzx+swMxLox4aGFUSEVrBGyQ3tjhuyxd00j6vo5vUh+py/vz8VJm/DMZLJJ1657rLG44Lq+GmlwDGHBcLx02BAViwWhCHsmFZM2Jg6ozGXZQhdaxQw196PV79d2spIYN5a3/IA+ODFo1DjbC7thhTBqUdrvoVSPyB2NVNSqPTv5r/c2WXCxAifPYDDulYLXmOkqT1KNDVX6/3kQId333SHnga5ZwoxevGIHB+n4Sc3XRgWKE65oHlIl4vGX2AaNzhmkq29p3MOTyrUilQKQDMP96bo5+i4lqhuCyjgfPjQx7v6EhJLzL+,iv:Tdc+Jm6vd6RKk8jiwq91TH4mEuHFZXarl728+8yJrQs=,tag:fZsYVegrxUSpIktoNhYEdA==,type:str]", + "vaultwarden_smtp_password": "ENC[AES256_GCM,data:FtDSlE40XNl3F66Xe00y2U3DL9U=,iv:cTG7nQrfypdWOu0JyBL8o9q+DAo41iB4JjNqW7BP6g4=,tag:cn4ncyBrPEbJ7L9Gnx46tQ==,type:str]", + "webhook_handler_git_token": "ENC[AES256_GCM,data:beBCSrjvXSmr8t2mTllGlHQEKk+8QjNzgcGaaF+x4r3gsa8Y3/B1XQ==,iv:+pNszXYt+DIN2oNQnbXw7PljEiDIaHevynpCpvOJsMI=,tag:hVRpJ58FQJ97Bu8XShGlCQ==,type:str]", + "webhook_handler_git_user": "ENC[AES256_GCM,data:vupE3n/HmfnzqB1A,iv:1HiuGbQAKRhijKHYVMbdI4tuNRBxMukziHA/gOGN7Zo=,tag:jhqlVRp4DH3f7Kiv7WpX1g==,type:str]", + "wireguard_firewall_sh": "ENC[AES256_GCM,data:v5nle0tjSSwlLHRlii89FMZXtkGrJl8JMlVkVCYe7qQiTjBcp8b9uwTJc2vaV3jszVxTwUCxXSyICKkZ7q6URXRfS5rUb8DiTFgSYsuZWPyLyJNMU9sT/VW7ErtlmfP3038TTQQa7h2yuN1HzqmoNfSe4O2pxAn5L+X/82UYcz0ehAfxpxTU6rtwGiYtDNrszt9Xt0/sQL61qxlBRYaaMxRgxhUxmHdz07U4AhSmmSL7sXJuc3RqJdMUZ9y1nVBsuOJMuzWGWadwKEThMXrpP7RJ62zVOUmdwuMZBBPUQbU6eZaXKy01n/UlSEK7hCIBm6z2r1O74DSP5nBwt9hgZyVOnR8PCkF84K67SWjoNVh1F3W0xU3owM+jv0RJQfMbLb68xMieV5D9eUQoF1E5op4ruL62ITyY3++Ca82mSmEJzS4vOG931vGQXC+WxH6blof/fX+eVdTy+V/xRIkO5Wz7hA3yBPT7HG6Xv2+kSXbVPOIYWZs6u4ibJ5eLqZ+e+2tiOXF9dVPqTpNcgS+SS37DY0+WZzqAa1K4yw==,iv:vWH2u8vzeyH8YQHg7JIhhAoObJU/pbHnu+/Cl9wx9+k=,tag:www6kWYLGiP4YX1KPNbTOA==,type:str]", + "wireguard_wg_0_conf": "ENC[AES256_GCM,data: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,iv:NX5K5Zr7QT/+mQQv6u++2nU9+7+Bl2d8gik3MBAy9DY=,tag:u/Bc/ENYe+aIH11iafaoSQ==,type:str]", + "wireguard_wg_0_key": "ENC[AES256_GCM,data:6GHbeyd7qEw4EF9sR8M4vSWPi6cQAUFiV92KkgAJuJiItU6sMQu5rG9fx1E=,iv:6UeeznjkXROrd2IUjRv5xXh08zJmxAcvwOnbKf0dNG8=,tag:jd6sczCLAjGghC9RoQkKoQ==,type:str]", + "xray_reality_clients": "ENC[AES256_GCM,data:I6Y3gDco5+XZWBefIJ4ZyVcw64e9JPelnF9MBeHyUZ7lZeZfxQBzXM/5WmK2480=,iv:/5QT6++jCf1cukPl2vgxV9LVTGInW4PO9LzEY/fX21s=,tag:zcu2P2mwpJnlPI6jVXZx7Q==,type:str]", + "xray_reality_private_key": "ENC[AES256_GCM,data:7eWhKSH3uFTrOwqbO8jX0GrUpWE4dbA0sXhOwVL2cNebrabvmyVKGCqOTw==,iv:ngaNsp5MvzecaGl8HKb1auIzRgwmdNG0ZmAsqUmZjfw=,tag:90bczRc86gO2XI48/MsKFQ==,type:str]", + "xray_reality_short_ids": "ENC[AES256_GCM,data:OJrKAlVNwUO8TxkGF9e0D4tmo9SZ+B1cEdh9WOPnDFqBIvltUHJF0w9VxS+hiokn/3gbWHv0TskRS5uLCaR8qgg=,iv:+wzkoe7bs47fI07EEH1g/bhJJidIpaXnGucnway0jkU=,tag:FIRGmd8jRHgo7ZgSepFcAw==,type:str]" }, - "name": "ENC[AES256_GCM,data:I/REUQ==,iv:AwUMmpXwwbflwmqMAwYzq14F0RV2UclidLqgoFZQe4Q=,tag:fCJpGBKLbAkleMiqzPABAg==,type:str]", - "namespace": "ENC[AES256_GCM,data:APYIMt1c+wBNmn4=,iv:WwrdA7L3exB3rHJFd7FPVBgZPx+w3YYCD3Hoc6+2fRE=,tag:LWk8H7W6YeR1YViQ+GqBVQ==,type:str]", - "pass_credentials": "ENC[AES256_GCM,data:u5eYqhw=,iv:lFFP+tzyorVbsbOD6v9SM2sdxXyWJkRB8R+Hj3PkvGg=,tag:6dn0DRKpwYLV+MT9YMBypg==,type:bool]", + "data_json": "ENC[AES256_GCM,data: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,iv:fKTmPDCsMTslu01Hu3Zi2cNdeKRr/3pKY717M/YHbZA=,tag:b6BSMSjqAmb+uVHpZ5sqAg==,type:str]", + "deletion_time": "", + "destroyed": "ENC[AES256_GCM,data:awtNiKI=,iv:HJF6tFkYlGwmRlprNG+3t6N8UmHn7sWRaOnkm+4SyGA=,tag:H+Xl6TOb/iztRLiQRNF4MA==,type:bool]", + "id": "ENC[AES256_GCM,data:VJjOzIN2r8FuNNrlUJe5JnQ5DZk=,iv:nDL1m45qkLv6O2FZdBEh3zoycuvUR1iZ9QZXVEek75U=,tag:JrURTwGMVqRJJQrPoKYyHQ==,type:str]", + "mount": "ENC[AES256_GCM,data:DoOjjdBv,iv:YfVToBDeW2DTVaX5hhK+izGsfaDwDeio4ODRU/GVvQg=,tag:Lz6RmmjwYGzbQSRZ93dhKQ==,type:str]", + "name": "ENC[AES256_GCM,data:boXon+sZOfs=,iv:mBsNozLr+ftij6UX2LQ6YJ1AKVrPTlzkpWsb+SxtTdE=,tag:6v1BCK5GNxEPbYvYM5wXjQ==,type:str]", + "namespace": null, + "path": "ENC[AES256_GCM,data:ivQoNod7CnXxRxVctUV8AT58Dy0=,iv:K1HXhyZocWAY2I3rI9Z9CKfbBNPIfN800VZ61Q73E1w=,tag:+eTr/dTbHa481FeOa8E/DA==,type:str]", + "version": "ENC[AES256_GCM,data:r1s=,iv:4kmyp0/ltjBVXWx5BT6epGTBleVItydByiGunyg6zDM=,tag:JptuOoYbxzdBDMNq34+fbA==,type:float]" + }, + "sensitive_attributes": [ + [ + { + "type": "ENC[AES256_GCM,data:FSCPlpuMymc=,iv:go1HtTi7CjqWPDcwsPUhPX1DrM6NQgMWszJRmuZ/MyY=,tag:O4fEO5e87V58BlLS/kn1EQ==,type:str]", + "value": "ENC[AES256_GCM,data:X0e+Rw==,iv:npG2nQJQb986mD5JR4DiqqVbG6Xc7IYV7TnuXpILLRs=,tag:B+ABzmFw9SHjH5EmXJ7C1Q==,type:str]" + } + ], + [ + { + "type": "ENC[AES256_GCM,data:iB3M+HXdOYY=,iv:KXRDmCdtwSCb9G6xZCEjnh42zBAPnLThXuYpGfffzKY=,tag:nU4XP8wsYb90ew31t5Dixg==,type:str]", + "value": "ENC[AES256_GCM,data:9h7vZCxkP6zT,iv:VUU+ZOCjrQ1uaCYzJ/054hlQ4oZdS/4lHgRyt9/VhHA=,tag:QFHi5OBZ33TfiwL1nQef0A==,type:str]" + } + ] + ], + "identity_schema_version": "ENC[AES256_GCM,data:Vg==,iv:BU2FT/mBD8giefkKF4SqseB+k+OHjyhXmo7jXpkAJZw=,tag:dnF8vS22UZc9lG/4Y+/4/w==,type:float]" + } + ] + }, + { + "module": "ENC[AES256_GCM,data:YuOcwBDo77bP/r8=,iv:+p3g9L1YEg/rc3boVLQRhfOM6RvIxNRuXum0dCh7lvY=,tag:QHzP90NRzHt9IjhiOTe7jQ==,type:str]", + "mode": "ENC[AES256_GCM,data:c9/a87FD+w==,iv:HH5N2v3ecGV0vBYR7IA9Xdcse9ES68Zt7AsPyOUXKLM=,tag:1qHF3AON1FJjNdkJGYQPOQ==,type:str]", + "type": "ENC[AES256_GCM,data:yrwLqvbEXkyznfwI,iv:pNnC5dJD9goapLSsgDCiZfca3saoCiKgFIu4IXZeT1c=,tag:1gtUNiGdxK0Lutma1T1HIg==,type:str]", + "name": "ENC[AES256_GCM,data:pjc18A==,iv:F9AUDAyyb++QHvRNa340UDTnil4ETgo2pLnibcOHEDk=,tag:Xt25XivZdzYD3YHNnOGGOw==,type:str]", + "provider": "ENC[AES256_GCM,data:IiZQ9DqPB9acQmlDJ1thpUOv8QgXXoYQX03ctb4HbHNyhhxeOMpNpbkruEYAr2kK,iv:MetzR2DisVSxjYXieAybhkwlQ5Fqok9r/XQcwNAUles=,tag:A1o3t8NQA3s0PIeQ6YCpSg==,type:str]", + "instances": [ + { + "schema_version": "ENC[AES256_GCM,data:jw==,iv:bFlIxdG8FCA2uR3LAWZ4gTUecoPgEeJQDneEltecurQ=,tag:ZzHov/at6StEiUMHiRPEZQ==,type:float]", + "attributes": { + "atomic": "ENC[AES256_GCM,data:Whs4BA==,iv:6sezkfpqaa4n6paPjfjW32sFAkP/ioQTzKtmnIVKgUE=,tag:ogStqGBYK+Sq4/oG5omI2Q==,type:bool]", + "chart": "ENC[AES256_GCM,data:h0gchfRMykn4YQuamws=,iv:lSPc3OnP2iEZxp4bnq6eJIA4WPw60H8MN/1oCKbGuyE=,tag:U5spNZLv3F+ZLqUyUk9xrw==,type:str]", + "cleanup_on_fail": "ENC[AES256_GCM,data:v7EtYUs=,iv:s9Xj+xsyV/GaB6Jc8VblqgHn0vv7LkoOlG5uO27LpIY=,tag:7sKbQor7uiS5+CHPmBDmgg==,type:bool]", + "create_namespace": "ENC[AES256_GCM,data:oehHdtA=,iv:MtnYZRjYzow3c01nsVsZCpLqzDbioF41B9tSpGROpPI=,tag:iVqRqIuLYeuCMup2BXuBwg==,type:bool]", + "dependency_update": "ENC[AES256_GCM,data:aDbmSfc=,iv:/9sAlKSEMREVTyu9c7LsTrHG22ZoEewysc0RmBp97u8=,tag:DVJNrYmJvkVurVT794tUIg==,type:bool]", + "description": "ENC[AES256_GCM,data:rEGeoLVj5R5+K9cNVEWTYg==,iv:gwtG4A6ebu8yVmA99ZZqEXH/w8pRcSpyIvbZOZkJKeM=,tag:9CsABsIauRSLJ3xmNPRgDg==,type:str]", + "devel": null, + "disable_crd_hooks": "ENC[AES256_GCM,data:4G6754E=,iv:MHohB1urg8UAz0TTngPK327EfkhX6WWv+wJIyHR5CxA=,tag:YsCnSJhgeRpc6kSFcOjkXA==,type:bool]", + "disable_openapi_validation": "ENC[AES256_GCM,data:N/4Wwkg=,iv:5PKlEoT5HubP63tBYRPLy1XX+TDvIqz5btdDd91vjvo=,tag:ymuV6TtPnTY+5zbjPeIiPQ==,type:bool]", + "disable_webhooks": "ENC[AES256_GCM,data:dWu3UIo=,iv:8GixWh/rdA7XBN5NLz1q3KflN7AbKXALzMCT3Q9oCz4=,tag:bCptePW7aHmLLu9Pc/qpGA==,type:bool]", + "force_update": "ENC[AES256_GCM,data:Vr9UCRU=,iv:Tl/xk88CTPK77E+VrdPUWJT9/ofxQid8MOTU9qu8oHA=,tag:4CJPZT0AYdsYuSCXUKo9aw==,type:bool]", + "id": "ENC[AES256_GCM,data:1sypbQ==,iv:0Kd1AIkMSt1QDFmYik9tjSFiqRVwipETQE48DOSsAHE=,tag:V6VdPAtnuEbtCKuDxgGPCg==,type:str]", + "keyring": null, + "lint": "ENC[AES256_GCM,data:c9mYU7o=,iv:rKmJGNpqdW09AWRVZLzJJNBoOI7/MlJEckWm+eHxLPA=,tag:r44J6ALVxc+Q9iLSIbPAiw==,type:bool]", + "manifest": null, + "max_history": "ENC[AES256_GCM,data:UQ==,iv:zlplkueOuuJtYfsmhEB+3YbDNcRk2KAefgPklPOVMho=,tag:70E24RaEb/Lse3cAZ0oPvw==,type:float]", + "metadata": { + "app_version": "ENC[AES256_GCM,data:MhqDxUzO,iv:szmGF0WobhMcrIihk+KzSw3isczFxFsIIdJpPSaZuv8=,tag:1elEI532j/65/oz8lXvu4w==,type:str]", + "chart": "ENC[AES256_GCM,data:2/4ASCO0lTeINH8F3c0=,iv:fsdgczm5Vfk2PUNOGw+5ztun5fep7WXYDquFsmF9ots=,tag:3DNxpo59SfAZLFZg1HGIjw==,type:str]", + "first_deployed": "ENC[AES256_GCM,data:jGhtFytnfznMlw==,iv:4FPR5SndS1EFrSPMyypYIUAULDtv1NVcms3MqZ5Tz3Q=,tag:uWefF7Ct6g70YvPAChfAxw==,type:float]", + "last_deployed": "ENC[AES256_GCM,data:U9i8BYND0z9EdA==,iv:hUjhPshpi9c7WjfP0F1nbUPSZbL7FDaaVjl35M6aC2o=,tag:v4a88x6n4KqD/eQXWfv1ag==,type:float]", + "name": "ENC[AES256_GCM,data:suaPvQ==,iv:q3J+9n/ARXxe5J4wZMcwaAm2jFh4e5W+Bpu7Fisc1pY=,tag:B7pRC1GLqan262yqR0mmvw==,type:str]", + "namespace": "ENC[AES256_GCM,data:nGLcQb+LNZEl6Vo=,iv:FZeCPnQoFYCK3xaaZ82MCfEQ1MNo+lGBfqaiWE+tLL4=,tag:mUUlrj9lV9XTtXiVcQMLTw==,type:str]", + "notes": "ENC[AES256_GCM,data:1S/3nTp1fAeI4/IF4PTdzSPqySO1rh8Pzq4M32CcKnKcklT3VlWUQo9a69USWK8BF1WoVTwK1zu3f+kbwIZ4bEJZevzwMuCcoHrTDfXeLa968ZzyuO8mGcvBO25i7F0vbwxRR59BX+jbfxgaUuKmrCUxBk0EdLyDSYmPdJ25eIL7PMMazcybCLk1sgLhpV+2qIwr/3U2oKZSameIfbjk5c6xhr847eG4iHEvXoGh0uEwnNRqFsa7mT3Q9NxngHelxKlB7n8qxl+OjAVgbPzk6KHgEY6UYYSI3a1tygeBT4ZkaerUJ15lYRzET7b2i+zcIjF48Jc5mMap27XvPeY4eFSqS3uOUZwtRMpWSxpQLQ0PGV2uc6Bmvy1xwANVAy//o9UZEOA8zEzcowLnmaPTnPlWNx8ZsjzaKwH6D1ZPBHFQMCwzS109pJdR/l5tnYvuAW6duXhPtl8m1Vr1VstLH/TSkdlpp2HAJA==,iv:XlEZmFYijr54uud6P97067rYG827oDb1KUOjNHMHN2E=,tag:Urm2I5k8oMCfvlbhznFykw==,type:str]", + "revision": "ENC[AES256_GCM,data:dw==,iv:PR27D2gQ56afvhBXavMmQ98wvkO5M6iMAi0tj8UHC1k=,tag:cdAYdYOPd/0l/ZQyZepkFg==,type:float]", + "values": "ENC[AES256_GCM,data:yw4C4y0UxESibaTFkrVbDpfViwatTOKyjjR28Vk/hT4MvNZZhDVDxnQdzUnx735TJi5qMA0aHBYVv8jDuMlkgsqVWx0iu/4RblsjnuRF1gP3/d0IvmKV4TvE4WzHWZvcjfzXQesxsw0gZymJ5cMSbIdoW/dp1xhZQXysGZUl7CGhnywdSb5JU7Fw5UaJ7sEISHO3eWdH3IVqpuqBiuMLPOVQ8jDZ57+sfEspikBEEaR3gA==,iv:eSLxe78NKI6HjBbfvrH1cXJCZE7OdZjtwfxBhf6RAXc=,tag:b/ZG9MK32xjmU/GZADgcWw==,type:str]", + "version": "ENC[AES256_GCM,data:mHrSO9ly,iv:X1BNUh290irGHdh2hkxb03Y7r+wZieJJVUSVSrqhw/g=,tag:5E+/m1FuwuTDgaJKSFsYqg==,type:str]" + }, + "name": "ENC[AES256_GCM,data:dnl4gQ==,iv:kLQ/1lbqT0uVn88hXWaT6HsKta0nIiK43x8iWI4IFvs=,tag:OgjQDrgzUMNLa6lkH5npEw==,type:str]", + "namespace": "ENC[AES256_GCM,data:G2vg5AFKe7RbmqU=,iv:Wmj7pCwItpVsY8exnzY21QFxMqSlgDzcPfGdVJE08fc=,tag:l9GHII10iUMe6Y77KiFyrA==,type:str]", + "pass_credentials": "ENC[AES256_GCM,data:X0Se3Qw=,iv:ivSxMzsHftyOEoV3wpkiwqlRdm2iFXBtjrNaeBgMz3g=,tag:fR3GfgP+7wSudDUTmxYGQQ==,type:bool]", "postrender": null, - "recreate_pods": "ENC[AES256_GCM,data:KzyPxe8=,iv:53Re0a3dSWmeUEVrpw8y/VlOukKXFoXBSZFlM3gwBwA=,tag:N9u4RTZVGLImylbqPVNikg==,type:bool]", - "render_subchart_notes": "ENC[AES256_GCM,data:gZQUOQ==,iv:H7XjaXSyi7G+bpHj/BAXVUv0XdqHtFr1JLYHiwzhElQ=,tag:xmohAzJc5QG857+pJL1SOQ==,type:bool]", - "replace": "ENC[AES256_GCM,data:5YoLlHc=,iv:bpoXMv00Gdti95JlaJ8HUwAuXTiimEvYdwBvZQUHOCk=,tag:N8jw6s3lJvUoS+ML4adcqw==,type:bool]", - "repository": "ENC[AES256_GCM,data:n/tHscKhZi3Wmbf1tpzwG/sLCQ0ZxlJPp3OmLDxAgpjWR0oIKhYn,iv:QUoY9Y8GOuWvSd0pKfiRsEFRMHt32pPQnnmJoUM8erI=,tag:bm6lL/ZFpEtWhEWaNTTiew==,type:str]", + "recreate_pods": "ENC[AES256_GCM,data:7dwBSDw=,iv:DhXNnbVy58Sx29QmsCuNKZ5flSA7XiiYxCJ+ucTVdFQ=,tag:o9VyC1PQ7972EDMsWnx/AA==,type:bool]", + "render_subchart_notes": "ENC[AES256_GCM,data:DgZcYw==,iv:dsdQS2S7aKsRx2vj77+CM3unjfoPnpOZC278AR6fgd8=,tag:YiZWN5HJh30zZA8QJ7jLCg==,type:bool]", + "replace": "ENC[AES256_GCM,data:JmfT2co=,iv:jrk9utEtGz4Qat/NJMWLqM09n6SmhVbDwRq1AB6q4Qs=,tag:e7fLmCtDtB5/kTO45GLkug==,type:bool]", + "repository": "ENC[AES256_GCM,data:WbgXFSsRpXphosuKf8Lb30u8S3KHETUR1EdDBgwsqc4vFgXDCN4h,iv:So/O3CJX0Q03Iu7V87vtpzjHLC/tRCHzKbfBYGmSsg8=,tag:6JnKaftYbM2XLiFKXg3g4g==,type:str]", "repository_ca_file": null, "repository_cert_file": null, "repository_key_file": null, "repository_password": null, "repository_username": null, - "reset_values": "ENC[AES256_GCM,data:BSSDzhE=,iv:P4bgmA3cgxiRKDOKfK34fc5T8Nlma7NtxunZKaoZ/f0=,tag:wbHSjWG+TNKt/vP04wkoyQ==,type:bool]", + "reset_values": "ENC[AES256_GCM,data:uD21Bkg=,iv:u7JvFU5/DdbJX057p/6HT7GgYARHD+pfPHwM7jew+ok=,tag:vCN+IkGTtnyC5DajwBqdlA==,type:bool]", "resources": null, - "reuse_values": "ENC[AES256_GCM,data:JFILVrY=,iv:nkX68AkQzEycGzh7T92Gdh4dFxVIqUg/Zq9fjKjRHsw=,tag:AZ40cbsAJBEbGlohpgVwDg==,type:bool]", + "reuse_values": "ENC[AES256_GCM,data:aFh0XOg=,iv:3CC0B1onPt25VT0CcAOUEIo9OFZVbXcYvykhs/T8uQE=,tag:PorlvNoQjd050N2Pkrj/Yg==,type:bool]", "set": null, "set_list": null, "set_sensitive": null, "set_wo": null, "set_wo_revision": null, - "skip_crds": "ENC[AES256_GCM,data:DQeWk9M=,iv:hKyzYslP9r0+T1qg6uVP5qstOizxYDA/kN8fc6x5EhA=,tag:bAnaoWAqAVn0G8GGimLVhQ==,type:bool]", - "status": "ENC[AES256_GCM,data:VVYzXYJeABE=,iv:xRpJGx8L6S6wDVCqo0peYB4ihE3IbUZzoEkuvp+IFW4=,tag:ZPDP4ScFANdwx0V2sr4gUA==,type:str]", - "take_ownership": "ENC[AES256_GCM,data:eHe+LRI=,iv:aakYUE7jTZwCw7KSlx0+0xvrxlXQG+ELq7JuylDt6Ig=,tag:lpfH7K1hTlLWpgekY+pbOA==,type:bool]", - "timeout": "ENC[AES256_GCM,data:GSJ0,iv:HWNU4ikyRIMnybFDr91ImQQOM4vvbKpMpsuS/Eqt8Fs=,tag:ZjrDak21S4IyjOL8cMdt0g==,type:float]", + "skip_crds": "ENC[AES256_GCM,data:O6K9/ys=,iv:vzE8o1//VEBY6O4/Omf3vdG+0AkKhwSDf+xAUlBvUvc=,tag:ouEEYO+SkflG4Rrgd4tbiw==,type:bool]", + "status": "ENC[AES256_GCM,data:18MS1IxWkdI=,iv:PwKqvlvptRibupnhhQR+HTm0h/oHAoy/N+V3tJ5jDrA=,tag:6hkGYGzVLsY5ShnxvkKknA==,type:str]", + "take_ownership": "ENC[AES256_GCM,data:LeHkRII=,iv:IxMHQJprsIOTH8pOBRJ0ITm4hp4GIc6MTCPbgIGc40U=,tag:Yrx9GJFxHATIwCp0MczAfQ==,type:bool]", + "timeout": "ENC[AES256_GCM,data:wxEW,iv:Xi/bjEtNP4aX0HNw7NGHU07mzmgrw9WJLxGOx+oJJvo=,tag:NTTpWfkM3YEsXD+nTqbeRw==,type:float]", "timeouts": null, - "upgrade_install": "ENC[AES256_GCM,data:A68achs=,iv:PQIby7bub0yqyhbKZv1jVi3qNVtIe65euVsXLq7L2C8=,tag:hHYXSKYQn1Tikpc620zIJg==,type:bool]", + "upgrade_install": "ENC[AES256_GCM,data:pJ5nvcM=,iv:s14qfakTjq2B9wDVAVTqli9/Wq799Jb1T8PBQfznLHw=,tag:JLQi/HGkPA6ncZkXGcJ9yg==,type:bool]", "values": [ - "ENC[AES256_GCM,data:QWaH9xqfO8SpNelwmJTgo/HYcZPPo1YlZS86aDMCWoXo37mL3dA7/z0xwSRSjgalSJwFv4A8B2s02n5SPjTMw0Mw1/CjHSzOdK3GvWJNNQV5KWiTFfx60rwFln1HssQlcla1cm7dSXqWE5mJfDAgfvtvTU4J0p3hcKAli3ctC6ZBBJjwSkeYWhszD8bGsfxa,iv:rniqGccmB4C+6prP4IS/X/Xdh3TRGK/cCvkhpdqFNFs=,tag:ctJy8lnwKK90yrTXHWOy3A==,type:str]" + "ENC[AES256_GCM,data:tV6v57PHsQ4jfQBIs2Cf2/v2XiXJojPvUNBwRvdNeCXGLY/8yHQRsr3b4MmJtDe0aOhahxllwFQmsa+vE91ce8cBKl8gwSz6WEwIaXZhTgvfaLXE2y+R3txGsJ573MQfF+rOFGAit4zI8vhsuiHgrVSaGnHURJENN1T7nthhJCTmIZc+/QVvTZZ/UXpUGy2rvPtHRKiOYidqqbD/GjSybW2ZFLjAxipF7XGkydjgkPoQ96GQZzZvP7l1NwN4JkME6aYsEmDnzVh1,iv:peLlYJX0kG6hSuV6wrVHx5tH51VdJdGy3+Y5QvUspiw=,tag:f5nvt2aof13/4F9Ll3WPLQ==,type:str]" ], - "verify": "ENC[AES256_GCM,data:hhQFa7c=,iv:i8VdGJ5VrJRGxdPur3wZLwRaZgKWwp3+16sPb5ivNCI=,tag:Y9PxF0tgkucmk+PaYF9ssw==,type:bool]", - "version": "ENC[AES256_GCM,data:y/OdveA7,iv:hheTSbmKqErx+gCj6w2chnw1JJ9zgqKNKGZVSQZELi0=,tag:CCMqnsHMOpRPFNROeWGuIQ==,type:str]", - "wait": "ENC[AES256_GCM,data:sa6APg==,iv:xCqmWtWd2YCSxLhY9pnDihXGxdQMLElxUKeA7ASxq0A=,tag:DUy6d60bqkICvSG2ZSbPcw==,type:bool]", - "wait_for_jobs": "ENC[AES256_GCM,data:bw5lz50=,iv:axdzEhwUWWnJwmj9M1sht01MlWX4DTlSgnvq2oK/3dM=,tag:4YRXqZyOgw6/nG5tAf895Q==,type:bool]" + "verify": "ENC[AES256_GCM,data:RuZwHwo=,iv:myEwhFxisD1U7hbl9EOd5X3oZfBokEBSvWjdeOIuVtw=,tag:Wnk6gKkRhwj2ANY8/6WVjQ==,type:bool]", + "version": "ENC[AES256_GCM,data:Umj42DOt,iv:kSN2hrp4uSsp4DHx4Zg3PKgD5gS2jJO9KxMJVzC0VNA=,tag:aybF972J1TTqQZA+O0WEVg==,type:str]", + "wait": "ENC[AES256_GCM,data:4mIOsQ==,iv:p4BvBLe/cmNhurFZ7CM86aVV15xjhsQXc4QsI8YqhsI=,tag:M8uauh86Cb8AJkHALthI2Q==,type:bool]", + "wait_for_jobs": "ENC[AES256_GCM,data:g1haN2k=,iv:YBAGofbbJ7V04l1JdKiLWxY0h/Z2C8zHb6AvVEwaePc=,tag:7MVUbmocuY1wEsBNdVq/uA==,type:bool]" + }, + "sensitive_attributes": [ + [ + { + "type": "ENC[AES256_GCM,data:rg6SGaD0EcE=,iv:n8RBMq/Lp4hyFzSDUEV87mYX6vkQNa7+BKFgoiejyu0=,tag:GvWMWPsbJ5P4ySR9MhGeEw==,type:str]", + "value": "ENC[AES256_GCM,data:XH9Tq3MGXXqYJqdHGWx2kCYwyQ==,iv:GVaWcVLQi1kDsogpNNGJoIQXGRBcq6nlID6AQlcnVVo=,tag:CQRaoOiGMrEt4SxRDEnFwg==,type:str]" + } + ] + ], + "identity_schema_version": "ENC[AES256_GCM,data:/g==,iv:zQKGwgwHuALUYCYW/uYqB0C8EYAntvLV6woti9QfgIg=,tag:IbwINqNtDBF9H1A5rcrwgA==,type:float]", + "identity": { + "namespace": "ENC[AES256_GCM,data:5E/Hh0i0/hwEWRQ=,iv:hNAib/OaVUM5SV/yKaYkFHLijt6pGXrBGaiagQzD2js=,tag:TEuZBsPn5xpmYgjsQ0HUSw==,type:str]", + "release_name": "ENC[AES256_GCM,data:5Ny4Kg==,iv:lBvx75J0uTvvEc47tMM3qKzUfQeGzOk8C3uj2MQkxkQ=,tag:vnqslmmTtLX2DyoC8/HMrA==,type:str]" }, - "sensitive_attributes": [], "dependencies": [ - "ENC[AES256_GCM,data:tutAVergsm7cpFbfOC0nEPniM3jw6xJjXOkpWEAAAuwg1jz1vxRYBKLTJ4o=,iv:tJLEWAOTc7oFOn1VOITqTTNvZbGkRUjQQMBY0KHaECw=,tag:whP6fX/cp/lMuxORHizLRw==,type:str]" + "ENC[AES256_GCM,data:c8Hx7I9AiVufx3b5YYL28eq6RJS3aAl+yL6urOUm580WluQlxDKHCEheyBM=,iv:GmC8NRyEhQANN51uLpE7B0O22DpH0OzZEyloCelYLGw=,tag:czT/3lGSHWszkCRy+hYPwg==,type:str]" ] } ] }, { - "module": "ENC[AES256_GCM,data:RTis/X1eDDJdUq8=,iv:KFPw/yZwguLHgTo1Le+rt6/tcwhAoKoyL38mb61AsFc=,tag:3vsxc6HlvaUpJfVYHSbBuQ==,type:str]", - "mode": "ENC[AES256_GCM,data:l9SszzNU2w==,iv:0Bdeq3PfDHmED15LwUg0rBstJPMHj+QjYmHHxnayR50=,tag:IC51b0s3lmB69xSstp3Ruw==,type:str]", - "type": "ENC[AES256_GCM,data:UNRheeYfuqjawsT9fHsjwJt7TgU=,iv:u1k/f97fEFVlY4OlQ0cZwR6Vli3yWVKv8ItiHPOHqK4=,tag:d/SlS/jFe1If/d+gQJb/pQ==,type:str]", - "name": "ENC[AES256_GCM,data:ARdy8G072YooKdo=,iv:NKFaoV42xzZ9hc+tTDIj+qBCSmzr2Lg4sx/bAIPut00=,tag:k70lrPFm88V3FIBXNHjwBQ==,type:str]", - "provider": "ENC[AES256_GCM,data:/8VMguUgf5sFf7BOM/Yg0Yr5e/RFgkEV9rELlnV7mtplIDJzwbYjdRczjaUEKxVOidpksKBD,iv:y/Tte1pHDywiDitGSYTrDikEqYK+EcxMhYRzbwlkZ1M=,tag:CB8dSFe+kZJDfowpoLAnjg==,type:str]", + "module": "ENC[AES256_GCM,data:5rJ7SZ7z4KZn9v0=,iv:0ZgS0W3Kw5gb3cmA04FYLG/AlxEa7cS7ud44mStAWVY=,tag:vFhv8BKlT/39Tseqfafupg==,type:str]", + "mode": "ENC[AES256_GCM,data:j9+iGigNYw==,iv:hF/OHl1K+aw1QHu4yhp7ehyk4XaRxnC3HKiPDW4BUbw=,tag:rsmn1t0u2QwdaWEry7fm8w==,type:str]", + "type": "ENC[AES256_GCM,data:4aM1pFtTPAGPkWVZDEHcrWA8iG0=,iv:SJkHt21faCJ+IKOKermhLQPVRlDaSAaY7oZuxrZmREY=,tag:j0yTJW2Z3xXLAHVr/OhoOw==,type:str]", + "name": "ENC[AES256_GCM,data:Y0FYE8T5U3yPeYE=,iv:ZuvS6nsU6ENosrpZcvag2AOkK1LiWJSy8+FkU/2C33w=,tag:hfWLO2dhhxamejAZUra+iQ==,type:str]", + "provider": "ENC[AES256_GCM,data:Pc+6Y/fMGl7jgBFRFc7pUrFMnKmyuH7UpbJ2yUNsmeKPdeK+JtPgqiqRe2e4hoPCwmXrmC6s,iv:PmvYrjUZO+94pHuL5xtHm5k1qTMTCFbjfcXvPutFBQU=,tag:QcXhQwmcACc/E4aWENs9tg==,type:str]", "instances": [ { - "schema_version": "ENC[AES256_GCM,data:Eg==,iv:POycZkaQAxO6gV70/s6cA0ErrpaQHiGAlyid+/oAt60=,tag:fDpn3HA391B7hUTxjfoZ/g==,type:float]", + "schema_version": "ENC[AES256_GCM,data:LQ==,iv:S1rbez+4r7Qncs3Ixy3YElqQ9czhSidh6hvE3AKFKXU=,tag:c84S7Tgul0VB0F4mFHMJqw==,type:float]", "attributes": { - "id": "ENC[AES256_GCM,data:1HnhaPLtT+EeSME=,iv:75vs9xkl62RkrZiHigsZR5Sh+ux/7b0pBdK8L8bSA/I=,tag:T5HL36tKGbI/e27b5jcKEw==,type:str]", + "id": "ENC[AES256_GCM,data:VGxNKHc0yELlfoA=,iv:G3C9hrB7lrU5lulqqzFkuNNUn853wp4I/Jn38upCrPk=,tag:Hf/Ox3rc6HJ7pTzwvoU7hA==,type:str]", "metadata": [ { "annotations": {}, "generate_name": "", - "generation": "ENC[AES256_GCM,data:yw==,iv:Enwqf6bUy9smZ9vih/Khfyh4Sz+CAi8lF+cWjmAdiFc=,tag:se0ExJEm46tUygmZJmM97A==,type:float]", + "generation": "ENC[AES256_GCM,data:kw==,iv:GSl53GvT3q8vbXY7UhTXCxOieXAAM1Q2EfjMWu9tZ9k=,tag:SUaBeiEtGhLffslhUwZRfA==,type:float]", "labels": { - "tier": "ENC[AES256_GCM,data:TVp+JIknXwed,iv:+brf9tpmK2gq4uMx/VE7yM2yf3mj2piJfey4wtd5zU4=,tag:AosuOVOMo0+FpVe2GunXyw==,type:str]" + "tier": "ENC[AES256_GCM,data:21JL98Ts3Lc+,iv:kxN2aZXi/CuiHRe0KIoDZ7bwa9n0pVNHj6o8uFfelNQ=,tag:Qzn+4Q+ChwPpbGsbqJ5YZw==,type:str]" }, - "name": "ENC[AES256_GCM,data:BBYdZbAnU9DJwwc=,iv:KgzLh09BNmgHWfETBsjJQOJ/Ikqpt9gEcsMCjhNYgMc=,tag:i9tdB4RaF7mAzx1nuOa5Yg==,type:str]", - "resource_version": "ENC[AES256_GCM,data:VzTNOrSG/Tio,iv:/HcHmhfPMip9q7UWoFFWg4Nn3IjwLYubusFbgL38UZ4=,tag:kHyKX65NWByA11asXB3ekw==,type:str]", - "uid": "ENC[AES256_GCM,data:3Ou7mX/2v0urMSU9j06Ti+/Pi24ZGFQ4QISseEM/0SZn05qo,iv:SOgKQM9uNCUvS3BMWpl/M8JzbMQq4Re9781etdFQw7U=,tag:JgUsia5IRXfdNceurE6cag==,type:str]" + "name": "ENC[AES256_GCM,data:sadc23p4Gwem1/s=,iv:AkMmiidTg0rIWJFIqlw2/amYD5ZXJ7t4QalMKgX1CuY=,tag:pAKewEzNO+UpWhQx1WXZSg==,type:str]", + "resource_version": "ENC[AES256_GCM,data:1GZO3kT4l/4u,iv:TN8DI+e7I6Uj1pY0UyNQ1XFrbav6B2cSiR5/W60gGZk=,tag:dqo7HxVUxjjNzt/SWxfA1Q==,type:str]", + "uid": "ENC[AES256_GCM,data:XlSnKyJ3zQ7tcV9WNgfbXpyJ6ICfwbU0qP0HR8QKAgooctyv,iv:GAvk36xkX5NZ4ojHC3JmoET58Buwx5P8xV3J7IT/NQ0=,tag:avHDe0IjhpK95XjP2k2g6w==,type:str]" } ], "timeouts": null, - "wait_for_default_service_account": "ENC[AES256_GCM,data:rOChatg=,iv:e4lfPVGAnx8IA/3iRuDU3spHHSgD1ymETN00xFvDWaI=,tag:FG/JqsiWpvfWH6nEIwU91g==,type:bool]" + "wait_for_default_service_account": "ENC[AES256_GCM,data:kHLk9G0=,iv:+Dxebf+/2f39/AiWvlO6itmHKjmpuxLtDqwJU9FmNlc=,tag:4JbLjmxQfqDRUhNlkPWJjw==,type:bool]" }, "sensitive_attributes": [], - "private": "ENC[AES256_GCM,data:e7OW4JmAaHbR4b1L4naZeZQrCxtf/d94+HO0TZYd3chLY5/sxrhGrMY+ko8vdbbYjNMaMLmsMMo7CJdDC5H8I3LIaoBiT85ldWBWEBWBFLGffFOYK/SRpQ==,iv:/sUyInMIMhY0n6uKXth0w0ew754KrJw00iqYA7C12RY=,tag:B9sWFdziKX+0Aa3zTMXiKQ==,type:str]" + "identity_schema_version": "ENC[AES256_GCM,data:Pg==,iv:dGHlam2ggxOioApM8FcorYmoZZyATwvQ0vrTrhcjOjM=,tag:QAdImzbfDsmt/Ob4uMwurA==,type:float]", + "identity": { + "api_version": "ENC[AES256_GCM,data:f4A=,iv:73AjC8SQwWZPI21rChn8bBSCsRbCJ/d618Rhrwfl7So=,tag:gl8afDrwYVCdcRyo+vfmmQ==,type:str]", + "kind": "ENC[AES256_GCM,data:C9igvvf07YwZ,iv:3WY4lgTPUy7ePGyuE1HSX3i6+SkuE6iMgLZDsEXeiQU=,tag:NU8LW9BCGo9szdmNX5U6/w==,type:str]", + "name": "ENC[AES256_GCM,data:QtEp8UqQr20Rg2w=,iv:YUeuTHfIXL7asj53MfM69ejhG/medoKjhLgPn7gDCK8=,tag:PaDdUdzB8X05zzJrJF37TA==,type:str]" + }, + "private": "ENC[AES256_GCM,data:/dq5199HIOzL5yU1fr1ynu71CsrtzThw1k6N/xMgB1GFFH9T8IQ1fXN1YSfXNGOMvlH/0qN+7byHICaTtgRLrJaPREOaBvo9iVoUkq95YSdIDtOUX8+d4w==,iv:cEMZ1SLCaOX9Y9q2VU/P3cKc4TcsFofKzramgngzMC4=,tag:mQf2IldUBa0xEaiQ5IC4Sw==,type:str]" } ] } ], "check_results": null, "sops": { - "kms": null, - "gcp_kms": null, - "azure_kv": null, "hc_vault": [ { "vault_address": "https://vault.viktorbarzin.me", "engine_path": "transit", "key_name": "sops-state-cnpg", - "created_at": "2026-03-21T11:22:33Z", - "enc": "vault:v1:HI6Zt16/JPTVu983iEtXc+jBA9D/7/1ZTQVRgRF2zNtQD4/46cMW9R3JNfTK9elfNIxEk1vLrCDIcMLC" + "created_at": "2026-05-22T15:00:03Z", + "enc": "vault:v1:g0jQaZpGroBIYSrC0Zp87kr81bg4xCNAC+byJn5QrQIK7qQxsfEx0nsw92DcI87dTGlwDJBP3GWfIEvu" } ], "age": [ { "recipient": "age1z64h9t3acsm2rr74pz7j4846kwj5tutx9sk78jqv46y8fln4vs2sy920ce", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0OFcwaWFHZ1pBQXB4eWEy\nT3lxckxZWFhiVWRQNnYwdTJjZUliWjNqVVM0ClNGblI5QXJWUCtUMnVpY1llYzJJ\nVUNaTHZ4SVVDNlpQRUdaWWlCVGtPRWsKLS0tIEJrdFczc01oREM3OGlzcjI2S2FD\nb1JqN2paR25oOU9nN0ZyNTBHeFljUGcKonghnVeOPMVP1KHtL3BLwK18RbYR4CbI\nAyfL9fBvSFVOLgls7LawE7R40lsUFQJPPHd+AU1qUeBuKxgbiFs+4g==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhMGsrQStqKzMxd0hzTkR5\neU5oOFAwaHV6c0lhVzVhY3hRT0V4VVlSRHdZClppNmQyZVRML0dvQlhGSGhLeHJY\nUjJqeFBsbkpUQ25CTi94OEx0cC83a3MKLS0tIDE4MjNGVG8ycnlUY1luV2hzbTNY\naW50cElDaURGRCtheGFuanRBVk4xZjgKj2pWEOWdWhmD1WeMnhHvEcQy3st+Pux5\nBYK7SVrMMG3//qmuyQWJvrHErJDXOjNkCNGo50HQlpiOE8robYYD4A==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1rekkad48r2wzhwqgfetw5yugu3ln3qlht4xg3txmx55tee8cveess60r90", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnUzNwckYvS3NFWEU0RkJk\nZ1E5d1AybUY4cndWN3Jvd2VBRFUxK1p0T2xjCmNDMEx2RlJWTXBRVllWZVR1dHBy\nejJQcnhZNWIzWUxPWXE5ZVRvS3hXRmsKLS0tIDl1MFBnRCtRYjJaTHJKQ2tYVldz\neUxSaFpPOFVVdnBCOGE2dkt2RysydTgK9lfXhIhYoNTH4PPf5mkTsiIKIDCxBLPk\nZsLJTEd/NHy9yL4q/iQ88LlwKiVCDAsMYX10X+Z0Z+OWc9AV0sLi3w==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVbHVDaEJIRVA0c04yWnYv\nY2RoWExuamNHcWNSWkpiR0lRYjJCR0szK0NnCmxSZUg4eEpXdkZDQnFlbFhTUjl1\nbk5OaUlxQkdxVDNjTEFiRWhLZFJTQmcKLS0tIEdwTHhYZ2dBbEVWc0xZcjdOTWFq\nSVFyUm1qQUovQ2pjekNVcktTR0U5bEkKroY9qcGB1ucBW1nO0jlRajEGEWLfz/lw\n+6IJhlyaHvYE1PMGCwHE5VZjmLBPBzILFEcuYcMs0IClRiI0HnTsdg==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2026-03-21T11:22:33Z", - "mac": "ENC[AES256_GCM,data:1TDsbpzVtAsLEteYbMEqbbM/wSeYAkZ1iZNTn/k8q6sl78ztA+8y3oilIyS97hlW0FEOnSsYhAFtZBVgzxEWi3oQHLlp9ILJusXXD4JlswUWj9342QTBgjWeA8no4daATodnVFBKXfyYT4jYUf1KEOUTRUkahwP5dmrVzNPSXIE=,iv:WlmqJnTvCPPx8AsBr5ilQdOPpLHAPflwGV/2ZGR65+g=,tag:FjPD7FFQrdkG5UO9uP81Og==,type:str]", - "pgp": null, + "lastmodified": "2026-05-22T15:00:03Z", + "mac": "ENC[AES256_GCM,data:A726LuYOgQaYVejrCAxQtjtIPV2BF1kNUwyaAvhZ+RLPGkqX9Bi5mwlrKayfWAWMR2gJrsr3pH5zy8KwIVrExtRGpWuA22SBfY/FyLPv62CceHEP6fnjhoA3qY2HpRxHeaWJ7DHLdzEE/3P0a3yHtOdyIchEMcfYqkkNcKNZnrk=,iv:+hvuK+/cTVY8UyPk7FvguQnf1R4vsnCQjOfu/TRVUmw=,tag:lBqBt/JPvvHKAwkauIEGrA==,type:str]", "unencrypted_suffix": "_unencrypted", - "version": "3.9.4" + "version": "3.12.1" } -} \ No newline at end of file +}