From b9e4210ea9157be44100a44965a4dae0768ea156 Mon Sep 17 00:00:00 2001 From: Oleg Kashaev Date: Tue, 2 Jun 2026 15:57:36 +0200 Subject: [PATCH 1/9] feat: introduce dedicated index_name validator type Replace the two-validator combination (regex + string length) used for Splunk index name validation with a single dedicated `index_name` validator type. This simplifies the globalConfig schema and generated REST handler code, and makes the intent explicit. - Add `IndexNameValidator` Zod schema and register it in `AllValidators` - Add `IndexNameValidator` class in `validator_builder.py` generating `validator.IndexName()` - Update `IndexEntity.long_form()` and `migrateIndexTypeEntity` to emit `{"type": "index_name"}` - Add testdata golden file and update unit tests accordingly Co-Authored-By: Claude Opus 4.7 --- .../rest_builder/validator_builder.py | 12 ++++++++ .../entity/index_entity.py | 13 +------- .../rest_builder/test_validator_builder.py | 4 +++ tests/unit/entity/test_index_entity.py | 30 ++----------------- .../validator_builder_result_index_name | 1 + ui/src/CustomEntity/helper.tsx | 15 +--------- ui/src/types/globalConfig/baseSchemas.ts | 2 ++ ui/src/types/globalConfig/validators.ts | 6 ++++ 8 files changed, 29 insertions(+), 54 deletions(-) create mode 100644 tests/unit/testdata/validator_builder_result_index_name diff --git a/splunk_add_on_ucc_framework/commands/rest_builder/validator_builder.py b/splunk_add_on_ucc_framework/commands/rest_builder/validator_builder.py index 8c2ee322ec..e7ac13c032 100644 --- a/splunk_add_on_ucc_framework/commands/rest_builder/validator_builder.py +++ b/splunk_add_on_ucc_framework/commands/rest_builder/validator_builder.py @@ -141,6 +141,17 @@ def _get_arguments(self, config: dict[str, Any]) -> dict[str, Any]: return {"regex": "r" + quote_regex(regex)} +class IndexNameValidator(BaseValidator): + def _get_class_name(self) -> str: + return "IndexName" + + def _get_arguments(self, config: dict[str, Any]) -> dict[str, Any]: + return {} + + def build(self, config: dict[str, Any]) -> str: + return "validator.IndexName()" + + class ValidatorBuilder: _validation_config_map = { "string": StringValidator, @@ -150,6 +161,7 @@ class ValidatorBuilder: "ipv4": Ipv4Validator, "date": DateValidator, "url": UrlValidator, + "index_name": IndexNameValidator, # file validator does not need any generated code, everything is # validated in the UI } diff --git a/splunk_add_on_ucc_framework/entity/index_entity.py b/splunk_add_on_ucc_framework/entity/index_entity.py index 6c7845383b..d73425e255 100644 --- a/splunk_add_on_ucc_framework/entity/index_entity.py +++ b/splunk_add_on_ucc_framework/entity/index_entity.py @@ -31,18 +31,7 @@ def long_form(self) -> dict[str, Any]: "createSearchChoice": True, }, "validators": [ - { - "type": "regex", - "errorMsg": "Index names must begin with a letter or a number " - "and must contain only letters, numbers, underscores or hyphens.", - "pattern": r"^[a-zA-Z0-9][a-zA-Z0-9\\_\\-]*$", - }, - { - "type": "string", - "errorMsg": "Length of index name should be between 1 and 80.", - "minLength": 1, - "maxLength": 80, - }, + {"type": "index_name"}, ], } diff --git a/tests/unit/commands/rest_builder/test_validator_builder.py b/tests/unit/commands/rest_builder/test_validator_builder.py index 425ac34966..07de857752 100644 --- a/tests/unit/commands/rest_builder/test_validator_builder.py +++ b/tests/unit/commands/rest_builder/test_validator_builder.py @@ -60,6 +60,10 @@ [{"type": "url"}], get_testdata_file("validator_builder_result_url"), ), + ( + [{"type": "index_name"}], + get_testdata_file("validator_builder_result_index_name"), + ), ( [ { diff --git a/tests/unit/entity/test_index_entity.py b/tests/unit/entity/test_index_entity.py index 313ab89922..f7213f9fdd 100644 --- a/tests/unit/entity/test_index_entity.py +++ b/tests/unit/entity/test_index_entity.py @@ -17,20 +17,7 @@ def test_interval_min_definition(): "denyList": "^_.*$", "createSearchChoice": True, }, - "validators": [ - { - "type": "regex", - "errorMsg": "Index names must begin with a letter or a number and must contain only letters, " - "numbers, underscores or hyphens.", - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\\\_\\\\-]*$", - }, - { - "type": "string", - "errorMsg": "Length of index name should be between 1 and 80.", - "minLength": 1, - "maxLength": 80, - }, - ], + "validators": [{"type": "index_name"}], } @@ -59,18 +46,5 @@ def test_interval_max_definition(): "denyList": "^_.*$", "createSearchChoice": True, }, - "validators": [ - { - "type": "regex", - "errorMsg": "Index names must begin with a letter or a number and must contain only letters, numbers, " - "underscores or hyphens.", - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\\\_\\\\-]*$", - }, - { - "type": "string", - "errorMsg": "Length of index name should be between 1 and 80.", - "minLength": 1, - "maxLength": 80, - }, - ], + "validators": [{"type": "index_name"}], } diff --git a/tests/unit/testdata/validator_builder_result_index_name b/tests/unit/testdata/validator_builder_result_index_name new file mode 100644 index 0000000000..30e2828570 --- /dev/null +++ b/tests/unit/testdata/validator_builder_result_index_name @@ -0,0 +1 @@ +validator.IndexName() \ No newline at end of file diff --git a/ui/src/CustomEntity/helper.tsx b/ui/src/CustomEntity/helper.tsx index 6ef8de9243..4bfde2169e 100644 --- a/ui/src/CustomEntity/helper.tsx +++ b/ui/src/CustomEntity/helper.tsx @@ -112,19 +112,6 @@ export const migrateIndexTypeEntity = ( denyList: '^_.*$', createSearchChoice: true, }, - validators: [ - { - type: 'regex', - pattern: '^[a-zA-Z0-9][a-zA-Z0-9\\_\\-]*$', - errorMsg: - 'Index names must begin with a letter or a number and must contain only letters, numbers, underscores or hyphens.', - }, - { - type: 'string', - minLength: 1, - maxLength: 80, - errorMsg: 'Length of index name should be between 1 and 80.', - }, - ], + validators: [{ type: 'index_name' }], }; }; diff --git a/ui/src/types/globalConfig/baseSchemas.ts b/ui/src/types/globalConfig/baseSchemas.ts index 1ddda02d93..949d4f4ecb 100644 --- a/ui/src/types/globalConfig/baseSchemas.ts +++ b/ui/src/types/globalConfig/baseSchemas.ts @@ -2,6 +2,7 @@ import { z } from 'zod'; import { DateValidator, EmailValidator, + IndexNameValidator, Ipv4Validator, NumberValidator, RegexValidator, @@ -146,5 +147,6 @@ export const AllValidators = z.array( Ipv4Validator.strict(), UrlValidator.strict(), DateValidator.strict(), + IndexNameValidator.strict(), ]) ); diff --git a/ui/src/types/globalConfig/validators.ts b/ui/src/types/globalConfig/validators.ts index f00e943898..424abec9f2 100644 --- a/ui/src/types/globalConfig/validators.ts +++ b/ui/src/types/globalConfig/validators.ts @@ -34,6 +34,11 @@ export const DateValidator = z.object({ type: z.literal('date'), }); +export const IndexNameValidator = z.object({ + errorMsg: z.string().optional(), + type: z.literal('index_name'), +}); + export const AnyOfValidators = z.discriminatedUnion('type', [ NumberValidator, StringValidator, @@ -42,4 +47,5 @@ export const AnyOfValidators = z.discriminatedUnion('type', [ Ipv4Validator, UrlValidator, DateValidator, + IndexNameValidator, ]); From c7a926b80133e876b63b1a969da93ba33774f341 Mon Sep 17 00:00:00 2001 From: srv-rr-github-token <94607705+srv-rr-github-token@users.noreply.github.com> Date: Tue, 2 Jun 2026 14:09:12 +0000 Subject: [PATCH 2/9] update screenshots --- .../__images__/DashboardPage-dashboard-page-view-chromium.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png b/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png index c92dc74943..dc7419d93c 100644 --- a/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png +++ b/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21e43dce8e4c75465949ac3cf6330a9b9291c18cfb1e26656818f8ba3192814a -size 74283 +oid sha256:5f178905f38692c71ee53968de19d942173c5d40837467a8db61e7a8ee3626c5 +size 71259 From 26be17775a393beb9de1b04eeb5d126adbc93912 Mon Sep 17 00:00:00 2001 From: Oleg Kashaev Date: Wed, 3 Jun 2026 13:03:16 +0200 Subject: [PATCH 3/9] fix: address review comments for index_name validator - Add IndexNameValidator to schema.json definitions and AnyValidator - Update expected REST handler fixtures to emit validator.IndexName() - Fix test function names from test_interval_* to test_index_* Co-Authored-By: Claude Opus 4.7 --- .../schema/schema.json | 21 +++++++++++++++++++ ...lunk_ta_uccexample_rh_example_input_one.py | 5 +---- ...lunk_ta_uccexample_rh_example_input_two.py | 10 +-------- tests/unit/entity/test_index_entity.py | 4 ++-- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/splunk_add_on_ucc_framework/schema/schema.json b/splunk_add_on_ucc_framework/schema/schema.json index 9e00d7f96c..ab3ae7a703 100644 --- a/splunk_add_on_ucc_framework/schema/schema.json +++ b/splunk_add_on_ucc_framework/schema/schema.json @@ -3331,6 +3331,24 @@ ], "additionalProperties": false }, + "IndexNameValidator": { + "type": "object", + "description": "Validates that the field value is a valid Splunk index name.", + "properties": { + "errorMsg": { + "$ref": "#/definitions/errorMsg" + }, + "type": { + "const": "index_name", + "type": "string", + "description": "Exactly: index_name" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, "AnyValidator": { "type": "array", "description": "It is used to validate the values of fields using various validators.", @@ -3356,6 +3374,9 @@ }, { "$ref": "#/definitions/DateValidator" + }, + { + "$ref": "#/definitions/IndexNameValidator" } ] } diff --git a/tests/testdata/expected_addons/expected_output_global_config_everything/Splunk_TA_UCCExample/bin/splunk_ta_uccexample_rh_example_input_one.py b/tests/testdata/expected_addons/expected_output_global_config_everything/Splunk_TA_UCCExample/bin/splunk_ta_uccexample_rh_example_input_one.py index 7a42874789..a83e1df0a9 100644 --- a/tests/testdata/expected_addons/expected_output_global_config_everything/Splunk_TA_UCCExample/bin/splunk_ta_uccexample_rh_example_input_one.py +++ b/tests/testdata/expected_addons/expected_output_global_config_everything/Splunk_TA_UCCExample/bin/splunk_ta_uccexample_rh_example_input_one.py @@ -82,10 +82,7 @@ required=True, encrypted=False, default='default', - validator=validator.String( - max_len=80, - min_len=1, - ) + validator=validator.IndexName() ), field.RestField( 'account', diff --git a/tests/testdata/expected_addons/expected_output_global_config_everything/Splunk_TA_UCCExample/bin/splunk_ta_uccexample_rh_example_input_two.py b/tests/testdata/expected_addons/expected_output_global_config_everything/Splunk_TA_UCCExample/bin/splunk_ta_uccexample_rh_example_input_two.py index 2c0bed743a..15b6f4e74c 100644 --- a/tests/testdata/expected_addons/expected_output_global_config_everything/Splunk_TA_UCCExample/bin/splunk_ta_uccexample_rh_example_input_two.py +++ b/tests/testdata/expected_addons/expected_output_global_config_everything/Splunk_TA_UCCExample/bin/splunk_ta_uccexample_rh_example_input_two.py @@ -47,15 +47,7 @@ required=True, encrypted=False, default='default', - validator=validator.AllOf( - validator.Pattern( - regex=r"""^[a-zA-Z0-9][a-zA-Z0-9\\_\\-]*$""", - ), - validator.String( - max_len=80, - min_len=1, - ) - ) + validator=validator.IndexName() ), field.RestField( 'account', diff --git a/tests/unit/entity/test_index_entity.py b/tests/unit/entity/test_index_entity.py index f7213f9fdd..fb9c369f52 100644 --- a/tests/unit/entity/test_index_entity.py +++ b/tests/unit/entity/test_index_entity.py @@ -1,7 +1,7 @@ from splunk_add_on_ucc_framework.entity import IndexEntity -def test_interval_min_definition(): +def test_index_min_definition(): definition = {"type": "index", "field": "index", "label": "Index"} index = IndexEntity.from_definition(definition) @@ -21,7 +21,7 @@ def test_interval_min_definition(): } -def test_interval_max_definition(): +def test_index_max_definition(): definition = { "type": "index", "field": "index", From e43094e181aef24d61826c01ac7a3647232150c8 Mon Sep 17 00:00:00 2001 From: srv-rr-github-token <94607705+srv-rr-github-token@users.noreply.github.com> Date: Wed, 3 Jun 2026 11:32:03 +0000 Subject: [PATCH 4/9] update screenshots --- .../__images__/DashboardPage-dashboard-page-view-chromium.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png b/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png index dc7419d93c..c92dc74943 100644 --- a/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png +++ b/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f178905f38692c71ee53968de19d942173c5d40837467a8db61e7a8ee3626c5 -size 71259 +oid sha256:21e43dce8e4c75465949ac3cf6330a9b9291c18cfb1e26656818f8ba3192814a +size 74283 From 18bd710394b4b497125fa2a9004f18032d259813 Mon Sep 17 00:00:00 2001 From: Oleg Kashaev Date: Wed, 3 Jun 2026 14:28:41 +0200 Subject: [PATCH 5/9] fix(schema): add IndexNameValidator to SingleSelectEntity validators Co-Authored-By: Claude Opus 4.7 --- splunk_add_on_ucc_framework/schema/schema.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/splunk_add_on_ucc_framework/schema/schema.json b/splunk_add_on_ucc_framework/schema/schema.json index ab3ae7a703..9dac700169 100644 --- a/splunk_add_on_ucc_framework/schema/schema.json +++ b/splunk_add_on_ucc_framework/schema/schema.json @@ -1217,6 +1217,9 @@ }, { "$ref": "#/definitions/DateValidator" + }, + { + "$ref": "#/definitions/IndexNameValidator" } ] } From 172af4fb574f21321a2211173f610cfd4d3d10ec Mon Sep 17 00:00:00 2001 From: Oleg Kashaev Date: Wed, 3 Jun 2026 19:42:45 +0200 Subject: [PATCH 6/9] fix(test): update example_input_one index validator to index_name type Replace the old explicit string validator with the new dedicated index_name validator type in the everything test addon globalConfig. Co-Authored-By: Claude Opus 4.7 --- .../package_global_config_everything/globalConfig.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/testdata/test_addons/package_global_config_everything/globalConfig.json b/tests/testdata/test_addons/package_global_config_everything/globalConfig.json index 5b3f57bb29..04a5511203 100644 --- a/tests/testdata/test_addons/package_global_config_everything/globalConfig.json +++ b/tests/testdata/test_addons/package_global_config_everything/globalConfig.json @@ -1216,10 +1216,7 @@ "label": "Index", "validators": [ { - "type": "string", - "errorMsg": "Length of index name should be between 1 and 80.", - "minLength": 1, - "maxLength": 80 + "type": "index_name" } ], "defaultValue": "default", From 797adfea6da465153c59c01d4ce0b0443383c3cb Mon Sep 17 00:00:00 2001 From: Oleg Kashaev Date: Fri, 5 Jun 2026 13:40:26 +0200 Subject: [PATCH 7/9] fix: bump splunktaucclib minimum version to 8.2.0 Required for validator.IndexName() support introduced in splunktaucclib 8.2.0. Co-Authored-By: Claude Opus 4.7 --- splunk_add_on_ucc_framework/install_python_libraries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splunk_add_on_ucc_framework/install_python_libraries.py b/splunk_add_on_ucc_framework/install_python_libraries.py index fe793d3011..1bbbc38af4 100644 --- a/splunk_add_on_ucc_framework/install_python_libraries.py +++ b/splunk_add_on_ucc_framework/install_python_libraries.py @@ -32,7 +32,7 @@ logger = logging.getLogger("ucc_gen") -LIBS_REQUIRED_FOR_UI = {"splunktaucclib": "6.6.0"} +LIBS_REQUIRED_FOR_UI = {"splunktaucclib": "8.2.0"} LIBS_REQUIRED_FOR_OAUTH = {"solnlib": "5.5.0"} From 101c931fdc4f0f97121ad7b968c3d56951476182 Mon Sep 17 00:00:00 2001 From: Oleg Kashaev Date: Fri, 5 Jun 2026 13:56:39 +0200 Subject: [PATCH 8/9] fix(test): update expected splunktaucclib version strings to 8.2.0 Co-Authored-By: Claude Opus 4.7 --- tests/unit/test_install_python_libraries.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_install_python_libraries.py b/tests/unit/test_install_python_libraries.py index 1e834b6c9a..a4bbd064c5 100644 --- a/tests/unit/test_install_python_libraries.py +++ b/tests/unit/test_install_python_libraries.py @@ -255,7 +255,7 @@ def test_install_libraries_when_no_splunktaucclib_is_present_but_has_ui( expected_msg = ( f"This add-on has an UI, so the splunktaucclib is required but not found in {tmp_lib_reqs_file}. " - f"Please add it there and make sure it is at least version 6.6.0." + f"Please add it there and make sure it is at least version 8.2.0." ) expected_caplog = "Command result: WARNING: Package(s) not found: splunktaucclib" @@ -280,7 +280,7 @@ def test_install_libraries_when_wrong_splunktaucclib_is_present_but_has_ui( tmp_lib_reqs_file = tmp_lib_path / "requirements.txt" tmp_lib_reqs_file.write_text("splunktaucclib==6.3\n") - expected_msg = "splunktaucclib found but has the wrong version. Please make sure it is at least version 6.6.0." + expected_msg = "splunktaucclib found but has the wrong version. Please make sure it is at least version 8.2.0." expected_caplog = "Command result: Name: splunktaucclib\nVersion: 6.3.0" with pytest.raises(WrongSplunktaucclibVersion) as exc: From 423f56ec780f7f400cc8d083320ca2fd8038a7d3 Mon Sep 17 00:00:00 2001 From: srv-rr-github-token <94607705+srv-rr-github-token@users.noreply.github.com> Date: Fri, 5 Jun 2026 13:47:16 +0000 Subject: [PATCH 9/9] update screenshots --- .../__images__/DashboardPage-dashboard-page-view-chromium.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png b/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png index dc7419d93c..c92dc74943 100644 --- a/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png +++ b/ui/src/pages/Dashboard/stories/__images__/DashboardPage-dashboard-page-view-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f178905f38692c71ee53968de19d942173c5d40837467a8db61e7a8ee3626c5 -size 71259 +oid sha256:21e43dce8e4c75465949ac3cf6330a9b9291c18cfb1e26656818f8ba3192814a +size 74283