2026-06-21 20:35:03 -04:00
#!/usr/bin/env python3
""" Interface web locale pour gerer un inventaire Set-OPS. """
from __future__ import annotations
from http . server import BaseHTTPRequestHandler , ThreadingHTTPServer
import argparse
import json
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
import os
import re
import secrets
import subprocess
import tempfile
import threading
2026-06-21 20:35:03 -04:00
from pathlib import Path
from urllib . parse import urlparse
import yaml
2026-06-21 20:47:44 -04:00
from inventory_rules import (
GROUPE_HOTES_ACTIFS ,
GROUPE_HOTES_PLANIFIES ,
GROUPES_ETAT_HOTE ,
2026-06-22 19:14:12 -04:00
chaine_connexion ,
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
charger_applications ,
2026-06-22 19:14:12 -04:00
charger_bases_donnees ,
2026-06-21 21:31:03 -04:00
charger_dependances ,
2026-06-23 20:10:15 -04:00
charger_domaines ,
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
charger_nomenclature ,
2026-06-23 20:44:08 -04:00
charger_serveurs ,
2026-06-21 20:47:44 -04:00
est_groupe_operationnel ,
groupes_operationnels_connus ,
2026-06-23 20:44:08 -04:00
reconcilier_serveur ,
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
valider_applications ,
2026-06-22 19:14:12 -04:00
valider_bases ,
2026-06-23 22:04:01 -04:00
valider_serveurs ,
2026-06-21 20:47:44 -04:00
)
2026-06-21 20:35:03 -04:00
RACINE = Path ( __file__ ) . resolve ( ) . parents [ 1 ]
2026-06-24 09:10:49 -04:00
INSTANCE = Path ( os . environ . get ( " SETOPS_INSTANCE " ) or ( RACINE / " instance " ) )
2026-06-24 09:16:18 -04:00
INVENTAIRE_DEFAUT = INSTANCE / " inventories/production/hosts.yml "
INVENTAIRE_PRODUCTION = ( INSTANCE / " inventories/production/hosts.yml " ) . resolve ( )
2026-06-21 20:35:03 -04:00
DOSSIER_PLAYBOOKS_GROUPES = RACINE / " playbooks/groupes "
2026-06-21 21:31:03 -04:00
FICHIER_DEPENDANCES = RACINE / " docs/dependances-groupes.yml "
2026-06-24 09:10:49 -04:00
FICHIER_NOMENCLATURE = INSTANCE / " plan/nomenclature.yml "
FICHIER_BASES = INSTANCE / " plan/bases-donnees.yml "
FICHIER_APPLICATIONS = INSTANCE / " plan/applications.yml "
FICHIER_DOMAINES = INSTANCE / " plan/domaines.yml "
FICHIER_SERVEURS = INSTANCE / " plan/serveurs.yml "
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
# Garde-fous des executions (verifier / deployer) depuis l'interface.
JETON = secrets . token_urlsafe ( 18 )
VERROU = threading . Lock ( )
VERIF_OK : dict [ str , bool ] = { }
MOTIF_HOTE = re . compile ( r " ^[A-Za-z0-9._-] { 1,63}$ " )
# Champs de provisioning persistes comme variables d'hote dans l'inventaire.
# (cle_gui, variable_inventaire, type)
CHAMPS_PROVISION = [
( " adresse_ip " , " ansible_host " , " str " ) ,
( " utilisateur_ansible " , " ansible_user " , " str " ) ,
( " cidr " , " proxmox_cidr " , " int " ) ,
( " passerelle " , " proxmox_passerelle " , " str " ) ,
( " vlan " , " proxmox_vlan " , " int " ) ,
( " pont " , " proxmox_pont " , " str " ) ,
( " dns " , " proxmox_dns " , " str " ) ,
( " vmid " , " proxmox_vmid " , " int " ) ,
( " noeud " , " proxmox_noeud " , " str " ) ,
( " stockage " , " proxmox_stockage " , " str " ) ,
( " disque_taille " , " proxmox_disque_taille " , " str " ) ,
( " memoire " , " proxmox_memoire " , " int " ) ,
( " coeurs " , " proxmox_coeurs " , " int " ) ,
]
2026-06-21 20:35:03 -04:00
def charger_yaml ( path : Path ) - > dict :
if not path . exists ( ) :
return { " all " : { " children " : { } } }
with path . open ( " r " , encoding = " utf-8 " ) as fichier :
data = yaml . safe_load ( fichier ) or { }
if not isinstance ( data , dict ) :
raise ValueError ( f " { path } ne contient pas une table YAML. " )
data . setdefault ( " all " , { } )
data [ " all " ] . setdefault ( " children " , { } )
return data
def ecrire_yaml ( path : Path , data : dict ) - > None :
with path . open ( " w " , encoding = " utf-8 " ) as fichier :
yaml . safe_dump ( data , fichier , default_flow_style = False , sort_keys = False , allow_unicode = True )
def enfants ( data : dict ) - > dict :
return data . setdefault ( " all " , { } ) . setdefault ( " children " , { } )
def groupes_disponibles ( data : dict ) - > list [ str ] :
2026-06-21 20:47:44 -04:00
return groupes_operationnels_connus ( enfants ( data ) , DOSSIER_PLAYBOOKS_GROUPES )
2026-06-21 20:35:03 -04:00
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
def roles_des_groupes ( ) - > dict :
""" Pour chaque playbook de groupe, extrait les roles appliques (chaine groupe -> roles). """
resultat : dict = { }
for chemin in sorted ( DOSSIER_PLAYBOOKS_GROUPES . glob ( " *.yml " ) ) :
roles : list [ str ] = [ ]
try :
with chemin . open ( " r " , encoding = " utf-8 " ) as fichier :
docs = yaml . safe_load ( fichier ) or [ ]
plays = docs if isinstance ( docs , list ) else [ docs ]
for play in plays :
if not isinstance ( play , dict ) :
continue
for role in play . get ( " roles " , [ ] ) or [ ] :
if isinstance ( role , str ) :
roles . append ( role )
elif isinstance ( role , dict ) :
nom = role . get ( " role " ) or role . get ( " name " )
if nom :
roles . append ( str ( nom ) )
except ( OSError , yaml . YAMLError ) :
pass
resultat [ chemin . stem ] = { " roles " : roles , " stub " : not roles }
return resultat
def hotes_actifs_fichier ( path : Path ) - > set [ str ] :
data = charger_yaml ( path )
return set ( enfants ( data ) . get ( GROUPE_HOTES_ACTIFS , { } ) . get ( " hosts " , { } ) or { } )
2026-06-21 20:35:03 -04:00
def variables_hote ( data : dict , hote : str ) - > dict :
resultat : dict = { }
for groupe_data in enfants ( data ) . values ( ) :
hosts = groupe_data . get ( " hosts " , { } )
valeurs = hosts . get ( hote )
if isinstance ( valeurs , dict ) :
resultat . update ( valeurs )
return resultat
def liste_hotes ( data : dict ) - > list [ dict ] :
noms = set ( )
for groupe_data in enfants ( data ) . values ( ) :
noms . update ( groupe_data . get ( " hosts " , { } ) )
hotes = [ ]
for nom in sorted ( noms ) :
groupes = [ ]
etat = " planifie "
2026-06-21 20:47:44 -04:00
visible = False
2026-06-21 20:35:03 -04:00
for groupe , groupe_data in enfants ( data ) . items ( ) :
if nom not in groupe_data . get ( " hosts " , { } ) :
continue
2026-06-21 20:47:44 -04:00
if groupe == GROUPE_HOTES_ACTIFS :
2026-06-21 20:35:03 -04:00
etat = " actif "
2026-06-21 20:47:44 -04:00
visible = True
elif groupe in GROUPES_ETAT_HOTE :
visible = True
2026-06-21 20:35:03 -04:00
continue
2026-06-21 20:47:44 -04:00
elif est_groupe_operationnel ( groupe ) :
2026-06-21 20:35:03 -04:00
groupes . append ( groupe )
2026-06-21 20:47:44 -04:00
visible = True
if not visible :
continue
2026-06-21 20:35:03 -04:00
variables = variables_hote ( data , nom )
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
hote = { " nom " : nom , " etat " : etat , " groupes " : sorted ( groupes ) }
for cle , var , _type in CHAMPS_PROVISION :
valeur = variables . get ( var , " " )
hote [ cle ] = " " if valeur is None else valeur
if not str ( hote . get ( " utilisateur_ansible " , " " ) ) . strip ( ) :
hote [ " utilisateur_ansible " ] = " ansible "
hotes . append ( hote )
2026-06-21 20:35:03 -04:00
return hotes
2026-06-23 20:44:08 -04:00
def serveurs_reconcilies ( data : dict ) - > list :
""" Serveurs du plan + valeurs derivees + statut de reconciliation (lecture). """
registre = charger_serveurs ( FICHIER_SERVEURS )
nomenclature = charger_nomenclature ( FICHIER_NOMENCLATURE )
hotes = { h [ " nom " ] : h for h in liste_hotes ( data ) if h . get ( " nom " ) }
resultat = [ ]
for nom , srv in ( registre . get ( " serveurs " ) or { } ) . items ( ) :
rec = reconcilier_serveur ( nom , srv , hotes . get ( nom ) , nomenclature )
d = rec [ " derive " ]
statut = " absent " if rec [ " absent_inventaire " ] else ( " divergence " if rec [ " divergences " ] else " reconcilie " )
resultat . append ( {
" nom " : nom , " fonction " : srv . get ( " fonction " , " " ) , " etat " : srv . get ( " etat " , " " ) ,
" noeud " : srv . get ( " noeud " , " " ) , " stockage " : srv . get ( " stockage " , " " ) ,
" disque " : srv . get ( " disque " , " " ) , " memoire " : srv . get ( " memoire " , " " ) , " coeurs " : srv . get ( " coeurs " , " " ) ,
2026-06-23 22:23:36 -04:00
" integrations " : srv . get ( " integrations " , [ ] ) ,
2026-06-23 20:44:08 -04:00
" vmid " : d . get ( " vmid " , " " ) , " adresse_ip " : d . get ( " adresse_ip " , " " ) , " vlan " : d . get ( " vlan " , " " ) ,
" statut " : statut , " divergences " : rec [ " divergences " ] ,
} )
return resultat
2026-06-21 20:35:03 -04:00
def inventaire_api ( path : Path ) - > dict :
data = charger_yaml ( path )
2026-06-21 21:31:03 -04:00
dependencies = charger_dependances ( FICHIER_DEPENDANCES )
2026-06-21 20:35:03 -04:00
return {
2026-06-24 10:12:03 -04:00
" inventaire " : os . path . relpath ( path , RACINE ) ,
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
" production " : path . resolve ( ) == INVENTAIRE_PRODUCTION ,
2026-06-21 20:35:03 -04:00
" groupes " : groupes_disponibles ( data ) ,
2026-06-21 21:31:03 -04:00
" dependances " : dependencies ,
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
" nomenclature " : charger_nomenclature ( FICHIER_NOMENCLATURE ) ,
" chaine " : roles_des_groupes ( ) ,
2026-06-22 19:14:12 -04:00
" bases " : charger_bases_donnees ( FICHIER_BASES ) ,
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
" applications " : charger_applications ( FICHIER_APPLICATIONS ) ,
2026-06-23 20:10:15 -04:00
" domaines " : charger_domaines ( FICHIER_DOMAINES ) ,
2026-06-23 20:44:08 -04:00
" serveurs " : serveurs_reconcilies ( data ) ,
2026-06-21 20:35:03 -04:00
" hotes " : liste_hotes ( data ) ,
}
2026-06-22 19:14:12 -04:00
def ecrire_bases ( path : Path , registre : dict ) - > None :
entete = (
" # Registre des bases de donnees Set-OPS (serveurs_bd + bases_donnees). \n "
" # Edite par make inventaire-ui ou scripts/bases_donnees.py. \n "
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
" # ' portee ' (application|groupe|hote) interprete ' consommateur ' ; defaut groupe. \n "
" # ' secret ' nomme une variable Ansible Vault (jamais le mot de passe). \n "
2026-06-22 19:14:12 -04:00
" --- \n "
)
contenu = {
" serveurs_bd " : registre . get ( " serveurs_bd " , { } ) or { } ,
" bases_donnees " : registre . get ( " bases_donnees " , { } ) or { } ,
}
with path . open ( " w " , encoding = " utf-8 " ) as fichier :
fichier . write ( entete )
yaml . safe_dump ( contenu , fichier , default_flow_style = False , sort_keys = False , allow_unicode = True )
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
def ecrire_applications ( path : Path , registre : dict ) - > None :
entete = (
" # Registre des applications Set-OPS (application = entite pivot). \n "
" # Edite par make inventaire-ui ou scripts/applications.py. \n "
" # Une VM peut porter plusieurs applications ; une base se lie a une application. \n "
" --- \n "
)
with path . open ( " w " , encoding = " utf-8 " ) as fichier :
fichier . write ( entete )
yaml . safe_dump ( { " applications " : registre . get ( " applications " , { } ) or { } } ,
fichier , default_flow_style = False , sort_keys = False , allow_unicode = True )
2026-06-23 22:04:01 -04:00
def ecrire_serveurs ( path : Path , registre : dict ) - > None :
entete = (
" # Registre des serveurs (VM) du plan Set-OPS. \n "
" # Edite par make inventaire-ui ou scripts/serveurs.py. \n "
2026-06-24 10:04:14 -04:00
" # VMID/IP/VLAN/passerelle sont DERIVES de la fonction via instance/plan/nomenclature.yml. \n "
2026-06-23 22:04:01 -04:00
" --- \n "
)
with path . open ( " w " , encoding = " utf-8 " ) as fichier :
fichier . write ( entete )
yaml . safe_dump ( { " serveurs " : registre . get ( " serveurs " , { } ) or { } } ,
fichier , default_flow_style = False , sort_keys = False , allow_unicode = True )
2026-06-21 20:35:03 -04:00
def donnees_hote ( hote : dict ) - > dict :
variables : dict = { }
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
for cle , var , typ in CHAMPS_PROVISION :
brut = str ( hote . get ( cle , " " ) ) . strip ( )
if not brut :
continue
if typ == " int " and brut . lstrip ( " - " ) . isdigit ( ) :
variables [ var ] = int ( brut )
else :
variables [ var ] = brut
2026-06-21 20:35:03 -04:00
return variables
def construire_inventaire ( payload : dict , groupes_connus : list [ str ] ) - > dict :
enfants_data : dict = {
" modeles_vm " : { " hosts " : { } } ,
2026-06-21 20:47:44 -04:00
GROUPE_HOTES_ACTIFS : { " hosts " : { } } ,
GROUPE_HOTES_PLANIFIES : { " hosts " : { } } ,
2026-06-21 20:35:03 -04:00
}
for groupe in groupes_connus :
enfants_data . setdefault ( groupe , { " hosts " : { } } )
enfants_data . setdefault ( " hotes_proxmox " , { " hosts " : { } } )
for hote in payload . get ( " hotes " , [ ] ) :
nom = str ( hote . get ( " nom " , " " ) ) . strip ( )
if not nom :
continue
variables = donnees_hote ( hote )
2026-06-21 20:47:44 -04:00
groupe_etat = GROUPE_HOTES_ACTIFS if hote . get ( " etat " ) == " actif " else GROUPE_HOTES_PLANIFIES
2026-06-21 20:35:03 -04:00
enfants_data [ groupe_etat ] [ " hosts " ] [ nom ] = variables
for groupe in hote . get ( " groupes " , [ ] ) :
if groupe not in groupes_connus :
continue
enfants_data [ groupe ] [ " hosts " ] [ nom ] = { }
return { " all " : { " children " : enfants_data } }
2026-06-21 21:31:03 -04:00
def valider_dependances_payload ( payload : dict , dependencies : dict ) - > None :
hotes = payload . get ( " hotes " , [ ] )
active_groups : set [ str ] = set ( )
for hote in hotes :
if hote . get ( " etat " ) != " actif " :
continue
active_groups . update ( hote . get ( " groupes " , [ ] ) )
missing : list [ str ] = [ ]
for hote in hotes :
if hote . get ( " etat " ) != " actif " :
continue
nom = str ( hote . get ( " nom " , " " ) ) . strip ( )
for groupe in hote . get ( " groupes " , [ ] ) :
for required_group in dependencies . get ( groupe , { } ) . get ( " requiert_groupes_actifs " , [ ] ) :
if required_group not in active_groups :
missing . append ( f " { nom } : { groupe } requiert { required_group } actif " )
if missing :
raise ValueError ( " Dependances manquantes: " + " ; " . join ( missing ) )
def valider_payload ( payload : dict , groupes_connus : list [ str ] , dependencies : dict ) - > None :
2026-06-21 20:35:03 -04:00
noms : set [ str ] = set ( )
2026-06-21 20:47:44 -04:00
vmids : dict [ str , str ] = { }
2026-06-21 20:35:03 -04:00
for hote in payload . get ( " hotes " , [ ] ) :
nom = str ( hote . get ( " nom " , " " ) ) . strip ( )
if not nom :
raise ValueError ( " Un hote a un nom vide. " )
if nom in noms :
raise ValueError ( f " Hote en double: { nom } " )
noms . add ( nom )
2026-06-21 20:47:44 -04:00
if hote . get ( " etat " ) == " actif " and not str ( hote . get ( " adresse_ip " , " " ) ) . strip ( ) :
raise ValueError ( f " Hote actif sans adresse IP: { nom } " )
2026-06-21 20:35:03 -04:00
groupes = hote . get ( " groupes " , [ ] )
if not groupes :
raise ValueError ( f " Aucun groupe operationnel pour: { nom } " )
inconnus = sorted ( set ( groupes ) - set ( groupes_connus ) )
if inconnus :
raise ValueError ( f " Groupes inconnus pour { nom } : { ' , ' . join ( inconnus ) } " )
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
vlan = str ( hote . get ( " vlan " , " " ) ) . strip ( )
if vlan and ( not vlan . isdigit ( ) or not 1 < = int ( vlan ) < = 4094 ) :
raise ValueError ( f " VLAN invalide pour { nom } : { vlan } (attendu 1-4094) " )
cidr = str ( hote . get ( " cidr " , " " ) ) . strip ( )
if cidr and ( not cidr . isdigit ( ) or not 0 < = int ( cidr ) < = 32 ) :
raise ValueError ( f " CIDR invalide pour { nom } : { cidr } (attendu 0-32) " )
for cle , libelle in ( ( " memoire " , " Memoire " ) , ( " coeurs " , " Coeurs " ) ) :
valeur = str ( hote . get ( cle , " " ) ) . strip ( )
if valeur and ( not valeur . isdigit ( ) or int ( valeur ) < = 0 ) :
raise ValueError ( f " { libelle } invalide pour { nom } : { valeur } (entier positif attendu) " )
2026-06-21 20:47:44 -04:00
vmid = str ( hote . get ( " vmid " , " " ) ) . strip ( )
if not vmid :
continue
if vmid in vmids :
raise ValueError ( f " VMID en double: { vmid } pour { vmids [ vmid ] } et { nom } " )
vmids [ vmid ] = nom
2026-06-21 20:35:03 -04:00
2026-06-21 21:31:03 -04:00
valider_dependances_payload ( payload , dependencies )
2026-06-21 20:35:03 -04:00
HTML = r """ <!doctype html>
< html lang = " fr " >
< head >
< meta charset = " utf-8 " >
< meta name = " viewport " content = " width=device-width, initial-scale=1 " >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< title > Set - OPS · Votre artisan numérique < / title >
2026-06-21 20:35:03 -04:00
< style >
2026-06-21 21:40:45 -04:00
: root {
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
color - scheme : dark ;
- - fond : #0c1119;
- - fond - degrade : radial - gradient ( 1100 px 540 px at 100 % - 8 % , #142033 0, transparent 55%), var(--fond);
- - surface : #151d2b;
- - surface - 2 : #1a2333;
- - surface - 3 : #212d41;
- - texte : #e8edf6;
- - muted : #93a1bb;
- - faint : #67738c;
- - ligne : #27324a;
- - ligne - forte : #36445f;
- - primaire : #3b82f6;
- - primaire - fort : #2f6fe0;
- - teal : #2dd4bf;
- - vert : #34d399; --vert-fond:rgba(52,211,153,.13);
- - bleu : #60a5fa; --bleu-fond:rgba(96,165,250,.13);
- - rouge : #f87171; --rouge-fond:rgba(248,113,113,.13);
- - ambre : #fbbf24; --ambre-fond:rgba(251,191,36,.13);
- - ombre : 0 1 px 2 px rgba ( 0 , 0 , 0 , .35 ) , 0 10 px 30 px - 14 px rgba ( 0 , 0 , 0 , .7 ) ;
- - ombre - forte : 0 18 px 50 px - 18 px rgba ( 0 , 0 , 0 , .8 ) ;
- - rayon : 11 px ; - - rayon - sm : 8 px ;
2026-06-21 21:40:45 -04:00
}
2026-06-21 20:35:03 -04:00
* { box - sizing : border - box ; }
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
body {
margin : 0 ; background : var ( - - fond - degrade ) ; color : var ( - - texte ) ; min - height : 100 vh ;
font - family : ui - sans - serif , system - ui , - apple - system , " Segoe UI " , Roboto , sans - serif ;
font - size : 14 px ; line - height : 1.5 ; - webkit - font - smoothing : antialiased ;
}
: : selection { background : color - mix ( in srgb , var ( - - teal ) 35 % , transparent ) ; }
* { scrollbar - width : thin ; scrollbar - color : var ( - - ligne - forte ) transparent ; }
header {
position : sticky ; top : 0 ; z - index : 20 ;
display : flex ; align - items : center ; gap : 16 px ; flex - wrap : wrap ;
padding : 12 px 22 px ; border - bottom : 1 px solid var ( - - ligne ) ;
background : color - mix ( in srgb , var ( - - surface ) 82 % , transparent ) ;
backdrop - filter : saturate ( 150 % ) blur ( 12 px ) ;
2026-06-21 21:40:45 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
. marque { display : flex ; align - items : center ; gap : 9 px ; min - width : 0 ; }
. marque . pastille { width : 9 px ; height : 9 px ; border - radius : 50 % ; background : var ( - - teal ) ; box - shadow : 0 0 0 4 px color - mix ( in srgb , var ( - - teal ) 18 % , transparent ) ; flex : none ; }
. marque . titre { display : flex ; flex - direction : column ; line - height : 1.15 ; min - width : 0 ; }
h1 { margin : 0 ; font - size : 15 px ; font - weight : 800 ; letter - spacing : - .01 em ; white - space : nowrap ; }
. slogan { font - size : 10.5 px ; color : var ( - - muted ) ; font - weight : 600 ; letter - spacing : .02 em ; white - space : nowrap ; }
. chemin { color : var ( - - muted ) ; font - size : 12 px ; font - family : ui - monospace , SFMono - Regular , Menlo , monospace ; white - space : nowrap ; overflow : hidden ; text - overflow : ellipsis ; }
. grandit { flex : 1 1 auto ; min - width : 0 ; }
. resume { display : flex ; gap : 6 px ; flex - wrap : wrap ; }
. chip { display : inline - flex ; align - items : center ; gap : 6 px ; border : 1 px solid var ( - - ligne ) ; border - radius : 999 px ; padding : 3 px 10 px ; background : var ( - - surface - 2 ) ; color : var ( - - muted ) ; font - size : 11.5 px ; font - weight : 650 ; }
. chip b { color : var ( - - texte ) ; font - weight : 800 ; }
. pt { width : 7 px ; height : 7 px ; border - radius : 50 % ; flex : none ; }
. pt . actif { background : var ( - - vert ) ; } . pt . plan { background : var ( - - bleu ) ; } . pt . bloq { background : var ( - - rouge ) ; }
. barre { display : flex ; gap : 8 px ; align - items : center ; flex - wrap : wrap ; }
. recherche { position : relative ; }
. recherche input { padding - left : 30 px ; min - width : 180 px ; }
. recherche : : before { content : " ⌕ " ; position : absolute ; left : 10 px ; top : 50 % ; transform : translateY ( - 50 % ) ; color : var ( - - faint ) ; font - size : 16 px ; }
button {
border : 1 px solid var ( - - ligne - forte ) ; background : var ( - - surface - 2 ) ; color : var ( - - texte ) ;
padding : 8 px 13 px ; border - radius : var ( - - rayon - sm ) ; cursor : pointer ; font : inherit ; font - weight : 700 ;
transition : background .15 s , border - color .15 s , transform .05 s , box - shadow .15 s , opacity .15 s , color .15 s ;
}
button : hover : not ( : disabled ) { border - color : var ( - - teal ) ; }
button : active : not ( : disabled ) { transform : translateY ( 1 px ) ; }
button : disabled { opacity : .4 ; cursor : not - allowed ; }
button . primaire { background : var ( - - primaire ) ; color : #fff; border-color: var(--primaire); box-shadow: var(--ombre); }
button . primaire : hover : not ( : disabled ) { background : var ( - - primaire - fort ) ; border - color : var ( - - primaire - fort ) ; }
button . fantome { background : transparent ; }
button . attention { border - color : var ( - - ambre ) ; color : var ( - - ambre ) ; }
button . danger { color : var ( - - rouge ) ; border - color : transparent ; background : transparent ; }
button . danger : hover : not ( : disabled ) { background : var ( - - rouge - fond ) ; }
input , select {
width : 100 % ; border : 1 px solid var ( - - ligne - forte ) ; border - radius : var ( - - rayon - sm ) ;
padding : 8 px 10 px ; background : var ( - - surface ) ; color : var ( - - texte ) ; font : inherit ;
transition : border - color .15 s , box - shadow .15 s ;
}
input : : placeholder { color : var ( - - faint ) ; }
input : focus , select : focus { outline : none ; border - color : var ( - - teal ) ; box - shadow : 0 0 0 3 px color - mix ( in srgb , var ( - - teal ) 22 % , transparent ) ; }
main { padding : 16 px 22 px 44 px ; display : grid ; grid - template - columns : minmax ( 0 , 1 fr ) minmax ( 330 px , 380 px ) ; gap : 20 px ; align - items : start ; max - width : 1640 px ; margin : 0 auto ; }
. message { min - height : 18 px ; font - size : 13 px ; font - weight : 650 ; color : var ( - - bleu ) ; margin : 0 2 px 12 px ; }
. message . erreur { color : var ( - - rouge ) ; } . message . ok { color : var ( - - vert ) ; }
. chips - filtre { display : flex ; gap : 7 px ; flex - wrap : wrap ; margin - bottom : 16 px ; }
. chip - f { padding : 6 px 13 px ; border - radius : 999 px ; border : 1 px solid var ( - - ligne - forte ) ; background : var ( - - surface - 2 ) ; color : var ( - - muted ) ; font - weight : 700 ; font - size : 12.5 px ; cursor : pointer ; display : inline - flex ; align - items : center ; gap : 7 px ; transition : all .14 s ; }
. chip - f : hover { border - color : var ( - - ligne - forte ) ; color : var ( - - texte ) ; }
. chip - f . n { font - size : 11 px ; opacity : .8 ; }
. chip - f . on { color : #07101f; border-color: transparent; }
. chip - f . on . tous { background : var ( - - teal ) ; }
. chip - f . on . actif { background : var ( - - vert ) ; }
. chip - f . on . planifie { background : var ( - - bleu ) ; }
. chip - f . on . bloque { background : var ( - - rouge ) ; }
. section - grille { margin - bottom : 22 px ; }
. section - tete { display : flex ; align - items : center ; gap : 10 px ; margin : 0 0 11 px ; color : var ( - - faint ) ; font - size : 11 px ; font - weight : 800 ; letter - spacing : .09 em ; text - transform : uppercase ; }
. section - tete . compte { color : var ( - - muted ) ; }
. section - tete : : after { content : " " ; height : 1 px ; background : var ( - - ligne ) ; flex : 1 ; }
. grille - cartes { display : grid ; grid - template - columns : repeat ( auto - fill , minmax ( 190 px , 1 fr ) ) ; gap : 12 px ; }
. carte {
position : relative ; text - align : left ; display : flex ; flex - direction : column ; gap : 8 px ;
background : var ( - - surface ) ; border : 1 px solid var ( - - ligne ) ; border - radius : var ( - - rayon ) ;
padding : 12 px 13 px ; cursor : pointer ; font : inherit ; color : var ( - - texte ) ;
transition : border - color .14 s , box - shadow .14 s , transform .05 s , background .14 s ;
}
. carte : : before { content : " " ; position : absolute ; left : 0 ; top : 11 px ; bottom : 11 px ; width : 3 px ; border - radius : 0 3 px 3 px 0 ; background : var ( - - bleu ) ; }
. carte . actif : : before { background : var ( - - vert ) ; }
. carte . bloque : : before { background : var ( - - rouge ) ; }
. carte : hover { border - color : var ( - - ligne - forte ) ; box - shadow : var ( - - ombre ) ; }
. carte . selectionnee { border - color : var ( - - teal ) ; box - shadow : 0 0 0 1 px var ( - - teal ) , var ( - - ombre ) ; background : var ( - - surface - 2 ) ; }
. carte - haut { display : flex ; align - items : center ; justify - content : space - between ; gap : 8 px ; }
. carte - vmid { color : var ( - - faint ) ; font - size : 11 px ; font - family : ui - monospace , SFMono - Regular , Menlo , monospace ; }
. carte - nom { font - weight : 800 ; font - size : 14 px ; overflow : hidden ; text - overflow : ellipsis ; white - space : nowrap ; }
. carte - nom . sans { color : var ( - - faint ) ; font - style : italic ; font - weight : 600 ; }
. carte - ip { color : var ( - - muted ) ; font - size : 12 px ; font - family : ui - monospace , SFMono - Regular , Menlo , monospace ; }
. carte - grps { display : flex ; gap : 5 px ; flex - wrap : wrap ; margin - top : 1 px ; }
. tag { font - size : 10.5 px ; font - weight : 700 ; padding : 2 px 7 px ; border - radius : 999 px ; background : var ( - - surface - 3 ) ; color : var ( - - muted ) ; white - space : nowrap ; }
. tag . plus { background : transparent ; color : var ( - - faint ) ; }
. badge - statut { display : inline - flex ; align - items : center ; gap : 5 px ; border - radius : 999 px ; padding : 3 px 9 px ; font - size : 10.5 px ; font - weight : 800 ; }
. badge - statut . ok { color : var ( - - vert ) ; background : var ( - - vert - fond ) ; }
. badge - statut . attente { color : var ( - - bleu ) ; background : var ( - - bleu - fond ) ; }
. badge - statut . bloque { color : var ( - - rouge ) ; background : var ( - - rouge - fond ) ; }
aside { position : sticky ; top : 70 px ; max - height : calc ( 100 vh - 90 px ) ; overflow : auto ; }
. detail { background : var ( - - surface ) ; border : 1 px solid var ( - - ligne ) ; border - radius : var ( - - rayon ) ; box - shadow : var ( - - ombre ) ; overflow : hidden ; }
. detail . bloque { border - color : color - mix ( in srgb , var ( - - rouge ) 50 % , var ( - - ligne ) ) ; }
. detail - tete { display : flex ; align - items : center ; gap : 10 px ; padding : 14 px 16 px 12 px ; border - bottom : 1 px solid var ( - - ligne ) ; flex - wrap : wrap ; }
. detail - nom { flex : 1 1 150 px ; min - width : 0 ; }
. detail - nom input { font - weight : 800 ; font - size : 17 px ; border - color : transparent ; background : transparent ; padding : 4 px 7 px ; }
. detail - nom input : hover { background : var ( - - surface - 2 ) ; border - color : var ( - - ligne ) ; }
. zone - hint { display : inline - block ; margin : 4 px 0 0 8 px ; font - size : 11 px ; font - weight : 700 ; color : var ( - - teal ) ; }
. etat - bascule { display : inline - flex ; border : 1 px solid var ( - - ligne - forte ) ; border - radius : 999 px ; padding : 2 px ; background : var ( - - surface - 3 ) ; gap : 2 px ; flex : none ; }
. etat - bascule button { border : none ; background : transparent ; border - radius : 999 px ; padding : 5 px 12 px ; font - size : 12 px ; font - weight : 750 ; color : var ( - - muted ) ; box - shadow : none ; }
. etat - bascule button . on { background : var ( - - surface ) ; color : var ( - - texte ) ; }
. etat - bascule button . on . actif { color : var ( - - vert ) ; }
. stats { display : grid ; grid - template - columns : repeat ( auto - fit , minmax ( 64 px , 1 fr ) ) ; gap : 8 px ; padding : 14 px 16 px ; }
. stat { background : var ( - - surface - 2 ) ; border : 1 px solid var ( - - ligne ) ; border - radius : var ( - - rayon - sm ) ; padding : 9 px 10 px ; min - width : 0 ; }
. stat . v { font - size : 18 px ; font - weight : 800 ; line - height : 1.1 ; overflow : hidden ; text - overflow : ellipsis ; white - space : nowrap ; }
. stat . v . vide { color : var ( - - faint ) ; }
. stat . l { font - size : 9.5 px ; text - transform : uppercase ; letter - spacing : .06 em ; color : var ( - - faint ) ; font - weight : 800 ; margin - top : 3 px ; }
. onglets { display : flex ; gap : 2 px ; padding : 0 12 px ; border - bottom : 1 px solid var ( - - ligne ) ; }
. onglet { padding : 9 px 12 px ; background : transparent ; border : none ; border - bottom : 2 px solid transparent ; color : var ( - - muted ) ; font - weight : 750 ; font - size : 13 px ; cursor : pointer ; border - radius : 0 ; }
. onglet : hover { color : var ( - - texte ) ; border - color : transparent ; }
. onglet . actif { color : var ( - - texte ) ; border - bottom - color : var ( - - teal ) ; }
. onglet - corps { padding : 14 px 16 px ; }
. grille { display : grid ; grid - template - columns : repeat ( auto - fit , minmax ( 135 px , 1 fr ) ) ; gap : 11 px 12 px ; }
. champ { display : flex ; flex - direction : column ; gap : 4 px ; min - width : 0 ; }
. champ > span { color : var ( - - muted ) ; font - size : 11 px ; font - weight : 700 ; }
. champ . unite { color : var ( - - faint ) ; font - weight : 600 ; }
. groupes - liste { display : grid ; gap : 7 px ; }
. groupe { display : block ; border : 1 px solid var ( - - ligne ) ; border - radius : var ( - - rayon - sm ) ; padding : 8 px 10 px ; background : var ( - - surface - 2 ) ; cursor : pointer ; transition : border - color .12 s , background .12 s ; }
. groupe : hover { border - color : var ( - - ligne - forte ) ; }
. groupe . selectionne { border - color : color - mix ( in srgb , var ( - - bleu ) 55 % , var ( - - ligne ) ) ; background : var ( - - bleu - fond ) ; }
. groupe . ok { border - color : color - mix ( in srgb , var ( - - vert ) 55 % , var ( - - ligne ) ) ; background : var ( - - vert - fond ) ; }
. groupe . attente { border - color : color - mix ( in srgb , var ( - - ambre ) 55 % , var ( - - ligne ) ) ; background : var ( - - ambre - fond ) ; }
. groupe . bloque { border - color : color - mix ( in srgb , var ( - - rouge ) 60 % , var ( - - ligne ) ) ; background : var ( - - rouge - fond ) ; }
. groupe - ligne { display : flex ; align - items : center ; gap : 8 px ; font - weight : 700 ; font - size : 13 px ; overflow - wrap : anywhere ; }
. groupe - ligne input { width : 15 px ; height : 15 px ; flex : none ; accent - color : var ( - - teal ) ; }
. groupe - detail { color : var ( - - muted ) ; font - size : 11 px ; line - height : 1.35 ; margin : 4 px 0 0 23 px ; }
. pied { padding : 12 px 16 px ; border - top : 1 px solid var ( - - ligne ) ; display : flex ; gap : 8 px ; align - items : center ; }
. pied . grandit { flex : 1 ; }
. pied . hint - dep { color : var ( - - faint ) ; font - size : 12 px ; font - style : italic ; }
. dep - bloc { margin - top : 4 px ; }
. dep - bloc > summary { list - style : none ; cursor : pointer ; padding : 10 px 13 px ; display : flex ; align - items : center ; justify - content : space - between ; gap : 8 px ; font - weight : 800 ; font - size : 12.5 px ; background : var ( - - surface ) ; border : 1 px solid var ( - - ligne ) ; border - radius : var ( - - rayon - sm ) ; }
. dep - bloc > summary : : - webkit - details - marker { display : none ; }
. dep - bloc > summary : : after { content : " ▾ " ; color : var ( - - faint ) ; }
. dep - bloc [ open ] > summary { border - radius : var ( - - rayon - sm ) var ( - - rayon - sm ) 0 0 ; }
. dep - corps { border : 1 px solid var ( - - ligne ) ; border - top : none ; border - radius : 0 0 var ( - - rayon - sm ) var ( - - rayon - sm ) ; padding : 11 px ; display : grid ; grid - template - columns : repeat ( auto - fill , minmax ( 220 px , 1 fr ) ) ; gap : 8 px ; }
. carte - dep { border : 1 px solid var ( - - ligne ) ; border - radius : var ( - - rayon - sm ) ; padding : 9 px 10 px ; background : var ( - - surface - 2 ) ; }
. carte - dep . ok { border - color : color - mix ( in srgb , var ( - - vert ) 45 % , var ( - - ligne ) ) ; }
. carte - dep . attente { border - color : color - mix ( in srgb , var ( - - ambre ) 45 % , var ( - - ligne ) ) ; }
. carte - dep . bloque { border - color : color - mix ( in srgb , var ( - - rouge ) 50 % , var ( - - ligne ) ) ; }
. carte - dep . haut { display : flex ; align - items : center ; justify - content : space - between ; gap : 8 px ; margin - bottom : 4 px ; }
. carte - dep . nom { font - weight : 800 ; font - size : 12 px ; overflow - wrap : anywhere ; }
. carte - dep . txt { color : var ( - - muted ) ; font - size : 11 px ; line - height : 1.4 ; }
. vide { color : var ( - - muted ) ; padding : 40 px 24 px ; text - align : center ; }
. vide b { color : var ( - - texte ) ; display : block ; margin - bottom : 4 px ; font - size : 15 px ; }
. vue - bascule { display : inline - flex ; border : 1 px solid var ( - - ligne - forte ) ; border - radius : 999 px ; padding : 2 px ; background : var ( - - surface - 3 ) ; gap : 2 px ; }
. vue - bascule button { border : none ; background : transparent ; border - radius : 999 px ; padding : 6 px 13 px ; font - size : 12.5 px ; font - weight : 750 ; color : var ( - - muted ) ; box - shadow : none ; }
. vue - bascule button : hover { color : var ( - - texte ) ; background : transparent ; }
. vue - bascule button . on { background : var ( - - surface ) ; color : var ( - - teal ) ; box - shadow : var ( - - ombre ) ; }
. arbre - vm { background : var ( - - surface ) ; border : 1 px solid var ( - - ligne ) ; border - radius : var ( - - rayon ) ; margin - bottom : 10 px ; box - shadow : var ( - - ombre ) ; }
. arbre - vm > summary { list - style : none ; cursor : pointer ; padding : 11 px 14 px ; display : flex ; align - items : center ; gap : 10 px ; font - size : 14 px ; }
. arbre - vm > summary : : - webkit - details - marker { display : none ; }
. arbre - vm > summary : : before { content : " \25 B8 " ; color : var ( - - faint ) ; }
. arbre - vm [ open ] > summary : : before { content : " \25 BE " ; }
. arbre - vm . ch - meta { color : var ( - - muted ) ; font - size : 12 px ; margin - left : auto ; }
. arbre - corps { padding : 2 px 16 px 14 px 32 px ; display : grid ; gap : 9 px ; }
. ch - grp { border - left : 2 px solid var ( - - ligne - forte ) ; padding : 3 px 0 3 px 12 px ; }
. ch - grp - tete { display : flex ; align - items : center ; gap : 7 px ; font - weight : 700 ; font - size : 13 px ; flex - wrap : wrap ; }
. ch - fleche { color : var ( - - faint ) ; }
. mono { font - family : ui - monospace , SFMono - Regular , Menlo , monospace ; color : var ( - - teal ) ; font - size : 12 px ; }
. ch - roles { display : flex ; flex - wrap : wrap ; gap : 5 px ; margin - top : 6 px ; }
. ch - stub { color : var ( - - ambre ) ; font - size : 11.5 px ; font - style : italic ; margin - top : 5 px ; }
2026-06-22 19:14:12 -04:00
. bases - liste { display : grid ; gap : 10 px ; }
. base - ligne { display : grid ; grid - template - columns : repeat ( auto - fit , minmax ( 120 px , 1 fr ) ) auto ; gap : 9 px 11 px ; align - items : end ; background : var ( - - surface ) ; border : 1 px solid var ( - - ligne ) ; border - radius : var ( - - rayon - sm ) ; padding : 11 px 12 px ; box - shadow : var ( - - ombre ) ; }
. base - ligne . danger { align - self : end ; }
. base - ligne . dsn { grid - column : 1 / - 1 ; color : var ( - - muted ) ; font - size : 11.5 px ; padding - top : 2 px ; overflow - wrap : anywhere ; }
2026-06-22 19:44:05 -04:00
. ch - bases { display : grid ; gap : 4 px ; margin : 6 px 0 0 23 px ; }
. ch - base { font - size : 11.5 px ; color : var ( - - muted ) ; overflow - wrap : anywhere ; }
. badge - bd { display : inline - block ; font - size : 10 px ; font - weight : 800 ; padding : 1 px 6 px ; border - radius : 999 px ; background : color - mix ( in srgb , var ( - - bleu ) 18 % , transparent ) ; color : var ( - - bleu ) ; }
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
. modale { position : fixed ; inset : 0 ; z - index : 50 ; display : flex ; align - items : center ; justify - content : center ; background : rgba ( 0 , 0 , 0 , .55 ) ; }
. modale [ hidden ] { display : none ; }
. modale - boite { background : var ( - - surface ) ; border : 1 px solid var ( - - ligne - forte ) ; border - radius : var ( - - rayon ) ; box - shadow : var ( - - ombre - forte ) ; padding : 18 px 20 px ; width : min ( 440 px , 92 vw ) ; display : grid ; gap : 12 px ; }
. modale - titre { font - weight : 800 ; font - size : 15 px ; }
. modale - texte { color : var ( - - muted ) ; font - size : 13 px ; line - height : 1.5 ; }
. modale - actions { display : flex ; justify - content : flex - end ; gap : 8 px ; margin - top : 4 px ; }
. console { position : fixed ; left : 0 ; right : 0 ; bottom : 0 ; height : 44 vh ; background : var ( - - surface ) ; border - top : 1 px solid var ( - - ligne - forte ) ; box - shadow : 0 - 16 px 50 px - 18 px rgba ( 0 , 0 , 0 , .8 ) ; z - index : 40 ; display : flex ; flex - direction : column ; }
. console [ hidden ] { display : none ; }
. console - tete { display : flex ; align - items : center ; gap : 12 px ; padding : 9 px 16 px ; border - bottom : 1 px solid var ( - - ligne ) ; background : var ( - - surface - 2 ) ; }
. console - titre { font - weight : 800 ; font - size : 13 px ; }
. console - etat { font - size : 12 px ; font - weight : 800 ; }
. console - etat . actif { color : var ( - - bleu ) ; animation : pulse 1.2 s ease - in - out infinite ; }
. console - etat . ok { color : var ( - - vert ) ; } . console - etat . echec { color : var ( - - rouge ) ; }
@keyframes pulse { 50 % { opacity : .4 ; } }
. console pre { margin : 0 ; padding : 12 px 16 px ; overflow : auto ; flex : 1 ; font - family : ui - monospace , SFMono - Regular , Menlo , monospace ; font - size : 12 px ; line - height : 1.45 ; white - space : pre - wrap ; word - break : break - word ; color : #cdd6e6; }
@media ( max - width : 1000 px ) {
main { grid - template - columns : 1 fr ; }
aside { position : static ; max - height : none ; order : - 1 ; }
2026-06-21 20:35:03 -04:00
}
< / style >
< / head >
< body >
< header >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< div class = " marque " > < span class = " pastille " > < / span > < div class = " titre " > < h1 > Set - OPS < / h1 > < span class = " slogan " > Votre artisan numérique < / span > < / div > < / div >
< span class = " chemin " id = " chemin " > < / span >
< div class = " grandit " > < / div >
< div class = " resume " id = " resume " > < / div >
2026-06-21 20:35:03 -04:00
< div class = " barre " >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< div class = " vue-bascule " >
< button type = " button " id = " btn-vue-cartes " class = " on " onclick = " setVue( ' cartes ' ) " > Inventaire < / button >
2026-06-23 20:44:08 -04:00
< button type = " button " id = " btn-vue-serveurs " onclick = " setVue( ' serveurs ' ) " > Serveurs < / button >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< button type = " button " id = " btn-vue-chaine " onclick = " setVue( ' chaine ' ) " > Chaîne < / button >
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
< button type = " button " id = " btn-vue-applications " onclick = " setVue( ' applications ' ) " > Applications < / button >
2026-06-22 19:14:12 -04:00
< button type = " button " id = " btn-vue-bases " onclick = " setVue( ' bases ' ) " > Bases < / button >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< / div >
< span class = " recherche " > < input id = " filtre " type = " search " placeholder = " Filtrer… " oninput = " filtrer(this.value) " > < / span >
< button type = " button " class = " fantome " onclick = " ajouterHote() " > + Hôte < / button >
< button type = " button " class = " fantome " onclick = " charger() " > Recharger < / button >
< button type = " button " class = " primaire " id = " btn-sauver " onclick = " sauvegarder() " > Sauvegarder < / button >
2026-06-21 20:35:03 -04:00
< / div >
< / header >
< main >
2026-06-21 21:40:45 -04:00
< section >
< div class = " message " id = " message " > < / div >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< div class = " chips-filtre " id = " chips " > < / div >
< div id = " grilles " > < / div >
< details class = " dep-bloc " id = " panneau-dep " >
< summary > Dépendances causales < span id = " dep-resume " class = " chip " > < / span > < / summary >
< div class = " dep-corps " id = " dependances " > < / div >
< / details >
2026-06-21 21:40:45 -04:00
< / section >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< aside > < div id = " detail " > < / div > < / aside >
2026-06-21 20:35:03 -04:00
< / main >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< div class = " modale " id = " modale " hidden >
< div class = " modale-boite " >
< div class = " modale-titre " id = " modale-titre " > < / div >
< div class = " modale-texte " id = " modale-texte " > < / div >
< label class = " champ " > < span > Mot de passe du vault Ansible ( laisser vide si non requis ) < / span >
< input type = " password " id = " modale-vault " autocomplete = " off " placeholder = " •••••••• " onkeydown = " if(event.key=== ' Enter ' )confirmerModale() " > < / label >
< div class = " modale-actions " >
< button type = " button " onclick = " annulerModale() " > Annuler < / button >
< button type = " button " class = " primaire " onclick = " confirmerModale() " > Confirmer < / button >
< / div >
< / div >
< / div >
< div class = " console " id = " console " hidden >
< div class = " console-tete " >
< span class = " console-titre " id = " console-titre " > < / span >
< span class = " console-etat " id = " console-etat " > < / span >
< span class = " grandit " > < / span >
< button type = " button " id = " btn-fermer-console " onclick = " fermerConsole() " > Fermer < / button >
< / div >
< pre id = " console-sortie " > < / pre >
< / div >
2026-06-21 20:35:03 -04:00
< script >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const JETON = " __JETON__ " ;
2026-06-21 20:35:03 -04:00
let groupes = [ ] ;
2026-06-21 21:31:03 -04:00
let dependances = { } ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
let nomenclature = { } ;
let chaine = { } ;
2026-06-21 20:35:03 -04:00
let hotes = [ ] ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
let estProduction = false ;
let filtre = ' ' ;
let filtreEtat = ' tous ' ;
let vuePrincipale = ' cartes ' ;
2026-06-22 19:14:12 -04:00
let bdServeurs = [ ] ;
let bdApplis = [ ] ;
let basesModifie = false ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
let applications = [ ] ;
let applicationsModifie = false ;
2026-06-23 20:44:08 -04:00
let serveurs = [ ] ;
2026-06-23 22:23:36 -04:00
let serveursModifie = false ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
let selection = - 1 ;
let selectionNom = null ;
let ongletActif = ' reseau ' ;
let modifie = false ;
let occupe = false ;
let verifie = { } ;
let motVault = ' ' ;
let modaleResolveur = null ;
const ONGLETS = {
reseau : [
[ ' adresse_ip ' , ' Adresse IP ' , { placeholder : ' 192.168.12.101 ' } ] ,
[ ' cidr ' , ' CIDR ' , { type : ' number ' , placeholder : ' 24 ' , min : 0 , max : 32 } ] ,
[ ' passerelle ' , ' Passerelle ' , { placeholder : ' 192.168.12.1 ' } ] ,
[ ' vlan ' , ' VLAN ' , { type : ' number ' , placeholder : ' 12 ' , min : 1 , max : 4094 } ] ,
[ ' pont ' , ' Pont ' , { placeholder : ' vmbr0 ' } ] ,
[ ' dns ' , ' DNS ' , { placeholder : ' 192.168.12.1 ' } ] ,
[ ' utilisateur_ansible ' , ' Utilisateur Ansible ' , { placeholder : ' ansible ' } ] ,
] ,
proxmox : [
[ ' vmid ' , ' VMID ' , { type : ' number ' , placeholder : ' 95301 ' } ] ,
[ ' noeud ' , ' Nœud ' , { placeholder : ' pve-01 ' } ] ,
[ ' stockage ' , ' Stockage ' , { placeholder : ' local-zfs ' } ] ,
[ ' disque_taille ' , ' Disque ' , { placeholder : ' 32G ' , unite : ' taille ' } ] ,
[ ' memoire ' , ' Mémoire ' , { type : ' number ' , placeholder : ' 2048 ' , unite : ' Mo ' } ] ,
[ ' coeurs ' , ' Cœurs ' , { type : ' number ' , placeholder : ' 2 ' , min : 1 } ] ,
] ,
} ;
function message ( texte , type = ' ' ) {
2026-06-21 20:35:03 -04:00
const el = document . getElementById ( ' message ' ) ;
el . textContent = texte ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
el . className = ' message ' + ( type ? ' ' + type : ' ' ) ;
2026-06-21 20:35:03 -04:00
}
async function charger ( ) {
const reponse = await fetch ( ' /api/inventaire ' ) ;
const data = await reponse . json ( ) ;
groupes = data . groupes ;
2026-06-21 21:31:03 -04:00
dependances = data . dependances | | { } ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
nomenclature = data . nomenclature | | { } ;
chaine = data . chaine | | { } ;
2026-06-22 19:14:12 -04:00
chargerBases ( data ) ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
chargerApplications ( data ) ;
2026-06-23 22:23:36 -04:00
chargerServeurs ( data ) ;
2026-06-21 20:35:03 -04:00
hotes = data . hotes ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
estProduction = ! ! data . production ;
modifie = false ; verifie = { } ;
document . getElementById ( ' chemin ' ) . textContent = data . inventaire ;
restaurerSelection ( ) ;
2026-06-21 20:35:03 -04:00
dessiner ( ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
message ( ' Inventaire chargé. ' , ' ok ' ) ;
2026-06-21 20:35:03 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function restaurerSelection ( ) {
if ( selectionNom != null ) {
const i = hotes . findIndex ( h = > h . nom == = selectionNom ) ;
selection = i > = 0 ? i : ( hotes . length ? 0 : - 1 ) ;
} else {
selection = hotes . length ? 0 : - 1 ;
}
selectionNom = selection > = 0 ? hotes [ selection ] . nom : null ;
}
function selectionner ( index ) {
selection = index ;
selectionNom = hotes [ index ] ? hotes [ index ] . nom : null ;
2026-06-21 20:35:03 -04:00
dessiner ( ) ;
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function marquerModifie ( ) { modifie = true ; verifie = { } ; majIndicateurSauvegarde ( ) ; majBoutonsDeploiement ( ) ; }
function ajouterHote ( ) {
Mettre les noms de roles et playbooks au singulier
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>
2026-06-23 23:18:52 -04:00
hotes . unshift ( { nom : ' ' , etat : ' planifie ' , utilisateur_ansible : ' ansible ' , groupes : [ ' serveur_debian ' , ' serveur_durci ' ] } ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
selection = 0 ; selectionNom = ' ' ; filtre = ' ' ; filtreEtat = ' tous ' ;
document . getElementById ( ' filtre ' ) . value = ' ' ;
marquerModifie ( ) ; dessiner ( ) ;
const champNom = document . querySelector ( ' .detail-nom input ' ) ;
if ( champNom ) champNom . focus ( ) ;
}
2026-06-21 20:35:03 -04:00
function supprimerHote ( index ) {
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const nom = hotes [ index ] & & hotes [ index ] . nom ;
if ( nom & & ! confirm ( ' Retirer ' + nom + ' de l \' inventaire ? ' ) ) return ;
2026-06-21 20:35:03 -04:00
hotes . splice ( index , 1 ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
if ( selection > = hotes . length ) selection = hotes . length - 1 ;
selectionNom = selection > = 0 ? hotes [ selection ] . nom : null ;
marquerModifie ( ) ; dessiner ( ) ;
2026-06-21 20:35:03 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function definir ( index , champ , valeur ) { hotes [ index ] [ champ ] = valeur ; marquerModifie ( ) ; }
function definirNom ( index , valeur ) {
hotes [ index ] . nom = valeur ; selectionNom = valeur ;
const c = document . getElementById ( ' carte- ' + index ) ;
if ( c ) { const n = c . querySelector ( ' .carte-nom ' ) ; if ( n ) { n . textContent = valeur | | ' (sans nom) ' ; n . className = ' carte-nom ' + ( valeur ? ' ' : ' sans ' ) ; } }
marquerModifie ( ) ;
2026-06-21 20:35:03 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function definirEtat ( index , etat ) { hotes [ index ] . etat = etat ; marquerModifie ( ) ; dessiner ( ) ; }
2026-06-21 20:35:03 -04:00
function basculerGroupe ( index , groupe , actif ) {
const ensemble = new Set ( hotes [ index ] . groupes | | [ ] ) ;
if ( actif ) ensemble . add ( groupe ) ; else ensemble . delete ( groupe ) ;
hotes [ index ] . groupes = Array . from ( ensemble ) . sort ( ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
marquerModifie ( ) ; dessiner ( ) ;
2026-06-21 21:40:45 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function setOnglet ( o ) { ongletActif = o ; dessinerDetail ( ) ; }
function setFiltreEtat ( e ) { filtreEtat = e ; dessinerChips ( ) ; dessinerGrilles ( ) ; }
function filtrer ( valeur ) { filtre = ( valeur | | ' ' ) . trim ( ) . toLowerCase ( ) ; dessinerGrilles ( ) ; }
2026-06-21 21:40:45 -04:00
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function groupesActifs ( ) { const a = new Set ( ) ; hotes . forEach ( h = > { if ( h . etat == = ' actif ' ) ( h . groupes | | [ ] ) . forEach ( g = > a . add ( g ) ) ; } ) ; return a ; }
function groupesPlanifies ( ) { const p = new Set ( ) ; hotes . forEach ( h = > ( h . groupes | | [ ] ) . forEach ( g = > p . add ( g ) ) ) ; return p ; }
2026-06-21 21:40:45 -04:00
function statutDependance ( groupe ) {
const requis = ( ( dependances [ groupe ] | | { } ) . requiert_groupes_actifs | | [ ] ) ;
if ( ! requis . length ) return ' neutre ' ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const actifs = groupesActifs ( ) , planifies = groupesPlanifies ( ) ;
const manquants = requis . filter ( i = > ! actifs . has ( i ) ) ;
2026-06-21 21:40:45 -04:00
if ( ! manquants . length ) return ' ok ' ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
if ( manquants . every ( i = > planifies . has ( i ) ) ) return ' attente ' ;
2026-06-21 21:40:45 -04:00
return ' bloque ' ;
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function manquantsPourGroupe ( groupe ) { const a = groupesActifs ( ) ; return ( ( dependances [ groupe ] | | { } ) . requiert_groupes_actifs | | [ ] ) . filter ( i = > ! a . has ( i ) ) ; }
function hoteBloque ( h ) { if ( ! h | | h . etat != = ' actif ' ) return false ; return ( h . groupes | | [ ] ) . some ( g = > manquantsPourGroupe ( g ) . length ) ; }
function statutHote ( h ) { return h . etat == = ' actif ' ? ( hoteBloque ( h ) ? ' bloque ' : ' ok ' ) : ' attente ' ; }
function libelleStatut ( s ) { return { ok : ' actif ' , attente : ' planifié ' , bloque : ' bloqué ' , neutre : ' libre ' } [ s ] | | s ; }
function abrege ( g ) { return g . replace ( / ^ serveurs_ / , ' ' ) . replace ( / ^ clients_ / , ' cli· ' ) ; }
function dessiner ( ) { dessinerResume ( ) ; dessinerChips ( ) ; dessinerGrilles ( ) ; dessinerDependances ( ) ; dessinerDetail ( ) ; majIndicateurSauvegarde ( ) ; }
2026-06-21 21:40:45 -04:00
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function majIndicateurSauvegarde ( ) {
const b = document . getElementById ( ' btn-sauver ' ) ;
if ( b ) { b . classList . toggle ( ' attention ' , modifie ) ; b . textContent = modifie ? ' Sauvegarder • ' : ' Sauvegarder ' ; }
2026-06-21 21:40:45 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function dessinerResume ( ) {
const actifs = hotes . filter ( h = > h . etat == = ' actif ' ) . length ;
const bloques = hotes . filter ( h = > hoteBloque ( h ) ) . length ;
document . getElementById ( ' resume ' ) . innerHTML = `
< span class = " chip " > < b > $ { hotes . length } < / b > hôtes < / span >
< span class = " chip " > < span class = " pt actif " > < / span > < b > $ { actifs } < / b > actifs < / span >
< span class = " chip " > < span class = " pt plan " > < / span > < b > $ { hotes . length - actifs } < / b > planifiés < / span >
$ { bloques ? ` < span class = " chip " > < span class = " pt bloq " > < / span > < b > $ { bloques } < / b > bloqués < / span > ` : ' ' } ` ;
2026-06-21 21:40:45 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function dessinerChips ( ) {
const n = { tous : hotes . length , actif : 0 , planifie : 0 , bloque : 0 } ;
hotes . forEach ( h = > { if ( h . etat == = ' actif ' ) n . actif + + ; else n . planifie + + ; if ( hoteBloque ( h ) ) n . bloque + + ; } ) ;
const defs = [ [ ' tous ' , ' Tous ' ] , [ ' actif ' , ' Actifs ' ] , [ ' planifie ' , ' Planifiés ' ] , [ ' bloque ' , ' Bloqués ' ] ] ;
document . getElementById ( ' chips ' ) . innerHTML = defs . map ( ( [ cle , lib ] ) = >
` < button type = " button " class = " chip-f $ {cle} $ { filtreEtat === cle ? ' on ' : ' ' } " onclick = " setFiltreEtat( ' $ {cle} ' ) " > $ { lib } < span class = " n " > $ { n [ cle ] } < / span > < / button > `
) . join ( ' ' ) ;
2026-06-21 20:35:03 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function correspond ( h ) {
if ( filtreEtat == = ' actif ' & & h . etat != = ' actif ' ) return false ;
if ( filtreEtat == = ' planifie ' & & h . etat == = ' actif ' ) return false ;
if ( filtreEtat == = ' bloque ' & & ! hoteBloque ( h ) ) return false ;
if ( filtre & & ! [ h . nom , h . adresse_ip , h . vmid , . . . ( h . groupes | | [ ] ) ] . join ( ' ' ) . toLowerCase ( ) . includes ( filtre ) ) return false ;
return true ;
2026-06-21 21:40:45 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function carte ( h , index ) {
const st = statutHote ( h ) ;
const cls = st == = ' bloque ' ? ' bloque ' : ( h . etat == = ' actif ' ? ' actif ' : ' attente ' ) ;
const grps = h . groupes | | [ ] ;
const tags = grps . slice ( 0 , 3 ) . map ( g = > ` < span class = " tag " > $ { echapper ( abrege ( g ) ) } < / span > ` ) . join ( ' ' )
+ ( grps . length > 3 ? ` < span class = " tag plus " > + $ { grps . length - 3 } < / span > ` : ' ' ) ;
return `
< button type = " button " class = " carte $ {cls} $ { index === selection ? ' selectionnee ' : ' ' } " id = " carte-$ {index} " onclick = " selectionner($ {index} ) " >
< div class = " carte-haut " >
< span class = " badge-statut $ {st} " > $ { libelleStatut ( st ) } < / span >
$ { h . vmid ? ` < span class = " carte-vmid " > #${echapper(h.vmid)}</span>` : ''}
< / div >
< div class = " carte-nom $ { h.nom ? ' ' : ' sans ' } " > $ { echapper ( h . nom | | ' (sans nom) ' ) } < / div >
< div class = " carte-ip " > $ { echapper ( h . adresse_ip | | ' — ' ) } < / div >
$ { tags ? ` < div class = " carte-grps " > $ { tags } < / div > ` : ' ' }
< / button > ` ;
}
function setVue ( v ) {
vuePrincipale = v ;
document . getElementById ( ' btn-vue-cartes ' ) . classList . toggle ( ' on ' , v == = ' cartes ' ) ;
2026-06-23 20:44:08 -04:00
document . getElementById ( ' btn-vue-serveurs ' ) . classList . toggle ( ' on ' , v == = ' serveurs ' ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
document . getElementById ( ' btn-vue-chaine ' ) . classList . toggle ( ' on ' , v == = ' chaine ' ) ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
document . getElementById ( ' btn-vue-applications ' ) . classList . toggle ( ' on ' , v == = ' applications ' ) ;
2026-06-22 19:14:12 -04:00
document . getElementById ( ' btn-vue-bases ' ) . classList . toggle ( ' on ' , v == = ' bases ' ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
dessinerGrilles ( ) ;
}
function dessinerGrilles ( ) {
2026-06-22 19:14:12 -04:00
document . getElementById ( ' chips ' ) . style . display = vuePrincipale == = ' cartes ' ? ' ' : ' none ' ;
2026-06-23 20:44:08 -04:00
if ( vuePrincipale == = ' serveurs ' ) { dessinerServeurs ( ) ; return ; }
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
if ( vuePrincipale == = ' chaine ' ) { dessinerArbre ( ) ; return ; }
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
if ( vuePrincipale == = ' applications ' ) { dessinerApplications ( ) ; return ; }
2026-06-22 19:14:12 -04:00
if ( vuePrincipale == = ' bases ' ) { dessinerBases ( ) ; return ; }
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const cible = document . getElementById ( ' grilles ' ) ;
if ( ! hotes . length ) { cible . innerHTML = ' <div class= " vide " ><b>Inventaire vide</b>Ajoutez un hôte pour commencer.</div> ' ; return ; }
const visibles = hotes . map ( ( h , i ) = > [ h , i ] ) . filter ( ( [ h ] ) = > correspond ( h ) ) ;
if ( ! visibles . length ) { cible . innerHTML = ' <div class= " vide " >Aucun hôte ne correspond au filtre.</div> ' ; return ; }
const sections = [ [ ' Actifs ' , visibles . filter ( ( [ h ] ) = > h . etat == = ' actif ' ) ] , [ ' Planifiés ' , visibles . filter ( ( [ h ] ) = > h . etat != = ' actif ' ) ] ] ;
2026-06-23 22:23:36 -04:00
const banniere = ' <div class= " dsn " style= " margin:0 2px 12px;padding:10px 12px;background:#1e293b;border-left:3px solid #38bdf8;border-radius:6px;color:#cbd5e1 " >🔒 Inventaire <b>généré depuis le plan</b> (lecture seule). Pour modifier : vues <b>Serveurs</b> et <b>Applications</b>, puis <b>« Appliquer le plan »</b>.</div> ' ;
cible . innerHTML = banniere + sections . filter ( ( [ , l ] ) = > l . length ) . map ( ( [ titre , liste ] ) = > `
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< div class = " section-grille " >
< div class = " section-tete " > $ { titre } < span class = " compte " > $ { liste . length } < / span > < / div >
< div class = " grille-cartes " > $ { liste . map ( ( [ h , i ] ) = > carte ( h , i ) ) . join ( ' ' ) } < / div >
< / div > ` ) . join ( ' ' ) ;
}
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
function basesDeApp ( app , hoteNom ) {
return bdApplis . filter ( a = > {
const p = a . portee | | ' groupe ' ;
return ( p == = ' application ' & & a . consommateur == = app . id )
| | ( p == = ' groupe ' & & a . consommateur == = app . groupe )
| | ( p == = ' hote ' & & a . consommateur == = hoteNom ) ;
} ) ;
}
function lignesDsn ( liste , etiquette ) {
return liste . length ? ` < div class = " ch-bases " > $ { liste . map ( a = > `
< div class = " ch-base " > < span class = " badge-bd " > $ { echapper ( etiquette ( a ) ) } < / span > < span class = " mono " > $ { echapper ( dsnBase ( a ) ) } < / span > < / div > ` ) . join ( ' ' ) } < / div > ` : ' ' ;
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function renduChaine ( hote ) {
const grps = hote . groupes | | [ ] ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
const apps = applications . filter ( a = > a . hote == = hote . nom ) ;
if ( ! grps . length & & ! apps . length ) return ' <div class= " vide " style= " padding:18px " >Aucun groupe opérationnel ni application.</div> ' ;
const grpHtml = grps . map ( g = > {
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const c = chaine [ g ] | | { roles : [ ] , stub : true } ;
const corps = ( c . roles & & c . roles . length )
? ` < div class = " ch-roles " > $ { c . roles . map ( r = > ` < span class = " tag " > $ { echapper ( r ) } < / span > ` ) . join ( ' ' ) } < / div > `
: ' <div class= " ch-stub " >stub — aucun rôle rattaché</div> ' ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
const bg = bdApplis . filter ( a = > ( a . portee | | ' groupe ' ) == = ' groupe ' & & a . consommateur == = g ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
return ` < div class = " ch-grp " >
< div class = " ch-grp-tete " > < span > $ { echapper ( g ) } < / span > < span class = " ch-fleche " > → < / span > < span class = " mono " > $ { echapper ( g ) } . yml < / span > < / div >
$ { corps }
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
$ { lignesDsn ( bg , a = > ' BD partagée ' + ( a . usage | | ' ' ) ) }
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< / div > ` ;
} ) . join ( ' ' ) ;
2026-06-23 20:22:33 -04:00
const ligneLien = ( etiquette , valeur ) = > ` < div class = " ch-base " > < span class = " badge-bd " > $ { etiquette } < / span > < span class = " mono " > $ { echapper ( valeur ) } < / span > < / div > ` ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
const appHtml = apps . map ( app = > {
const dsns = basesDeApp ( app , hote . nom ) ;
2026-06-23 20:22:33 -04:00
const liens = [ ] ;
if ( String ( app . expose | | ' ' ) . trim ( ) ) liens . push ( ligneLien ( ' expose ' , app . expose ) ) ;
if ( String ( app . requiert | | ' ' ) . trim ( ) ) liens . push ( ligneLien ( ' requiert ' , app . requiert ) ) ;
dsns . forEach ( a = > liens . push ( ` < div class = " ch-base " > < span class = " badge-bd " > BD $ { echapper ( ( a . portee | | ' groupe ' ) + ' · ' + ( a . usage | | ' ' ) ) } < / span > < span class = " mono " > $ { echapper ( dsnBase ( a ) ) } < / span > < / div > ` ) ) ;
const corps = liens . length ? ` < div class = " ch-bases " > $ { liens . join ( ' ' ) } < / div > ` : ' <div class= " ch-stub " >aucun lien</div> ' ;
const port = String ( app . port | | ' ' ) . trim ( ) ? ` < span class = " ch-meta " > : $ { echapper ( app . port ) } < / span > ` : ' ' ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
return ` < div class = " ch-grp " >
2026-06-23 20:22:33 -04:00
< div class = " ch-grp-tete " > < span class = " badge-bd " > app < / span > < span > $ { echapper ( app . id ) } < / span > $ { port } < span class = " ch-fleche " > → < / span > < span class = " mono " > $ { echapper ( app . groupe ) } < / span > < / div >
$ { corps }
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
< / div > ` ;
} ) . join ( ' ' ) ;
const appSection = apps . length ? ` < div class = " section-tete " style = " margin:6px 2px 2px " > Applications sur cet hôte < span class = " compte " > $ { apps . length } < / span > < / div > $ { appHtml } ` : ' ' ;
return grpHtml + appSection ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
}
function dessinerArbre ( ) {
const cible = document . getElementById ( ' grilles ' ) ;
const visibles = hotes . map ( ( h , i ) = > [ h , i ] ) . filter ( ( [ h ] ) = > correspond ( h ) ) ;
if ( ! visibles . length ) { cible . innerHTML = ' <div class= " vide " >Aucun hôte.</div> ' ; return ; }
cible . innerHTML = visibles . map ( ( [ h ] ) = > {
const st = statutHote ( h ) ;
const cls = st == = ' bloque ' ? ' bloq ' : ( h . etat == = ' actif ' ? ' actif ' : ' plan ' ) ;
return ` < details class = " arbre-vm " >
< summary > < span class = " pt $ {cls} " > < / span > < b > $ { echapper ( h . nom | | ' (sans nom) ' ) } < / b >
< span class = " badge-statut $ {st} " > $ { libelleStatut ( st ) } < / span >
< span class = " ch-meta " > $ { ( h . groupes | | [ ] ) . length } groupes < / span > < / summary >
< div class = " arbre-corps " > $ { renduChaine ( h ) } < / div >
< / details > ` ;
} ) . join ( ' ' ) ;
2026-06-21 21:40:45 -04:00
}
2026-06-22 19:14:12 -04:00
function chargerBases ( data ) {
const b = data . bases | | { serveurs_bd : { } , bases_donnees : { } } ;
bdServeurs = Object . entries ( b . serveurs_bd | | { } ) . map ( ( [ nom , s ] ) = > ( {
nom , type : s . type | | ' postgres ' , hote : s . hote | | ' ' , port : s . port | | 5432 , groupe : s . groupe | | ' ' } ) ) ;
bdApplis = Object . entries ( b . bases_donnees | | { } ) . map ( ( [ cle , x ] ) = > ( {
2026-06-22 19:44:05 -04:00
cle , serveur : x . serveur | | ' ' , base : x . base | | ' ' , proprietaire : x . proprietaire | | ' ' , secret : x . secret | | ' ' ,
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
consommateur : x . consommateur | | ' ' , portee : x . portee | | ' groupe ' , usage : x . usage | | ' principale ' } ) ) ;
2026-06-22 19:14:12 -04:00
basesModifie = false ;
}
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
function chargerApplications ( data ) {
const a = ( data . applications | | { } ) . applications | | { } ;
2026-06-23 20:10:15 -04:00
applications = Object . entries ( a ) . map ( ( [ id , x ] ) = > ( {
id , groupe : x . groupe | | ' ' , hote : x . hote | | ' ' , port : x . port | | ' ' ,
requiert : ( x . requiert | | [ ] ) . join ( ' , ' ) , expose : ( x . expose | | [ ] ) . join ( ' , ' ) } ) ) ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
applicationsModifie = false ;
}
2026-06-22 19:14:12 -04:00
function dsnBase ( a ) {
const s = bdServeurs . find ( x = > x . nom == = a . serveur ) ;
if ( ! s ) return ' (serveur inconnu : ' + echapper ( a . serveur | | ' — ' ) + ' ) ' ;
return ` $ { s . type } : / / $ { a . proprietaire | | ' ? ' } : * * * * @ $ { s . hote | | ' ? ' } : $ { s . port | | ' ? ' } / $ { a . base | | ' ? ' } ` ;
}
function marquerBasesModifie ( ) {
basesModifie = true ;
const b = document . getElementById ( ' btn-sauver-bases ' ) ;
if ( b ) { b . classList . toggle ( ' attention ' , true ) ; b . textContent = ' Sauvegarder les bases • ' ; }
}
function definirServeurBd ( i , champ , v ) { bdServeurs [ i ] [ champ ] = v ; marquerBasesModifie ( ) ; }
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
function definirBaseBd ( i , champ , v ) { bdApplis [ i ] [ champ ] = v ; marquerBasesModifie ( ) ; if ( champ == = ' serveur ' | | champ == = ' portee ' ) dessinerBases ( ) ; }
2026-06-22 19:14:12 -04:00
function ajouterServeurBd ( ) { bdServeurs . push ( { nom : ' ' , type : ' postgres ' , hote : ' ' , port : 5432 , groupe : ' ' } ) ; marquerBasesModifie ( ) ; dessinerBases ( ) ; }
function retirerServeurBd ( i ) { bdServeurs . splice ( i , 1 ) ; marquerBasesModifie ( ) ; dessinerBases ( ) ; }
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
function ajouterBaseBd ( ) { bdApplis . push ( { cle : ' ' , serveur : ( bdServeurs [ 0 ] | | { } ) . nom | | ' ' , base : ' ' , proprietaire : ' ' , secret : ' ' , consommateur : ' ' , portee : ' groupe ' , usage : ' principale ' } ) ; marquerBasesModifie ( ) ; dessinerBases ( ) ; }
2026-06-22 19:14:12 -04:00
function retirerBaseBd ( i ) { bdApplis . splice ( i , 1 ) ; marquerBasesModifie ( ) ; dessinerBases ( ) ; }
function dessinerBases ( ) {
const cible = document . getElementById ( ' grilles ' ) ;
const serveurs = bdServeurs . length ? bdServeurs . map ( ( s , i ) = > `
< div class = " base-ligne " >
< label class = " champ " > < span > Nom < / span > < input value = " $ { echapper(s.nom)} " oninput = " definirServeurBd($ {i} , ' nom ' , this.value) " > < / label >
< label class = " champ " > < span > Type < / span > < input value = " $ { echapper(s.type)} " oninput = " definirServeurBd($ {i} , ' type ' , this.value) " > < / label >
< label class = " champ " > < span > Hôte < / span > < input value = " $ { echapper(s.hote)} " oninput = " definirServeurBd($ {i} , ' hote ' , this.value) " > < / label >
< label class = " champ " > < span > Port < / span > < input type = " number " value = " $ { echapper(s.port)} " oninput = " definirServeurBd($ {i} , ' port ' , this.value) " > < / label >
Mettre les noms de roles et playbooks au singulier
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>
2026-06-23 23:18:52 -04:00
< label class = " champ " > < span > Groupe Ansible < / span > < input value = " $ { echapper(s.groupe)} " placeholder = " serveur_postgresql " oninput = " definirServeurBd($ {i} , ' groupe ' , this.value) " > < / label >
2026-06-22 19:14:12 -04:00
< button type = " button " class = " danger " title = " Retirer " onclick = " retirerServeurBd($ {i} ) " > ✕ < / button >
< / div > ` ) . join ( ' ' ) : ' <div class= " vide " style= " padding:14px " >Aucun serveur de BD.</div> ' ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
const sourceConso = ( portee ) = > portee == = ' hote ' ? hotes . map ( h = > h . nom ) . filter ( Boolean )
: portee == = ' application ' ? applications . map ( a = > a . id )
: groupes ;
const optConso = ( portee , sel ) = > ' <option value= " " >—</option> ' + sourceConso ( portee ) . map ( v = > ` < option value = " $ { echapper(v)} " $ { v == = sel ? ' selected ' : ' ' } > $ { echapper ( v ) } < / option > ` ) . join ( ' ' ) ;
const optPortee = ( sel ) = > [ ' groupe ' , ' application ' , ' hote ' ] . map ( p = > ` < option value = " $ {p} " $ { p == = sel ? ' selected ' : ' ' } > $ { p } < / option > ` ) . join ( ' ' ) ;
2026-06-22 19:14:12 -04:00
const applis = bdApplis . length ? bdApplis . map ( ( a , i ) = > `
< div class = " base-ligne " >
2026-06-22 19:44:05 -04:00
< label class = " champ " > < span > Identifiant < / span > < input value = " $ { echapper(a.cle)} " oninput = " definirBaseBd($ {i} , ' cle ' , this.value) " > < / label >
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
< label class = " champ " > < span > Portée < / span > < select onchange = " definirBaseBd($ {i} , ' portee ' , this.value) " > $ { optPortee ( a . portee | | ' groupe ' ) } < / select > < / label >
< label class = " champ " > < span > Consommateur < / span > < select onchange = " definirBaseBd($ {i} , ' consommateur ' , this.value) " > $ { optConso ( a . portee | | ' groupe ' , a . consommateur ) } < / select > < / label >
2026-06-22 19:44:05 -04:00
< label class = " champ " > < span > Usage < / span > < input value = " $ { echapper(a.usage)} " placeholder = " principale " oninput = " definirBaseBd($ {i} , ' usage ' , this.value) " > < / label >
2026-06-22 19:14:12 -04:00
< label class = " champ " > < span > Serveur < / span > < select onchange = " definirBaseBd($ {i} , ' serveur ' , this.value) " >
$ { bdServeurs . map ( s = > ` < option value = " $ { echapper(s.nom)} " $ { s . nom == = a . serveur ? ' selected ' : ' ' } > $ { echapper ( s . nom ) } < / option > ` ) . join ( ' ' ) }
< / select > < / label >
< label class = " champ " > < span > Base < / span > < input value = " $ { echapper(a.base)} " oninput = " definirBaseBd($ {i} , ' base ' , this.value) " > < / label >
< label class = " champ " > < span > Propriétaire < / span > < input value = " $ { echapper(a.proprietaire)} " oninput = " definirBaseBd($ {i} , ' proprietaire ' , this.value) " > < / label >
< label class = " champ " > < span > Secret ( Vault ) < / span > < input value = " $ { echapper(a.secret)} " placeholder = " vault_bd_app " oninput = " definirBaseBd($ {i} , ' secret ' , this.value) " > < / label >
< button type = " button " class = " danger " title = " Retirer " onclick = " retirerBaseBd($ {i} ) " > ✕ < / button >
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
< div class = " dsn mono " > $ { echapper ( a . portee | | ' groupe ' ) } · $ { echapper ( a . consommateur | | ' — ' ) } · $ { echapper ( dsnBase ( a ) ) } < / div >
2026-06-22 19:14:12 -04:00
< / div > ` ) . join ( ' ' ) : ' <div class= " vide " style= " padding:14px " >Aucune base applicative.</div> ' ;
cible . innerHTML = `
< div class = " section-grille " >
< div class = " section-tete " > Serveurs de bases de données < button type = " button " class = " fantome " style = " margin-left:auto " onclick = " ajouterServeurBd() " > + Serveur < / button > < / div >
< div class = " bases-liste " > $ { serveurs } < / div >
< / div >
< div class = " section-grille " >
< div class = " section-tete " > Bases applicatives < button type = " button " class = " fantome " style = " margin-left:auto " onclick = " ajouterBaseBd() " > + Base < / button > < / div >
< div class = " bases-liste " > $ { applis } < / div >
< / div >
< div style = " margin:4px 2px 20px " > < button type = " button " class = " primaire $ { basesModifie ? ' attention ' : ' ' } " id = " btn-sauver-bases " onclick = " sauvegarderBases() " > Sauvegarder les bases $ { basesModifie ? ' • ' : ' ' } < / button > < / div > ` ;
}
async function sauvegarderBases ( ) {
const sd = { } ;
bdServeurs . forEach ( s = > { if ( String ( s . nom ) . trim ( ) ) sd [ s . nom ] = { type : s . type , hote : s . hote , port : parseInt ( s . port , 10 ) | | s . port , . . . ( s . groupe ? { groupe : s . groupe } : { } ) } ; } ) ;
const bd = { } ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
bdApplis . forEach ( a = > { if ( String ( a . cle ) . trim ( ) ) bd [ a . cle ] = { serveur : a . serveur , base : a . base , proprietaire : a . proprietaire , secret : a . secret , consommateur : a . consommateur , portee : a . portee | | ' groupe ' , usage : a . usage | | ' principale ' } ; } ) ;
2026-06-22 19:14:12 -04:00
const rep = await fetch ( ' /api/bases ' , {
method : ' POST ' , headers : { ' Content-Type ' : ' application/json ' , ' X-Jeton ' : JETON } , body : JSON . stringify ( { serveurs_bd : sd , bases_donnees : bd } )
} ) ;
const data = await rep . json ( ) ;
if ( ! rep . ok ) { message ( data . erreur | | ' Sauvegarde refusée. ' , ' erreur ' ) ; return ; }
chargerBases ( data ) ;
dessinerBases ( ) ;
message ( ' Bases de données sauvegardées. ' , ' ok ' ) ;
}
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
function marquerApplicationsModifie ( ) {
applicationsModifie = true ;
const b = document . getElementById ( ' btn-sauver-applications ' ) ;
if ( b ) { b . classList . add ( ' attention ' ) ; b . textContent = ' Sauvegarder les applications • ' ; }
}
function definirApplication ( i , champ , v ) { applications [ i ] [ champ ] = v ; marquerApplicationsModifie ( ) ; if ( champ == = ' hote ' | | champ == = ' groupe ' ) dessinerApplications ( ) ; }
2026-06-23 20:10:15 -04:00
function ajouterApplication ( ) { applications . push ( { id : ' ' , groupe : ( groupes [ 0 ] | | ' ' ) , hote : ' ' , port : ' ' , requiert : ' ' , expose : ' ' } ) ; marquerApplicationsModifie ( ) ; dessinerApplications ( ) ; }
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
function retirerApplication ( i ) { applications . splice ( i , 1 ) ; marquerApplicationsModifie ( ) ; dessinerApplications ( ) ; }
function dessinerApplications ( ) {
const cible = document . getElementById ( ' grilles ' ) ;
const optGroupe = ( sel ) = > groupes . map ( g = > ` < option value = " $ { echapper(g)} " $ { g == = sel ? ' selected ' : ' ' } > $ { echapper ( g ) } < / option > ` ) . join ( ' ' ) ;
const optHote = ( sel ) = > ' <option value= " " >—</option> ' + hotes . map ( h = > h . nom ) . filter ( Boolean ) . map ( n = > ` < option value = " $ { echapper(n)} " $ { n == = sel ? ' selected ' : ' ' } > $ { echapper ( n ) } < / option > ` ) . join ( ' ' ) ;
const lignes = applications . length ? applications . map ( ( a , i ) = > {
const dsns = basesDeApp ( a , a . hote ) ;
const resume = dsns . length ? dsns . map ( b = > ` < span class = " mono " > $ { echapper ( ( b . portee | | ' groupe ' ) ) } : $ { echapper ( dsnBase ( b ) ) } < / span > ` ) . join ( ' <br> ' ) : ' <span class= " ch-stub " >aucune base liée</span> ' ;
return ` < div class = " base-ligne " >
< label class = " champ " > < span > Identifiant < / span > < input value = " $ { echapper(a.id)} " placeholder = " boutique " oninput = " definirApplication($ {i} , ' id ' , this.value) " > < / label >
2026-06-23 20:10:15 -04:00
< label class = " champ " > < span > Groupe ( rôle ) < / span > < select onchange = " definirApplication($ {i} , ' groupe ' , this.value) " > $ { optGroupe ( a . groupe ) } < / select > < / label >
< label class = " champ " > < span > Hôte ( VM ) < / span > < select onchange = " definirApplication($ {i} , ' hote ' , this.value) " > $ { optHote ( a . hote ) } < / select > < / label >
< label class = " champ " > < span > Port < / span > < input type = " number " value = " $ { echapper(a.port)} " placeholder = " 3000 " oninput = " definirApplication($ {i} , ' port ' , this.value) " > < / label >
< label class = " champ " > < span > Requiert ( applis ) < / span > < input value = " $ { echapper(a.requiert)} " placeholder = " pg-principal, … " oninput = " definirApplication($ {i} , ' requiert ' , this.value) " > < / label >
Neutraliser le moteur pour partage public (100% neutre)
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>
2026-06-24 19:58:00 -04:00
< label class = " champ " > < span > Expose ( FQDN ) < / span > < input value = " $ { echapper(a.expose)} " placeholder = " forge.exemple.ca " oninput = " definirApplication($ {i} , ' expose ' , this.value) " > < / label >
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
< button type = " button " class = " danger " title = " Retirer " onclick = " retirerApplication($ {i} ) " > ✕ < / button >
< div class = " dsn " > $ { resume } < / div >
< / div > ` ;
} ) . join ( ' ' ) : ' <div class= " vide " style= " padding:14px " >Aucune application. Une VM peut en porter plusieurs.</div> ' ;
cible . innerHTML = `
< div class = " section-grille " >
< div class = " section-tete " > Applications < span class = " compte " > $ { applications . length } < / span > < button type = " button " class = " fantome " style = " margin-left:auto " onclick = " ajouterApplication() " > + Application < / button > < / div >
< div class = " bases-liste " > $ { lignes } < / div >
< / div >
< div style = " margin:4px 2px 20px " > < button type = " button " class = " primaire $ { applicationsModifie ? ' attention ' : ' ' } " id = " btn-sauver-applications " onclick = " sauvegarderApplications() " > Sauvegarder les applications $ { applicationsModifie ? ' • ' : ' ' } < / button > < / div > ` ;
}
2026-06-23 20:10:15 -04:00
function listeDepuisTexte ( v ) { return String ( v | | ' ' ) . split ( ' , ' ) . map ( s = > s . trim ( ) ) . filter ( Boolean ) ; }
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
async function sauvegarderApplications ( ) {
const apps = { } ;
2026-06-23 20:10:15 -04:00
applications . forEach ( a = > {
if ( ! String ( a . id ) . trim ( ) ) return ;
const o = { groupe : a . groupe , hote : a . hote } ;
if ( String ( a . port ) . trim ( ) ) o . port = parseInt ( a . port , 10 ) | | a . port ;
const req = listeDepuisTexte ( a . requiert ) ; if ( req . length ) o . requiert = req ;
const exp = listeDepuisTexte ( a . expose ) ; if ( exp . length ) o . expose = exp ;
apps [ a . id ] = o ;
} ) ;
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
const rep = await fetch ( ' /api/applications ' , {
method : ' POST ' , headers : { ' Content-Type ' : ' application/json ' , ' X-Jeton ' : JETON } , body : JSON . stringify ( { applications : apps } )
} ) ;
const data = await rep . json ( ) ;
if ( ! rep . ok ) { message ( data . erreur | | ' Sauvegarde refusée. ' , ' erreur ' ) ; return ; }
chargerApplications ( data ) ;
dessinerApplications ( ) ;
message ( ' Applications sauvegardées. ' , ' ok ' ) ;
}
2026-06-23 22:23:36 -04:00
function chargerServeurs ( data ) {
serveurs = ( data . serveurs | | [ ] ) . map ( s = > ( { . . . s , integrations : ( s . integrations | | [ ] ) . join ( ' , ' ) } ) ) ;
serveursModifie = false ;
}
function deriveServeur ( nom , fonction ) {
const info = infoFonction ( fonction ) ;
const seq = fonctionDe ( nom ) . seq ;
if ( ! info | | seq == null ) return { vmid : ' ? ' , ip : ' ? ' , vlan : ' ? ' } ;
const base3 = info . sous_reseau . split ( ' . ' ) . slice ( 0 , 3 ) . join ( ' . ' ) ;
return { vmid : ' 9 ' + info . categorie + info . service + String ( seq ) . padStart ( 2 , ' 0 ' ) , ip : base3 + ' . ' + ( info . service * 10 + seq ) , vlan : String ( info . vlan ) } ;
}
function marquerServeursModifie ( ) {
serveursModifie = true ;
const b = document . getElementById ( ' btn-sauver-serveurs ' ) ;
if ( b ) { b . classList . add ( ' attention ' ) ; b . textContent = ' Sauvegarder les serveurs • ' ; }
}
function definirServeur ( i , champ , v ) { serveurs [ i ] [ champ ] = v ; marquerServeursModifie ( ) ; if ( champ == = ' nom ' | | champ == = ' fonction ' ) dessinerServeurs ( ) ; }
function ajouterServeur ( ) { serveurs . push ( { nom : ' ' , fonction : ( Object . keys ( nomenclature . fonctions | | { } ) [ 0 ] | | ' ' ) , etat : ' planifie ' , noeud : ' ' , stockage : ' ' , disque : ' ' , memoire : ' ' , coeurs : ' ' , integrations : ' ' } ) ; marquerServeursModifie ( ) ; dessinerServeurs ( ) ; }
function retirerServeur ( i ) { serveurs . splice ( i , 1 ) ; marquerServeursModifie ( ) ; dessinerServeurs ( ) ; }
2026-06-23 20:44:08 -04:00
function dessinerServeurs ( ) {
const cible = document . getElementById ( ' grilles ' ) ;
2026-06-23 22:23:36 -04:00
const optFonction = ( sel ) = > Object . keys ( nomenclature . fonctions | | { } ) . map ( f = > ` < option value = " $ { echapper(f)} " $ { f == = sel ? ' selected ' : ' ' } > $ { echapper ( f ) } < / option > ` ) . join ( ' ' ) ;
const optEtat = ( sel ) = > [ ' planifie ' , ' actif ' ] . map ( e = > ` < option value = " $ {e} " $ { e == = sel ? ' selected ' : ' ' } > $ { e } < / option > ` ) . join ( ' ' ) ;
const lignes = serveurs . length ? serveurs . map ( ( s , i ) = > {
const d = deriveServeur ( s . nom , s . fonction ) ;
return ` < div class = " base-ligne " >
< label class = " champ " > < span > Serveur ( fonction - NN ) < / span > < input value = " $ { echapper(s.nom)} " placeholder = " web-frontal-03 " oninput = " definirServeur($ {i} , ' nom ' , this.value) " > < / label >
< label class = " champ " > < span > Fonction < / span > < select onchange = " definirServeur($ {i} , ' fonction ' , this.value) " > $ { optFonction ( s . fonction ) } < / select > < / label >
< label class = " champ " > < span > État < / span > < select onchange = " definirServeur($ {i} , ' etat ' , this.value) " > $ { optEtat ( s . etat ) } < / select > < / label >
Neutraliser le moteur pour partage public (100% neutre)
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>
2026-06-24 19:58:00 -04:00
< label class = " champ " > < span > Nœud < / span > < input value = " $ { echapper(s.noeud)} " placeholder = " noeud-1 " oninput = " definirServeur($ {i} , ' noeud ' , this.value) " > < / label >
< label class = " champ " > < span > Stockage < / span > < input value = " $ { echapper(s.stockage)} " placeholder = " stockage-1 " oninput = " definirServeur($ {i} , ' stockage ' , this.value) " > < / label >
2026-06-23 22:23:36 -04:00
< label class = " champ " > < span > Disque < / span > < input value = " $ { echapper(s.disque)} " placeholder = " 16G " oninput = " definirServeur($ {i} , ' disque ' , this.value) " > < / label >
< label class = " champ " > < span > Mémoire < / span > < input type = " number " value = " $ { echapper(s.memoire)} " placeholder = " 2048 " oninput = " definirServeur($ {i} , ' memoire ' , this.value) " > < / label >
< label class = " champ " > < span > Cœurs < / span > < input type = " number " value = " $ { echapper(s.coeurs)} " placeholder = " 2 " oninput = " definirServeur($ {i} , ' coeurs ' , this.value) " > < / label >
Mettre les noms de roles et playbooks au singulier
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>
2026-06-23 23:18:52 -04:00
< label class = " champ " > < span > Intégrations < / span > < input value = " $ { echapper(s.integrations)} " placeholder = " client_dns, … " oninput = " definirServeur($ {i} , ' integrations ' , this.value) " > < / label >
2026-06-23 22:23:36 -04:00
< button type = " button " class = " danger " title = " Retirer " onclick = " retirerServeur($ {i} ) " > ✕ < / button >
< div class = " dsn mono " > dérivé → vmid $ { echapper ( d . vmid ) } · ip $ { echapper ( d . ip ) } · vlan $ { echapper ( d . vlan ) } < / div >
< / div > ` ;
} ) . join ( ' ' ) : ' <div class= " vide " style= " padding:14px " >Aucun serveur. Utilise « + Serveur » ou make serveurs-bootstrap.</div> ' ;
2026-06-23 20:44:08 -04:00
cible . innerHTML = `
< div class = " section-grille " >
2026-06-23 22:23:36 -04:00
< div class = " section-tete " > Serveurs du plan < span class = " compte " > $ { serveurs . length } < / span > < button type = " button " class = " fantome " style = " margin-left:auto " onclick = " ajouterServeur() " > + Serveur < / button > < / div >
2026-06-23 20:44:08 -04:00
< div class = " bases-liste " > $ { lignes } < / div >
2026-06-23 22:23:36 -04:00
< div style = " margin:4px 2px 8px;display:flex;gap:8px;align-items:center;flex-wrap:wrap " >
< button type = " button " class = " primaire $ { serveursModifie ? ' attention ' : ' ' } " id = " btn-sauver-serveurs " onclick = " sauvegarderServeurs() " > Sauvegarder les serveurs $ { serveursModifie ? ' • ' : ' ' } < / button >
< button type = " button " class = " fantome " onclick = " appliquerPlan() " > ⚙ Appliquer le plan → hosts . yml < / button >
< / div >
< div class = " dsn " style = " padding:6px 2px;color:#94a3b8 " > VMID / IP / VLAN sont < b > dérivés < / b > de la fonction . « Appliquer le plan » régénère l ' inventaire (refuse si conflit ; git est le filet).</div>
2026-06-23 20:44:08 -04:00
< / div > ` ;
}
2026-06-23 22:23:36 -04:00
async function sauvegarderServeurs ( ) {
const srv = { } ;
serveurs . forEach ( s = > {
if ( ! String ( s . nom ) . trim ( ) ) return ;
const o = { fonction : s . fonction , etat : s . etat | | ' planifie ' } ;
[ ' noeud ' , ' stockage ' , ' disque ' ] . forEach ( k = > { if ( String ( s [ k ] | | ' ' ) . trim ( ) ) o [ k ] = s [ k ] ; } ) ;
[ ' memoire ' , ' coeurs ' ] . forEach ( k = > { if ( String ( s [ k ] | | ' ' ) . trim ( ) ) o [ k ] = parseInt ( s [ k ] , 10 ) | | s [ k ] ; } ) ;
const integ = listeDepuisTexte ( s . integrations ) ; if ( integ . length ) o . integrations = integ ;
srv [ s . nom ] = o ;
} ) ;
const rep = await fetch ( ' /api/serveurs ' , {
method : ' POST ' , headers : { ' Content-Type ' : ' application/json ' , ' X-Jeton ' : JETON } , body : JSON . stringify ( { serveurs : srv } )
} ) ;
const data = await rep . json ( ) ;
if ( ! rep . ok ) { message ( data . erreur | | ' Sauvegarde refusée. ' , ' erreur ' ) ; return ; }
chargerServeurs ( data ) ; dessinerServeurs ( ) ;
message ( ' Serveurs (plan) sauvegardés. Pense à « Appliquer le plan ». ' , ' ok ' ) ;
}
async function appliquerPlan ( ) {
message ( ' Application du plan… ' ) ;
const rep = await fetch ( ' /api/instancier ' , { method : ' POST ' , headers : { ' Content-Type ' : ' application/json ' , ' X-Jeton ' : JETON } , body : ' {} ' } ) ;
const data = await rep . json ( ) ;
const derniere = ( data . sortie | | ' ' ) . split ( ' \n ' ) . pop ( ) ;
message ( ( data . ok ? ' Plan appliqué : ' : ' Échec : ' ) + derniere , data . ok ? ' ok ' : ' erreur ' ) ;
if ( data . ok ) charger ( ) ;
}
2026-06-21 21:40:45 -04:00
function dessinerDependances ( ) {
const cible = document . getElementById ( ' dependances ' ) ;
const noms = Object . keys ( dependances ) . sort ( ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const bloques = noms . filter ( g = > statutDependance ( g ) == = ' bloque ' ) . length ;
const resume = document . getElementById ( ' dep-resume ' ) ;
resume . textContent = bloques ? bloques + ' bloqués ' : noms . length + ' suivis ' ;
if ( ! noms . length ) { cible . innerHTML = ' <div class= " vide " style= " padding:14px " >Aucune dépendance.</div> ' ; return ; }
2026-06-21 21:40:45 -04:00
cible . innerHTML = noms . map ( groupe = > {
const config = dependances [ groupe ] | | { } ;
const requis = config . requiert_groupes_actifs | | [ ] ;
const statut = statutDependance ( groupe ) ;
const manquants = manquantsPourGroupe ( groupe ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const detail = requis . length ? ` requiert $ { requis . join ( ' , ' ) } ` : ' aucun prérequis ' ;
const manque = requis . length & & manquants . length ? ` manquant : $ { manquants . join ( ' , ' ) } ` : ' ' ;
2026-06-21 21:40:45 -04:00
return `
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< div class = " carte-dep $ {statut} " title = " $ { echapper(config.raison || ' ' )} " >
< div class = " haut " > < span class = " nom " > $ { echapper ( groupe ) } < / span > < span class = " chip " > < span class = " pt $ { statut === ' ok ' ? ' actif ' : statut === ' bloque ' ? ' bloq ' : ' plan ' } " > < / span > $ { libelleStatut ( statut ) } < / span > < / div >
< div class = " txt " > $ { echapper ( detail ) } < / div >
$ { manque ? ` < div class = " txt " > $ { echapper ( manque ) } < / div > ` : ' ' }
< / div > ` ;
2026-06-21 21:40:45 -04:00
} ) . join ( ' ' ) ;
2026-06-21 20:35:03 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function champ ( index , cle , libelle , opts = { } ) {
const h = hotes [ index ] ;
const type = opts . type | | ' text ' ;
const attrs = [ ` type = " $ {type} " ` , ` value = " $ { echapper(h[cle] != null ? h[cle] : ' ' )} " ` ,
opts . placeholder ? ` placeholder = " $ { echapper(opts.placeholder)} " ` : ' ' ,
opts . min != null ? ` min = " $ {opts.min} " ` : ' ' , opts . max != null ? ` max = " $ {opts.max} " ` : ' ' ,
type == = ' number ' ? ' inputmode= " numeric " ' : ' ' ] . filter ( Boolean ) . join ( ' ' ) ;
const unite = opts . unite ? ` < span class = " unite " > · $ { echapper ( opts . unite ) } < / span > ` : ' ' ;
return ` < label class = " champ " > < span > $ { echapper ( libelle ) } $ { unite } < / span >
< input $ { attrs } oninput = " definir($ {index} , ' $ {cle} ' , this.value) " > < / label > ` ;
}
function tuile ( valeur , libelle ) {
const v = ( valeur == = ' ' | | valeur == null ) ? ' — ' : String ( valeur ) ;
return ` < div class = " stat " > < div class = " v $ { v === ' — ' ? ' vide ' : ' ' } " > $ { echapper ( v ) } < / div > < div class = " l " > $ { echapper ( libelle ) } < / div > < / div > ` ;
}
function dessinerDetail ( ) {
const cible = document . getElementById ( ' detail ' ) ;
if ( selection < 0 | | ! hotes [ selection ] ) {
cible . innerHTML = ' <div class= " detail " ><div class= " vide " ><b>Aucun hôte sélectionné</b>Choisissez une carte, ou ajoutez un hôte.</div></div> ' ;
2026-06-21 21:40:45 -04:00
return ;
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const index = selection , h = hotes [ index ] ;
const actif = h . etat == = ' actif ' ;
2026-06-23 20:20:40 -04:00
const info = infoFonction ( fonctionDe ( h . nom ) . fonction ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const zoneHint = info ? ` < span class = " zone-hint " title = " Dérivé de la nomenclature " > $ { echapper ( info . libelle ) } · VLAN $ { info . vlan } < / span > ` : ' ' ;
const st = statutHote ( h ) ;
const libelle = actif ? ( hoteBloque ( h ) ? ' prérequis manquant ' : ' déployable ' ) : ' planifié ' ;
let pied ;
if ( actif & & ! hoteBloque ( h ) & & estProduction ) {
pied = ` < div class = " pied " > < span class = " grandit " > < / span >
< button type = " button " id = " btn-verifier " onclick = " lancer( ' verifier ' , $ {index} ) " > Vérifier < / button >
< button type = " button " id = " btn-deployer " class = " primaire " onclick = " lancer( ' deployer ' , $ {index} ) " > Déployer < / button > < / div > ` ;
} else {
const txt = ! actif ? ' Hôte actif requis pour déployer ' : ( ! estProduction ? ' Déploiement : inventaire production requis ' : ' Prérequis manquant ' ) ;
pied = ` < div class = " pied " > < span class = " hint-dep " > $ { txt } < / span > < span class = " grandit " > < / span > < span class = " badge-statut $ {st} " > $ { libelle } < / span > < / div > ` ;
}
const onglet = ONGLETS [ ongletActif ] ;
let corps ;
if ( onglet ) {
corps = ` < div class = " grille " > $ { onglet . map ( ( [ c , l , o ] ) = > champ ( index , c , l , o ) ) . join ( ' ' ) } < / div > ` ;
} else if ( ongletActif == = ' chaine ' ) {
corps = renduChaine ( h ) ;
} else {
corps = ` < div class = " groupes-liste " > $ { groupes . map ( g = > renduGroupe ( index , h , g ) ) . join ( ' ' ) } < / div > ` ;
}
cible . innerHTML = `
< article class = " detail $ { hoteBloque(h) ? ' bloque ' : ' ' } " >
< div class = " detail-tete " >
2026-06-23 20:20:40 -04:00
< div class = " detail-nom " > < input value = " $ { echapper(h.nom || ' ' )} " placeholder = " fonction-NN (ex. web-frontal-03) " oninput = " definirNom($ {index} , this.value) " onchange = " autoProposer($ {index} ) " > $ { zoneHint } < / div >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< button type = " button " class = " fantome " title = " Proposer VMID, VLAN, IP et passerelle depuis la nomenclature " onclick = " proposer($ {index} ) " > ✨ Proposer < / button >
< div class = " etat-bascule " >
< button type = " button " class = " $ { actif ? ' on actif ' : ' ' } " onclick = " definirEtat($ {index} , ' actif ' ) " > actif < / button >
< button type = " button " class = " $ { !actif ? ' on ' : ' ' } " onclick = " definirEtat($ {index} , ' planifie ' ) " > planifié < / button >
2026-06-21 21:40:45 -04:00
< / div >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< button type = " button " class = " danger " title = " Retirer " onclick = " supprimerHote($ {index} ) " > ✕ < / button >
< / div >
< div class = " stats " >
$ { tuile ( h . vmid , ' VMID ' ) }
$ { tuile ( h . memoire ? h . memoire + ' Mo ' : ' ' , ' Mémoire ' ) }
$ { tuile ( h . coeurs , ' Cœurs ' ) }
$ { tuile ( h . disque_taille , ' Disque ' ) }
$ { tuile ( ( h . groupes | | [ ] ) . length , ' Groupes ' ) }
< / div >
< div class = " onglets " >
< button type = " button " class = " onglet $ { ongletActif === ' reseau ' ? ' actif ' : ' ' } " onclick = " setOnglet( ' reseau ' ) " > Réseau < / button >
< button type = " button " class = " onglet $ { ongletActif === ' proxmox ' ? ' actif ' : ' ' } " onclick = " setOnglet( ' proxmox ' ) " > Proxmox < / button >
< button type = " button " class = " onglet $ { ongletActif === ' groupes ' ? ' actif ' : ' ' } " onclick = " setOnglet( ' groupes ' ) " > Groupes < / button >
< button type = " button " class = " onglet $ { ongletActif === ' chaine ' ? ' actif ' : ' ' } " onclick = " setOnglet( ' chaine ' ) " > Chaîne < / button >
< / div >
< div class = " onglet-corps " > $ { corps } < / div >
$ { pied }
< / article > ` ;
majBoutonsDeploiement ( ) ;
}
function majBoutonsDeploiement ( ) {
const bv = document . getElementById ( ' btn-verifier ' ) ;
const bd = document . getElementById ( ' btn-deployer ' ) ;
const hote = selection > = 0 & & hotes [ selection ] ? ( hotes [ selection ] . nom | | ' ' ) : ' ' ;
if ( bv ) { bv . disabled = occupe | | modifie ; bv . title = modifie ? ' Sauvegardez d \' abord ' : ( occupe ? ' Exécution en cours ' : ' Dry-run (--check --diff), aucune modification ' ) ; }
if ( bd ) { bd . disabled = occupe | | modifie | | ! verifie [ hote ] ; bd . title = modifie ? ' Sauvegardez d \' abord ' : ( ! verifie [ hote ] ? ' Vérifiez (dry-run) d \' abord ' : ' Applique les playbooks sur la VM réelle ' ) ; }
2026-06-21 21:40:45 -04:00
}
function renduGroupe ( index , hote , groupe ) {
const selectionne = ( hote . groupes | | [ ] ) . includes ( groupe ) ;
const manquants = manquantsPourGroupe ( groupe ) ;
const config = dependances [ groupe ] | | { } ;
let statut = selectionne ? ' selectionne ' : ' ' ;
if ( selectionne & & hote . etat == = ' actif ' & & manquants . length ) statut = ' bloque ' ;
else if ( selectionne & & hote . etat == = ' actif ' ) statut = ' ok ' ;
else if ( selectionne & & hote . etat != = ' actif ' & & ( config . requiert_groupes_actifs | | [ ] ) . length ) statut = ' attente ' ;
return `
< label class = " groupe $ {statut} " title = " $ { echapper(titreGroupe(groupe))} " >
< span class = " groupe-ligne " >
< input type = " checkbox " $ { selectionne ? ' checked ' : ' ' } onchange = " basculerGroupe($ {index} , ' $ {groupe} ' , this.checked) " >
< span > $ { echapper ( groupe ) } < / span >
< / span >
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
< span class = " groupe-detail " > $ { echapper ( detailGroupe ( groupe , hote ) ) } < / span >
< / label > ` ;
2026-06-21 21:40:45 -04:00
}
function detailGroupe ( groupe , hote ) {
const requis = ( ( dependances [ groupe ] | | { } ) . requiert_groupes_actifs | | [ ] ) ;
if ( ! requis . length ) return ' aucun prérequis actif ' ;
const manquants = manquantsPourGroupe ( groupe ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
if ( ! manquants . length ) return ` prérequis actifs : $ { requis . join ( ' , ' ) } ` ;
if ( hote . etat == = ' actif ' ) return ` manquant : $ { manquants . join ( ' , ' ) } ` ;
return ` requerra : $ { requis . join ( ' , ' ) } ` ;
2026-06-21 20:35:03 -04:00
}
2026-06-21 21:31:03 -04:00
function titreGroupe ( groupe ) {
const config = dependances [ groupe ] | | { } ;
const requis = config . requiert_groupes_actifs | | [ ] ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const lignes = [ requis . length ? ` Prérequis actif : $ { requis . join ( ' , ' ) } ` : ' Aucun prérequis actif déclaré. ' ] ;
2026-06-21 21:40:45 -04:00
if ( config . raison ) lignes . push ( config . raison ) ;
if ( config . surveillance ) lignes . push ( config . surveillance ) ;
return lignes . join ( ' \n ' ) ;
}
2026-06-23 20:20:40 -04:00
function fonctionDe ( nom ) {
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const m = ( nom | | ' ' ) . match ( / ^ ( . + ) - ( \d + ) $ / ) ;
2026-06-23 20:20:40 -04:00
return m ? { fonction : m [ 1 ] , seq : parseInt ( m [ 2 ] , 10 ) } : { fonction : nom | | ' ' , seq : null } ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
}
2026-06-23 20:20:40 -04:00
function infoFonction ( fonction ) {
const d = ( nomenclature . fonctions | | { } ) [ fonction ] ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
if ( ! d ) return null ;
const c = ( nomenclature . categories | | { } ) [ d . categorie ] ;
if ( ! c ) return null ;
return { categorie : d . categorie , service : d . service , libelle : c . libelle , vlan : c . vlan , sous_reseau : c . sous_reseau , passerelle : c . passerelle } ;
}
2026-06-23 20:20:40 -04:00
function prochainSeqLibre ( fonction ) {
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const pris = new Set ( ) ;
2026-06-23 20:20:40 -04:00
hotes . forEach ( h = > { const x = fonctionDe ( h . nom ) ; if ( x . fonction == = fonction & & x . seq != null ) pris . add ( x . seq ) ; } ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
let s = 1 ; while ( pris . has ( s ) ) s + + ; return s ;
}
function proposer ( index , silencieux = false ) {
const h = hotes [ index ] ;
2026-06-23 20:20:40 -04:00
let { fonction , seq } = fonctionDe ( h . nom ) ;
const info = infoFonction ( fonction ) ;
if ( ! info ) { if ( ! silencieux ) message ( ' Fonction inconnue de la nomenclature : ' + ( fonction | | ' (vide) ' ) , ' erreur ' ) ; return ; }
if ( seq == null ) { seq = prochainSeqLibre ( fonction ) ; h . nom = fonction + ' - ' + String ( seq ) . padStart ( 2 , ' 0 ' ) ; selectionNom = h . nom ; }
if ( seq > 9 ) { if ( ! silencieux ) message ( ' Séquence > 9 pour ' + fonction + ' : hors plage d \' adressage, à saisir à la main. ' , ' erreur ' ) ; return ; }
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
const base3 = info . sous_reseau . split ( ' . ' ) . slice ( 0 , 3 ) . join ( ' . ' ) ;
h . vmid = ' 9 ' + info . categorie + info . service + String ( seq ) . padStart ( 2 , ' 0 ' ) ;
h . vlan = String ( info . vlan ) ;
h . adresse_ip = base3 + ' . ' + ( info . service * 10 + seq ) ;
h . passerelle = info . passerelle ;
h . cidr = String ( nomenclature . cidr_hote | | 24 ) ;
marquerModifie ( ) ; dessiner ( ) ;
if ( ! silencieux ) message ( ' Valeurs proposées pour ' + h . nom + ' ( ' + info . libelle + ' , VLAN ' + info . vlan + ' ). ' , ' ok ' ) ;
}
function autoProposer ( index ) {
const h = hotes [ index ] ;
2026-06-23 20:20:40 -04:00
if ( ! String ( h . vmid | | ' ' ) . trim ( ) & & infoFonction ( fonctionDe ( h . nom ) . fonction ) ) proposer ( index , true ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
}
2026-06-21 21:40:45 -04:00
function echapper ( valeur ) {
return String ( valeur ) . replace ( / [ & < > " ' ]/g, c => ( { ' & ' : ' & ' , ' < ' : ' < ' , ' > ' : ' > ' , ' " ' : ' & quot ; ' , " ' " : ' ' ' }[c]));
2026-06-21 21:31:03 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
function ouvrirConsole ( titre , hote ) {
document . getElementById ( ' console-titre ' ) . textContent = titre + ' · ' + hote ;
document . getElementById ( ' console-sortie ' ) . textContent = ' ' ;
const etat = document . getElementById ( ' console-etat ' ) ;
etat . className = ' console-etat actif ' ; etat . textContent = ' ● en cours ' ;
document . getElementById ( ' btn-fermer-console ' ) . disabled = true ;
document . getElementById ( ' console ' ) . hidden = false ;
}
function ecrireConsole ( t ) { const p = document . getElementById ( ' console-sortie ' ) ; p . textContent + = t ; p . scrollTop = p . scrollHeight ; }
function finirConsole ( rc ) {
const etat = document . getElementById ( ' console-etat ' ) ;
etat . className = ' console-etat ' + ( rc == = 0 ? ' ok ' : ' echec ' ) ;
etat . textContent = rc == = 0 ? ' ✓ succès ' : ' ✗ échec (rc= ' + rc + ' ) ' ;
document . getElementById ( ' btn-fermer-console ' ) . disabled = false ;
}
function fermerConsole ( ) { if ( ! occupe ) document . getElementById ( ' console ' ) . hidden = true ; }
function ouvrirModale ( titre , texte ) {
document . getElementById ( ' modale-titre ' ) . textContent = titre ;
document . getElementById ( ' modale-texte ' ) . textContent = texte ;
const champ = document . getElementById ( ' modale-vault ' ) ;
champ . value = motVault | | ' ' ;
document . getElementById ( ' modale ' ) . hidden = false ;
setTimeout ( ( ) = > champ . focus ( ) , 0 ) ;
return new Promise ( res = > { modaleResolveur = res ; } ) ;
}
function confirmerModale ( ) {
const v = document . getElementById ( ' modale-vault ' ) . value ;
document . getElementById ( ' modale ' ) . hidden = true ;
const r = modaleResolveur ; modaleResolveur = null ;
if ( r ) r ( v ) ;
}
function annulerModale ( ) {
document . getElementById ( ' modale ' ) . hidden = true ;
const r = modaleResolveur ; modaleResolveur = null ;
if ( r ) r ( null ) ;
}
async function lancer ( mode , index ) {
const hote = hotes [ index ] ? hotes [ index ] . nom : ' ' ;
if ( ! hote ) { message ( ' Nommez l \' hôte d \' abord. ' , ' erreur ' ) ; return ; }
if ( modifie ) { message ( ' Sauvegardez avant d \' exécuter. ' , ' erreur ' ) ; return ; }
if ( occupe ) return ;
let vault = ' ' ;
if ( mode == = ' deployer ' ) {
if ( ! verifie [ hote ] ) { message ( ' Vérifiez (dry-run) d \' abord. ' , ' erreur ' ) ; return ; }
vault = await ouvrirModale ( ' Déployer ' + hote ,
' Applique les playbooks de groupes sur la VM réelle, en root (sudo). Action non transactionnelle : pas de rollback automatique en cas d \' échec. ' ) ;
if ( vault == = null ) return ;
motVault = vault ;
}
occupe = true ; majBoutonsDeploiement ( ) ;
ouvrirConsole ( mode == = ' deployer ' ? ' Déploiement ' : ' Vérification (dry-run) ' , hote ) ;
try {
const rep = await fetch ( ' /api/ ' + mode , {
method : ' POST ' , headers : { ' Content-Type ' : ' application/json ' , ' X-Jeton ' : JETON } ,
body : JSON . stringify ( vault ? { hote , vault } : { hote } )
} ) ;
if ( ! rep . ok | | ! rep . body ) {
const d = await rep . json ( ) . catch ( ( ) = > ( { } ) ) ;
ecrireConsole ( ( d . erreur | | ' Refusé. ' ) + ' \n ' ) ; finirConsole ( 1 ) ;
occupe = false ; majBoutonsDeploiement ( ) ; return ;
}
const lecteur = rep . body . getReader ( ) ;
const dec = new TextDecoder ( ) ;
let rc = null ;
while ( true ) {
const { value , done } = await lecteur . read ( ) ;
if ( done ) break ;
let texte = dec . decode ( value , { stream : true } ) ;
const m = texte . match ( / __FIN__ rc = ( - ? \d + ) / ) ;
if ( m ) { rc = parseInt ( m [ 1 ] , 10 ) ; texte = texte . replace ( / \n ? __FIN__ rc = - ? \d + \n ? / , ' ' ) ; }
if ( texte ) ecrireConsole ( texte ) ;
}
if ( rc == = null ) rc = 1 ;
finirConsole ( rc ) ;
if ( mode == = ' verifier ' & & rc == = 0 ) { verifie [ hote ] = true ; message ( ' Vérification réussie — déploiement débloqué pour ' + hote + ' . ' , ' ok ' ) ; }
else if ( mode == = ' deployer ' ) { verifie [ hote ] = false ; message ( rc == = 0 ? ' Déploiement terminé. ' : ' Déploiement en échec. ' , rc == = 0 ? ' ok ' : ' erreur ' ) ; }
} catch ( e ) {
ecrireConsole ( ' Erreur client : ' + e . message + ' \n ' ) ; finirConsole ( 1 ) ;
}
occupe = false ; majBoutonsDeploiement ( ) ;
}
2026-06-21 20:35:03 -04:00
async function sauvegarder ( ) {
const reponse = await fetch ( ' /api/inventaire ' , {
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
method : ' POST ' , headers : { ' Content-Type ' : ' application/json ' , ' X-Jeton ' : JETON } , body : JSON . stringify ( { hotes } )
2026-06-21 20:35:03 -04:00
} ) ;
const data = await reponse . json ( ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
if ( ! reponse . ok ) { message ( data . erreur | | ' Sauvegarde refusée. ' , ' erreur ' ) ; return ; }
2026-06-21 21:31:03 -04:00
dependances = data . dependances | | { } ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
nomenclature = data . nomenclature | | { } ;
chaine = data . chaine | | { } ;
2026-06-21 20:35:03 -04:00
groupes = data . groupes ;
hotes = data . hotes ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
estProduction = ! ! data . production ;
modifie = false ; verifie = { } ;
restaurerSelection ( ) ;
2026-06-21 20:35:03 -04:00
dessiner ( ) ;
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
message ( ' Inventaire sauvegardé. ' , ' ok ' ) ;
2026-06-21 20:35:03 -04:00
}
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
document . addEventListener ( ' keydown ' , e = > {
if ( e . key == = ' Escape ' & & modaleResolveur ) { annulerModale ( ) ; return ; }
if ( ( e . ctrlKey | | e . metaKey ) & & e . key == = ' s ' ) { e . preventDefault ( ) ; if ( ! occupe ) sauvegarder ( ) ; }
} ) ;
charger ( ) . catch ( err = > message ( err . message , ' erreur ' ) ) ;
2026-06-21 20:35:03 -04:00
< / script >
< / body >
< / html >
"""
class Gestionnaire ( BaseHTTPRequestHandler ) :
inventaire : Path = INVENTAIRE_DEFAUT
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
def log_message ( self , * args ) - > None : # silence par defaut
pass
2026-06-21 20:35:03 -04:00
def repondre ( self , status : int , contenu : bytes , content_type : str ) - > None :
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
try :
self . send_response ( status )
self . send_header ( " Content-Type " , content_type )
self . send_header ( " Content-Length " , str ( len ( contenu ) ) )
self . end_headers ( )
self . wfile . write ( contenu )
except ( BrokenPipeError , ConnectionResetError ) :
pass # le client a ferme la connexion : rien a faire
2026-06-21 20:35:03 -04:00
def repondre_json ( self , status : int , data : dict ) - > None :
self . repondre ( status , json . dumps ( data , ensure_ascii = False ) . encode ( " utf-8 " ) , " application/json; charset=utf-8 " )
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
def _ecrire_flux ( self , texte : str ) - > bool :
try :
self . wfile . write ( texte . encode ( " utf-8 " , " replace " ) )
self . wfile . flush ( )
return True
except ( BrokenPipeError , ConnectionResetError ) :
return False
def executer_flux ( self , hote : str , mode : str , vault : str | None = None ) - > None :
if not MOTIF_HOTE . match ( hote or " " ) :
self . repondre_json ( 400 , { " erreur " : " Nom d ' hote invalide. " } )
return
if self . inventaire != INVENTAIRE_PRODUCTION :
self . repondre_json ( 409 , { " erreur " : " Deploiement reserve a l ' inventaire production. " } )
return
if hote not in hotes_actifs_fichier ( self . inventaire ) :
self . repondre_json ( 409 , { " erreur " : f " { hote } n ' est pas un hote actif sauvegarde. " } )
return
if mode == " deployer " and not VERIF_OK . get ( hote ) :
self . repondre_json ( 409 , { " erreur " : " Verification (dry-run) requise avant de deployer. " } )
return
if not VERROU . acquire ( blocking = False ) :
self . repondre_json ( 409 , { " erreur " : " Une execution est deja en cours. " } )
return
fichier_vault = None
try :
cible = " deployer " if mode == " deployer " else " verifier-deploiement "
env = dict ( os . environ , PYTHONUNBUFFERED = " 1 " , ANSIBLE_FORCE_COLOR = " 0 " )
if vault :
fd , fichier_vault = tempfile . mkstemp ( prefix = " setops-vault- " ) # 0600 par defaut
os . write ( fd , str ( vault ) . encode ( " utf-8 " ) )
os . close ( fd )
env [ " ANSIBLE_VAULT_PASSWORD_FILE " ] = fichier_vault
self . send_response ( 200 )
self . send_header ( " Content-Type " , " text/plain; charset=utf-8 " )
self . send_header ( " Cache-Control " , " no-cache " )
self . end_headers ( )
self . _ecrire_flux ( f " $ make { cible } HOTE= { hote } \n \n " )
proc = subprocess . Popen (
[ " make " , cible , f " HOTE= { hote } " ] ,
cwd = str ( RACINE ) , env = env ,
stdin = subprocess . DEVNULL ,
stdout = subprocess . PIPE , stderr = subprocess . STDOUT , text = True , bufsize = 1 ,
)
try :
for ligne in proc . stdout :
if not self . _ecrire_flux ( ligne ) :
proc . terminate ( )
break
finally :
rc = proc . wait ( )
if mode == " verifier " and rc == 0 :
VERIF_OK [ hote ] = True
elif mode == " deployer " :
VERIF_OK . pop ( hote , None )
self . _ecrire_flux ( f " \n __FIN__ rc= { rc } \n " )
finally :
if fichier_vault :
try :
os . remove ( fichier_vault )
except OSError :
pass
VERROU . release ( )
2026-06-21 20:35:03 -04:00
def do_GET ( self ) - > None :
chemin = urlparse ( self . path ) . path
try :
if chemin == " / " :
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
page = HTML . replace ( " __JETON__ " , JETON )
self . repondre ( 200 , page . encode ( " utf-8 " ) , " text/html; charset=utf-8 " )
elif chemin == " /favicon.ico " :
self . repondre ( 204 , b " " , " image/x-icon " )
2026-06-21 20:35:03 -04:00
elif chemin == " /api/inventaire " :
self . repondre_json ( 200 , inventaire_api ( self . inventaire ) )
else :
self . repondre_json ( 404 , { " erreur " : " Introuvable " } )
except Exception as exc :
self . repondre_json ( 500 , { " erreur " : str ( exc ) } )
def do_POST ( self ) - > None :
chemin = urlparse ( self . path ) . path
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
if self . headers . get ( " X-Jeton " ) != JETON :
self . repondre_json ( 403 , { " erreur " : " Jeton manquant ou invalide. " } )
return
longueur = int ( self . headers . get ( " Content-Length " , " 0 " ) or 0 )
corps = self . rfile . read ( longueur ) . decode ( " utf-8 " ) if longueur else " "
2026-06-21 20:35:03 -04:00
try :
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
donnees = json . loads ( corps ) if corps else { }
except json . JSONDecodeError :
self . repondre_json ( 400 , { " erreur " : " Corps JSON invalide. " } )
return
try :
if chemin == " /api/inventaire " :
2026-06-23 22:23:36 -04:00
self . repondre_json ( 409 , { " erreur " : " hosts.yml est genere depuis le plan. "
2026-06-24 10:04:14 -04:00
" Edite instance/plan/serveurs.yml et instance/plan/applications.yml "
2026-06-23 22:23:36 -04:00
" (vues Serveurs / Applications), puis « Appliquer le plan ». " } )
2026-06-22 19:14:12 -04:00
elif chemin == " /api/bases " :
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
valider_bases ( donnees , charger_applications ( FICHIER_APPLICATIONS ) )
2026-06-22 19:14:12 -04:00
ecrire_bases ( FICHIER_BASES , donnees )
self . repondre_json ( 200 , inventaire_api ( self . inventaire ) )
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
elif chemin == " /api/applications " :
2026-06-23 20:10:15 -04:00
valider_applications ( donnees , charger_domaines ( FICHIER_DOMAINES ) )
Faire de l'application une entite de premiere classe (BD multi-portee)
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>
2026-06-23 13:38:30 -04:00
ecrire_applications ( FICHIER_APPLICATIONS , donnees )
self . repondre_json ( 200 , inventaire_api ( self . inventaire ) )
2026-06-23 22:04:01 -04:00
elif chemin == " /api/serveurs " :
valider_serveurs ( donnees , charger_nomenclature ( FICHIER_NOMENCLATURE ) )
ecrire_serveurs ( FICHIER_SERVEURS , donnees )
self . repondre_json ( 200 , inventaire_api ( self . inventaire ) )
elif chemin == " /api/instancier " :
resultat = subprocess . run (
[ " python3 " , str ( RACINE / " scripts/instancier.py " ) , " appliquer " ] ,
capture_output = True , text = True , cwd = str ( RACINE ) )
self . repondre_json ( 200 , { " ok " : resultat . returncode == 0 ,
" sortie " : ( resultat . stdout + resultat . stderr ) . strip ( ) } )
Construire l'ecosysteme de services et outiller l'inventaire
Registres (source unique):
- docs/nomenclature.yml: domaines, VMID, plan d'adressage 10.1.0.0/16 segmente.
- docs/bases-donnees.yml: bases applicatives (1 appli -> 1 base -> 1 owner -> 1 DSN).
Roles de service:
- Reseau/edge/PKI/mail: nginx, step_ca, sendmail.
- Donnees/identite: postgresql (consommateur du registre BD), redis, openldap, keycloak.
- Observabilite: prometheus, loki, grafana.
- Supervision: icinga (coeur; Icinga Web 2 differe). Forge: forgejo.
Integrations clientes:
- clients_metriques, clients_journaux, clients_pki, clients_ldap, clients_smtp.
Inventaire et outillage:
- make inventaire-ui: refonte (cartes, theme sombre, onglets, vue Chaine VM->groupes->
playbooks->roles), saisie du provisioning, auto-proposition depuis la nomenclature,
deploiement securise (verifier/deployer, jeton anti-CSRF, verrou, mot de passe vault),
robustesse reseau (connexions fermees, favicon).
- Makefile: cible verifier-deploiement; detection d'un group_vars de production chiffre.
- Scission serveurs_web -> serveurs_web_frontaux/dorsaux; migration de l'adressage vers
10.1.x; retrait des hotes de test; planification des hotes; requirements.yml.
Chaque role valide en --syntax-check et ansible-lint (profil production).
Secrets references depuis Ansible Vault (jamais en clair); roles non testes live.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:06:11 -04:00
elif chemin == " /api/verifier " :
self . executer_flux ( str ( donnees . get ( " hote " , " " ) ) , " verifier " , donnees . get ( " vault " ) )
elif chemin == " /api/deployer " :
self . executer_flux ( str ( donnees . get ( " hote " , " " ) ) , " deployer " , donnees . get ( " vault " ) )
else :
2026-06-21 20:35:03 -04:00
self . repondre_json ( 404 , { " erreur " : " Introuvable " } )
except Exception as exc :
self . repondre_json ( 400 , { " erreur " : str ( exc ) } )
def main ( ) - > int :
parser = argparse . ArgumentParser ( description = " Interface web locale pour gerer un inventaire Set-OPS. " )
parser . add_argument ( " --inventaire " , type = Path , default = INVENTAIRE_DEFAUT )
parser . add_argument ( " --hote " , default = " 127.0.0.1 " )
parser . add_argument ( " --port " , type = int , default = 8765 )
args = parser . parse_args ( )
Gestionnaire . inventaire = args . inventaire . resolve ( )
serveur = ThreadingHTTPServer ( ( args . hote , args . port ) , Gestionnaire )
print ( f " Interface inventaire: http:// { args . hote } : { args . port } / " )
print ( f " Inventaire: { Gestionnaire . inventaire } " )
serveur . serve_forever ( )
return 0
if __name__ == " __main__ " :
raise SystemExit ( main ( ) )