diff options
author | Jenkins <jenkins@review.openstack.org> | 2017-03-21 23:12:27 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2017-03-21 23:12:27 +0000 |
commit | 40e452063e01fe6d6edf273bbd45f1bcd934cd01 (patch) | |
tree | f44085a032a2378163da58f31b2666bd44fe7867 | |
parent | 597d10c014190c0bf52b5c67a25bd9978bdd4787 (diff) | |
parent | 34d46d90a816f2811d203ddb5233ed3fd3d3a434 (diff) | |
download | heat-40e452063e01fe6d6edf273bbd45f1bcd934cd01.tar.gz |
Merge "Pass on outputs errors to parent stacks" into stable/ocata
-rw-r--r-- | heat/common/exception.py | 4 | ||||
-rw-r--r-- | heat/engine/resources/stack_resource.py | 22 | ||||
-rw-r--r-- | heat/tests/test_provider_template.py | 2 |
3 files changed, 20 insertions, 8 deletions
diff --git a/heat/common/exception.py b/heat/common/exception.py index e01d45392..c842dc61a 100644 --- a/heat/common/exception.py +++ b/heat/common/exception.py @@ -158,6 +158,10 @@ class InvalidTemplateReference(HeatException): ' is incorrect.') +class TemplateOutputError(HeatException): + msg_fmt = _('Error in %(resource)s output %(attribute)s: %(message)s') + + class InvalidExternalResourceDependency(HeatException): msg_fmt = _("Invalid dependency with external %(resource_type)s " "resource: %(external_id)s") diff --git a/heat/engine/resources/stack_resource.py b/heat/engine/resources/stack_resource.py index e0bc85b12..9b27f1fe1 100644 --- a/heat/engine/resources/stack_resource.py +++ b/heat/engine/resources/stack_resource.py @@ -585,8 +585,10 @@ class StackResource(resource.Resource): particular exception, not KeyError, being raised if the key does not exist.) """ - if self._outputs is None or self._outputs.get(op, - NotImplemented) is None: + if (self._outputs is None or + (op in self._outputs and + rpc_api.OUTPUT_ERROR not in self._outputs[op] and + self._outputs[op].get(rpc_api.OUTPUT_VALUE) is None)): stack_identity = self.nested_identifier() if stack_identity is None: return @@ -595,14 +597,20 @@ class StackResource(resource.Resource): if not stack: return outputs = stack[0].get(rpc_api.STACK_OUTPUTS) or {} - self._outputs = {o[rpc_api.OUTPUT_KEY]: o[rpc_api.OUTPUT_VALUE] - for o in outputs if rpc_api.OUTPUT_ERROR not in o} + self._outputs = {o[rpc_api.OUTPUT_KEY]: o for o in outputs} - try: - return self._outputs[op] - except KeyError: + if op not in self._outputs: raise exception.InvalidTemplateAttribute(resource=self.name, key=op) + output_data = self._outputs[op] + if rpc_api.OUTPUT_ERROR in output_data: + raise exception.TemplateOutputError( + resource=self.name, + attribute=op, + message=output_data[rpc_api.OUTPUT_ERROR]) + + return output_data[rpc_api.OUTPUT_VALUE] + def _resolve_attribute(self, name): return self.get_output(name) diff --git a/heat/tests/test_provider_template.py b/heat/tests/test_provider_template.py index 6df378a27..5e17bd563 100644 --- a/heat/tests/test_provider_template.py +++ b/heat/tests/test_provider_template.py @@ -319,7 +319,7 @@ class ProviderTemplateTest(common.HeatTestCase): output = {'outputs': [{'output_key': 'Foo', 'output_value': None, 'output_error': 'it is all bad'}]} temp_res._rpc_client.show_stack.return_value = [output] - self.assertRaises(exception.InvalidTemplateAttribute, + self.assertRaises(exception.TemplateOutputError, temp_res.FnGetAtt, 'Foo') def test_properties_normal(self): |