]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Reassign IP to vlan interface when deleting a VLAN bridge
authorRalf Haferkamp <rhafer@suse.de>
Tue, 26 Nov 2013 16:38:44 +0000 (17:38 +0100)
committerThomas Goirand <thomas@goirand.fr>
Thu, 13 Mar 2014 07:20:13 +0000 (15:20 +0800)
When deleting a VLAN bridge that has an IP address assigned to it, don't delete
the VLAN interface, but reassigned the IP address back to the underlying VLAN
interface.

Closes-Bug: #1255153

Change-Id: I5e39877c0786b43eddba9b5e1394d4c2ec023c0a

neutron/plugins/linuxbridge/agent/linuxbridge_neutron_agent.py
neutron/tests/unit/linuxbridge/test_lb_neutron_agent.py

index 3b5ec31a4c1584b6dda7e10ddb2d3b6ce42bae3b..a4e4fbc249b3bcc0e7c8d6eb07765929ddca4297 100755 (executable)
@@ -427,15 +427,17 @@ class LinuxBridgeManager:
                     continue
 
                 for physical_interface in self.interface_mappings.itervalues():
-                    if physical_interface == interface:
-                        # This is a flat network => return IP's from bridge to
-                        # interface
+                    if (interface.startswith(physical_interface)):
                         ips, gateway = self.get_interface_details(bridge_name)
-                        self.update_interface_ip_details(interface,
-                                                         bridge_name,
-                                                         ips, gateway)
-                    elif interface.startswith(physical_interface):
-                        self.delete_vlan(interface)
+                        if ips:
+                            # This is a flat network or a VLAN interface that
+                            # was setup outside of neutron => return IP's from
+                            # bridge to interface
+                            self.update_interface_ip_details(interface,
+                                                             bridge_name,
+                                                             ips, gateway)
+                        elif physical_interface != interface:
+                            self.delete_vlan(interface)
 
             LOG.debug(_("Deleting bridge %s"), bridge_name)
             if utils.execute(['ip', 'link', 'set', bridge_name, 'down'],
index 0687d023ecb5d65f7a29bb11e4b216742ef84285..ca979fc53afb4fe3c820f2af30e0662303ad726b 100644 (file)
@@ -509,24 +509,60 @@ class TestLinuxBridgeManager(base.BaseTestCase):
             mock.patch.object(self.lbm, "remove_interface"),
             mock.patch.object(self.lbm, "get_interface_details"),
             mock.patch.object(self.lbm, "update_interface_ip_details"),
-            mock.patch.object(self.lbm, "delete_vlan"),
             mock.patch.object(self.lbm, "delete_vxlan"),
             mock.patch.object(utils, "execute")
         ) as (de_fn, getif_fn, remif_fn, if_det_fn,
-              updif_fn, del_vlan, del_vxlan, exec_fn):
+              updif_fn, del_vxlan, exec_fn):
             de_fn.return_value = False
             self.lbm.delete_vlan_bridge("br0")
             self.assertFalse(getif_fn.called)
 
             de_fn.return_value = True
-            getif_fn.return_value = ["eth0", "eth1.1", "eth1", "vxlan-1002"]
+            getif_fn.return_value = ["eth0", "eth1", "vxlan-1002"]
             if_det_fn.return_value = ("ips", "gateway")
             exec_fn.return_value = False
             self.lbm.delete_vlan_bridge("br0")
             updif_fn.assert_called_with("eth1", "br0", "ips", "gateway")
-            del_vlan.assert_called_with("eth1.1")
             del_vxlan.assert_called_with("vxlan-1002")
 
+    def test_delete_vlan_bridge_with_ip(self):
+        with contextlib.nested(
+            mock.patch.object(self.lbm, "device_exists"),
+            mock.patch.object(self.lbm, "get_interfaces_on_bridge"),
+            mock.patch.object(self.lbm, "remove_interface"),
+            mock.patch.object(self.lbm, "get_interface_details"),
+            mock.patch.object(self.lbm, "update_interface_ip_details"),
+            mock.patch.object(self.lbm, "delete_vlan"),
+            mock.patch.object(utils, "execute")
+        ) as (de_fn, getif_fn, remif_fn, if_det_fn,
+              updif_fn, del_vlan, exec_fn):
+            de_fn.return_value = True
+            getif_fn.return_value = ["eth0", "eth1.1"]
+            if_det_fn.return_value = ("ips", "gateway")
+            exec_fn.return_value = False
+            self.lbm.delete_vlan_bridge("br0")
+            updif_fn.assert_called_with("eth1.1", "br0", "ips", "gateway")
+            self.assertFalse(del_vlan.called)
+
+    def test_delete_vlan_bridge_no_ip(self):
+        with contextlib.nested(
+            mock.patch.object(self.lbm, "device_exists"),
+            mock.patch.object(self.lbm, "get_interfaces_on_bridge"),
+            mock.patch.object(self.lbm, "remove_interface"),
+            mock.patch.object(self.lbm, "get_interface_details"),
+            mock.patch.object(self.lbm, "update_interface_ip_details"),
+            mock.patch.object(self.lbm, "delete_vlan"),
+            mock.patch.object(utils, "execute")
+        ) as (de_fn, getif_fn, remif_fn, if_det_fn,
+              updif_fn, del_vlan, exec_fn):
+            de_fn.return_value = True
+            getif_fn.return_value = ["eth0", "eth1.1"]
+            exec_fn.return_value = False
+            if_det_fn.return_value = ([], None)
+            self.lbm.delete_vlan_bridge("br0")
+            del_vlan.assert_called_with("eth1.1")
+            self.assertFalse(updif_fn.called)
+
     def test_delete_vxlan_bridge_no_int_mappings(self):
         interface_mappings = {}
         lbm = linuxbridge_neutron_agent.LinuxBridgeManager(