Skip to content

feat(splunk): add Splunk Enterprise and Cloud integration - #6743

Merged
waleedlatif1 merged 7 commits into
stagingfrom
feat/splunk-integration
Aug 16, 2026
Merged

feat(splunk): add Splunk Enterprise and Cloud integration#6743
waleedlatif1 merged 7 commits into
stagingfrom
feat/splunk-integration

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a Splunk block with 12 tools over the Splunk Enterprise / Splunk Cloud management REST API: run search, create/get/cancel search job, get search results, list/get/dispatch saved searches, list/get fired alerts, list indexes, list apps.
  • Auth is a bearer authentication token, with username/password basic auth as a fallback. Requests are namespace-aware (/services by default, /servicesNS/{owner}/{app} when an owner or app is set) and always pin output_mode=json so a caller cannot flip the response back to XML.

Three things worth a reviewer's attention:

  • Get Search Results now uses search/v2/jobs/{sid}/results. The v1 instance of that endpoint is deprecated and turned off by default from Splunk Enterprise 9.0.1 / Splunk Cloud 9.0.2208 onward, so every call was hitting a disabled endpoint. Both versions publish the same JSON envelope (init_offset, messages, preview, results), so the response mapping is unchanged.
  • enable_lookups and allow_partial_results were being sent as 0 on every search job. Both were switch subBlocks, and an untouched subBlock does not resolve to "unset" — so the request silently inverted Splunk's documented default of true for both. They are dropdowns defaulting to Yes now. The same class of bug affected every other optional field: an untouched subBlock resolves to null, and the form/query serializers only skipped undefined, so String(null) put earliest_time=null, trigger_actions=null, and force_dispatch=null on the wire. Max Results was worse — Number(null) is 0, and count=0 is Splunk's documented "return every available row", so an untouched Max Results asked for the entire result set on all six paginated operations instead of the documented default of 100. Both serializers now drop null alongside undefined, and the coercion guards against it.
  • One detail remains unsourced: count/offset on alerts/fired_alerts/{name}. The entity reference for that endpoint says "Request parameters: None", while the sibling collection endpoint alerts/fired_alerts documents both. They are exposed on the assumption that the shared Atom collection pagination applies; an instance that ignores them just returns the full set. This is recorded in a TSDoc note on the tool.

Everything else — endpoints, parameter names, defaults, and response field names — is taken from the Splunk REST API reference. Response fields are mapped individually rather than dumped, with Splunk's 0/1 booleans normalized and both the entry[] and feed.entry[] collection envelopes handled.

Type of Change

  • New feature (non-breaking change which adds functionality)

Testing

Tested manually. Added unit tests for the URL and form-body serializers covering the null-drop behavior, the pinned output_mode, explicit falsy values, and namespace selection.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 16, 2026 12:07am

Request Review

@cursor

cursor Bot commented Aug 15, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
New third-party integration that stores Splunk credentials and executes SPL against customer instances; scope is bounded by existing block/tool patterns and focused serializer tests, but mis-parameterized searches or auth still affect production Splunk data and load.

Overview
Adds a Splunk workflow block and catalog/docs wiring so Splunk Enterprise and Splunk Cloud can run SPL searches, manage async search jobs, saved searches, alerts, indexes, and apps from Sim.

The block exposes 12 operations (run search, create/get/cancel job, get results, list/get/dispatch saved searches, fired alerts, indexes, apps) with API-key auth (bearer token, optional basic auth and namespace fields). Param mapping normalizes dropdown/switch toggles via toSplunkToggle, omits untouched pagination fields so Splunk defaults apply, and remaps UI fields like savedSearchName / alertName to API name.

Also adds SplunkIcon (theme-aware wordmark), registers the block in registry-maps, icon mappings, integrations.json, integration docs splunk.mdx, and unit tests for the block’s tools.config.params mapper and subBlock consistency.

Reviewed by Cursor Bugbot for commit f76a211. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds a Splunk Enterprise and Cloud integration with block configuration, twelve management API tools, generated registry metadata, tests, icons, and documentation.

  • Supports synchronous searches and asynchronous search-job lifecycle operations.
  • Adds saved-search, fired-alert, index, and app operations.
  • Normalizes optional parameters while preserving explicit false and zero values.
  • Registers the integration across the application and documentation catalogs.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/blocks/blocks/splunk.ts Defines the Splunk block and correctly preserves typed boolean false values while omitting untouched toggles.
apps/sim/blocks/blocks/splunk.test.ts Covers typed and string toggle values, untouched fields, pagination coercion, parameter remapping, and operation registration.
apps/sim/tools/splunk/utils.ts Implements namespace-aware URLs, authentication, null-safe serialization, and response normalization.
apps/sim/tools/splunk/requests.test.ts Exercises Splunk URL and form-body serialization behavior.
apps/sim/tools/registry.ts Registers the new Splunk tools with the central execution registry.
apps/docs/content/docs/en/integrations/splunk.mdx Documents the integration’s operations, inputs, and outputs.

Reviews (4): Last reviewed commit: "fix(splunk): keep the f field filter on ..." | Re-trigger Greptile

Comment thread apps/sim/blocks/blocks/splunk.ts Outdated
Comment thread apps/sim/blocks/blocks/splunk.ts Outdated
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 5b4f159. Configure here.

