Referentiel: boutons sync iTop (import/export) + messages status

This commit is contained in:
Pierre & Lumière 2026-04-10 23:17:58 +02:00
parent acf20c5890
commit f73ea25d5d
2 changed files with 77 additions and 0 deletions

View File

@ -476,3 +476,55 @@ def dns_delete(request: Request, dns_id: int, db=Depends(get_db)):
db.execute(text("DELETE FROM domain_ltd_list WHERE id = :id"), {"id": dns_id})
db.commit()
return RedirectResponse(url="/referentiel?tab=dns&msg=deleted", status_code=303)
# =========================================================
# SYNC iTop
# =========================================================
@router.post("/referentiel/itop/sync-from")
def itop_sync_from(request: Request, db=Depends(get_db)):
"""Importer serveurs et contacts depuis iTop"""
user = get_current_user(request)
if not user:
return RedirectResponse(url="/login")
perms = get_user_perms(db, user)
if not can_edit(perms, "settings"):
return RedirectResponse(url="/referentiel?tab=domains")
from ..services.secrets_service import get_secret
from ..services.itop_service import sync_from_itop
itop_url = get_secret(db, "itop_url")
itop_user = get_secret(db, "itop_user")
itop_pass = get_secret(db, "itop_pass")
if not itop_url or not itop_user:
return RedirectResponse(url="/referentiel?tab=domains&msg=itop_noconfig", status_code=303)
stats = sync_from_itop(db, itop_url, itop_user, itop_pass)
msg = f"itop_from_{stats['servers_created']}_{stats['servers_updated']}_{stats['contacts_created']}_{stats['contacts_updated']}"
return RedirectResponse(url=f"/referentiel?tab=domains&msg={msg}", status_code=303)
@router.post("/referentiel/itop/sync-to")
def itop_sync_to(request: Request, db=Depends(get_db)):
"""Exporter serveurs PatchCenter vers iTop"""
user = get_current_user(request)
if not user:
return RedirectResponse(url="/login")
perms = get_user_perms(db, user)
if not can_edit(perms, "settings"):
return RedirectResponse(url="/referentiel?tab=domains")
from ..services.secrets_service import get_secret
from ..services.itop_service import sync_to_itop
itop_url = get_secret(db, "itop_url")
itop_user = get_secret(db, "itop_user")
itop_pass = get_secret(db, "itop_pass")
if not itop_url or not itop_user:
return RedirectResponse(url="/referentiel?tab=domains&msg=itop_noconfig", status_code=303)
stats = sync_to_itop(db, itop_url, itop_user, itop_pass)
msg = f"itop_to_{stats['updated']}"
return RedirectResponse(url=f"/referentiel?tab=domains&msg={msg}", status_code=303)

View File

@ -48,6 +48,31 @@
<!-- ONGLET DOMAINES -->
<!-- ============================================================ -->
{% if tab == 'domains' %}
<!-- Sync iTop -->
{% if can_modify %}
<div class="card mb-4" style="padding:12px 16px; display:flex; align-items:center; gap:12px; flex-wrap:wrap;">
<span class="text-sm text-gray-400" style="margin-right:8px">Synchronisation iTop :</span>
<form method="POST" action="/referentiel/itop/sync-from" style="display:inline">
<button type="submit" class="btn-primary" style="padding:6px 16px;font-size:0.85rem"
onclick="this.disabled=true;this.textContent='Sync en cours...';this.form.submit()">
Importer depuis iTop
</button>
</form>
<form method="POST" action="/referentiel/itop/sync-to" style="display:inline">
<button type="submit" style="padding:6px 16px;font-size:0.85rem;background:#334155;color:#e2e8f0;border:1px solid #475569;border-radius:6px;cursor:pointer"
onclick="this.disabled=true;this.textContent='Export en cours...';this.form.submit()">
Exporter vers iTop
</button>
</form>
{% if 'itop_from' in request.query_params.get('msg','') %}
<span class="text-sm text-green-400">Import iTop OK</span>
{% elif 'itop_to' in request.query_params.get('msg','') %}
<span class="text-sm text-green-400">Export iTop OK</span>
{% elif request.query_params.get('msg') == 'itop_noconfig' %}
<span class="text-sm text-red-400">Configurer iTop dans Settings</span>
{% endif %}
</div>
{% endif %}
<div class="card">
<table class="table-cyber w-full">
<thead><tr>