"""Remplit servers.domain_ltd via resolution DNS. Pour chaque serveur sans domain_ltd, essaye de resoudre hostname. en testant les domaines SANEF. Le 1er qui resout gagne. Ordre de test: sanef.groupe, sanef-rec.fr, serveur.est.sanef.fr, serveur.ouest.sanef.fr Usage: python tools/fill_domain_ltd_by_dns.py [--dry-run] [--timeout 2] """ import os import socket import threading import argparse from sqlalchemy import create_engine, text DATABASE_URL = os.getenv("DATABASE_URL_DEMO") or os.getenv("DATABASE_URL") \ or "postgresql://patchcenter:PatchCenter2026!@localhost:5432/patchcenter_demo" SUFFIXES = [ "sanef.groupe", "sanef-rec.fr", "serveur.est.sanef.fr", "serveur.ouest.sanef.fr", "sanef.fr", ] def resolve(hostname, suffix, timeout): """Retourne True si hostname.suffix resout en DNS, timeout via thread.""" fqdn = f"{hostname}.{suffix}" result = [False] def _do(): try: socket.gethostbyname(fqdn) result[0] = True except Exception: result[0] = False t = threading.Thread(target=_do, daemon=True) t.start() t.join(timeout) return result[0] def main(): parser = argparse.ArgumentParser() parser.add_argument("--dry-run", action="store_true") parser.add_argument("--timeout", type=float, default=2.0) args = parser.parse_args() engine = create_engine(DATABASE_URL) print(f"[INFO] DB: {DATABASE_URL.split('@')[-1]}") conn = engine.connect().execution_options(isolation_level="AUTOCOMMIT") rows = conn.execute(text(""" SELECT id, hostname FROM servers WHERE (domain_ltd IS NULL OR domain_ltd = '') ORDER BY hostname """)).fetchall() print(f"[INFO] {len(rows)} serveurs sans domain_ltd") updated = skipped = 0 for i, r in enumerate(rows, 1): h = (r.hostname or "").strip() if not h: skipped += 1 continue print(f" [{i}/{len(rows)}] Resolve {h}...", flush=True) found = None for suffix in SUFFIXES: if resolve(h, suffix, args.timeout): found = suffix break if not found: print(f" [NO-DNS] {h}") skipped += 1 continue if args.dry_run: print(f" DRY: {h:25s} -> {found}") else: conn.execute(text("UPDATE servers SET domain_ltd=:d WHERE id=:sid"), {"d": found, "sid": r.id}) updated += 1 conn.close() print(f"\n[DONE] Maj: {updated} | Skip (DNS KO): {skipped}") if __name__ == "__main__": main()