123 lines
4.2 KiB
Python
123 lines
4.2 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Valide TOUS les modeles d'instance, pas seulement le socle public.
|
||
|
|
|
||
|
|
Un modele est un dossier portant un `plan/` (serveurs, applications, bases,
|
||
|
|
domaines, nomenclature). Ce script rejoue sur chacun les MEMES validateurs que
|
||
|
|
sur une instance reelle — il ne reimplemente aucune regle.
|
||
|
|
|
||
|
|
Pourquoi : les modeles assembles vivent dans un depot separe (actif commercial).
|
||
|
|
Rien ne les verifiait, et `integral` a porte pendant des semaines une application
|
||
|
|
posee sur un hote jamais declare. Un modele defectueux se propage a chaque
|
||
|
|
locataire cree depuis lui.
|
||
|
|
|
||
|
|
Decouverte des modeles :
|
||
|
|
- `exemples/modeles/*` du depot (le socle public) ;
|
||
|
|
- plus les chemins de la variable d'environnement SETOPS_MODELES
|
||
|
|
(separes par ':'). Un chemin peut designer un modele OU un dossier de
|
||
|
|
modeles. Absent = ignore en silence (le depot prive n'est pas toujours la).
|
||
|
|
|
||
|
|
Usage :
|
||
|
|
python3 scripts/modeles.py lister
|
||
|
|
python3 scripts/modeles.py verifier
|
||
|
|
SETOPS_MODELES=../Set-OPS-Modeles python3 scripts/modeles.py verifier
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import argparse
|
||
|
|
import os
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
RACINE = Path(__file__).resolve().parents[1]
|
||
|
|
MODELES_DEPOT = RACINE / "exemples" / "modeles"
|
||
|
|
VALIDATEURS = ("domaines", "serveurs", "applications", "bases_donnees")
|
||
|
|
|
||
|
|
|
||
|
|
def _est_modele(p: Path) -> bool:
|
||
|
|
return p.is_dir() and (p / "plan").is_dir()
|
||
|
|
|
||
|
|
|
||
|
|
def decouvrir() -> list[Path]:
|
||
|
|
"""Modeles du depot + ceux designes par SETOPS_MODELES. Tries, dedoublonnes."""
|
||
|
|
trouves: list[Path] = []
|
||
|
|
if MODELES_DEPOT.is_dir():
|
||
|
|
trouves += [p for p in sorted(MODELES_DEPOT.iterdir()) if _est_modele(p)]
|
||
|
|
for brut in (os.environ.get("SETOPS_MODELES") or "").split(":"):
|
||
|
|
brut = brut.strip()
|
||
|
|
if not brut:
|
||
|
|
continue
|
||
|
|
chemin = Path(brut)
|
||
|
|
if not chemin.is_absolute():
|
||
|
|
chemin = (RACINE / chemin).resolve()
|
||
|
|
if not chemin.is_dir():
|
||
|
|
continue
|
||
|
|
if _est_modele(chemin):
|
||
|
|
trouves.append(chemin)
|
||
|
|
else:
|
||
|
|
trouves += [p for p in sorted(chemin.iterdir()) if _est_modele(p)]
|
||
|
|
vus: dict[str, Path] = {}
|
||
|
|
for p in trouves:
|
||
|
|
vus.setdefault(str(p.resolve()), p)
|
||
|
|
return list(vus.values())
|
||
|
|
|
||
|
|
|
||
|
|
def verifier_un(modele: Path) -> list[str]:
|
||
|
|
"""Rejoue les 4 validateurs sur un modele. Renvoie la liste des erreurs."""
|
||
|
|
erreurs: list[str] = []
|
||
|
|
env = {**os.environ, "SETOPS_INSTANCE": str(modele)}
|
||
|
|
env.pop("SETOPS_INVENTAIRE", None)
|
||
|
|
for nom in VALIDATEURS:
|
||
|
|
r = subprocess.run([sys.executable, f"scripts/{nom}.py", "verifier"],
|
||
|
|
cwd=RACINE, env=env, capture_output=True, text=True)
|
||
|
|
if r.returncode != 0:
|
||
|
|
lignes = (r.stdout + r.stderr).strip().splitlines()
|
||
|
|
erreurs.append(f"{nom}: {lignes[-1] if lignes else 'rc!=0'}")
|
||
|
|
return erreurs
|
||
|
|
|
||
|
|
|
||
|
|
def main() -> int:
|
||
|
|
parser = argparse.ArgumentParser(description="Validation des modeles d'instance Set-OPS.")
|
||
|
|
sub = parser.add_subparsers(dest="commande", required=True)
|
||
|
|
sub.add_parser("lister", help="Liste les modeles decouverts.")
|
||
|
|
sub.add_parser("verifier", help="Valide les registres de chaque modele.")
|
||
|
|
args = parser.parse_args()
|
||
|
|
|
||
|
|
modeles = decouvrir()
|
||
|
|
if args.commande == "lister":
|
||
|
|
if not modeles:
|
||
|
|
print("Aucun modele decouvert.")
|
||
|
|
return 0
|
||
|
|
for m in modeles:
|
||
|
|
try:
|
||
|
|
rel = m.relative_to(RACINE)
|
||
|
|
except ValueError:
|
||
|
|
rel = m
|
||
|
|
print(f"{m.name} ({rel})")
|
||
|
|
return 0
|
||
|
|
|
||
|
|
if not modeles:
|
||
|
|
print("Aucun modele decouvert : rien a verifier.")
|
||
|
|
return 0
|
||
|
|
|
||
|
|
en_faute = 0
|
||
|
|
for m in modeles:
|
||
|
|
erreurs = verifier_un(m)
|
||
|
|
if erreurs:
|
||
|
|
en_faute += 1
|
||
|
|
print(f"MODELE {m.name} : INVALIDE", file=sys.stderr)
|
||
|
|
for e in erreurs:
|
||
|
|
print(f" - {e}", file=sys.stderr)
|
||
|
|
else:
|
||
|
|
print(f"MODELE {m.name} : valide")
|
||
|
|
if en_faute:
|
||
|
|
print(f"erreur: {en_faute} modele(s) invalide(s) sur {len(modeles)}.", file=sys.stderr)
|
||
|
|
return 2
|
||
|
|
print(f"Les {len(modeles)} modele(s) decouvert(s) valident.")
|
||
|
|
return 0
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
raise SystemExit(main())
|