示例#1
0
def convert_script_to_dict(script_file, tokens):
    """Converts a JSON file to a config dict.

    Reads in a JSON file, swaps out any environment variables that
    have been used inside the JSON, and then returns a dictionary.

    Args:
        script_file: Path to the JSON/YAML file to import, or file instance.
        tokens: dictionary to pass to populate_with_tokens.

    Returns:
        <Dictonary of Config Data>

    Raises:
        kingpin.exceptions.InvalidScript
    """

    filename = ''
    try:
        if type(script_file) in (str, unicode):
            filename = script_file
            instance = open(script_file)
        elif type(script_file) is file:
            filename = script_file.name
            instance = script_file
        else:
            filename = str(script_file)
            instance = script_file
    except IOError as e:
        raise exceptions.InvalidScript('Error reading script %s: %s' %
                                       (script_file, e))

    log.debug('Reading %s' % filename)
    raw = instance.read()
    parsed = populate_with_tokens(raw, tokens)

    # If the file ends with .json, use demjson to read it. If it ends with
    # .yml/.yaml, use PyYAML. If neither, error.
    suffix = filename.split('.')[-1].strip().lower()
    try:
        if suffix == 'json':
            decoded = demjson.decode(parsed)
        elif suffix in ('yml', 'yaml'):
            decoded = yaml.safe_load(parsed)
            if decoded is None:
                raise exceptions.InvalidScript('Invalid YAML in `%s`' %
                                               filename)
        else:
            raise exceptions.InvalidScriptName('Invalid file extension: %s' %
                                               suffix)
    except demjson.JSONError as e:
        # demjson exceptions have `pretty_description()` method with
        # much more useful info.
        raise exceptions.InvalidScript('JSON in `%s` has an error: %s' %
                                       (filename, e.pretty_description()))
    return decoded
示例#2
0
def validate(config):
    """Validates the JSON against our schemas.

    TODO: Support multiple schema versions

    Args:
        config: Dictionary of parsed JSON

    Returns:
        None: if all is well

    Raises:
        Execption if something went wrong.
    """
    try:
        return jsonschema.validate(config, SCHEMA_1_0)
    except jsonschema.exceptions.ValidationError as e:
        raise exceptions.InvalidScript(e)
示例#3
0
    def test_init_with_errors(self):

        # Remote files are prohibited for now
        with self.assertRaises(exceptions.UnrecoverableActorFailure):
            misc.Macro('Unit Test', {
                'macro': 'ftp://fail.test.json',
                'tokens': {}
            })

        # Remote file with bad URL
        with self.assertRaises(exceptions.UnrecoverableActorFailure):
            misc.Macro('Unit Test', {
                'macro': 'http://fail.test.json',
                'tokens': {}
            })

        # Non-existent file
        with self.assertRaises(exceptions.UnrecoverableActorFailure):
            misc.Macro('Unit Test', {
                'macro': 'dontcreatethis.json',
                'tokens': {}
            })

        # We don't want the rest of the tests failing on downloading this file.
        misc.Macro._get_macro = mock.Mock(return_value='unit-test-file')

        # Schema failure
        with mock.patch('kingpin.utils.convert_script_to_dict') as j2d:
            j2d.return_value = {
                'desc': 'unit test',
                'options': {}  # `actor` keyword is missing
            }

            with self.assertRaises(exceptions.UnrecoverableActorFailure):
                misc.Macro('Unit Test', {'macro': 'test.json', 'tokens': {}})

        # JSON syntax error
        with mock.patch('kingpin.utils.convert_script_to_dict') as j2d:

            j2d.side_effect = kingpin_exceptions.InvalidScript('Fail!')

            with self.assertRaises(exceptions.UnrecoverableActorFailure):
                misc.Macro('Unit Test', {'macro': 'test.json', 'tokens': {}})