Change the exception type from ValueError to IpamValueInvalid

The current ValueError in _validate_with_subnet will return an unfriendly
"Internal Server Error" to user who wrong configured the subnet and pool. This
patch introduces a new exception IpamValueInvalid and it will be mapped to an
meaningful webob exception.

Closes-Bug: #1531401

Change-Id: Ib50a4b3cd1881a0c364d354728fc43040c3ed520
This commit is contained in:
Yalei Wang 2016-01-06 17:07:31 +08:00
parent 3fb153b15b
commit 8da632a22d
4 changed files with 34 additions and 9 deletions

View File

@ -69,3 +69,9 @@ class IPAllocationFailed(exceptions.NeutronException):
class IpamAvailabilityRangeNoChanges(exceptions.NeutronException):
message = _("New value for first_ip or last_ip has to be specified.")
class IpamValueInvalid(exceptions.Conflict):
def __init__(self, message=None):
self.message = message
super(IpamValueInvalid, self).__init__()

View File

@ -110,16 +110,18 @@ class SubnetRequest(object):
if (gw_ip.version == 4 or (gw_ip.version == 6
and not gw_ip.is_link_local())):
if self.gateway_ip not in subnet_cidr:
raise ValueError(_("gateway_ip is not in the subnet"))
raise ipam_exc.IpamValueInvalid(_(
"gateway_ip %s is not in the subnet") %
self.gateway_ip)
if self.allocation_pools:
if subnet_cidr.version != self.allocation_pools[0].version:
raise ValueError(_("allocation_pools use the wrong ip "
"version"))
raise ipam_exc.IpamValueInvalid(_(
"allocation_pools use the wrong ip version"))
for pool in self.allocation_pools:
if pool not in subnet_cidr:
raise ValueError(_("allocation_pools are not in the "
"subnet"))
raise ipam_exc.IpamValueInvalid(_(
"allocation_pools are not in the subnet"))
class AnySubnetRequest(SubnetRequest):

View File

@ -5560,6 +5560,23 @@ class TestSubnetPoolsV2(NeutronDbPluginV2TestCase):
res = self.deserialize(self.fmt, req.get_response(self.api))
self.assertEqual(1, res['subnetpool']['default_quota'])
def test_allocate_subnet_bad_gateway(self):
with self.network() as network:
sp = self._test_create_subnetpool(['10.10.0.0/8'],
tenant_id=self._tenant_id,
name=self._POOL_NAME,
default_prefixlen='24')
# Request a subnet allocation (no CIDR)
data = {'subnet': {'network_id': network['network']['id'],
'subnetpool_id': sp['subnetpool']['id'],
'prefixlen': 32,
'ip_version': 4,
'tenant_id': network['network']['tenant_id']}}
req = self.new_create_request('subnets', data)
result = req.get_response(self.api)
self.assertEqual(409, result.status_int)
def test_allocate_any_subnet_with_prefixlen(self):
with self.network() as network:
sp = self._test_create_subnetpool(['10.10.0.0/16'],

View File

@ -134,7 +134,7 @@ class TestIpamAnySubnetRequest(IpamSubnetRequestTestCase):
def test_subnet_request_bad_gateway(self):
cfg.CONF.set_override('force_gateway_on_subnet', True)
self.assertRaises(ValueError,
self.assertRaises(ipam_exc.IpamValueInvalid,
ipam_req.AnySubnetRequest,
self.tenant_id,
self.subnet_id,
@ -153,7 +153,7 @@ class TestIpamAnySubnetRequest(IpamSubnetRequestTestCase):
def test_subnet_request_allocation_pool_wrong_version(self):
pools = [netaddr.IPRange('0.0.0.4', '0.0.0.5')]
self.assertRaises(ValueError,
self.assertRaises(ipam_exc.IpamValueInvalid,
ipam_req.AnySubnetRequest,
self.tenant_id,
self.subnet_id,
@ -163,7 +163,7 @@ class TestIpamAnySubnetRequest(IpamSubnetRequestTestCase):
def test_subnet_request_allocation_pool_not_in_net(self):
pools = [netaddr.IPRange('0.0.0.64', '0.0.0.128')]
self.assertRaises(ValueError,
self.assertRaises(ipam_exc.IpamValueInvalid,
ipam_req.AnySubnetRequest,
self.tenant_id,
self.subnet_id,
@ -185,7 +185,7 @@ class TestIpamSpecificSubnetRequest(IpamSubnetRequestTestCase):
def test_subnet_request_bad_gateway(self):
cfg.CONF.set_override('force_gateway_on_subnet', True)
self.assertRaises(ValueError,
self.assertRaises(ipam_exc.IpamValueInvalid,
ipam_req.SpecificSubnetRequest,
self.tenant_id,
self.subnet_id,