Mark nested stacks unhealthy by refid

Previously, we added the ability to mark a resource unhealthy using its
physical resource ID. This poses a difficulty for a template resource - the
can substitute the result of get_resource with the ID of a resource inside
the nested stack by providing an output named "OS::stack_id". However, the
physical_resource_id of the resource stored in the database is the UUID of
the nested stack, and thus the template resource will not be found when
marking a resource unhealthy using the ID returned from get_resource.

This particularly shows up when using a scaling group where the members are
defined by a template rather than a native resource type.

Solve this by falling back to Stack.resource_by_refid() if we can't find
the resource in the database. This iterates through all of the resources in
the stack and finds one where the output of get_resource matches.

Change-Id: Ia332af68123c3a43a581c0bf7899371bbe043e0d
Related-Bug: #1635295
This commit is contained in:
Zane Bitter 2017-01-11 11:41:45 -05:00
parent e1124b2605
commit d6f6bfc2e6
1 changed files with 10 additions and 5 deletions

View File

@ -1917,13 +1917,18 @@ class EngineService(service.ServiceBase):
matches = [stack[rs.name] for rs in rsrcs if in_stack(rs)]
if not matches:
raise exception.ResourceNotFound(resource_name=resource_name,
stack_name=stack.name)
if len(matches) > 1:
if matches:
if len(matches) == 1:
return matches[0]
raise exception.PhysicalResourceIDAmbiguity(phys_id=resource_name)
return matches[0]
# Try it the slow way
match = stack.resource_by_refid(resource_name)
if match is not None:
return match
raise exception.ResourceNotFound(resource_name=resource_name,
stack_name=stack.name)
@context.request_context
def find_physical_resource(self, cnxt, physical_resource_id):