aabe1a6837
The refusal you get on the first run is "no Sextant client is paired with this SOAR client", and it names the identifier it did not recognise — but nothing told you which ones it would have recognised. This does. Clients with no pairing appear with an empty identifier, and are surfaced again under `unpaired`: they are the whole reason somebody runs this command twice, and spotting them in a list is exactly what nobody does. Verified against a running Sextant: the paired client comes back with its identifier, and the route refuses a caller with no ingestion token. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
import json, os, sys, urllib.error, urllib.request
|
|
|
|
|
|
def _cfg():
|
|
return json.loads(os.environ.get("INTEGRATION_SECRETS", "{}"))
|
|
|
|
|
|
def main():
|
|
cfg = _cfg()
|
|
base = str(cfg.get("base_url") or "").rstrip("/")
|
|
if not base:
|
|
raise Exception("base_url is not configured")
|
|
req = urllib.request.Request(
|
|
base + "/api/ingest/clients",
|
|
headers={
|
|
"Accept": "application/json",
|
|
"Authorization": "Bearer " + str(cfg.get("token") or ""),
|
|
"User-Agent": "Riposte-SOAR/sextant",
|
|
},
|
|
method="GET",
|
|
)
|
|
with urllib.request.urlopen(req, timeout=30) as r:
|
|
result = json.loads(r.read() or b"{}")
|
|
clients = result.get("clients", [])
|
|
# The unpaired ones are surfaced separately rather than left to be spotted in
|
|
# a list: they are the whole reason somebody runs this command twice.
|
|
unpaired = [c.get("code") for c in clients if not c.get("soar_client_id")]
|
|
print(json.dumps({"clients": clients, "unpaired": unpaired}))
|
|
|
|
|
|
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)
|