pare-feu Proxmox : un tenant retire sort du perimetre, ses objets aussi
Les IPSets et groupes t29- restaient poses : le perimetre ne retenait que les prefixes des tenants presents. Les etiquettes des zones retirees (ANCIEN_NOMMAGE du SDN) y entrent, pour etre retirees. Et un cluster muet arrete le plan au lieu de se lire vide. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
fde604c2a5
commit
badbcd3971
2 changed files with 38 additions and 4 deletions
|
|
@ -37,6 +37,12 @@ frères (`decouvrir()`), alors que la frontière et le SDN s'en tiennent à
|
|||
proposait donc de recréer ses groupes ; le poste comptait un dossier de CI comme tenant.
|
||||
Les deux devis suivent maintenant la même liste : 2 tenants, et non 3.
|
||||
|
||||
Filtré ainsi, le devis ne voyait plus du tout `t29` — ni à créer, ni à RETIRER : son
|
||||
périmètre ne retient que les préfixes des tenants présents. 3 IPSets et 6 groupes `t29-`
|
||||
restaient posés sur le cluster. `appliquer_proxmox_fw.py` ajoute à son périmètre les
|
||||
étiquettes des zones de `ANCIEN_NOMMAGE` (une liste, pas deux), et reçoit le même garde
|
||||
que le SDN contre un cluster muet.
|
||||
|
||||
Wiki republié (P60) : deux de ses pages nommaient patient 0. `make verifier` : 82 OK, 1 échec — P02,
|
||||
`test_ecriture_plan.py` sur `domaines.yml` (`'list' object has no attribute 'get'`),
|
||||
présent avant ce changement.
|
||||
|
|
|
|||
|
|
@ -83,8 +83,36 @@ def _regle_cle(r: dict) -> tuple:
|
|||
str(r.get("dport") or ""))
|
||||
|
||||
|
||||
def _prefixes_retires() -> tuple[str, ...]:
|
||||
"""Les etiquettes des tenants RETIRES : `t29-` pour la zone `t29`.
|
||||
|
||||
UN TENANT RETIRE SORT DU PERIMETRE, ET SES OBJETS AVEC (2026-09-28). Le perimetre ne
|
||||
retient que les prefixes du devis ; un index libere n'y est plus, donc ses IPSets et
|
||||
ses groupes n'existaient plus pour ce script — ni a creer, ni a retirer. Ils restaient
|
||||
poses. La liste n'est pas ecrite ici : c'est celle du SDN (`ANCIEN_NOMMAGE`), dont les
|
||||
zones `t<index>` portent la meme etiquette que les IPSets. Une liste, pas deux.
|
||||
"""
|
||||
import devis_sdn
|
||||
return tuple(f"{z}-" for z in devis_sdn.ANCIEN_NOMMAGE
|
||||
if z.startswith("t") and z[1:].isdigit())
|
||||
|
||||
|
||||
def _lire(api: Cluster, chemin: str):
|
||||
"""Une lecture du cluster, ou l'arret : un cluster muet n'est pas un cluster vide.
|
||||
|
||||
Meme defaut, meme correctif que `appliquer_sdn._lire` (2026-09-28) : `rep or []`
|
||||
parcourait le dict d'erreur comme une liste vide, et le plan proposait de tout creer.
|
||||
"""
|
||||
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
|
||||
|
||||
|
||||
def plan(api: Cluster, devis: dict) -> dict:
|
||||
prefixes = tuple(_prefixe(b) for b in devis["blocs"] if _prefixe(b))
|
||||
prefixes = tuple(_prefixe(b) for b in devis["blocs"] if _prefixe(b)) + _prefixes_retires()
|
||||
|
||||
ipsets_voulus, groupes_voulus, affect_voulues = {}, {}, {}
|
||||
for b in devis["blocs"]:
|
||||
|
|
@ -98,20 +126,20 @@ def plan(api: Cluster, devis: dict) -> dict:
|
|||
|
||||
# --- etat du cluster, restreint a nos prefixes -----------------------------
|
||||
ipsets_poses = {}
|
||||
for s in (api("/cluster/firewall/ipset") or []):
|
||||
for s in (_lire(api, "/cluster/firewall/ipset") or []):
|
||||
if isinstance(s, dict) and str(s.get("name", "")).startswith(prefixes):
|
||||
membres = [str(m.get("cidr")) for m in (api(f"/cluster/firewall/ipset/{s['name']}") or [])
|
||||
if isinstance(m, dict)]
|
||||
ipsets_poses[s["name"]] = sorted({_norm(m) for m in membres})
|
||||
|
||||
groupes_poses = {}
|
||||
for g in (api("/cluster/firewall/groups") or []):
|
||||
for g in (_lire(api, "/cluster/firewall/groups") or []):
|
||||
if isinstance(g, dict) and str(g.get("group", "")).startswith(prefixes):
|
||||
regles = [r for r in (api(f"/cluster/firewall/groups/{g['group']}") or [])
|
||||
if isinstance(r, dict)]
|
||||
groupes_poses[g["group"]] = regles
|
||||
|
||||
vm_du_cluster = {int(r["vmid"]): r["node"] for r in (api("/cluster/resources?type=vm") or [])
|
||||
vm_du_cluster = {int(r["vmid"]): r["node"] for r in (_lire(api, "/cluster/resources?type=vm") or [])
|
||||
if isinstance(r, dict) and r.get("vmid")}
|
||||
|
||||
affect_posees, vm_absentes = {}, []
|
||||
|
|
|
|||
Loading…
Reference in a new issue