Avoid RPC call in TemplateResource.get_reference_id()

Most TemplateResources probably don't have an OS::stack_id output defined
in the template, so it's unfortunate that we have to make an RPC call to
check that every time we retrieve the resource's reference_id, which we
have to do for most stack operations.

To cut down on unnecessary RPC calls, check the template first locally to
see if there is an OS::stack_id output present.

Change-Id: Ia32ed6bca453b391371f544ad0a07d49dc0616e3
Related-Bug: #1719333
This commit is contained in:
Zane Bitter 2017-09-28 17:14:25 -04:00
parent 6ce26aeb4d
commit 6857b7f368
2 changed files with 43 additions and 21 deletions

View File

@ -29,6 +29,7 @@ from heat.engine import environment
from heat.engine import resource
from heat.engine import scheduler
from heat.engine import stack as parser
from heat.engine import stk_defn
from heat.engine import template
from heat.objects import raw_template
from heat.objects import stack as stack_object
@ -316,12 +317,15 @@ class StackResource(resource.Resource):
self.resource_id_set(result['stack_id'])
def _stack_kwargs(self, user_params, child_template, adopt_data=None):
def child_definition(self, child_template=None, user_params=None,
nested_identifier=None):
if user_params is None:
user_params = self.child_params()
if child_template is None:
child_template = self.child_template()
if nested_identifier is None:
nested_identifier = self.nested_identifier()
child_env = environment.get_child_environment(
self.stack.env,
user_params,
@ -330,6 +334,14 @@ class StackResource(resource.Resource):
parsed_template = self._child_parsed_template(child_template,
child_env)
return stk_defn.StackDefinition(self.context, parsed_template,
nested_identifier,
None)
def _stack_kwargs(self, user_params, child_template, adopt_data=None):
defn = self.child_definition(child_template, user_params)
parsed_template = defn.t
if adopt_data is None:
template_id = parsed_template.store(self.context)
return {
@ -341,7 +353,7 @@ class StackResource(resource.Resource):
else:
return {
'template': parsed_template.t,
'params': child_env.user_env_as_dict(),
'params': defn.env.user_env_as_dict(),
'files': parsed_template.files,
}

View File

@ -60,6 +60,8 @@ class TemplateResource(stack_resource.StackResource):
self.stack = stack
self.validation_exception = None
self._reference_id = None
tri = self._get_resource_info(json_snippet)
self.properties_schema = {}
@ -306,25 +308,33 @@ class TemplateResource(stack_resource.StackResource):
if self.resource_id is None:
return six.text_type(self.name)
stack_identity = self.nested_identifier()
try:
if self._outputs is not None:
return self.get_output(STACK_ID_OUTPUT)
if self._reference_id is not None:
return self._reference_id
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.TemplateOutputError as err:
LOG.info('%s', err)
except (exception.InvalidTemplateAttribute, exception.NotFound):
pass
else:
return output[rpc_api.OUTPUT_VALUE]
stack_identity = self.nested_identifier()
with self.frozen_properties():
nest_defn = self.child_definition(nested_identifier=stack_identity)
if STACK_ID_OUTPUT in nest_defn.enabled_output_names():
try:
if self._outputs is not None:
self._reference_id = self.get_output(STACK_ID_OUTPUT)
return self._reference_id
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.TemplateOutputError as err:
LOG.info('%s', err)
except (exception.InvalidTemplateAttribute, exception.NotFound):
pass
else:
self._reference_id = output[rpc_api.OUTPUT_VALUE]
return self._reference_id
return stack_identity.arn()