Fix: inclure status partial (serveurs Ayoub) dans toutes les requetes audit/patching/dashboard

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalid MOUTAOUAKIL 2026-04-06 18:20:33 +02:00
parent dc3efd081e
commit 390a162cf4
3 changed files with 34 additions and 34 deletions

View File

@ -64,8 +64,8 @@ async def audit_full_list(request: Request, db=Depends(get_db)):
COUNT(*) FILTER (WHERE services::text ~* 'docker|podman' OR processes::text ~* 'dockerd|podman') as app_container, COUNT(*) FILTER (WHERE services::text ~* 'docker|podman' OR processes::text ~* 'dockerd|podman') as app_container,
COUNT(*) FILTER (WHERE listen_ports::text ~* '"java"' OR processes::text ~* '\.jar') as app_java COUNT(*) FILTER (WHERE listen_ports::text ~* '"java"' OR processes::text ~* '\.jar') as app_java
FROM server_audit_full FROM server_audit_full
WHERE status = 'ok' WHERE status IN ('ok','partial')
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
""")).fetchone() """)).fetchone()
# Domaines + zones pour le filtre # Domaines + zones pour le filtre
@ -85,17 +85,17 @@ async def audit_full_list(request: Request, db=Depends(get_db)):
elif filtre == "disk_critical": elif filtre == "disk_critical":
ids = {r.id for r in db.execute(text(""" ids = {r.id for r in db.execute(text("""
SELECT saf.id FROM server_audit_full saf SELECT saf.id FROM server_audit_full saf
WHERE saf.status = 'ok' AND EXISTS ( WHERE saf.status IN ('ok','partial') AND EXISTS (
SELECT 1 FROM jsonb_array_elements(saf.disk_usage) d WHERE (d->>'pct')::int >= 90 SELECT 1 FROM jsonb_array_elements(saf.disk_usage) d WHERE (d->>'pct')::int >= 90
) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) ) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
""")).fetchall()} """)).fetchall()}
audits = [a for a in audits if a.id in ids] audits = [a for a in audits if a.id in ids]
elif filtre == "disk_warning": elif filtre == "disk_warning":
ids = {r.id for r in db.execute(text(""" ids = {r.id for r in db.execute(text("""
SELECT saf.id FROM server_audit_full saf SELECT saf.id FROM server_audit_full saf
WHERE saf.status = 'ok' AND EXISTS ( WHERE saf.status IN ('ok','partial') AND EXISTS (
SELECT 1 FROM jsonb_array_elements(saf.disk_usage) d WHERE (d->>'pct')::int >= 80 SELECT 1 FROM jsonb_array_elements(saf.disk_usage) d WHERE (d->>'pct')::int >= 80
) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) ) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
""")).fetchall()} """)).fetchall()}
audits = [a for a in audits if a.id in ids] audits = [a for a in audits if a.id in ids]
elif filtre == "uptime": elif filtre == "uptime":
@ -122,9 +122,9 @@ async def audit_full_list(request: Request, db=Depends(get_db)):
if pattern: if pattern:
ids = {r.id for r in db.execute(text(""" ids = {r.id for r in db.execute(text("""
SELECT id FROM server_audit_full SELECT id FROM server_audit_full
WHERE status = 'ok' WHERE status IN ('ok','partial')
AND (services::text ~* :pat OR listen_ports::text ~* :pat OR processes::text ~* :pat) AND (services::text ~* :pat OR listen_ports::text ~* :pat OR processes::text ~* :pat)
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
"""), {"pat": pattern}).fetchall()} """), {"pat": pattern}).fetchall()}
audits = [a for a in audits if a.id in ids] audits = [a for a in audits if a.id in ids]
@ -248,8 +248,8 @@ async def audit_full_patching(request: Request, db=Depends(get_db)):
f" COUNT(*) FILTER (WHERE {yr_count} >= 2) as twice," f" COUNT(*) FILTER (WHERE {yr_count} >= 2) as twice,"
f" COUNT(*) FILTER (WHERE {yr_count} >= 3) as thrice," f" COUNT(*) FILTER (WHERE {yr_count} >= 3) as thrice,"
f" COUNT(*) FILTER (WHERE {yr_count} = 0 OR {yr_count} IS NULL) as never" f" COUNT(*) FILTER (WHERE {yr_count} = 0 OR {yr_count} IS NULL) as never"
f" FROM server_audit_full WHERE status = 'ok'" f" FROM server_audit_full WHERE status IN ('ok','partial')"
f" AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)" f" AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)"
)).fetchone() )).fetchone()
patch_by_domain = db.execute(text( patch_by_domain = db.execute(text(
@ -260,8 +260,8 @@ async def audit_full_patching(request: Request, db=Depends(get_db)):
f" COUNT(DISTINCT saf.hostname) FILTER (WHERE saf.{yr_count} = 0 OR saf.{yr_count} IS NULL) as never" f" COUNT(DISTINCT saf.hostname) FILTER (WHERE saf.{yr_count} = 0 OR saf.{yr_count} IS NULL) as never"
f" FROM server_audit_full saf JOIN servers s ON saf.server_id = s.id" f" FROM server_audit_full saf JOIN servers s ON saf.server_id = s.id"
f" JOIN domain_environments de ON s.domain_env_id = de.id JOIN domains d ON de.domain_id = d.id" f" JOIN domain_environments de ON s.domain_env_id = de.id JOIN domains d ON de.domain_id = d.id"
f" WHERE saf.status = 'ok'" f" WHERE saf.status IN ('ok','partial')"
f" AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)" f" AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)"
f" GROUP BY d.name, d.code, d.display_order ORDER BY d.display_order" f" GROUP BY d.name, d.code, d.display_order ORDER BY d.display_order"
)).fetchall() )).fetchall()
@ -269,8 +269,8 @@ async def audit_full_patching(request: Request, db=Depends(get_db)):
if year == 2026: if year == 2026:
patch_weekly = db.execute(text( patch_weekly = db.execute(text(
"SELECT last_patch_week as week, COUNT(*) as cnt FROM server_audit_full" "SELECT last_patch_week as week, COUNT(*) as cnt FROM server_audit_full"
" WHERE status = 'ok' AND last_patch_year = 2026 AND last_patch_week IS NOT NULL" " WHERE status IN ('ok','partial') AND last_patch_year = 2026 AND last_patch_week IS NOT NULL"
" AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)" " AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)"
" GROUP BY last_patch_week ORDER BY last_patch_week" " GROUP BY last_patch_week ORDER BY last_patch_week"
)).fetchall() )).fetchall()
@ -288,7 +288,7 @@ async def audit_full_patching(request: Request, db=Depends(get_db)):
f" LEFT JOIN domains d ON de.domain_id = d.id" f" LEFT JOIN domains d ON de.domain_id = d.id"
f" LEFT JOIN environments e ON de.environment_id = e.id" f" LEFT JOIN environments e ON de.environment_id = e.id"
f" LEFT JOIN zones z ON s.zone_id = z.id" f" LEFT JOIN zones z ON s.zone_id = z.id"
f" WHERE saf.status = 'ok'" f" WHERE saf.status IN ('ok','partial')"
f" ORDER BY saf.hostname, saf.audit_date DESC" f" ORDER BY saf.hostname, saf.audit_date DESC"
)).fetchall() )).fetchall()
@ -362,9 +362,9 @@ async def audit_full_export_csv(request: Request, db=Depends(get_db)):
if pattern: if pattern:
ids = {r.id for r in db.execute(text(""" ids = {r.id for r in db.execute(text("""
SELECT id FROM server_audit_full SELECT id FROM server_audit_full
WHERE status = 'ok' WHERE status IN ('ok','partial')
AND (services::text ~* :pat OR listen_ports::text ~* :pat OR processes::text ~* :pat) AND (services::text ~* :pat OR listen_ports::text ~* :pat OR processes::text ~* :pat)
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
"""), {"pat": pattern}).fetchall()} """), {"pat": pattern}).fetchall()}
audits = [a for a in audits if a.id in ids] audits = [a for a in audits if a.id in ids]
if domain: if domain:
@ -423,7 +423,7 @@ async def audit_full_flow_map(request: Request, db=Depends(get_db)):
# Serveurs audites pour l'autocompletion # Serveurs audites pour l'autocompletion
audited_servers = db.execute(text(""" audited_servers = db.execute(text("""
SELECT DISTINCT hostname FROM server_audit_full WHERE status = 'ok' ORDER BY hostname SELECT DISTINCT hostname FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname
""")).fetchall() """)).fetchall()
if server_filter: if server_filter:
@ -436,7 +436,7 @@ async def audit_full_flow_map(request: Request, db=Depends(get_db)):
JOIN server_audit_full saf ON nfm.audit_id = saf.id JOIN server_audit_full saf ON nfm.audit_id = saf.id
WHERE saf.id IN ( WHERE saf.id IN (
SELECT DISTINCT ON (hostname) id FROM server_audit_full SELECT DISTINCT ON (hostname) id FROM server_audit_full
WHERE status = 'ok' ORDER BY hostname, audit_date DESC WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC
) )
AND (nfm.source_hostname = :srv OR nfm.dest_hostname = :srv) AND (nfm.source_hostname = :srv OR nfm.dest_hostname = :srv)
AND nfm.source_hostname != nfm.dest_hostname AND nfm.source_hostname != nfm.dest_hostname
@ -468,7 +468,7 @@ async def audit_full_flow_map(request: Request, db=Depends(get_db)):
JOIN server_audit_full saf ON nfm.audit_id = saf.id JOIN server_audit_full saf ON nfm.audit_id = saf.id
WHERE saf.id IN ( WHERE saf.id IN (
SELECT DISTINCT ON (hostname) id FROM server_audit_full SELECT DISTINCT ON (hostname) id FROM server_audit_full
WHERE status = 'ok' ORDER BY hostname, audit_date DESC WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC
) )
AND (nfm.source_hostname = ANY(:hosts) OR nfm.dest_hostname = ANY(:hosts)) AND (nfm.source_hostname = ANY(:hosts) OR nfm.dest_hostname = ANY(:hosts))
AND nfm.source_hostname != COALESCE(nfm.dest_hostname, '') AND nfm.source_hostname != COALESCE(nfm.dest_hostname, '')

