Trouve en validant une mise a jour du CHANGELOG. Deux invocations de la meme preuve,
deux verdicts : `make prouver` -> NON CONFORME (« lab : 17 hotes avec ecart »),
`python3 scripts/prouver.py` -> CONFORME 37/37. Le lab n'avait aucun ecart.
DEUX VARIABLES DESIGNENT LA CIBLE, ET LA SECONDE GAGNE. Le Makefile exporte
SETOPS_INVENTAIRE (ligne 13), derive de l'instance ACTIVE ; instancier.py:68 lui fait
FORCER la cible par-dessus SETOPS_INSTANCE. P03 (prouver.py:505) ne redirigeait que
SETOPS_INSTANCE : elle generait le plan de CHAQUE instance federee et le comparait a
l'inventaire applique de la SEULE instance active.
LE ROUGE N'ETAIT PAS LE PROBLEME, LE VERT L'ETAIT. Sous `make`, l'inventaire applique
de lab et de Technolibre n'etait JAMAIS lu — l'angle meme pour lequel P03 a ete ecrite
le 2026-08-12 (un tenant qu'on ne regarde pas imposant ses vieilles adresses au pare-feu
partage). La preuve etait aveugle a son propre cas, par l'invocation documentee. Les
rapports du 13 et du 14 sortent de cette invocation-la. Signature visible sans lire le
code : les hosts.genere.yml de lab et de Technolibre ne bougeaient pas.
CORRECTIF, cinq sites : env.pop("SETOPS_INVENTAIRE") partout ou l'on redirige
SETOPS_INSTANCE — P03 et P15, plus les trois applicateurs (opnsense, proxmox_fw, sdn) qui
pointent vers l'HEBERGEUR. Ces trois sont sans effet tant qu'hebergeur et tenant actif
coincident, c'est-a-dire jusqu'au second site. Le geste existait deja (modeles.py:96).
GARDE, pour que la classe cesse d'etre silencieuse : inventory_rules.inventaire_force()
REFUSE une cible hors de l'instance visee, en nommant les deux valeurs. Eprouvee dans les
deux sens (contradiction -> code 1 ; cible legitime dans l'instance -> passe). Branchee
sur les quatre resolutions de _inventaire (instancier, serveurs, applications,
config_proxmox). Le GUI garde la sienne : il ne redirige jamais SETOPS_INSTANCE pour un
fils et resout par symlink a chaque requete.
make prouver : 37 OK, 0 echec, 0 saute — et les hosts.genere.yml des TROIS instances
portent l'horodatage du passage. make test 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Reconcilie les trois couches du devis : 26 IPSets, 36 groupes, affectations aux
VM. Cree, met a jour, retire — meme contrat que les applicateurs de la frontiere
et du SDN.
Il n'active JAMAIS le pare-feu du datacenter : ce reglage vaut pour toutes les
VM du cluster, y compris les 37 heritees sans regle, et le basculer couperait le
parc. L'ecart est signale a chaque execution ; la decision reste humaine.
Les 28 VM du devis n'existent pas encore : listees comme differees, pas comme
erreurs. Les objets poses sont donc inertes, ce qui rend l'application sure.
`scripts/proxmox_api.py` extrait ce que les deux applicateurs Proxmox partagent,
en particulier la recomposition du jeton dont la voute ne porte que le nom.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deuxieme applicateur du depot, meme contrat que celui de la frontiere. Deux
cibles : les objets de cluster par l'API Proxmox, la sortie du VRF par SSH —
`/etc/frr/frr.conf.local` n'est expose par aucune API.
Perimetre strict : seules les zones du devis et les anciens nommages listes sont
touches ; une zone inconnue est signalee et laissee intacte. Un VNet encore
branche a une VM est refuse, avec le nom des machines. L'ordre suit les
dependances : sous-reseaux, VNets, zones.
`devis_sdn.strophe_frr()` est la source unique : le devis l'affiche,
l'applicateur la compare au fichier distant.
Defaut trouve a la premiere execution : la lecture sans `sudo` echouait, un
`|| true` masquait l'echec, et un fichier present etait declare absent puis
reecrit. Trois etats distingues desormais : absent, illisible, different.
Rejeu a vide, six VRF avec leur defaut, sortie tenant fonctionnelle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>