Support adding tags for subnet

Allow to set/update tags for neutron subnet.

Change-Id: I0a21d87a7a5db3864439cc76b9d19a9aece9c8ac
Blueprint: support-add-tags-for-neutron-resources
This commit is contained in:
huangtianhua 2017-04-19 15:00:24 +08:00
parent b6707a3661
commit 6df8b1472a
3 changed files with 39 additions and 5 deletions

View File

@ -38,12 +38,12 @@ class Subnet(neutron.NeutronResource):
NETWORK_ID, NETWORK, SUBNETPOOL, PREFIXLEN, CIDR, NETWORK_ID, NETWORK, SUBNETPOOL, PREFIXLEN, CIDR,
VALUE_SPECS, NAME, IP_VERSION, DNS_NAMESERVERS, GATEWAY_IP, VALUE_SPECS, NAME, IP_VERSION, DNS_NAMESERVERS, GATEWAY_IP,
ENABLE_DHCP, ALLOCATION_POOLS, TENANT_ID, HOST_ROUTES, ENABLE_DHCP, ALLOCATION_POOLS, TENANT_ID, HOST_ROUTES,
IPV6_RA_MODE, IPV6_ADDRESS_MODE, SEGMENT IPV6_RA_MODE, IPV6_ADDRESS_MODE, SEGMENT, TAGS,
) = ( ) = (
'network_id', 'network', 'subnetpool', 'prefixlen', 'cidr', 'network_id', 'network', 'subnetpool', 'prefixlen', 'cidr',
'value_specs', 'name', 'ip_version', 'dns_nameservers', 'gateway_ip', 'value_specs', 'name', 'ip_version', 'dns_nameservers', 'gateway_ip',
'enable_dhcp', 'allocation_pools', 'tenant_id', 'host_routes', 'enable_dhcp', 'allocation_pools', 'tenant_id', 'host_routes',
'ipv6_ra_mode', 'ipv6_address_mode', 'segment' 'ipv6_ra_mode', 'ipv6_address_mode', 'segment', 'tags',
) )
_ALLOCATION_POOL_KEYS = ( _ALLOCATION_POOL_KEYS = (
@ -244,6 +244,13 @@ class Subnet(neutron.NeutronResource):
], ],
support_status=support.SupportStatus(version='9.0.0') support_status=support.SupportStatus(version='9.0.0')
), ),
TAGS: properties.Schema(
properties.Schema.LIST,
_('The tags to be added to the subnet.'),
schema=properties.Schema(properties.Schema.STRING),
update_allowed=True,
support_status=support.SupportStatus(version='9.0.0')
),
} }
attributes_schema = { attributes_schema = {
@ -374,12 +381,19 @@ class Subnet(neutron.NeutronResource):
props['network_id'] = props.pop(self.NETWORK) props['network_id'] = props.pop(self.NETWORK)
if self.SEGMENT in props and props[self.SEGMENT]: if self.SEGMENT in props and props[self.SEGMENT]:
props['segment_id'] = props.pop(self.SEGMENT) props['segment_id'] = props.pop(self.SEGMENT)
tags = props.pop(self.TAGS, [])
if self.SUBNETPOOL in props and props[self.SUBNETPOOL]: if self.SUBNETPOOL in props and props[self.SUBNETPOOL]:
props['subnetpool_id'] = props.pop('subnetpool') props['subnetpool_id'] = props.pop('subnetpool')
self._null_gateway_ip(props) self._null_gateway_ip(props)
subnet = self.client().create_subnet({'subnet': props})['subnet'] subnet = self.client().create_subnet({'subnet': props})['subnet']
self.resource_id_set(subnet['id']) self.resource_id_set(subnet['id'])
if tags:
self.set_tags(tags)
def handle_delete(self): def handle_delete(self):
try: try:
self.client().delete_subnet(self.resource_id) self.client().delete_subnet(self.resource_id)
@ -397,7 +411,9 @@ class Subnet(neutron.NeutronResource):
# If the new value is '', set to None # If the new value is '', set to None
self._null_gateway_ip(prop_diff) self._null_gateway_ip(prop_diff)
if self.TAGS in prop_diff:
tags = prop_diff.pop(self.TAGS)
self.set_tags(tags)
self.client().update_subnet( self.client().update_subnet(
self.resource_id, {'subnet': prop_diff}) self.resource_id, {'subnet': prop_diff})

View File

@ -124,11 +124,14 @@ class NeutronSubnetTest(common.HeatTestCase):
stack) stack)
return rsrc return rsrc
def _setup_mock(self, stack_name=None, use_deprecated_templ=False): def _setup_mock(self, stack_name=None, use_deprecated_templ=False,
tags=None):
if use_deprecated_templ: if use_deprecated_templ:
t = template_format.parse(neutron_template_deprecated) t = template_format.parse(neutron_template_deprecated)
else: else:
t = template_format.parse(neutron_template) t = template_format.parse(neutron_template)
if tags:
t['resources']['sub_net']['properties']['tags'] = tags
stack = utils.parse_stack(t, stack_name=stack_name) stack = utils.parse_stack(t, stack_name=stack_name)
sn = { sn = {
"subnet": { "subnet": {
@ -170,11 +173,12 @@ class NeutronSubnetTest(common.HeatTestCase):
'host_routes': [{'destination': '192.168.1.0/24', 'host_routes': [{'destination': '192.168.1.0/24',
'nexthop': '194.168.1.2'}], 'nexthop': '194.168.1.2'}],
'gateway_ip': '10.0.3.105', 'gateway_ip': '10.0.3.105',
'tags': ['tag2', 'tag3'],
'allocation_pools': [ 'allocation_pools': [
{'start': '10.0.3.20', 'end': '10.0.3.100'}, {'start': '10.0.3.20', 'end': '10.0.3.100'},
{'start': '10.0.3.110', 'end': '10.0.3.200'}]}} {'start': '10.0.3.110', 'end': '10.0.3.200'}]}}
t, stack = self._setup_mock() t, stack = self._setup_mock(tags=['tag1', 'tag2'])
create_props = {'subnet': { create_props = {'subnet': {
'name': utils.PhysName(stack.name, 'test_subnet'), 'name': utils.PhysName(stack.name, 'test_subnet'),
'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766', 'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
@ -190,10 +194,16 @@ class NeutronSubnetTest(common.HeatTestCase):
self.patchobject(stack['net'], 'FnGetRefId', self.patchobject(stack['net'], 'FnGetRefId',
return_value='fc68ea2c-b60b-4b4f-bd82-94ec81110766') return_value='fc68ea2c-b60b-4b4f-bd82-94ec81110766')
set_tag_mock = self.patchobject(neutronclient.Client, 'replace_tag')
rsrc = self.create_subnet(t, stack, 'sub_net') rsrc = self.create_subnet(t, stack, 'sub_net')
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.create_mock.assert_called_once_with(create_props) self.create_mock.assert_called_once_with(create_props)
set_tag_mock.assert_called_once_with(
'subnets',
rsrc.resource_id,
{'tags': ['tag1', 'tag2']}
)
rsrc.validate() rsrc.validate()
ref_id = rsrc.FnGetRefId() ref_id = rsrc.FnGetRefId()
self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id) self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
@ -213,6 +223,11 @@ class NeutronSubnetTest(common.HeatTestCase):
self.update_mock.assert_called_once_with( self.update_mock.assert_called_once_with(
'91e47a57-7508-46fe-afc9-fc454e8580e1', '91e47a57-7508-46fe-afc9-fc454e8580e1',
update_props) update_props)
set_tag_mock.assert_called_with(
'subnets',
rsrc.resource_id,
{'tags': ['tag2', 'tag3']}
)
# with name None # with name None
del update_props['subnet']['name'] del update_props['subnet']['name']
rsrc.handle_update(update_snippet, {}, update_props['subnet']) rsrc.handle_update(update_snippet, {}, update_props['subnet'])

View File

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