fix(servers): bulk + edit comparaisons domain/env/zone case-insensitive (BD mixte RECETTE/Recette/recette) + fallback bulk env_code si serveur sans domain_env_id + log INFO/WARNING + retour msg=bulk_<n_updated_reel>
This commit is contained in:
parent
5d3c07885d
commit
1b82440813
@ -239,41 +239,65 @@ async def servers_bulk(request: Request, db=Depends(get_db),
|
|||||||
|
|
||||||
from sqlalchemy import text as sqlt
|
from sqlalchemy import text as sqlt
|
||||||
|
|
||||||
|
bulk_value_clean = (bulk_value or "").strip()
|
||||||
|
n_updated = 0
|
||||||
|
|
||||||
if bulk_field in ("tier", "etat", "patch_os_owner", "licence_support"):
|
if bulk_field in ("tier", "etat", "patch_os_owner", "licence_support"):
|
||||||
db.execute(sqlt(f"UPDATE servers SET {bulk_field} = :val WHERE id = ANY(:ids)"),
|
res = db.execute(sqlt(f"UPDATE servers SET {bulk_field} = :val WHERE id = ANY(:ids)"),
|
||||||
{"val": bulk_value, "ids": ids})
|
{"val": bulk_value_clean, "ids": ids})
|
||||||
|
n_updated = res.rowcount or 0
|
||||||
elif bulk_field == "domain_code":
|
elif bulk_field == "domain_code":
|
||||||
# Trouver le domain_env_id correspondant (prod par defaut)
|
# Tous les serveurs prennent le 1er domain_env de ce domaine
|
||||||
|
# (priorité Production > autres via display_order)
|
||||||
row = db.execute(sqlt("""
|
row = db.execute(sqlt("""
|
||||||
SELECT de.id FROM domain_environments de
|
SELECT de.id FROM domain_environments de
|
||||||
JOIN domains d ON de.domain_id = d.id
|
JOIN domains d ON de.domain_id = d.id
|
||||||
JOIN environments e ON de.environment_id = e.id
|
JOIN environments e ON de.environment_id = e.id
|
||||||
WHERE d.code = :dc ORDER BY e.display_order LIMIT 1
|
WHERE LOWER(d.code) = LOWER(:dc) ORDER BY e.display_order LIMIT 1
|
||||||
"""), {"dc": bulk_value}).fetchone()
|
"""), {"dc": bulk_value_clean}).fetchone()
|
||||||
if row:
|
if row:
|
||||||
db.execute(sqlt("UPDATE servers SET domain_env_id = :deid WHERE id = ANY(:ids)"),
|
res = db.execute(sqlt("UPDATE servers SET domain_env_id = :deid WHERE id = ANY(:ids)"),
|
||||||
{"deid": row.id, "ids": ids})
|
{"deid": row.id, "ids": ids})
|
||||||
|
n_updated = res.rowcount or 0
|
||||||
|
else:
|
||||||
|
logger.warning(f"servers_bulk domain_code: aucun domain_environments pour {bulk_value_clean!r}")
|
||||||
elif bulk_field == "env_code":
|
elif bulk_field == "env_code":
|
||||||
# Pour chaque serveur, garder son domaine mais changer l'env
|
# Pour chaque serveur, garder son domaine actuel et changer l'env.
|
||||||
|
# Si serveur sans domain_env_id, fallback : 1er domain dispo + cet env.
|
||||||
for sid in ids:
|
for sid in ids:
|
||||||
srv = db.execute(sqlt("""
|
srv = db.execute(sqlt("""
|
||||||
SELECT d.id as did FROM servers s
|
SELECT s.id, s.domain_env_id, de.domain_id AS did
|
||||||
JOIN domain_environments de ON s.domain_env_id = de.id
|
FROM servers s
|
||||||
JOIN domains d ON de.domain_id = d.id
|
LEFT JOIN domain_environments de ON s.domain_env_id = de.id
|
||||||
WHERE s.id = :sid
|
WHERE s.id = :sid
|
||||||
"""), {"sid": sid}).fetchone()
|
"""), {"sid": sid}).fetchone()
|
||||||
if srv:
|
if not srv:
|
||||||
|
continue
|
||||||
|
did = srv.did # peut être None si serveur sans domaine
|
||||||
|
if did:
|
||||||
de = db.execute(sqlt("""
|
de = db.execute(sqlt("""
|
||||||
SELECT de.id FROM domain_environments de
|
SELECT de.id FROM domain_environments de
|
||||||
JOIN environments e ON de.environment_id = e.id
|
JOIN environments e ON de.environment_id = e.id
|
||||||
WHERE de.domain_id = :did AND e.code = :ec
|
WHERE de.domain_id = :did AND LOWER(e.code) = LOWER(:ec)
|
||||||
"""), {"did": srv.did, "ec": bulk_value}).fetchone()
|
"""), {"did": did, "ec": bulk_value_clean}).fetchone()
|
||||||
|
else:
|
||||||
|
# Fallback : on prend n'importe quel domain_env avec cet env
|
||||||
|
de = db.execute(sqlt("""
|
||||||
|
SELECT de.id FROM domain_environments de
|
||||||
|
JOIN environments e ON de.environment_id = e.id
|
||||||
|
WHERE LOWER(e.code) = LOWER(:ec)
|
||||||
|
ORDER BY de.id LIMIT 1
|
||||||
|
"""), {"ec": bulk_value_clean}).fetchone()
|
||||||
if de:
|
if de:
|
||||||
db.execute(sqlt("UPDATE servers SET domain_env_id = :deid WHERE id = :sid"),
|
db.execute(sqlt("UPDATE servers SET domain_env_id = :deid WHERE id = :sid"),
|
||||||
{"deid": de.id, "sid": sid})
|
{"deid": de.id, "sid": sid})
|
||||||
|
n_updated += 1
|
||||||
|
else:
|
||||||
|
logger.warning(f"servers_bulk env_code: pas de domain_env pour env {bulk_value_clean!r} (sid={sid}, did={did})")
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
return RedirectResponse(url=f"/servers?msg=bulk_{len(ids)}", status_code=303)
|
logger.info(f"servers_bulk: field={bulk_field} value={bulk_value_clean!r} ids={len(ids)} updated={n_updated}")
|
||||||
|
return RedirectResponse(url=f"/servers?msg=bulk_{n_updated}", status_code=303)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/servers/{server_id}/sync-qualys", response_class=HTMLResponse)
|
@router.post("/servers/{server_id}/sync-qualys", response_class=HTMLResponse)
|
||||||
|
|||||||
@ -208,25 +208,39 @@ def list_servers(db, filters, page=1, per_page=50, sort="hostname", sort_dir="as
|
|||||||
|
|
||||||
|
|
||||||
def update_server(db, server_id, data, username):
|
def update_server(db, server_id, data, username):
|
||||||
"""Met a jour un serveur et log l'action"""
|
"""Met a jour un serveur et log l'action.
|
||||||
|
Comparaisons code domain/env/zone en case-insensitive (la BD mixte
|
||||||
|
'RECETTE'/'Recette'/'recette' n'a pas une casse cohérente)."""
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger("patchcenter.server")
|
||||||
|
|
||||||
# Domain + Env -> domain_env_id
|
# Domain + Env -> domain_env_id
|
||||||
if data.get("domain_code") and data.get("env_code"):
|
dc = (data.get("domain_code") or "").strip()
|
||||||
|
ec = (data.get("env_code") or "").strip()
|
||||||
|
if dc and ec:
|
||||||
row = db.execute(text("""
|
row = db.execute(text("""
|
||||||
SELECT de.id FROM domain_environments de
|
SELECT de.id FROM domain_environments de
|
||||||
JOIN domains d ON de.domain_id = d.id
|
JOIN domains d ON de.domain_id = d.id
|
||||||
JOIN environments e ON de.environment_id = e.id
|
JOIN environments e ON de.environment_id = e.id
|
||||||
WHERE d.code = :dc AND e.code = :ec
|
WHERE LOWER(d.code) = LOWER(:dc) AND LOWER(e.code) = LOWER(:ec)
|
||||||
"""), {"dc": data["domain_code"], "ec": data["env_code"]}).fetchone()
|
"""), {"dc": dc, "ec": ec}).fetchone()
|
||||||
if row:
|
if row:
|
||||||
db.execute(text("UPDATE servers SET domain_env_id = :deid WHERE id = :id"),
|
db.execute(text("UPDATE servers SET domain_env_id = :deid WHERE id = :id"),
|
||||||
{"deid": row.id, "id": server_id})
|
{"deid": row.id, "id": server_id})
|
||||||
|
else:
|
||||||
|
log.warning(f"update_server({server_id}): pas de domain_environments pour ({dc!r}, {ec!r})")
|
||||||
|
|
||||||
# Zone
|
# Zone (case-insensitive sur name)
|
||||||
if data.get("zone"):
|
zn = (data.get("zone") or "").strip()
|
||||||
zrow = db.execute(text("SELECT id FROM zones WHERE name = :z"), {"z": data["zone"]}).fetchone()
|
if zn:
|
||||||
|
zrow = db.execute(text(
|
||||||
|
"SELECT id FROM zones WHERE LOWER(name) = LOWER(:z)"
|
||||||
|
), {"z": zn}).fetchone()
|
||||||
if zrow:
|
if zrow:
|
||||||
db.execute(text("UPDATE servers SET zone_id = :zid WHERE id = :id"),
|
db.execute(text("UPDATE servers SET zone_id = :zid WHERE id = :id"),
|
||||||
{"zid": zrow.id, "id": server_id})
|
{"zid": zrow.id, "id": server_id})
|
||||||
|
else:
|
||||||
|
log.warning(f"update_server({server_id}): zone {zn!r} introuvable")
|
||||||
|
|
||||||
# IPs (reelle + connexion)
|
# IPs (reelle + connexion)
|
||||||
update_server_ips(db, server_id, data.get("ip_reelle"), data.get("ip_connexion"))
|
update_server_ips(db, server_id, data.get("ip_reelle"), data.get("ip_connexion"))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user