pare-feu Proxmox : un seul schéma de nommage
Les IPSets portaient l'étiquette longue (`chez17_serveur_postgresql`), les groupes l'index court (`t17-srv-postgresql`) : deux conventions dans un même document. Tout porte maintenant `t<index>-` et la même forme abrégée. La troncature reste propre à chaque objet — Proxmox est large sur les IPSets, étroit sur les groupes. Un nom peut être entier d'un côté et abrégé de l'autre ; chacun respecte sa contrainte, le préfixe reste commun. Vérifié : aucune collision d'IPSet, et tout renvoi `+X` d'une règle pointe vers un IPSet existant — 58 IPSets, 34 groupes, aucun orphelin. Preuves : 25 OK, 0 échec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
6de44736ff
commit
ece250ae49
2 changed files with 32 additions and 9 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -24,6 +24,18 @@ 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
|
rend la troncature bien plus rare, et une garde **échoue** sur toute collision plutôt que
|
||||||
d'émettre un devis pareil. Exercée.
|
d'émettre un devis pareil. Exercée.
|
||||||
|
|
||||||
|
### Unifié — un seul schéma de nommage dans le devis
|
||||||
|
Les IPSets portaient l'étiquette longue (`chez17_serveur_postgresql`), les groupes l'index
|
||||||
|
court (`t17-srv-postgresql`) : deux conventions à lire dans un même document. Tout porte
|
||||||
|
désormais le préfixe `t<index>-` et la même forme abrégée de rôle.
|
||||||
|
|
||||||
|
La troncature reste **propre à chaque objet** : Proxmox est large sur les IPSets, étroit
|
||||||
|
(18 caractères) sur les groupes. Un nom peut donc être entier d'un côté et abrégé de l'autre —
|
||||||
|
chacun respecte sa contrainte, et le préfixe reste commun.
|
||||||
|
|
||||||
|
Vérifié : aucune collision d'IPSet, et **tout renvoi `+X` d'une règle pointe vers un IPSet qui
|
||||||
|
existe** — 58 IPSets, 34 groupes, aucun orphelin.
|
||||||
|
|
||||||
### Corrigé — l'affectation variait selon l'état du tenant
|
### 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
|
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),
|
tenants donnaient donc deux comportements : Technolibre listait ses 14 VM (zéro actif → repli),
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,25 @@ from resoudre_flux import ( # noqa: E402
|
||||||
from devis_reseau import admin_de, decouvrir, inventaire_de, prefixe # noqa: E402
|
from devis_reseau import admin_de, decouvrir, inventaire_de, prefixe # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
def nom_ipset(role: str, etiquette: str) -> str:
|
|
||||||
return f"{etiquette}_{role}".lower()
|
|
||||||
|
|
||||||
|
|
||||||
LONGUEUR_MAX_GROUPE = 18 # limite de Proxmox pour un nom de groupe de securite
|
LONGUEUR_MAX_GROUPE = 18 # limite de Proxmox pour un nom de groupe de securite
|
||||||
|
|
||||||
|
|
||||||
|
def _role_court(role: str) -> str:
|
||||||
|
"""Forme abregee d'un role, commune aux IPSets et aux groupes."""
|
||||||
|
return role.replace("serveur_", "srv-").replace("client_", "cli-").replace("_", "-")
|
||||||
|
|
||||||
|
|
||||||
|
def nom_ipset(role: str, index: int) -> str:
|
||||||
|
"""Nom d'IPSet. MEME prefixe que les groupes — `t17-` — pour qu'un seul schema de
|
||||||
|
nommage se lise dans tout le devis.
|
||||||
|
|
||||||
|
Pas de troncature ici : Proxmox est large sur les IPSets, etroit sur les groupes.
|
||||||
|
Un nom peut donc etre entier cote IPSet et abrege cote groupe ; chacun respecte sa
|
||||||
|
contrainte, et le prefixe reste commun.
|
||||||
|
"""
|
||||||
|
return f"t{index}-{_role_court(role)}".lower()
|
||||||
|
|
||||||
|
|
||||||
def nom_groupe(role: str, index: int) -> str:
|
def nom_groupe(role: str, index: int) -> str:
|
||||||
"""Nom de groupe de securite, sous la limite de 18 caracteres de Proxmox.
|
"""Nom de groupe de securite, sous la limite de 18 caracteres de Proxmox.
|
||||||
|
|
||||||
|
|
@ -58,8 +70,7 @@ def nom_groupe(role: str, index: int) -> str:
|
||||||
`chez17-`, ce qui laisse trois caracteres de plus au role et rend la troncature
|
`chez17-`, ce qui laisse trois caracteres de plus au role et rend la troncature
|
||||||
beaucoup plus rare. Les groupes sont a l'echelle du datacenter, d'ou le prefixe.
|
beaucoup plus rare. Les groupes sont a l'echelle du datacenter, d'ou le prefixe.
|
||||||
"""
|
"""
|
||||||
court = role.replace("serveur_", "srv-").replace("client_", "cli-").replace("_", "-")
|
return f"t{index}-{_role_court(role)}".lower()[:LONGUEUR_MAX_GROUPE]
|
||||||
return f"t{index}-{court}".lower()[:LONGUEUR_MAX_GROUPE]
|
|
||||||
|
|
||||||
|
|
||||||
def _verifier_unicite(noms: list[str], tenant: str) -> None:
|
def _verifier_unicite(noms: list[str], tenant: str) -> None:
|
||||||
|
|
@ -106,7 +117,7 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict:
|
||||||
continue
|
continue
|
||||||
membres = sorted({ips[h] for h in _hotes_du_groupe(data, groupe) if h in ips})
|
membres = sorted({ips[h] for h in _hotes_du_groupe(data, groupe) if h in ips})
|
||||||
if membres:
|
if membres:
|
||||||
ipsets[nom_ipset(groupe, etiquette)] = {
|
ipsets[nom_ipset(groupe, n["index"])] = {
|
||||||
"role": groupe, "membres": membres,
|
"role": groupe, "membres": membres,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,8 +142,8 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict:
|
||||||
sans_source.append(f"{groupe}:{','.join(_ports(fl))}")
|
sans_source.append(f"{groupe}:{','.join(_ports(fl))}")
|
||||||
continue
|
continue
|
||||||
# Source par IPSet quand le pair est UN role : une seule liste a tenir.
|
# Source par IPSet quand le pair est UN role : une seule liste a tenir.
|
||||||
source = (f"+{nom_ipset(pairs[0], etiquette)}"
|
source = (f"+{nom_ipset(pairs[0], n['index'])}"
|
||||||
if len(pairs) == 1 and nom_ipset(pairs[0], etiquette) in ipsets
|
if len(pairs) == 1 and nom_ipset(pairs[0], n["index"]) in ipsets
|
||||||
else ",".join(srcs))
|
else ",".join(srcs))
|
||||||
for port in _ports(fl):
|
for port in _ports(fl):
|
||||||
regles.append({
|
regles.append({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue