fix(qualys): migration API 2.0 EOL -> 5.0 (auth refusee en 2.0 INVALID_CREDENTIALS, OK en 5.0). 12+3+1 endpoints qps/rest mis a jour

This commit is contained in:
Pierre & Lumière 2026-05-05 16:40:34 +02:00
parent 3e3f5618a0
commit 37faba382e
3 changed files with 16 additions and 16 deletions

View File

@ -50,7 +50,7 @@ def search_assets_api(db, query, field="name", operator="CONTAINS", force_refres
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/search/am/hostasset",
f"{qualys_url}/qps/rest/5.0/search/am/hostasset",
json={"ServiceRequest": {
"preferences": {"limitResults": 200},
"filters": {"Criteria": [
@ -82,7 +82,7 @@ def get_all_tags_api(db):
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/search/am/tag",
f"{qualys_url}/qps/rest/5.0/search/am/tag",
json={"ServiceRequest": {"preferences": {"limitResults": 1000}}},
auth=(qualys_user, qualys_pass),
verify=False, timeout=60, proxies=proxies,
@ -153,7 +153,7 @@ def create_tag_api(db, tag_name):
proxies = {"https": qualys_proxy, "http": qualys_proxy} if qualys_proxy else None
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/create/am/tag",
f"{qualys_url}/qps/rest/5.0/create/am/tag",
json={"ServiceRequest": {"data": {"Tag": {"name": tag_name}}}},
auth=(qualys_user, qualys_pass), verify=False, timeout=30, proxies=proxies,
headers={"Content-Type": "application/json"})
@ -179,7 +179,7 @@ def delete_tag_api(db, qualys_tag_id):
proxies = {"https": qualys_proxy, "http": qualys_proxy} if qualys_proxy else None
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/delete/am/tag/{qualys_tag_id}",
f"{qualys_url}/qps/rest/5.0/delete/am/tag/{qualys_tag_id}",
auth=(qualys_user, qualys_pass), verify=False, timeout=30, proxies=proxies,
headers={"Content-Type": "application/json"})
if r.status_code == 200 and "SUCCESS" in r.text:
@ -200,7 +200,7 @@ def add_tag_to_asset_api(db, asset_id, tag_id):
proxies = {"https": qualys_proxy, "http": qualys_proxy} if qualys_proxy else None
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/update/am/hostasset/{asset_id}",
f"{qualys_url}/qps/rest/5.0/update/am/hostasset/{asset_id}",
json={"ServiceRequest": {"data": {"HostAsset": {"tags": {"add": {"TagSimple": {"id": tag_id}}}}}}},
auth=(qualys_user, qualys_pass), verify=False, timeout=30, proxies=proxies,
headers={"Content-Type": "application/json"})
@ -224,7 +224,7 @@ def remove_tag_from_asset_api(db, asset_id, tag_id):
proxies = {"https": qualys_proxy, "http": qualys_proxy} if qualys_proxy else None
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/update/am/hostasset/{asset_id}",
f"{qualys_url}/qps/rest/5.0/update/am/hostasset/{asset_id}",
json={"ServiceRequest": {"data": {"HostAsset": {"tags": {"remove": {"TagSimple": {"id": tag_id}}}}}}},
auth=(qualys_user, qualys_pass), verify=False, timeout=30, proxies=proxies,
headers={"Content-Type": "application/json"})
@ -284,7 +284,7 @@ def sync_server_qualys(db, server_id):
# Recuperer l'asset complet avec tags
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/search/am/hostasset",
f"{qualys_url}/qps/rest/5.0/search/am/hostasset",
json={"ServiceRequest": {
"filters": {"Criteria": [
{"field": "id", "operator": "EQUALS", "value": str(qid)}
@ -372,7 +372,7 @@ def _find_asset_by_hostname(qualys_url, qualys_user, qualys_pass, hostname, prox
"""Cherche un asset Qualys par hostname"""
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/search/am/hostasset",
f"{qualys_url}/qps/rest/5.0/search/am/hostasset",
json={"ServiceRequest": {
"preferences": {"limitResults": 5},
"filters": {"Criteria": [
@ -672,7 +672,7 @@ def _refresh_all_agents_impl(db, mode="diff"):
for attempt in range(3):
try:
r = sess.post(
f"{qualys_url}/qps/rest/2.0/search/am/hostasset",
f"{qualys_url}/qps/rest/5.0/search/am/hostasset",
json=payload, timeout=600)
break
except Exception:
@ -897,7 +897,7 @@ def _fetch_asset_ids_by_tag(db, tag_name):
proxies = {"https": qualys_proxy, "http": qualys_proxy} if qualys_proxy else None
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/search/am/hostasset",
f"{qualys_url}/qps/rest/5.0/search/am/hostasset",
json={"ServiceRequest": {
"preferences": {"limitResults": 1000},
"filters": {"Criteria": [
@ -1140,7 +1140,7 @@ def fetch_all_qualys_assets(db, with_progress=False):
"filters": {"Criteria": criteria}}}
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/search/am/hostasset",
f"{qualys_url}/qps/rest/5.0/search/am/hostasset",
json=body, auth=(qualys_user, qualys_pass),
verify=False, timeout=180, proxies=proxies,
headers={"Content-Type": "application/json"}
@ -1248,7 +1248,7 @@ def delete_qualys_asset(db, asset_id):
proxies = {"https": qualys_proxy, "http": qualys_proxy} if qualys_proxy else None
try:
r = requests.post(
f"{qualys_url}/qps/rest/2.0/delete/am/hostasset/{int(asset_id)}",
f"{qualys_url}/qps/rest/5.0/delete/am/hostasset/{int(asset_id)}",
auth=(qualys_user, qualys_pass), verify=False, timeout=60, proxies=proxies,
headers={"Content-Type": "application/json"}
)

View File

@ -70,7 +70,7 @@ def list_qualys_tags(db):
"""Liste tous les tags Qualys (nom, id, type DYN/STAT, ruleText)."""
# search all tags
payload = {"ServiceRequest": {"preferences": {"limitResults": 1000}}}
r = _qualys_post(db, "/qps/rest/2.0/search/am/tag", payload)
r = _qualys_post(db, "/qps/rest/5.0/search/am/tag", payload)
if not r.get("ok"):
return {"ok": False, "msg": r.get("msg") or f"HTTP {r.get('status')}", "tags": []}
tags = []
@ -175,7 +175,7 @@ def create_static_tag(db, name, color="", description=""):
}
}
}
r = _qualys_post(db, "/qps/rest/2.0/create/am/tag", payload)
r = _qualys_post(db, "/qps/rest/5.0/create/am/tag", payload)
if r.get("ok"):
return {"ok": True, "msg": f"Tag '{name}' cree"}
return {"ok": False, "msg": r.get("msg") or f"HTTP {r.get('status')}: {r.get('text', '')[:200]}"}
@ -183,7 +183,7 @@ def create_static_tag(db, name, color="", description=""):
def delete_tag(db, tag_id):
"""Supprime un tag Qualys par id."""
r = _qualys_post(db, f"/qps/rest/2.0/delete/am/tag/{tag_id}", {})
r = _qualys_post(db, f"/qps/rest/5.0/delete/am/tag/{tag_id}", {})
return {"ok": r.get("ok"), "msg": r.get("msg") or f"HTTP {r.get('status')}"}

View File

@ -45,7 +45,7 @@
<div class="card p-3">
<p class="text-xs text-gray-400 mb-2">
Le plus recent (en haut de chaque groupe) est probablement l'asset actif. Les autres sont des zombies (anciennes installations, ré-IPs, doublons de scan).
Bouton <strong>Supprimer</strong> = appel API Qualys <code>POST /qps/rest/2.0/delete/am/hostasset/{id}</code>.
Bouton <strong>Supprimer</strong> = appel API Qualys <code>POST /qps/rest/5.0/delete/am/hostasset/{id}</code>.
{% if not can_delete %}<br><span class="text-yellow-400">Tu n'as pas la permission edit pour supprimer.</span>{% endif %}
</p>
<table class="w-full text-xs">