diff options
author | Jenkins <jenkins@review.openstack.org> | 2017-07-31 12:04:56 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2017-07-31 12:04:56 +0000 |
commit | 8c7b66a8a35180b5c352279e2800ec89cc8b77dc (patch) | |
tree | ea07a4713fc02863e27a47d88f184ab195e7ee80 /heat | |
parent | 139eff252acfa4fcae1f7ec0468cd70afe05362e (diff) | |
parent | b0916ad5bb458a69f860fc0ebc1cc257a2020838 (diff) | |
download | heat-8c7b66a8a35180b5c352279e2800ec89cc8b77dc.tar.gz |
Merge "Cache names of required resources in ResourceDefinition"
Diffstat (limited to 'heat')
-rw-r--r-- | heat/engine/rsrc_defn.py | 72 | ||||
-rw-r--r-- | heat/tests/test_rsrc_defn.py | 3 |
2 files changed, 47 insertions, 28 deletions
diff --git a/heat/engine/rsrc_defn.py b/heat/engine/rsrc_defn.py index 9fe0ff04e..295ac448c 100644 --- a/heat/engine/rsrc_defn.py +++ b/heat/engine/rsrc_defn.py @@ -99,6 +99,7 @@ class ResourceDefinition(object): self._hash = hash(self.resource_type) self._rendering = None + self._dep_names = None assert isinstance(self.description, six.string_types) @@ -202,11 +203,44 @@ class ResourceDefinition(object): function.dep_attrs(self._metadata, resource_name)) + def required_resource_names(self): + """Return a set of names of all resources on which this depends. + + Note that this is done entirely in isolation from the rest of the + template, so the resource names returned may refer to resources that + don't actually exist, or would have strict_dependency=False. Use the + dependencies() method to get validated dependencies. + """ + if self._dep_names is None: + explicit_depends = [] if self._depends is None else self._depends + + def path(section): + return '.'.join([self.name, section]) + + prop_deps = function.dependencies(self._properties, + path('Properties')) + metadata_deps = function.dependencies(self._metadata, + path('Metadata')) + implicit_depends = six.moves.map(lambda rp: rp.name, + itertools.chain(prop_deps, + metadata_deps)) + + # (ricolin) External resource should not depend on any other + # resources. This operation is not allowed for now. + if self.external_id(): + if explicit_depends: + raise exception.InvalidExternalResourceDependency( + external_id=self.external_id(), + resource_type=self.resource_type + ) + self._dep_names = set() + else: + self._dep_names = set(itertools.chain(explicit_depends, + implicit_depends)) + return self._dep_names + def dependencies(self, stack): """Return the Resource objects in given stack on which this depends.""" - def path(section): - return '.'.join([self.name, section]) - def get_resource(res_name): if res_name not in stack: if res_name in stack.t.get(stack.t.RESOURCES): @@ -215,31 +249,13 @@ class ResourceDefinition(object): return raise exception.InvalidTemplateReference(resource=res_name, key=self.name) - return stack[res_name] - - def strict_func_deps(data, datapath): - return six.moves.filter( - lambda r: getattr(r, 'strict_dependency', True), - six.moves.map(lambda rp: stack[rp.name], - function.dependencies(data, datapath))) - - explicit_depends = [] if self._depends is None else self._depends - prop_deps = strict_func_deps(self._properties, path('Properties')) - metadata_deps = strict_func_deps(self._metadata, path('Metadata')) - - # (ricolin) External resource should not depend on any other resources. - # This operation is not allowed for now. - if self.external_id(): - if explicit_depends: - raise exception.InvalidExternalResourceDependency( - external_id=self.external_id(), - resource_type=self.resource_type - ) - return itertools.chain() - - return itertools.chain( - filter(None, (get_resource(dep) for dep in explicit_depends)), - prop_deps, metadata_deps) + res = stack[res_name] + if getattr(res, 'strict_dependency', True): + return res + + return six.moves.filter(None, + six.moves.map(get_resource, + self.required_resource_names())) def set_translation_rules(self, rules=None, client_resolve=True): """Helper method to update properties with translation rules.""" diff --git a/heat/tests/test_rsrc_defn.py b/heat/tests/test_rsrc_defn.py index 37f505c44..9109e10db 100644 --- a/heat/tests/test_rsrc_defn.py +++ b/heat/tests/test_rsrc_defn.py @@ -92,11 +92,13 @@ class ResourceDefinitionTest(common.HeatTestCase): def test_dependencies_default(self): rd = rsrc_defn.ResourceDefinition('rsrc', 'SomeType') stack = {'foo': 'FOO', 'bar': 'BAR'} + self.assertEqual(set(), rd.required_resource_names()) self.assertEqual([], list(rd.dependencies(stack))) def test_dependencies_explicit(self): rd = rsrc_defn.ResourceDefinition('rsrc', 'SomeType', depends=['foo']) stack = {'foo': 'FOO', 'bar': 'BAR'} + self.assertEqual({'foo'}, rd.required_resource_names()) self.assertEqual(['FOO'], list(rd.dependencies(stack))) def test_dependencies_explicit_ext(self): @@ -117,6 +119,7 @@ class ResourceDefinitionTest(common.HeatTestCase): t = template_format.parse(TEMPLATE_WITH_INVALID_EXPLICIT_DEPEND) stack = utils.parse_stack(t) rd = stack.t.resource_definitions(stack)['test3'] + self.assertEqual({'test2'}, rd.required_resource_names()) self.assertRaises(exception.InvalidTemplateReference, lambda: list(rd.dependencies(stack))) |