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:
File diff suppressed because one or more lines are too long
@@ -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))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user