diff --git a/docs/teilprojekte-archiv.md b/docs/teilprojekte-archiv.md index 75ca706..3c206a5 100644 --- a/docs/teilprojekte-archiv.md +++ b/docs/teilprojekte-archiv.md @@ -64,6 +64,7 @@ teuerste Eigenschaft der Datei zerstört, um ihr billigstes Problem zu lösen. B | [TP-R](#tp-r) | Router-Capabilities-Sweep | FERTIG (docs/research/routeros-capabilities.md) | | [TP39](#tp39) | LXC-Hygiene pve: Resolver-Altlasten, `networking.service`, DB-Reverse-Lookup | ✅ ABGESCHLOSSEN (2026-09-01) — pve+NAS-Sweep grün | | [TP34](#tp34) | Caddyfile via Nautobot/GC (generische Reverse-Proxy-Schnittstelle) | ❌ VERWORFEN (2026-09-08) — Caddyfile bleibt manuell | +| [TP44](#tp44) | Cloudflare-Estate als Dokumentations-SSoT in Nautobot | ✅ DURCH (2026-09-10) | Dazu am Ende: **[TP25 (Langfassung)](#tp25-lang)** — die Messchronik und die Funde A–E im Volltext. TP25 selbst ist **nicht** abgeschlossen und steht weiter in `teilprojekte.md`; nur seine 394 Zeilen @@ -1796,3 +1797,50 @@ gemessen hat. Beim Beheben kam eine zweite, unabhängige Altlast zum Vorschein. - **Abh.:** TP22 (GC-Pipeline) ✅ · TP23 (DNS/Caddy-Voraussetzungen) ✅ Stufe 1 · 🔴 **NEU 2026-09-06: TP37 Punkt 1+2** — Caddy rendert *Config aus Daten*, die Backend-Dienste müssen als `ipam.Service` in Nautobot existieren, sonst gibt es nichts zu rendern. **TP37 vor TP34.** - **Datenmodell (entschieden 2026-09-06):** native Modelle — Backend = `ipam.Service`, Proxy-Route = Relationship/CustomField Frontend↔Backend, GC-Job rendert den Caddyfile. Keine eigene App (konsistent zu TP44). - **Status:** 🔜 Stub; wartet auf TP37 P1+2. Quick-Win `terpene.teilzeitladen.xyz → 10.40.20.167:8890` als manueller Caddy-Block ist **Schritt 0** des Runbooks. Plan: [`handoff-20260906-tp37-34-36-plan.md`](handoff-20260906-tp37-34-36-plan.md). + +--- + + +### TP44 — Cloudflare-Estate als Dokumentations-SSoT in Nautobot ▸ ✅ **DURCH (2026-09-10): Etappe 1 + Etappe 2 (Teil A IPAM-Prefixe, Teil B Live-Sync als täglicher Nautobot-Job)** +> **Entscheid (User, 2026-09-02):** die volle CF-Estate (Tunnel + WARP-Connector + VPC-Service + +> Hyperdrive + Workers + alle Access-Apps) als strukturierte, abfragbare SSoT in Nautobot abbilden — +> **etappenweise: manuell jetzt, Sync später.** Nautobot kann CF nicht steuern → „SSoT" heißt +> **Dokumentations-SSoT; CF bleibt operativer Master.** Detail-Handoff: +> [`handoff-20260902-cf-estate-nautobot-ssot.md`](handoff-20260902-cf-estate-nautobot-ssot.md). + +- **Warum eigenes TP, nicht TP36:** TP36 ist eng auf `teilprojekte.md`-Live-Daten geschnitten; gleiche + Idee (Nautobot als Doku-SSoT), andere Dimension. TP44 = nächste freie Nummer nach TP43. +- **Modell (native `nautobot.cloud`, Nautobot 3.1.7 — keine eigene App):** `Manufacturer "Cloudflare"` → + `CloudAccount` (`393c051f…`) → `CloudResourceType ×6` → `CloudNetwork ×4` (`bf-public`/`fm`/`terpene-db`/ + `bf-core-mesh`) + `CloudService ×14`; Service↔Tunnel über das Through-Modell + `cloud-service-network-assignments` (3 Rows). IDs/Ports/Hostnames/Origins je Objekt in `extra_config`. +- **Werkzeug:** `nautobot/tp44-cf-estate-seed.py` — idempotenter Seeder (Re-Run = 26/26 „existiert"), + Datenstand inline (Live-CF-Inventur 2026-09-02). Token aus `docs/nas-vlan20/stacks/210-nautobot.yml`. +- ✅ **Verifikation 2026-09-06 (live gegen die API):** CloudAccount 1 · ResourceType 6 · CloudNetwork 4 · + CloudService 14 — unverändert seit 09-02. +- 🔴 **Gotchas:** `CloudService.cloud_networks` ist `read_only` (nur Through-Rows schreiben/lesen) · + VPC-Service-API unter `connectivity/directory/services` (PUT, voller Body) · **VPC-Objekte tragen ihren + Identifier in `service_id`, NICHT `id`** (kostete im Sync einen Fehl-Match) · ⚠️ **DRIFT-KORREKTUR + 2026-09-10:** die frühere Zeile „Repo-`CF_API_TOKEN` darf kein Workers-VPC → über den `cloudflare`-MCP" + war **falsch**. Live getestet liest der `CF_API_TOKEN` aus `~/.secrets/credentials.env` Hyperdrive **und** + VPC **und** Workers (alle 200). Der schmale Token ist `CF_DNS_API_TOKEN` (403). Der `cloudflare`-MCP ist + der **remote OAuth-MCP** (kein API-Token) und für einen serverseitigen Job ohnehin nicht nutzbar. +- ✅ **Etappe 2 Teil A (2026-09-08): IPAM-Prefixe live.** `10.40.0.0/16` (container, Route `bf-core-mesh`) + + `10.101.0.0/24` (network, Route `fm`) angelegt via `nautobot/tp44-ipam-prefixes.py`; der Seeder-Re-Run + hat die zwei `cloud-network-prefix-assignments` eingehängt (count=2, Idempotenz-Gegenprobe grün). +- ✅ **Etappe 2 Teil B (2026-09-10): Live-Sync als Nautobot-Job — DURCH.** Governance (User 2026-09-09): + periodische externe→Nautobot-Syncs leben als **Nautobot-Jobs** in `bf-infra/jobs/`, in Nautobot geplant — + **kein per-Task-Container/-Cron.** Runtime `jobs/cf_estate_sync.py` (`CFEstateSync`, ORM, read-only Pull, + 403-tolerant, Verwaisung = `extra_config.stale` statt Löschen). Token = Nautobot-Secret `cf-api-token` + (Provider env → `CF_API_TOKEN` am Worker, in `210-nautobot.yml` verdrahtet). **Schedule: täglich 03:00Z** + (`ScheduledJob "CF Estate Sync – taeglich"`). Verifiziert: Dry-Run + Commit-Run sauber, **4 Networks / + 14 Services, alle Endpoints lesbar, 0 Drift**. Der REST-Einmalproof `nautobot/tp44-cf-sync.py` bleibt als + workstation-seitiges Diagnose-Werkzeug liegen (nicht die kanonische Runtime). + - 🔴 **Drei load-bearing Funde (Detail-Handoff `handoff-20260910-tp44-teilb-sync-live.md`):** + (1) **Wurzel-`__init__.py` im Repo ist Pflicht** — Nautobot lädt Git-Repo-Jobs via + `pkgutil.walk_packages([GIT_ROOT])`, das Namespace-Packages (ohne `__init__.py`) NICHT entdeckt; ohne die + Datei bleibt `bf_infra.jobs` unsichtbar (Symptom: Sync SUCCESS + „No jobs were registered"). bf-infra ist + das erste Git-Repo mit `extras.job`. (2) `register_jobs()` gehört ins **Paket-`__init__`**, nicht nur ins + Submodul. (3) `Meta.has_sensitive_variables=False` nötig, sonst verweigert Nautobot das Scheduling. +- **Beziehung zu TP37:** TP44 hat **TP37 Punkt 3** (CF-Connectoren) vorweggenommen — dieselbe native-Modell- + Linie, die TP37 P1+2 (Substrat/Dienste) fortsetzt. diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index 18bbceb..c3a7cc1 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -2676,7 +2676,7 @@ Dauerläufer am dw. Cross-Projekt (teilzeitladen.xyz). Handoff: „wo läuft was" steht. 2. **Dienste abbilden** — `ipam.Service` je exponiertem Port (Caddy `:80/:443`, AdGuard `:53`, Nautobot `:8080`, n8n `:5678`, …). Das ist Nautobot-Kernmodell, **keine eigene App nötig**. - 3. ✅ **CF-Connectoren — ERLEDIGT via [TP44](#tp44) (Etappe 1, 2026-09-02).** Die Modellwahl ist damit + 3. ✅ **CF-Connectoren — ERLEDIGT via [TP44](teilprojekte-archiv.md#tp44) (Etappe 1, 2026-09-02).** Die Modellwahl ist damit entschieden: **native `nautobot.cloud`-Modelle** (Tunnel/WARP = `CloudNetwork`, VPC/Hyperdrive/Worker/ Access-App = `CloudService`, IDs/Ports/Origins in `extra_config`), **keine eigene App**. Offen nur noch TP44 Etappe 2 (CF-API→Nautobot-Sync). ⇒ **Punkt 1+2 unten sind der echte Rest von TP37.** @@ -2705,53 +2705,6 @@ Dauerläufer am dw. Cross-Projekt (teilzeitladen.xyz). Handoff: --- - -### TP44 — Cloudflare-Estate als Dokumentations-SSoT in Nautobot ▸ ✅ **DURCH (2026-09-10): Etappe 1 + Etappe 2 (Teil A IPAM-Prefixe, Teil B Live-Sync als täglicher Nautobot-Job)** -> **Entscheid (User, 2026-09-02):** die volle CF-Estate (Tunnel + WARP-Connector + VPC-Service + -> Hyperdrive + Workers + alle Access-Apps) als strukturierte, abfragbare SSoT in Nautobot abbilden — -> **etappenweise: manuell jetzt, Sync später.** Nautobot kann CF nicht steuern → „SSoT" heißt -> **Dokumentations-SSoT; CF bleibt operativer Master.** Detail-Handoff: -> [`handoff-20260902-cf-estate-nautobot-ssot.md`](handoff-20260902-cf-estate-nautobot-ssot.md). - -- **Warum eigenes TP, nicht TP36:** TP36 ist eng auf `teilprojekte.md`-Live-Daten geschnitten; gleiche - Idee (Nautobot als Doku-SSoT), andere Dimension. TP44 = nächste freie Nummer nach TP43. -- **Modell (native `nautobot.cloud`, Nautobot 3.1.7 — keine eigene App):** `Manufacturer "Cloudflare"` → - `CloudAccount` (`393c051f…`) → `CloudResourceType ×6` → `CloudNetwork ×4` (`bf-public`/`fm`/`terpene-db`/ - `bf-core-mesh`) + `CloudService ×14`; Service↔Tunnel über das Through-Modell - `cloud-service-network-assignments` (3 Rows). IDs/Ports/Hostnames/Origins je Objekt in `extra_config`. -- **Werkzeug:** `nautobot/tp44-cf-estate-seed.py` — idempotenter Seeder (Re-Run = 26/26 „existiert"), - Datenstand inline (Live-CF-Inventur 2026-09-02). Token aus `docs/nas-vlan20/stacks/210-nautobot.yml`. -- ✅ **Verifikation 2026-09-06 (live gegen die API):** CloudAccount 1 · ResourceType 6 · CloudNetwork 4 · - CloudService 14 — unverändert seit 09-02. -- 🔴 **Gotchas:** `CloudService.cloud_networks` ist `read_only` (nur Through-Rows schreiben/lesen) · - VPC-Service-API unter `connectivity/directory/services` (PUT, voller Body) · **VPC-Objekte tragen ihren - Identifier in `service_id`, NICHT `id`** (kostete im Sync einen Fehl-Match) · ⚠️ **DRIFT-KORREKTUR - 2026-09-10:** die frühere Zeile „Repo-`CF_API_TOKEN` darf kein Workers-VPC → über den `cloudflare`-MCP" - war **falsch**. Live getestet liest der `CF_API_TOKEN` aus `~/.secrets/credentials.env` Hyperdrive **und** - VPC **und** Workers (alle 200). Der schmale Token ist `CF_DNS_API_TOKEN` (403). Der `cloudflare`-MCP ist - der **remote OAuth-MCP** (kein API-Token) und für einen serverseitigen Job ohnehin nicht nutzbar. -- ✅ **Etappe 2 Teil A (2026-09-08): IPAM-Prefixe live.** `10.40.0.0/16` (container, Route `bf-core-mesh`) + - `10.101.0.0/24` (network, Route `fm`) angelegt via `nautobot/tp44-ipam-prefixes.py`; der Seeder-Re-Run - hat die zwei `cloud-network-prefix-assignments` eingehängt (count=2, Idempotenz-Gegenprobe grün). -- ✅ **Etappe 2 Teil B (2026-09-10): Live-Sync als Nautobot-Job — DURCH.** Governance (User 2026-09-09): - periodische externe→Nautobot-Syncs leben als **Nautobot-Jobs** in `bf-infra/jobs/`, in Nautobot geplant — - **kein per-Task-Container/-Cron.** Runtime `jobs/cf_estate_sync.py` (`CFEstateSync`, ORM, read-only Pull, - 403-tolerant, Verwaisung = `extra_config.stale` statt Löschen). Token = Nautobot-Secret `cf-api-token` - (Provider env → `CF_API_TOKEN` am Worker, in `210-nautobot.yml` verdrahtet). **Schedule: täglich 03:00Z** - (`ScheduledJob "CF Estate Sync – taeglich"`). Verifiziert: Dry-Run + Commit-Run sauber, **4 Networks / - 14 Services, alle Endpoints lesbar, 0 Drift**. Der REST-Einmalproof `nautobot/tp44-cf-sync.py` bleibt als - workstation-seitiges Diagnose-Werkzeug liegen (nicht die kanonische Runtime). - - 🔴 **Drei load-bearing Funde (Detail-Handoff `handoff-20260910-tp44-teilb-sync-live.md`):** - (1) **Wurzel-`__init__.py` im Repo ist Pflicht** — Nautobot lädt Git-Repo-Jobs via - `pkgutil.walk_packages([GIT_ROOT])`, das Namespace-Packages (ohne `__init__.py`) NICHT entdeckt; ohne die - Datei bleibt `bf_infra.jobs` unsichtbar (Symptom: Sync SUCCESS + „No jobs were registered"). bf-infra ist - das erste Git-Repo mit `extras.job`. (2) `register_jobs()` gehört ins **Paket-`__init__`**, nicht nur ins - Submodul. (3) `Meta.has_sensitive_variables=False` nötig, sonst verweigert Nautobot das Scheduling. -- **Beziehung zu TP37:** TP44 hat **TP37 Punkt 3** (CF-Connectoren) vorweggenommen — dieselbe native-Modell- - Linie, die TP37 P1+2 (Substrat/Dienste) fortsetzt. - ---- - ## Abgeschlossene Teilprojekte ▸ [`teilprojekte-archiv.md`](teilprojekte-archiv.md) **34 abgeschlossene TPs** liegen dort im Volltext, unverändert und mit eigenem Inhaltsverzeichnis. @@ -2768,7 +2721,7 @@ Kurzorientierung, wo was zu finden ist: | **Firewall / QoS** | [TP5](teilprojekte-archiv.md#tp5) deny-by-default · [TP26](teilprojekte-archiv.md#tp26) `ip-firewall-filter` unter Drift-Kontrolle · [TP6](teilprojekte-archiv.md#tp6) CAKE *(geschlossen statt gebaut)* · [TP6.1](teilprojekte-archiv.md#tp6-1) Upload-Priorisierung | | **Discovery / Media** | [TP7](teilprojekte-archiv.md#tp7) mDNS · [TP7.1](teilprojekte-archiv.md#tp7-1) SSDP-Relay · [TP7.2](teilprojekte-archiv.md#tp7-2) HA↔Sonos | | **Hosts / Migration** | [TP14](teilprojekte-archiv.md#tp14) (+[.1](teilprojekte-archiv.md#tp14-1)/[.2](teilprojekte-archiv.md#tp14-2)/[.2a](teilprojekte-archiv.md#tp14-2a)/[.3](teilprojekte-archiv.md#tp14-3)/[.5](teilprojekte-archiv.md#tp14-5)) VLAN20-Cutover · [TP17](teilprojekte-archiv.md#tp17) Shelly→VLAN30 · [TP19](teilprojekte-archiv.md#tp19) VLAN1-Retirement | -| **Control-Plane** | [TP20](teilprojekte-archiv.md#tp20) Platform-Postgres · [TP21](teilprojekte-archiv.md#tp21) Nautobot GC · [TP22](teilprojekte-archiv.md#tp22) Adoption + Compliance-Push · [TP27](teilprojekte-archiv.md#tp27) RouterBOOT 7.24 · [TP-R](teilprojekte-archiv.md#tp-r) Capabilities-Sweep | +| **Control-Plane** | [TP20](teilprojekte-archiv.md#tp20) Platform-Postgres · [TP21](teilprojekte-archiv.md#tp21) Nautobot GC · [TP22](teilprojekte-archiv.md#tp22) Adoption + Compliance-Push · [TP27](teilprojekte-archiv.md#tp27) RouterBOOT 7.24 · [TP-R](teilprojekte-archiv.md#tp-r) Capabilities-Sweep · [TP44](teilprojekte-archiv.md#tp44) CF-Estate Doku-SSoT | | **Zugang** | [TP10](teilprojekte-archiv.md#tp10) Multi-Site-VPN *(offen nur der DDNS-Updater, s. Follow-ups)* · [TP16.1](teilprojekte-archiv.md#tp16-1) natives CF-Mesh | | **Verworfen** | [TP9](teilprojekte-archiv.md#tp9) Gateway-HA (User-Entscheid 2026-08-08) |