feat(cortex-xdr): endpoint_count counts by operational status (1.10.0)

The endpoints API has no filter on operational_status, so the endpoints
the other filters match are read 100 at a time and counted by the script.
Lets an agent reporting playbook count the agents in error, as
SentinelOne's operationalStatesNin does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LaiNEwG2W5Y9fMo4qXcesr
This commit is contained in:
2026-10-13 08:43:18 +00:00
parent 91855fce4f
commit 62157e5dee
2 changed files with 25 additions and 4 deletions
@@ -135,14 +135,34 @@ def count(filters):
return int(reply.get("total_count") or 0)
def count_operational(filters, wanted):
# The endpoints grid does not filter on operational_status, so the endpoints
# the other filters match are read 100 at a time — the API's page ceiling —
# and counted here. Costs one call per hundred endpoints.
n, start = 0, 0
while True:
request_data = {"search_from": start, "search_to": start + 100, "filters": filters}
reply = post("/endpoints/get_endpoint/", request_data).get("reply") or {}
page = reply.get("endpoints") or []
n += sum(1 for e in page if str(e.get("operational_status") or "").upper() in wanted)
start += len(page)
if not page or start >= int(reply.get("total_count") or 0):
return n
def main():
inputs = json.loads(os.environ.get("INTEGRATION_INPUTS", "{}"))
filters = build_filters(inputs)
result = {"count": count(filters), "filters": filters}
wanted = {x.upper() for x in csv(inputs.get("operational_status"))}
if wanted:
result = {"count": count_operational(filters, wanted), "filters": filters,
"operational_status": sorted(wanted)}
else:
result = {"count": count(filters), "filters": filters}
# The fleet total is the denominator the filtered count is read against: it
# turns a bare number into a proportion, and makes a filter that matched the
# whole estate — because it was too broad — visible instead of plausible.
result["total"] = count([]) if filters else result["count"]
result["total"] = count([]) if filters or wanted else result["count"]
print(json.dumps(result))