]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
DVR to delete router namespaces for service ports
authorVivekanandan Narasimhan <vivekanandan.narasimhan@hp.com>
Wed, 3 Sep 2014 08:48:39 +0000 (01:48 -0700)
committerVivekanandan Narasimhan <vivekanandan.narasimhan@hp.com>
Fri, 19 Sep 2014 02:18:09 +0000 (19:18 -0700)
Earlier merge that enabled LBaaS in DVR with review #114141
had not covered the removal of DVR router namespace on
VIP Port deletion in ml2 plugin.

Here we fix the ml2 plugin to attempt namespace removal for
all dvr serviced ports.

Change-Id: Ie7930ebedb12212886d45294132fefff7296e104
Closes-Bug: #1364839

neutron/db/l3_dvrscheduler_db.py
neutron/plugins/ml2/plugin.py
neutron/tests/unit/ml2/test_ml2_plugin.py
neutron/tests/unit/test_l3_schedulers.py

index 2797c73a8c95e50c57744f693e13c9268d6359b2..a8c9dae945de8ab19b2b1a8922a70d0a81d3f11a 100644 (file)
@@ -110,7 +110,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
                     break
             LOG.debug('DVR: dvr_update_router_addvm %s ', router_id)
 
-    def get_dvr_routers_by_vmportid(self, context, port_id):
+    def get_dvr_routers_by_portid(self, context, port_id):
         """Gets the dvr routers on vmport subnets."""
         router_ids = set()
         port_dict = self._core_plugin.get_port(context, port_id)
@@ -153,9 +153,9 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
                 return True
         return False
 
