From 6a7188290f30ee8fbe0c78ee707507c54bed3339 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Mon, 28 Sep 2026 09:34:20 -0400 Subject: [PATCH] sdn : un cluster muet n est pas un cluster vide, et t29 se retire MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le poste coupe du site, sdn-plan annoncait a creer : 33 — toutes les zones, Chezlepro comprise. Une lecture en echec rendait un dict d erreur, que rep or [] parcourait comme une liste vide. La lecture s arrete maintenant, comme la frontiere. t29 rejoint l ancien nommage : sortie du devis sans cela, la zone aurait ete lue comme etrangere et laissee en place, avec ses VLAN 1291-1296. Co-Authored-By: Claude Opus 5.5 --- scripts/appliquer_sdn.py | 23 ++++++++++++++++++++--- scripts/devis_sdn.py | 11 ++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/scripts/appliquer_sdn.py b/scripts/appliquer_sdn.py index dfc73a0..44f5646 100644 --- a/scripts/appliquer_sdn.py +++ b/scripts/appliquer_sdn.py @@ -66,13 +66,30 @@ def _vm_par_vnet(api: Cluster) -> dict[str, list[str]]: return dedans +def _lire(api: Cluster, chemin: str) -> list: + """Une LISTE du cluster, ou l'arret — jamais une liste vide a la place d'une erreur. + + UN CLUSTER MUET N'EST PAS UN CLUSTER VIDE (2026-09-27). `Cluster` rend + `{'_erreur': ...}` au lieu de lever ; `rep or []` iterait alors sur les CLES de ce + dict, que le filtre `isinstance(dict)` ecartait en silence. Poste coupe du site, le + plan annoncait « a creer : 33 » — toutes les zones, celles qui existent comprises. + `frontiere-plan` refusait deja de conclure dans ce cas ; celui-ci le fait aussi. + """ + rep = api(chemin) + if api.rate(rep): + raise SystemExit(f"Le cluster {api.hote} ne repond pas sur `{chemin}` : " + f"{api.rate(rep)}\n (un cluster injoignable serait lu comme un " + f"cluster VIDE, et le plan proposerait de tout recreer)") + return rep or [] + + def plan(api: Cluster, devis: dict) -> dict: zones_voulues = {b["zone"]: b for b in devis["zones"]} connues = set(zones_voulues) | set(devis.get("anciennes") or []) - zones_posees = {z["zone"]: z for z in (api("/cluster/sdn/zones") or []) + zones_posees = {z["zone"]: z for z in _lire(api, "/cluster/sdn/zones") if isinstance(z, dict)} - vnets_poses = {v["vnet"]: v for v in (api("/cluster/sdn/vnets") or []) + vnets_poses = {v["vnet"]: v for v in _lire(api, "/cluster/sdn/vnets") if isinstance(v, dict)} vnets_voulus = {v["vnet"]: (b["zone"], v) @@ -83,7 +100,7 @@ def plan(api: Cluster, devis: dict) -> dict: for nom, v in vnets_poses.items(): if v.get("zone") not in connues: continue - for s in (api(f"/cluster/sdn/vnets/{nom}/subnets") or []): + for s in _lire(api, f"/cluster/sdn/vnets/{nom}/subnets"): if isinstance(s, dict): sr_poses[(nom, s.get("cidr"))] = s sr_voulus = {(v["vnet"], v["sous_reseau"]): (b["zone"], v) diff --git a/scripts/devis_sdn.py b/scripts/devis_sdn.py index 02b2f43..95a023a 100644 --- a/scripts/devis_sdn.py +++ b/scripts/devis_sdn.py @@ -75,7 +75,9 @@ LONGUEUR_MAX_ID = 8 MARQUEUR_SORTIE = "" # Nommages precedents, a retirer : VRF00xx (cree a la main) puis CHEZ17/TECH11 # (premiere derivation, remplacee — les chiffres de zone n'etaient pas lisibles). -ANCIEN_NOMMAGE = ("VRF0011", "VRF0017", "CHEZ17", "TECH11") +# `t29` : l'index 29, libere le 2026-09-27. Sortie du devis sans passer ici, la zone +# serait lue comme ETRANGERE — laissee intacte, et ses VLAN avec elle. +ANCIEN_NOMMAGE = ("VRF0011", "VRF0017", "CHEZ17", "TECH11", "t29") def zone_de(index: int) -> str: @@ -276,11 +278,10 @@ def rendre(devis: dict) -> str: ] if devis.get("anciennes"): out += [ - "## 0. Retirer l'ancien nommage (fait a la main, remplace)", + "## 0. Retirer les zones qui ne servent plus (ancien nommage, index liberes)", "#", - "# Ces zones ne portent AUCUN VNet : les supprimer ne debranche rien. C'est", - "# precisement pourquoi on renomme maintenant — avec des VM attachees, ce", - "# serait une migration. Verifier l'absence de VNet avant de supprimer :", + "# `make sdn-appliquer` les retire, VNets et sous-reseaux compris, et REFUSE", + "# un VNet ou une VM est encore branchee. A la main, verifier d'abord :", "# pvesh get /cluster/sdn/vnets --output-format json", ] for z in devis["anciennes"]: