This repository has been archived on 2026-06-26. You can view files and clone it, but cannot push or open issues or pull requests.
Set-OPS/scripts/applications.py
Daniel Allaire 27bb51d007 Refonte application-hub Phase 1 : liens explicites
L'application porte tous ses liens (groupe=capacite, hote=VM, port,
requiert, expose). L'exposition DNS quitte docs/domaines.yml et vit sur
l'application via 'expose' ; domaines.yml ne decrit plus que les zones.

- inventory_rules : expositions_des_applications + domaine_parent ;
  valider_applications valide requiert / expose / port.
- serveurs_nginx derive ses vhosts des applications (expose + edge),
  resolvant application -> hote -> IP (role + template reecrits).
- filter plugin : expose la nouvelle regle a Ansible.
- CLI : applications.py --port/--requiert/--expose ; domaines.py affiche
  les expositions derivees des applications.
- GUI : champs Port/Requiert/Expose sur la fiche Application (persistes ;
  corrige la perte de champs a la sauvegarde) ; l'API expose les domaines.

Le groupe n'est plus une cible de liaison, seulement une capacite.
Renommage nomenclature.domaines -> fonctions : Phase 1b. Generation de
l'inventaire depuis le plan : Phase 3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 20:10:15 -04:00

116 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""Lit et valide le registre des applications Set-OPS (docs/applications.yml)."""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
import yaml
from inventory_rules import (
bases_de_application,
chaine_connexion,
charger_applications,
charger_bases_donnees,
charger_domaines,
valider_applications,
)
RACINE = Path(__file__).resolve().parents[1]
FICHIER = RACINE / "docs/applications.yml"
FICHIER_BASES = RACINE / "docs/bases-donnees.yml"
FICHIER_DOMAINES = RACINE / "docs/domaines.yml"
def _liste(valeur: str) -> list:
return [v.strip() for v in (valeur or "").split(",") if v.strip()]
def ecrire(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 FICHIER.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)
def lister(registre: dict, bases: dict) -> None:
apps = registre.get("applications", {})
if not apps:
print("Aucune application declaree.")
return
for nom, app in apps.items():
extras = []
if app.get("port"):
extras.append(f"port {app['port']}")
if app.get("requiert"):
extras.append(f"requiert {', '.join(app['requiert'])}")
if app.get("expose"):
extras.append(f"expose {', '.join(app['expose'])}")
suffixe = (" {" + " ; ".join(extras) + "}") if extras else ""
print(f"{nom} [groupe {app.get('groupe', '?')}, hote {app.get('hote', '?')}]{suffixe}")
for entree in bases_de_application(bases, application=nom,
groupe=app.get("groupe"), hote=app.get("hote")):
base = entree["base"]
portee = base.get("portee", "groupe")
print(f" DSN ({portee}/{base.get('usage', '-')}): {chaine_connexion(base, entree['serveur'])}")
def main() -> int:
parser = argparse.ArgumentParser(description="Registre des applications Set-OPS.")
sub = parser.add_subparsers(dest="commande", required=True)
sub.add_parser("lister", help="Affiche les applications et leurs DSN resolus.")
sub.add_parser("verifier", help="Valide la coherence du registre.")
pa = sub.add_parser("ajouter", help="Ajoute ou met a jour une application.")
pa.add_argument("--id", required=True)
pa.add_argument("--groupe", required=True)
pa.add_argument("--hote", required=True)
pa.add_argument("--port", type=int)
pa.add_argument("--requiert", default="", help="Applications dont elle depend (separees par virgule).")
pa.add_argument("--expose", default="", help="FQDN publics qui la publient (separes par virgule).")
pr = sub.add_parser("retirer", help="Retire une application.")
pr.add_argument("--id", required=True)
args = parser.parse_args()
try:
registre = charger_applications(FICHIER)
domaines = charger_domaines(FICHIER_DOMAINES)
if args.commande == "lister":
lister(registre, charger_bases_donnees(FICHIER_BASES))
elif args.commande == "verifier":
valider_applications(registre, domaines)
print("Registre des applications valide.")
elif args.commande == "ajouter":
app = {"groupe": args.groupe, "hote": args.hote}
if args.port is not None:
app["port"] = args.port
if _liste(args.requiert):
app["requiert"] = _liste(args.requiert)
if _liste(args.expose):
app["expose"] = _liste(args.expose)
registre["applications"][args.id] = app
valider_applications(registre, domaines)
ecrire(registre)
print(f"Application '{args.id}' enregistree.")
elif args.commande == "retirer":
registre["applications"].pop(args.id, None)
valider_applications(registre, domaines)
ecrire(registre)
print(f"Application '{args.id}' retiree.")
except Exception as exc:
print(f"erreur: {exc}", file=sys.stderr)
return 2
return 0
if __name__ == "__main__":
raise SystemExit(main())