Set up external validation
In your modular input script, it is a good idea to validate the configuration of your input. Specify <use_external_validation>true</use_external_validation>
in your introspection scheme to enable external validation.
If you provide an external validation routine and enable external validation the following occurs when a user creates or edits the configuration for a script:
- Splunk software reads the configuration parameters from the user and creates an XML configuration of the parameters.
The XML configuration looks something like this:
<items> <server_host>myHost</server_host> <server_uri>https://127.0.0.1:8089</server_uri> <session_key>123102983109283019283</session_key> <checkpoint_dir>/opt/splunk/var/lib/splunk/modinputs</checkpoint_dir> <item name="myScheme"> <param name="param1">value1</param> <param_list name="param2"> <value>value2</value> <value>value3</value> <value>value4</value> </param_list> </item> </items>
Notes: The <items> element can only contain one <item>. (This is because you can only operate on one item at a time.) The XML stream itself must be encoded in UTF-8.
Refer to the Read XML configuration from splunkd section for a description of the XML configuration.
- Splunk software invokes your script with the --validate-arguments option, passing in the XML configuration.
- Your script validation routine determines if the configuration is valid.
- If the configuration is valid, your script exits with return status of zero.
- Otherwise the script exits with a non-zero status and a message indicating why configuration failed. Format the message in <error> tags so Splunk software can properly display the message in Splunk Web.
The following snippets shows how the S3 example validates data returned from the Amazon S3 service. The snippet at the end shows how to provide the --validate-arguments option when invoking the script. This script has been made cross-compatible with Python 2 and Python 3 using python-future.<error> <message>Access is denied.</message> </error>
Validation snippets
. . . from builtins import str def get_validation_data(): val_data = {} # read everything from stdin val_str = sys.stdin.read() # parse the validation XML doc = xml.dom.minidom.parseString(val_str) root = doc.documentElement logging.debug("XML: found items") item_node = root.getElementsByTagName("item")[0] if item_node: logging.debug("XML: found item") name = item_node.getAttribute("name") val_data["stanza"] = name params_node = item_node.getElementsByTagName("param") for param in params_node: name = param.getAttribute("name") logging.debug("Found param %s" % name) if name and param.firstChild and \ param.firstChild.nodeType == param.firstChild.TEXT_NODE: val_data[name] = param.firstChild.data return val_data # make sure that the amazon credentials are good def validate_arguments(): val_data = get_validation_data() try: url = "s3://" + val_data["stanza"] bucket, obj = read_from_s3_uri(url) conn = get_http_connection(val_data["key_id"], val_data["secret_key"], bucket, obj, method = "HEAD") resp = conn.getresponse() log_response(resp) if resp.status != 200: raise Exception("Amazon returned HTTP status code %d (%s): %s" % (resp.status, resp.reason, get_amazon_error(resp.read()))) except Exception as e: print_error("Invalid configuration specified: %s" % str(e)) sys.exit(1) . . . # Provide --validate-arguments arg on startup if __name__ == '__main__': if len(sys.argv) > 1: if sys.argv[1] == "--scheme": do_scheme() elif sys.argv[1] == "--validate-arguments": validate_arguments() elif sys.argv[1] == "--test": test() else: usage() else: # just request data from S3 run()