import argparse import logging import os import sys import urllib3 from .engine import normalize_env from .loader import EXAMPLE_CONFIG, EXAMPLE_MANIFEST, load_config, load_manifest from .models import NormResult from .report import print_report from ._colors import _c urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", datefmt="%H:%M:%S", ) log = logging.getLogger(__name__) def main(): parser = argparse.ArgumentParser( description="Axway API Manager — normalisation multi-environnements", formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument("--manifest", default="apps.yaml", help="Manifeste YAML des organisations/applications (défaut: apps.yaml)") parser.add_argument("--config", default="config.json", help="Config JSON des environnements Axway (défaut: config.json)") parser.add_argument("--dry-run", action="store_true", help="Simule les actions sans appliquer de changements") parser.add_argument("--env", metavar="ENV", help="Restreindre l'exécution à cet environnement (ex: --env DEV_LAN)") parser.add_argument("--init-manifest", action="store_true", help="Génère un fichier apps.yaml d'exemple et quitte") parser.add_argument("--init-config", action="store_true", help="Génère un fichier config.json d'exemple et quitte") parser.add_argument("--verbose", action="store_true", help="Affiche les actions skip (debug)") args = parser.parse_args() if args.verbose: logging.getLogger().setLevel(logging.DEBUG) if args.init_manifest: with open(args.manifest, "w", encoding="utf-8") as f: f.write(EXAMPLE_MANIFEST) print(f"✅ Manifeste d'exemple créé : {args.manifest}") return if args.init_config: with open(args.config, "w", encoding="utf-8") as f: f.write(EXAMPLE_CONFIG) print(f"✅ Config d'exemple créée : {args.config}") return apim_user = os.environ.get("APIM_USER") apim_password = os.environ.get("APIM_PASSWORD") if not apim_user or not apim_password: log.error("Variables d'environnement APIM_USER et APIM_PASSWORD requises") sys.exit(1) for path, label in [(args.manifest, "manifeste"), (args.config, "configuration")]: if not os.path.exists(path): log.error(f"Fichier {label} introuvable : {path}") hint = "--init-manifest" if "yaml" in path else "--init-config" log.error(f" → Utilisez `{hint}` pour générer un exemple.") sys.exit(1) dry_run = args.dry_run if dry_run: log.info(_c("yellow", "Mode DRY-RUN activé — aucune modification ne sera effectuée")) else: log.warning(_c("red", "⚠️ Mode APPLY — les changements vont être appliqués sur les instances Axway !")) manifest = load_manifest(args.manifest) environments = load_config(args.config) for env in environments: env.username = apim_user env.password = apim_password log.info(f"Manifeste : {len(manifest.organizations)} org(s), {len(manifest.applications)} app(s)") if args.env: environments = [e for e in environments if e.name == args.env] if not environments: log.error(f"Aucun environnement correspondant à : {args.env!r}") sys.exit(1) log.info(f"Environnements ciblés : {[e.name for e in environments]}") results: dict[str, NormResult] = {} for env in environments: try: results[env.name] = normalize_env(env, manifest, dry_run) except Exception as e: r = NormResult() r.errors.append(f"Erreur fatale : {e}") results[env.name] = r log.exception(f"[{env.name}] Erreur fatale non gérée") print_report(results, dry_run) total_errors = sum(len(r.errors) for r in results.values()) sys.exit(1 if total_errors else 0)