Add removal_policies_mode to ResourceGroup

This enables choice over the current behavior which is to always append
to the resource data blacklist, or overwrite it (which is sometimes needed
e.g if you decide you want to reuse that group index)

The default behavior is unchanged, but the new behavior can be selected
via the "update" value.

Change-Id: I1157627b07d98dd079657c320ad783a3ba5bce81
Closes-Bug: #1741053
This commit is contained in:
Steven Hardy 2018-01-03 14:22:52 +00:00
parent 5aa603bb2b
commit 7a42ec8657
3 changed files with 51 additions and 10 deletions

View File

@ -76,8 +76,10 @@ class ResourceGroup(stack_resource.StackResource):
PROPERTIES = ( PROPERTIES = (
COUNT, INDEX_VAR, RESOURCE_DEF, REMOVAL_POLICIES, COUNT, INDEX_VAR, RESOURCE_DEF, REMOVAL_POLICIES,
REMOVAL_POLICIES_MODE,
) = ( ) = (
'count', 'index_var', 'resource_def', 'removal_policies', 'count', 'index_var', 'resource_def', 'removal_policies',
'removal_policies_mode'
) )
_RESOURCE_DEF_KEYS = ( _RESOURCE_DEF_KEYS = (
@ -92,6 +94,12 @@ class ResourceGroup(stack_resource.StackResource):
'resource_list', 'resource_list',
) )
_REMOVAL_POLICY_MODES = (
REMOVAL_POLICY_APPEND, REMOVAL_POLICY_UPDATE
) = (
'append', 'update'
)
_ROLLING_UPDATES_SCHEMA_KEYS = ( _ROLLING_UPDATES_SCHEMA_KEYS = (
MIN_IN_SERVICE, MAX_BATCH_SIZE, PAUSE_TIME, MIN_IN_SERVICE, MAX_BATCH_SIZE, PAUSE_TIME,
) = ( ) = (
@ -195,6 +203,18 @@ class ResourceGroup(stack_resource.StackResource):
default=[], default=[],
support_status=support.SupportStatus(version='2015.1') 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 = { attributes_schema = {
@ -313,12 +333,18 @@ class ResourceGroup(stack_resource.StackResource):
nested = self.nested() nested = self.nested()
# To avoid reusing names after removal, we store a comma-separated # 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() 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 # Now we iterate over the removal policies, and update the blacklist
# with any additional names # with any additional names
rsrc_names = set(current_blacklist) rsrc_names = set(new_blacklist)
for r in self.properties[self.REMOVAL_POLICIES]: for r in self.properties[self.REMOVAL_POLICIES]:
if self.REMOVAL_RSRC_LIST in r: if self.REMOVAL_RSRC_LIST in r:

View File

@ -638,26 +638,34 @@ class ResourceGroupBlackList(common.HeatTestCase):
scenarios = [ scenarios = [
('1', dict(data_in=None, rm_list=[], ('1', dict(data_in=None, rm_list=[],
nested_rsrcs=[], expected=[], nested_rsrcs=[], expected=[],
saved=False)), saved=False, rm_mode='append')),
('2', dict(data_in='0,1,2', rm_list=[], ('2', dict(data_in='0,1,2', rm_list=[],
nested_rsrcs=[], expected=['0', '1', '2'], nested_rsrcs=[], expected=['0', '1', '2'],
saved=False)), saved=False, rm_mode='append')),
('3', dict(data_in='1,3', rm_list=['6'], ('3', dict(data_in='1,3', rm_list=['6'],
nested_rsrcs=['0', '1', '3'], nested_rsrcs=['0', '1', '3'],
expected=['1', '3'], expected=['1', '3'],
saved=False)), saved=False, rm_mode='append')),
('4', dict(data_in='0,1', rm_list=['id-7'], ('4', dict(data_in='0,1', rm_list=['id-7'],
nested_rsrcs=['0', '1', '3'], nested_rsrcs=['0', '1', '3'],
expected=['0', '1'], expected=['0', '1'],
saved=False)), saved=False, rm_mode='append')),
('5', dict(data_in='0,1', rm_list=['3'], ('5', dict(data_in='0,1', rm_list=['3'],
nested_rsrcs=['0', '1', '3'], nested_rsrcs=['0', '1', '3'],
expected=['0', '1', '3'], expected=['0', '1', '3'],
saved=True)), saved=True, rm_mode='append')),
('6', dict(data_in='0,1', rm_list=['id-3'], ('6', dict(data_in='0,1', rm_list=['id-3'],
nested_rsrcs=['0', '1', '3'], nested_rsrcs=['0', '1', '3'],
expected=['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): def test_blacklist(self):
@ -666,8 +674,9 @@ class ResourceGroupBlackList(common.HeatTestCase):
# mock properties # mock properties
resg.properties = mock.MagicMock() resg.properties = mock.MagicMock()
resg.properties.__getitem__.return_value = [ p_data = {'removal_policies': [{'resource_list': self.rm_list}],
{'resource_list': self.rm_list}] 'removal_policies_mode': self.rm_mode}
resg.properties.__getitem__.side_effect = p_data.__getitem__
# mock data get/set # mock data get/set
resg.data = mock.Mock() resg.data = mock.Mock()

View File

@ -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.