Export CSV: serveurs sans agent + agents inactifs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5db47c497f
commit
7f5e5c83eb
@ -479,6 +479,58 @@ async def qualys_agents_page(request: Request, db=Depends(get_db)):
|
||||
return templates.TemplateResponse("qualys_agents.html", ctx)
|
||||
|
||||
|
||||
@router.get("/qualys/agents/export-no-agent")
|
||||
async def export_no_agent_csv(request: Request, db=Depends(get_db)):
|
||||
user = get_current_user(request)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login")
|
||||
import io, csv as _csv
|
||||
rows = db.execute(text("""
|
||||
SELECT s.hostname, s.os_family, s.etat, d.name as domain, e.name as env, z.name as zone
|
||||
FROM servers s
|
||||
LEFT JOIN domain_environments de ON s.domain_env_id = de.id
|
||||
LEFT JOIN domains d ON de.domain_id = d.id
|
||||
LEFT JOIN environments e ON de.environment_id = e.id
|
||||
LEFT JOIN zones z ON s.zone_id = z.id
|
||||
WHERE NOT EXISTS (SELECT 1 FROM qualys_assets qa WHERE LOWER(qa.hostname) = LOWER(s.hostname))
|
||||
ORDER BY s.hostname
|
||||
""")).fetchall()
|
||||
output = io.StringIO()
|
||||
w = _csv.writer(output, delimiter=";")
|
||||
w.writerow(["Hostname", "OS", "Domaine", "Environnement", "Zone", "Etat"])
|
||||
for r in rows:
|
||||
w.writerow([r.hostname, r.os_family or "", r.domain or "", r.env or "", r.zone or "", r.etat or ""])
|
||||
output.seek(0)
|
||||
return StreamingResponse(
|
||||
iter(["\ufeff" + output.getvalue()]),
|
||||
media_type="text/csv",
|
||||
headers={"Content-Disposition": "attachment; filename=serveurs_sans_agent.csv"})
|
||||
|
||||
|
||||
@router.get("/qualys/agents/export-inactive")
|
||||
async def export_inactive_csv(request: Request, db=Depends(get_db)):
|
||||
user = get_current_user(request)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login")
|
||||
import io, csv as _csv
|
||||
rows = db.execute(text("""
|
||||
SELECT qa.hostname, qa.os, qa.agent_version, qa.last_checkin, s.etat
|
||||
FROM qualys_assets qa LEFT JOIN servers s ON qa.server_id = s.id
|
||||
WHERE qa.agent_status ILIKE '%inactive%' ORDER BY qa.hostname
|
||||
""")).fetchall()
|
||||
output = io.StringIO()
|
||||
w = _csv.writer(output, delimiter=";")
|
||||
w.writerow(["Hostname", "OS", "Version agent", "Dernier check-in", "Etat"])
|
||||
for r in rows:
|
||||
lc = str(r.last_checkin)[:10] if r.last_checkin else ""
|
||||
w.writerow([r.hostname, r.os or "", r.agent_version or "", lc, r.etat or ""])
|
||||
output.seek(0)
|
||||
return StreamingResponse(
|
||||
iter(["\ufeff" + output.getvalue()]),
|
||||
media_type="text/csv",
|
||||
headers={"Content-Disposition": "attachment; filename=agents_inactifs.csv"})
|
||||
|
||||
|
||||
@router.get("/qualys/vulns/{ip}", response_class=HTMLResponse)
|
||||
async def qualys_vulns_detail(request: Request, ip: str, db=Depends(get_db)):
|
||||
"""Retourne le detail des vulns severity 3,4,5 pour une IP (fragment HTMX)"""
|
||||
|
||||
@ -87,7 +87,8 @@
|
||||
{% if no_agent_servers %}
|
||||
<div class="card p-4 mb-4" x-data="{fHost:'', fOs:'', fDom:'', fEnv:'', fEtat:''}">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<h3 class="text-sm font-bold text-cyber-red">Serveurs sans agent Qualys (<span x-text="document.querySelectorAll('#noagent-body tr:not([style*=none])').length">{{ no_agent_servers|length }}</span>)</h3>
|
||||
<h3 class="text-sm font-bold text-cyber-red">Serveurs sans agent Qualys ({{ no_agent_servers|length }})</h3>
|
||||
<a href="/qualys/agents/export-no-agent" class="btn-sm bg-cyber-green text-black px-3 py-1 text-xs">Exporter CSV</a>
|
||||
</div>
|
||||
<div class="flex gap-2 mb-3">
|
||||
<input type="text" x-model="fHost" placeholder="Hostname..." class="text-xs py-1 px-2 flex-1 font-mono">
|
||||
@ -147,7 +148,10 @@
|
||||
<!-- Agents inactifs -->
|
||||
{% if inactive_agents %}
|
||||
<div id="inactive-list" class="card p-4 mb-4">
|
||||
<h3 class="text-sm font-bold text-cyber-red mb-3">* Agents inactifs ({{ inactive_agents|length }})</h3>
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<h3 class="text-sm font-bold text-cyber-red">* Agents inactifs ({{ inactive_agents|length }})</h3>
|
||||
<a href="/qualys/agents/export-inactive" class="btn-sm bg-cyber-green text-black px-3 py-1 text-xs">Exporter CSV</a>
|
||||
</div>
|
||||
<div class="card p-3 mb-3 text-xs text-gray-400" style="background:#111827;">
|
||||
<b>* Légende :</b> Ces serveurs ont un agent Qualys installé mais qui ne communique plus avec le cloud Qualys.
|
||||
Causes possibles : serveur éteint, flux réseau bloqué (port 443 vers qualysagent.qualys.eu), agent crashé, ou OS non supporté (RHEL 5 EOL).
|
||||
|
||||
Loading…
Reference in New Issue
Block a user