From f256b61dd222f64fbcdea98c98060352ffab517f Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Thu, 29 Jun 2017 09:07:02 -0400 Subject: [PATCH] Refactor out a new Resource.referenced_attrs() method Calculating all of the attributes of a resource that are referenced in the template was previously done inside the node_data() method, but this is useful for the resource to be able to access for other reasons so refactor it into a separate method. Change-Id: I8ec943652e6f93a2352f2ea5e6ac46e0088e5458 Related-Bug: #1660831 Partially-Implements: blueprint stack-definition --- heat/engine/resource.py | 32 ++++++++++++++----- heat/tests/test_stack_collect_attributes.py | 35 +++++++++++++++++++++ 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 7668175d30..f2105e330f 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -918,6 +918,30 @@ class Resource(status.ResourceStatus): self._rsrc_prop_data = None self.attributes.reset_resolved_values() + def referenced_attrs(self, in_resources=True, in_outputs=True): + """Return the set of all attributes referenced in the template. + + This enables the resource to calculate which of its attributes will + be used. By default, attributes referenced in either other resources + or outputs will be included. Either can be excluded by setting the + `in_resources` or `in_outputs` parameters to False. + """ + def get_dep_attrs(source_dict): + return set(self.stack.get_dep_attrs(six.itervalues(source_dict), + self.name)) + + refd_attrs = set() + if in_resources: + refd_attrs |= get_dep_attrs(self.stack.resources) + if in_outputs: + refd_attrs |= get_dep_attrs(self.stack.outputs) + + if attributes.ALL_ATTRIBUTES in refd_attrs: + refd_attrs.remove(attributes.ALL_ATTRIBUTES) + refd_attrs |= (set(self.attributes) - {self.SHOW}) + + return refd_attrs + def node_data(self): def get_attrs(attrs): for attr in attrs: @@ -927,13 +951,7 @@ class Resource(status.ResourceStatus): except exception.InvalidTemplateAttribute as ita: LOG.info('%s', ita) - dep_attrs = set(self.stack.get_dep_attrs( - six.itervalues(self.stack.resources), - self.name)) - if attributes.ALL_ATTRIBUTES in dep_attrs: - dep_attrs.remove(attributes.ALL_ATTRIBUTES) - dep_attrs |= (set(self.attributes) - {self.SHOW}) - + dep_attrs = self.referenced_attrs(in_outputs=False) return node_data.NodeData(self.id, self.name, self.uuid, self.get_reference_id(), dict(get_attrs(dep_attrs)), diff --git a/heat/tests/test_stack_collect_attributes.py b/heat/tests/test_stack_collect_attributes.py index 71c3c93f15..596bf12d45 100644 --- a/heat/tests/test_stack_collect_attributes.py +++ b/heat/tests/test_stack_collect_attributes.py @@ -232,3 +232,38 @@ class DepAttrsTest(common.HeatTestCase): self.stack.get_dep_attrs( resources, res.name)) + + +class ReferencedAttrsTest(common.HeatTestCase): + def setUp(self): + super(ReferencedAttrsTest, self).setUp() + parsed_tmpl = template_format.parse(tmpl6) + self.stack = stack.Stack(utils.dummy_context(), 'test_stack', + template.Template(parsed_tmpl)) + self.resA = self.stack['AResource'] + self.resB = self.stack['BResource'] + + def test_referenced_attrs_resources(self): + self.assertEqual(self.resA.referenced_attrs(in_resources=True, + in_outputs=False), + {('list', 1), ('nested_dict', 'dict', 'b')}) + self.assertEqual(self.resB.referenced_attrs(in_resources=True, + in_outputs=False), + set()) + + def test_referenced_attrs_outputs(self): + self.assertEqual(self.resA.referenced_attrs(in_resources=False, + in_outputs=True), + {('flat_dict', 'key2'), ('nested_dict', 'string')}) + self.assertEqual(self.resB.referenced_attrs(in_resources=False, + in_outputs=True), + {'attr_B3'}) + + def test_referenced_attrs_both(self): + self.assertEqual(self.resA.referenced_attrs(in_resources=True, + in_outputs=True), + {('list', 1), ('nested_dict', 'dict', 'b'), + ('flat_dict', 'key2'), ('nested_dict', 'string')}) + self.assertEqual(self.resB.referenced_attrs(in_resources=True, + in_outputs=True), + {'attr_B3'})