instancier : accepter un adressage declare, pour les plans sans index
Un SITE decrit les machines de l'hebergeur : pas d'index, pas de cohabitation avec les tenants, il vit dans le reseau d'administration. Rien ne peut donc deriver d'un seed inexistant. L'explicite (`ip`, `vmid`, `vlan`) gagne sur le derive, et les deux chemins se rejoignent sur un seul jeu de hostvars. La garde reste entiere : une machine sans adresse -- ni declaree ni derivable -- est toujours refusee. Revele en preparant le plan du site : l'underlay ne dit PAS quel pont Proxmox porte quel reseau. Les tenants ne s'en apercevaient pas, leur pont etant un VNet derive de leur index. Un SITE n'en a pas. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
85ef6e107e
commit
9960cfd68e
2 changed files with 55 additions and 4 deletions
29
CHANGELOG.md
29
CHANGELOG.md
|
|
@ -1,5 +1,34 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-08-24 — Un plan peut désormais déclarer son adressage, faute d'index à en dériver
|
||||
|
||||
Un **SITE** décrit les machines de l'hébergeur. Il n'a pas d'index — il ne cohabite pas
|
||||
avec les tenants, il vit dans le réseau d'administration — et rien ne peut donc se dériver
|
||||
d'un seed qui n'existe pas.
|
||||
|
||||
`instancier` accepte maintenant un adressage **déclaré** (`ip`, `vmid`, `vlan`, `cidr`,
|
||||
`passerelle` au plan), et l'explicite gagne sur le dérivé. Les deux chemins se rejoignent
|
||||
sur un seul jeu de `hostvars` : un tenant ne déclare rien et tout descend de son index ;
|
||||
un site déclare, parce qu'il n'y a rien d'où descendre.
|
||||
|
||||
**La garde reste entière** : une machine sans adresse — ni déclarée ni dérivable — est
|
||||
toujours refusée. C'est l'absence d'adresse qui est fautive, pas l'absence de dérivation.
|
||||
|
||||
### Ce que la préparation a révélé
|
||||
|
||||
**Le réseau d'administration `10.17.0.0/24` est à l'intérieur du supernet que l'index 17
|
||||
dérive pour Chezlepro** (`10.17.0.0/16`). Pas de collision réelle — les zones d'un tenant
|
||||
commencent à `10.17.16.0` — mais le nom trompe, et un jour ça mordra.
|
||||
|
||||
**L'underlay ne dit pas quel pont Proxmox porte quel réseau.** Il déclare les VLAN, les
|
||||
sous-réseaux, les passerelles ; il documente `vmbr0` pour la grappe et `vmbr3` pour le
|
||||
transport VXLAN — en commentaire. Rien ne dit par où une VM rejoint le plan
|
||||
d'administration. Les tenants ne s'en apercevaient pas : leur pont est un VNet SDN, dérivé
|
||||
de leur index. Un SITE, lui, n'en a pas.
|
||||
|
||||
C'est un intrant manquant, pas un détail : sans lui, un plan de site ne peut pas dire à
|
||||
quoi rattacher ses machines.
|
||||
|
||||
## 2026-08-24 — Quinze invites pour un seul mot de passe
|
||||
|
||||
`flotte-creer` appelait `make creer-vm` **une fois par hôte**, et chaque appel ajoutait
|
||||
|
|
|
|||
|
|
@ -186,16 +186,27 @@ def generer() -> dict:
|
|||
#
|
||||
# On refuse en BLOC plutot qu'a la premiere fautive : l'exploitant corrige son plan
|
||||
# une fois, pas une machine a la fois.
|
||||
# UN SITE N'A PAS D'INDEX, DONC RIEN NE SE DERIVE (2026-08-24).
|
||||
#
|
||||
# Un SITE decrit les machines de l'HEBERGEUR : elles vivent dans le reseau
|
||||
# d'administration, pas dans un supernet de tenant, et il n'y en a qu'un jeu par site.
|
||||
# Leur adressage est donc DECLARE, pas derive — il n'y a pas de seed dont le faire
|
||||
# descendre, et inventer un index pour un site le ferait cohabiter avec les tenants.
|
||||
#
|
||||
# La garde reste entiere pour les deux mondes : une machine sans adresse — ni derivee
|
||||
# ni declaree — est refusee. C'est l'absence d'adresse qui est fautive, pas l'absence
|
||||
# de derivation.
|
||||
sans_fonction = [
|
||||
nom for nom, srv in serveurs.items()
|
||||
if not (deriver_nomenclature(str(srv.get("fonction", "")),
|
||||
fonction_seq(nom)[1], nomenclature) or {}).get("adresse_ip")
|
||||
if not str(srv.get("ip", "")).strip()
|
||||
and not (deriver_nomenclature(str(srv.get("fonction", "")),
|
||||
fonction_seq(nom)[1], nomenclature) or {}).get("adresse_ip")
|
||||
]
|
||||
if sans_fonction:
|
||||
connues = ", ".join(sorted((nomenclature.get("fonctions") or {}))) or "(aucune)"
|
||||
raise SystemExit(
|
||||
"Machines sans adresse derivable — leur `fonction` n'est pas declaree dans "
|
||||
"`nomenclature.fonctions` :\n"
|
||||
"Machines sans adresse : ni declaree (`ip:` au plan, cas d'un SITE), ni "
|
||||
"derivable — leur `fonction` n'est pas dans `nomenclature.fonctions` :\n"
|
||||
+ "".join(f" - {n} : fonction « {serveurs[n].get('fonction', '')} »\n" for n in sans_fonction)
|
||||
+ f"Fonctions connues de ce plan : {connues}")
|
||||
|
||||
|
|
@ -207,6 +218,17 @@ def generer() -> dict:
|
|||
for nom, srv in serveurs.items():
|
||||
_, seq = fonction_seq(nom)
|
||||
d = deriver_nomenclature(str(srv.get("fonction", "")), seq, nomenclature) or {}
|
||||
# L'EXPLICITE GAGNE SUR LE DERIVE. Un SITE declare `ip`, `vmid` et `vlan` ; un
|
||||
# tenant ne declare rien et tout descend de son index. Les deux chemins se
|
||||
# rejoignent ici, et un seul jeu de hostvars en sort.
|
||||
if str(srv.get("ip", "")).strip():
|
||||
d = dict(d)
|
||||
d["adresse_ip"] = srv["ip"]
|
||||
d["cidr"] = srv.get("cidr", 24)
|
||||
d["passerelle"] = srv.get("passerelle") or d.get("passerelle")
|
||||
d["vlan"] = srv.get("vlan", d.get("vlan"))
|
||||
d["vmid"] = srv.get("vmid", d.get("vmid"))
|
||||
d["zone"] = None # pas de zone : pas de VNet SDN a deriver
|
||||
hostvars = {
|
||||
# Supernet du tenant, DERIVE du seed comme tout le reste. Il repond a la
|
||||
# question « quels clients mon service doit-il accepter ? », posee par
|
||||
|
|
|
|||
Loading…
Reference in a new issue