summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-03-21 23:12:27 +0000
committerGerrit Code Review <review@openstack.org>2017-03-21 23:12:27 +0000
commit40e452063e01fe6d6edf273bbd45f1bcd934cd01 (patch)
treef44085a032a2378163da58f31b2666bd44fe7867
parent597d10c014190c0bf52b5c67a25bd9978bdd4787 (diff)
parent34d46d90a816f2811d203ddb5233ed3fd3d3a434 (diff)
downloadheat-40e452063e01fe6d6edf273bbd45f1bcd934cd01.tar.gz
Merge "Pass on outputs errors to parent stacks" into stable/ocata
-rw-r--r--heat/common/exception.py4
-rw-r--r--heat/engine/resources/stack_resource.py22
-rw-r--r--heat/tests/test_provider_template.py2
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):