diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 91ea5da5c4..826fa93371 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -3,6 +3,14 @@ # MD001/heading-increment MD001: false +ul-style: + style: sublist + +MD007: + # set indent as 4 spaces + # reason: https://python-markdown.github.io/#differences + indent: 4 + # MD010/no-hard-tabs MD010: # Include code blocks diff --git a/docs/advanced/groups_feature.md b/docs/advanced/groups_feature.md index 8e5c510448..17234c8b71 100644 --- a/docs/advanced/groups_feature.md +++ b/docs/advanced/groups_feature.md @@ -7,8 +7,8 @@ The groups will be displayed at the bottom of the form. - `label` displays the title of a specific group. - `fields` specifies the list of fields in a group. All fields must be present in the **entity**. - `options`: - - `isExpandable` can be used to hide/show fields of the group. The default value is **false**. - - `expand` can be used to show all fields of the group while opening the form. The default value is **false**. + + `isExpandable` can be used to hide/show fields of the group. The default value is **false**. + + `expand` can be used to show all fields of the group while opening the form. The default value is **false**. ### Usage diff --git a/docs/advanced/oauth_support.md b/docs/advanced/oauth_support.md index 30590b4a49..ae43dd1a75 100644 --- a/docs/advanced/oauth_support.md +++ b/docs/advanced/oauth_support.md @@ -6,40 +6,40 @@ Auth can be used inside the entity tag. Use `type: "oauth"` in the entity list a - `type` field value must be oauth. - `options`: - - `auth_type` must be present. It can have either ["basic", "oauth"] (If we want basic and oauth both support) or ["oauth"] (If we want oauth support only). - - `basic` must be present only if the auth_type is ["basic"]. - - This will have a list of fields for you to add in the basic authentication flow. In the given example, it is username, password, and security_token. - - **Note: As of now, if you are selecting basic as auth_type, then the username and password fields are mandatory.** - - `oauth` will have a list of fields for you to add in the oauth authentication flow. In the given example, it is `client_id`, `client_secret`, `redirect_url`, `scope`, and `endpoint`. - - These fields are mandatory: - - `client_id` is the client id for applying auth to your app or apps. - - `client_secret` is the client secret for applying auth to your app or apps. - - `redirect_url` will show the redirect url, which needs to be put in the app's redirect url. - - `endpoint` will be the endpoint for you to build oauth support. For example, for salesforce, it will either be "login.salesforce.com", "test.salesforce.com", or any other custom endpoint. - - There is also the ability to specify separate endpoints for authorize and token. To do this, instead of the single 'endpoint' field, use two separate ones: - - `endpoint_authorize` specifies the endpoint used for authorization, for example, login.salesforce.com. - - `endpoint_token` specifies the endpoint used for the token acqusition, for example, api.login.salesforce.com. - - `auth_code_endpoint` must be present and its value should be the endpoint value for getting the auth_code using the app. If the url to get the auth_code is https://login.salesforce.com/services/oauth2/authorize, then this will have the value /services/oauth2/authorize. - - `access_token_endpoint` must be present and its value should be the endpoint value for getting the ccess_token using the auth_code received. If the url to get the access token is https://login.salesforce.com/services/oauth2/token, then it will have the value /services/oauth2/token. - - `auth_label` allows the user to have the custom label for the Auth Type dropdown. - - `oauth_popup_width` is the width in pixels of the pop-up window that will open for oauth authentication (Optional, defaults to 600). - - `oauth_popup_height` is the height in pixels of the pop-up window that will open for oauth authentication (Optional, defaults to 600). - - `oauth_timeout` is the timeout in seconds for oauth authentication (Optional, defaults to 180 seconds). - - `oauth_state_enabled` is used to include the state for oauth authentication (default value is false). - - `auth_endpoint_token_access_type` is an optional parameter that is mapped into the value of the token_access_type query param in the authorisation url. + + `auth_type` must be present. It can have either ["basic", "oauth"] (If we want basic and oauth both support) or ["oauth"] (If we want oauth support only). + + `basic` must be present only if the auth_type is ["basic"]. + - This will have a list of fields for you to add in the basic authentication flow. In the given example, it is username, password, and security_token. + - **Note: As of now, if you are selecting basic as auth_type, then the username and password fields are mandatory.** + + `oauth` will have a list of fields for you to add in the oauth authentication flow. In the given example, it is `client_id`, `client_secret`, `redirect_url`, `scope`, and `endpoint`. + + These fields are mandatory: + - `client_id` is the client id for applying auth to your app or apps. + - `client_secret` is the client secret for applying auth to your app or apps. + - `redirect_url` will show the redirect url, which needs to be put in the app's redirect url. + - `endpoint` will be the endpoint for you to build oauth support. For example, for salesforce, it will either be "login.salesforce.com", "test.salesforce.com", or any other custom endpoint. + + There is also the ability to specify separate endpoints for authorize and token. To do this, instead of the single 'endpoint' field, use two separate ones: + - `endpoint_authorize` specifies the endpoint used for authorization, for example, login.salesforce.com. + - `endpoint_token` specifies the endpoint used for the token acqusition, for example, api.login.salesforce.com. + + `auth_code_endpoint` must be present and its value should be the endpoint value for getting the auth_code using the app. If the url to get the auth_code is https://login.salesforce.com/services/oauth2/authorize, then this will have the value /services/oauth2/authorize. + + `access_token_endpoint` must be present and its value should be the endpoint value for getting the ccess_token using the auth_code received. If the url to get the access token is https://login.salesforce.com/services/oauth2/token, then it will have the value /services/oauth2/token. + + `auth_label` allows the user to have the custom label for the Auth Type dropdown. + + `oauth_popup_width` is the width in pixels of the pop-up window that will open for oauth authentication (Optional, defaults to 600). + + `oauth_popup_height` is the height in pixels of the pop-up window that will open for oauth authentication (Optional, defaults to 600). + + `oauth_timeout` is the timeout in seconds for oauth authentication (Optional, defaults to 180 seconds). + + `oauth_state_enabled` is used to include the state for oauth authentication (default value is false). + + `auth_endpoint_token_access_type` is an optional parameter that is mapped into the value of the token_access_type query param in the authorisation url. - - The fields allowed in the basic and oauth fields are the following: - - `oauth_field` should be kept as it is and without any change. - - `label` can be changed if the user wants to change the label of the field in UI. - - `field` must keep it as it is for mandatory fields as mentioned before. - - `help` can be changed the if user wants to change the help text displayed below the field. - - `encrypted` should be true if the user wants that particular field encrypted, otherwise, there is no need to have this parameter. - - `required` specifies whether the field is required or not. The default value is true. - - `defaultValue` is the initial input value (string, number, or boolean). - - `options`: - - `placeholder`: (RENOUNCED) The placeholder for the field. - - `disableonEdit`: When the form is in edit mode, the field becomes unable to be edited. The default value is false. - - `enable`: The enable property sets whether a field is enabled or not. The default value is true. + + The fields allowed in the basic and oauth fields are the following: + - `oauth_field` should be kept as it is and without any change. + - `label` can be changed if the user wants to change the label of the field in UI. + - `field` must keep it as it is for mandatory fields as mentioned before. + - `help` can be changed the if user wants to change the help text displayed below the field. + - `encrypted` should be true if the user wants that particular field encrypted, otherwise, there is no need to have this parameter. + - `required` specifies whether the field is required or not. The default value is true. + - `defaultValue` is the initial input value (string, number, or boolean). + - `options`: + + `placeholder`: (RENOUNCED) The placeholder for the field. + + `disableonEdit`: When the form is in edit mode, the field becomes unable to be edited. The default value is false. + + `enable`: The enable property sets whether a field is enabled or not. The default value is true. > [!WARNING] > The [Placeholder](https://splunkui.splunkeng.com/Packages/react-ui/Text?section=develop) attribute is deprecated and renounced. Instead, we recommend to use the "help" attribute. diff --git a/docs/alert_actions/alert_scripts.md b/docs/alert_actions/alert_scripts.md index 72780bd70e..612f9cebb0 100644 --- a/docs/alert_actions/alert_scripts.md +++ b/docs/alert_actions/alert_scripts.md @@ -9,16 +9,16 @@ The following files would be created/ updated in the output folder once you exec In the python file that is created, below are the methods that you can use or override for varying use cases: - `process_event()` - - This is the start point of where you require to write the logic of sending data from Splunk to any other + + This is the start point of where you require to write the logic of sending data from Splunk to any other service via its APIs. Additionally, you can validate the parameters that are provided in the alert action as client side validation (via JavaScript) isn't allowed in Splunk's alert action's HTML page for security reasons.
Note: This method must be overwritten. - `get_events()` -> List[dict] - - Used to get the events that triggered the alert. It returns a list of dictionary. A dictionary points to an event that triggered the alert, and each dictionary has the fields extracted by Splunk. + + Used to get the events that triggered the alert. It returns a list of dictionary. A dictionary points to an event that triggered the alert, and each dictionary has the fields extracted by Splunk. - `addevent(raw: str, sourcetype: str)` - - If you are bringing additional information from an outer service, you can write that information using this method. You write a single record using the method. This method will append all the records and will dump it to Splunk when `writeevents()` method is called. + + If you are bringing additional information from an outer service, you can write that information using this method. You write a single record using the method. This method will append all the records and will dump it to Splunk when `writeevents()` method is called. - `writeevents(index: str, host: str, source: str)` - - All the events added to the queue using `addevent()` method are written to Splunk with the details passed in the arguments. + + All the events added to the queue using `addevent()` method are written to Splunk with the details passed in the arguments. An example of a script with validations: diff --git a/docs/contributing.md b/docs/contributing.md index 3feac4a39a..4a9f6a0beb 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -129,7 +129,7 @@ gh pr merge main --auto --merge ``` - If a release encounters issues requiring a quick bug fix (handled by the UCC team): - - Create a PR to the main branch with the fix, including tests that reproduce and then fix the issue. - - Ensure CI passes and await team review. - - Merge the PR using the merge commit option on GitHub. - - Backport the bug fix PR to the develop branch. + + Create a PR to the main branch with the fix, including tests that reproduce and then fix the issue. + + Ensure CI passes and await team review. + + Merge the PR using the merge commit option on GitHub. + + Backport the bug fix PR to the develop branch. diff --git a/docs/dashboard.md b/docs/dashboard.md index 5676baa077..efacf4d1ac 100644 --- a/docs/dashboard.md +++ b/docs/dashboard.md @@ -113,6 +113,27 @@ except Exception as e: log.log_exception(logger, e, "Other") ``` +By default, the error section displays events logged with the ERROR level, but since version **5.50** UCC allows the user to define what level of logs should be displayed in this section. There are two levels to choose from: + +* ERROR +* CRITICAL + +```json + "dashboard": { + "panels": [ + { + "name": "default" + } + ], + "settings": { + "error_panel_log_lvl": [ + "ERROR", + "CRITICAL" + ] + } + } +``` + ## Configuration To be able to add a monitoring dashboard page to an existing add-on, you need to adjust your diff --git a/docs/openapi.md b/docs/openapi.md index e0851f3b44..3c487f6769 100644 --- a/docs/openapi.md +++ b/docs/openapi.md @@ -28,9 +28,9 @@ The OpenAPI Description document can be used to create: * interactive documentation that generates simple curl requests to all documented endpoints (check [this section](#how-to-get-curl-commands-and-use-them) for the relevant instructions). * automation that uses the simple requests to create more complex solutions such as: - * orchestration - * mass load or migration - * automated tests. + - orchestration + - mass load or migration + - automated tests. Check [swagger](https://swagger.io/) or [other tools](https://github.com/OAI/OpenAPI-Specification/blob/main/IMPLEMENTATIONS.md) for more possibilities. @@ -44,7 +44,7 @@ Check [swagger](https://swagger.io/) or [other tools](https://github.com/OAI/Ope ### Instructions 1. Open https://editor.swagger.io/ - * Alternatively, you can run your own instance of Swagger Editor + - Alternatively, you can run your own instance of Swagger Editor by running the following command in terminal: `docker run -p 8081:8080 swaggerapi/swagger-editor` @@ -80,12 +80,14 @@ Make sure you clicked the Authorize button, gave the username and password, and 1. Go to the directory where you downloaded `openapi.json` file 2. Run the following command: `docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate -i /local/openapi.json -g python -o /local/restapi_client` - * make sure `openapi.json` is in the current directory - * you can generate clients for other languages as well - run + + - make sure `openapi.json` is in the current directory + - you can generate clients for other languages as well - run `docker run --rm openapitools/openapi-generator-cli generate list` to see the list of supported languages + 3. The client should appear in `restapi_client`. Open that directory (`cd restapi_client`) 4. Install the client (`pip install .`) 5. See `README.md` for an example of usage diff --git a/docs/quickstart.md b/docs/quickstart.md index b8cc8d002b..2589914bf8 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -214,15 +214,12 @@ It accepts the following parameters: the `output//appserver/static/js/build` directory. * collects and installs the add-on's requirements into the `output//lib` directory of add-on's package. -* NOTE: For the add-on's requirements, the packages are installed according to - following information: - * `lib/requirements.txt` installs Python3 compatible packages into - the `output//lib`. - * It removes `setuptools*`, `bin*`, `pip*`, `distribute*`, and `wheel*` if - they exist from `output//lib` - * It removes the execute bit from every file under `output//lib`. * replaces tokens in views. * copies the add-on's `package/*` to the `output//*` directory. * If an add-on requires some additional configurations in packaging, then `ucc-gen` runs the code in the `additional_packaging.py` file as well. +* **NOTE:** For the add-on's requirements, the packages are installed according to following information: + - `lib/requirements.txt` installs Python3 compatible packages into the `output//lib`. + - It removes `setuptools*`, `bin*`, `pip*`, `distribute*`, and `wheel*` if they exist from `output//lib` + - It removes the execute bit from every file under `output//lib`. * **NOTE:** The build won't be generated only when the add-on name in `meta[name]` of `globalConfig` and `info[id][name]` in `app.manifest` are not same. diff --git a/docs/table.md b/docs/table.md index 3da59bd14e..0fd65011ce 100644 --- a/docs/table.md +++ b/docs/table.md @@ -5,15 +5,15 @@ Tables include many built-in features such as sorting, filtering, and pagination ### Properties - `header`* (Array Objects) specifies the list of columns in the table. - - `field`* is he name of the field where the column data will be displayed. - - `label`* is the title of the column. - - [mapping](advanced/custom_mapping.md) is used to map field values to more meaningful values. - - [customCell](custom_ui_extensions/custom_cell.md) is used to modify the default cell values. + + `field`* is he name of the field where the column data will be displayed. + + `label`* is the title of the column. + + [mapping](advanced/custom_mapping.md) is used to map field values to more meaningful values. + + [customCell](custom_ui_extensions/custom_cell.md) is used to modify the default cell values. - `actions`* (Array) specifies what type of action can be performed on the stanza. The supported types are `edit`, `clone`, and `delete`. - `moreInfo` (Array Objects) specifies the list of fields that will be displayed in row form when the user clicks the Row Expand button. - - `field` is used to dispaly the data in a column. - - `label` is the title of the column. - - [mapping](advanced/custom_mapping.md) is used to map field values to more meaningful values. + + `field` is used to dispaly the data in a column. + + `label` is the title of the column. + + [mapping](advanced/custom_mapping.md) is used to map field values to more meaningful values. - [customRow](custom_ui_extensions/custom_row.md) can be used to customise the moreInfo Component. ### List of built-in table fields for Modular Input diff --git a/splunk_add_on_ucc_framework/dashboard.py b/splunk_add_on_ucc_framework/dashboard.py index 52b5bf1d51..30f7460ceb 100644 --- a/splunk_add_on_ucc_framework/dashboard.py +++ b/splunk_add_on_ucc_framework/dashboard.py @@ -62,7 +62,7 @@ "| join _time [search index=_internal source=*{addon_name}* action=events_ingested " '| timechart sum(n_events) as \\"Number of events\\" ]' ) -errors_count = "index=_internal source=*{addon_name}* log_level=ERROR | timechart count as Errors by exc_l" +errors_count = "index=_internal source=*{addon_name}* log_level IN ({log_lvl}) | timechart count as Errors by exc_l" events_count = ( "index=_internal source=*{addon_name}* action=events_ingested | " 'timechart sum(n_events) as \\"Number of events\\"' @@ -131,7 +131,7 @@ '| rename event_input as \\"Input\\", events as \\"Number of events\\", sparkevent as \\"Event trendline\\"' ) -errors_list_query = "index=_internal source=*{addon_name}* log_level=ERROR" +errors_list_query = "index=_internal source=*{addon_name}* log_level IN ({log_lvl})" resource_cpu_query = ( "index = _introspection component=PerProcess data.args=*{addon_name}* " @@ -149,6 +149,7 @@ def generate_dashboard_content( input_names: List[str], definition_json_name: str, lic_usg_search_params: Optional[Tuple[str, str]], + error_panel_log_lvl: str, ) -> str: determine_by = lic_usg_search_params[0] if lic_usg_search_params else "s" lic_usg_condition = ( @@ -169,7 +170,9 @@ def generate_dashboard_content( addon_name=addon_name.lower(), determine_by=determine_by, ), - errors_count=errors_count.format(addon_name=addon_name.lower()), + errors_count=errors_count.format( + addon_name=addon_name.lower(), log_lvl=error_panel_log_lvl + ), events_count=events_count.format(addon_name=addon_name.lower()), ) ) @@ -182,7 +185,9 @@ def generate_dashboard_content( data_ingestion=data_ingestion.format( lic_usg_condition=lic_usg_condition, determine_by=determine_by ), - errors_count=errors_count.format(addon_name=addon_name.lower()), + errors_count=errors_count.format( + addon_name=addon_name.lower(), log_lvl=error_panel_log_lvl + ), events_count=events_count.format(addon_name=addon_name.lower()), table_sourcetype=table_sourcetype_query.format( lic_usg_condition=lic_usg_condition, @@ -216,8 +221,12 @@ def generate_dashboard_content( utils.get_j2_env() .get_template(definition_json_name) .render( - errors_count=errors_count.format(addon_name=addon_name.lower()), - errors_list=errors_list_query.format(addon_name=addon_name.lower()), + errors_count=errors_count.format( + addon_name=addon_name.lower(), log_lvl=error_panel_log_lvl + ), + errors_list=errors_list_query.format( + addon_name=addon_name.lower(), log_lvl=error_panel_log_lvl + ), ) ) @@ -251,10 +260,16 @@ def generate_dashboard( lic_usg_search_params = _get_license_usage_search_params(global_config.dashboard) + error_panel_log_lvl = _get_error_panel_log_lvl(global_config.dashboard) + if PANEL_DEFAULT in panel_names: for definition_json_name in default_definition_json_filename.values(): content = generate_dashboard_content( - addon_name, input_names, definition_json_name, lic_usg_search_params + addon_name, + input_names, + definition_json_name, + lic_usg_search_params, + error_panel_log_lvl, ) with open( os.path.join(definition_json_path, definition_json_name), "w" @@ -303,6 +318,17 @@ def _get_license_usage_search_params( return determine_by, lic_usg_condition +def _get_error_panel_log_lvl(dashboard: Dict[Any, Any]) -> str: + try: + error_lvl = dashboard["settings"]["error_panel_log_lvl"] + except KeyError: + logger.info( + "No custom error log level found. Proceeding with default parameters." + ) + return "ERROR" + return ", ".join(error_lvl) + + def get_custom_json_content(custom_dashboard_path: str) -> Dict[Any, Any]: custom_dashboard = load_custom_json(custom_dashboard_path) diff --git a/splunk_add_on_ucc_framework/schema/schema.json b/splunk_add_on_ucc_framework/schema/schema.json index 40ff9f96c5..63ee606b82 100644 --- a/splunk_add_on_ucc_framework/schema/schema.json +++ b/splunk_add_on_ucc_framework/schema/schema.json @@ -81,7 +81,11 @@ } } }, - "required": ["field", "label", "type"], + "required": [ + "field", + "label", + "type" + ], "additionalProperties": false }, "Alerts": { @@ -166,7 +170,12 @@ "description": "The sourcetype in which the result of the AR alert action would be written to. The value is updated in the alert action script. If you don’t specify any value you can update your alert action script manually once it is generated." } }, - "required": ["task", "subject", "category", "technology"] + "required": [ + "task", + "subject", + "category", + "technology" + ] }, "entity": { "type": "array", @@ -199,7 +208,11 @@ "description": "A Python script that would have validation and logic for alert action execution. The script should be present at /bin/. Refer documentation for more information." } }, - "required": ["name", "label", "description"], + "required": [ + "name", + "label", + "description" + ], "additionalProperties": false }, "ConfigurationPage": { @@ -234,7 +247,10 @@ "minItems": 1 } }, - "required": ["title", "tabs"], + "required": [ + "title", + "tabs" + ], "description": "Page for account configuration, proxy configuration, and logging level configuration.", "additionalProperties": false }, @@ -261,7 +277,10 @@ "description": "Used to map field values to more meaningful values." } }, - "required": ["field", "label"] + "required": [ + "field", + "label" + ] }, "description": "Specifies the list of fields that will be displayed in row form when the user clicks the Row Expand button." }, @@ -290,7 +309,10 @@ "description": "Used to modify the default cell values." } }, - "required": ["field", "label"] + "required": [ + "field", + "label" + ] } }, "customRow": { @@ -302,11 +324,18 @@ "description": "Specifies what type of action can be performed on the stanza. The supported types are edit, clone, and delete.", "items": { "type": "string", - "enum": ["edit", "delete", "clone"] + "enum": [ + "edit", + "delete", + "clone" + ] } } }, - "required": ["header", "actions"], + "required": [ + "header", + "actions" + ], "description": "Configuration of single tab", "additionalProperties": false }, @@ -361,12 +390,29 @@ "search_condition" ], "additionalProperties": false + }, + "error_panel_log_lvl": { + "type": "array", + "minItems": 1, + "items": { + "anyOf": [ + { + "type": "string", + "enum": [ + "ERROR", "CRITICAL" + ] + } + ] + }, + "uniqueItems": true } }, "additionalProperties": false } }, - "required": ["panels"], + "required": [ + "panels" + ], "description": "The dashboard page provides some additional information about the add-on operations to increase the visibility into what the add-on is actually doing under the hood.", "additionalProperties": false }, @@ -383,7 +429,9 @@ "const": "date" } }, - "required": ["type"], + "required": [ + "type" + ], "additionalProperties": false }, "EmailValidator": { @@ -398,7 +446,9 @@ "description": "Exactly: email" } }, - "required": ["type"], + "required": [ + "type" + ], "additionalProperties": false }, "SaveValidatorHook": { @@ -448,7 +498,10 @@ } } }, - "required": ["label", "fields"], + "required": [ + "label", + "fields" + ], "additionalProperties": false } }, @@ -481,7 +534,10 @@ "description": "It is a link where the user will be redirected." } }, - "required": ["text", "link"], + "required": [ + "text", + "link" + ], "additionalProperties": false }, "help": { @@ -491,7 +547,11 @@ "$ref": "#/definitions/tooltip" } }, - "required": ["field", "type", "options"], + "required": [ + "field", + "type", + "options" + ], "additionalProperties": false }, "TextEntity": { @@ -584,7 +644,11 @@ "$ref": "#/definitions/modifyFieldsOnValue" } }, - "required": ["field", "label", "type"], + "required": [ + "field", + "label", + "type" + ], "additionalProperties": false }, "TextareaEntity": { @@ -675,7 +739,11 @@ "$ref": "#/definitions/modifyFieldsOnValue" } }, - "required": ["field", "label", "type"], + "required": [ + "field", + "label", + "type" + ], "additionalProperties": false }, "SingleSelectEntity": { @@ -815,7 +883,12 @@ "$ref": "#/definitions/modifyFieldsOnValue" } }, - "required": ["field", "label", "type", "options"], + "required": [ + "field", + "label", + "type", + "options" + ], "additionalProperties": false }, "MultipleSelectEntity": { @@ -953,7 +1026,12 @@ "$ref": "#/definitions/modifyFieldsOnValue" } }, - "required": ["field", "label", "type", "options"], + "required": [ + "field", + "label", + "type", + "options" + ], "additionalProperties": false }, "CheckboxEntity": { @@ -1015,7 +1093,11 @@ "$ref": "#/definitions/modifyFieldsOnValue" } }, - "required": ["field", "label", "type"], + "required": [ + "field", + "label", + "type" + ], "additionalProperties": false }, "CheckboxGroupEntity": { @@ -1070,7 +1152,10 @@ "uniqueItems": true } }, - "required": ["label", "fields"], + "required": [ + "label", + "fields" + ], "additionalProperties": false } }, @@ -1122,7 +1207,9 @@ "additionalProperties": false } }, - "required": ["field"], + "required": [ + "field" + ], "additionalProperties": false }, "minItems": 1 @@ -1131,7 +1218,9 @@ "$ref": "#/definitions/disableonEdit" } }, - "required": ["rows"], + "required": [ + "rows" + ], "additionalProperties": false }, "validators": { @@ -1148,7 +1237,12 @@ "type": "boolean" } }, - "required": ["field", "label", "type", "options"], + "required": [ + "field", + "label", + "type", + "options" + ], "additionalProperties": false }, "RadioEntity": { @@ -1204,14 +1298,21 @@ } } }, - "required": ["items"], + "required": [ + "items" + ], "additionalProperties": false }, "modifyFieldsOnValue": { "$ref": "#/definitions/modifyFieldsOnValue" } }, - "required": ["field", "label", "type", "options"], + "required": [ + "field", + "label", + "type", + "options" + ], "additionalProperties": false }, "FileEntity": { @@ -1301,7 +1402,11 @@ "$ref": "#/definitions/modifyFieldsOnValue" } }, - "required": ["field", "label", "type"], + "required": [ + "field", + "label", + "type" + ], "additionalProperties": false }, "OAuthEntity": { @@ -1436,7 +1541,9 @@ } }, "then": { - "required": ["basic"] + "required": [ + "basic" + ] } }, { @@ -1453,15 +1560,24 @@ } }, "then": { - "required": ["oauth"] + "required": [ + "oauth" + ] } } ], "additionalProperties": false, - "required": ["auth_type"] + "required": [ + "auth_type" + ] } }, - "required": ["field", "label", "type", "options"], + "required": [ + "field", + "label", + "type", + "options" + ], "additionalProperties": false }, "CustomEntity": { @@ -1519,7 +1635,12 @@ "additionalProperties": false } }, - "required": ["field", "label", "type", "options"], + "required": [ + "field", + "label", + "type", + "options" + ], "additionalProperties": false }, "AnyOfEntity": { @@ -1587,7 +1708,10 @@ } } }, - "required": ["label", "children"] + "required": [ + "label", + "children" + ] } }, { @@ -1634,7 +1758,10 @@ "description": "Used to map field values to more meaningful values." } }, - "required": ["field", "label"] + "required": [ + "field", + "label" + ] } }, "header": { @@ -1662,7 +1789,10 @@ "description": "Used to modify the default cell values." } }, - "required": ["field", "label"] + "required": [ + "field", + "label" + ] } }, "customRow": { @@ -1674,11 +1804,20 @@ "description": "Specifies what type of action can be performed on the stanza. The supported types are edit, clone, and delete.", "items": { "type": "string", - "enum": ["edit", "delete", "clone", "enable", "search"] + "enum": [ + "edit", + "delete", + "clone", + "enable", + "search" + ] } } }, - "required": ["header", "actions"], + "required": [ + "header", + "actions" + ], "description": "Displays input stanzas in a tabular format.", "additionalProperties": false }, @@ -1694,7 +1833,9 @@ "description": "Exactly: ipv4" } }, - "required": ["type"], + "required": [ + "type" + ], "additionalProperties": false }, "Meta": { @@ -1825,11 +1966,19 @@ "type": "array", "items": { "type": "string", - "enum": ["light", "dark"] + "enum": [ + "light", + "dark" + ] } } }, - "required": ["displayName", "name", "restRoot", "version"], + "required": [ + "displayName", + "name", + "restRoot", + "version" + ], "description": "Metadata regarding build", "additionalProperties": false }, @@ -1852,7 +2001,10 @@ "description": "Specifies if the number should be an integer (true) or can be a float (false). Default value is false" } }, - "required": ["type", "range"], + "required": [ + "type", + "range" + ], "additionalProperties": false }, "RangeValue": { @@ -1924,7 +2076,9 @@ } }, "then": { - "required": ["basic"] + "required": [ + "basic" + ] } }, "OauthRequirement": { @@ -1940,7 +2094,9 @@ } }, "then": { - "required": ["oauth"] + "required": [ + "oauth" + ] } }, "Pages": { @@ -1957,7 +2113,9 @@ "$ref": "#/definitions/DashboardPage" } }, - "required": ["configuration"], + "required": [ + "configuration" + ], "additionalProperties": false }, "RegexValidator": { @@ -1976,7 +2134,10 @@ "description": "Regex pattern." } }, - "required": ["type", "pattern"], + "required": [ + "type", + "pattern" + ], "additionalProperties": false }, "StringValidator": { @@ -2001,7 +2162,11 @@ "description": "Specifies the maximum number of characters allowed." } }, - "required": ["type", "minLength", "maxLength"], + "required": [ + "type", + "minLength", + "maxLength" + ], "additionalProperties": false }, "TabContent": { @@ -2031,7 +2196,10 @@ "style": { "description": "By specifying this property in the global configuration file, the forms can either be opened as a new page or in a dialog.", "type": "string", - "enum": ["page", "dialog"] + "enum": [ + "page", + "dialog" + ] }, "conf": { "type": "string", @@ -2067,10 +2235,18 @@ }, "anyOf": [ { - "required": ["entity", "name", "title"] + "required": [ + "entity", + "name", + "title" + ] }, { - "required": ["customTab", "name", "title"] + "required": [ + "customTab", + "name", + "title" + ] } ], "additionalProperties": false @@ -2096,7 +2272,11 @@ "maxLength": 100 } }, - "required": ["version", "product", "vendor"], + "required": [ + "version", + "product", + "vendor" + ], "additionalProperties": false }, "UrlValidator": { @@ -2111,7 +2291,9 @@ "description": "Exactly: url" } }, - "required": ["type"], + "required": [ + "type" + ], "additionalProperties": false }, "ValueLabelPair": { @@ -2138,7 +2320,9 @@ "description": "Text displayed next to entity field" } }, - "required": ["label"], + "required": [ + "label" + ], "additionalProperties": false }, "DashboardPanel": { @@ -2150,7 +2334,9 @@ "maxLength": 100 } }, - "required": ["name"], + "required": [ + "name" + ], "additionalProperties": false }, "WarningMessage": { @@ -2186,7 +2372,9 @@ "description": "Defines if message should disappear after any input changes." } }, - "required": ["message"] + "required": [ + "message" + ] }, "Field": { "type": "string", @@ -2224,9 +2412,15 @@ "type": "string" } }, - "required": ["slug", "linkText", "link"] + "required": [ + "slug", + "linkText", + "link" + ] }, - "required": ["text"] + "required": [ + "text" + ] } } }, @@ -2276,7 +2470,9 @@ "$ref": "#/definitions/markdownMessage" } }, - "required": ["fieldId"] + "required": [ + "fieldId" + ] }, "fieldToModify": { "type": "object", @@ -2298,7 +2494,12 @@ "mode": { "type": "string", "description": "Defines under which Mode modifications should occure. If not present modifications occure for all Mods", - "enum": ["create", "edit", "config", "clone"] + "enum": [ + "create", + "edit", + "config", + "clone" + ] }, "fieldsToModify": { "type": "array", @@ -2309,7 +2510,10 @@ "minItems": 1 } }, - "required": ["fieldValue", "fieldsToModify"] + "required": [ + "fieldValue", + "fieldsToModify" + ] }, "modifyFieldsOnValue": { "type": "array", @@ -2335,7 +2539,10 @@ "description": "Specify color of displayied text. Accepts all CSS colors" } }, - "required": ["markdownType", "text"] + "required": [ + "markdownType", + "text" + ] }, "markdownMessageHybrid": { "type": "object", @@ -2362,7 +2569,13 @@ "description": "Declare url that will use for redirection" } }, - "required": ["markdownType", "text", "token", "link", "linkText"] + "required": [ + "markdownType", + "text", + "token", + "link", + "linkText" + ] }, "markdownMessageLink": { "type": "object", @@ -2381,7 +2594,11 @@ "description": "Declare url that will use for redirection" } }, - "required": ["markdownType", "text", "link"] + "required": [ + "markdownType", + "text", + "link" + ] }, "markdownMessagePlainText": { "type": "object", @@ -2391,7 +2608,9 @@ "description": "Declare message content" } }, - "required": ["text"] + "required": [ + "text" + ] }, "markdownMessage": { "description": "Message that will be displayed as additional information", @@ -2441,7 +2660,13 @@ }, "levels": { "type": "array", - "default": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], + "default": [ + "DEBUG", + "INFO", + "WARNING", + "ERROR", + "CRITICAL" + ], "description": "List of all possible log levels.", "items": { "type": "string" @@ -2456,7 +2681,9 @@ "$ref": "#/definitions/help" } }, - "required": ["type"], + "required": [ + "type" + ], "additionalProperties": false }, "InputPageSingleTable": { @@ -2510,7 +2737,10 @@ } } }, - "required": ["groupTitle", "groupName"] + "required": [ + "groupTitle", + "groupName" + ] } }, "services": { @@ -2547,7 +2777,10 @@ "style": { "description": "By specifying this property in the global configuration file, the forms can either be opened as a new page or in a dialog.", "type": "string", - "enum": ["page", "dialog"] + "enum": [ + "page", + "dialog" + ] }, "hook": { "description": "It is used to add custom behaviour to forms.", @@ -2583,9 +2816,15 @@ } }, "not": { - "required": ["table"] + "required": [ + "table" + ] }, - "required": ["name", "title", "entity"] + "required": [ + "name", + "title", + "entity" + ] } }, "hideFieldId": { @@ -2595,7 +2834,11 @@ "type": "string" } }, - "required": ["title", "table", "services"], + "required": [ + "title", + "table", + "services" + ], "description": "Input Page definition where there is only one single tabel listing all services.", "additionalProperties": false }, @@ -2648,7 +2891,10 @@ "style": { "description": "By specifying this property in the global configuration file, the forms can either be opened as a new page or in a dialog.", "type": "string", - "enum": ["page", "dialog"] + "enum": [ + "page", + "dialog" + ] }, "hook": { "description": "It is used to add custom behaviour to forms.", @@ -2675,7 +2921,12 @@ "maxLength": 100 } }, - "required": ["name", "title", "table", "entity"] + "required": [ + "name", + "title", + "table", + "entity" + ] } }, "hideFieldId": { @@ -2685,7 +2936,10 @@ "type": "string" } }, - "required": ["title", "services"], + "required": [ + "title", + "services" + ], "description": "Input Page definition where there are tabs for each service with separate table listing input service entries.", "additionalProperties": false }, @@ -2760,7 +3014,9 @@ } }, "additionalProperties": false, - "required": ["range"] + "required": [ + "range" + ] }, "help": { "$ref": "#/definitions/help" @@ -2772,7 +3028,11 @@ "$ref": "#/definitions/required" } }, - "required": ["type", "field", "label"], + "required": [ + "type", + "field", + "label" + ], "additionalProperties": false }, "IntervalValue": { @@ -2813,7 +3073,11 @@ "$ref": "#/definitions/required" } }, - "required": ["type", "field", "label"], + "required": [ + "type", + "field", + "label" + ], "additionalProperties": false } }, @@ -2834,6 +3098,9 @@ "minItems": 1 } }, - "required": ["meta", "pages"], + "required": [ + "meta", + "pages" + ], "additionalProperties": false } diff --git a/tests/unit/expected_results/errors_tab_definition.json b/tests/unit/expected_results/errors_tab_definition.json index 542c3e1201..d0863e8244 100644 --- a/tests/unit/expected_results/errors_tab_definition.json +++ b/tests/unit/expected_results/errors_tab_definition.json @@ -80,7 +80,7 @@ "errors_tab_errors_count_ds": { "type": "ds.search", "options": { - "query": "index=_internal source=*splunk_ta_uccexample* log_level=ERROR | timechart count as Errors by exc_l", + "query": "index=_internal source=*splunk_ta_uccexample* log_level IN (ERROR, CRITICAL) | timechart count as Errors by exc_l", "queryParameters": { "earliest": "$errors_tab_time.earliest$", "latest": "$errors_tab_time.latest$" @@ -90,7 +90,7 @@ "errors_tab_errors_list_ds": { "type": "ds.search", "options": { - "query": "index=_internal source=*splunk_ta_uccexample* log_level=ERROR exc_l IN ($error_types$)", + "query": "index=_internal source=*splunk_ta_uccexample* log_level IN (ERROR, CRITICAL) exc_l IN ($error_types$)", "queryParameters": { "earliest": "$errors_tab_time.earliest$", "latest": "$errors_tab_time.latest$" diff --git a/tests/unit/expected_results/overview_definition.json b/tests/unit/expected_results/overview_definition.json index 1a84c92c5d..27bb620c45 100644 --- a/tests/unit/expected_results/overview_definition.json +++ b/tests/unit/expected_results/overview_definition.json @@ -112,7 +112,7 @@ "overview_errors_count_ds": { "type": "ds.search", "options": { - "query": "index=_internal source=*splunk_ta_uccexample* log_level=ERROR | timechart count as Errors by exc_l", + "query": "index=_internal source=*splunk_ta_uccexample* log_level IN (ERROR, CRITICAL) | timechart count as Errors by exc_l", "queryParameters": { "earliest": "$overview_time.earliest$", "latest": "$overview_time.latest$" diff --git a/tests/unit/testdata/valid_config.json b/tests/unit/testdata/valid_config.json index 4ae11f1d6e..2e84d89dbf 100644 --- a/tests/unit/testdata/valid_config.json +++ b/tests/unit/testdata/valid_config.json @@ -1186,7 +1186,13 @@ { "name": "default" } - ] + ], + "settings": { + "error_panel_log_lvl": [ + "ERROR", + "CRITICAL" + ] + } } }, "alerts": [ diff --git a/tests/unit/testdata/valid_config_with_custom_dashboard.json b/tests/unit/testdata/valid_config_with_custom_dashboard.json index 9d105be26e..5d69641f03 100644 --- a/tests/unit/testdata/valid_config_with_custom_dashboard.json +++ b/tests/unit/testdata/valid_config_with_custom_dashboard.json @@ -75,7 +75,13 @@ { "name": "custom" } - ] + ], + "settings": { + "error_panel_log_lvl": [ + "ERROR", + "CRITICAL" + ] + } } }, "meta": {