Support set tags for neutron subnetpool

Allow to set/update tags for neutron subnetpool.

Change-Id: I772123d2c17e8773eb98fc3c64370c6a2d7125e5
Blueprint: support-add-tags-for-neutron-resources
This commit is contained in:
huangtianhua 2017-04-19 15:37:55 +08:00
parent 6df8b1472a
commit da0167d9d7
3 changed files with 44 additions and 4 deletions

View File

@ -36,11 +36,11 @@ class SubnetPool(neutron.NeutronResource):
PROPERTIES = ( PROPERTIES = (
NAME, PREFIXES, ADDRESS_SCOPE, DEFAULT_QUOTA, NAME, PREFIXES, ADDRESS_SCOPE, DEFAULT_QUOTA,
DEFAULT_PREFIXLEN, MIN_PREFIXLEN, MAX_PREFIXLEN, DEFAULT_PREFIXLEN, MIN_PREFIXLEN, MAX_PREFIXLEN,
IS_DEFAULT, TENANT_ID, SHARED, IS_DEFAULT, TENANT_ID, SHARED, TAGS,
) = ( ) = (
'name', 'prefixes', 'address_scope', 'default_quota', 'name', 'prefixes', 'address_scope', 'default_quota',
'default_prefixlen', 'min_prefixlen', 'max_prefixlen', 'default_prefixlen', 'min_prefixlen', 'max_prefixlen',
'is_default', 'tenant_id', 'shared', 'is_default', 'tenant_id', 'shared', 'tags',
) )
properties_schema = { properties_schema = {
@ -121,6 +121,13 @@ class SubnetPool(neutron.NeutronResource):
'attribute to administrative users only.'), 'attribute to administrative users only.'),
default=False, default=False,
), ),
TAGS: properties.Schema(
properties.Schema.LIST,
_('The tags to be added to the subnetpool.'),
schema=properties.Schema(properties.Schema.STRING),
update_allowed=True,
support_status=support.SupportStatus(version='9.0.0')
),
} }
def validate(self): def validate(self):
@ -177,10 +184,14 @@ class SubnetPool(neutron.NeutronResource):
props['address_scope_id'] = self.client_plugin( props['address_scope_id'] = self.client_plugin(
).find_resourceid_by_name_or_id( ).find_resourceid_by_name_or_id(
'address_scope', props.pop(self.ADDRESS_SCOPE)) 'address_scope', props.pop(self.ADDRESS_SCOPE))
tags = props.pop(self.TAGS, [])
subnetpool = self.client().create_subnetpool( subnetpool = self.client().create_subnetpool(
{'subnetpool': props})['subnetpool'] {'subnetpool': props})['subnetpool']
self.resource_id_set(subnetpool['id']) self.resource_id_set(subnetpool['id'])
if tags:
self.set_tags(tags)
def handle_delete(self): def handle_delete(self):
if self.resource_id is not None: if self.resource_id is not None:
with self.client_plugin().ignore_not_found: with self.client_plugin().ignore_not_found:
@ -200,6 +211,9 @@ class SubnetPool(neutron.NeutronResource):
else: else:
prop_diff[ prop_diff[
'address_scope_id'] = prop_diff.pop(self.ADDRESS_SCOPE) 'address_scope_id'] = prop_diff.pop(self.ADDRESS_SCOPE)
if self.TAGS in prop_diff:
tags = prop_diff.pop(self.TAGS)
self.set_tags(tags)
if prop_diff: if prop_diff:
self.prepare_update_properties(prop_diff) self.prepare_update_properties(prop_diff)
self.client().update_subnetpool( self.client().update_subnetpool(

View File

@ -37,8 +37,10 @@ class NeutronSubnetPoolTest(common.HeatTestCase):
'find_resourceid_by_name_or_id', 'find_resourceid_by_name_or_id',
return_value='new_test') return_value='new_test')
def create_subnetpool(self, status='COMPLETE'): def create_subnetpool(self, status='COMPLETE', tags=None):
self.t = template_format.parse(inline_templates.SPOOL_TEMPLATE) self.t = template_format.parse(inline_templates.SPOOL_TEMPLATE)
if tags:
self.t['resources']['sub_pool']['properties']['tags'] = tags
self.stack = utils.parse_stack(self.t) self.stack = utils.parse_stack(self.t)
resource_defns = self.stack.t.resource_definitions(self.stack) resource_defns = self.stack.t.resource_definitions(self.stack)
rsrc = subnetpool.SubnetPool('sub_pool', resource_defns['sub_pool'], rsrc = subnetpool.SubnetPool('sub_pool', resource_defns['sub_pool'],
@ -61,6 +63,10 @@ class NeutronSubnetPoolTest(common.HeatTestCase):
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, status), rsrc.state) self.assertEqual((rsrc.CREATE, status), rsrc.state)
if tags:
self.set_tag_mock.assert_called_once_with('subnetpools',
rsrc.resource_id,
{'tags': tags})
return rsrc return rsrc
def test_validate_prefixlen_min_gt_max(self): def test_validate_prefixlen_min_gt_max(self):
@ -113,6 +119,14 @@ class NeutronSubnetPoolTest(common.HeatTestCase):
ref_id = rsrc.FnGetRefId() ref_id = rsrc.FnGetRefId()
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id) self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
def test_create_subnetpool_with_tags(self):
tags = ['for_test']
self.set_tag_mock = self.patchobject(neutronclient.Client,
'replace_tag')
rsrc = self.create_subnetpool(tags=tags)
ref_id = rsrc.FnGetRefId()
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
def test_create_subnetpool_failed(self): def test_create_subnetpool_failed(self):
self.create_subnetpool('FAILED') self.create_subnetpool('FAILED')
@ -144,11 +158,15 @@ class NeutronSubnetPoolTest(common.HeatTestCase):
def test_update_subnetpool(self): def test_update_subnetpool(self):
update_subnetpool = self.patchobject(neutronclient.Client, update_subnetpool = self.patchobject(neutronclient.Client,
'update_subnetpool') 'update_subnetpool')
rsrc = self.create_subnetpool() self.set_tag_mock = self.patchobject(neutronclient.Client,
'replace_tag')
old_tags = ['old_tag']
rsrc = self.create_subnetpool(tags=old_tags)
self.patchobject(rsrc, 'physical_resource_name', self.patchobject(rsrc, 'physical_resource_name',
return_value='the_new_sp') return_value='the_new_sp')
ref_id = rsrc.FnGetRefId() ref_id = rsrc.FnGetRefId()
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id) self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
new_tags = ['new_tag']
props = { props = {
'name': 'the_new_sp', 'name': 'the_new_sp',
'prefixes': [ 'prefixes': [
@ -160,6 +178,7 @@ class NeutronSubnetPoolTest(common.HeatTestCase):
'min_prefixlen': '24', 'min_prefixlen': '24',
'max_prefixlen': '28', 'max_prefixlen': '28',
'is_default': False, 'is_default': False,
'tags': new_tags
} }
update_dict = props.copy() update_dict = props.copy()
update_dict['name'] = 'the_new_sp' update_dict['name'] = 'the_new_sp'
@ -168,12 +187,16 @@ class NeutronSubnetPoolTest(common.HeatTestCase):
props) props)
# with name # with name
self.assertIsNone(rsrc.handle_update(update_snippet, {}, props)) self.assertIsNone(rsrc.handle_update(update_snippet, {}, props))
self.set_tag_mock.assert_called_with('subnetpools',
rsrc.resource_id,
{'tags': new_tags})
# without name # without name
props['name'] = None props['name'] = None
self.assertIsNone(rsrc.handle_update(update_snippet, {}, props)) self.assertIsNone(rsrc.handle_update(update_snippet, {}, props))
self.assertEqual(2, update_subnetpool.call_count) self.assertEqual(2, update_subnetpool.call_count)
update_dict.pop('tags')
update_subnetpool.assert_called_with( update_subnetpool.assert_called_with(
'fc68ea2c-b60b-4b4f-bd82-94ec81110766', 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
{'subnetpool': update_dict}) {'subnetpool': update_dict})

View File

@ -0,0 +1,3 @@
---
features:
- Allow to set or update the tags for OS::Neutron::SubnetPool resource.