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"), # Scopes the count to one or more accounts of a multi-tenant console. "accountIds": ",".join(csv(inputs.get("accountIds"))), # 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"))), } # Only sent when the caller actually set it: an unset boolean must not become # isActive=false and quietly count the inactive agents instead of all of them. if inputs.get("isActive") not in (None, ""): qs["isActive"] = "true" if inputs["isActive"] in (True, "true", "True", 1, "1") else "false" 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)