Merge "Make allocation_pools attribute of subnet updateable by PUT"

This commit is contained in:
Jenkins 2014-06-10 02:27:50 +00:00 committed by Gerrit Code Review
commit 979b13a452
5 changed files with 86 additions and 14 deletions

View File

@ -704,8 +704,7 @@ RESOURCE_ATTRIBUTE_MAP = {
'default': ATTR_NOT_SPECIFIED,
'validate': {'type:ip_address_or_none': None},
'is_visible': True},
#TODO(salvatore-orlando): Enable PUT on allocation_pools
'allocation_pools': {'allow_post': True, 'allow_put': False,
'allocation_pools': {'allow_post': True, 'allow_put': True,
'default': ATTR_NOT_SPECIFIED,
'validate': {'type:ip_pools': None},
'is_visible': True},

View File

@ -1213,6 +1213,21 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
return self._make_subnet_dict(subnet)
def _update_subnet_allocation_pools(self, context, id, s):
context.session.query(models_v2.IPAllocationPool).filter_by(
subnet_id=id).delete()
new_pools = [models_v2.IPAllocationPool(
first_ip=p['start'], last_ip=p['end'],
subnet_id=id) for p in s['allocation_pools']]
context.session.add_all(new_pools)
NeutronDbPluginV2._rebuild_availability_ranges(context, [s])
#Gather new pools for result:
result_pools = [{'start': pool['start'],
'end': pool['end']}
for pool in s['allocation_pools']]
del s['allocation_pools']
return result_pools
def update_subnet(self, context, id, subnet):
"""Update the subnet with new info.
@ -1222,6 +1237,7 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
s = subnet['subnet']
changed_host_routes = False
changed_dns = False
changed_allocation_pools = False
db_subnet = self._get_subnet(context, id)
# Fill 'ip_version' and 'allocation_pools' fields with the current
# value since _validate_subnet() expects subnet spec has 'ip_version'
@ -1288,6 +1304,12 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
'nexthop': route_str.partition("_")[2]})
del s["host_routes"]
if "allocation_pools" in s:
self._validate_allocation_pools(s['allocation_pools'],
s['cidr'])
changed_allocation_pools = True
new_pools = self._update_subnet_allocation_pools(context,
id, s)
subnet = self._get_subnet(context, id)
subnet.update(s)
result = self._make_subnet_dict(subnet)
@ -1296,6 +1318,8 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
result['dns_nameservers'] = new_dns
if changed_host_routes:
result['host_routes'] = new_routes
if changed_allocation_pools:
result['allocation_pools'] = new_pools
return result
def delete_subnet(self, context, id):

View File

@ -79,7 +79,7 @@ class IPAllocationPool(model_base.BASEV2, HasId):
available_ranges = orm.relationship(IPAvailabilityRange,
backref='ipallocationpool',
lazy="joined",
cascade='delete')
cascade='all, delete-orphan')
def __repr__(self):
return "%s - %s" % (self.first_ip, self.last_ip)

View File

@ -81,18 +81,17 @@ class TestPlumgridPluginPortsV2(test_plugin.TestPortsV2,
class TestPlumgridPluginSubnetsV2(test_plugin.TestSubnetsV2,
PLUMgridPluginV2TestCase):
def test_create_subnet_default_gw_conflict_allocation_pool_returns_409(
self):
self.skipTest("Plugin does not support Neutron allocation process")
_unsupported = (
'test_create_subnet_default_gw_conflict_allocation_pool_returns_409',
'test_create_subnet_defaults', 'test_create_subnet_gw_values',
'test_update_subnet_gateway_in_allocation_pool_returns_409',
'test_update_subnet_allocation_pools',
'test_update_subnet_allocation_pools_invalid_pool_for_cidr')
def test_create_subnet_defaults(self):
self.skipTest("Plugin does not support Neutron allocation process")
def test_create_subnet_gw_values(self):
self.skipTest("Plugin does not support Neutron allocation process")
def test_update_subnet_gateway_in_allocation_pool_returns_409(self):
self.skipTest("Plugin does not support Neutron allocation process")
def setUp(self):
if self._testMethodName in self._unsupported:
self.skipTest("Plugin does not support Neutron allocation process")
super(TestPlumgridPluginSubnetsV2, self).setUp()
class TestPlumgridPluginPortBinding(PLUMgridPluginV2TestCase,

View File

@ -3333,6 +3333,56 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
self.assertEqual(res.status_int,
webob.exc.HTTPClientError.code)
def test_update_subnet_allocation_pools(self):
"""Test that we can successfully update with sane params.
This will create a subnet with specified allocation_pools
Then issue an update (PUT) to update these using correct
(i.e. non erroneous) params. Finally retrieve the updated
subnet and verify.
"""
allocation_pools = [{'start': '192.168.0.2', 'end': '192.168.0.254'}]
with self.network() as network:
with self.subnet(network=network,
allocation_pools=allocation_pools,
cidr='192.168.0.0/24') as subnet:
data = {'subnet': {'allocation_pools': [
{'start': '192.168.0.10', 'end': '192.168.0.20'},
{'start': '192.168.0.30', 'end': '192.168.0.40'}]}}
req = self.new_update_request('subnets', data,
subnet['subnet']['id'])
#check res code but then do GET on subnet for verification
res = req.get_response(self.api)
self.assertEqual(res.status_code, 200)
req = self.new_show_request('subnets', subnet['subnet']['id'],
self.fmt)
res = self.deserialize(self.fmt, req.get_response(self.api))
self.assertEqual(len(res['subnet']['allocation_pools']), 2)
res_vals = res['subnet']['allocation_pools'][0].values() +\
res['subnet']['allocation_pools'][1].values()
for pool_val in ['10', '20', '30', '40']:
self.assertTrue('192.168.0.%s' % (pool_val) in res_vals)
#updating alloc pool to something outside subnet.cidr
def test_update_subnet_allocation_pools_invalid_pool_for_cidr(self):
"""Test update alloc pool to something outside subnet.cidr.
This makes sure that an erroneous allocation_pool specified
in a subnet update (outside subnet cidr) will result in an error.
"""
allocation_pools = [{'start': '192.168.0.2', 'end': '192.168.0.254'}]
with self.network() as network:
with self.subnet(network=network,
allocation_pools=allocation_pools,
cidr='192.168.0.0/24') as subnet:
data = {'subnet': {'allocation_pools': [
{'start': '10.0.0.10', 'end': '10.0.0.20'}]}}
req = self.new_update_request('subnets', data,
subnet['subnet']['id'])
res = req.get_response(self.api)
self.assertEqual(res.status_int,
webob.exc.HTTPClientError.code)
def test_show_subnet(self):
with self.network() as network:
with self.subnet(network=network) as subnet: