9c04290a34
Expand from 9 to 70 commands covering the official + DEV SentinelOne V2 integrations: agents (actions/info/tags/count), threats & alerts (verdict/status/ notes/mitigate/fetch-file), hash blocklist & exclusions, IOCs, STAR rules, Deep Visibility, remote scripts, endpoint tags, firewall rules and network discovery. All script-based (urllib, INTEGRATION_SECRETS/INPUTS contract); inputs prioritized from the DEV integration.
62 lines
2.3 KiB
Python
62 lines
2.3 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 ===
|
|
body = {
|
|
"data": {
|
|
"name": inputs.get("name"),
|
|
"description": inputs.get("description"),
|
|
"s1ql": inputs.get("query"),
|
|
"queryType": inputs.get("query_type") or "events",
|
|
"severity": inputs.get("rule_severity"),
|
|
"expirationMode": inputs.get("expiration_mode"),
|
|
"expiration": inputs.get("expiration_date"),
|
|
"status": "Draft",
|
|
"networkQuarantine": inputs.get("network_quarantine") in (True, "true", "True", 1),
|
|
"treatAsThreat": inputs.get("treatAsThreat"),
|
|
},
|
|
"filter": {"tenant": "true"},
|
|
}
|
|
if inputs.get("query_lang") is not None:
|
|
body["data"]["queryLang"] = inputs.get("query_lang")
|
|
if inputs.get("site_ids"):
|
|
body["filter"]["siteIds"] = csv(inputs["site_ids"])
|
|
if inputs.get("group_ids"):
|
|
body["filter"]["groupIds"] = csv(inputs["group_ids"])
|
|
if inputs.get("account_ids"):
|
|
body["filter"]["accountIds"] = csv(inputs["account_ids"])
|
|
rule_id = urllib.parse.quote(str(inputs.get("rule_id", "")), safe="")
|
|
print(json.dumps(request("PUT", base + "/cloud-detection/rules/" + rule_id, headers, body)))
|
|
# === 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)
|