underlay : l'invariant du dernier octet retrouve sa portée (D-04, D-52 à D-54)
Il valait partout ; il ne vaut que dans l'adressage dérivé des tenants, où passerelle_de(index, zone) produit le même .1 dans les treize sous-réseaux d'un tenant. C'est une propriété de la dérivation, pas une loi universelle. Dans l'underlay il produisait deux effets pervers. Un seuil arbitraire : les sous-réseaux plus étroits qu'un /24 étaient exemptés, donc élargir un /29 changeait la validité du fichier sans que rien d'autre bouge. Et une couture entre propriétaires : l'octet attendu venait de la nomenclature d'un tenant, appliquée à la fabric de l'hébergeur — la validité de l'underlay aurait dépendu du tenant actif. Ce qui reste est plus fort et suffit (D-52) : une passerelle doit être l'adresse d'un hôte déclaré sur ce réseau. Elle attrape les passerelles fantômes, ce que le comptage d'octets ne faisait pas. Vérifié : la garde mord toujours. À noter, parce que l'ordre était mauvais : le ré-adressage de l'OPNsense en .1 a été demandé au nom de cette règle, deux messages avant qu'elle soit recadrée. Pas perdu — .1 est la position conventionnelle d'une passerelle — mais la portée aurait dû être questionnée avant de faire changer une adresse en service. D-53 : le réseau et l'underlay de l'hébergeur méritent leur propre dépôt. underlay.yml décrit une infrastructure, le dépôt de tenant une organisation ; un tenant peut déménager, une fabric non. Consigné, non fait. D-54 : 10.0.0.0/24 est réservé à l'IPAM, la gestion des équipements et l'OOB, accès sysadmin. Aucun hyperviseur, aucune VM, aucun trafic tenant. C'est la raison d'être des VLAN 11 et 40. 30 preuves OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
1bc516fd92
commit
63aa79e710
4 changed files with 88 additions and 22 deletions
39
CHANGELOG.md
39
CHANGELOG.md
|
|
@ -1,5 +1,44 @@
|
||||||
# CHANGELOG — Set-OPS
|
# CHANGELOG — Set-OPS
|
||||||
|
|
||||||
|
## 2026-08-04 (suite 2) — l'invariant du dernier octet retrouve sa portée
|
||||||
|
|
||||||
|
Il valait partout ; il ne vaut que là où il a un sens : l'**adressage dérivé des
|
||||||
|
tenants**, où `passerelle_de(index, zone)` produit le même `.1` dans les treize
|
||||||
|
sous-réseaux. C'est une propriété de la dérivation, pas une loi universelle.
|
||||||
|
|
||||||
|
Dans l'underlay, il produisait deux effets pervers :
|
||||||
|
|
||||||
|
- **un seuil arbitraire** — les sous-réseaux plus étroits qu'un `/24` étaient exemptés,
|
||||||
|
donc élargir un `/29` changeait la validité du fichier sans que rien d'autre bouge ;
|
||||||
|
- **une couture entre propriétaires** — l'octet attendu venait de la nomenclature d'un
|
||||||
|
*tenant*, appliquée à la fabric de l'*hébergeur*. La validité de l'underlay aurait
|
||||||
|
dépendu du tenant actif si l'un d'eux réservait autre chose.
|
||||||
|
|
||||||
|
Ce qui reste est plus fort, et suffit : **une passerelle doit être l'adresse d'un hôte
|
||||||
|
déclaré sur ce réseau** (D-52). Elle attrape les passerelles fantômes, ce que le comptage
|
||||||
|
d'octets ne faisait pas.
|
||||||
|
|
||||||
|
> **À noter, parce que l'ordre était mauvais.** Le ré-adressage de l'OPNsense en `.1` a
|
||||||
|
> été demandé au nom de cette règle, deux messages avant qu'elle soit recadrée. Il n'est
|
||||||
|
> pas perdu — `.1` est la position conventionnelle d'une passerelle, et la frontière la
|
||||||
|
> porte désormais partout — mais la portée de la règle aurait dû être questionnée avant
|
||||||
|
> de faire changer une adresse sur un boîtier en service.
|
||||||
|
|
||||||
|
### Deux décisions consignées, non construites
|
||||||
|
|
||||||
|
**D-53** — le **réseau et l'underlay** de l'hébergeur méritent leur propre dépôt.
|
||||||
|
`underlay.yml` décrit une **infrastructure** ; le dépôt de tenant décrit une
|
||||||
|
**organisation**. Un tenant peut déménager, une fabric non. Les mêler oblige, à chaque
|
||||||
|
commit, à trancher ce qu'on touche. Le symlink désignant l'hébergeur pointerait vers ce
|
||||||
|
dépôt-là — la distinction deviendrait visible dans les chemins.
|
||||||
|
|
||||||
|
**D-54** — `10.0.0.0/24` est réservé à l'**IPAM, la gestion des équipements et l'OOB** ;
|
||||||
|
accès sysadmin. Aucun hyperviseur, aucune VM, aucun trafic tenant — ni encapsulé, ni
|
||||||
|
décapsulé. C'est la raison d'être des VLAN 11 et 40. Écrit dans `underlay.yml` à côté du
|
||||||
|
réseau lui-même, pas seulement dans la documentation.
|
||||||
|
|
||||||
|
30 preuves OK.
|
||||||
|
|
||||||
## 2026-08-04 (suite) — plus aucun commutateur ne route
|
## 2026-08-04 (suite) — plus aucun commutateur ne route
|
||||||
|
|
||||||
Question posée à froid : « je ne vois plus de valeur ajoutée au point de routage
|
Question posée à froid : « je ne vois plus de valeur ajoutée au point de routage
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ sont les seules vérifiables.
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| **D-01** | OPNsense est une frontière **nord/sud**, pas la passerelle des zones | le routage inter-zone reste au débit ligne ; la bordure ne voit pas l'est-ouest | `frontiere-opnsense.md` §1 | — |
|
| **D-01** | OPNsense est une frontière **nord/sud**, pas la passerelle des zones | le routage inter-zone reste au débit ligne ; la bordure ne voit pas l'est-ouest | `frontiere-opnsense.md` §1 | — |
|
||||||
| **D-02** | Le **lien de transit** vit dans l'underlay, pas dans un tenant | la frontière route vers tous les tenants par le même saut : il ne peut dériver d'aucun `index` | `frontiere-opnsense.md` §6 | P23 |
|
| **D-02** | Le **lien de transit** vit dans l'underlay, pas dans un tenant | la frontière route vers tous les tenants par le même saut : il ne peut dériver d'aucun `index` | `frontiere-opnsense.md` §6 | P23 |
|
||||||
| **D-04** | Un point de routage porte **le même dernier octet** sur tous ses sous-réseaux | on retient une adresse, pas treize | `frontiere-opnsense.md` §4 | P23 |
|
| **D-04** | Un point de routage porte **le même dernier octet** sur tous ses sous-réseaux — **dans l'adressage dérivé des tenants seulement** | on retient une adresse, pas treize. Dans l'underlay, l'adressage est dicté par les participants d'un lien physique : la règle y imposait un seuil arbitraire et empruntait sa valeur à la nomenclature d'un tenant | `frontiere-opnsense.md` §4 | P20 |
|
||||||
|
| **D-52** | Dans l'underlay, une passerelle doit être **l'adresse d'un hôte déclaré** sur ce réseau | remplace le comptage d'octets par une règle plus forte : elle attrape les passerelles fantômes | `underlay.py` | P23 |
|
||||||
| **D-49** | **Aucun commutateur ne route.** La frontière est le seul équipement L3 | l'EVPN a retiré les VLAN tenants du fil, puis la fusion du lien de sortie a rendu les nœuds de sortie **adjacents** à la frontière : plus un seul flux à router | `underlay.yml` | P23 |
|
| **D-49** | **Aucun commutateur ne route.** La frontière est le seul équipement L3 | l'EVPN a retiré les VLAN tenants du fil, puis la fusion du lien de sortie a rendu les nœuds de sortie **adjacents** à la frontière : plus un seul flux à router | `underlay.yml` | P23 |
|
||||||
| **D-50** | `passerelle` = la passerelle du sous-réseau, **où qu'elle vive** ; le SVI se **dérive** du rôle de son porteur | la clé signifiait « adresse du SVI du switch » — une hypothèse, pas une donnée. Un même moteur sert désormais les deux postures | `devis_reseau.py` | P23 |
|
| **D-50** | `passerelle` = la passerelle du sous-réseau, **où qu'elle vive** ; le SVI se **dérive** du rôle de son porteur | la clé signifiait « adresse du SVI du switch » — une hypothèse, pas une donnée. Un même moteur sert désormais les deux postures | `devis_reseau.py` | P23 |
|
||||||
| **D-51** | **Deux** commutateurs en paire, pas trois en étoile | le centre d'une étoile est sur **tous** les chemins : point de panne unique du plan de données. Deux liens vers deux commutateurs donnent la redondance qu'une étoile ne peut pas donner | `underlay.yml` | — |
|
| **D-51** | **Deux** commutateurs en paire, pas trois en étoile | le centre d'une étoile est sur **tous** les chemins : point de panne unique du plan de données. Deux liens vers deux commutateurs donnent la redondance qu'une étoile ne peut pas donner | `underlay.yml` | — |
|
||||||
|
|
@ -60,6 +61,8 @@ sont les seules vérifiables.
|
||||||
| **D-46** | Un hébergeur porte **trois** catégories, pas deux : son **tenant**, ses **opérations**, le **plan de contrôle** | Chezlepro est hébergeur ET tenant, ce qui masquait des besoins n'appartenant à aucun tenant | `hebergeur-exploitation.md` §2 | — |
|
| **D-46** | Un hébergeur porte **trois** catégories, pas deux : son **tenant**, ses **opérations**, le **plan de contrôle** | Chezlepro est hébergeur ET tenant, ce qui masquait des besoins n'appartenant à aucun tenant | `hebergeur-exploitation.md` §2 | — |
|
||||||
| **D-47** | Les **services d'exploitation** de l'hébergeur vivent dans **son dépôt**, et leurs VM se rattachent à un **pont VLAN, jamais un VNet** | un service qui observe la fabric ne peut pas dépendre d'elle : l'EVPN tombe, et la supervision tombe avec la raison de la panne | `hebergeur-exploitation.md` §1, §4 | — |
|
| **D-47** | Les **services d'exploitation** de l'hébergeur vivent dans **son dépôt**, et leurs VM se rattachent à un **pont VLAN, jamais un VNet** | un service qui observe la fabric ne peut pas dépendre d'elle : l'EVPN tombe, et la supervision tombe avec la raison de la panne | `hebergeur-exploitation.md` §1, §4 | — |
|
||||||
| **D-48** | Les **hyperviseurs** sont gérables par Ansible ; « hors flotte » ne vaut que pour les **commutateurs** et la **frontière** | ce sont des Debian joignables en SSH ; c'est la seule façon d'y poser un exportateur de métriques | `hebergeur-exploitation.md` §5 | — |
|
| **D-48** | Les **hyperviseurs** sont gérables par Ansible ; « hors flotte » ne vaut que pour les **commutateurs** et la **frontière** | ce sont des Debian joignables en SSH ; c'est la seule façon d'y poser un exportateur de métriques | `hebergeur-exploitation.md` §5 | — |
|
||||||
|
| **D-53** | Le **réseau et l'underlay** de l'hébergeur méritent leur **propre dépôt**, séparé de son tenant | `underlay.yml` et le cluster décrivent une infrastructure ; le dépôt de tenant décrit une organisation. Les mêler oblige à trancher qui possède quoi à chaque commit | `hebergeur-exploitation.md` §7 | — |
|
||||||
|
| **D-54** | `10.0.0.0/24` est réservé à l'**IPAM, la gestion des équipements et l'OOB** — accès sysadmin | aucun hyperviseur, aucune VM, aucun trafic tenant ; c'est la raison d'être des VLAN 11 et 40 | `underlay.yml` | — |
|
||||||
| **D-18** | Chaque tenant a un **responsable désigné** | sans lui, « qui peut décider de déménager cette organisation ? » se pose au pire moment | `migration-tenant.md` §3 | — |
|
| **D-18** | Chaque tenant a un **responsable désigné** | sans lui, « qui peut décider de déménager cette organisation ? » se pose au pire moment | `migration-tenant.md` §3 | — |
|
||||||
|
|
||||||
| **D-38** | Toute authentification **web** passe par Keycloak ; LDAP est la **source unique** des comptes | une identité, un mot de passe ; aucun service ne tient son propre répertoire d'humains | `authentification.md` §1-2 | — |
|
| **D-38** | Toute authentification **web** passe par Keycloak ; LDAP est la **source unique** des comptes | une identité, un mot de passe ; aucun service ne tient son propre répertoire d'humains | `authentification.md` §1-2 | — |
|
||||||
|
|
|
||||||
|
|
@ -84,3 +84,31 @@ Deux obstacles mesurés le 2026-08-04, à lever avant :
|
||||||
|
|
||||||
À noter au passage : la convention héritée était déjà `1000 + numéro de tenant`. La formule
|
À noter au passage : la convention héritée était déjà `1000 + numéro de tenant`. La formule
|
||||||
de Set-OPS (`1000 + index×10 + zone`) en est un raffinement, pas une invention.
|
de Set-OPS (`1000 + index×10 + zone`) en est un raffinement, pas une invention.
|
||||||
|
|
||||||
|
## 7. Un dépôt à part pour le réseau (décidé, non fait)
|
||||||
|
|
||||||
|
`underlay.yml` et `proxmox-hebergeur.yml` vivent aujourd'hui dans `OPS-Chezlepro`, qui est
|
||||||
|
aussi le dépôt du **tenant** Chezlepro. C'est ce qui a permis de démarrer, et c'est ce qui
|
||||||
|
oblige, à chaque commit, à trancher si l'on touche à l'infrastructure ou à l'organisation.
|
||||||
|
|
||||||
|
Ils décrivent des objets différents : l'un une **infrastructure** — des câbles, des VLAN,
|
||||||
|
un cluster —, l'autre une **organisation** — ses serveurs, ses applications, ses comptes.
|
||||||
|
Un tenant peut déménager ; une fabric ne déménage pas.
|
||||||
|
|
||||||
|
Le dépôt réseau de l'hébergeur porterait donc `underlay.yml`, `proxmox-hebergeur.yml`, et
|
||||||
|
plus tard l'inventaire des services d'exploitation (§4). Le symlink qui désigne
|
||||||
|
l'hébergeur pointerait vers lui plutôt que vers son tenant — ce qui rendrait enfin la
|
||||||
|
distinction visible dans les chemins eux-mêmes.
|
||||||
|
|
||||||
|
**Rien n'est fait.** La bascule demande de déplacer deux fichiers, de refaire le symlink,
|
||||||
|
et de vérifier que les trois générateurs qui les lisent suivent.
|
||||||
|
|
||||||
|
## 8. Le VLAN de gestion, et ce qu'il n'est pas
|
||||||
|
|
||||||
|
`10.0.0.0/24` est réservé à l'**IPAM, la gestion des équipements et l'OOB/IPMI**. Accès
|
||||||
|
sysadmin uniquement.
|
||||||
|
|
||||||
|
Aucun hyperviseur n'y a d'adresse, aucune VM n'y est branchée, aucun trafic tenant ne le
|
||||||
|
traverse — ni encapsulé, ni décapsulé. C'est précisément la raison d'être des VLAN 11
|
||||||
|
(transport VXLAN) et 40 (sortie tenant) : les avoir sortis de ce domaine de diffusion.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -364,27 +364,23 @@ def valider(underlay: dict | None,
|
||||||
if p.get("montante") and hn == r_courant:
|
if p.get("montante") and hn == r_courant:
|
||||||
erreurs.append(f"hote '{hn}': une `montante` alors qu'il EST le routeur")
|
erreurs.append(f"hote '{hn}': une `montante` alors qu'il EST le routeur")
|
||||||
|
|
||||||
# Invariant du dernier octet : tous les points de routage doivent le partager.
|
# L'INVARIANT DU DERNIER OCTET NE S'APPLIQUE PAS ICI (decide le 2026-08-04).
|
||||||
# Exemption des sous-reseaux plus etroits qu'un /24 : sur un /29 de transit,
|
#
|
||||||
# l'adressage est dicte par les participants du lien, pas par la convention.
|
# Il vaut pour l'adressage DERIVE des tenants, ou `passerelle_de(index, zone)`
|
||||||
attendu = octet_passerelle(plan_nomenclature)
|
# produit le meme `.1` dans les treize sous-reseaux d'un tenant : on retient une
|
||||||
if attendu is not None:
|
# adresse, pas treize. C'est une propriete de la derivation, pas une regle
|
||||||
for r in reseaux(underlay):
|
# universelle.
|
||||||
gw = r.get("passerelle")
|
#
|
||||||
if not gw:
|
# Dans l'underlay, l'adressage est dicte par les PARTICIPANTS d'un lien physique.
|
||||||
continue
|
# La regle y produisait deux effets pervers : un seuil arbitraire (les sous-reseaux
|
||||||
try:
|
# plus etroits qu'un /24 etaient exemptes, donc elargir un /29 changeait la
|
||||||
net = ipaddress.ip_network(r["sous_reseau"], strict=False)
|
# validite du fichier), et une couture entre proprietaires — l'octet attendu venait
|
||||||
except ValueError:
|
# de la nomenclature d'un TENANT, appliquee a la fabric de l'HEBERGEUR. La validite
|
||||||
continue
|
# de l'underlay aurait dependu du tenant actif si l'un d'eux reservait autre chose.
|
||||||
if net.prefixlen > 24:
|
#
|
||||||
continue # lien etroit : exempte, cf. le /29 de transit
|
# Ce qui reste, et qui est plus fort : une passerelle doit etre l'adresse d'un hote
|
||||||
octet = int(str(gw).rsplit(".", 1)[1])
|
# DECLARE sur ce reseau (verifie plus bas). Elle attrape les passerelles fantomes,
|
||||||
if octet != attendu:
|
# ce que le comptage d'octets ne faisait pas.
|
||||||
erreurs.append(
|
|
||||||
f"reseau '{r.get('nom','?')}': passerelle {gw} finit par .{octet} alors que "
|
|
||||||
f"les points de routage portent .{attendu} partout "
|
|
||||||
f"(nomenclature: reservations.passerelle)")
|
|
||||||
|
|
||||||
v = (underlay or {}).get("acl_inter_tenant")
|
v = (underlay or {}).get("acl_inter_tenant")
|
||||||
if v is not None and not isinstance(v, bool):
|
if v is not None and not isinstance(v, bool):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue