From cc550c2d84fd0a6c0ce90dacaff641abf14039c6 Mon Sep 17 00:00:00 2001 From: Admin MPCZ Date: Sat, 25 Apr 2026 10:31:07 +0000 Subject: [PATCH] fix(qualys/duplicates): scan async (background thread) + bandeau scan en cours - evite 503 HAProxy --- app/routers/qualys.py | 31 ++++++++++++++++++++++++---- app/templates/qualys_duplicates.html | 18 +++++++++++++--- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/app/routers/qualys.py b/app/routers/qualys.py index 742923c..668870e 100644 --- a/app/routers/qualys.py +++ b/app/routers/qualys.py @@ -1299,20 +1299,43 @@ async def qualys_dashboard_history(request: Request, db=Depends(get_db), # === DOUBLONS QUALYS === +_dupes_scan_running = False + @router.get("/qualys/duplicates", response_class=HTMLResponse) async def qualys_duplicates(request: Request, db=Depends(get_db), refresh: int = 0): + global _dupes_scan_running user = get_current_user(request) if not user: return RedirectResponse(url="/login") perms = get_user_perms(db, user) if not can_view(perms, "qualys"): return RedirectResponse(url="/dashboard") - from app.services.qualys_service import find_duplicate_hostnames - data = find_duplicate_hostnames(db, force_refresh=bool(refresh)) + from app.services.qualys_service import find_duplicate_hostnames, _cache + if refresh: + _cache.delete("qualys:duplicates") + cached = _cache.get("qualys:duplicates") + if cached is None and not _dupes_scan_running: + _dupes_scan_running = True + import threading + def _runner(): + global _dupes_scan_running + try: + from app.database import SessionLocal + ss = SessionLocal() + try: + find_duplicate_hostnames(ss, force_refresh=True) + finally: + ss.close() + finally: + _dupes_scan_running = False + threading.Thread(target=_runner, daemon=True).start() ctx = base_context(request, db, user) - ctx.update({"dupes_data": data, - "can_delete": can_edit(perms, "qualys")}) + ctx.update({"dupes_data": cached or {"total_assets": 0, "duplicate_hostnames": 0, + "total_zombies": 0, "items": []}, + "can_delete": can_edit(perms, "qualys"), + "scan_running": _dupes_scan_running and cached is None, + "from_cache": cached is not None}) return templates.TemplateResponse("qualys_duplicates.html", ctx) diff --git a/app/templates/qualys_duplicates.html b/app/templates/qualys_duplicates.html index 3b1a6da..63d5d6d 100644 --- a/app/templates/qualys_duplicates.html +++ b/app/templates/qualys_duplicates.html @@ -3,11 +3,23 @@ {% block content %}
-

Doublons Qualys (assets zombies)

- 🔄 Re-scan API +

Doublons Qualys (serveurs uniquement)

+ 🔄 Re-scan API
+{% if scan_running %} +
+
+
+
Scan API Qualys en cours...
+
Recuperation de tous les assets via API (~6000), durée typique 2 à 4 minutes. La page se rafraîchira automatiquement.
+
+
+ +{% elif from_cache %} +
Données du cache (TTL 10min). Re-scan pour forcer.
+{% endif %} +
Total assets Qualys