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
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
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
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
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)
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)
def _call_get(callable, *args, **kwargs): try: return callable(*args, **kwargs) except TemplateSyntaxError as e: raise error.ParseError(str(e), anchor=JinjaSyntaxAnchor(e))