Exemplo n.º 1
0
def run(template_fd, resource_fds, output_fd, local_tags, format="yaml"):
    assemblies = {}
    for fd in resource_fds:
        try:
            record_assemblies(fd, assemblies, local_tags)
        except YAMLError as e:
            log.error("While processing resource document %s:",
                      getattr(fd, "filename", "<input>"))
            log.error("%s", str(e))
            return 1

    try:
        docs = transclude_template(template_fd, assemblies, local_tags)
    except YAMLError as e:
        log.error("While processing template document %s:",
                  getattr(template_fd, "filename", "<input>"))
        log.error("%s", str(e))
        return 1

    if format == "json":
        if len(docs) > 1:
            log.warning("Multiple documents are not supported with JSON "
                        "output; only the first document will be written.")

        constructor = SafeConstructor()
        pyobjs = constructor.construct_document(docs[0])
        json_dump(pyobjs, output_fd)
    else:
        yaml_serialize_all(docs, stream=output_fd, Dumper=SafeDumper)

    return 0
Exemplo n.º 2
0
 def python_type(self, ast_node):
     if type(ast_node) is ScalarNode:
         return type(SafeConstructor().construct_object(ast_node))
     if type(ast_node) is SequenceNode:
         return list
     if type(ast_node) is MappingNode:
         return dict
     raise RuntimeError('Unable to map ast_node type ({0})'.format(
         type(ast_node)))
Exemplo n.º 3
0
    def validate(self, ast_node, parent_key=None):
        ast_node_type = self.python_type(ast_node)
        if self._type is str:
            wrong_type = type(ast_node) is not ScalarNode
            ast_node.tag = 'tag:yaml.org,2002:str'  # enforce string type.
        else:
            wrong_type = ast_node_type is not self._type
        if wrong_type:
            if (self.python_type(ast_node) is type(None)):
                msg = 'Expected a type {0} but got nothing'.format(
                    self.pretty_type(self._type))
            else:
                msg = 'Expected a type {0} but got {1} type {2}'.format(
                    self.pretty_type(self._type),
                    'a' if bool(ast_node.value) else 'an empty',
                    self.pretty_type(self.python_type(ast_node)))
            self.raise_error(msg, ast_node)

        if len(self._checks) > 0:
            if ast_node_type is dict:
                value = parent_key
            else:
                value = SafeConstructor().construct_object(ast_node)
            for desc, check in self._checks:
                if not check(value):
                    self.raise_error('Invalid {0} "{1}"'.format(desc, value),
                                     ast_node)

        if self._allowed is not None:
            value = SafeConstructor().construct_object(ast_node)
            (desc, allowed_set) = self._allowed
            if value not in allowed_set:
                self.raise_error('Unrecognized {0} "{1}"'.format(desc, value),
                                 ast_node)

        if self._subnode is None:
            return

        if self.python_type(ast_node) is dict:
            required_nodes = set(k for k, v in self._subnode.items()
                                 if not v.optional)
            for subnode_key, ast_subnode in ast_node.value:
                subnode_key = subnode_key.value
                if '*' in self._subnode:
                    self._subnode['*'].validate(ast_subnode,
                                                parent_key=subnode_key)
                    if '*' in required_nodes:
                        required_nodes.remove('*')
                elif subnode_key in self._subnode:  # ignore everything else
                    self._subnode[subnode_key].validate(ast_subnode,
                                                        parent_key=subnode_key)
                    if subnode_key in required_nodes:
                        required_nodes.remove(subnode_key)
            if len(required_nodes):
                if '*' in required_nodes:
                    msg = '{0} cannot be empty'.format(parent_key)
                else:
                    msg = 'Missing mandatory {0}: "{1}"'.format(
                        'entry' if len(required_nodes) == 1 else 'entries',
                        ', '.join(required_nodes))
                self.raise_error(msg, ast_node)