]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Do not delete subnets with IPs on router interfaces
authorSalvatore Orlando <salv.orlando@gmail.com>
Fri, 8 Mar 2013 17:10:38 +0000 (18:10 +0100)
committerSalvatore Orlando <salv.orlando@gmail.com>
Fri, 8 Mar 2013 21:20:41 +0000 (22:20 +0100)
Bug 1152171

This patch simply causes a 409 to be returned when attempting to
delete a subnet which has IPs on ports whose device_owner is
network:router_interface

This does not address a similar problem that arises when the ips for
a port owned by a router_interface are updated. This problem is hidden
when updating a port which has been assigned the gateway_ip by an
exception in the IP recycling process. However, it will hit when the
port was explicitly added to the router, since it will have an ip
different from the subnet's gateway ip.

Change-Id: I38dfd2639acd03db8d3f1f933495a456a4a8724f

quantum/db/db_base_plugin_v2.py
quantum/tests/unit/openvswitch/test_agent_scheduler.py
quantum/tests/unit/test_l3_plugin.py

index 36d1356c5602b7e500db04f887944fa7e158a340..b5dce8bcc468da09db956c5989d23e8efad7d40d 100644 (file)
@@ -46,7 +46,7 @@ AGENT_OWNER_PREFIX = 'network:'
 # finds out that all existing IP Allocations are associated with ports
 # with these owners, it will allow subnet deletion to proceed with the
 # IP allocations being cleaned up by cascade.
-AUTO_DELETE_PORT_OWNERS = ['network:dhcp', 'network:router_interface']
+AUTO_DELETE_PORT_OWNERS = ['network:dhcp']
 
 
 class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
index 4c80ca15b4895d46d6e6960854075ff2fdf5afed..d44b12968aae233d6be23b8d493ccc0c6462e7a5 100644 (file)
@@ -602,6 +602,16 @@ class OvsAgentSchedulerTestCase(test_l3_plugin.L3NatTestCaseMixin,
                 router1['router']['id'])
             l3_agents_2 = self._list_l3_agents_hosting_router(
                 router2['router']['id'])
+            # safe cleanup
+            self._router_interface_action('remove',
+                                          router1['router']['id'],
+                                          subnet1['subnet']['id'],
+                                          None)
+            self._router_interface_action('remove',
+                                          router2['router']['id'],
+                                          subnet2['subnet']['id'],
+                                          None)
+
         # L3 agent will host only the compatible router.
         self.assertEqual(1, num_hosta_routers)
         self.assertEqual(1, len(l3_agents_1['agents']))
index 64463141be4f8e17e1d81059b7794f4ca464c8ca..703686b24e3b03190be83d3d948abb3a29d8e524 100644 (file)
@@ -969,23 +969,6 @@ class L3NatDBTestCase(L3NatTestCaseBase):
                     r['router']['id'],
                     n['network']['id'], expected_code=exc.HTTPBadRequest.code)
 
-    def test_delete_unused_router_interface(self):
-        with self.network() as n:
-            with self.router() as r:
-                with self.subnet(network=n) as s:
-                    res = self._create_port(self.fmt,
-                                            s['subnet']['network_id'])
-                    p = self.deserialize(self.fmt, res)
-                    self._router_interface_action('add',
-                                                  r['router']['id'],
-                                                  None,
-                                                  p['port']['id'])
-                # The subnet here is deleted, and the port should have no IP
-                self._delete('ports', p['port']['id'])
-                # Verify the port has been deleted
-                self._show('ports', p['port']['id'],
-                           expected_code=exc.HTTPNotFound.code)
-
     def test_router_remove_interface_inuse_returns_409(self):
         with self.router() as r:
             with self.subnet() as s:
@@ -1635,6 +1618,22 @@ class L3NatDBTestCase(L3NatTestCaseBase):
             self.assertTrue(floatingips[0]['fixed_ip_address'] is not None)
             self.assertTrue(floatingips[0]['router_id'] is not None)
 
+    def test_router_delete_subnet_inuse_returns_409(self):
+        with self.router() as r:
+            with self.subnet() as s:
+                self._router_interface_action('add',
+                                              r['router']['id'],
+                                              s['subnet']['id'],
+                                              None)
+                # subnet cannot be delete as it's attached to a router
+                self._delete('subnets', s['subnet']['id'],
+                             expected_code=exc.HTTPConflict.code)
+                # remove interface so test can exit without errors
+                self._router_interface_action('remove',
+                                              r['router']['id'],
+                                              s['subnet']['id'],
+                                              None)
+
 
 class L3NatDBTestCaseXML(L3NatDBTestCase):
     fmt = 'xml'