From 0eae97c6ec70eedc99af87ef31c2d3457c692230 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Sun, 2 Aug 2026 17:05:12 -0400 Subject: [PATCH] =?UTF-8?q?underlay=20:=20mont=C3=A9=20par=20symlink=20dep?= =?UTF-8?q?uis=20le=20d=C3=A9p=C3=B4t=20de=20l'h=C3=A9bergeur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il vivait gitignoré à la racine du moteur : consommé par deux générateurs, validé par P23, versionné nulle part. La dizaine de modifications de la journée n'était récupérable d'aucune façon, et un clone frais repartait du gabarit. Il appartient à l'hébergeur — ses switches, ses câbles — pas au moteur, qui est générique, ni à un tenant, qui n'en possède pas. Chezlepro est ici hébergeur ET tenant, d'où la confusion initiale. Le moteur le monte par symlink comme il monte le plan par `instance/`. Ce lien NE SUIT PAS `make instance-utiliser` : la fabric reste celle de l'hébergeur quel que soit le tenant actif. Vérifié : les deux devis sortent identiques octet pour octet avant et après, P23 verte, 24 preuves. Symlink brisé (clone sans dépôt frère) : dégrade proprement, sections omises au lieu d'échouer. Cas exercé. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ scripts/inventory_gui.py | 7 ++++--- scripts/underlay.py | 16 +++++++++++++--- underlay.yml.example | 4 +++- wiki/Multi-instance-et-fédération.md | 6 ++++-- 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cc355d..b7b3ad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # CHANGELOG — Set-OPS +## 2026-08-02 (suite 5) — l'underlay rejoint le dépôt de l'hébergeur + +`underlay.yml` vivait **gitignoré** à la racine du moteur : consommé par deux générateurs, +validé par la preuve P23, et versionné nulle part. La dizaine de modifications de la journée +— transit, renumérotage du `/29`, séparation des fabrics, spanning-tree, dialecte, ports — +n'était récupérable d'aucune façon, et un clone frais repartait du gabarit. + +Il appartient à l'**hébergeur** : ce sont ses switches, ses câbles, ses VLAN. Pas au moteur, +qui est générique, ni à un tenant, qui n'en possède pas. Chezlepro est ici hébergeur *et* +tenant, d'où la confusion : un tenant qui s'hébergerait sur son propre matériel aurait son +propre underlay, dans son dépôt. + +Le moteur le monte par symlink, comme il monte le plan par `instance/` : + +``` +Set-OPS-public/underlay.yml -> ../OPS-Chezlepro/underlay.yml +``` + +**Ce lien ne suit pas `make instance-utiliser`.** Basculer l'instance active sur un autre +tenant ne change pas la fabric : elle reste celle de l'hébergeur. Deux symlinks, deux durées +de vie — c'est la conséquence directe de la distinction hébergeur/tenant. + +Vérifié : les deux devis sortent **identiques octet pour octet** avant et après, P23 reste +verte, 24 preuves. Et un symlink **brisé** — le cas d'un clone du moteur sans le dépôt de +l'hébergeur — dégrade proprement : `exists()` suit le lien, l'underlay est vu comme absent, +et les devis omettent leurs sections au lieu d'échouer. Cas exercé. + ## 2026-08-02 (suite 4) — deux devis qui se contredisaient, et une case à cocher ### Corrigé — le devis frontière certifiait des routes inexistantes diff --git a/scripts/inventory_gui.py b/scripts/inventory_gui.py index 819e912..6973ad2 100644 --- a/scripts/inventory_gui.py +++ b/scripts/inventory_gui.py @@ -88,9 +88,10 @@ INTRANTS_PROXMOX = INVENTAIRE_MODELE.parent / "group_vars/proxmox.yml" # Frontiere nord/sud (OPNsense) : parametres NON sensibles du pare-feu de bordure. # La cle/secret d'API n'y entrent JAMAIS — voute uniquement (cf. INTRANTS_CLES_INTERDITES). INTRANTS_FRONTIERE = INVENTAIRE_DEFAUT.parent / "group_vars/opnsense.yml" -# Fabric physique : `underlay.yml` a la RACINE du moteur (pas dans l'instance) — il est -# cluster-global. Imbrique sous `underlay:` et riche en commentaires : on l'ecrit -# chirurgicalement, jamais par un safe_dump qui les effacerait. +# Fabric physique : `underlay.yml`, monte par symlink a la racine du moteur depuis le +# depot de l'HEBERGEUR (ses switches, ses cables). Distinct de l'instance : il ne suit +# pas `make instance-utiliser`. Imbrique sous `underlay:` et riche en commentaires : +# on l'ecrit chirurgicalement, jamais par un safe_dump qui les effacerait. FICHIER_UNDERLAY = Path(os.environ.get("SETOPS_UNDERLAY") or (RACINE / "underlay.yml")) FICHIERS_INTRANTS = {"identite": INTRANTS_IDENTITE, "proxmox": INTRANTS_PROXMOX, "reseau": FICHIER_NOMENCLATURE, "frontiere": INTRANTS_FRONTIERE, diff --git a/scripts/underlay.py b/scripts/underlay.py index be1b66a..31f39a9 100644 --- a/scripts/underlay.py +++ b/scripts/underlay.py @@ -9,8 +9,14 @@ aucun tenant. Convention : VLAN < 1000, franchement SOUS la plage tenant (VLAN = 1000+index*10+zone). Les sous-reseaux ne doivent chevaucher aucun supernet tenant (10.(10+index).0.0/16). -Fichier : `underlay.yml` a la racine du moteur (gitignore ; voir `underlay.yml.example`), -surchargeable par `SETOPS_UNDERLAY`. Absent => le devis omet simplement la section underlay. +EMPLACEMENT : l'underlay appartient a l'HEBERGEUR — ses switches, ses cables. Il vit +donc dans SON depot, et le moteur le monte par symlink : + + Set-OPS-public/underlay.yml -> ../OPS-/underlay.yml + +Ce symlink NE SUIT PAS `make instance-utiliser` : la fabric reste celle de l'hebergeur, +quel que soit le tenant actif. Surchargeable par `SETOPS_UNDERLAY`. Absent (ou lien +brise, cas d'un clone sans depot frere) => le devis omet simplement la section. CLI : `python3 scripts/underlay.py` (affiche + valide), `--verifier` (P23, code de sortie). """ @@ -32,7 +38,11 @@ SEUIL_VLAN_TENANT = 1000 def chemin() -> Path | None: - """Emplacement du underlay.yml : SETOPS_UNDERLAY, sinon racine du moteur. None si absent.""" + """Emplacement du underlay.yml : SETOPS_UNDERLAY, sinon le symlink a la racine. + + `exists()` suit le lien : un symlink brise (clone sans le depot de l'hebergeur) + rend None, et tout degrade proprement au lieu d'echouer. + """ env = os.environ.get("SETOPS_UNDERLAY") if env: p = Path(env).expanduser() diff --git a/underlay.yml.example b/underlay.yml.example index 9ce728e..d68c34d 100644 --- a/underlay.yml.example +++ b/underlay.yml.example @@ -3,7 +3,9 @@ # Cluster-global : ces reseaux portent TOUTE la flotte, ils n'appartiennent a aucun # tenant et ne derivent d'aucun `index`. Ils vivent dans le *sous-sol* du modele. # -# Copier vers `underlay.yml` (a la racine du moteur ; gitignore) et adapter a ta fabric. +# Copier dans le depot de l'HEBERGEUR (celui qui possede les switches), puis le monter : +# ln -s ../OPS-/underlay.yml underlay.yml +# Le moteur l'ignore (gitignore) : c'est une donnee de site, versionnee chez son proprietaire. # Surchargeable par SETOPS_UNDERLAY=/chemin/underlay.yml. Absent => le devis switch # omet simplement la section underlay (retro-compatible). # diff --git a/wiki/Multi-instance-et-fédération.md b/wiki/Multi-instance-et-fédération.md index 0e0b1e4..2ac9a5c 100644 --- a/wiki/Multi-instance-et-fédération.md +++ b/wiki/Multi-instance-et-fédération.md @@ -63,8 +63,10 @@ lecture seule) suit l'environnement. **Le dépôt public reste générique** (`c **L'underlay — le sous-sol.** Les VLAN tenant (`1000+index×10+zone`) sont les *overlays*. En dessous vit la **fabric physique** partagée par toute la flotte : management des switches et de Proxmox/OOB, iSCSI, Ceph (public + cluster). Elle **n'appartient à aucun tenant** et ne dérive -d'aucun `index`. On la décrit dans `underlay.yml` (racine du moteur, gitignore comme le vault ; -gabarit `underlay.yml.example`) : +d'aucun `index`. On la décrit dans `underlay.yml`, qui vit dans le dépôt de **l'hébergeur** +(ses switches, ses câbles) et que le moteur monte par symlink à sa racine — comme il monte le +plan par `instance/`. Ce lien ne suit pas `make instance-utiliser` : la fabric reste celle de +l'hébergeur, quel que soit le tenant actif. Gabarit : `underlay.yml.example`. | Underlay | VLAN | Sous-réseau | |---|---|---|