Check for floating IP pool in nova-network

There are no checks in nova-network to see if a specified
floating IP pool exists or not before attempting to allocate
an IP address. If a pool does not exist, nova throws an
unrelated error - 'No more floating ips available'. The
following patch adds a check for the existence of the IP pool
and throws a FloatingIpPoolNotFound if it is not found.

Change-Id: I72cb8dd044f7ac094287bad7df9167b8e77a4b5b
Related-Bug: #1355623
This commit is contained in:
Thang Pham 2014-09-10 17:15:40 -04:00
parent 16d38947ae
commit b13be2cd56
4 changed files with 36 additions and 1 deletions

View File

@ -202,6 +202,17 @@ class FloatingIP(object):
'project': context.project_id})
raise exception.Forbidden()
def _floating_ip_pool_exists(self, context, name):
"""Returns true if the specified floating ip pool exists. Otherwise,
returns false.
"""
pools = [pool.get('name') for pool in
self.get_floating_ip_pools(context)]
if name in pools:
return True
return False
def allocate_floating_ip(self, context, project_id, auto_assigned=False,
pool=None):
"""Gets a floating ip from the pool."""
@ -209,6 +220,9 @@ class FloatingIP(object):
pool = pool or CONF.default_floating_pool
use_quota = not auto_assigned
if not self._floating_ip_pool_exists(context, pool):
raise exception.FloatingIpPoolNotFound()
# Check the quota; can't put this in the API because we get
# called into from other places
try:

View File

@ -293,7 +293,11 @@ class CloudTestCase(test.TestCase):
'pool': 'nova'})
self.assertEqual(allocate(self.context)['publicIp'], address)
db.floating_ip_destroy(self.context, address)
self.assertRaises(exception.NoMoreFloatingIps,
# There are no longer any pools since the last one was destroyed above
pools = db.floating_ip_get_pools(self.context)
self.assertEqual(0, len(pools))
self.assertRaises(exception.FloatingIpPoolNotFound,
allocate,
self.context)

View File

@ -1275,6 +1275,9 @@ class VlanNetworkTestCase(test.TestCase):
ctxt = context.RequestContext('testuser', 'testproject',
is_admin=False)
self.stubs.Set(self.network, '_floating_ip_pool_exists',
lambda _x, _y: True)
def fake_allocate_address(*args, **kwargs):
return {'address': '10.0.0.1', 'project_id': ctxt.project_id}
@ -3325,6 +3328,18 @@ class FloatingIPTestCase(test.TestCase):
self.context, mock.sentinel.address))
mock_get.assert_called_once_with(self.context, mock.sentinel.address)
@mock.patch('nova.db.floating_ip_get_pools')
def test_floating_ip_pool_exists(self, floating_ip_get_pools):
floating_ip_get_pools.return_value = [{'name': 'public'}]
self.assertTrue(self.network._floating_ip_pool_exists(self.context,
'public'))
@mock.patch('nova.db.floating_ip_get_pools')
def test_floating_ip_pool_does_not_exist(self, floating_ip_get_pools):
floating_ip_get_pools.return_value = []
self.assertFalse(self.network._floating_ip_pool_exists(self.context,
'public'))
class InstanceDNSTestCase(test.TestCase):
"""Tests nova.network.manager instance DNS."""

View File

@ -120,6 +120,7 @@ class QuotaIntegrationTestCase(test.TestCase):
address = '192.168.0.100'
db.floating_ip_create(context.get_admin_context(),
{'address': address,
'pool': 'nova',
'project_id': self.project_id})
self.assertRaises(exception.QuotaError,
self.network.allocate_floating_ip,
@ -131,6 +132,7 @@ class QuotaIntegrationTestCase(test.TestCase):
address = '192.168.0.100'
db.floating_ip_create(context.get_admin_context(),
{'address': address,
'pool': 'nova',
'project_id': self.project_id})
# auto allocated addresses should not be counted
self.assertRaises(exception.NoMoreFloatingIps,