un site prend son propre index, et la garde les compte enfin

Decision de l exploitant : sites et locataires se partagent la classe A,
chacun avec son propre index. L exception du guide — un site derive du meme
index que son tenant — disparait.

Ce qu elle cachait : le plan d administration du site vit dans 10.17.0.0/24,
a l interieur du supernet du locataire OPS-Chezlepro. Pas dangereux, mais
10.17.0.0/16 designait deux choses. Et les zones du site ne derivaient de
rien — le site etait la seule partie du systeme sans seed.

La seconde liste nait avec cette decision : un site et un locataire peuvent
desormais reclamer le meme nombre, et make instances ne voyait que les depots
OPS-*. La decouverte lit maintenant SITE-*/underlay.yml et son champ index.
Un site sans index declare reste hors du compte.

SITE-Technolibre : squelette du deuxieme site pour la visite du 14. Un seul
noeud Proxmox en version 9, meme forme que Chezlepro, adresse depuis l index
31. COLLECTE.md liste les 35 valeurs a relever.

Reste a l exploitant : OPS-Chezlepro passe a 37, ce qui libere 17 pour le
site qui l utilise deja.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
Daniel Allaire 2026-09-12 14:31:51 -04:00
parent 904ece3004
commit 5419ee2d71
6 changed files with 218 additions and 6 deletions

View file

