Reference the parent stack, not parent resource in Stack
In order to eliminate circular references, we need to define the Stack as the top of any reference hierarchy. This means we can't hold a reference to a Resource directly without also holding a reference to its Stack. Change-Id: I7430b109bbe1c5d6d64be9b8c778b394e9cff269 Related-Bug: #1454873
This commit is contained in:
parent
e95336340e
commit
2032548c4e
|
@ -123,7 +123,7 @@ class Stack(collections.Mapping):
|
|||
self.timeout_mins = timeout_mins
|
||||
self.disable_rollback = disable_rollback
|
||||
self.parent_resource_name = parent_resource
|
||||
self._parent_resource = None
|
||||
self._parent_stack = None
|
||||
self._resources = None
|
||||
self._dependencies = None
|
||||
self._access_allowed_handlers = {}
|
||||
|
@ -176,19 +176,18 @@ class Stack(collections.Mapping):
|
|||
|
||||
Note: this should only be used by "Fn::ResourceFacade"
|
||||
"""
|
||||
if self._parent_resource is not None:
|
||||
return self._parent_resource
|
||||
if self._parent_stack is None:
|
||||
# we need both parent name and owner id.
|
||||
if self.parent_resource_name is None or self.owner_id is None:
|
||||
return None
|
||||
|
||||
# we need both parent name and owner id.
|
||||
if self.parent_resource_name is None or self.owner_id is None:
|
||||
return None
|
||||
try:
|
||||
owner = self.load(self.context, stack_id=self.owner_id)
|
||||
except exception.NotFound:
|
||||
return None
|
||||
self._parent_stack = owner
|
||||
|
||||
try:
|
||||
owner = self.load(self.context, stack_id=self.owner_id)
|
||||
except exception.NotFound:
|
||||
return None
|
||||
self._parent_resource = owner[self.parent_resource_name]
|
||||
return self._parent_resource
|
||||
return self._parent_stack[self.parent_resource_name]
|
||||
|
||||
def stored_context(self):
|
||||
if self.user_creds_id:
|
||||
|
|
|
@ -797,7 +797,7 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
stack = parser.Stack(utils.dummy_context(), 'test_stack',
|
||||
template.Template(hot_tpl_empty),
|
||||
parent_resource='parent')
|
||||
stack._parent_resource = parent_resource
|
||||
stack._parent_stack = dict(parent=parent_resource)
|
||||
self.assertEqual({"foo": "bar"},
|
||||
self.resolve(metadata_snippet, stack.t, stack))
|
||||
self.assertEqual('Retain',
|
||||
|
@ -823,7 +823,7 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
stack = parser.Stack(utils.dummy_context(), 'test_stack',
|
||||
template.Template(hot_tpl_empty),
|
||||
parent_resource='parent')
|
||||
stack._parent_resource = parent_resource
|
||||
stack._parent_stack = dict(parent=parent_resource)
|
||||
self.assertEqual('Retain',
|
||||
self.resolve(deletion_policy_snippet, stack.t, stack))
|
||||
|
||||
|
@ -843,13 +843,14 @@ class HOTemplateTest(common.HeatTestCase):
|
|||
parent_resource = DummyClass()
|
||||
parent_resource.metadata_set({"foo": "bar"})
|
||||
parent_resource.t = rsrc_defn.ResourceDefinition('parent', 'SomeType')
|
||||
parent_resource.stack = parser.Stack(utils.dummy_context(),
|
||||
'toplevel_stack',
|
||||
template.Template(hot_tpl_empty))
|
||||
parent_stack = parser.Stack(utils.dummy_context(),
|
||||
'toplevel_stack',
|
||||
template.Template(hot_tpl_empty))
|
||||
parent_stack._resources = {'parent': parent_resource}
|
||||
stack = parser.Stack(utils.dummy_context(), 'test_stack',
|
||||
template.Template(hot_tpl_empty),
|
||||
parent_resource='parent')
|
||||
stack._parent_resource = parent_resource
|
||||
stack._parent_stack = parent_stack
|
||||
self.assertEqual('Delete', self.resolve(snippet, stack.t, stack))
|
||||
|
||||
def test_removed_function(self):
|
||||
|
|
|
@ -279,10 +279,12 @@ class StackTest(common.HeatTestCase):
|
|||
{'A': {'Type': 'GenericResourceType'}}}
|
||||
self.stack = stack.Stack(self.ctx, 'test_stack',
|
||||
template.Template(tpl),
|
||||
status_reason='blarg')
|
||||
status_reason='blarg',
|
||||
parent_resource='parent')
|
||||
|
||||
self.stack._parent_resource = mock.Mock()
|
||||
self.stack._parent_resource.stack = None
|
||||
parent_resource = mock.Mock()
|
||||
parent_resource.stack = None
|
||||
self.stack._parent_stack = dict(parent=parent_resource)
|
||||
self.assertEqual(self.stack, self.stack.root_stack)
|
||||
|
||||
def test_root_stack_with_parent(self):
|
||||
|
@ -290,10 +292,11 @@ class StackTest(common.HeatTestCase):
|
|||
'Resources':
|
||||
{'A': {'Type': 'GenericResourceType'}}}
|
||||
stk = stack.Stack(self.ctx, 'test_stack', template.Template(tpl),
|
||||
status_reason='blarg')
|
||||
status_reason='blarg', parent_resource='parent')
|
||||
|
||||
stk._parent_resource = mock.Mock()
|
||||
stk._parent_resource.stack.root_stack = 'test value'
|
||||
parent_resource = mock.Mock()
|
||||
parent_resource.stack.root_stack = 'test value'
|
||||
stk._parent_stack = dict(parent=parent_resource)
|
||||
self.assertEqual('test value', stk.root_stack)
|
||||
|
||||
def test_load_parent_resource(self):
|
||||
|
|
|
@ -777,7 +777,7 @@ Mappings:
|
|||
stk = stack.Stack(self.ctx, 'test_stack',
|
||||
template.Template(empty_template),
|
||||
parent_resource='parent', owner_id=45)
|
||||
stk._parent_resource = parent_resource
|
||||
stk._parent_stack = dict(parent=parent_resource)
|
||||
self.assertEqual({"foo": "bar"},
|
||||
self.resolve(metadata_snippet, stk.t, stk))
|
||||
self.assertEqual('Retain',
|
||||
|
@ -801,7 +801,7 @@ Mappings:
|
|||
stk = stack.Stack(self.ctx, 'test_stack',
|
||||
template.Template(empty_template),
|
||||
parent_resource='parent')
|
||||
stk._parent_resource = parent_resource
|
||||
stk._parent_stack = dict(parent=parent_resource)
|
||||
self.assertEqual('Retain',
|
||||
self.resolve(deletion_policy_snippet, stk.t, stk))
|
||||
|
||||
|
@ -825,7 +825,7 @@ Mappings:
|
|||
stk = stack.Stack(self.ctx, 'test_stack',
|
||||
template.Template(empty_template),
|
||||
parent_resource='parent', owner_id=78)
|
||||
stk._parent_resource = parent_resource
|
||||
stk._parent_stack = dict(parent=parent_resource)
|
||||
self.assertEqual('Delete', self.resolve(snippet, stk.t, stk))
|
||||
|
||||
def test_prevent_parameters_access(self):
|
||||
|
|
Loading…
Reference in New Issue