-    def dvr_deletens_if_no_vm(self, context, port_id):
-        """Delete the DVR namespace if no VM exists."""
-        router_ids = self.get_dvr_routers_by_vmportid(context, port_id)
+    def dvr_deletens_if_no_port(self, context, port_id):
+        """Delete the DVR namespace if no dvr serviced port exists."""
+        router_ids = self.get_dvr_routers_by_portid(context, port_id)
         port_host = ml2_db.get_port_binding_host(port_id)
         if not router_ids:
             LOG.debug('No namespaces available for this DVR port %(port)s '
@@ -165,16 +165,16 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
         removed_router_info = []
         for router_id in router_ids:
             subnet_ids = self.get_subnet_ids_on_router(context, router_id)
-            vm_exists_on_subnet = False
+            port_exists_on_subnet = False
             for subnet in subnet_ids:
                 if self.check_ports_active_on_host_and_subnet(context,
                                                               port_host,
                                                               port_id,
                                                               subnet):
-                    vm_exists_on_subnet = True
+                    port_exists_on_subnet = True
                     break
 
-            if vm_exists_on_subnet:
+            if port_exists_on_subnet:
                 continue
             filter_rtr = {'device_id': [router_id],
                           'device_owner':
index e6a8d9040cad4ea28270bf956674dfd286d029e3..80cae035ed03a6a3d0aa9c387e3cff30418d1c8a 100644 (file)
@@ -964,7 +964,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
 
             network = self.get_network(context, port['network_id'])
             mech_context = None
-            if port['device_owner'] == const.DEVICE_OWNER_DVR_INTERFACE:
+            device_owner = port['device_owner']
+            if device_owner == const.DEVICE_OWNER_DVR_INTERFACE:
                 bindings = db.get_dvr_port_bindings(context.session, id)
                 for bind in bindings:
                     mech_context = driver_context.DvrPortContext(
@@ -973,8 +974,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
             else:
                 mech_context = driver_context.PortContext(self, context, port,
                                                           network, binding)
-                if "compute:" in port['device_owner'] and is_dvr_enabled:
-                    router_info = l3plugin.dvr_deletens_if_no_vm(context, id)
+                if is_dvr_enabled and utils.is_dvr_serviced(device_owner):
+                    router_info = l3plugin.dvr_deletens_if_no_port(context, id)
                     removed_routers += router_info
                 self.mechanism_manager.delete_port_precommit(mech_context)
                 self._delete_port_security_group_bindings(context, id)
@@ -985,7 +986,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
                     l3plugin.dvr_vmarp_table_update(context, id, "del")
 
             LOG.debug("Calling delete_port for %(port_id)s owned by %(owner)s"
-                      % {"port_id": id, "owner": port['device_owner']})
+                      % {"port_id": id, "owner": device_owner})
             super(Ml2Plugin, self).delete_port(context, id)
 
         # now that we've left db transaction, we are safe to notify
index ca0a061f946f33dcc89141a38a64a61baf5f37b9..61c00926f2aa6e4f8b99fabe15e2f717a4fb6121 100644 (file)
@@ -177,6 +177,9 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
         self.assertTrue(utils.is_dvr_serviced(
             constants.DEVICE_OWNER_LOADBALANCER))
 
+    def test_check_if_dhcp_port_serviced_by_dvr(self):
+        self.assertTrue(utils.is_dvr_serviced(constants.DEVICE_OWNER_DHCP))
+
     def test_check_if_port_not_serviced_by_dvr(self):
         self.assertFalse(utils.is_dvr_serviced(
             constants.DEVICE_OWNER_ROUTER_INTF))
@@ -205,61 +208,49 @@ class TestMl2DvrPortsV2(TestMl2PortsV2):
             mock.PropertyMock(return_value=extensions))
         self.service_plugins = {'L3_ROUTER_NAT': self.l3plugin}
 
-    def test_delete_last_vm_port(self):
-        fip_set = set()
-        ns_to_delete = {'host': 'vmhost', 'agent_id': 'vm_l3_agent',
+    def _test_delete_dvr_serviced_port(self, device_owner, floating_ip=False):
+        ns_to_delete = {'host': 'myhost', 'agent_id': 'vm_l3_agent',
                         'router_id': 'my_router'}
+        fip_set = set()
+        if floating_ip:
+            fip_set.add(ns_to_delete['router_id'])
 
         with contextlib.nested(
             mock.patch.object(manager.NeutronManager,
                               'get_service_plugins',
                               return_value=self.service_plugins),
-            self.port(do_delete=False, device_owner='compute:None'),
+            self.port(do_delete=False,
+                      device_owner=device_owner),
             mock.patch.object(self.l3plugin, 'notify_routers_updated'),
             mock.patch.object(self.l3plugin, 'disassociate_floatingips',
                               return_value=fip_set),
-            mock.patch.object(self.l3plugin, 'dvr_deletens_if_no_vm',
+            mock.patch.object(self.l3plugin, 'dvr_deletens_if_no_port',
                               return_value=[ns_to_delete]),
             mock.patch.object(self.l3plugin, 'remove_router_from_l3_agent')
         ) as (get_service_plugin, port, notify, disassociate_floatingips,
-              ddinv, remove_router_from_l3_agent):
+              dvr_delns_ifno_port, remove_router_from_l3_agent):
 
             port_id = port['port']['id']
             self.plugin.delete_port(self.context, port_id)
 
             notify.assert_has_calls([mock.call(self.context, fip_set)])
+            dvr_delns_ifno_port.assert_called_once_with(self.context,
+                                                        port['port']['id'])
             remove_router_from_l3_agent.assert_has_calls([
                 mock.call(self.context, ns_to_delete['agent_id'],
                           ns_to_delete['router_id'])
             ])
 
-    def test_delete_last_vm_port_with_floatingip(self):
-        ns_to_delete = {'host': 'vmhost', 'agent_id': 'vm_l3_agent',
-                        'router_id': 'my_router'}
-        fip_set = set([ns_to_delete['router_id']])
-
-        with contextlib.nested(
-            mock.patch.object(manager.NeutronManager,
-                              'get_service_plugins',
-                              return_value=self.service_plugins),
-            self.port(do_delete=False, device_owner='compute:None'),
-            mock.patch.object(self.l3plugin, 'notify_routers_updated'),
-            mock.patch.object(self.l3plugin, 'disassociate_floatingips',
-                              return_value=fip_set),
-            mock.patch.object(self.l3plugin, 'dvr_deletens_if_no_vm',
-                              return_value=[ns_to_delete]),
-            mock.patch.object(self.l3plugin, 'remove_router_from_l3_agent')
-        ) as (get_service_plugins, port, notify, disassociate_floatingips,
-              ddinv, remove_router_from_l3_agent):
+    def test_delete_last_vm_port(self):
+        self._test_delete_dvr_serviced_port(device_owner='compute:None')
 
-            port_id = port['port']['id']
-            self.plugin.delete_port(self.context, port_id)
+    def test_delete_last_vm_port_with_floatingip(self):
+        self._test_delete_dvr_serviced_port(device_owner='compute:None',
+                                            floating_ip=True)
 
-            notify.assert_has_calls([mock.call(self.context, fip_set)])
-            remove_router_from_l3_agent.assert_has_calls([
-                mock.call(self.context, ns_to_delete['agent_id'],
-                          ns_to_delete['router_id'])
-            ])
+    def test_delete_lbaas_vip_port(self):
+        self._test_delete_dvr_serviced_port(
+            device_owner=constants.DEVICE_OWNER_LOADBALANCER)
 
 
 class TestMl2PortBinding(Ml2PluginV2TestCase,
index fdf823213b3efdecccfffdaf55c818e50dce49c4..b3eb448591173a43830bc376e8649cc4bfa5874c 100644 (file)
@@ -822,7 +822,7 @@ class L3DvrSchedulerTestCase(testlib_api.SqlTestCase,
                        '.L3AgentNotifyAPI')):
             self.dut.dvr_update_router_addvm(self.adminContext, port)
 
-    def test_get_dvr_routers_by_vmportid(self):
+    def test_get_dvr_routers_by_portid(self):
         dvr_port = {
                 'id': 'dvr_port1',
                 'device_id': 'r1',
@@ -844,8 +844,8 @@ class L3DvrSchedulerTestCase(testlib_api.SqlTestCase,
                        '.get_port', return_value=dvr_port),
             mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2'
                        '.get_ports', return_value=[dvr_port])):
-            router_id = self.dut.get_dvr_routers_by_vmportid(self.adminContext,
-                                                             dvr_port['id'])
+            router_id = self.dut.get_dvr_routers_by_portid(self.adminContext,
+                                                           dvr_port['id'])
             self.assertEqual(router_id.pop(), r1['id'])
 
     def test_get_subnet_ids_on_router(self):