diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py index 241063c41..932d5c08a 100644 --- a/neutron/db/db_base_plugin_v2.py +++ b/neutron/db/db_base_plugin_v2.py @@ -362,9 +362,9 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, pool_id = allocation_pool['id'] break if not pool_id: - error_message = _("No allocation pool found for " - "ip address:%s") % ip_address - raise q_exc.InvalidInput(error_message=error_message) + NeutronDbPluginV2._delete_ip_allocation( + context, network_id, subnet_id, ip_address) + return # Two requests will be done on the database. The first will be to # search if an entry starts with ip_address + 1 (r1). The second # will be to see if an entry ends with ip_address -1 (r2). diff --git a/neutron/tests/unit/test_db_plugin.py b/neutron/tests/unit/test_db_plugin.py index a33707d61..668ce5388 100644 --- a/neutron/tests/unit/test_db_plugin.py +++ b/neutron/tests/unit/test_db_plugin.py @@ -1706,6 +1706,28 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s self.assertEqual(q.count(), 1) + def test_recycle_ip_address_without_allocation_pool(self): + plugin = NeutronManager.get_plugin() + allocation_pools = [{"start": '10.0.0.10', + "end": '10.0.0.50'}] + with self.subnet(cidr='10.0.0.0/24', + allocation_pools=allocation_pools) as subnet: + network_id = subnet['subnet']['network_id'] + subnet_id = subnet['subnet']['id'] + fixed_ips = [{"subnet_id": subnet_id, + "ip_address": '10.0.0.100'}] + with self.port(subnet=subnet, fixed_ips=fixed_ips) as port: + update_context = context.Context('', port['port']['tenant_id']) + ip_address = port['port']['fixed_ips'][0]['ip_address'] + plugin._recycle_ip(update_context, + network_id, + subnet_id, + ip_address) + + q = update_context.session.query(models_v2.IPAllocation) + q = q.filter_by(subnet_id=subnet_id) + self.assertEqual(q.count(), 0) + def test_recycle_held_ip_address(self): plugin = NeutronManager.get_plugin() with self.subnet() as subnet: