underlay : un SITE n'a pas d'index — le vestige est retire
`index: 17` ne disait pas « voici mon adressage » : un site ne derive rien, ses machines vivent sur un reseau de fabric hors de toute derivation. Il disait UNE seule chose — quel supernet de tenant est le mien — pour autoriser un reseau du site a en occuper la bande basse (D-77). Un reste de la coincidence hebergeur<->tenant chez Chezlepro, qui est les deux a la fois ; ailleurs il aurait fallu inventer un index a un hebergeur qui n'heberge pas son propre ecosysteme. L'exception se declare desormais sur le RESEAU qui en a besoin, et elle NOMME le tenant dont elle occupe la bande basse (`bande_basse_de: OPS-Chezlepro`). Plus vrai : un seul reseau est concerne. Plus verifiable : le nom se resout dans le registre `tenants:`, donc une faute de frappe est refusee au lieu de passer. Quatre controles negatifs, tous refuses — tenant inconnu, exception absente, debordement sur la bande des zones, et le mauvais tenant nomme. 42 preuves vertes, les quatre devis du panneau OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
467b05cbc0
commit
add94f2cbd
2 changed files with 58 additions and 5 deletions
30
CHANGELOG.md
30
CHANGELOG.md
|
|
@ -1,5 +1,35 @@
|
||||||
# CHANGELOG — Set-OPS
|
# CHANGELOG — Set-OPS
|
||||||
|
|
||||||
|
## 2026-08-25 — Un SITE n'a pas d'index : le vestige est retiré
|
||||||
|
|
||||||
|
Le site portait `index: 17`. Ça n'a jamais voulu dire « voici mon adressage » — un site
|
||||||
|
ne dérive rien, ses machines vivent sur un réseau de fabric (`10.0.3.0/24`), hors de toute
|
||||||
|
dérivation. Ça voulait dire **une seule chose** : *quel supernet de tenant est le mien*,
|
||||||
|
pour autoriser un réseau du site à en occuper la bande basse (D-77).
|
||||||
|
|
||||||
|
C'était un reste de la coïncidence hébergeur↔tenant chez Chezlepro, qui est les deux à la
|
||||||
|
fois. Ailleurs, ça aurait induit en erreur : un hébergeur qui n'héberge pas son propre
|
||||||
|
écosystème n'a aucun supernet à lui, et devait quand même inventer un index.
|
||||||
|
|
||||||
|
**L'exception se déclare désormais sur le réseau qui en a besoin**, et elle **nomme** le
|
||||||
|
tenant dont elle occupe la bande basse :
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- nom: management
|
||||||
|
segment_physique: true
|
||||||
|
bande_basse_de: OPS-Chezlepro
|
||||||
|
sous_reseau: 10.17.0.0/24
|
||||||
|
```
|
||||||
|
|
||||||
|
Trois gains. C'est **plus vrai** — un seul réseau est concerné, pas le site entier. C'est
|
||||||
|
**plus lisible** — le lecteur voit pourquoi ce `/24` habite un `/16` qui n'est pas le sien.
|
||||||
|
Et c'est **vérifiable** : le nom se résout dans le registre `tenants:`, donc une faute de
|
||||||
|
frappe est refusée au lieu de passer silencieusement.
|
||||||
|
|
||||||
|
Quatre contrôles négatifs, tous refusés : un tenant inconnu, l'exception absente alors que
|
||||||
|
le chevauchement existe, un débordement sur la bande des zones, et — le cas subtil — le
|
||||||
|
**mauvais** tenant nommé.
|
||||||
|
|
||||||
## 2026-08-25 — Le SITE devient un écosystème complet : PKI, DNS, forge
|
## 2026-08-25 — Le SITE devient un écosystème complet : PKI, DNS, forge
|
||||||
|
|
||||||
Le site portait **trois services sur les sept** que le modèle `origine` appelle le plus
|
Le site portait **trois services sur les sept** que le modèle `origine` appelle le plus
|
||||||
|
|
|
||||||
|
|
@ -479,9 +479,31 @@ def valider(underlay: dict | None,
|
||||||
if tenants_vlans is None or tenants_supernets is None:
|
if tenants_vlans is None or tenants_supernets is None:
|
||||||
tenants_vlans, tenants_supernets = _tenants_reperes()
|
tenants_vlans, tenants_supernets = _tenants_reperes()
|
||||||
t_supernets = [ipaddress.ip_network(s, strict=False) for s in tenants_supernets]
|
t_supernets = [ipaddress.ip_network(s, strict=False) for s in tenants_supernets]
|
||||||
# Sans `index` declare, on ignore quel supernet est le SIEN : on retombe alors sur la
|
# UN SITE N'A PAS D'INDEX (2026-08-25). Il en portait un, et c'etait un vestige.
|
||||||
# regle stricte d'avant D-77 (aucun chevauchement), qui reste sure.
|
#
|
||||||
idx_site = index_site(underlay)
|
# Cette valeur ne disait pas « voici mon adressage » — le site ne derive rien, ses
|
||||||
|
# machines vivent sur un reseau de fabric. Elle disait une seule chose : « QUEL
|
||||||
|
# SUPERNET DE TENANT EST LE MIEN », pour autoriser un reseau du site a occuper sa
|
||||||
|
# bande basse. C'etait un reste de la coincidence hebergeur↔tenant chez Chezlepro,
|
||||||
|
# qui est a la fois les deux — et qui aurait induit en erreur partout ailleurs.
|
||||||
|
#
|
||||||
|
# L'exception se declare desormais SUR LE RESEAU qui en a besoin, et elle NOMME le
|
||||||
|
# tenant dont elle occupe la bande basse. C'est plus vrai (un seul reseau est
|
||||||
|
# concerne, pas le site entier) et plus verifiable : le nom se resout dans le registre
|
||||||
|
# d'allocation, donc une faute de frappe est refusee au lieu de passer.
|
||||||
|
alloc = allocations(underlay)
|
||||||
|
|
||||||
|
def _supernet_hote(r: dict) -> tuple[ipaddress.IPv4Network | None, str | None]:
|
||||||
|
"""Supernet dont ce reseau occupe la bande basse, et l'erreur s'il n'existe pas."""
|
||||||
|
nom_t = str(r.get("bande_basse_de") or "").strip()
|
||||||
|
if not nom_t:
|
||||||
|
return None, None
|
||||||
|
if nom_t not in alloc:
|
||||||
|
return None, (f"reseau '{r.get('nom', '?')}': `bande_basse_de: {nom_t}` — ce "
|
||||||
|
f"nom n'est pas dans le registre `tenants:` du site. Sans "
|
||||||
|
f"allocation connue, on ne peut pas savoir quel supernet il "
|
||||||
|
f"occupe, ni verifier qu'il reste dans la bande basse.")
|
||||||
|
return ipaddress.ip_network(supernet_de(alloc[nom_t]), strict=False), None
|
||||||
|
|
||||||
erreurs: list[str] = []
|
erreurs: list[str] = []
|
||||||
if mode_site:
|
if mode_site:
|
||||||
|
|
@ -528,8 +550,9 @@ def valider(underlay: dict | None,
|
||||||
# Chevaucher celui d'un AUTRE tenant reste une erreur — c'est ce qui empeche deux
|
# Chevaucher celui d'un AUTRE tenant reste une erreur — c'est ce qui empeche deux
|
||||||
# sites de se joindre. Et deborder sur la bande haute de son propre supernet en
|
# sites de se joindre. Et deborder sur la bande haute de son propre supernet en
|
||||||
# est une aussi : on entrerait en collision avec ses propres zones.
|
# est une aussi : on entrerait en collision avec ses propres zones.
|
||||||
mien = ipaddress.ip_network(supernet_de(idx_site), strict=False) \
|
mien, err_bande = _supernet_hote(r)
|
||||||
if idx_site is not None else None
|
if err_bande:
|
||||||
|
erreurs.append(err_bande)
|
||||||
for ts in t_supernets:
|
for ts in t_supernets:
|
||||||
if not net.overlaps(ts):
|
if not net.overlaps(ts):
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue