Use a sentinel to indicate when all attributes are required
To generate its NodeData, a Resource must know which of its attributes other parts of the template have dependencies on, which it determines by asking the intrinsic functions in the template. Currently, the get_attr function when used with no arguments depends on all of the attributes of the resource (except 'show'), and it obtains this list from the Resource itself (via the attributes_schema). This presents a chicken-and-egg problem if we want to give Functions access only to a ResourceProxy based on the NodeData. Resolve this by returning a constant sentinel value (indicating that all attributes are required) to the Resource, which can determine for itself what attributes it has. Change-Id: If209b589278fe1facb06e157fe76209fdd42a8a2 Partially-Implements: blueprint stack-definition
This commit is contained in:
parent
2cf7af7deb
commit
06afc2f3b0
@ -135,6 +135,10 @@ def _stack_id_output(resource_name, template_type='cfn'):
|
||||
|
||||
BASE_ATTRIBUTES = (SHOW_ATTR, ) = ('show', )
|
||||
|
||||
# Returned by function.dep_attrs() to indicate that all attributes are
|
||||
# referenced
|
||||
ALL_ATTRIBUTES = '*'
|
||||
|
||||
|
||||
@repr_wrapper
|
||||
class Attributes(collections.Mapping):
|
||||
@ -146,6 +150,9 @@ class Attributes(collections.Mapping):
|
||||
self._attributes = Attributes._make_attributes(schema)
|
||||
self.reset_resolved_values()
|
||||
|
||||
assert ALL_ATTRIBUTES not in schema, \
|
||||
"Invalid attribute name '%s'" % ALL_ATTRIBUTES
|
||||
|
||||
def reset_resolved_values(self):
|
||||
self._resolved_values = {}
|
||||
|
||||
|
@ -73,6 +73,9 @@ class Function(object):
|
||||
|
||||
Return an iterator over any attributes of the specified resource that
|
||||
this function references.
|
||||
|
||||
The special value heat.engine.attributes.ALL_ATTRIBUTES may be used to
|
||||
indicate that all attributes of the resource are required.
|
||||
"""
|
||||
return dep_attrs(self.args, resource_name)
|
||||
|
||||
@ -179,6 +182,9 @@ class Macro(Function):
|
||||
|
||||
Return an iterator over any attributes of the specified resource that
|
||||
this function references.
|
||||
|
||||
The special value heat.engine.attributes.ALL_ATTRIBUTES may be used to
|
||||
indicate that all attributes of the resource are required.
|
||||
"""
|
||||
return dep_attrs(self.parsed, resource_name)
|
||||
|
||||
|
@ -315,8 +315,7 @@ class GetAttAllAttributes(GetAtt):
|
||||
if self._attribute is not None:
|
||||
return super(GetAttAllAttributes, self).dep_attrs(resource_name)
|
||||
elif self._res_name() == resource_name:
|
||||
res = self._resource()
|
||||
attrs = six.iterkeys(res.attributes_schema)
|
||||
attrs = [attributes.ALL_ATTRIBUTES]
|
||||
else:
|
||||
attrs = []
|
||||
return itertools.chain(function.dep_attrs(self.args,
|
||||
|
@ -872,9 +872,13 @@ class Resource(status.ResourceStatus):
|
||||
except exception.InvalidTemplateAttribute as ita:
|
||||
LOG.info('%s', ita)
|
||||
|
||||
dep_attrs = self.stack.get_dep_attrs(
|
||||
dep_attrs = set(self.stack.get_dep_attrs(
|
||||
six.itervalues(self.stack.resources),
|
||||
self.name)
|
||||
self.name))
|
||||
if attributes.ALL_ATTRIBUTES in dep_attrs:
|
||||
dep_attrs.remove(attributes.ALL_ATTRIBUTES)
|
||||
dep_attrs |= (set(self.attributes) - {self.SHOW})
|
||||
|
||||
return node_data.NodeData(self.id, self.name, self.uuid,
|
||||
self.get_reference_id(),
|
||||
dict(get_attrs(dep_attrs)),
|
||||
|
Loading…
Reference in New Issue
Block a user