cebb3af796
The count only knew where an agent was, not what it was running or what it runs on. Four filters carry the console's own vocabulary through: agentVersion__gt to count the fleet still below a target build, networkStatuses to keep only the endpoints in a given connection state, operationalStatesNin to leave states out of the tally, and machineTypes to count servers apart from laptops. The list filters are split and re-joined so a hand-typed "connected, disconnected" does not reach the API with the space inside the value.
54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
import json, os, sys, urllib.request, urllib.parse, urllib.error
|
|
|
|
|
|
def request(method, url, headers, body=None):
|
|
data = json.dumps(body).encode("utf-8") if body is not None else None
|
|
req = urllib.request.Request(url, data=data, headers=headers, method=method)
|
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
raw = resp.read()
|
|
return json.loads(raw) if raw else {}
|
|
|
|
|
|
def csv(v):
|
|
return [x.strip() for x in str(v or "").split(",") if x.strip()]
|
|
|
|
|
|
def main():
|
|
secrets = json.loads(os.environ.get("INTEGRATION_SECRETS", "{}"))
|
|
inputs = json.loads(os.environ.get("INTEGRATION_INPUTS", "{}"))
|
|
base = secrets.get("url", "").rstrip("/") + "/web/api/v2.1"
|
|
headers = {
|
|
"Authorization": "ApiToken " + secrets.get("api_token", ""),
|
|
"Accept": "application/json",
|
|
"Content-Type": "application/json",
|
|
}
|
|
# === REQUEST ===
|
|
qs = {
|
|
"computerName": inputs.get("computer_name"),
|
|
"osTypes": inputs.get("os_type"),
|
|
"scan_status": inputs.get("scan_status"),
|
|
"siteIds": inputs.get("siteIds"),
|
|
"groupIds": inputs.get("groupIds"),
|
|
# Agents strictly newer than the given version, e.g. 23.4.2.6 — the console
|
|
# answers with the fleet still trailing behind a target build.
|
|
"agentVersion__gt": inputs.get("agentVersion__gt"),
|
|
# Comma-separated lists are re-joined so a hand-typed "connected, disconnected"
|
|
# does not reach the API with the space inside the value.
|
|
"networkStatuses": ",".join(csv(inputs.get("networkStatuses"))),
|
|
"operationalStatesNin": ",".join(csv(inputs.get("operationalStatesNin"))),
|
|
"machineTypes": ",".join(csv(inputs.get("machineTypes"))),
|
|
}
|
|
url = base + "/agents/count?" + urllib.parse.urlencode({k: v for k, v in qs.items() if v not in (None, "")})
|
|
print(json.dumps(request("GET", url, headers)))
|
|
# === END ===
|
|
|
|
|
|
try:
|
|
main()
|
|
except urllib.error.HTTPError as e:
|
|
print(json.dumps({"error": "HTTP " + str(e.code), "detail": e.read().decode("utf-8", "replace")}))
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(json.dumps({"error": str(e)}))
|
|
sys.exit(1)
|