patchcenter/tools/import_sanef_ips.py

85 lines
2.9 KiB
Python

"""Import des IPs SANEF (export iTop 'Interface réseau') → table server_ips.
Usage:
python tools/import_sanef_ips.py <csv_path>
"""
import csv
import os
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"
def main():
parser = argparse.ArgumentParser()
parser.add_argument("csv_path")
parser.add_argument("--replace", action="store_true",
help="Vider server_ips avant l'import")
args = parser.parse_args()
engine = create_engine(DATABASE_URL)
print(f"[INFO] DB: {DATABASE_URL.split('@')[-1]}")
print(f"[INFO] CSV: {args.csv_path}")
with open(args.csv_path, "r", encoding="utf-8-sig", newline="") as f:
reader = csv.DictReader(f)
rows = list(reader)
print(f"[INFO] {len(rows)} lignes")
conn = engine.connect().execution_options(isolation_level="AUTOCOMMIT")
if args.replace:
conn.execute(text("DELETE FROM server_ips"))
print("[OK] server_ips vidé")
linked = 0
missing = 0
skipped = 0
for r in rows:
# Hostname peut venir de Machine virtuelle / Serveur / Nom selon l'export iTop
vm_name = (r.get("Machine virtuelle->Nom") or r.get("Machine virtuelle")
or r.get("Serveur->Nom") or r.get("Serveur")
or r.get("Système->Nom") or r.get("Nom") or "").strip()
if vm_name:
vm_name = vm_name.split(".")[0].lower()
ip = (r.get("Adresse IP") or r.get("IP") or "").strip()
gw = (r.get("Passerelle") or "").strip() or None
mask = (r.get("Masque de sous réseau") or "").strip() or None
vrf = (r.get("VRF") or "").strip() or None
if not vm_name or not ip:
skipped += 1
continue
srv = conn.execute(text("SELECT id FROM servers WHERE hostname=:h"),
{"h": vm_name}).fetchone()
if not srv:
missing += 1
continue
try:
existing = conn.execute(text(
"SELECT id FROM server_ips WHERE server_id=:sid AND ip_address=CAST(:ip AS inet)"
), {"sid": srv.id, "ip": ip}).fetchone()
if existing:
skipped += 1
continue
conn.execute(text("""
INSERT INTO server_ips (server_id, ip_address, is_primary, gateway, netmask, vrf)
VALUES (:sid, CAST(:ip AS inet), true, :gw, :mask, :vrf)
"""), {"sid": srv.id, "ip": ip, "gw": gw, "mask": mask, "vrf": vrf})
linked += 1
except Exception as e:
print(f" [ERR] {vm_name} {ip}: {str(e)[:150]}")
skipped += 1
conn.close()
print(f"[DONE] Liés: {linked} | Hostname introuvable: {missing} | Ignoré: {skipped}")
if __name__ == "__main__":
main()