diff --git a/nova/network/floating_ips.py b/nova/network/floating_ips.py index 3f0a7ed95341..1f3e076bc80f 100644 --- a/nova/network/floating_ips.py +++ b/nova/network/floating_ips.py @@ -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: diff --git a/nova/tests/unit/api/ec2/test_cloud.py b/nova/tests/unit/api/ec2/test_cloud.py index 113af8c96ccd..01a96a1bbb45 100644 --- a/nova/tests/unit/api/ec2/test_cloud.py +++ b/nova/tests/unit/api/ec2/test_cloud.py @@ -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) diff --git a/nova/tests/unit/network/test_manager.py b/nova/tests/unit/network/test_manager.py index bb120251acaf..4e3390761649 100644 --- a/nova/tests/unit/network/test_manager.py +++ b/nova/tests/unit/network/test_manager.py @@ -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.""" diff --git a/nova/tests/unit/test_quota.py b/nova/tests/unit/test_quota.py index b53492ca4727..41bca1b3c916 100644 --- a/nova/tests/unit/test_quota.py +++ b/nova/tests/unit/test_quota.py @@ -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,