@ -1,5 +1,61 @@
# CHANGELOG — Set-OPS # CHANGELOG — Set-OPS
## 2026-09-12 (1) — Un site prend son propre index, et la garde les compte enfin
Decision de l'exploitant : **sites et locataires se partagent la classe A**, chacun avec
son propre index. L'exception du guide — « un site derive du meme index que son tenant » —
disparait. Il reste une seule regle : tout prend un index.
### Ce que l'exception cachait
Chez l'hebergeur de reference, le plan d'administration du site vit dans `10.17.0.0/24`,
**a l'interieur du supernet du locataire `OPS-Chezlepro`**. Ce n'est pas dangereux — les
zones d'un tenant commencent a l'octet 16 par construction, mesure faite — mais
`10.17.0.0/16` designait alors deux choses : un locataire, et le plan d'administration de
celui qui l'heberge. Deux sens pour une adresse.
Les zones du site, elles, ne derivaient de rien : `10.0.31` a `10.0.36`, tapees a la main
dans `underlay.yml`. Le site etait la seule partie du systeme qui n'avait pas de seed.
### La seconde liste, et sa garde ecrite le meme jour
Tant que les sites n'avaient pas d'index, ils ne pouvaient heurter personne. Depuis cette
decision, un site et un locataire peuvent reclamer le meme nombre — et
`make instances` ne voyait que les depots `OPS-*` :
for chemin in sorted(FRERES.glob("*/plan/nomenclature.yml")):
Un site n'a pas de `nomenclature.yml` : il etait invisible a la garde des collisions, celle
qui refuse deux instances aux memes VLAN et VMID. La decouverte lit desormais aussi
`SITE-*/underlay.yml` et son champ `index`. Un site qui n'en declare pas reste hors du
compte — il y entre le jour ou il en prend un.
OPS-Chezlepro 17 1171-1176
OPS-Technolibre 23 1231-1236
OPS-Patient0 29 1291-1296
SITE-Technolibre 31 —
### SITE-Technolibre
Squelette du deuxieme site, pour la visite du 14 septembre. Un seul noeud Proxmox, en
version 9, derriere un OPNsense. Meme forme que le site de Chezlepro — sept machines, six
zones, memes services — adresse depuis l'index **31** : gestion en `10.31.0.0/24`, zones en
`10.31.31` a `10.31.36` (le 3e octet reste le numero de VLAN).
Trois differences ecrites dans son README plutot que decouvertes sur place : le SPOF est
total (gabarit et clones sur la meme machine), les clones sont COMPLETS (un clone lie
n'achete rien sans second noeud), et **rien n'a jamais tourne contre un PVE 9**.
`COLLECTE.md` liste les 35 valeurs a relever, dont la question de forme : ce qu'il y a
entre le noeud et l'OPNsense decide du mode de routage.
### Ce qui reste a faire, et qui appartient a l'exploitant
`OPS-Chezlepro` passe a l'index **37**, ce qui libere 17 pour le site qui l'utilise deja.
C'est un renumerotage de quatorze machines : il se fera quand l'exploitant le decidera.
`SITE-Chezlepro` ne declare donc pas encore son index — il entrera dans le compte ce
jour-la.
## 2026-09-11 (5) — Les correctifs de securite reviennent au quotidien, sans personne ## 2026-09-11 (5) — Les correctifs de securite reviennent au quotidien, sans personne
Decision de l'exploitant, et elle corrige un mauvais jugement de ma part. J'avais decrit Decision de l'exploitant, et elle corrige un mauvais jugement de ma part. J'avais decrit

View file

@ -0,0 +1,104 @@
# Preuve de conformite — Set-OPS — 2026-09-12
> Genere par `make prouver` (`scripts/prouver.py`). **Rejouable** : relancer
> reproduit ce rapport. Chaque preuve rejoue l'outillage existant du depot ;
> aucune validation n'est reimplementee ici. Voir le mode d'emploi :
> [`docs/audit/README.md`](README.md), et le registre trace :
> [`docs/audit/affirmations.md`](affirmations.md).
- **Instance** : `/home/danallaire/Espace Chezlepro/DépôtsSurForge/Set-OPS-public/instance` — inventaire `/home/danallaire/Espace Chezlepro/DépôtsSurForge/Set-OPS-public/instance/inventories/principal/hosts.yml`
- **Verdict** : ✅ CONFORME (67 OK · 0 echec · 1 saute)
## Preuves
| # | Preuve | Affirmations | Statut | Detail |
|---|---|---|---|---|
| P01 | Lint (ansible-lint) | AFF-006 | ✅ OK |  |
| P02 | Tests unitaires (inventaire, raser, ecritures du plan, rendu du GUI) | — | ✅ OK | OK |
| P03 | Diff-vide du plan — TOUTES les instances | AFF-001, AFF-004, AFF-030, AFF-031, AFF-032 | ✅ OK | 4 instance(s) verifiee(s) — OPS-Chezlepro-lab, OPS-Chezlepro, OPS-Technolibre, OPS-Patient0 : plan et inventaire applique coincident. |
| P04 | Groupes <-> playbooks homonymes | AFF-008 | ✅ OK | |
| P05 | Dependances causales de groupes | AFF-009, AFF-084 | ✅ OK | |
| P06 | Validateurs de registres (serveurs/apps/bases/domaines) | AFF-003 | ✅ OK | Registre des domaines valide. |
| P07 | GUI (node --check) | AFF-033 | ✅ OK | JS du GUI : syntaxe valide (node --check), 1 nom(s) surveille(s) sans reference orpheline. |
| P08 | Orchestration (couches + graphe) | AFF-070 | ✅ OK | Orchestration coherente : 41 groupes classes, aucun cycle, aucune arete en arriere. |
| P09 | Flux reseau (schema + matrice) | AFF-071 | ✅ OK | Flux coherents : 39 rôles, 107 flux, schéma + matrice OK. |
| P10 | Handlers <-> notify | AFF-034, AFF-035 | ✅ OK | Tout notify pointe vers un handler du meme role (49 roles). |
| P11 | Syntaxe des playbooks (--syntax-check) | AFF-083 | ✅ OK | serveur_resolveur_site |
| P12 | Existence des runbooks cites | AFF-010, AFF-011, AFF-012, AFF-083 | ✅ OK | 17/17 runbooks/registres cites presents. |
| P13 | Invariants structurels/doctrinaux | AFF-015, AFF-022, AFF-037, AFF-038, AFF-062 | ✅ OK | LICENSE, socle dossier, pas de couches paralleles, SSH clef-only, nftables off : OK. |
| P14 | Pas de chemin lab/ code en dur | AFF-097 | ✅ OK | Aucun chemin instance/inventories/lab/group_vars code en dur. |
| 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 : 23 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 : 4 instance(s) federee(s), aucun index en collision. |
| P22 | Plan de recette a jour (genere du wiki) | AFF-002 | ✅ OK | Plan de recette à jour (22 sections). |
| P23 | Underlay sans collision avec la plage tenant | AFF-103 | ✅ OK | Underlay conforme : 13 reseau(x), aucune collision avec la plage tenant. |
| P24 | Frontiere nord/sud : acces d'administration declare | AFF-104 | ✅ OK | note : serveur_powerdns declare un port `derive` que le plan du site ne resout pas — aucune regle emise. |
| P25 | Pare-feu Proxmox : est-ouest intra-tenant derive | AFF-107 | ✅ OK | CONFORME : pare-feu Proxmox, 3 tenant(s), 49 groupe(s), 87 regle(s). |
| P26 | Integrations universelles : aucun hote laisse de cote | AFF-108 | ✅ OK | 14 hote(s) x 6 integration(s) universelle(s) : aucune lacune, aucune recopie (0 exemption(s) derivee(s) du service rendu). |
| P27 | Propriete des intrants : hebergeur et tenant separes | AFF-109 | ✅ OK | 8 cle(s) de cluster chez l'hebergeur, aucune recopiee dans les group_vars du tenant. |
| P28 | Pools Proxmox : un par tenant, sans collision | AFF-110 | ✅ OK | CONFORME : 3 pool(s) Proxmox, 34 VM placee(s), aucun nom ni VMID en collision. |
| 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 | 60 scripts expliques et atteignables, 117 cibles make documentees, 68 roles avec README. |
| P32 | Intrants exiges par les roles : tous fournis | — | ✅ OK | CONFORME : 38 exigence(s) de role, toutes satisfaites (138 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 | 44 document(s) declarent leur lecteur (38 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). |
| P36 | Tout detenteur d'etat porte une sauvegarde | — | ✅ OK | 9 hote(s) de l'ecosysteme et 3 du site detiennent de l'etat, tous porteurs de `client_backup` (9 groupe(s) au catalogue). |
| P37 | Le placement du tenant existe chez son hebergeur | — | ✅ OK | placement confronte a l'hebergeur monte (SITE-Chezlepro) : noeud, stockage, pont — tous offerts. |
| P38 | Catalogue des services : la carte dit ce que le moteur fait | — | ✅ OK | Catalogue a jour : 41 role(s) serveur/client tous nommes, 41 groupe(s) cite(s) en table existent tous. |
| P39 | Glossaire : tout mot employe est enseigne | — | ✅ OK | Glossaire complet : 81 terme(s) du jargon expliques, 15 lien(s) valides, 27 page(s) de wiki toutes atteignables. |
| P40 | Parente : l'ecosysteme sait de quoi il descend | — | ✅ OK | Parente coherente : 4 depot(s), tous retrouves, tous porteurs d'un remote. |
| P41 | Resolution d'instance : une seule, partagee | — | ✅ OK | Resolution unique : 56 script(s) passent par `inventory_rules`, 3 exemption(s) nommee(s). |
| P42 | L'edge porte les noms qu'il publie | — | ✅ OK | 4 edge(s) emettent un certificat portant les noms publies (OPS-Chezlepro-lab/principal, OPS-Chezlepro/principal, OPS-Technolibre/principal, OPS-Patient0/product |
| P43 | Frontiere : le devis voit les machines du site | — | ✅ OK | Devis de la frontiere : 7 machine(s) du plan retrouvees, 151 regle(s) du site. |
| P44 | Integrations : le serveur avant ses clients | — | ✅ OK | 5 integration(s) appliquent leur serveur avant leurs clients. |
| P45 | Pare-feu Proxmox : arme sur les VNet SDN, jamais ailleurs | — | ✅ OK | Le pare-feu Proxmox ne s'arme que sur un VNet SDN (4 cas evalues, dont un qui doit rendre VRAI). |
| P46 | Plancher /etc/hosts : un seul role en decide | — | ✅ OK | Un seul maitre du plancher — roles/hosts_statiques/tasks/main.yml : manage_etc_hosts: false ; et le gabarit maitre est pose (roles/hosts_statiques/templates/hos |
| P47 | Zones inverses : couvrir l'occupe, et rien de plus | — | ✅ OK | Les zones inverses couvrent l'occupe et rien de plus (5 cas evalues, dont un site a quatre zones et un tenant a une). |
| P48 | La carte d'orientation designe ce qui existe, et compte juste | — | ✅ OK | La carte designe 89 chemin(s) qui existent, et ses 7 chiffres correspondent a la mesure. |
| P49 | Registre des flux : la matrice d'audit est a jour | — | ✅ OK | Le registre des flux reproduit exactement ce que les `meta/flux.yml` declarent (125 lignes). |
| 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 219 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 |
| 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. |
| 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 (68 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. |
| P59 | Enumerations annoncees : le nombre correspond a ce qui suit | — | ✅ OK | 2 enumeration(s) annoncee(s) correspondent a ce qu'elles annoncent (formes non ambigues seulement). |
| P60 | Wiki publie : la forge sert ce que le depot dit | AFF-002 | ✅ OK | Le wiki publie correspond au depot : `wiki/` n'a pas bouge depuis `989398f` (publie le 2026-09-11). |
| P61 | Schema du plan : il decrit tout ce que les plans contiennent | AFF-033 | ✅ OK | Le schema decrit 47 champ(s) sur 6 registres ; il couvre tout ce que les plans reels contiennent, et la FORME de chaque champ (scalaire / objet / table) corresp |
| P62 | Schema du plan : il decrit tout ce que le MOTEUR accepte | AFF-033 | ✅ OK | Les 4 validateurs n'acceptent aucun champ que le schema ignore (applications:8, bases_donnees:4, domaines_publics:5, serveurs:3 champ(s) lus par validateur). |
| P63 | cloud-init nait avec la VM et ne lui survit pas | — | ✅ OK | cloud-init est au gabarit (la premiere seconde), absent du socle (pas de va-et-vient), et retire par le durcissement — avec la garde qui verifie que le reseau s |
| P64 | Sondes de supervision : declarees ET deposees | — | ✅ OK | 26 sonde(s) declaree(s) ET deposee(s), chacune avec sa raison et son `ttl` : client_journal/journaux, client_metrique/metriques, client_pki/certificat, serveur_ |
| P65 | Depots tiers : demandes au cache, jamais en HTTPS direct | — | ✅ OK | 4 depot(s) tiers relaye(s) par le cache, aucun role ne les vise en https:// ecrit en dur. |
| P66 | Clients OIDC : chaque URI vise un nom que le plan expose | — | ✅ OK | 4 client(s) OIDC, toutes leurs URI visent un FQDN que le plan expose (6 exposition(s)). |
| P67 | Nom public : le service porte celui du plan, pas celui du role | — | ✅ OK | 6 service(s) expose(s) portent le nom du plan (6 groupe(s) derive(s)). |
| P68 | Cle de depot telechargee : mesuree avant d'etre utilisee | — | ✅ OK | 5 role(s) telechargent une cle de depot, tous la mesurent avant de s'en servir. |
## Couverture des affirmations ✅ du registre
Chaque affirmation ✅ automatisable est couverte par la preuve indiquee ci-dessus.
Les ✅ **structurelles/doctrinales** non rejouables par une commande (ex. AFF-005
`make`=aide, AFF-014 ciblage groupe, AFF-024 `instancier-appliquer`, AFF-051 autorite
d'AGENTS.md, AFF-073/075 gardes `make`, AFF-090 wiki) ont ete verifiees a l'audit ;
elles restent hors du harnais recurrent (rien d'executable a rejouer).
## Declarations d'intention (⚪ invérifiables localement — assumees)
Ces affirmations ne sont pas rejouables hors production ; elles sont **assumees**
comme declarations d'intention, non comme preuves :
- **AFF-036** — « testables avec `--check` autant que possible » : verifiable seulement
contre une flotte vivante.
- **AFF-091** — contenu pedagogique du wiki : affirmations conceptuelles.
- **AFF-096** — « GUI 100 % francais » : revue exhaustive des libelles rendus, non automatisee.
- **AFF-007** — hote d'exemple `web-frontal-01` : placeholder assume.
_Rapport genere le 2026-09-12._

View file

@ -1,5 +1,5 @@
--- ---
# Ecrit par `make wiki-publier`, lu par la preuve P60. Ne pas editer a la main. # Ecrit par `make wiki-publier`, lu par la preuve P60. Ne pas editer a la main.
remote: ssh://git@forge.genese.internal/genome/set-ops-public.wiki.git remote: ssh://git@forge.genese.internal/genome/set-ops-public.wiki.git
source: 989398f source: 904ece3
date: 2026-09-11 date: 2026-09-12

View file

@ -26,7 +26,7 @@ README de rôles). Cette page comble ces deux trous.
| rôles | 68 | `roles/*/` | | rôles | 68 | `roles/*/` |
| README de rôles | 68 | `roles/*/README.md` — l'écart avec la ligne au-dessus est la dette | | README de rôles | 68 | `roles/*/README.md` — l'écart avec la ligne au-dessus est la dette |
| documents | 40 | `docs/*.md` | | documents | 40 | `docs/*.md` |
| pièces d'audit | 42 | `docs/audit/*` | | pièces d'audit | 43 | `docs/audit/*` |
| unités de wiki | 27 | `wiki/*.md` | | unités de wiki | 27 | `wiki/*.md` |
| décisions en vigueur | 85 | lignes `\| **D-nn** \|` de `decisions-architecture.md` | | décisions en vigueur | 85 | lignes `\| **D-nn** \|` de `decisions-architecture.md` |
| décisions renversées | 3 | lignes `\| **D-nn** —` du même document | | décisions renversées | 3 | lignes `\| **D-nn** —` du même document |

View file

@ -25,9 +25,22 @@ listes de stockages et de ponts différentes. Un hébergeur décrit son matérie
## 2. Le plan d'adressage — la seule chose à respecter à la lettre ## 2. Le plan d'adressage — la seule chose à respecter à la lettre
**Un site dérive du même `index` que son tenant.** Il n'y a pas de second registre à **Un site prend son PROPRE `index`, comme un tenant.** Il n'y a pas de second registre à
tenir : le seul seed de tout l'adressage reste l'`index`, et l'underlay occupe la **bande tenir : le seul seed de tout l'adressage reste l'`index`, et **sites et tenants se
basse** du supernet — celle que la dérivation des tenants n'alloue jamais. partagent la même classe A** — chacun le sien, aucun partagé.
> **Corrigé le 2026-09-12.** Cette règle disait « un site dérive du même index que son
> tenant ». Conséquence mesurée chez l'hébergeur de référence : le plan d'administration
> du site vivait dans `10.17.0.0/24`, **à l'intérieur du supernet du locataire
> `OPS-Chezlepro`**. Ce n'était pas dangereux — les zones d'un tenant commencent à l'octet
> 16 par construction — mais `10.17.0.0/16` désignait alors deux choses : un locataire, et
> le plan d'administration de celui qui l'héberge. Deux sens pour une adresse.
>
> L'exception disparaît : **tout prend un index**. Le seul cas particulier restant serait
> qu'il n'y en ait plus, et l'octet en offre 256.
>
> `make instances` compte désormais les sites avec les tenants — un site et un locataire
> ne peuvent plus réclamer le même nombre sans que la garde le dise.
| Rôle | VLAN | Sous-réseau | MTU | Nature | | Rôle | VLAN | Sous-réseau | MTU | Nature |
|---|---|---|---|---| |---|---|---|---|---|

View file

@ -59,9 +59,48 @@ def _production(depot: Path) -> bool | None:
return None return None
def _sites() -> list[dict]:
"""Les depots de SITE et l'index qu'ils declarent dans leur underlay.
POURQUOI ILS ENTRENT DANS LE COMPTE (2026-09-12). Tant que les sites n'avaient pas
d'index, ils ne pouvaient heurter personne : leur adressage etait tape a la main,
hors de la derivation. L'exploitant a decide que SITES et OPS partagent la classe A,
chacun avec son propre index — un site et un locataire peuvent donc desormais
reclamer le meme nombre, et rien ne l'attrapait.
C'est une seconde liste qui suit une premiere. Sa garde s'ecrit le jour meme.
L'index d'un site vit dans son `underlay.yml`, pas dans une `nomenclature.yml` :
c'est la carte de son MATERIEL, et un site n'a pas de categories de zones a la
maniere d'un locataire. Un site sans `index:` declare reste invisible ici — il
n'entre dans le compte que le jour ou il en prend un.
"""
trouves = []
for chemin in sorted(FRERES.glob("SITE-*/underlay.yml")):
try:
d = (yaml.safe_load(chemin.read_text(encoding="utf-8")) or {}).get("underlay") or {}
except (OSError, yaml.YAMLError):
continue
if d.get("index") is None:
continue
trouves.append({"depot": chemin.parent, "index": d["index"]})
return trouves
def decouvrir() -> list[dict]: def decouvrir() -> list[dict]:
actif = _actif() actif = _actif()
instances = [] instances = []
for site in _sites():
instances.append({
"nom": site["depot"].name,
"index": site["index"],
"actif": False,
"federe": True, # un site partage la fabric qu'il fournit
"production": None,
"zones": [],
"vlans": None,
"site": True,
})
for chemin in sorted(FRERES.glob("*/plan/nomenclature.yml")): for chemin in sorted(FRERES.glob("*/plan/nomenclature.yml")):
try: try:
n = yaml.safe_load(chemin.read_text(encoding="utf-8")) or {} n = yaml.safe_load(chemin.read_text(encoding="utf-8")) or {}