Beispiel #1
0
    def add(self, typename, instance):
        if not hasattr(instance, "keys"):
            raise error.ParseError("Expected mapping for %s" % typename,
                                   anchor=getattr(instance, "anchor", None))

        try:
            kls = ResourceType.resources[typename]
        except KeyError:
            raise error.ParseError("There is no resource type of '%s'" %
                                   typename,
                                   anchor=instance.anchor)

        resource = kls(instance)
        if resource.id in self:
            raise error.ParseError("'%s' cannot be defined multiple times" %
                                   resource.id,
                                   anchor=instance.anchor)

        self[resource.id] = resource

        # Create implicit File[] nodes for any watched files
        try:
            for watched in resource.watch:
                res = bind({
                    "name": watched,
                    "policy": "watched",
                })
                res.parent = instance
                w = self.add("File", res)
                w._original_hash = None
        except errors.NoMatching:
            pass

        return resource
Beispiel #2
0
    def create_from_yay_expression(cls, expression, verbose_errors=False):
        """ Given a Yay expression that resolves to a list of types and
        parameters, build a resource bundle.  """
        bundle = cls()
        try:
            for node in expression.get_iterable():
                bundle.add_from_node(node)

        except LanguageError as exc:
            raise
            p = error.ParseError()
            p.msg = str(exc)
            if exc.anchor:
                p.file = exc.anchor.source
                p.line = exc.anchor.lineno
            p.column = 0
            raise p

        except error.ParseError as exc:
            raise
            if getattr(node, "anchor", None):
                exc.msg += "\nFile %s, line %d, column %s" % (
                    node.anchor.source, node.anchor.lineno, "unknown")
                exc.file = node.anchor.source
                exc.line = node.anchor.lineno
            exc.column = 0
            raise

        return bundle
Beispiel #3
0
    def validate(self, context):
        """ Validate that this resource is correctly specified. Will raise
        an exception if it is invalid. Returns True if it is valid.

        We only validate if:

           - only known arguments are specified
           - the chosen policies all exist, or
           - there is at least one default policy, and
           - the arguments provided conform with all selected policies, and
           - the selected policies all share a single provider

        If the above is all true then we can identify a provider that should
        be able to implement the required policies.

        """

        # This will throw any error if any of our validation fails
        self.get_argument_values()

        # Only allow keys that are in the schema
        for key in self.inner.keys():
            if not key in self.get_argument_names():
                raise error.ParseError(
                    "'%s' is not a valid option for resource %s" % (key, self),
                    self.inner.anchor)

        # Error if doesn't conform to policy
        for p in self.get_potential_policies():
            p.validate(self)

            # throws an exception if there is not oneandonlyone provider
            p.get_provider(context)

        return True
Beispiel #4
0
    def __new__(meta, class_name, bases, new_attrs):
        cls = type.__new__(meta, class_name, bases, new_attrs)

        cls.policies = AvailableResourcePolicies()

        if class_name != 'Resource':
            rname = new_attrs.get("__resource_name__", class_name)
            if rname in meta.resources:
                raise error.ParseError("Redefinition of resource %s" % rname)
            else:
                meta.resources[rname] = cls

        return cls
Beispiel #5
0
    def add_from_node(self, spec):
        try:
            spec.as_dict()
        except errors.TypeError:
            raise error.ParseError("Not a valid Resource definition",
                                   anchor=spec.anchor)

        keys = list(spec.keys())
        if len(keys) > 1:
            raise error.ParseError("Too many keys in list item",
                                   anchor=spec.anchor)

        typename = keys[0]
        instances = spec.get_key(typename)

        try:
            instances.as_dict()
            iterable = [instances]
        except errors.TypeError:
            iterable = instances.get_iterable()

        for instance in iterable:
            self.add(typename, instance)
Beispiel #6
0
    def resolve(self):
        instance = self.resource

        try:
            value = self.node.resolve()
        except errors.NoMatching:
            # return PolicyCollection(instance.policies.default())
            return None

        if type(value) in types.StringTypes:
            if not value in instance.policies:
                raise error.ParseError("'%s' is not a valid policy for %r" %
                                       (value, instance))
            return PolicyCollection(StandardPolicy(value))

        if isinstance(value, dict):
            triggers = []
            for policy, conditions in value.items():
                if not policy in instance.policies:
                    raise error.ParseError(
                        "'%s' is not a valid policy for %r" %
                        (policy, instance))
                if not isinstance(conditions, list):
                    conditions = [conditions]
                for condition in conditions:
                    triggers.append(
                        PolicyTrigger(
                            policy=policy,
                            when=str(condition['when']),
                            on=str(condition['on']),
                        ))
            return PolicyCollection(triggers=triggers)

        raise error.ParseError(
            "Expected either a string literal or mapping as 'policy' argument for %r"
            % instance)
Beispiel #7
0
def _call_get(callable, *args, **kwargs):
    try:
        return callable(*args, **kwargs)
    except TemplateSyntaxError as e:
        raise error.ParseError(str(e), anchor=JinjaSyntaxAnchor(e))