Suppression de toute trace Chezlepro de l'outil (roles, scripts, docs
publiques, exemples, LICENSE). Prouve par scan exhaustif : git grep vide
pour chezlepro, asgard/TrueNAS, supernet reel 10.1.x.
Corrige 5 defauts de genericite fonctionnels (motd, app.ini Forgejo,
organisation openldap, nom AC step-ca, et IP reelles codees en dur dans
les defaults de roles -> plage d'exemple 10.0.x). LICENSE -> Alliance
Boreale. Fichiers mainteneur + CHANGELOG conserves (par decision).
La separation moteur/instance tient : OPS-Chezlepro surcharge deja ses
vraies valeurs de topologie. Verifie : make verifier exit 0 (4 tests).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
creer-vm HOTE=<hote> ne prend plus qu'un argument : il lit
VMID/IP/CIDR/passerelle/VLAN/stockage/disque/noeud dans l'inventaire
genere (nouvelle sous-commande inventory_host parametres-proxmox), comme
deployer lit ses groupes, et n'ecrit plus dans l'inventaire (plus de
hote-ajouter). Les 3 cibles legacy hote-ajouter/planifier/groupes sont
neutralisees (refus -> plan). Aide + docs alignees. Premier test stdlib
du depot + cible make test, cablee dans make verifier.
Verifie : make verifier exit 0 (4 tests), extraction testee sur
l'inventaire reel + chemins de refus. Clonage reel non execute (Proxmox).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Impératif (Fractal) : un sysadmin doit pouvoir exploiter Set-OPS sans
aucune IA. Grave a deux endroits car AGENTS.md/CLAUDE.md (fichiers du
mainteneur) ne font pas partie de l'outil livre :
- AGENTS.md, principe #10 : regle pour l'IA-mainteneur (ne jamais
introduire de fonctionnalite qui exige une IA pour s'en servir) ;
- README : face humaine, qui survit a la livraison sans les fichiers IA.
La doc / make / GUI sont l'interface primaire et complete ; l'IA
n'assiste que le mainteneur. Souverainete jusqu'au bout : ne pas
remplacer la dependance aux geants par une dependance a une IA.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Avant un test a froid par un sysadmin etranger, on corrige les blocages
d'accueil (mauvaises raisons d'echouer) :
- QUICKSTART.md : parcours lineaire zero -> ecosysteme deploye sur Proxmox
(modele -> instance -> config -> golden template -> instancier ->
cloner-vm -> deployer), honnete sur prerequis et seam creation-de-VM.
- README : reoriente "moteur generique pour un hebergeur" (plus "infra
Chezlepro"), pointeur QUICKSTART.
- Makefile : garde-fou _instance-requise (message utile + liste des
modeles si l'instance manque, au lieu d'un faux "valide" silencieux) ;
make aide route vers QUICKSTART.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cinq modeles d'ecosystemes prets a deployer, en plus de presence-web,
generes par un script pilote par spec :
- socle (4 VM) : DNS/PKI/edge/mail ;
- forge (6) : socle + Forgejo + PG ;
- identite (6) : socle + LDAP + Keycloak + PG ;
- observabilite (7) : socle + Prometheus/Loki/Grafana + Icinga ;
- integral (11) : tous les services implementes.
Chacun valide par generation : ecosysteme distinct, zero fuite Chezlepro,
verificateurs OK. collaboration (Nextcloud/Collabora) reste a construire.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
exemples/modeles/ : instances pretes a deployer (socle + modules + presets).
Un hebergeur copie un modele, le renseigne a ses couleurs, instancie.
Remplace le demonstrateur jetable.
Premier modele : presence-web (socle souverain DNS/PKI/edge/mail + web
frontal/dorsal + donnees PG/Redis, 7 VM). Valide par generation :
ecosysteme complet et distinct (10.10.x), zero fuite Chezlepro.
.ansible-lint exclut exemples/ ; hosts generes ignores.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Path.relative_to(RACINE) levait quand l'instance est externe
(SETOPS_INSTANCE = ../OPS-laPreuve par ex.). Remplace par os.path.relpath
dans instancier.py / inventory_gui.py / config_proxmox.py.
Revele par une instance d'essai agnostique (lapreuve.local, 10.9.0.0/16) :
le moteur genere un inventaire distinct, zero fuite Chezlepro. Cas normal
(OPS-Chezlepro via symlink) inchange : diff vide, lint 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rafraichir les chemins dans docs secondaires, README de roles, messages,
docstrings : inventories/ -> instance/inventories/, docs/<plan>.yml ->
instance/plan/<plan>.yml. Correction de chemins de playbooks perimes
(preexistants) dans CLAUDE.md/SOLUTION.md : vm_templates/..._prepare|
verify|cleanup -> modeles_vm/..._preparer|verifier|nettoyer, et
confirm_template_cleanup -> template_cleanup_confirm.
Valide : diff vide, ansible-lint 0 echec, make inventaire-verifier.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le contenu de instance/ part dans un depot d'instance dedie (OPS-Chezlepro).
Set-OPS devient le moteur pur (aucune donnee Chezlepro). L'instance est
montee via un symlink instance -> ../OPS-Chezlepro (gitignore) ; le defaut
SETOPS_INSTANCE=instance la resout sans config. Le moteur regenere
hosts.yml DANS le depot d'instance.
.ansible-lint exclut instance/. Valide : diff vide, ansible-lint 0 echec,
inventaire-verifier, instancier-appliquer. Modele A (freres) jusqu'a
preuve du concept ; modele B (sous-module) pour la meute ensuite.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Les fichiers geres par les roles (99-chezlepro.conf, chezlepro_filter,
chezlepro-bind.conf, /etc/redis/chezlepro.conf...) et les 14 templates
correspondants passent a la marque neutre du moteur 'setops' (git mv +
references src/dest). Un loup ne deploie plus de fichiers marques chezlepro.
Coherence src <-> template verifiee, ansible-lint 0 echec, diff vide,
syntax-check des playbooks de groupes OK. READMEs laisses (exemples).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Variable d'identite d'instance domaine_interne (group_vars/all.yml). Les
13 roles qui codaient chezlepro.internal en dur utilisent {{ domaine_interne }} ;
base_dn LDAP et domaine court derives (dc=acme,dc=local pour un autre loup).
Comportement identique pour Chezlepro (domaine_interne: chezlepro.internal),
mais le moteur devient generique -- premiere brique pour partager l'outil
a la meute. Ajout exemples/instance.exemple.yml.
Non destructif : diff de generation vide, ansible-lint 0 echec, base_dn
derive == ancien code en dur (verifie).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le depot vivait dans un dossier synchronise (Dropbox/Nextcloud) : la sync
a ressuscite d'anciens fichiers pluriels supprimes par le renommage au
singulier, et un git add -A les a recommittes. Retire :
- 6 group_vars pluriels (serveurs_*, clients_pki) ;
- 7 playbooks de groupes pluriels ;
- 1 'applications (conflicted copy ...).py'.
Les vrais fichiers au singulier existent tous. Valide : ansible-lint 0
echec, diff vide, inventaire-verifier, syntax-check de tous les playbooks.
La sync a ete desactivee pour le repertoire des depots (cause racine).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le coeur de Set-OPS (plan -> generation d'inventaire) recoupe NetBox ;
l'execution recoupe AWX/Semaphore ; « la definition instancie la flotte »
recoupe NixOS+Colmena/Terraform ; le modele application-pivot recoupe
Backstage.
Decision : garder le plan de controle maison (souverain, bien dimensionne
pour ~13 VM) mais GELER son perimetre ; seuils explicites d'adoption de
l'outil mur. Regle ancree dans AGENTS.md (« plan de controle gele »).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
serveurs_* -> serveur_, clients_ -> client_, suffixes pluriels au
singulier (serveur_web_dorsal/frontal, client_metrique, client_journal).
Renommage par tokens exacts : repertoires de roles, playbooks de groupes,
group_vars, variables internes des roles (serveur_nginx_*, conformite
ansible-lint), groupes du plan, constantes de code, docs. Faux-amis
preserves (serveurs_bd, scripts/serveurs.py, fonctions Python). Groupes
d'etat gardes au pluriel (hotes_actifs/planifies, modeles_vm).
Valide : ansible-lint 0 echec (0 var-naming), diff vide de la generation,
node --check, tous les registres. Ajout de .ansible-lint excluant docs/
(registres de donnees, pas du contenu Ansible).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- docs/plan-et-generation.md (nouveau) : guide central -- modele
(entites + liens), registres et schemas, reference make/CLI et vues
GUI, flux editer-le-plan -> instancier -> appliquer, garde-fous.
- AGENTS.md : section « Le plan et la generation de l'inventaire »
(regle d'or : hosts.yml est genere, ne pas l'editer).
- README.md : section plan + remplacement du flux legacy
hote-planifier/ajouter par le flux par le plan ; liste des registres.
- Rafraichissement architecture-set-ops.md, nomenclature-vm.md,
catalogue-services.md ; terminologie domaine -> fonction dans la prose.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Vue Serveurs editable : fonction/etat/placement/integrations, VMID/IP/VLAN
derives en direct, + Serveur, Sauvegarder (POST /api/serveurs) et
« Appliquer le plan » (POST /api/instancier -> instancier appliquer).
- API serveurs_reconcilies expose 'integrations'.
- Vue Inventaire en lecture seule : banniere + POST /api/inventaire refuse
(409) car hosts.yml est genere. Tout passe par le plan puis Appliquer.
Garde-fou node --check a chaque etape (corrige aussi un piege \n en raw
string). La bascule meta-classe est complete : on edite le plan, l'UI
genere l'inventaire.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ecrire_serveurs + POST /api/serveurs (valide via valider_serveurs +
nomenclature, ecrit docs/serveurs.yml).
- POST /api/instancier : lance scripts/instancier.py appliquer et renvoie
ok + sortie (regenere hosts.yml depuis le plan).
Permettra a la vue Serveurs d'editer le plan et a un bouton « Appliquer »
de regenerer l'inventaire.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
make instancier-appliquer regenere inventories/production/hosts.yml
depuis le plan (serveurs.yml + applications.yml + nomenclature.yml).
Garde-fou : refuse si le diff n'est pas vide (FORCE=1 pour un changement
intentionnel) ; git est le filet.
Bascule effectuee avec diff vide verifie. hosts.yml est desormais un
artefact genere, semantiquement identique a l'ancien (make
inventaire-verifier complet OK, GUI charge 13 hotes).
NOTE : a ce stade le GUI edite encore hosts.yml directement. Tant que le
rework GUI n'est pas fait, editer le PLAN puis make instancier-appliquer.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
make instancier genere hosts.genere.yml (gitignore) depuis le plan
(serveurs.yml + applications.yml + nomenclature.yml) et compare
SEMANTIQUEMENT a l'inventaire actuel via ansible-inventory --list.
- scripts/instancier.py : generer + comparer (host vars derives, groupes
derives = socle + services (applications) + integrations (clients_*) + etat).
- serveurs.py bootstrap capture les clients_* comme 'integrations' par VM.
- inventory_rules : valide 'integrations'.
Resultat : DIFF VIDE -- le plan reproduit exactement les 13 hotes. La
bascule (hosts.yml genere + UI editant le plan) reste NON effectuee :
elle attend une validation explicite.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
make applications-bootstrap : un groupe serveurs_* (hors socle debian/
durcis) sur un hote = une application. Les entrees existantes (pg-principal,
forge avec port/expose/requiert) sont preservees ; le reste est complete
depuis les appartenances de groupes de l'inventaire.
Resultat : 18 applications couvrant tous les services (multi-applis par VM
preservee : data-01 = postgresql+redis, obs-01 = grafana+loki+prometheus...).
Permettra au generateur de Phase 3 de deriver les groupes -> diff vide.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dessinerServeurs contenait une apostrophe mal echappee (l\\'inventaire)
qui, une fois rendue, terminait prematurement la chaine JS : une seule
erreur de syntaxe fait tomber tout le script -> page inutilisable.
Remplace par l'apostrophe typographique (sans echappement).
Garde-fou : scripts/verifier_gui.py extrait le JS embarque et le passe a
`node --check` (saute si node absent), integre a make inventaire-verifier.
py_compile ne voyait pas le JS ; ce trou est desormais ferme.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
La vue Chaine de make inventaire-ui montre, par application, l'ensemble
de ses liens (expose, requiert, bases/DSN, port) : on voit comment VM,
applications, bases et domaines s'articulent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Leve la collision de nom entre les familles fonctionnelles de la
nomenclature (infra-pki, web-frontal...) et les domaines DNS.
- docs/nomenclature.yml : cle domaines -> fonctions (+ commentaires).
- inventory_gui.py : domaineDe/infoDomaine -> fonctionDe/infoFonction,
nomenclature.fonctions, libelles et placeholder alignes.
- inventory_rules.py : docstring.
Aucun role ni inventaire impacte (nomenclature lue a la planification).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
L'application porte tous ses liens (groupe=capacite, hote=VM, port,
requiert, expose). L'exposition DNS quitte docs/domaines.yml et vit sur
l'application via 'expose' ; domaines.yml ne decrit plus que les zones.
- inventory_rules : expositions_des_applications + domaine_parent ;
valider_applications valide requiert / expose / port.
- serveurs_nginx derive ses vhosts des applications (expose + edge),
resolvant application -> hote -> IP (role + template reecrits).
- filter plugin : expose la nouvelle regle a Ansible.
- CLI : applications.py --port/--requiert/--expose ; domaines.py affiche
les expositions derivees des applications.
- GUI : champs Port/Requiert/Expose sur la fiche Application (persistes ;
corrige la perte de champs a la sauvegarde) ; l'API expose les domaines.
Le groupe n'est plus une cible de liaison, seulement une capacite.
Renommage nomenclature.domaines -> fonctions : Phase 1b. Generation de
l'inventaire depuis le plan : Phase 3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Une VM peut porter plusieurs applications ; c'est l'application, pas l'hote,
a laquelle une base se lie via son DSN.
- docs/applications.yml : nouveau registre application -> groupe, hote.
- docs/bases-donnees.yml : champ 'portee' (application|groupe|hote, defaut
groupe). Une application A (groupe G, hote H) recoit les bases ou
(portee=application ET consommateur=A) OU (portee=groupe ET consommateur=G)
OU (portee=hote ET consommateur=H). Plusieurs DSN par application.
- inventory_rules.py : charger/valider_applications, applications_de_hote,
bases_de_application, PORTEES_BD ; valider_bases croise portee=application
avec le registre des applications.
- CLI : scripts/applications.py + bases_donnees.py --portee ; cibles make
applications / applications-verifier ; integre a inventaire-verifier.
- GUI : vue Applications (CRUD), portee + consommateur dynamique dans Bases,
vue Chaine par application (DSN resolus par hote).
- filter_plugins/registres.py : meme regle de resolution exposee a Ansible
(source unique). Playbooks web_dorsaux/web_frontaux iterent sur les
applications de l'hote (scaffold ; deploiement applicatif s'y insere).
Services en grappe (keycloak/icingadb/forgejo) restent en portee groupe.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
serveurs_nginx derive ses vhosts de docs/domaines.yml (bloc exposition) :
pour chaque exposition web ciblant cet edge, un server block est genere
(expositions.conf.j2). Amont = entree 'amont' explicite, sinon
http://<IP interne de la cible>:<port> resolu depuis l'inventaire. Une
exposition non resolvable (cible sans hote actif, ou sans port) est listee
mais non publiee.
- defaults : serveurs_nginx_groupe (edge cible), serveurs_nginx_publier_expositions.
- Les sites declares a la main coexistent.
- Ajout du port 3000 a l'exposition forge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Registre declaratif docs/domaines.yml pour la publication externe des
hostnames, symetrique de docs/bases-donnees.yml. Modele d'autorite :
primaire cache + secondaires. Le bloc « exposition » est le binding
nom public -> service interne (cible) -> edge, destine a trois
consommateurs (zone publique, vhosts nginx, ACME).
- inventory_rules.py : charger_domaines, valider_domaines,
fqdn_exposition, expositions_du_groupe, AUTORITES_DNS.
- scripts/domaines.py : CLI miroir (lister / verifier).
- Makefile : cibles domaines / domaines-verifier + validation dans
inventaire-verifier.
Premiere entree reelle : forge.alliance-boreale.ca -> serveurs_forgejo.
Secondaires, mail et DNSSEC laisses a renseigner (structurel, pas
encore operationnel ; l'interne chezlepro.internal n'est pas touche).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Acter dans les docs d'autorite que Set-OPS ne se limite plus a
l'exploitation mais definit et construit l'ecosysteme numerique
souverain de Chezlepro Inc.
- AGENTS.md : nouvelle section « Mission et identite » (piliers,
proprietes visees, nuances honnetes : pas auto-repare, defini avant
deploiement, registres = source unique).
- README.md : section « Mission » + « Domaines prevus » rationalise en
« Portee transverse » (retire ce que les piliers couvrent deja).
- CHANGELOG.md : entree du 2026-06-22.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Modele:
- Chaque base porte un "consommateur" (le groupe applicatif qui l'utilise) et un
"usage" (principale/cache...). Une application peut avoir plusieurs bases.
- Le binding appli<->base n'est plus une convention de nom mais un champ gere.
Regles partagees (inventory_rules): consommateur requis a la validation;
helper bases_du_groupe(registre, groupe).
GUI (make inventaire-ui):
- Vue "Bases": menu deroulant Consommateur + champ Usage par base -> on fait les
connexions ici; plusieurs bases par appli supportees.
- Vue "Chaine" detaillee: chaque groupe affiche ses roles ET ses bases avec leur
chaine de connexion (appli -> base -> serveur de BD -> hote).
CLI (bases_donnees.py): ajouter-base --consommateur --usage; lister affiche
"base <- consommateur (usage): DSN".
Roles serveurs_keycloak / serveurs_forgejo / serveurs_icinga: resolution de leur
base par consommateur (groupe), plus de cle codee en dur.
Valide: ansible-lint (roles), node --check (JS), round-trips GUI et CLI,
multi-BD verifie (serveurs_web_dorsaux -> 2 bases), make inventaire-verifier.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Registre multi-serveurs (docs/bases-donnees.yml):
- Section serveurs_bd: serveurs de BD nommes (type/hote/port/groupe).
- Chaque base reference un serveur nomme; la chaine de connexion derivee fait
le lien appli <-> BD. L'hote n'est plus code en dur dans les roles applicatifs.
Regles partagees (scripts/inventory_rules.py):
- charger_bases_donnees, valider_bases, chaine_connexion (GUI et CLI s'appuient dessus).
GUI (make inventaire-ui):
- Vue "Bases": serveurs, bases et chaines de connexion (mot de passe masque),
gestion complete (ajout/edition/retrait), endpoint POST /api/bases (valide, jeton).
CLI (scripts/bases_donnees.py):
- lister/verifier/ajouter-serveur/ajouter-base/retirer-*; cibles make bases et
bases-verifier; registre valide dans make inventaire-verifier.
Roles migres: serveurs_postgresql (filtre par serveur nomme relie a son groupe),
serveurs_keycloak / serveurs_forgejo / serveurs_icinga (hote et port depuis le registre).
Valide: ansible-lint (roles migres), node --check (JS), round-trips GUI et CLI.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>