]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Remove port from ovsdb after its deletion
authorElena Ezhova <eezhova@mirantis.com>
Wed, 24 Dec 2014 14:09:32 +0000 (17:09 +0300)
committerElena Ezhova <eezhova@mirantis.com>
Tue, 10 Feb 2015 15:18:06 +0000 (18:18 +0300)
When port is being deleted via API it is not removed
from ovsdb and corresponding iptables chains remain
even though the port does not exist.

This patch adds a notification for the ovs neutron agent,
upon which the port is deleted from ovsdb.

Co-Authored-By: Akash Gangil <akashg1611@gmail.com>
Closes-Bug: #1333365
Change-Id: Iccda3bee98d561ef3a06d0317d3d68d6b1dfb76b

neutron/plugins/ml2/plugin.py
neutron/plugins/ml2/rpc.py
neutron/plugins/openvswitch/agent/ovs_neutron_agent.py
neutron/tests/unit/ml2/test_rpcapi.py
neutron/tests/unit/openvswitch/test_ovs_neutron_agent.py

index 411002dc7b3931c5ff1a15f0da9f41051a1e535c..bc719288cdfb3410763e8f1de7d9d00eed37ca41 100644 (file)
@@ -1172,6 +1172,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
             # fact that an error occurred.
             LOG.error(_LE("mechanism_manager.delete_port_postcommit failed for"
                           " port %s"), id)
+        self.notifier.port_delete(context, id)
         self.notify_security_groups_member_updated(context, port)
 
     def get_bound_port_context(self, plugin_context, port_id, host=None):
index b08d06be1697c92fa7e946aca4a5385e8032c8b9..6595c8291b9b5b9d1ac5f25015ac5104d9a99b8f 100644 (file)
@@ -198,6 +198,10 @@ class AgentNotifierApi(dvr_rpc.DVRAgentRpcApiMixin,
         self.topic_port_update = topics.get_topic_name(topic,
                                                        topics.PORT,
                                                        topics.UPDATE)
+        self.topic_port_delete = topics.get_topic_name(topic,
+                                                       topics.PORT,
+                                                       topics.DELETE)
+
         target = oslo_messaging.Target(topic=topic, version='1.0')
         self.client = n_rpc.get_client(target)
 
@@ -213,3 +217,8 @@ class AgentNotifierApi(dvr_rpc.DVRAgentRpcApiMixin,
         cctxt.cast(context, 'port_update', port=port,
                    network_type=network_type, segmentation_id=segmentation_id,
                    physical_network=physical_network)
+
+    def port_delete(self, context, port_id):
+        cctxt = self.client.prepare(topic=self.topic_port_delete,
+                                    fanout=True)
+        cctxt.cast(context, 'port_delete', port_id=port_id)
index b1a3565bb7c7a55846d8e19d6699e5f144b1cf50..b3199421be29f7ac22fae1785baa2f9a5ce81ce4 100644 (file)
@@ -294,6 +294,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         self.endpoints = [self]
         # Define the listening consumers for the agent
         consumers = [[topics.PORT, topics.UPDATE],
+                     [topics.PORT, topics.DELETE],
                      [topics.NETWORK, topics.DELETE],
                      [constants.TUNNEL, topics.UPDATE],
                      [topics.SECURITY_GROUP, topics.UPDATE],
@@ -331,6 +332,13 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         self.updated_ports.add(port['id'])
         LOG.debug("port_update message processed for port %s", port['id'])
 
+    def port_delete(self, context, **kwargs):
+        port_id = kwargs.get('port_id')
+        port = self.int_br.get_vif_port_by_id(port_id)
+        # If port exists, delete it
+        if port:
+            self.int_br.delete_port(port.port_name)
+
     def tunnel_update(self, context, **kwargs):
         LOG.debug("tunnel_update received")
         if not self.enable_tunneling:
index a3b4955f62a6b8f7e43119e080ec6fa630e8446b..08978f66e77682a19dc7dfce83aefb8a00aaceb0 100644 (file)
@@ -223,6 +223,16 @@ class RpcApiTestCase(base.BaseTestCase):
                 segmentation_id='fake_segmentation_id',
                 physical_network='fake_physical_network')
 
+    def test_port_delete(self):
+        rpcapi = plugin_rpc.AgentNotifierApi(topics.AGENT)
+        self._test_rpc_api(
+            rpcapi,
+            topics.get_topic_name(topics.AGENT,
+                                  topics.PORT,
+                                  topics.DELETE),
+            'port_delete', rpc_method='cast',
+            fanout=True, port_id='fake_port')
+
     def test_tunnel_update(self):
         rpcapi = plugin_rpc.AgentNotifierApi(topics.AGENT)
         self._test_rpc_api(
index 3e124fbf69a75d250e708bdba954e4186733d845..a7d90416ff27cbfc38024ec148d2d99181964cdc 100644 (file)
@@ -498,6 +498,20 @@ class TestOvsNeutronAgent(base.BaseTestCase):
                                physical_network="physnet")
         self.assertEqual(set(['123']), self.agent.updated_ports)
 
+    def test_port_delete(self):
+        port_id = "123"
+        port_name = "foo"
+        with contextlib.nested(
+            mock.patch.object(self.agent.int_br, 'get_vif_port_by_id',
+                              return_value=mock.MagicMock(
+                                      port_name=port_name)),
+            mock.patch.object(self.agent.int_br, "delete_port")
+        ) as (get_vif_func, del_port_func):
+            self.agent.port_delete("unused_context",
+                                   port_id=port_id)
+            self.assertTrue(get_vif_func.called)
+            del_port_func.assert_called_once_with(port_name)
+
     def test_setup_physical_bridges(self):
         with contextlib.nested(
             mock.patch.object(ip_lib, "device_exists"),