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 listen_ports::text ~* '"java"' OR processes::text ~* '\.jar') as app_java
FROM server_audit_full
WHERE status = 'ok'
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
WHERE status IN ('ok','partial')
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
""")).fetchone()
# Domaines + zones pour le filtre
@ -85,17 +85,17 @@ async def audit_full_list(request: Request, db=Depends(get_db)):
elif filtre == "disk_critical":
ids = {r.id for r in db.execute(text("""
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
) 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()}
audits = [a for a in audits if a.id in ids]
elif filtre == "disk_warning":
ids = {r.id for r in db.execute(text("""
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
) 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()}
audits = [a for a in audits if a.id in ids]
elif filtre == "uptime":
@ -122,9 +122,9 @@ async def audit_full_list(request: Request, db=Depends(get_db)):
if pattern:
ids = {r.id for r in db.execute(text("""
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 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()}
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} >= 3) as thrice,"
f" COUNT(*) FILTER (WHERE {yr_count} = 0 OR {yr_count} IS NULL) as never"
f" FROM server_audit_full WHERE status = 'ok'"
f" AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)"
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 IN ('ok','partial') ORDER BY hostname, audit_date DESC)"
)).fetchone()
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" 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" WHERE saf.status = 'ok'"
f" AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)"
f" WHERE saf.status IN ('ok','partial')"
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"
)).fetchall()
@ -269,8 +269,8 @@ async def audit_full_patching(request: Request, db=Depends(get_db)):
if year == 2026:
patch_weekly = db.execute(text(
"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"
" AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)"
" 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 IN ('ok','partial') ORDER BY hostname, audit_date DESC)"
" GROUP BY last_patch_week ORDER BY last_patch_week"
)).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 environments e ON de.environment_id = e.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"
)).fetchall()
@ -362,9 +362,9 @@ async def audit_full_export_csv(request: Request, db=Depends(get_db)):
if pattern:
ids = {r.id for r in db.execute(text("""
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 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()}
audits = [a for a in audits if a.id in ids]
if domain:
@ -423,7 +423,7 @@ async def audit_full_flow_map(request: Request, db=Depends(get_db)):
# Serveurs audites pour l'autocompletion
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()
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
WHERE saf.id IN (
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 != 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
WHERE saf.id IN (
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 != 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 reboot_required = true) as needs_reboot
FROM server_audit_full
WHERE status = 'ok'
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
WHERE status IN ('ok','partial')
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
""")).fetchone()
# Frequence patching par semaine 2026
patch_weekly = db.execute(text("""
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
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
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 IN ('ok','partial') ORDER BY hostname, audit_date DESC)
GROUP BY last_patch_week ORDER BY last_patch_week
""")).fetchall()
@ -78,8 +78,8 @@ async def dashboard(request: Request, db=Depends(get_db)):
JOIN servers s ON saf.server_id = s.id
JOIN domain_environments de ON s.domain_env_id = de.id
JOIN domains d ON de.domain_id = d.id
WHERE saf.status = 'ok'
AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
WHERE saf.status IN ('ok','partial')
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
ORDER BY d.display_order
""")).fetchall()
@ -93,8 +93,8 @@ async def dashboard(request: Request, db=Depends(get_db)):
JOIN servers s ON saf.server_id = s.id
JOIN domain_environments de ON s.domain_env_id = de.id
JOIN environments e ON de.environment_id = e.id
WHERE saf.status = 'ok'
AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
WHERE saf.status IN ('ok','partial')
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
""")).fetchall()
@ -107,8 +107,8 @@ async def dashboard(request: Request, db=Depends(get_db)):
FROM server_audit_full saf
JOIN servers s ON saf.server_id = s.id
JOIN zones z ON s.zone_id = z.id
WHERE saf.status = 'ok'
AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
WHERE saf.status IN ('ok','partial')
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
""")).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(processes, '[]')) as proc_count
FROM server_audit_full
WHERE status = 'ok'
WHERE status IN ('ok','partial')
ORDER BY hostname, audit_date DESC
LIMIT :lim
"""), {"lim": limit}).fetchall()
@ -430,7 +430,7 @@ def get_flow_map(db):
JOIN server_audit_full saf ON nfm.audit_id = saf.id
WHERE saf.id IN (
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,
dest_hostname, process_name, direction, state
@ -463,7 +463,7 @@ def get_flow_map_for_domain(db, domain_code):
WHERE d.code = :dc
AND saf.id IN (
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
"""), {"dc": domain_code}).fetchall()
@ -472,7 +472,7 @@ def get_flow_map_for_domain(db, domain_code):
def get_app_map(db):
audits = db.execute(text("""
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
""")).fetchall()
app_groups = {}