Skip to content

feat(ADDON-88124): add IndexName validator for Splunk index name validation - #353

Merged
artemrys merged 2 commits into
mainfrom
develop
Jun 5, 2026
Merged

feat(ADDON-88124): add IndexName validator for Splunk index name validation#353
artemrys merged 2 commits into
mainfrom
develop

Conversation

@okashaev-splunk

Copy link
Copy Markdown
Contributor

Why

This PR is part of a multilayer change to replace current per-add-on length and regex index name validators with a central, authoritative validation endpoint. The new validation also covers MDL (Machine Data Lake) federated dataset names — ~.federated.<name> — which route data to Machine Data Lake via Ingest Processor and have naming rules that a single regex cannot handle correctly.

The changes:

  • SplCore — implements POST /services/data/indexes/_validateName as the single point of truth for index name validation. All future rule changes happen here only, without requiring updates across individual add-ons.
  • splunktaucclib (this PR) — adds IndexName validator that calls the SplCore endpoint. Falls back to a local reimplementation of the same rules to stay compatible with older Splunk versions where the endpoint is not yet available.
  • splunk-add-on-ucc-framework — adds {"type": "index_name"} support to globalConfig.json schema and generates validator.IndexName() in REST handler code. Most add-ons have no custom REST handler and rely entirely on ucc-gen; without this change they would need to add a custom handler just to use the new validator.
  • Technology add-ons — replace current length and regex validators in globalConfig.json with {"type": "index_name"}. Add-ons with existing custom validators replace those with IndexName directly.

What

Adds a new IndexName validator class to splunktaucclib/rest_handler/endpoint/validator.py.

How

  • Calls POST /services/data/indexes/_validateName (Splunk core endpoint) to validate a candidate index name without creating anything.
  • Session key is auto-detected from __main__.___sessionKey (written by MConfigHandler.__init__ from stdin before any handler method runs).
  • splunkd URI is auto-detected from the SPLUNKD_URI environment variable, falling back to solnlib.splunkenv.get_splunkd_uri().
  • Falls back to local pure-Python validation rules (mirroring IndexAdminHandler::validateName() from splcore develop branch) when the endpoint is unavailable: HTTP 404 (older Splunk versions), HTTP 400 with unsupported index_name argument, or no session key available.
  • _call_validate_endpoint returns (None, None) to signal fallback, (True, None) for valid, (False, str) for invalid or request failure.
  • validate_fallback and helpers (_validate_as_index_name, _validate_as_dataset_name) return a plain str — empty means valid, non-empty is the error message.
  • Handles three name shapes: regular index names, federated: prefix (stripped before applying index rules), and ~.federated. MDL dataset names (routed to dataset-specific validation).
  • ucclog logging throughout _call_validate_endpoint (WARNING for 404/400/403/5xx, ERROR for unexpected exceptions and malformed responses) and validate() (DEBUG for local fallback rejections).
  • self._msg cleared at the start of validate() to prevent stale error messages when the validator instance is reused across requests.
  • Lazy import of ucclog inside methods to avoid solnlib.log.Logs() being called at import time (requires Splunk runtime).
  • Endpoint response parsing and HTTP error message extraction both wrapped defensively: except (KeyError, IndexError, TypeError, ValueError) covers missing keys, empty/null lists, null content, and non-JSON bodies.
  • Zero-argument constructor — works as a drop-in RestField validator at class definition time, consistent with all existing validators.
  • _INTERNAL_INDEXES frozenset sourced from splcore develop branch IndexAdminHandler::validateName().

Usage

RestField("index", required=True, validator=IndexName())

Tests

98 unit tests across five test classes:

  • TestValidateFallback — parametrized valid/invalid name cases for local rules, covering regular names, federated: prefix, ~.federated. MDL dataset names, case-insensitive kvstore and default checks, length boundaries, and all reserved internal index names.
  • TestGetSessionKey — reads __main__.___sessionKey; absent attribute returns None.
  • TestGetSplunkdInfoSPLUNKD_URI env var parsing; solnlib fallback when env var absent.
  • TestCallValidateEndpoint — HTTP interaction: correct client.post() endpoint/body, correct SplunkRestClient constructor args, 404/403/400/5xx handling with log assertions, malformed response shapes (non-JSON, empty entry list, missing content key, content: null, messages: null, empty messages list), no session key path.
  • TestValidate — orchestration: endpoint called with correct value, fallback triggered on (None, None), self.msg set correctly on failure, no-session-key falls back to local rules.

okashaev-splunk and others added 2 commits May 29, 2026 22:54
## Why

