Ignore conditions when reparsing ResourceDefinition

In the legacy path we reparse a resource definition to refer to a different
StackDefinition when copying a resource definition into the existing
template (as the resource is updated) or into the backup stack's template.
However, the resources 'condition' may reference conditionals that are not
defined in the template it is being copied into (e.g. during a stack update
that creates a new condition), and in this case the destination template
will become unusable.

Since the fact that we care about the resource definition at all indicates
that the condition was enabled, just ignore the condition after reparsing.
This is consistent with what we do for 'if' macros, which is to resolve the
condition part during reparsing.

Change-Id: I59a374435f6275badc8124efbd7b7db2e36e2de5
Story: #2003558
Task: 24847
This commit is contained in:
Zane Bitter 2018-08-23 19:53:46 -04:00
parent 99cbff3803
commit 92101b18e2
2 changed files with 26 additions and 8 deletions

View File

@ -187,6 +187,10 @@ class ResourceDefinition(object):
This returns a new resource definition, with all of the functions
parsed in the context of the specified stack and template.
Any conditions are *not* included - it is assumed that the resource is
being interpreted in any context that it should be enabled in that
context.
"""
assert not getattr(self, '_frozen', False
), "Cannot re-parse a frozen definition"
@ -202,7 +206,7 @@ class ResourceDefinition(object):
deletion_policy=reparse_snippet(self._deletion_policy),
update_policy=reparse_snippet(self._update_policy),
external_id=reparse_snippet(self._external_id),
condition=self._condition)
condition=None)
def validate(self):
"""Validate intrinsic functions that appear in the definition."""

View File

@ -679,7 +679,7 @@ resources:
expected_status='UPDATE_FAILED')
self._stack_delete(stack_identifier)
def test_stack_update_with_conditions(self):
def _test_conditional(self, test3_resource):
"""Update manages new conditions added.
When a new resource is added during updates, the stacks handles the new
@ -691,12 +691,7 @@ resources:
updated_template = copy.deepcopy(test_template_two_resource)
updated_template['conditions'] = {'cond1': True}
updated_template['resources']['test3'] = {
'type': 'OS::Heat::TestResource',
'properties': {
'value': {'if': ['cond1', 'val3', 'val4']}
}
}
updated_template['resources']['test3'] = test3_resource
test2_props = updated_template['resources']['test2']['properties']
test2_props['action_wait_secs'] = {'create': 30}
@ -716,3 +711,22 @@ resources:
return True
self.assertTrue(test.call_until_true(20, 2, check_resources))
def test_stack_update_with_if_conditions(self):
test3 = {
'type': 'OS::Heat::TestResource',
'properties': {
'value': {'if': ['cond1', 'val3', 'val4']}
}
}
self._test_conditional(test3)
def test_stack_update_with_conditions(self):
test3 = {
'type': 'OS::Heat::TestResource',
'condition': 'cond1',
'properties': {
'value': 'foo',
}
}
self._test_conditional(test3)