Much better configuration parsing, validation, and substitution of defaults using jsonschema.

This commit is contained in:
pyth0n1c
2021-11-18 13:01:55 -08:00
parent 82d53ccbd9
commit cf8d5f2dff
3 changed files with 61 additions and 17 deletions
@@ -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: