From: Dane LeBlanc Date: Wed, 19 Feb 2014 20:53:18 +0000 (-0500) Subject: Delete subnet fails if assoc port has IPs from another subnet X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=f50df8eb3c5bf38abbb0389b85c4b628cffb59f4;p=openstack-build%2Fneutron-build.git Delete subnet fails if assoc port has IPs from another subnet This change fixes the following failure scenario: - Create a network - Create two subnets on the network - Create a port on the network using one of the subnets - Delete the other subnet = = = > FAILURE: Subnet delete fails because supposedly there is/are port(s) still associated with that subnet. The problem addressed is that delete_subnet() in neutron/db/db_base_plugin.py is checking for port(s) still being associated with the subnet's network, not the subnet itself. Change-Id: I7adbe18cce412135b2e42dcb7c592e60c1ec5f8f Closes-Bug: #1281694 --- diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py index f96edf9b0..a1e72c90b 100644 --- a/neutron/db/db_base_plugin_v2.py +++ b/neutron/db/db_base_plugin_v2.py @@ -1235,10 +1235,11 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, with context.session.begin(subtransactions=True): subnet = self._get_subnet(context, id) # Check if any tenant owned ports are using this subnet - allocated_qry = context.session.query(models_v2.IPAllocation) - allocated_qry = allocated_qry.join(models_v2.Port) - allocated = allocated_qry.filter_by( - network_id=subnet.network_id).with_lockmode('update') + allocated = (context.session.query(models_v2.IPAllocation). + filter_by(subnet_id=subnet['id']). + join(models_v2.Port). + filter_by(network_id=subnet['network_id']). + with_lockmode('update')) # remove network owned ports for a in allocated: diff --git a/neutron/tests/unit/test_db_plugin.py b/neutron/tests/unit/test_db_plugin.py index 88e158ba2..11680269e 100644 --- a/neutron/tests/unit/test_db_plugin.py +++ b/neutron/tests/unit/test_db_plugin.py @@ -2430,6 +2430,22 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase): msg = str(q_exc.SubnetInUse(subnet_id=id)) self.assertEqual(data['NeutronError']['message'], msg) + def test_delete_subnet_with_other_subnet_on_network_still_in_use(self): + with self.network() as network: + with contextlib.nested( + self.subnet(network=network), + self.subnet(network=network, cidr='10.0.1.0/24', + do_delete=False)) as (subnet1, subnet2): + subnet1_id = subnet1['subnet']['id'] + subnet2_id = subnet2['subnet']['id'] + with self.port( + subnet=subnet1, + fixed_ips=[{'subnet_id': subnet1_id}]): + req = self.new_delete_request('subnets', subnet2_id) + res = req.get_response(self.api) + self.assertEqual(res.status_int, + webob.exc.HTTPNoContent.code) + def test_delete_network(self): gateway_ip = '10.0.0.1' cidr = '10.0.0.0/24'