pare-feu Proxmox : l'affectation variait selon l'état du tenant

Elle partait de `hotes_actifs` avec un repli sur « tous » quand il n'y en
avait aucun. Technolibre listait donc ses 14 VM (zéro actif, repli déclenché)
et Chezlepro une seule (un actif) — un opérateur aurait lu qu'une seule VM
avait besoin de règles.

Les IPSets et les groupes incluaient déjà les hôtes planifiés,
délibérément : un pare-feu se prépare avant que la VM existe. L'affectation
suit la même règle. 14 de chaque côté, toutes avec leur VMID.

Preuves : 25 OK, 0 échec.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-08-03 11:47:13 -04:00
parent fd62b59989
commit 6de44736ff
2 changed files with 14 additions and 2 deletions

View file

@ -24,6 +24,16 @@ Le préfixe porte maintenant l'**index** (`t17-`) plutôt que l'étiquette (`che
rend la troncature bien plus rare, et une garde **échoue** sur toute collision plutôt que
d'émettre un devis pareil. Exercée.
### Corrigé — l'affectation variait selon l'état du tenant
Elle partait de `hotes_actifs`, avec un repli sur « tous » quand il n'y en avait aucun. Deux
tenants donnaient donc deux comportements : Technolibre listait ses 14 VM (zéro actif → repli),
Chezlepro **une seule** (un actif). Un opérateur aurait lu qu'une seule VM avait besoin de
règles.
Les IPSets et les groupes incluaient déjà les hôtes **planifiés**, délibérément — un pare-feu
se prépare avant que la VM existe. L'affectation suit désormais la même règle : 14 de chaque
côté, toutes avec leur VMID.
### Conséquence à retenir
Puisque **tout** ce qui entre dans un tenant passe par la frontière, le contrôleur Ansible
aussi. **L'OPNsense devient un prérequis de déploiement**, pas une étape parmi d'autres :

View file

@ -151,8 +151,10 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict:
# Affectation : quelle VM recoit quels groupes.
affect: list[dict] = []
par_nom_groupe = {g["role"]: g["nom"] for g in groupes}
for hote in sorted(_hotes_du_groupe(data, "hotes_actifs")
or [h for h in ips]):
# TOUS les hotes du plan, actifs comme planifies — meme regle que les IPSets.
# Se limiter aux actifs donnait un devis different selon l'etat du tenant : un
# operateur aurait lu qu'une seule VM avait besoin de regles.
for hote in sorted(ips):
vmid = None
for g, membres in _enfants(data).items():
h = (membres.get("hosts") or {}).get(hote) or {}