From b613873c3a1d06bd50ad4c7bab847e1ea23e2eaf Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Sat, 1 Aug 2026 20:18:16 -0400 Subject: [PATCH] =?UTF-8?q?nommage=20:=20bifrost=20aux=20fronti=C3=A8res,?= =?UTF-8?q?=20sleipnir=20=C3=A0=20la=20fabric=20interne?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `bifrost-0` et `bifrost-1` sont réservés aux deux frontières OPNsense — Bifröst est le pont vers l'extérieur. Les switches internes deviennent `sleipnir-01..03` : le cheval qui traverse les mondes, pas le pont qui en sort. La division du nom suit celle de l'architecture. Les deux boîtiers sont déclarés comme hôtes du lien de transit (10.0.4.2, 10.0.4.3) : hors flotte Ansible, la déclaration documente le lien et réserve les noms. Le /29 choisi plus tôt les loge tous les deux. Conséquence traitée : la partie B du devis aurait listé les deux pare-feux parmi les « switches d'accès ». Elle ne retient plus que les hôtes du réseau de management — un équipement déclaré ailleurs ne reçoit aucune ligne de configuration de switch. Le devis frontière nomme le boîtier quand il est déclaré. Preuves : 24 OK, 0 échec. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 16 ++++++++++++++++ docs/frontiere-opnsense.md | 7 +++++++ scripts/devis_opnsense.py | 16 +++++++++++++++- scripts/devis_reseau.py | 6 +++++- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d88a07d..ca5ca08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # CHANGELOG — Set-OPS +## 2026-08-01 (suite 6) — nommage : `bifrost` aux frontières, `sleipnir` à la fabric + +`bifrost-0` et `bifrost-1` sont réservés aux deux frontières OPNsense — Bifröst est le pont +vers l'extérieur. Les switches internes deviennent `sleipnir-01…03` : le cheval qui traverse +les mondes, pas le pont qui en sort. La division du nom suit celle de l'architecture. + +Les deux boîtiers sont déclarés comme hôtes du lien de transit (`10.0.4.2`, `10.0.4.3`) : +hors flotte Ansible, la déclaration documente le lien et réserve les noms. Le `/29` choisi +plus tôt les loge tous les deux, comme prévu. + +Conséquence à traiter : la partie B du devis switch aurait listé les deux pare-feux parmi les +« switches d'accès ». Elle ne retient désormais que les hôtes du **réseau de management** — +un équipement déclaré ailleurs ne reçoit aucune ligne de configuration de switch. + +Le devis frontière nomme le boîtier quand il est déclaré : `frontiere 10.0.4.2 (bifrost-0)`. + ## 2026-08-01 (suite 5) — deux incohérences du devis switch ### Corrigé — le routeur avait deux adresses de gestion contradictoires diff --git a/docs/frontiere-opnsense.md b/docs/frontiere-opnsense.md index b3223d5..389313c 100644 --- a/docs/frontiere-opnsense.md +++ b/docs/frontiere-opnsense.md @@ -88,6 +88,13 @@ sur ce lien : passerelle_sortie: 10.0.4.2 # la frontière = sortie par défaut de la flotte ``` +**Nommage.** `bifrost-0` et `bifrost-1` désignent les deux frontières — Bifröst est le pont +vers l'extérieur. La fabric interne porte un autre nom, `sleipnir-01…03` : le cheval qui +traverse les mondes, pas le pont qui en sort. Les deux boîtiers sont déclarés comme hôtes du +lien de transit ; ils sont **hors flotte Ansible**, la déclaration ne sert qu'à documenter le +lien et à réserver les noms. Le devis switch ne leur adresse aucune ligne — sa partie B ne +retient que les hôtes du réseau de management. + Un `/29` plutôt qu'un `/30` : pendant une transition, deux pare-feux cohabitent sur le lien, et un `/30` n'offre que deux adresses. `make underlay` (**preuve P23**) refuse une sortie hors du lien, confondue avec le SVI, sans SVI, ou déclarée deux fois. diff --git a/scripts/devis_opnsense.py b/scripts/devis_opnsense.py index 3faf3fb..cd0b5f3 100644 --- a/scripts/devis_opnsense.py +++ b/scripts/devis_opnsense.py @@ -79,6 +79,17 @@ def transit_underlay() -> dict | None: return underlay_mod.reseau_transit(underlay_mod.charger()) +def nom_frontiere(transit: dict | None) -> str: + """Nom du boitier de bordure, s'il est declare comme hote sur le lien de transit.""" + if not transit: + return "" + sortie = str(transit.get("passerelle_sortie") or "") + for h in underlay_mod.hotes(underlay_mod.charger()): + if h.get("reseau") == transit.get("nom") and str(h.get("ip")) == sortie: + return str(h.get("nom") or "") + return "" + + def prochain_saut(transit: dict | None) -> str: """Prochain saut des routes tenants = le SVI du switch sur le lien de transit. @@ -224,6 +235,7 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict: "sous_reseau": (transit or {}).get("sous_reseau"), "svi_switch": saut, "adresse_frontiere": (transit or {}).get("passerelle_sortie"), + "nom_frontiere": nom_frontiere(transit), } if transit else None, "reciproque_switch": [ f"ip route {cidr} -> {saut} (retour vers l'administration)" @@ -263,7 +275,9 @@ def rendre(devis: dict) -> str: if tr: out += [ f"# lien '{tr['nom']}' {tr['sous_reseau']} — VLAN {tr['vlan']} a etiqueter", - f"# switch {tr['svi_switch']} <-> frontiere {tr['adresse_frontiere']}", + f"# switch {tr['svi_switch']} <-> frontiere" + f" {tr['adresse_frontiere']}" + + (f" ({tr['nom_frontiere']})" if tr.get("nom_frontiere") else ""), ] out += [ "", diff --git a/scripts/devis_reseau.py b/scripts/devis_reseau.py index 928fdfe..f60b1e8 100644 --- a/scripts/devis_reseau.py +++ b/scripts/devis_reseau.py @@ -93,7 +93,11 @@ def partie_acces(underlay: dict | None, tenants: list, vlans: str) -> list[str]: if not r_nom: return [] mgmt = next((r for r in underlay_mod.reseaux(underlay) if r.get("passerelle")), None) - autres = [h for h in underlay_mod.hotes(underlay) if h.get("nom") != r_nom] + # UNIQUEMENT les hotes du reseau de management : les autres equipements declares + # (frontieres sur le lien de transit, par exemple) ne sont pas des switches et ne + # doivent recevoir aucune de ces lignes. + autres = [h for h in underlay_mod.hotes(underlay) + if h.get("nom") != r_nom and mgmt and h.get("reseau") == mgmt["nom"]] if not autres: return [] out = [