mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
Much better configuration parsing, validation, and substitution of defaults using jsonschema.
This commit is contained in:
+4
@@ -71,13 +71,17 @@ def check_json(json_object, schema, context=None) -> tuple[list[str], dict]:
|
||||
DefaultValidatingDraft7Validator = extend_with_default(
|
||||
jsonschema.Draft7Validator)
|
||||
|
||||
|
||||
validator = DefaultValidatingDraft7Validator(schema, jsonschema.FormatChecker())
|
||||
#validator = jsonschema.Draft7Validator(schema, jsonschema.FormatChecker())
|
||||
errors_formatted = []
|
||||
|
||||
for error in sorted(validator.iter_errors(json_object), key=str):
|
||||
|
||||
#validate(json_object, schema, format_checker=FormatChecker())
|
||||
# except jsonschema.ValidationError as e:
|
||||
report = generate_validation_error_report(error, json_object)
|
||||
|
||||
#note = "\n*** Note - If there is more than one error, only the first error is shown ***\n\n"
|
||||
if context:
|
||||
errors_formatted.append(
|
||||
|
||||
@@ -6,15 +6,56 @@ import sys
|
||||
|
||||
|
||||
def configure_action(args):
|
||||
print("WE ARE CONFIGURING!")
|
||||
settings = OrderedDict()
|
||||
|
||||
settings = validate_args.v(validate_args.setup_schema)
|
||||
if settings is False:
|
||||
if args.input_config_file is None:
|
||||
settings,schema = validate_args.validate({})
|
||||
else:
|
||||
try:
|
||||
cfg = json.loads(args.input_config_file.read())
|
||||
except Exception as e:
|
||||
raise(e)
|
||||
settings,schema = validate_args.validate(cfg)
|
||||
|
||||
|
||||
|
||||
if settings == None:
|
||||
print("Failure while processing settings.\n\tQuitting...", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
new_config = {}
|
||||
for arg in settings:
|
||||
choice = input("%s [%s]:"%(arg,settings[arg]))
|
||||
default = settings[arg]
|
||||
default_string = str(default).replace("'", '"')
|
||||
choice = input("%s [default: %s]: "%(arg,default_string))
|
||||
choice = choice.strip()
|
||||
if len(choice) == 0:
|
||||
print("\tNothing entered, using default:")
|
||||
new_config[arg] = default
|
||||
else:
|
||||
if choice.lower() in ["true", "false"] and schema['properties'][arg]['type'] == "boolean" :
|
||||
new_config[arg] = json.loads(choice.lower())
|
||||
else:
|
||||
if choice in ['true','false'] or (choice.isdigit() and schema['properties'][arg]['type'] != "integer"):
|
||||
choice = '"' + choice + '"'
|
||||
# replace all single quotes with doubles quotes to make valid json
|
||||
if "'" in choice:
|
||||
print('''Found %d single quotes (') in input... we will convert these to double quotes (") to ensure valida json.'''%(choice.count("'")))
|
||||
choice = choice.replace("'",'"')
|
||||
new_config[arg] = json.loads(choice)
|
||||
print("\t{0}\n".format(new_config[arg]))
|
||||
|
||||
|
||||
#Now parse the new config and make sure it's good
|
||||
validated_new_settings, schema = validate_args.validate(new_config)
|
||||
if validate_args == None:
|
||||
print("Error in the new settings!")
|
||||
else:
|
||||
print("New settings worked great. Writing results to : %s"%(args.output_config_file.name))
|
||||
args.output_config_file.write(json.dumps(validated_new_settings, sort_keys=True, indent=4))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -39,8 +80,8 @@ def main(args):
|
||||
configure_parser = actions_parser.add_parser(
|
||||
"configure", help="Configure a test run")
|
||||
configure_parser.set_defaults(func=configure_action)
|
||||
configure_parser.add_argument('-i', '--input_config_file', required=False, type=argparse.FileType('r'), default=DEFAULT_CONFIG_FILE, help="The config file to base the configuration off of.")
|
||||
configure_parser.add_argument('-o', '--output_config_file', required=False, type=argparse.FileType('w'), help="The config file to write the configuration off of.")
|
||||
configure_parser.add_argument('-i', '--input_config_file', required=False, type=argparse.FileType('r'), help="The config file to base the configuration off of.")
|
||||
configure_parser.add_argument('-o', '--output_config_file', required=True, type=argparse.FileType('w'), help="The config file to write the configuration off of.")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import sys
|
||||
import jsonschema.exceptions
|
||||
import jsonschema
|
||||
import argparse
|
||||
import copy
|
||||
import io
|
||||
import json
|
||||
import jsonschema
|
||||
import jsonschema.exceptions
|
||||
import jsonschema_errorprinter
|
||||
import sys
|
||||
from typing import Union
|
||||
|
||||
|
||||
@@ -12,8 +13,6 @@ from typing import Union
|
||||
setup_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
|
||||
"branch": {
|
||||
"type": "string",
|
||||
"default": "develop"
|
||||
@@ -161,24 +160,24 @@ setup_schema = {
|
||||
}
|
||||
|
||||
|
||||
def v(configuration: dict) -> Union[bool, dict]:
|
||||
def validate(configuration: dict) -> tuple[Union[dict,None],dict]:
|
||||
#v = jsonschema.Draft201909Validator(argument_schema)
|
||||
|
||||
|
||||
try:
|
||||
validation_errors, validated_json = jsonschema_errorprinter.check_json(
|
||||
configuration, setup_schema)
|
||||
if len(validation_errors) == 0:
|
||||
print("Input configuration successfully validated!")
|
||||
return validated_json
|
||||
return validated_json, setup_schema
|
||||
else:
|
||||
print("[%d] failures detected during validation of the configuration!" % (
|
||||
len(validation_errors)))
|
||||
for error in validation_errors:
|
||||
print(error, end="\n\n", file=sys.stderr)
|
||||
return False
|
||||
return None, setup_schema
|
||||
except Exception as e:
|
||||
print(str(e), file=sys.stderr)
|
||||
return False
|
||||
return None, setup_schema
|
||||
|
||||
"""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user