summaryrefslogtreecommitdiff
path: root/heat
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-07-31 12:04:56 +0000
committerGerrit Code Review <review@openstack.org>2017-07-31 12:04:56 +0000
commit8c7b66a8a35180b5c352279e2800ec89cc8b77dc (patch)
treeea07a4713fc02863e27a47d88f184ab195e7ee80 /heat
parent139eff252acfa4fcae1f7ec0468cd70afe05362e (diff)
parentb0916ad5bb458a69f860fc0ebc1cc257a2020838 (diff)
downloadheat-8c7b66a8a35180b5c352279e2800ec89cc8b77dc.tar.gz
Merge "Cache names of required resources in ResourceDefinition"
Diffstat (limited to 'heat')
-rw-r--r--heat/engine/rsrc_defn.py72
-rw-r--r--heat/tests/test_rsrc_defn.py3
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)))