Set-OPS-Public/docs/audit/schema-plan.json
Daniel Allaire 03c628d5e1 GUI : le formulaire des bases est GENERE depuis le schema
Etape 3, sur un seul registre — `bases_donnees`, le plus simple et le seul ou
observe et editable coincidaient deja. Les cinq autres gardent leurs formulaires
ecrits a la main : on ne bascule pas six vues d un coup.

CE QUI DISPARAIT DU JAVASCRIPT

Huit `<label>` en dur, trois constructions de `<option>`, et la regle qui
choisissait la source du consommateur selon la portee. Cette derniere ne vivait
que dans le JS ; elle est desormais DECLAREE au schema (`x-source-selon`), donc
lisible et gardee.

Le formulaire rend exactement les memes huit champs qu avant — verifie en
EXECUTANT le moteur sous node avec le schema et des donnees reelles, pas
seulement en passant `node --check`.

LA BOUCLE EST FERMEE DES DEUX COTES

Le chemin de SAUVEGARDE enumerait lui aussi les sept champs en dur. Un champ
ajoute au registre serait apparu au formulaire genere et aurait disparu
SILENCIEUSEMENT a l enregistrement — le pire des deux mondes. Il derive
maintenant du schema, valeurs par defaut comprises (`default`).

LA SEPARATION FORME / COHERENCE, MONTREE

  portee=groupe + consommateur APPLICATION   -> REFUSE par valider_bases
  portee=application + consommateur app      -> ACCEPTE
  secret absent                              -> REFUSE

Le schema a rempli la FORME (les defauts `groupe` et `principale` se sont
poses), le validateur a attrape l INCOHERENCE. Aucune de ces trois regles ne
s exprime en JSON Schema, et vouloir l y mettre creerait la seconde source de
verite que ce depot refuse.

CHAMPS_ECRITS_PAR_GUI COMMENCE A DISPARAITRE

Renomme CHAMPS_ECRITS_A_LA_MAIN, et `bases_donnees` en est SORTIE : sa
couverture se derive du schema. P19 lit desormais `champs_ecrits_par_gui()`, qui
reunit les deux. Le jour ou la table sera vide, elle gardera un mecanisme au
lieu d une liste.

UNE GARDE A CORRIGER AU PASSAGE

`declaration_derive()` verifiait que chaque champ declare apparait dans le
SOURCE du GUI. Pour un registre genere il n y apparait plus — c est le but.
Elle aurait crie sur precisement le progres qu elle devait constater. Les
registres generes en sont exemptes : c est P61 qui tient la promesse pour eux.

make prouver : CONFORME, 60 OK, 0 echec, 1 saute.
P07 (node --check), P19 (couverture), P61 (schema) : verts.

Reste : les cinq autres vues, et le trou de la nomenclature — que le passage au
generateur fermera par construction, puisque le schema decrit deja `categorie`
et `service`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-08 15:30:08 -04:00

