flux : un dossier genere doit aussi savoir supprimer
flux-genere/ ecrivait sans jamais retirer. Un hote sorti du plan y laissait son ruleset complet, indiscernable des vivants. Le dossier cessait d'etre une image du plan pour devenir le cumul de tous les plans successifs. P53 voyait l'orphelin — un ruleset perime n'a pas de refus audible — mais designait le fichier, pas la cause. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
parent
bd0e40753b
commit
77cf63f1cf
3 changed files with 41 additions and 4 deletions
18
CHANGELOG.md
18
CHANGELOG.md
|
|
@ -1,5 +1,23 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-09-13 (7) — Un hote retire du plan laissait son pare-feu derriere lui
|
||||
|
||||
En retirant `backup-01` du plan de TechnoLibre, `flux-genere/backup-01.nft` est reste sur
|
||||
le disque : un ruleset complet, pour une machine qui n'existe plus, indiscernable des
|
||||
autres au premier coup d'oeil. La generation ECRIVAIT sans jamais RETIRER.
|
||||
|
||||
Ce que ca coute : `flux-genere/` cesse d'etre une IMAGE du plan pour devenir le cumul de
|
||||
tous les plans successifs. Qui lit le dossier pour savoir ce qu'un ecosysteme expose lit
|
||||
alors un etat qui n'a jamais existe.
|
||||
|
||||
**P53 le voyait deja** — un ruleset perime n'a pas de refus audible — mais il designait le
|
||||
fichier, pas la cause. La generation supprime desormais les orphelins **et le dit** :
|
||||
|
||||
note : backup-01.nft retire — cet hote n'est plus au plan.
|
||||
|
||||
C'est le meme patron que les neuf resolutions d'instance : un dossier GENERE doit etre le
|
||||
reflet exact de sa source, donc la generation doit aussi supprimer.
|
||||
|
||||
## 2026-09-13 (6) — `balloon: 0` ne desactive pas le ballooning : il retire le peripherique
|
||||
|
||||
Soixante-et-un gigaoctets de RAM etaient **declares** a vingt-et-une machines. Mesure a
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
| P15 | Modele public socle valide | AFF-022, AFF-099 | ✅ OK | Modele public socle : domaines/serveurs/applications/bases valides. |
|
||||
| P16 | Inventaire Ansible complet (--list) | AFF-030 | ⚪ SAUTE | Voute chiffree sans ANSIBLE_VAULT_PASSWORD_FILE (prerequis AFF-026). |
|
||||
| P17 | Tous les modeles valident (registres + underlay) | AFF-022, AFF-099 | ✅ OK | Les 1 modele(s) decouvert(s) valident. |
|
||||
| P18 | Gabarit de voute complet | AFF-026 | ✅ OK | Gabarit de voute complet : 27 secret(s) exige(s), tous presents. (Voute reelle non lisible ici : verification sautee.) |
|
||||
| P18 | Gabarit de voute complet | AFF-026 | ✅ OK | Gabarit de voute complet : 29 secret(s) exige(s), tous presents. (Voute reelle non lisible ici : verification sautee.) |
|
||||
| P19 | Le GUI couvre le schema du plan | AFF-002, AFF-095 | ✅ OK | GUI : les 29 champ(s) des plans reels sont editables (2 plan(s) inspecte(s)), registres toleres : nomenclature. |
|
||||
| P20 | Adressage 100% derive du seed (aucun stocke) | AFF-001, AFF-003 | ✅ OK | 2 nomenclature(s) : adressage 100% derive du seed index. |
|
||||
| P21 | Federation : aucun index en collision | AFF-102 | ✅ OK | Federation coherente : 5 instance(s) federee(s), aucun index en collision. |
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
| P29 | Authentification : chaque role declare sa position | AFF-111 | ✅ OK | 33 role(s) serveur declares (interne-sans-auth 2, ldap-direct 2, sans-auth-humaine 22, socle-identite 2, web-sso 5) ; 2 lacune(s) nommee(s) : serveur_loki, serv |
|
||||
| P30 | SDN EVPN : zones, VNets et sous-reseaux derives | AFF-112 | ✅ OK | CONFORME : SDN EVPN, 3 zone(s), 15 VNet(s), 15 sous-reseau(x), aucune collision. |
|
||||
| P31 | Documentation : tout ce que le depot FAIT est nomme | — | ✅ OK | 63 scripts expliques et atteignables, 121 cibles make documentees, 68 roles avec README. |
|
||||
| P32 | Intrants exiges par les roles : tous fournis | — | ✅ OK | CONFORME : 38 exigence(s) de role, toutes satisfaites (140 cle(s) declaree(s) par l'instance). |
|
||||
| P32 | Intrants exiges par les roles : tous fournis | — | ✅ OK | CONFORME : 38 exigence(s) de role, toutes satisfaites (146 cle(s) declaree(s) par l'instance). |
|
||||
| P33 | Aucune collision de port entre roles co-localises | — | ✅ OK | CONFORME : 34 revendication(s) de port, aucune collision entre roles co-localises (36 groupes). |
|
||||
| P34 | Chaque document declare son lecteur | — | ✅ OK | 45 document(s) declarent leur lecteur (39 genere(s) exempte(s)). |
|
||||
| P35 | Toute application exigeant une base en a une au plan | — | ✅ OK | 5 application(s) exigeant une base l'ont toutes (4 entree(s) au registre). |
|
||||
|
|
@ -65,9 +65,9 @@
|
|||
| P50 | Silences : un refus muet est declare, place en dernier, et motive | — | ✅ OK | 2 silence(s) declare(s), tous en sequence > 1 (la plus haute des 236 regles `pass`), tous non consignes et tous motives. |
|
||||
| P51 | Collections : toutes declarees, toutes epinglees | — | ✅ OK | 3 collection(s) et 2 bibliotheque(s) Python declarees et epinglees : ansible.posix==1.6.2, community.general==10.3.0, community.postgresql==3.10.2 |
|
||||
| P52 | Materialiser n'exige pas d'entrer dans le tenant | — | ✅ OK | `creer-vm` confirme par l'agent invite (API des hyperviseurs, deja utilisee pour creer), sans exiger d'entrer dans le tenant. |
|
||||
| P53 | L'interne refuse a voix haute, la bordure se tait | — | ✅ OK | L'interne parle, la bordure se tait — 15 ruleset(s) nftables refusent a voix haute ; pare-feu est-ouest en REJECT, source unique ; frontiere muette (actions : b |
|
||||
| P53 | L'interne refuse a voix haute, la bordure se tait | — | ✅ OK | L'interne parle, la bordure se tait — 14 ruleset(s) nftables refusent a voix haute ; pare-feu est-ouest en REJECT, source unique ; frontiere muette (actions : b |
|
||||
| P54 | L'insemination ne reclame aucun secret du tenant | — | ✅ OK | 2 couche(s) d'insemination (serveur_debian, serveur_ops), 9 role(s) applique(s), aucun secret de tenant reclame. |
|
||||
| P55 | La cle du SITE ne nait que sur le runner d'un tenant | — | ✅ OK | 14 hote(s) : la cle du SITE ne nait que sur 1 runner(s) de tenant, celle du tenant sur 14. |
|
||||
| P55 | La cle du SITE ne nait que sur le runner d'un tenant | — | ✅ OK | 14 hote(s) : la cle du SITE ne nait que sur 1 runner(s) de tenant, celle du tenant sur 0. |
|
||||
| P56 | Gabarit minimal, et rien de retire n'est perdu | — | ✅ OK | Gabarit minimal : 4 role(s), tous indispensables au premier demarrage ; 14 role(s) retire(s), tous repris par le socle ou le durcissement. |
|
||||
| P57 | Comptes en prose : les chiffres du depot sur lui-meme | — | ✅ OK | Les comptes ecrits en prose correspondent a la mesure (74 preuves, 68 roles, 41 groupes). |
|
||||
| P58 | Habilitations : chaque service dit a quel GROUPE, et par quoi | — | ✅ OK | 8 habilitation(s) declarees, toutes nommant un groupe, un mecanisme connu et une raison ; les `role-realm` sont projetees. |
|
||||
|
|
|
|||
|
|
@ -685,6 +685,25 @@ def generer_nftables(flux_par_role: dict[str, list[dict]], site: bool = False) -
|
|||
chemin = sortie_dir / f"{hote}.nft"
|
||||
chemin.write_text(contenu, encoding="utf-8")
|
||||
ecrits.append(chemin)
|
||||
# UN HOTE RETIRE DU PLAN LAISSAIT SON PARE-FEU DERRIERE LUI (2026-09-13).
|
||||
#
|
||||
# Cette boucle ECRIVAIT sans jamais RETIRER. En retirant `backup-01` du plan d'un
|
||||
# locataire, son `backup-01.nft` est reste sur le disque — un ruleset complet pour une
|
||||
# machine qui n'existe plus, impossible a distinguer des autres au premier coup d'oeil.
|
||||
#
|
||||
# CE QUE CA COUTE : `flux-genere/` cesse d'etre une IMAGE du plan pour devenir un
|
||||
# cumul de tous les plans successifs. Quiconque lit le dossier pour savoir ce que
|
||||
# l'ecosysteme expose lit alors un etat qui n'a jamais existe.
|
||||
#
|
||||
# C'est le meme patron que les neuf resolutions d'instance et que les listes qui se
|
||||
# suivent : un dossier GENERE doit etre le reflet exact de sa source, donc la
|
||||
# generation doit aussi SUPPRIMER. La garde est posee en meme temps que le remede —
|
||||
# **P53** voyait deja l'orphelin, puisqu'un ruleset perime n'a pas de refus audible.
|
||||
for orphelin in sorted(sortie_dir.glob("*.nft")):
|
||||
if orphelin not in ecrits:
|
||||
orphelin.unlink()
|
||||
print(f"note : {orphelin.name} retire — cet hote n'est plus au plan.",
|
||||
file=sys.stderr)
|
||||
return ecrits
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue