{ "$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" }, "x-editeur": "matrice" }, "noeud": { "type": "string", "title": "Nœud Proxmox", "description": "Surcharge le defaut de `make config`.", "x-defaut-intrant": "proxmox_clone_noeud", "x-source-valeurs": "intrants.proxmox_noeuds" }, "stockage": { "type": "string", "title": "Stockage", "description": "Surcharge le defaut de `make config`.", "x-defaut-intrant": "proxmox_clone_stockage", "x-source-valeurs": "intrants.proxmox_stockages" }, "disque": { "type": "string", "title": "Disque", "description": "Ex. `32G`. Vide = derive des empreintes des roles.", "x-defaut-derive": "disque_taille" }, "memoire": { "type": "integer", "title": "Mémoire (Mo)", "description": "Vide = derive des empreintes des roles.", "x-defaut-derive": "memoire" }, "coeurs": { "type": "integer", "title": "Cœurs", "description": "Vide = derive des empreintes des roles.", "x-defaut-derive": "coeurs" } }, "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" ] }, "x-editeur": "liens" }, "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" ] } }, "enregistrements": { "type": "array", "title": "Enregistrements publics", "description": "MX, SPF, DMARC, DKIM, CAA et noms historiques de la zone.", "items": { "type": "object", "properties": { "nom": { "type": "string", "title": "Nom", "description": "Relatif a la zone : `@`, `mx`, `_dmarc`." }, "type": { "type": "string", "title": "Type", "enum": [ "A", "AAAA", "CAA", "CNAME", "MX", "TXT" ] }, "valeur": { "type": "string", "title": "Valeur", "description": "Adresse publique, nom d'hote complet ou texte (sans guillemets)." }, "priorite": { "type": "integer", "title": "Priorite", "description": "Requise pour un MX." }, "etiquette": { "type": "string", "title": "Etiquette CAA", "enum": [ "iodef", "issue", "issuewild" ] }, "ttl": { "type": "integer", "title": "TTL", "description": "Secondes (60 a 604800) ; defaut de la zone sinon." } }, "additionalProperties": false, "required": [ "nom", "type", "valeur" ] } } }, "additionalProperties": false, "required": [ "autorite", "edge" ] }, "x-clef": { "title": "Domaine", "description": "Le nom public, ex. `chezlepro.ca`." } }, "acces_admin_vpn": { "title": "Acces d'administration (WireGuard)", "x-fichier": "plan/acces.yml", "x-racine": "acces_admin_vpn", "entite": { "type": "object", "properties": { "cle_publique": { "type": "string", "title": "Cle publique", "description": "Cle WireGuard PUBLIQUE de l'appareil (44 caracteres). La privee ne quitte jamais l'appareil." }, "adresse": { "type": "string", "title": "Adresse dans le tunnel", "description": "Un /32 du reseau derive `10..29.0/24`." }, "etat": { "type": "string", "title": "Etat", "description": "`absent` revoque l'acces au prochain passage.", "enum": [ "present", "absent" ], "default": "present" } }, "additionalProperties": false, "required": [ "adresse", "cle_publique" ] }, "x-clef": { "title": "Pair", "description": "`personne-appareil`, ex. `daniel-portable` — un pair par appareil, pour revoquer l'un sans l'autre." } }, "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" ] } } } }