381 lines
11 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "GENERE par scripts/schema_plan.py (make schema). Ne pas editer a la main. Decrit la FORME des registres ; la COHERENCE reste aux validateurs de inventory_rules.py.",
"registres": {
"applications": {
"entite": {
"additionalProperties": false,
"properties": {
"expose": {
"description": "FQDN publies par l'edge. Derivent le vhost, les SAN et le plancher /etc/hosts.",
"items": {
"type": "string"
},
"title": "Exposition publique",
"type": "array"
},
"groupe": {
"description": "La capacite appliquee. Doit avoir un playbook homonyme.",
"title": "Groupe (rôle)",
"type": "string",
"x-source-valeurs": "groupes_operationnels"
},
"hote": {
"description": "Une VM declaree au plan. Un hote inconnu est un « hote fantome » (P06).",
"title": "Hôte",
"type": "string",
"x-source-valeurs": "serveurs"
},
"liens": {
"description": "Roles acceptes par le role porteur (meta/liens.yml).",
"items": {
"type": "object"
},
"title": "Liens (bindings)",
"type": "array"
},
"port": {
"title": "Port",
"type": "integer"
},
"requiert": {
"description": "Dependance applicative. Indicative : l'ordre de deploiement vient des couches.",
"items": {
"type": "string"
},
"title": "Requiert",
"type": "array"
},
"websocket": {
"description": "L'edge doit relayer la mise a niveau de connexion.",
"title": "WebSocket",
"type": "boolean"
}
},
"required": [
"groupe",
"hote"
],
"type": "object"
},
"title": "Applications",
"x-clef": {
"description": "Nom de l'application dans le plan.",
"title": "Identifiant"
},
"x-fichier": "plan/applications.yml",
"x-racine": "applications"
},
"bases_donnees": {
"entite": {
"additionalProperties": false,
"properties": {
"base": {
"title": "Base",
"type": "string"
},
"consommateur": {
"description": "Qui utilise cette base. La liste depend de la portee.",
"title": "Consommateur",
"type": "string",
"x-source-selon": {
"cas": {
"application": "applications",
"hote": "serveurs"
},
"champ": "portee",
"defaut": "groupes_operationnels"
}
},
"portee": {
"default": "groupe",
"description": "Comment le consommateur est designe : par application, par groupe ou par hote.",
"enum": [
"application",
"groupe",
"hote"
],
"title": "Portée",
"type": "string"
},
"proprietaire": {
"title": "Propriétaire",
"type": "string"
},
"secret": {
"description": "NOM d'une variable Vault, jamais une valeur. Le secret ne quitte pas le role.",
"title": "Secret (Vault)",
"type": "string"
},
"serveur": {
"title": "Serveur de BD",
"type": "string",
"x-source-valeurs": "serveurs_bd"
},
"usage": {
"default": "principale",
"title": "Usage",
"type": "string"
}
},
"required": [
"base",
"consommateur",
"proprietaire",
"secret",
"serveur"
],
"type": "object"
},
"title": "Bases de donnees",
"x-clef": {
"description": "Nom de l'entree au registre, ex. `bd_forgejo`.",
"title": "Identifiant"
},
"x-fichier": "plan/bases-donnees.yml",
"x-racine": "bases_donnees"
},
"domaines_publics": {
"entite": {
"additionalProperties": false,
"properties": {
"autorite": {
"enum": [
"auto-heberge",
"delegue",
"primaire-cache"
],
"title": "Autorité DNS",
"type": "string"
},
"dnssec": {
"title": "DNSSEC",
"type": "boolean"
},
"edge": {
"title": "Edge",
"type": "string",
"x-source-valeurs": "serveurs"
},
"mail": {
"description": "La zone porte des enregistrements de messagerie.",
"title": "Courriel",
"type": "boolean"
},
"secondaires": {
"items": {
"type": "string"
},
"title": "Secondaires",
"type": "array"
}
},
"type": "object"
},
"title": "Domaines publics",
"x-clef": {
"description": "Le nom public, ex. `chezlepro.ca`.",
"title": "Domaine"
},
"x-fichier": "plan/domaines.yml",
"x-racine": "domaines_publics"
},
"nomenclature": {
"entite": {
"additionalProperties": false,
"properties": {
"categories": {
"additionalProperties": {
"additionalProperties": false,
"properties": {
"libelle": {
"description": "Nom lisible de la zone (Frontiere, Identite...).",
"title": "Libellé",
"type": "string"
}
},
"required": [
"libelle"
],
"type": "object"
},
"description": "Une zone de securite par cle. Le numero derive le 3e octet et le VLAN.",
"title": "Catégories (zones)",
"type": "object"
},
"cidr_hote": {
"title": "CIDR d'hote",
"type": "integer"
},
"fonctions": {
"additionalProperties": {
"additionalProperties": false,
"properties": {
"categorie": {
"description": "La zone. Fixe le 3e octet (15 + categorie) et le VLAN.",
"title": "Catégorie",
"type": "integer"
},
"service": {
"description": "Fixe le bloc d'adresses de l'hote dans la zone.",
"title": "Service",
"type": "integer"
}
},
"required": [
"categorie",
"service"
],
"type": "object"
},
"description": "categorie + service par fonction. VMID et IP en derivent.",
"title": "Fonctions",
"type": "object"
},
"index": {
"description": "LE seul champ d'adressage. Tout en derive ; P20 refuse d'en stocker un autre.",
"maximum": 255,
"minimum": 0,
"title": "Index (seed)",
"type": "integer"
},
"reservations": {
"additionalProperties": {
"additionalProperties": false,
"properties": {
"passerelle": {
"description": "Dernier octet de la passerelle. P23 refuse un SVI qui s'en ecarte.",
"title": "Passerelle",
"type": "integer"
},
"reserve_max": {
"title": "Réserve (max)",
"type": "integer"
},
"reserve_min": {
"title": "Réserve (min)",
"type": "integer"
}
},
"type": "object"
},
"description": "Adresses soustraites a la derivation dans chaque zone.",
"title": "Réservations",
"type": "object"
}
},
"required": [
"index"
],
"type": "object"
},
"title": "Nomenclature",
"x-fichier": "plan/nomenclature.yml",
"x-racine": null
},
"serveurs": {
"entite": {
"additionalProperties": false,
"properties": {
"coeurs": {
"description": "Vide = derive des empreintes des roles.",
"title": "Cœurs",
"type": "integer"
},
"disque": {
"description": "Ex. `32G`. Vide = derive des empreintes des roles.",
"title": "Disque",
"type": "string"
},
"etat": {
"description": "`planifie` = decrit mais pas deploye ; `actif` = joignable par Ansible.",
"enum": [
"actif",
"planifie"
],
"title": "État",
"type": "string"
},
"fonction": {
"description": "Determine VMID, IP, VLAN et passerelle. Doit exister dans la nomenclature.",
"title": "Fonction",
"type": "string",
"x-source-valeurs": "nomenclature.fonctions"
},
"integrations": {
"description": "Seulement les facultatives. Les universelles viennent du role et sont refusees ici.",
"items": {
"type": "string"
},
"title": "Intégrations facultatives",
"type": "array"
},
"memoire": {
"description": "Vide = derive des empreintes des roles.",
"title": "Mémoire (Mo)",
"type": "integer"
},
"noeud": {
"description": "Surcharge le defaut de `make config`.",
"title": "Nœud Proxmox",
"type": "string"
},
"stockage": {
"description": "Surcharge le defaut.",
"title": "Stockage",
"type": "string"
}
},
"required": [
"fonction"
],
"type": "object"
},
"title": "Serveurs (VM)",
"x-clef": {
"description": "Le nom court de la VM. Le rang final derive l'adresse.",
"title": "Nom d'hôte"
},
"x-fichier": "plan/serveurs.yml",
"x-racine": "serveurs"
},
"serveurs_bd": {
"entite": {
"additionalProperties": false,
"properties": {
"groupe": {
"title": "Groupe",
"type": "string",
"x-source-valeurs": "groupes_operationnels"
},
"hote": {
"title": "Hôte",
"type": "string",
"x-source-valeurs": "serveurs"
},
"port": {
"title": "Port",
"type": "integer"
},
"type": {
"title": "Moteur",
"type": "string"
}
},
"required": [
"hote",
"type"
],
"type": "object"
},
"title": "Serveurs de bases de donnees",
"x-clef": {
"description": "Nom du serveur de bases, ex. `pg-principal`.",
"title": "Nom"
},
"x-fichier": "plan/bases-donnees.yml",
"x-racine": "serveurs_bd"
}
},
"title": "Registres du plan Set-OPS"
}