This PR is part of a multilayer change to replace current per-add-on
length and regex index name validators with a central, authoritative
validation endpoint. The new validation also covers MDL (Machine Data
Lake) federated dataset names — `~.federated.<name>` — which route data
to Machine Data Lake via Ingest Processor and have naming rules that a
single regex cannot handle correctly.

The changes:
- **SplCore** — implements `POST /services/data/indexes/_validateName`
as the single point of truth for index name validation. All future rule
changes happen here only, without requiring updates across individual
add-ons.
- **splunktaucclib (this PR)** — adds `IndexName` validator that calls
the SplCore endpoint. Falls back to a local reimplementation of the same
rules to stay compatible with older Splunk versions where the endpoint
is not yet available.
- **splunk-add-on-ucc-framework** — adds `{"type": "index_name"}`
support to `globalConfig.json` schema and generates
`validator.IndexName()` in REST handler code. Most add-ons have no
custom REST handler and rely entirely on ucc-gen; without this change
they would need to add a custom handler just to use the new validator.
- **Technology add-ons** — replace current length and regex validators
in `globalConfig.json` with `{"type": "index_name"}`. Add-ons with
existing custom validators replace those with `IndexName` directly.

## What

Adds a new `IndexName` validator class to
`splunktaucclib/rest_handler/endpoint/validator.py`.

## How

- Calls `POST /services/data/indexes/_validateName` (Splunk core
endpoint) to validate a candidate index name without creating anything.
- Session key is auto-detected from `__main__.___sessionKey` (written by
`MConfigHandler.__init__` from stdin before any handler method runs).
- splunkd URI is auto-detected from the `SPLUNKD_URI` environment
variable, falling back to `solnlib.splunkenv.get_splunkd_uri()`.
- Falls back to local pure-Python validation rules (mirroring
`IndexAdminHandler::validateName()` from splcore develop branch) when
the endpoint is unavailable: HTTP 404 (older Splunk versions), HTTP 400
with unsupported `index_name` argument, or no session key available.
- `_call_validate_endpoint` returns `(None, None)` to signal fallback,
`(True, None)` for valid, `(False, str)` for invalid or request failure.
- `validate_fallback` and helpers (`_validate_as_index_name`,
`_validate_as_dataset_name`) return a plain `str` — empty means valid,
non-empty is the error message.
- Handles three name shapes: regular index names, `federated:` prefix
(stripped before applying index rules), and `~.federated.` MDL dataset
names (routed to dataset-specific validation).
- `ucclog` logging throughout `_call_validate_endpoint` (WARNING for
404/400/403/5xx, ERROR for unexpected exceptions and malformed
responses) and `validate()` (DEBUG for local fallback rejections).
- `self._msg` cleared at the start of `validate()` to prevent stale
error messages when the validator instance is reused across requests.
- Lazy import of `ucclog` inside methods to avoid `solnlib.log.Logs()`
being called at import time (requires Splunk runtime).
- Endpoint response parsing and HTTP error message extraction both
wrapped defensively: `except (KeyError, IndexError, TypeError,
ValueError)` covers missing keys, empty/null lists, null content, and
non-JSON bodies.
- Zero-argument constructor — works as a drop-in `RestField` validator
at class definition time, consistent with all existing validators.
- `_INTERNAL_INDEXES` frozenset sourced from splcore develop branch
`IndexAdminHandler::validateName()`.

## Usage

```python
RestField("index", required=True, validator=IndexName())
```

## Tests

98 unit tests across five test classes:

- `TestValidateFallback` — parametrized valid/invalid name cases for
local rules, covering regular names, `federated:` prefix, `~.federated.`
MDL dataset names, case-insensitive `kvstore` and `default` checks,
length boundaries, and all reserved internal index names.
- `TestGetSessionKey` — reads `__main__.___sessionKey`; absent attribute
returns `None`.
- `TestGetSplunkdInfo` — `SPLUNKD_URI` env var parsing; solnlib fallback
when env var absent.
- `TestCallValidateEndpoint` — HTTP interaction: correct `client.post()`
endpoint/body, correct `SplunkRestClient` constructor args,
404/403/400/5xx handling with log assertions, malformed response shapes
(non-JSON, empty entry list, missing content key, `content: null`,
`messages: null`, empty `messages` list), no session key path.
- `TestValidate` — orchestration: endpoint called with correct value,
fallback triggered on `(None, None)`, `self.msg` set correctly on
failure, no-session-key falls back to local rules.

## Jira ticket reference 
- ADDON-88124

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
@artemrys
artemrys merged commit 9cd51fc into main Jun 5, 2026
27 of 30 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants