diff --git a/app/routers/applications.py b/app/routers/applications.py
index 750f812..22dc554 100644
--- a/app/routers/applications.py
+++ b/app/routers/applications.py
@@ -338,7 +338,7 @@ async def applications_assign_page(request: Request, app_id: int, db=Depends(get
if not app:
return RedirectResponse(url="/admin/applications?msg=notfound", status_code=303)
- where = ["s.etat NOT IN ('stock','obsolete')"]
+ where = ["s.etat NOT IN ('Stock','Obsolète')"]
params = {}
if search:
where.append("s.hostname ILIKE :s"); params["s"] = f"%{search}%"
diff --git a/app/routers/audit.py b/app/routers/audit.py
index b2c0df3..ab5e690 100644
--- a/app/routers/audit.py
+++ b/app/routers/audit.py
@@ -134,7 +134,7 @@ async def audit_global(request: Request, db=Depends(get_db)):
parallel = int(form.get("parallel", "5"))
# Construire la requete
- where = ["s.os_family = 'linux'", "s.etat = 'production'"]
+ where = ["s.os_family = 'linux'", "s.etat = 'Production'"]
params = {}
if exclude_domains:
where.append("d.code NOT IN :ed")
diff --git a/app/routers/dashboard.py b/app/routers/dashboard.py
index b4c8531..0094131 100644
--- a/app/routers/dashboard.py
+++ b/app/routers/dashboard.py
@@ -18,21 +18,21 @@ async def dashboard(request: Request, db=Depends(get_db)):
# Stats generales
stats = {}
stats["total_servers"] = db.execute(text("SELECT COUNT(*) FROM servers")).scalar()
- stats["patchable"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE patch_os_owner='secops' AND etat='production'")).scalar()
+ stats["patchable"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE patch_os_owner='secops' AND etat='Production'")).scalar()
stats["linux"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE os_family='linux'")).scalar()
stats["windows"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE os_family='windows'")).scalar()
- stats["decom"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE etat='obsolete'")).scalar()
+ stats["decom"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE etat='Obsolète'")).scalar()
stats["obsolete"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE licence_support='obsolete'")).scalar()
stats["qualys_assets"] = db.execute(text("SELECT COUNT(*) FROM qualys_assets")).scalar()
stats["qualys_tags"] = db.execute(text("SELECT COUNT(*) FROM qualys_tags")).scalar()
stats["qualys_active"] = db.execute(text("SELECT COUNT(*) FROM qualys_assets WHERE agent_status ILIKE '%active%' AND agent_status NOT ILIKE '%inactive%'")).scalar()
stats["qualys_inactive"] = db.execute(text("SELECT COUNT(*) FROM qualys_assets WHERE agent_status ILIKE '%inactive%'")).scalar()
- stats["qualys_no_agent"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE etat='production' AND NOT EXISTS (SELECT 1 FROM qualys_assets qa WHERE LOWER(qa.hostname) = LOWER(servers.hostname))")).scalar()
+ stats["qualys_no_agent"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE etat='Production' AND NOT EXISTS (SELECT 1 FROM qualys_assets qa WHERE LOWER(qa.hostname) = LOWER(servers.hostname))")).scalar()
# Par domaine
domains = db.execute(text("""
SELECT d.name, d.code, COUNT(s.id) as total,
- COUNT(*) FILTER (WHERE s.etat='production') as actifs,
+ COUNT(*) FILTER (WHERE s.etat='Production') as actifs,
COUNT(*) FILTER (WHERE s.os_family='linux') as linux,
COUNT(*) FILTER (WHERE s.os_family='windows') as windows
FROM servers s
diff --git a/app/routers/planning.py b/app/routers/planning.py
index a1cdda3..a22aa87 100644
--- a/app/routers/planning.py
+++ b/app/routers/planning.py
@@ -40,7 +40,7 @@ def _get_planning_data(db, year):
SELECT d.code, d.name, COUNT(s.id) as srv_count
FROM domains d
LEFT JOIN domain_environments de ON de.domain_id = d.id
- LEFT JOIN servers s ON s.domain_env_id = de.id AND s.etat = 'production'
+ LEFT JOIN servers s ON s.domain_env_id = de.id AND s.etat = 'Production'
GROUP BY d.code, d.name, d.display_order
ORDER BY d.display_order
""")).fetchall()
diff --git a/app/services/campaign_service.py b/app/services/campaign_service.py
index 77ecbfa..12a9d8b 100644
--- a/app/services/campaign_service.py
+++ b/app/services/campaign_service.py
@@ -124,7 +124,7 @@ def get_servers_for_planning(db, year, week_number):
or_clauses.append("z.name = 'DMZ'")
where = f"""
- s.etat = 'production' AND s.patch_os_owner = 'secops'
+ s.etat = 'Production' AND s.patch_os_owner = 'secops'
AND s.licence_support IN ('active', 'els') AND s.os_family = 'linux'
AND ({' OR '.join(or_clauses)})
"""
diff --git a/app/services/correspondance_service.py b/app/services/correspondance_service.py
index 6f8adf9..18b9557 100644
--- a/app/services/correspondance_service.py
+++ b/app/services/correspondance_service.py
@@ -53,7 +53,7 @@ def detect_correspondances(db, dry_run=False):
# Tous les serveurs actifs (exclut stock/obsolete)
rows = db.execute(text("""SELECT id, hostname FROM servers
- WHERE etat NOT IN ('stock','obsolete','eol') ORDER BY hostname""")).fetchall()
+ WHERE etat NOT IN ('Stock','Obsolète','EOL') ORDER BY hostname""")).fetchall()
by_signature = defaultdict(list) # signature -> [(server_id, env_char, hostname)]
for r in rows:
@@ -125,7 +125,7 @@ def detect_correspondances(db, dry_run=False):
def get_servers_for_builder(db, search="", app="", domain="", env=""):
"""Retourne tous les serveurs matchant les filtres, avec leurs correspondances existantes.
Exclut les serveurs en stock / obsolete (décommissionnés, EOL)."""
- where = ["s.etat NOT IN ('stock','obsolete','eol')"]
+ where = ["s.etat NOT IN ('Stock','Obsolète','EOL')"]
params = {}
if search:
where.append("s.hostname ILIKE :s"); params["s"] = f"%{search}%"
@@ -181,7 +181,7 @@ def bulk_create_correspondance(db, prod_ids, nonprod_ids, env_labels, user_id):
def get_correspondance_view(db, search="", app="", env=""):
"""Vue hiérarchique des correspondances groupées par application.
Exclut les serveurs en stock/obsolete."""
- where = ["s.etat NOT IN ('stock','obsolete','eol')"]
+ where = ["s.etat NOT IN ('Stock','Obsolète','EOL')"]
params = {}
if search:
where.append("s.hostname ILIKE :s"); params["s"] = f"%{search}%"
@@ -330,7 +330,7 @@ def get_orphan_nonprod(db):
LEFT JOIN environments e ON de.environment_id = e.id
LEFT JOIN domains d ON de.domain_id = d.id
WHERE e.name IS NOT NULL AND e.name NOT ILIKE '%production%'
- AND s.etat NOT IN ('stock','obsolete','eol')
+ AND s.etat NOT IN ('Stock','Obsolète','EOL')
AND NOT EXISTS (SELECT 1 FROM server_correspondance sc WHERE sc.nonprod_server_id = s.id)
ORDER BY s.application_name, s.hostname
LIMIT 500
diff --git a/app/services/itop_service.py b/app/services/itop_service.py
index b982ba7..3c21c4d 100644
--- a/app/services/itop_service.py
+++ b/app/services/itop_service.py
@@ -337,10 +337,16 @@ def sync_from_itop(db, itop_url, itop_user, itop_pass):
"patch_excludes,domain_ldap_name,last_patch_date,"
"applicationsolution_list")
- # PatchCenter etat = iTop status (meme enum: production, implementation, stock, obsolete, eol)
- itop_status = {"production": "production", "stock": "stock",
- "implementation": "implementation", "obsolete": "obsolete",
- "eol": "eol"}
+ # PatchCenter etat = label iTop verbatim (Production, Implémentation, Stock, Obsolète, EOL, prêt, tests, Nouveau, ...)
+ itop_status = {
+ "production": "Production", "implementation": "Implémentation",
+ "stock": "Stock", "obsolete": "Obsolète", "eol": "EOL",
+ "pret": "prêt", "tests": "tests", "nouveau": "Nouveau",
+ "casse": "Cassé", "cede": "Cédé", "en_panne": "En panne",
+ "a_recuperer": "A récupérer", "perdu": "Perdu",
+ "recycle": "Recyclé", "occasion": "Occasion",
+ "a_detruire": "A détruire", "vole": "Volé",
+ }
for v in vms:
hostname = v.get("name", "").split(".")[0].lower()
@@ -404,7 +410,7 @@ def sync_from_itop(db, itop_url, itop_user, itop_pass):
"os_family": "linux" if "linux" in v.get("osfamily_id_friendlyname", "").lower() else "windows",
"os_version": v.get("osversion_id_friendlyname", ""),
"machine_type": "vm",
- "etat": itop_status.get(v.get("status", ""), "production"),
+ "etat": itop_status.get(v.get("status", ""), "Production"),
"de_id": de_id, "zone_id": zone_id,
"resp_srv": resp_srv_name,
"resp_srv_email": person_email.get(resp_srv_name.lower(), ""),
@@ -499,7 +505,7 @@ def sync_from_itop(db, itop_url, itop_user, itop_pass):
try:
db.execute(text("""INSERT INTO servers (hostname, fqdn, os_family, os_version, machine_type,
etat, responsable_nom, commentaire, site, ssh_port, ssh_user, ssh_method, tier)
- VALUES (:h, :f, :osf, :osv, 'physical', 'production', :resp, :desc, :site,
+ VALUES (:h, :f, :osf, :osv, 'physical', 'Production', :resp, :desc, :site,
22, 'root', 'ssh_key', 'tier0')"""),
{"h": hostname, "f": s.get("name", hostname), "osf": osf, "osv": osv,
"resp": resp, "desc": s.get("description", ""),
@@ -562,8 +568,16 @@ def sync_to_itop(db, itop_url, itop_user, itop_pass):
for v in client.get_all("VirtualMachine", "name"):
itop_vms[v["name"].split(".")[0].lower()] = v
- status_map = {"production": "production", "implementation": "implementation",
- "stock": "stock", "obsolete": "obsolete", "eol": "eol"}
+ # DB (iTop label verbatim) -> iTop API internal code
+ status_map = {
+ "Production": "production", "Implémentation": "implementation",
+ "Stock": "stock", "Obsolète": "obsolete", "EOL": "eol",
+ "prêt": "pret", "tests": "tests", "Nouveau": "nouveau",
+ "Cassé": "casse", "Cédé": "cede", "En panne": "en_panne",
+ "A récupérer": "a_recuperer", "Perdu": "perdu",
+ "Recyclé": "recycle", "Occasion": "occasion",
+ "A détruire": "a_detruire", "Volé": "vole",
+ }
tier_map = {"tier0": "Tier 0", "tier1": "Tier 1", "tier2": "Tier 2", "tier3": "Tier 3"}
# Build OSVersion cache: name.lower() → itop_id
@@ -599,7 +613,7 @@ def sync_to_itop(db, itop_url, itop_user, itop_pass):
if srv.mgmt_ip:
fields["managementip"] = srv.mgmt_ip.split("/")[0]
if srv.etat:
- fields["status"] = status_map.get(srv.etat, "production")
+ fields["status"] = status_map.get(srv.etat, "production") # iTop API internal code
if srv.commentaire:
fields["description"] = srv.commentaire
if srv.patch_excludes:
diff --git a/app/services/prereq_service.py b/app/services/prereq_service.py
index edad0f4..c020b1b 100644
--- a/app/services/prereq_service.py
+++ b/app/services/prereq_service.py
@@ -146,7 +146,7 @@ def _check_server(s):
result["eligible"] = False
result["exclude_reason"] = "obsolete"
result["exclude_detail"] = "Licence EOL"
- elif s.etat != 'production':
+ elif s.etat != 'Production':
result["eligible"] = False
result["exclude_reason"] = "non_patchable"
result["exclude_detail"] = f"Etat: {s.etat}"
@@ -159,7 +159,7 @@ def _check_server(s):
result["exclude_detail"] = "Licence EOL — serveur non supporte"
return result
- if s.etat != 'production':
+ if s.etat != 'Production':
result["eligible"] = False
result["exclude_reason"] = "non_patchable"
result["exclude_detail"] = f"Etat: {s.etat}"
@@ -256,7 +256,7 @@ def _auto_exclude(db, campaign_id):
JOIN servers s ON ps.server_id = s.id
WHERE ps.campaign_id = :cid AND ps.status = 'pending'
AND (s.licence_support = 'obsolete'
- OR s.etat != 'production'
+ OR s.etat != 'Production'
OR ps.prereq_ssh = 'ko'
OR ps.prereq_disk_ok = false)
"""), {"cid": campaign_id}).fetchall()
@@ -265,7 +265,7 @@ def _auto_exclude(db, campaign_id):
for s in non_eligible:
if s.licence_support == 'obsolete':
reason, detail = "obsolete", "Licence EOL — auto-exclu"
- elif s.etat != 'production':
+ elif s.etat != 'Production':
reason, detail = "non_patchable", f"Etat {s.etat} — auto-exclu"
elif s.prereq_disk_ok is False:
reason, detail = "creneau_inadequat", "Espace disque insuffisant — auto-exclu"
diff --git a/app/services/quickwin_service.py b/app/services/quickwin_service.py
index 7df42e5..8444cab 100644
--- a/app/services/quickwin_service.py
+++ b/app/services/quickwin_service.py
@@ -86,7 +86,7 @@ def get_eligible_servers(db):
LEFT JOIN environments e ON de.environment_id = e.id
LEFT JOIN quickwin_server_config qc ON qc.server_id = s.id
WHERE s.os_family = 'linux'
- AND s.etat = 'production'
+ AND s.etat = 'Production'
AND s.patch_os_owner = 'secops'
ORDER BY e.display_order, d.display_order, s.hostname
""")).fetchall()
@@ -184,7 +184,7 @@ def get_available_servers(db, run_id, search="", domains=None, envs=None, zones=
LEFT JOIN environments e ON de.environment_id = e.id
LEFT JOIN zones z ON s.zone_id = z.id
WHERE s.os_family = 'linux'
- AND s.etat = 'production'
+ AND s.etat = 'Production'
AND s.patch_os_owner = 'secops'
AND s.id NOT IN (SELECT server_id FROM quickwin_entries WHERE run_id = :rid)
ORDER BY d.name, e.name, s.hostname
@@ -211,7 +211,7 @@ def get_available_filters(db, run_id):
LEFT JOIN environments e ON de.environment_id = e.id
LEFT JOIN zones z ON s.zone_id = z.id
WHERE s.os_family = 'linux'
- AND s.etat = 'production'
+ AND s.etat = 'Production'
AND s.patch_os_owner = 'secops'
AND s.id NOT IN (SELECT server_id FROM quickwin_entries WHERE run_id = :rid)
"""), {"rid": run_id}).fetchall()
diff --git a/app/templates/partials/server_detail.html b/app/templates/partials/server_detail.html
index 2b5afc8..a92fd94 100644
--- a/app/templates/partials/server_detail.html
+++ b/app/templates/partials/server_detail.html
@@ -51,7 +51,7 @@
Environnement{{ s.environnement }}
Zone{{ s.zone or 'LAN' }}
Tier{{ s.tier }}
- Etat{% if s.etat == 'obsolete' %}Décommissionné{% elif s.etat == 'eol' %}EOL{% else %}{{ s.etat }}{% endif %}
+ Etat{{ s.etat }}
diff --git a/app/templates/partials/server_edit.html b/app/templates/partials/server_edit.html
index c014e8f..4b400f2 100644
--- a/app/templates/partials/server_edit.html
+++ b/app/templates/partials/server_edit.html
@@ -58,7 +58,7 @@
diff --git a/app/templates/qualys_agents.html b/app/templates/qualys_agents.html
index aa10796..b526b03 100644
--- a/app/templates/qualys_agents.html
+++ b/app/templates/qualys_agents.html
@@ -212,7 +212,7 @@ function refreshAgents() {
{{ s.domain or '-' }} |
{{ s.env or '-' }} |
{% if s.zone == 'DMZ' %}DMZ{% else %}{{ s.zone or '-' }}{% endif %} |
- {% if s.etat == 'obsolete' %}Décom.{% elif s.etat == 'eol' %}EOL{% elif s.etat == 'production' %}Prod{% else %}{{ (s.etat or '-')[:8] }}{% endif %} |
+ {% if s.etat == 'Obsolète' %}Décom.{% elif s.etat == 'EOL' %}EOL{% elif s.etat == 'Production' %}Prod{% else %}{{ (s.etat or '-')[:8] }}{% endif %} |
{% endfor %}
diff --git a/app/templates/qualys_deploy.html b/app/templates/qualys_deploy.html
index e838f2e..9bf765a 100644
--- a/app/templates/qualys_deploy.html
+++ b/app/templates/qualys_deploy.html
@@ -127,7 +127,7 @@
{{ s.domain or '-' }} |
{{ s.env or '-' }} |
- {% if s.etat == 'production' %}Prod
+ {% if s.etat == 'Production' %}Prod
{% else %}{{ s.etat or '-' }}{% endif %}
|
diff --git a/app/templates/servers.html b/app/templates/servers.html
index 7a3a8ea..ce2fc00 100644
--- a/app/templates/servers.html
+++ b/app/templates/servers.html
@@ -36,7 +36,7 @@
{% for t in ['tier0','tier1','tier2','tier3'] %}{% endfor %}
|