From 36e64afd4494d7c73bccb230ba1c4a97752b5751 Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Wed, 4 Jul 2012 06:54:10 -0400 Subject: [PATCH] Address problems with foreign keys with subnet and network deletion This also fixes bug 1020879 and bug 1020847 Change-Id: Ib68f9357ed65f35e56d17577b83fabe8f96388cf --- quantum/db/db_base_plugin_v2.py | 3 -- quantum/db/models_v2.py | 15 ++++++---- .../plugins/linuxbridge/lb_quantum_plugin.py | 2 +- quantum/tests/unit/test_db_plugin.py | 28 +++++++++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/quantum/db/db_base_plugin_v2.py b/quantum/db/db_base_plugin_v2.py index f894405efb..e834cdf666 100644 --- a/quantum/db/db_base_plugin_v2.py +++ b/quantum/db/db_base_plugin_v2.py @@ -704,9 +704,6 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2): allocated = allocated_qry.filter_by(subnet_id=id).all() if allocated: raise q_exc.SubnetInUse(subnet_id=id) - # Delete IP Allocations on subnet - range_qry = context.session.query(models_v2.IPAllocationRange) - range_qry.filter_by(subnet_id=id).delete() context.session.delete(subnet) def get_subnet(self, context, id, fields=None, verbose=None): diff --git a/quantum/db/models_v2.py b/quantum/db/models_v2.py index f0401ef802..4f1bf094e6 100644 --- a/quantum/db/models_v2.py +++ b/quantum/db/models_v2.py @@ -44,7 +44,8 @@ class IPAvailabilityRange(model_base.BASEV2): """ allocation_pool_id = sa.Column(sa.String(36), - sa.ForeignKey('ipallocationpools.id'), + sa.ForeignKey('ipallocationpools.id', + ondelete="CASCADE"), nullable=True, primary_key=True) first_ip = sa.Column(sa.String(64), nullable=False, primary_key=True) @@ -57,7 +58,8 @@ class IPAvailabilityRange(model_base.BASEV2): class IPAllocationPool(model_base.BASEV2, HasId): """Representation of an allocation pool in a Quantum subnet.""" - subnet_id = sa.Column(sa.String(36), sa.ForeignKey('subnets.id'), + subnet_id = sa.Column(sa.String(36), sa.ForeignKey('subnets.id', + ondelete="CASCADE"), nullable=True) first_ip = sa.Column(sa.String(64), nullable=False) last_ip = sa.Column(sa.String(64), nullable=False) @@ -72,12 +74,15 @@ class IPAllocationPool(model_base.BASEV2, HasId): class IPAllocation(model_base.BASEV2): """Internal representation of allocated IP addresses in a Quantum subnet. """ - port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id'), + port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id', + ondelete="CASCADE"), nullable=False, primary_key=True) ip_address = sa.Column(sa.String(64), nullable=False, primary_key=True) - subnet_id = sa.Column(sa.String(36), sa.ForeignKey('subnets.id'), + subnet_id = sa.Column(sa.String(36), sa.ForeignKey('subnets.id', + ondelete="CASCADE"), nullable=False, primary_key=True) - network_id = sa.Column(sa.String(36), sa.ForeignKey("networks.id"), + network_id = sa.Column(sa.String(36), sa.ForeignKey("networks.id", + ondelete="CASCADE"), nullable=False, primary_key=True) diff --git a/quantum/plugins/linuxbridge/lb_quantum_plugin.py b/quantum/plugins/linuxbridge/lb_quantum_plugin.py index 4920812278..ffb52ba717 100644 --- a/quantum/plugins/linuxbridge/lb_quantum_plugin.py +++ b/quantum/plugins/linuxbridge/lb_quantum_plugin.py @@ -49,6 +49,6 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2): def delete_network(self, context, id): vlan_binding = cdb.get_vlan_binding(id) - cdb.release_vlanid(vlan_binding[const.VLANID]) + cdb.release_vlanid(vlan_binding['vlan_id']) cdb.remove_vlan_binding(id) return super(LinuxBridgePluginV2, self).delete_network(context, id) diff --git a/quantum/tests/unit/test_db_plugin.py b/quantum/tests/unit/test_db_plugin.py index 1b71e3d02e..4430ccb948 100644 --- a/quantum/tests/unit/test_db_plugin.py +++ b/quantum/tests/unit/test_db_plugin.py @@ -718,6 +718,34 @@ class TestSubnetsV2(QuantumDbPluginV2TestCase): self._test_create_subnet(gateway_ip=gateway_ip, cidr=cidr) + def test_delete_subnet(self): + gateway_ip = '10.0.0.1' + cidr = '10.0.0.0/24' + fmt = 'json' + # Create new network + res = self._create_network(fmt=fmt, name='net', + admin_status_up=True) + network = self.deserialize(fmt, res) + subnet = self._make_subnet(fmt, network, gateway_ip, + cidr, ip_version=4) + req = self.new_delete_request('subnets', subnet['subnet']['id']) + res = req.get_response(self.api) + self.assertEquals(res.status_int, 204) + + def test_delete_network(self): + gateway_ip = '10.0.0.1' + cidr = '10.0.0.0/24' + fmt = 'json' + # Create new network + res = self._create_network(fmt=fmt, name='net', + admin_status_up=True) + network = self.deserialize(fmt, res) + subnet = self._make_subnet(fmt, network, gateway_ip, + cidr, ip_version=4) + req = self.new_delete_request('networks', network['network']['id']) + res = req.get_response(self.api) + self.assertEquals(res.status_int, 204) + def test_create_subnet_defaults(self): gateway = '10.0.0.1' cidr = '10.0.0.0/24'