View File

@ -54,16 +54,16 @@ async def dashboard(request: Request, db=Depends(get_db)):
COUNT(*) FILTER (WHERE patch_count_2026 >= 3) as patched_thrice, COUNT(*) FILTER (WHERE patch_count_2026 >= 3) as patched_thrice,
COUNT(*) FILTER (WHERE reboot_required = true) as needs_reboot COUNT(*) FILTER (WHERE reboot_required = true) as needs_reboot
FROM server_audit_full FROM server_audit_full
WHERE status = 'ok' WHERE status IN ('ok','partial')
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
""")).fetchone() """)).fetchone()
# Frequence patching par semaine 2026 # Frequence patching par semaine 2026
patch_weekly = db.execute(text(""" patch_weekly = db.execute(text("""
SELECT last_patch_week as week, COUNT(*) as cnt SELECT last_patch_week as week, COUNT(*) as cnt
FROM server_audit_full FROM server_audit_full
WHERE status = 'ok' AND last_patch_year = 2026 AND last_patch_week IS NOT NULL WHERE status IN ('ok','partial') AND last_patch_year = 2026 AND last_patch_week IS NOT NULL
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
GROUP BY last_patch_week ORDER BY last_patch_week GROUP BY last_patch_week ORDER BY last_patch_week
""")).fetchall() """)).fetchall()
@ -78,8 +78,8 @@ async def dashboard(request: Request, db=Depends(get_db)):
JOIN servers s ON saf.server_id = s.id JOIN servers s ON saf.server_id = s.id
JOIN domain_environments de ON s.domain_env_id = de.id JOIN domain_environments de ON s.domain_env_id = de.id
JOIN domains d ON de.domain_id = d.id JOIN domains d ON de.domain_id = d.id
WHERE saf.status = 'ok' WHERE saf.status IN ('ok','partial')
AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
GROUP BY d.name, d.code, d.display_order GROUP BY d.name, d.code, d.display_order
ORDER BY d.display_order ORDER BY d.display_order
""")).fetchall() """)).fetchall()
@ -93,8 +93,8 @@ async def dashboard(request: Request, db=Depends(get_db)):
JOIN servers s ON saf.server_id = s.id JOIN servers s ON saf.server_id = s.id
JOIN domain_environments de ON s.domain_env_id = de.id JOIN domain_environments de ON s.domain_env_id = de.id
JOIN environments e ON de.environment_id = e.id JOIN environments e ON de.environment_id = e.id
WHERE saf.status = 'ok' WHERE saf.status IN ('ok','partial')
AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
GROUP BY e.name ORDER BY e.name GROUP BY e.name ORDER BY e.name
""")).fetchall() """)).fetchall()
@ -107,8 +107,8 @@ async def dashboard(request: Request, db=Depends(get_db)):
FROM server_audit_full saf FROM server_audit_full saf
JOIN servers s ON saf.server_id = s.id JOIN servers s ON saf.server_id = s.id
JOIN zones z ON s.zone_id = z.id JOIN zones z ON s.zone_id = z.id
WHERE saf.status = 'ok' WHERE saf.status IN ('ok','partial')
AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
GROUP BY z.name ORDER BY z.name GROUP BY z.name ORDER BY z.name
""")).fetchall() """)).fetchall()