Adds 11 tools covering the Splunk REST API search lifecycle, saved searches,
fired alerts, and index metadata, plus the block, catalog meta, and a
placeholder icon.

Search jobs are modelled honestly as asynchronous: create returns a sid, status
and results are separate calls, and the only synchronous path is the documented
exec_mode=oneshot search. Every request pins output_mode=json because Splunk
defaults to XML, and writes are form-encoded as the API expects.

Auth accepts a bearer authentication token or basic auth against a user-supplied
management URL, with optional /servicesNS owner and app namespacing.

The icon is a placeholder currentColor glyph pending the real brand mark.
… the REST reference

- Read results from `search/v2/jobs/{sid}/results`. The v1 instance is deprecated
  and turned off by default from Splunk Enterprise 9.0.1 / Cloud 9.0.2208 onward,
  so every Get Search Results call was hitting a disabled endpoint. Both versions
  publish the same JSON envelope, so the response mapping is unchanged.
- Stop sending `enable_lookups=0` / `allow_partial_results=0` on every search job.
  Both subBlocks were switches, which report false when untouched, silently
  inverting Splunk's documented default of true. They are now dropdowns that
  default to Yes.
- Add `max_count` to Run Search and Create Search Job so a oneshot search can be
  bounded below the 10000-row default.
- Add `force_dispatch` to Dispatch Saved Search and the documented
  `triggered_alerts`, `trigger_time_rendered`, and `expiration_time_rendered`
  fields to Get Fired Alerts.
- Add Splunk List Apps over `apps/local`, whose response keys are documented; the
  app name is the namespace value the other tools accept.
- Trim user-supplied path segments, pin `output_mode=json` so a query argument
  cannot override it, and default the index-type filter to all, since Splunk
  itself defaults `datatype` to event.
An untouched subBlock serializes as `null`, not `undefined`, so every optional
Splunk field the user left alone was reaching the request:

- `buildSplunkFormBody` and `buildSplunkUrl` skipped `undefined` and `''` but
  not `null`, so `String(null)` sent `earliest_time=null`, `trigger_actions=null`,
  `force_dispatch=null`, and `add_summary_to_metadata=null` on the wire. Each one
  overrode the default Splunk would otherwise have applied. `force_dispatch` and
  `trigger_actions` have no documented default in the REST reference at all, so
  asserting a value for them was unsourced either way.
- Max Results coerced `null` through `Number()` to `0`, and `count=0` is Splunk's
  documented "return every available row". An untouched Max Results therefore
  asked for the whole result set on all six paginated operations instead of the
  documented default of 100.

Record the sourcing gap on Get Fired Alerts: the entity reference for
`alerts/fired_alerts/{name}` says "Request parameters: None" while the sibling
collection endpoint documents `count`/`offset`.

Revert the unrelated whitespace and table-output drift the docs generator swept
in from the base branch.
The dropdown supplies the strings 'true'/'false', but a workflow variable, an
agent tool call, or a block created over the API supplies a real boolean.
Comparing only against the string turned an explicit `false` into `true`, so a
caller who deliberately disabled lookups or partial results got them enabled.
Normalize both forms, and leave an untouched toggle undefined so the field is
omitted and Splunk applies its own default.
…ing sid

Swarm-validated every tool against the Splunk REST reference on help.splunk.com.

- namespacePrefix filled a half-specified namespace with nobody/search. `nobody`
  names the shared-application owner, so `/servicesNS/nobody/myapp` silently hid
  every user-private saved search, alert, and job in that app; supplying only an
  owner pinned the request to the `search` app. The reference gives `-` as the
  wildcard for both nodes ("To indicate all users, all apps, or resources shared
  by all users, use the wildcard dash (-) symbol"). The old behavior was also
  codified in a test, which now asserts the wildcard instead.
- create/dispatch reported success with `sid: null` when no search ID came back.
  Both now fail loudly, and Create Search Job rejects `exec_mode=oneshot` up
  front — the reference says that mode "Does not return the search ID".
- The results and control endpoints can answer with an empty body (204 while a
  job is still running; the control endpoint documents "Returned values: None"),
  where `Response.json()` threw `Unexpected end of JSON input`.
- Get Fired Alerts no longer sends count/offset. `alerts/fired_alerts/{name}`
  documents "Request parameters: None" and, unlike its sibling collection, does
  not carry the pagination note; an unsupported argument can be rejected outright.
- saved/searches now sends the `f` field filter the reference prescribes for it
  ("This endpoint returns an unusually high number of values"). A saved search
  carries well over a hundred content keys; Sim projects 13.
- Get Saved Search fabricated an all-null saved search from an empty feed.
- The switch-typed toggles (Trigger Alert Actions, Force Dispatch, Include Field
  Summary) reached the tools as the raw string 'false' instead of a boolean.
- Corrected the bearer-token version floor (7.3, not 8.x) and the max_count and
  saved-search filter descriptions to what the reference actually documents.
@waleedlatif1
waleedlatif1 force-pushed the feat/splunk-integration branch from 5b4f159 to 5e11d9a Compare August 16, 2026 00:01
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

The reference attaches the "unusually high number of values" warning and its f
prescription to the saved/searches collection. The single-entity endpoint returns
one entry, so the filter buys nothing there and its support is not documented.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
waleedlatif1 merged commit 852906e into staging Aug 16, 2026
30 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit f76a211. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant