diff --git a/demo_addon_for_splunk/README.md b/demo_addon_for_splunk/README.md new file mode 100644 index 000000000..40172e8df --- /dev/null +++ b/demo_addon_for_splunk/README.md @@ -0,0 +1 @@ +# demo_addon_for_splunk diff --git a/demo_addon_for_splunk/globalConfig.json b/demo_addon_for_splunk/globalConfig.json new file mode 100644 index 000000000..545debb75 --- /dev/null +++ b/demo_addon_for_splunk/globalConfig.json @@ -0,0 +1,188 @@ +{ + "pages": { + "configuration": { + "tabs": [ + { + "name": "account", + "table": { + "actions": [ + "edit", + "delete", + "clone" + ], + "header": [ + { + "label": "Name", + "field": "name" + } + ] + }, + "entity": [ + { + "type": "text", + "label": "Name", + "validators": [ + { + "type": "regex", + "errorMsg": "Account Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + "pattern": "^[a-zA-Z]\\w*$" + }, + { + "type": "string", + "errorMsg": "Length of input name should be between 1 and 100", + "minLength": 1, + "maxLength": 100 + } + ], + "field": "name", + "help": "A unique name for the account.", + "required": true + }, + { + "type": "text", + "label": "API key", + "field": "api_key", + "help": "API key", + "required": true, + "encrypted": true + } + ], + "title": "Accounts" + }, + { + "type": "loggingTab" + } + ], + "title": "Configuration", + "description": "Set up your add-on" + }, + "inputs": { + "services": [ + { + "name": "demo_input", + "entity": [ + { + "type": "text", + "label": "Name", + "validators": [ + { + "type": "regex", + "errorMsg": "Input Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + "pattern": "^[a-zA-Z]\\w*$" + }, + { + "type": "string", + "errorMsg": "Length of input name should be between 1 and 100", + "minLength": 1, + "maxLength": 100 + } + ], + "field": "name", + "help": "A unique name for the data input.", + "required": true + }, + { + "type": "interval", + "label": "Interval", + "defaultValue": "300", + "field": "interval", + "options": { + "range": [ + 10, + 301 + ] + }, + "help": "Time interval of the data input, in seconds.", + "required": true + }, + { + "type": "index", + "field": "index", + "label": "Index" + }, + { + "type": "singleSelect", + "label": "Account to use", + "options": { + "referenceName": "account" + }, + "help": "Account to use for this input.", + "field": "account", + "required": true + } + ], + "inputHelperModule": "demo_input_helper", + "title": "demo_input" + } + ], + "title": "Inputs", + "description": "Manage your data inputs", + "table": { + "actions": [ + "edit", + "delete", + "clone" + ], + "header": [ + { + "label": "Name", + "field": "name" + }, + { + "label": "Interval", + "field": "interval" + }, + { + "label": "Index", + "field": "index" + }, + { + "label": "Status", + "field": "disabled" + } + ], + "moreInfo": [ + { + "label": "Name", + "field": "name" + }, + { + "label": "Interval", + "field": "interval" + }, + { + "label": "Index", + "field": "index" + }, + { + "label": "Status", + "field": "disabled", + "mapping": { + "true": "Inactive", + "false": "Active" + } + } + ] + } + }, + "dashboard": { + "panels": [ + { + "name": "default" + } + ] + } + }, + "meta": { + "name": "demo_addon_for_splunk", + "restRoot": "demo-addon-for-splunk", + "version": "1.0.0", + "displayName": "Demo Add-on for Splunk", + "schemaVersion": "0.0.9", + "supportedThemes": [ + "light", + "dark" + ], + "_uccVersion": "5.52.0" + } +} diff --git a/demo_addon_for_splunk/package/LICENSE.txt b/demo_addon_for_splunk/package/LICENSE.txt new file mode 100644 index 000000000..e69de29bb diff --git a/demo_addon_for_splunk/package/README.txt b/demo_addon_for_splunk/package/README.txt new file mode 100644 index 000000000..e69de29bb diff --git a/demo_addon_for_splunk/package/app.manifest b/demo_addon_for_splunk/package/app.manifest new file mode 100644 index 000000000..13470c6d0 --- /dev/null +++ b/demo_addon_for_splunk/package/app.manifest @@ -0,0 +1,57 @@ +{ + "schemaVersion": "2.0.0", + "info": { + "title": "Demo Add-on for Splunk", + "id": { + "group": null, + "name": "demo_addon_for_splunk", + "version": "1.0.0" + }, + "author": [ + { + "name": "", + "email": null, + "company": null + } + ], + "releaseDate": null, + "description": "Demo Add-on for Splunk", + "classification": { + "intendedAudience": "IT Professionals", + "categories": [ + "Security, Fraud & Compliance" + ], + "developmentStatus": "Production/Stable" + }, + "commonInformationModels": null, + "license": { + "name": null, + "text": "LICENSE.txt", + "uri": null + }, + "privacyPolicy": { + "name": null, + "text": null, + "uri": null + }, + "releaseNotes": { + "name": "README", + "text": "README.txt", + "uri": "" + } + }, + "dependencies": null, + "tasks": null, + "inputGroups": null, + "incompatibleApps": null, + "platformRequirements": null, + "supportedDeployments": [ + "_standalone", + "_distributed", + "_search_head_clustering" + ], + "targetWorkloads": [ + "_search_heads", + "_indexers" + ] +} \ No newline at end of file diff --git a/demo_addon_for_splunk/package/bin/demo_input_helper.py b/demo_addon_for_splunk/package/bin/demo_input_helper.py new file mode 100644 index 000000000..b39d589c3 --- /dev/null +++ b/demo_addon_for_splunk/package/bin/demo_input_helper.py @@ -0,0 +1,88 @@ +import json +import logging + +import import_declare_test +from solnlib import conf_manager, log +from splunklib import modularinput as smi + + +ADDON_NAME = "demo_addon_for_splunk" + +def logger_for_input(input_name: str) -> logging.Logger: + return log.Logs().get_logger(f"{ADDON_NAME.lower()}_{input_name}") + + +def get_account_api_key(session_key: str, account_name: str): + cfm = conf_manager.ConfManager( + session_key, + ADDON_NAME, + realm=f"__REST_CREDENTIAL__#{ADDON_NAME}#configs/conf-demo-addon-for-splunk_account", + ) + account_conf_file = cfm.get_conf("demo-addon-for-splunk_account") + return account_conf_file.get(account_name).get("api_key") + + +def get_data_from_api(logger: logging.Logger, api_key: str): + logger.info("Getting data from an external API") + dummy_data = [ + { + "line1": "hello", + }, + { + "line2": "world", + }, + ] + return dummy_data + + +def validate_input(definition: smi.ValidationDefinition): + return + + +def stream_events(inputs: smi.InputDefinition, event_writer: smi.EventWriter): + # inputs.inputs is a Python dictionary object like: + # { + # "demo_input://": { + # "account": "", + # "disabled": "0", + # "host": "$decideOnStartup", + # "index": "", + # "interval": "", + # "python.version": "python3", + # }, + # } + for input_name, input_item in inputs.inputs.items(): + normalized_input_name = input_name.split("/")[-1] + logger = logger_for_input(normalized_input_name) + try: + session_key = inputs.metadata["session_key"] + log_level = conf_manager.get_log_level( + logger=logger, + session_key=session_key, + app_name=ADDON_NAME, + conf_name="demo-addon-for-splunk_settings", + ) + logger.setLevel(log_level) + log.modular_input_start(logger, normalized_input_name) + api_key = get_account_api_key(session_key, input_item.get("account")) + data = get_data_from_api(logger, api_key) + sourcetype = "dummy-data" + for line in data: + event_writer.write_event( + smi.Event( + data=json.dumps(line, ensure_ascii=False, default=str), + index=input_item.get("index"), + sourcetype=sourcetype, + ) + ) + log.events_ingested( + logger, + input_name, + sourcetype, + len(data), + input_item.get("index"), + account=input_item.get("account"), + ) + log.modular_input_end(logger, normalized_input_name) + except Exception as e: + log.log_exception(logger, e, "my custom error type", msg_before="Exception raised while ingesting data for demo_input: ") diff --git a/demo_addon_for_splunk/package/lib/requirements.txt b/demo_addon_for_splunk/package/lib/requirements.txt new file mode 100644 index 000000000..99f4b184d --- /dev/null +++ b/demo_addon_for_splunk/package/lib/requirements.txt @@ -0,0 +1,3 @@ +splunktaucclib +splunk-sdk +solnlib diff --git a/ui/demo_addon_for_splunk/README.md b/ui/demo_addon_for_splunk/README.md new file mode 100644 index 000000000..40172e8df --- /dev/null +++ b/ui/demo_addon_for_splunk/README.md @@ -0,0 +1 @@ +# demo_addon_for_splunk diff --git a/ui/demo_addon_for_splunk/globalConfig.json b/ui/demo_addon_for_splunk/globalConfig.json new file mode 100644 index 000000000..126fc4f03 --- /dev/null +++ b/ui/demo_addon_for_splunk/globalConfig.json @@ -0,0 +1,189 @@ +{ + "pages": { + "configuration": { + "tabs": [ + { + "name": "account", + "table": { + "actions": [ + "edit", + "delete", + "clone" + ], + "header": [ + { + "label": "Name", + "field": "name" + } + ] + }, + "entity": [ + { + "type": "text", + "label": "Name", + "validators": [ + { + "type": "regex", + "errorMsg": "Account Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + "pattern": "^[a-zA-Z]\\w*$" + }, + { + "type": "string", + "errorMsg": "Length of input name should be between 1 and 100", + "minLength": 1, + "maxLength": 100 + } + ], + "field": "name", + "help": "A unique name for the account.", + "required": true + }, + { + "type": "text", + "label": "API key", + "field": "api_key", + "help": "API key", + "required": true, + "encrypted": true + } + ], + "title": "Accounts" + }, + { + "type": "loggingTab" + } + ], + "title": "Configuration", + "description": "Set up your add-on" + }, + "inputs": { + "services": [ + { + "name": "demo_input", + "entity": [ + { + "type": "text", + "label": "Name", + "validators": [ + { + "type": "regex", + "errorMsg": "Input Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + "pattern": "^[a-zA-Z]\\w*$" + }, + { + "type": "string", + "errorMsg": "Length of input name should be between 1 and 100", + "minLength": 1, + "maxLength": 100 + } + ], + "field": "name", + "help": "A unique name for the data input.", + "required": true + }, + { + "type": "interval", + "label": "Interval", + "defaultValue": "300", + "field": "interval", + "options": { + "range": [ + 10, + 301 + ] + }, + "help": "Time interval of the data input, in seconds.", + "required": true + }, + { + "type": "index", + "field": "index", + "label": "Index" + }, + { + "type": "singleSelect", + "label": "Account to use", + "options": { + "referenceName": "account" + }, + "help": "Account to use for this input.", + "field": "account", + "required": true + } + ], + "inputHelperModule": "demo_input_helper", + "title": "demo_input" + } + ], + "title": "Inputs", + "description": "Manage your data inputs", + "table": { + "actions": [ + "edit", + "enable", + "delete", + "clone" + ], + "header": [ + { + "label": "Name", + "field": "name" + }, + { + "label": "Interval", + "field": "interval" + }, + { + "label": "Index", + "field": "index" + }, + { + "label": "Status", + "field": "disabled" + } + ], + "moreInfo": [ + { + "label": "Name", + "field": "name" + }, + { + "label": "Interval", + "field": "interval" + }, + { + "label": "Index", + "field": "index" + }, + { + "label": "Status", + "field": "disabled", + "mapping": { + "true": "Inactive", + "false": "Active" + } + } + ] + } + }, + "dashboard": { + "panels": [ + { + "name": "default" + } + ] + } + }, + "meta": { + "name": "demo_addon_for_splunk", + "restRoot": "demo_addon_for_splunk", + "version": "1.0.0", + "displayName": "Demo Add-on for Splunk", + "schemaVersion": "0.0.8", + "supportedThemes": [ + "light", + "dark" + ], + "_uccVersion": "5.48.2" + } +} diff --git a/ui/demo_addon_for_splunk/package/LICENSE.txt b/ui/demo_addon_for_splunk/package/LICENSE.txt new file mode 100644 index 000000000..e69de29bb diff --git a/ui/demo_addon_for_splunk/package/README.txt b/ui/demo_addon_for_splunk/package/README.txt new file mode 100644 index 000000000..e69de29bb diff --git a/ui/demo_addon_for_splunk/package/app.manifest b/ui/demo_addon_for_splunk/package/app.manifest new file mode 100644 index 000000000..13470c6d0 --- /dev/null +++ b/ui/demo_addon_for_splunk/package/app.manifest @@ -0,0 +1,57 @@ +{ + "schemaVersion": "2.0.0", + "info": { + "title": "Demo Add-on for Splunk", + "id": { + "group": null, + "name": "demo_addon_for_splunk", + "version": "1.0.0" + }, + "author": [ + { + "name": "", + "email": null, + "company": null + } + ], + "releaseDate": null, + "description": "Demo Add-on for Splunk", + "classification": { + "intendedAudience": "IT Professionals", + "categories": [ + "Security, Fraud & Compliance" + ], + "developmentStatus": "Production/Stable" + }, + "commonInformationModels": null, + "license": { + "name": null, + "text": "LICENSE.txt", + "uri": null + }, + "privacyPolicy": { + "name": null, + "text": null, + "uri": null + }, + "releaseNotes": { + "name": "README", + "text": "README.txt", + "uri": "" + } + }, + "dependencies": null, + "tasks": null, + "inputGroups": null, + "incompatibleApps": null, + "platformRequirements": null, + "supportedDeployments": [ + "_standalone", + "_distributed", + "_search_head_clustering" + ], + "targetWorkloads": [ + "_search_heads", + "_indexers" + ] +} \ No newline at end of file diff --git a/ui/demo_addon_for_splunk/package/bin/demo_input_helper.py b/ui/demo_addon_for_splunk/package/bin/demo_input_helper.py new file mode 100644 index 000000000..01e036155 --- /dev/null +++ b/ui/demo_addon_for_splunk/package/bin/demo_input_helper.py @@ -0,0 +1,89 @@ +import json +import logging + +import import_declare_test +from solnlib import conf_manager, log +from splunklib import modularinput as smi + + +ADDON_NAME = "demo_addon_for_splunk" + + +def logger_for_input(input_name: str) -> logging.Logger: + return log.Logs().get_logger(f"{ADDON_NAME.lower()}_{input_name}") + + +def get_account_api_key(session_key: str, account_name: str): + cfm = conf_manager.ConfManager( + session_key, + ADDON_NAME, + realm=f"__REST_CREDENTIAL__#{ADDON_NAME}#configs/conf-demo_addon_for_splunk_account", + ) + account_conf_file = cfm.get_conf("demo_addon_for_splunk_account") + return account_conf_file.get(account_name).get("api_key") + + +def get_data_from_api(logger: logging.Logger, api_key: str): + logger.info("Getting data from an external API") + dummy_data = [ + { + "line1": "hello", + }, + { + "line2": "world", + }, + ] + return dummy_data + + +def validate_input(definition: smi.ValidationDefinition): + return + + +def stream_events(inputs: smi.InputDefinition, event_writer: smi.EventWriter): + # inputs.inputs is a Python dictionary object like: + # { + # "demo_input://": { + # "account": "", + # "disabled": "0", + # "host": "$decideOnStartup", + # "index": "", + # "interval": "", + # "python.version": "python3", + # }, + # } + for input_name, input_item in inputs.inputs.items(): + normalized_input_name = input_name.split("/")[-1] + logger = logger_for_input(normalized_input_name) + try: + session_key = inputs.metadata["session_key"] + log_level = conf_manager.get_log_level( + logger=logger, + session_key=session_key, + app_name=ADDON_NAME, + conf_name=f"{ADDON_NAME}_settings", + ) + logger.setLevel(log_level) + log.modular_input_start(logger, normalized_input_name) + api_key = get_account_api_key(session_key, input_item.get("account")) + data = get_data_from_api(logger, api_key) + sourcetype = "dummy-data" + for line in data: + event_writer.write_event( + smi.Event( + data=json.dumps(line, ensure_ascii=False, default=str), + index=input_item.get("index"), + sourcetype=sourcetype, + ) + ) + log.events_ingested( + logger, + input_name, + sourcetype, + len(data), + input_item.get("index"), + account=input_item.get("account"), + ) + log.modular_input_end(logger, normalized_input_name) + except Exception as e: + log.log_exception(logger, e, "my custom error type", msg_before="Exception raised while ingesting data for demo_input: ") diff --git a/ui/demo_addon_for_splunk/package/lib/requirements.txt b/ui/demo_addon_for_splunk/package/lib/requirements.txt new file mode 100644 index 000000000..99f4b184d --- /dev/null +++ b/ui/demo_addon_for_splunk/package/lib/requirements.txt @@ -0,0 +1,3 @@ +splunktaucclib +splunk-sdk +solnlib