diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 4f5e73e096..61cc8f3bde 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -1052,9 +1052,12 @@ class Resource(status.ResourceStatus): for e in get_attrs(out_attrs - dep_attrs, cacheable_only=True): pass + # Calculate attribute values *before* reference ID, to potentially + # save an extra RPC call in TemplateResource + attribute_values = dict(get_attrs(dep_attrs)) + return node_data.NodeData(self.id, self.name, self.uuid, - self.FnGetRefId(), - dict(get_attrs(dep_attrs)), + self.FnGetRefId(), attribute_values, self.action, self.status) def preview(self): diff --git a/heat/engine/resources/template_resource.py b/heat/engine/resources/template_resource.py index 4e87b5b826..7ab803f823 100644 --- a/heat/engine/resources/template_resource.py +++ b/heat/engine/resources/template_resource.py @@ -25,11 +25,14 @@ from heat.engine import environment from heat.engine import properties from heat.engine.resources import stack_resource from heat.engine import template +from heat.rpc import api as rpc_api REMOTE_SCHEMES = ('http', 'https') LOCAL_SCHEMES = ('file',) +STACK_ID_OUTPUT = 'OS::stack_id' + def generate_class_from_template(name, data, param_defaults): tmpl = template.Template(template_format.parse(data)) @@ -300,10 +303,25 @@ class TemplateResource(stack_resource.StackResource): if self.resource_id is None: return six.text_type(self.name) + stack_identity = self.nested_identifier() try: - return self.get_output('OS::stack_id') - except exception.InvalidTemplateAttribute: - return self.nested_identifier().arn() + if self._outputs is not None: + return self.get_output(STACK_ID_OUTPUT) + + output = self.rpc_client().show_output(self.context, + dict(stack_identity), + STACK_ID_OUTPUT) + if rpc_api.OUTPUT_ERROR in output: + raise exception.TemplateOutputError( + resource=self.name, + attribute=STACK_ID_OUTPUT, + message=output[rpc_api.OUTPUT_ERROR]) + except (exception.InvalidTemplateAttribute, exception.NotFound): + pass + else: + return output[rpc_api.OUTPUT_VALUE] + + return stack_identity.arn() def get_attribute(self, key, *path): if self.resource_id is None: