Skip to content

Commit

Permalink
feat: allow developers to choose the default view (#1197)
Browse files Browse the repository at this point in the history
**Issue number:** #1041

## Summary

### Changes

> Please provide a summary of what's being changed

Configuration page require admin privileges and if a Splunk user is not
an admin - configuration page will show an error which is confusing.
This PR allows to set a default page to `search` so there will be no
error shown when a Splunk user opens add-on for the first time.

This PR enables TA developers to choose the default view, one of four:
`inputs`, `configuration`, `dashboard` and `search`.

### User experience

> Please describe what the user experience looks like before and after
this change

Nothing changes for the existing customers. For customers who decide to
use `search` view as a default one - they need to update their
globalConfig file, specifically set `meta.defaultView` to `search` and
rebuild an add-on.

## Checklist

If your change doesn't seem to apply, please leave them unchecked.

* [x] I have performed a self-review of this change
* [x] Changes have been tested
* [ ] Changes are documented
* [x] PR title follows [conventional commit
semantics](https://www.conventionalcommits.org/en/v1.0.0/)
  • Loading branch information
artemrys committed Jun 3, 2024
1 parent 89b064f commit 21610e2
Show file tree
Hide file tree
Showing 19 changed files with 311 additions and 81 deletions.
3 changes: 2 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins = covdefaults
omit =
splunk_add_on_ucc_framework/commands/imports.py
splunk_add_on_ucc_framework/commands/modular_alert_builder/arf_template/alert_action_helper.py.template
splunk_add_on_ucc_framework/templates/input.module-template

[report]
fail_under = 77
fail_under = 78.5
3 changes: 3 additions & 0 deletions splunk_add_on_ucc_framework/commands/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def generate_data_ui(
addon_name: str,
include_inputs: bool,
include_dashboard: bool,
default_view: str,
) -> None:
# Create directories in the output folder for add-on's UI nav and views.
os.makedirs(
Expand All @@ -272,6 +273,7 @@ def generate_data_ui(
default_xml_content = data_ui_generator.generate_nav_default_xml(
include_inputs=include_inputs,
include_dashboard=include_dashboard,
default_view=default_view,
)
default_xml_file.write(default_xml_content)
with open(
Expand Down Expand Up @@ -556,6 +558,7 @@ def generate(
ta_name,
global_config.has_inputs(),
global_config.has_dashboard(),
global_config.meta.get("default_view", data_ui_generator.DEFAULT_VIEW),
)
logger.info("Copied UCC template directory")
global_config_file = (
Expand Down
28 changes: 23 additions & 5 deletions splunk_add_on_ucc_framework/data_ui_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
from xml.etree import ElementTree as ET
from defusedxml import minidom

DEFAULT_VIEW = "configuration"


def _pretty_print_xml(string: str) -> str:
"""
Expand All @@ -28,17 +30,33 @@ def _pretty_print_xml(string: str) -> str:
return minidom.parseString(string).toprettyxml(indent=" ")


def generate_nav_default_xml(include_inputs: bool, include_dashboard: bool) -> str:
def generate_nav_default_xml(
include_inputs: bool, include_dashboard: bool, default_view: str
) -> str:
"""
Generates `default/data/ui/nav/default.xml` file.
The validation is being done in `_validate_meta_default_view` function from `global_config_validator.py` file.
"""
nav = ET.Element("nav")
if include_inputs:
ET.SubElement(nav, "view", attrib={"name": "inputs"})
ET.SubElement(nav, "view", attrib={"name": "configuration", "default": "true"})
if default_view == "inputs":
ET.SubElement(nav, "view", attrib={"name": "inputs", "default": "true"})
else:
ET.SubElement(nav, "view", attrib={"name": "inputs"})
if default_view == "configuration":
ET.SubElement(nav, "view", attrib={"name": "configuration", "default": "true"})
else:
ET.SubElement(nav, "view", attrib={"name": "configuration"})
if include_dashboard:
ET.SubElement(nav, "view", attrib={"name": "dashboard"})
ET.SubElement(nav, "view", attrib={"name": "search"})
if default_view == "dashboard":
ET.SubElement(nav, "view", attrib={"name": "dashboard", "default": "true"})
else:
ET.SubElement(nav, "view", attrib={"name": "dashboard"})
if default_view == "search":
ET.SubElement(nav, "view", attrib={"name": "search", "default": "true"})
else:
ET.SubElement(nav, "view", attrib={"name": "search"})
nav_as_string = ET.tostring(nav, encoding="unicode")
return _pretty_print_xml(nav_as_string)

Expand Down
2 changes: 1 addition & 1 deletion splunk_add_on_ucc_framework/global_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def alerts(self) -> List[Dict[str, Any]]:
return self._content.get("alerts", [])

@property
def meta(self) -> Dict[str, str]:
def meta(self) -> Dict[str, Any]:
return self._content["meta"]

@property
Expand Down
37 changes: 26 additions & 11 deletions splunk_add_on_ucc_framework/global_config_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
import logging
import itertools


import jsonschema

from splunk_add_on_ucc_framework import dashboard as dashboard_lib
from splunk_add_on_ucc_framework import global_config as global_config_lib
from splunk_add_on_ucc_framework import data_ui_generator
from splunk_add_on_ucc_framework.tabs import resolve_tab, Tab

logger = logging.getLogger("ucc_gen")
Expand All @@ -43,6 +43,7 @@ class GlobalConfigValidator:

def __init__(self, source_dir: str, global_config: global_config_lib.GlobalConfig):
self._source_dir = source_dir
self._global_config = global_config
self._config = global_config.content

@property
Expand Down Expand Up @@ -613,11 +614,11 @@ def _is_circular(
visited = self._is_circular(
mods, visited, all_entity_fields, influenced_field
)
# all of dependent modifications fields are dead_end
# All dependent modifications fields are dead_end
visited[current_field] = DEAD_END
return visited

def _check_if_cilcular(
def _check_if_circular(
self,
all_entity_fields: List[Any],
fields_with_mods: List[Any],
Expand Down Expand Up @@ -672,7 +673,7 @@ def _get_all_entities(

return all_fields

def _get_all_modifiction_data(
def _get_all_modification_data(
self,
collections: List[Dict[str, Any]],
) -> List[Any]:
Expand All @@ -692,9 +693,9 @@ def _get_all_modifiction_data(
def _validate_field_modifications(self) -> None:
"""
Validates:
Circular dependencies
If fields try modify itself
If fields try modify unexisting field
* Circular dependencies
* If fields try to modify itself
* If fields try to modify field that do not exist
"""
pages = self._config["pages"]

Expand All @@ -706,9 +707,9 @@ def _validate_field_modifications(self) -> None:
fields_with_mods_config,
all_modifications_config,
all_fields_config,
) = self._get_all_modifiction_data(tabs)
) = self._get_all_modification_data(tabs)

self._check_if_cilcular(
self._check_if_circular(
all_fields_config, fields_with_mods_config, all_modifications_config
)

Expand All @@ -720,12 +721,25 @@ def _validate_field_modifications(self) -> None:
fields_with_mods_inputs,
all_modifications_inputs,
all_fields_inputs,
) = self._get_all_modifiction_data(services)
) = self._get_all_modification_data(services)

self._check_if_cilcular(
self._check_if_circular(
all_fields_inputs, fields_with_mods_inputs, all_modifications_inputs
)

def _validate_meta_default_view(self) -> None:
default_view = self._global_config.meta.get(
"defaultView", data_ui_generator.DEFAULT_VIEW
)
if default_view == "inputs" and not self._global_config.has_inputs():
raise GlobalConfigValidatorException(
'meta.defaultView == "inputs" but there is no inputs defined in globalConfig'
)
if default_view == "dashboard" and not self._global_config.has_dashboard():
raise GlobalConfigValidatorException(
'meta.defaultView == "dashboard" but there is no dashboard defined in globalConfig'
)

def validate(self) -> None:
self._validate_config_against_schema()
self._validate_configuration_tab_table_has_name_field()
Expand All @@ -740,3 +754,4 @@ def validate(self) -> None:
self._validate_checkbox_group()
self._validate_groups()
self._validate_field_modifications()
self._validate_meta_default_view()
19 changes: 18 additions & 1 deletion splunk_add_on_ucc_framework/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1690,6 +1690,23 @@
"type": "boolean",
"default": true
},
"defaultView": {
"type": "string",
"anyOf": [
{
"const": "inputs"
},
{
"const": "configuration"
},
{
"const": "dashboard"
},
{
"const": "search"
}
]
},
"os-dependentLibraries": {
"type": "array",
"description": "This feature allows you to download and unpack libraries with appropriate binaries for the indicated operating system during the build process.",
Expand Down Expand Up @@ -1753,7 +1770,7 @@
}
},
"required": ["displayName", "name", "restRoot", "version"],
"description": "Meta deta regarding build",
"description": "Metadata regarding build",
"additionalProperties": false
},
"NumberValidator": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
]
},
"defaultValue": "INFO",
"field": "loglevel"
"field": "loglevel",
"required": true
}
],
"title": "Logging"
Expand Down Expand Up @@ -116,19 +117,12 @@
"required": true
},
{
"type": "text",
"label": "Interval",
"validators": [
{
"type": "regex",
"errorMsg": "Interval must be an integer.",
"pattern": "^\\-[1-9]\\d*$|^\\d*$"
}
],
"defaultValue": "300",
"type": "interval",
"field": "interval",
"label": "Interval",
"help": "Time interval of the data input, in seconds.",
"required": true
"required": true,
"defaultValue": "300"
},
{
"type": "singleSelect",
Expand Down Expand Up @@ -206,9 +200,9 @@
"meta": {
"name": "test_addon",
"restRoot": "test_addon",
"version": "5.41.0Reda406cf",
"version": "5.44.0R7f88cfdd",
"displayName": "This is my add-on",
"schemaVersion": "0.0.6",
"_uccVersion": "5.42.1"
"schemaVersion": "0.0.7",
"_uccVersion": "5.44.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@
"restRoot": "splunk_ta_uccexample",
"version": "1.1.1",
"displayName": "Splunk UCC test Add-on",
"schemaVersion": "0.0.6",
"_uccVersion": "5.42.1"
"schemaVersion": "0.0.7",
"_uccVersion": "5.44.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1550,7 +1550,7 @@
"meta": {
"name": "Splunk_TA_UCCExample",
"restRoot": "splunk_ta_uccexample",
"version": "5.44.0Re9cd7340",
"version": "5.44.0R7f88cfdd",
"displayName": "Splunk UCC test Add-on",
"schemaVersion": "0.0.7",
"_uccVersion": "5.44.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,16 +602,9 @@
}
},
{
"type": "text",
"label": "Interval",
"validators": [
{
"type": "regex",
"errorMsg": "Interval must be an integer.",
"pattern": "^\\-[1-9]\\d*$|^\\d*$"
}
],
"type": "interval",
"field": "interval",
"label": "Interval",
"help": "Time interval of the data input, in seconds.",
"required": true
},
Expand Down Expand Up @@ -791,16 +784,9 @@
"required": true
},
{
"type": "text",
"label": "Interval",
"validators": [
{
"type": "regex",
"errorMsg": "Interval must be an integer.",
"pattern": "^\\-[1-9]\\d*$|^\\d*$"
}
],
"type": "interval",
"field": "interval",
"label": "Interval",
"help": "Time interval of the data input, in seconds .",
"required": true
},
Expand Down Expand Up @@ -1186,9 +1172,9 @@
"meta": {
"name": "Splunk_TA_UCCExample",
"restRoot": "splunk_ta_uccexample",
"version": "5.42.1R67372a0b",
"version": "5.44.0R7f88cfdd",
"displayName": "Splunk UCC test Add-on",
"schemaVersion": "0.0.6",
"_uccVersion": "5.42.1"
"schemaVersion": "0.0.7",
"_uccVersion": "5.44.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@
"meta": {
"name": "Splunk_TA_UCCExample",
"restRoot": "splunk_ta_uccexample",
"version": "5.44.0Re9cd7340",
"version": "5.44.0R7f88cfdd",
"displayName": "Splunk UCC test Add-on",
"schemaVersion": "0.0.7",
"_uccVersion": "5.44.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
"meta": {
"name": "Splunk_TA_UCCExample",
"restRoot": "splunk_ta_uccexample",
"version": "5.41.0Reda406cf",
"version": "5.44.0R7f88cfdd",
"displayName": "Splunk UCC test Add-on",
"schemaVersion": "0.0.6",
"_uccVersion": "5.42.1"
"schemaVersion": "0.0.7",
"_uccVersion": "5.44.0"
}
}
Loading

0 comments on commit 21610e2

Please sign in to comment.