diff --git a/heat/engine/resources/openstack/heat/resource_group.py b/heat/engine/resources/openstack/heat/resource_group.py index 3351395277..5e81858cd8 100644 --- a/heat/engine/resources/openstack/heat/resource_group.py +++ b/heat/engine/resources/openstack/heat/resource_group.py @@ -76,8 +76,10 @@ class ResourceGroup(stack_resource.StackResource): PROPERTIES = ( COUNT, INDEX_VAR, RESOURCE_DEF, REMOVAL_POLICIES, + REMOVAL_POLICIES_MODE, ) = ( 'count', 'index_var', 'resource_def', 'removal_policies', + 'removal_policies_mode' ) _RESOURCE_DEF_KEYS = ( @@ -92,6 +94,12 @@ class ResourceGroup(stack_resource.StackResource): 'resource_list', ) + _REMOVAL_POLICY_MODES = ( + REMOVAL_POLICY_APPEND, REMOVAL_POLICY_UPDATE + ) = ( + 'append', 'update' + ) + _ROLLING_UPDATES_SCHEMA_KEYS = ( MIN_IN_SERVICE, MAX_BATCH_SIZE, PAUSE_TIME, ) = ( @@ -195,6 +203,18 @@ class ResourceGroup(stack_resource.StackResource): default=[], support_status=support.SupportStatus(version='2015.1') ), + REMOVAL_POLICIES_MODE: properties.Schema( + properties.Schema.STRING, + _('How to handle changes to removal_policies on update. ' + 'The default "append" mode appends to the internal list, ' + '"update" replaces it on update.'), + default=REMOVAL_POLICY_APPEND, + constraints=[ + constraints.AllowedValues(_REMOVAL_POLICY_MODES) + ], + update_allowed=True, + support_status=support.SupportStatus(version='10.0.0') + ), } attributes_schema = { @@ -313,12 +333,18 @@ class ResourceGroup(stack_resource.StackResource): nested = self.nested() # To avoid reusing names after removal, we store a comma-separated - # blacklist in the resource data + # blacklist in the resource data - in cases where you want to + # overwrite the stored data, removal_policies_mode: update can be used current_blacklist = self._current_blacklist() + p_mode = self.properties[self.REMOVAL_POLICIES_MODE] + if p_mode == self.REMOVAL_POLICY_UPDATE: + new_blacklist = [] + else: + new_blacklist = current_blacklist # Now we iterate over the removal policies, and update the blacklist # with any additional names - rsrc_names = set(current_blacklist) + rsrc_names = set(new_blacklist) for r in self.properties[self.REMOVAL_POLICIES]: if self.REMOVAL_RSRC_LIST in r: diff --git a/heat/tests/openstack/heat/test_resource_group.py b/heat/tests/openstack/heat/test_resource_group.py index 4090eefdf6..1ae264355d 100644 --- a/heat/tests/openstack/heat/test_resource_group.py +++ b/heat/tests/openstack/heat/test_resource_group.py @@ -638,26 +638,34 @@ class ResourceGroupBlackList(common.HeatTestCase): scenarios = [ ('1', dict(data_in=None, rm_list=[], nested_rsrcs=[], expected=[], - saved=False)), + saved=False, rm_mode='append')), ('2', dict(data_in='0,1,2', rm_list=[], nested_rsrcs=[], expected=['0', '1', '2'], - saved=False)), + saved=False, rm_mode='append')), ('3', dict(data_in='1,3', rm_list=['6'], nested_rsrcs=['0', '1', '3'], expected=['1', '3'], - saved=False)), + saved=False, rm_mode='append')), ('4', dict(data_in='0,1', rm_list=['id-7'], nested_rsrcs=['0', '1', '3'], expected=['0', '1'], - saved=False)), + saved=False, rm_mode='append')), ('5', dict(data_in='0,1', rm_list=['3'], nested_rsrcs=['0', '1', '3'], expected=['0', '1', '3'], - saved=True)), + saved=True, rm_mode='append')), ('6', dict(data_in='0,1', rm_list=['id-3'], nested_rsrcs=['0', '1', '3'], expected=['0', '1', '3'], - saved=True)), + saved=True, rm_mode='append')), + ('7', dict(data_in='0,1', rm_list=['id-3'], + nested_rsrcs=['0', '1', '3'], + expected=['3'], + saved=True, rm_mode='update')), + ('8', dict(data_in='1', rm_list=[], + nested_rsrcs=['0', '1', '2'], + expected=[], + saved=True, rm_mode='update')), ] def test_blacklist(self): @@ -666,8 +674,9 @@ class ResourceGroupBlackList(common.HeatTestCase): # mock properties resg.properties = mock.MagicMock() - resg.properties.__getitem__.return_value = [ - {'resource_list': self.rm_list}] + p_data = {'removal_policies': [{'resource_list': self.rm_list}], + 'removal_policies_mode': self.rm_mode} + resg.properties.__getitem__.side_effect = p_data.__getitem__ # mock data get/set resg.data = mock.Mock() diff --git a/releasenotes/notes/resource_group_removal_policies_mode-d489e0cc49942e2a.yaml b/releasenotes/notes/resource_group_removal_policies_mode-d489e0cc49942e2a.yaml new file mode 100644 index 0000000000..409065c709 --- /dev/null +++ b/releasenotes/notes/resource_group_removal_policies_mode-d489e0cc49942e2a.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + OS::Heat::ResourceGroup now supports a removal_policies_mode property. + This can be used to optionally select different behavior on update where + you may wish to overwrite vs append to the current policy.