En voulant generer deux formulaires de plus, j ai trouve pire que ce que
je cherchais.
CE QUI ETAIT DEJA LA. Les quatre ecrivains de registre ecrasaient le
fichier au safe_dump. Mesure sur les fichiers reels : domaines.yml 6->3,
applications.yml 27->5, serveurs.yml 18->3. Quarante lignes, detruites
par n importe quel clic sur Sauvegarder dans les vues Serveurs,
Applications ou Domaines. Parmi elles, celle qui explique pourquoi
backup-01 a ete retire, et celle qui dit dans quel ordre les deux roles
du runner s appliquent. C etait l incident du 2026-08-18, jamais corrige
pour les registres du plan. Les quatre passent par _ecrire_registre :
aller-retour a vide identique a l octet, sur les quatre fichiers.
TROIS ECARTS DE SCHEMA, trouves en confrontant le schema aux VALIDATEURS
et non aux seuls plans :
- edge designe un GROUPE, pas un hote. Le schema disait serveurs : un
formulaire genere aurait offert une valeur qu aucun hote ne reconnait,
donc aucun SAN, donc la panne du 2026-08-25 reintroduite ;
- exposition, entierement valide par le moteur, manquait au schema ;
- liens etait items: {type: object} — une liste d objets sans forme.
Et mail, offert par la vue Domaines depuis sa creation, decrit ici comme
un booleen, saisi la-bas comme du texte, lu par rien : retire.
P62 garde tout ca. Elle separe l entite du reste mecaniquement : un
validateur lit son entite par des variables LOCALES, les autres registres
par ses PARAMETRES. Controle negatif rejoue.
LES FORMULAIRES. Serveurs de BD et Domaines sont generes, chargement et
sauvegarde compris. Quatre registres sur six. Le generateur a appris la
liste d objets.
LIMITE : restent serveurs et applications, les deux plus gros ; et je n ai
toujours pas ouvert ces pages dans un navigateur.
make prouver : CONFORME, 61 OK, 0 echec, 1 saute (62 preuves).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
432 lines
13 KiB
JSON
432 lines
13 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"title": "Registres du plan Set-OPS",
|
|
"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": {
|
|
"serveurs": {
|
|
"title": "Serveurs (VM)",
|
|
"x-fichier": "plan/serveurs.yml",
|
|
"x-racine": "serveurs",
|
|
"entite": {
|
|
"type": "object",
|
|
"properties": {
|
|
"fonction": {
|
|
"type": "string",
|
|
"title": "Fonction",
|
|
"description": "Determine VMID, IP, VLAN et passerelle. Doit exister dans la nomenclature.",
|
|
"x-source-valeurs": "nomenclature.fonctions"
|
|
},
|
|
"etat": {
|
|
"type": "string",
|
|
"title": "État",
|
|
"description": "`planifie` = decrit mais pas deploye ; `actif` = joignable par Ansible.",
|
|
"enum": [
|
|
"actif",
|
|
"planifie"
|
|
]
|
|
},
|
|
"integrations": {
|
|
"type": "array",
|
|
"title": "Intégrations facultatives",
|
|
"description": "Seulement les facultatives. Les universelles viennent du role et sont refusees ici.",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"noeud": {
|
|
"type": "string",
|
|
"title": "Nœud Proxmox",
|
|
"description": "Surcharge le defaut de `make config`."
|
|
},
|
|
"stockage": {
|
|
"type": "string",
|
|
"title": "Stockage",
|
|
"description": "Surcharge le defaut."
|
|
},
|
|
"disque": {
|
|
"type": "string",
|
|
"title": "Disque",
|
|
"description": "Ex. `32G`. Vide = derive des empreintes des roles."
|
|
},
|
|
"memoire": {
|
|
"type": "integer",
|
|
"title": "Mémoire (Mo)",
|
|
"description": "Vide = derive des empreintes des roles."
|
|
},
|
|
"coeurs": {
|
|
"type": "integer",
|
|
"title": "Cœurs",
|
|
"description": "Vide = derive des empreintes des roles."
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"fonction"
|
|
]
|
|
},
|
|
"x-clef": {
|
|
"title": "Nom d'hôte",
|
|
"description": "Le nom court de la VM. Le rang final derive l'adresse."
|
|
}
|
|
},
|
|
"applications": {
|
|
"title": "Applications",
|
|
"x-fichier": "plan/applications.yml",
|
|
"x-racine": "applications",
|
|
"entite": {
|
|
"type": "object",
|
|
"properties": {
|
|
"groupe": {
|
|
"type": "string",
|
|
"title": "Groupe (rôle)",
|
|
"description": "La capacite appliquee. Doit avoir un playbook homonyme.",
|
|
"x-source-valeurs": "groupes_operationnels"
|
|
},
|
|
"hote": {
|
|
"type": "string",
|
|
"title": "Hôte",
|
|
"description": "Une VM declaree au plan. Un hote inconnu est un « hote fantome » (P06).",
|
|
"x-source-valeurs": "serveurs"
|
|
},
|
|
"port": {
|
|
"type": "integer",
|
|
"title": "Port"
|
|
},
|
|
"expose": {
|
|
"type": "array",
|
|
"title": "Exposition publique",
|
|
"description": "FQDN publies par l'edge. Derivent le vhost, les SAN et le plancher /etc/hosts.",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"requiert": {
|
|
"type": "array",
|
|
"title": "Requiert",
|
|
"description": "Dependance applicative. Indicative : l'ordre de deploiement vient des couches.",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"liens": {
|
|
"type": "array",
|
|
"title": "Liens (bindings)",
|
|
"description": "Roles acceptes par le role porteur (meta/liens.yml).",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"vers": {
|
|
"type": "string",
|
|
"title": "Vers",
|
|
"description": "L'application liee.",
|
|
"x-source-valeurs": "applications"
|
|
},
|
|
"role": {
|
|
"type": "string",
|
|
"title": "Rôle",
|
|
"description": "Le role du lien, accepte par meta/liens.yml."
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"role",
|
|
"vers"
|
|
]
|
|
}
|
|
},
|
|
"websocket": {
|
|
"type": "boolean",
|
|
"title": "WebSocket",
|
|
"description": "L'edge doit relayer la mise a niveau de connexion."
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"groupe",
|
|
"hote"
|
|
]
|
|
},
|
|
"x-clef": {
|
|
"title": "Identifiant",
|
|
"description": "Nom de l'application dans le plan."
|
|
}
|
|
},
|
|
"bases_donnees": {
|
|
"title": "Bases de donnees",
|
|
"x-fichier": "plan/bases-donnees.yml",
|
|
"x-racine": "bases_donnees",
|
|
"entite": {
|
|
"type": "object",
|
|
"properties": {
|
|
"serveur": {
|
|
"type": "string",
|
|
"title": "Serveur de BD",
|
|
"x-source-valeurs": "serveurs_bd"
|
|
},
|
|
"base": {
|
|
"type": "string",
|
|
"title": "Base"
|
|
},
|
|
"proprietaire": {
|
|
"type": "string",
|
|
"title": "Propriétaire"
|
|
},
|
|
"secret": {
|
|
"type": "string",
|
|
"title": "Secret (Vault)",
|
|
"description": "NOM d'une variable Vault, jamais une valeur. Le secret ne quitte pas le role."
|
|
},
|
|
"consommateur": {
|
|
"type": "string",
|
|
"title": "Consommateur",
|
|
"description": "Qui utilise cette base. La liste depend de la portee.",
|
|
"x-source-selon": {
|
|
"champ": "portee",
|
|
"cas": {
|
|
"hote": "serveurs",
|
|
"application": "applications"
|
|
},
|
|
"defaut": "groupes_operationnels"
|
|
}
|
|
},
|
|
"portee": {
|
|
"type": "string",
|
|
"title": "Portée",
|
|
"description": "Comment le consommateur est designe : par application, par groupe ou par hote.",
|
|
"enum": [
|
|
"application",
|
|
"groupe",
|
|
"hote"
|
|
],
|
|
"default": "groupe"
|
|
},
|
|
"usage": {
|
|
"type": "string",
|
|
"title": "Usage",
|
|
"default": "principale"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"base",
|
|
"consommateur",
|
|
"proprietaire",
|
|
"secret",
|
|
"serveur"
|
|
]
|
|
},
|
|
"x-clef": {
|
|
"title": "Identifiant",
|
|
"description": "Nom de l'entree au registre, ex. `bd_forgejo`."
|
|
}
|
|
},
|
|
"serveurs_bd": {
|
|
"title": "Serveurs de bases de donnees",
|
|
"x-fichier": "plan/bases-donnees.yml",
|
|
"x-racine": "serveurs_bd",
|
|
"entite": {
|
|
"type": "object",
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"title": "Moteur"
|
|
},
|
|
"hote": {
|
|
"type": "string",
|
|
"title": "Hôte",
|
|
"x-source-valeurs": "serveurs"
|
|
},
|
|
"port": {
|
|
"type": "integer",
|
|
"title": "Port"
|
|
},
|
|
"groupe": {
|
|
"type": "string",
|
|
"title": "Groupe",
|
|
"x-source-valeurs": "groupes_operationnels"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"hote",
|
|
"type"
|
|
]
|
|
},
|
|
"x-clef": {
|
|
"title": "Nom",
|
|
"description": "Nom du serveur de bases, ex. `pg-principal`."
|
|
}
|
|
},
|
|
"domaines_publics": {
|
|
"title": "Domaines publics",
|
|
"x-fichier": "plan/domaines.yml",
|
|
"x-racine": "domaines_publics",
|
|
"entite": {
|
|
"type": "object",
|
|
"properties": {
|
|
"autorite": {
|
|
"type": "string",
|
|
"title": "Autorité DNS",
|
|
"enum": [
|
|
"auto-heberge",
|
|
"delegue",
|
|
"primaire-cache"
|
|
]
|
|
},
|
|
"edge": {
|
|
"type": "string",
|
|
"title": "Edge",
|
|
"description": "Le GROUPE Ansible qui sert cette zone (ex. serveur_nginx).",
|
|
"x-source-valeurs": "groupes_edge"
|
|
},
|
|
"secondaires": {
|
|
"type": "array",
|
|
"title": "Secondaires",
|
|
"description": "Serveurs DNS secondaires de la zone.",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"dnssec": {
|
|
"type": "boolean",
|
|
"title": "DNSSEC"
|
|
},
|
|
"exposition": {
|
|
"type": "array",
|
|
"title": "Expositions declarees",
|
|
"description": "FQDN publies pour cette zone, vers un groupe cible.",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"nom": {
|
|
"type": "string",
|
|
"title": "Nom",
|
|
"description": "Sous-domaine, ou `@` pour la zone elle-meme."
|
|
},
|
|
"cible": {
|
|
"type": "string",
|
|
"title": "Cible",
|
|
"description": "Le groupe interne qui sert ce nom.",
|
|
"x-source-valeurs": "groupes_operationnels"
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"title": "Type",
|
|
"default": "web"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"cible",
|
|
"nom"
|
|
]
|
|
}
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"autorite",
|
|
"edge"
|
|
]
|
|
},
|
|
"x-clef": {
|
|
"title": "Domaine",
|
|
"description": "Le nom public, ex. `chezlepro.ca`."
|
|
}
|
|
},
|
|
"nomenclature": {
|
|
"title": "Nomenclature",
|
|
"x-fichier": "plan/nomenclature.yml",
|
|
"x-racine": null,
|
|
"entite": {
|
|
"type": "object",
|
|
"properties": {
|
|
"index": {
|
|
"type": "integer",
|
|
"title": "Index (seed)",
|
|
"description": "LE seul champ d'adressage. Tout en derive ; P20 refuse d'en stocker un autre.",
|
|
"minimum": 0,
|
|
"maximum": 255
|
|
},
|
|
"cidr_hote": {
|
|
"type": "integer",
|
|
"title": "CIDR d'hôte",
|
|
"description": "Masque des sous-reseaux de zone. 24 = 254 hotes par zone."
|
|
},
|
|
"categories": {
|
|
"type": "object",
|
|
"title": "Catégories (zones)",
|
|
"description": "Une zone de securite par cle. Le numero derive le 3e octet et le VLAN.",
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"properties": {
|
|
"libelle": {
|
|
"type": "string",
|
|
"title": "Libellé",
|
|
"description": "Nom lisible de la zone (Frontiere, Identite...)."
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"libelle"
|
|
]
|
|
}
|
|
},
|
|
"fonctions": {
|
|
"type": "object",
|
|
"title": "Fonctions",
|
|
"description": "categorie + service par fonction. VMID et IP en derivent.",
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"properties": {
|
|
"categorie": {
|
|
"type": "integer",
|
|
"title": "Catégorie",
|
|
"description": "La zone. Fixe le 3e octet (15 + categorie) et le VLAN.",
|
|
"x-source-valeurs": "nomenclature.categories"
|
|
},
|
|
"service": {
|
|
"type": "integer",
|
|
"title": "Service",
|
|
"description": "Fixe le bloc d'adresses de l'hote dans la zone."
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"categorie",
|
|
"service"
|
|
]
|
|
}
|
|
},
|
|
"reservations": {
|
|
"type": "object",
|
|
"title": "Réservations",
|
|
"description": "Adresses soustraites a la derivation dans la zone.",
|
|
"properties": {
|
|
"passerelle": {
|
|
"type": "integer",
|
|
"title": "Passerelle",
|
|
"description": "Dernier octet de la passerelle. P23 refuse un SVI qui s'en ecarte."
|
|
},
|
|
"reserve_min": {
|
|
"type": "integer",
|
|
"title": "Réserve (min)",
|
|
"description": "Premier octet soustrait a la derivation."
|
|
},
|
|
"reserve_max": {
|
|
"type": "integer",
|
|
"title": "Réserve (max)",
|
|
"description": "Dernier octet soustrait a la derivation."
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"index"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|