View File

@ -409,7 +409,7 @@ def get_latest_audits(db, limit=100):
jsonb_array_length(COALESCE(connections, '[]')) as conn_count, jsonb_array_length(COALESCE(connections, '[]')) as conn_count,
jsonb_array_length(COALESCE(processes, '[]')) as proc_count jsonb_array_length(COALESCE(processes, '[]')) as proc_count
FROM server_audit_full FROM server_audit_full
WHERE status = 'ok' WHERE status IN ('ok','partial')
ORDER BY hostname, audit_date DESC ORDER BY hostname, audit_date DESC
LIMIT :lim LIMIT :lim
"""), {"lim": limit}).fetchall() """), {"lim": limit}).fetchall()
@ -430,7 +430,7 @@ def get_flow_map(db):
JOIN server_audit_full saf ON nfm.audit_id = saf.id JOIN server_audit_full saf ON nfm.audit_id = saf.id
WHERE saf.id IN ( WHERE saf.id IN (
SELECT DISTINCT ON (hostname) id FROM server_audit_full SELECT DISTINCT ON (hostname) id FROM server_audit_full
WHERE status = 'ok' ORDER BY hostname, audit_date DESC WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC
) )
GROUP BY source_hostname, source_ip, dest_ip, dest_port, GROUP BY source_hostname, source_ip, dest_ip, dest_port,
dest_hostname, process_name, direction, state dest_hostname, process_name, direction, state
@ -463,7 +463,7 @@ def get_flow_map_for_domain(db, domain_code):
WHERE d.code = :dc WHERE d.code = :dc
AND saf.id IN ( AND saf.id IN (
SELECT DISTINCT ON (hostname) id FROM server_audit_full SELECT DISTINCT ON (hostname) id FROM server_audit_full
WHERE status = 'ok' ORDER BY hostname, audit_date DESC WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC
) )
ORDER BY nfm.source_hostname ORDER BY nfm.source_hostname
"""), {"dc": domain_code}).fetchall() """), {"dc": domain_code}).fetchall()
@ -472,7 +472,7 @@ def get_flow_map_for_domain(db, domain_code):
def get_app_map(db): def get_app_map(db):
audits = db.execute(text(""" audits = db.execute(text("""
SELECT DISTINCT ON (hostname) hostname, server_id, processes, listen_ports SELECT DISTINCT ON (hostname) hostname, server_id, processes, listen_ports
FROM server_audit_full WHERE status = 'ok' FROM server_audit_full WHERE status IN ('ok','partial')
ORDER BY hostname, audit_date DESC ORDER BY hostname, audit_date DESC
""")).fetchall() """)).fetchall()
app_groups = {} app_groups = {}