From 41aad453efecbf42e0c17635498a505e1ca55a55 Mon Sep 17 00:00:00 2001 From: rabi Date: Tue, 28 Nov 2017 11:52:15 +0530 Subject: [PATCH] Ignore resources with non-existent template When listing resources with nested depth, we get all resources for the root stack and cache them in the context. By the time we iterate through the resources for a nested stack, if the current_template_id of resources do not match the stack template, we try to load the template. However, it's possible that the template does not exist anymore. It would be good to ignore those resources. Change-Id: I838320539838ed74f490bca8601cde96eaf7c7ee Closes-Bug: #1734815 --- heat/engine/stack.py | 5 ++++- heat/tests/test_stack.py | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/heat/engine/stack.py b/heat/engine/stack.py index 16e5d2e558..a78828f333 100644 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -389,7 +389,10 @@ class Stack(collections.Mapping): elif stk_def_cache and tid in stk_def_cache: stk_def = stk_def_cache[tid] else: - t = tmpl.Template.load(self.context, tid) + try: + t = tmpl.Template.load(self.context, tid) + except exception.NotFound: + return None stk_def = self.defn.clone_with_new_template(t, self.identifier()) if stk_def_cache is not None: diff --git a/heat/tests/test_stack.py b/heat/tests/test_stack.py index 1b59fc4229..378a6f2f06 100644 --- a/heat/tests/test_stack.py +++ b/heat/tests/test_stack.py @@ -381,6 +381,31 @@ class StackTest(common.HeatTestCase): # And returns the resource A self.assertEqual('A', all_resources[0].name) + @mock.patch.object(resource_objects.Resource, 'get_all_by_stack') + def test_iter_resources_with_nonexistent_template(self, mock_db_call): + tpl = {'HeatTemplateFormatVersion': '2012-12-12', + 'Resources': + {'A': {'Type': 'GenericResourceType'}, + 'B': {'Type': 'GenericResourceType'}}} + self.stack = stack.Stack(self.ctx, 'test_stack', + template.Template(tpl), + status_reason='blarg') + + self.stack.store() + + mock_rsc_a = mock.MagicMock(current_template_id=self.stack.t.id) + mock_rsc_a.name = 'A' + mock_rsc_b = mock.MagicMock(current_template_id=self.stack.t.id + 1) + mock_rsc_b.name = 'B' + mock_db_call.return_value = { + 'A': mock_rsc_a, + 'B': mock_rsc_b + } + + all_resources = list(self.stack.iter_resources()) + + self.assertEqual(1, len(all_resources)) + @mock.patch.object(resource_objects.Resource, 'get_all_by_stack') def test_iter_resources_nested_with_filters(self, mock_db_call): tpl = {'HeatTemplateFormatVersion': '2012-12-12',