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>
127 lines
5.2 KiB
Python
127 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Gere le registre des bases de donnees Set-OPS (CLI, miroir de make inventaire-ui)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
from inventory_rules import (
|
|
chaine_connexion,
|
|
charger_applications,
|
|
charger_bases_donnees,
|
|
valider_bases,
|
|
)
|
|
|
|
RACINE = Path(__file__).resolve().parents[1]
|
|
FICHIER = RACINE / "docs/bases-donnees.yml"
|
|
FICHIER_APPLICATIONS = RACINE / "docs/applications.yml"
|
|
|
|
|
|
def ecrire(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"
|
|
"# 'portee' (application|groupe|hote) interprete 'consommateur' ; defaut groupe.\n"
|
|
"# 'secret' nomme une variable Ansible Vault (jamais le mot de passe).\n"
|
|
"---\n"
|
|
)
|
|
contenu = {
|
|
"serveurs_bd": registre.get("serveurs_bd", {}) or {},
|
|
"bases_donnees": registre.get("bases_donnees", {}) or {},
|
|
}
|
|
with FICHIER.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)
|
|
|
|
|
|
def lister(registre: dict) -> None:
|
|
serveurs = registre.get("serveurs_bd", {})
|
|
print("Serveurs de bases de donnees:")
|
|
for nom, srv in serveurs.items():
|
|
print(f" {nom}: {srv.get('type')} {srv.get('hote')}:{srv.get('port')} (groupe {srv.get('groupe', '-')})")
|
|
print("Bases applicatives:")
|
|
for cle, base in registre.get("bases_donnees", {}).items():
|
|
srv = serveurs.get(base.get("serveur"), {})
|
|
conso = base.get("consommateur", "?")
|
|
portee = base.get("portee", "groupe")
|
|
usage = base.get("usage", "-")
|
|
print(f" {cle} <- {conso} [{portee}/{usage}]: {chaine_connexion(base, srv)} [secret {base.get('secret')}]")
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Registre des bases de donnees Set-OPS.")
|
|
sub = parser.add_subparsers(dest="commande", required=True)
|
|
sub.add_parser("lister", help="Affiche serveurs, bases et chaines de connexion.")
|
|
sub.add_parser("verifier", help="Valide la coherence du registre.")
|
|
|
|
ps = sub.add_parser("ajouter-serveur", help="Ajoute ou met a jour un serveur de BD.")
|
|
ps.add_argument("--nom", required=True)
|
|
ps.add_argument("--type", default="postgres")
|
|
ps.add_argument("--hote", required=True)
|
|
ps.add_argument("--port", type=int, default=5432)
|
|
ps.add_argument("--groupe", default="")
|
|
|
|
pb = sub.add_parser("ajouter-base", help="Ajoute ou met a jour une base applicative.")
|
|
pb.add_argument("--cle", required=True)
|
|
pb.add_argument("--serveur", required=True)
|
|
pb.add_argument("--base", required=True)
|
|
pb.add_argument("--proprietaire", required=True)
|
|
pb.add_argument("--secret", required=True)
|
|
pb.add_argument("--consommateur", required=True,
|
|
help="Qui utilise la base : groupe, hote ou id d'application (selon --portee).")
|
|
pb.add_argument("--portee", default="groupe", choices=["groupe", "hote", "application"])
|
|
pb.add_argument("--usage", default="principale")
|
|
|
|
pr = sub.add_parser("retirer-base", help="Retire une base applicative.")
|
|
pr.add_argument("--cle", required=True)
|
|
prs = sub.add_parser("retirer-serveur", help="Retire un serveur de BD.")
|
|
prs.add_argument("--nom", required=True)
|
|
|
|
args = parser.parse_args()
|
|
try:
|
|
registre = charger_bases_donnees(FICHIER)
|
|
applications = charger_applications(FICHIER_APPLICATIONS)
|
|
if args.commande == "lister":
|
|
lister(registre)
|
|
elif args.commande == "verifier":
|
|
valider_bases(registre, applications)
|
|
print("Registre des bases valide.")
|
|
elif args.commande == "ajouter-serveur":
|
|
registre["serveurs_bd"][args.nom] = {
|
|
"type": args.type, "hote": args.hote, "port": args.port,
|
|
**({"groupe": args.groupe} if args.groupe else {}),
|
|
}
|
|
valider_bases(registre, applications)
|
|
ecrire(registre)
|
|
print(f"Serveur de BD '{args.nom}' enregistre.")
|
|
elif args.commande == "ajouter-base":
|
|
registre["bases_donnees"][args.cle] = {
|
|
"serveur": args.serveur, "base": args.base,
|
|
"proprietaire": args.proprietaire, "secret": args.secret,
|
|
"consommateur": args.consommateur, "portee": args.portee, "usage": args.usage,
|
|
}
|
|
valider_bases(registre, applications)
|
|
ecrire(registre)
|
|
print(f"Base '{args.cle}' enregistree.")
|
|
elif args.commande == "retirer-base":
|
|
registre["bases_donnees"].pop(args.cle, None)
|
|
valider_bases(registre, applications)
|
|
ecrire(registre)
|
|
print(f"Base '{args.cle}' retiree.")
|
|
elif args.commande == "retirer-serveur":
|
|
registre["serveurs_bd"].pop(args.nom, None)
|
|
valider_bases(registre, applications)
|
|
ecrire(registre)
|
|
print(f"Serveur de BD '{args.nom}' retire.")
|
|
except Exception as exc:
|
|
print(f"erreur: {exc}", file=sys.stderr)
|
|
return 2
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|