devis switch : syntaxe des routes vérifiée sur le matériel Binardat

Un `show running-config` du commutateur tranche la question restée ouverte :
la plateforme écrit ses routes en notation CIDR — `ip route 0.0.0.0/0
192.168.10.254` — et non en masque séparé comme Cisco. Le générateur
produisait du Cisco quel que soit le dialecte.

`route_statique()` suit maintenant le dialecte, comme les masques d'ACL.
Vérifié dans les deux formes.

Restent non vérifiés faute d'apparaître dans la config réelle : la syntaxe
des ACL, celle de `switchport trunk allowed vlan add`, et le spanning-tree —
totalement absent du `show running-config`, ce qui suggère qu'il est
désactivé par défaut sur cette plateforme.

Preuves : 24 OK, 0 échec.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-08-02 18:03:37 -04:00
parent 0a1a46c009
commit 24959359e2
3 changed files with 37 additions and 10 deletions

View file

@ -1,5 +1,18 @@
# CHANGELOG — Set-OPS
## 2026-08-02 (suite 12) — la syntaxe des routes, vérifiée sur le matériel
Un `show running-config` du commutateur Binardat tranche la question restée ouverte : la
plateforme écrit ses routes en **notation CIDR**`ip route 0.0.0.0/0 192.168.10.254` — et
non en masque séparé comme Cisco. Le générateur produisait du Cisco quel que soit le dialecte.
`route_statique()` suit désormais le dialecte, au même titre que les masques d'ACL. Vérifié
dans les deux formes.
Restent non vérifiés faute d'apparaître dans la configuration réelle : la syntaxe des ACL,
celle de `switchport trunk allowed vlan add`, et le **spanning-tree** — totalement absent du
`show running-config`, ce qui suggère qu'il est désactivé par défaut sur cette plateforme.
## 2026-08-02 (suite 11) — le responsable prend sa section, et la symétrie est dite
### Corrigé — un renvoi ambigu

View file

@ -292,10 +292,12 @@ ansible-vault edit instance/inventories/principal/group_vars/all/vault.yml
interdit en bloc aux tenants. Si un besoin légitime apparaît (superviser l'hyperviseur
depuis `obs-01`, par exemple), il ne peut pas être *déclaré* : il faudrait ajouter un pair
`underlay` au registre plutôt qu'une exception manuelle dans l'ACL.
- **La syntaxe des routes n'est pas dialecte-consciente** — les ACL le sont (masque normal
en `binardat`, wildcard en `cisco`), les `ip route` de la section 5 sortent en forme Cisco
quel que soit le dialecte. Même réserve pour les lignes de spanning-tree, dont la forme
`binardat` n'a pas été confrontée au matériel. À vérifier sur un `show running-config`.
- ~~La syntaxe des routes~~**réglé le 2026-08-02**, confronté à un `show running-config`
Binardat : la plateforme écrit `ip route 0.0.0.0/0 <saut>` en notation CIDR. Le générateur
suit le dialecte.
- **Restent non vérifiés sur Binardat** : la syntaxe des ACL (`ip access-list extended`), celle
de `switchport trunk allowed vlan add`, et le **spanning-tree** — totalement absent du
`show running-config`, ce qui suggère qu'il est désactivé par défaut sur cette plateforme.
- **Les ports physiques restent à nommer**`<PORT-VERS-PROXMOX>`, `<PORT-VERS-FRONTIERE>`
et `<PORT-TRUNK>` ; rien dans le modèle ne peut les deviner.
- ~~**La sortie générale** n'est pas déclarée~~**réglé le 2026-08-02.** Elle est

View file

@ -344,7 +344,20 @@ def admin_tous_tenants() -> list[str]:
return sorted({c for nom, _pfx, _n in decouvrir() for c in admin_de(nom)})
def section_routes(underlay: dict | None) -> list[str]:
def route_statique(reseau: str, saut: str, dialecte: str) -> str:
"""Une route statique, dans la forme du dialecte.
VERIFIE sur un `show running-config` Binardat (2026-08-02) : la plateforme ecrit
`ip route 0.0.0.0/0 192.168.10.254` notation CIDR, pas de masque separe. Cisco IOS
veut `ip route <reseau> <masque> <saut>`.
"""
net = ipaddress.ip_network(reseau, strict=False)
if dialecte == "binardat":
return f"ip route {net.with_prefixlen} {saut}"
return f"ip route {net.network_address} {net.netmask} {saut}"
def section_routes(underlay: dict | None, dialecte: str = DIALECTE_SECOURS) -> list[str]:
"""Routes du switch vers la frontiere nord/sud. Vide si aucun transit declare.
Deux routes, et il en faut IMPERATIVEMENT deux :
@ -377,15 +390,14 @@ def section_routes(underlay: dict | None) -> list[str]:
f"! Transit '{transit['nom']}' (VLAN {transit['vlan']}) : SVI {transit['passerelle']}"
f" <-> frontiere {sortie}",
"! Aller : sortie generale de la flotte.",
f"ip route 0.0.0.0 0.0.0.0 {sortie}"]
route_statique("0.0.0.0/0", sortie, dialecte)]
admin = admin_tous_tenants() or _sources_admin_ssh()
if admin:
out.append("! Retour : sans ces routes, les reponses partent par une autre interface")
out.append("! que celle ou l'etat a ete cree, et le pare-feu les jette en silence.")
for cidr in admin:
net = ipaddress.ip_network(cidr, strict=False)
out.append(f"ip route {net.network_address} {net.netmask} {sortie}"
f" ! administration (intrant nftables_admin_ssh)")
out.append(route_statique(cidr, sortie, dialecte)
+ " ! administration (intrant nftables_admin_ssh)")
else:
out.append("! ATTENTION : intrant `nftables_admin_ssh` vide — aucune route de retour")
out.append("! vers l'administration ne peut etre derivee. Cf. preuve P24.")
@ -512,7 +524,7 @@ def generer(tenants: list[tuple[str, str, dict]], dialecte: str | None = None) -
ports=ports_ou_marqueur(hote_nomme(underlay, underlay_mod.routeur(underlay)),
"frontiere", "<PORT-VERS-FRONTIERE>"))
out += ["!"] + section_rayons(underlay, ",".join(vlans_underlay + vlans_tenants))
out += ["!"] + section_routes(underlay)
out += ["!"] + section_routes(underlay, dialecte)
out += section_stp(underlay, dialecte)
out += ["end", "write memory"]
# Les switches d'acces : memes VLANs, aucun SVI de zone, aucune ACL, aucune route.