]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add delete_port api to agent extension manager
authorMoshe Levi <moshele@mellanox.com>
Mon, 10 Aug 2015 11:43:55 +0000 (14:43 +0300)
committerJohn Schwarz <jschwarz@redhat.com>
Mon, 10 Aug 2015 15:20:29 +0000 (18:20 +0300)
This commit add delete_port api to the agent
extension manager, the agent extension and the qos
etension, and it update the ovs agent to call it upon
delete port.

Change-Id: Ia4e96c7c734cf4abe9a35c813bd8330b15b68f4c
Partially-Implements: bluerint ml2-qos

neutron/agent/l2/agent_extension.py
neutron/agent/l2/extensions/manager.py
neutron/agent/l2/extensions/qos.py
neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py
neutron/tests/unit/agent/l2/extensions/test_manager.py
neutron/tests/unit/agent/l2/extensions/test_qos.py

index 125a9bc0594ff55f03675637530c19e066e8b69a..9399f42379ef085bd89e5894ccf1767eec8436f3 100644 (file)
@@ -34,7 +34,19 @@ class AgentCoreResourceExtension(object):
 
     @abc.abstractmethod
     def handle_port(self, context, data):
-        """handle agent extension for port.
+        """Handle agent extension for port.
+
+        This can be called on either create or update, depending on the
+        code flow. Thus, it's this function's responsibility to check what
+        actually changed.
+
+        :param context - rpc context
+        :param data - port data
+        """
+
+    @abc.abstractmethod
+    def delete_port(self, context, data):
+        """Delete port from agent extension.
 
         :param context - rpc context
         :param data - port data
index 2c77adbf8e935194bd81c6671767a2849fcf0862..ba9b45952b1f86a8669d636d752814c7cc6f8f7a 100644 (file)
@@ -61,5 +61,17 @@ class AgentExtensionsManager(stevedore.named.NamedExtensionManager):
                         "while handling port update"),
                     {'name': extension.name}
                 )
-    #TODO(Qos) we are missing how to handle delete. we can pass action
-    #type in all the handle methods or add handle_delete_resource methods
+
+    def delete_port(self, context, data):
+        """Notify all agent extensions to delete port."""
+        for extension in self:
+            try:
+                extension.obj.delete_port(context, data)
+            # TODO(QoS) add agent extensions exception and catch them here
+            # instead of AttributeError
+            except AttributeError:
+                LOG.exception(
+                    _LE("Agent Extension '%(name)s' failed "
+                        "while handling port deletion"),
+                    {'name': extension.name}
+                )
index 736cc1458a743353bd5fc6c9051eb5a051efc5af..4b860a1a28eefb37c0a5d28b235bc257e0e9b3c1 100644 (file)
@@ -133,6 +133,9 @@ class QosAgentExtension(agent_extension.AgentCoreResourceExtension):
             context, resources.QOS_POLICY, qos_policy_id)
         self.qos_driver.create(port, qos_policy)
 
+    def delete_port(self, context, port):
+        self._process_reset_port(port)
+
     def _process_update_policy(self, qos_policy):
         for port_id, port in self.qos_policy_ports[qos_policy.id].items():
             # TODO(QoS): for now, just reflush the rules on the port. Later, we
index a5190f9a39657756fcaf463ba780eea13f809e4d..211e5176173ec8b99323a32d072fa7b47c4acd94 100644 (file)
@@ -403,6 +403,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
             # longer have access to the network
             self.sg_agent.remove_devices_filter([port_id])
             port = self.int_br.get_vif_port_by_id(port_id)
+            self.ext_manager.delete_port(self.context,
+                                         {"vif_port": port,
+                                          "port_id": port_id})
             if port:
                 # don't log errors since there is a chance someone will be
                 # removing the port from the bridge at the same time
index 3aa8ea58ba162d40450efda7c7b99a2c58b5720a..85f8533809ec795f0dd0b160614c7a24476e816e 100644 (file)
@@ -43,3 +43,10 @@ class TestAgentExtensionsManager(base.BaseTestCase):
         self.manager.handle_port(context, data)
         ext = self._get_extension()
         ext.handle_port.assert_called_once_with(context, data)
+
+    def test_delete_port(self):
+        context = object()
+        data = object()
+        self.manager.delete_port(context, data)
+        ext = self._get_extension()
+        ext.delete_port.assert_called_once_with(context, data)
index d78fc3121b18b68197f1f15901f03376e3193c45..4ed3090b8c378c25ae02d3c462ed27825359ebb1 100755 (executable)
@@ -98,6 +98,22 @@ class QosExtensionRpcTestCase(QosExtensionBaseTestCase):
         #TODO(QoS): handle qos_driver.update call check when
         #           we do that
 
+    def test_delete_known_port(self):
+        port = self._create_test_port_dict()
+        port_id = port['port_id']
+        self.qos_ext.handle_port(self.context, port)
+        self.qos_ext.qos_driver.reset_mock()
+        self.qos_ext.delete_port(self.context, port)
+        self.qos_ext.qos_driver.delete.assert_called_with(port, None)
+        self.assertNotIn(port_id, self.qos_ext.known_ports)
+
+    def test_delete_unknown_port(self):
+        port = self._create_test_port_dict()
+        port_id = port['port_id']
+        self.qos_ext.delete_port(self.context, port)
+        self.assertFalse(self.qos_ext.qos_driver.delete.called)
+        self.assertNotIn(port_id, self.qos_ext.known_ports)
+
     def test__handle_notification_ignores_all_event_types_except_updated(self):
         with mock.patch.object(
             self.qos_ext, '_process_update_policy') as update_mock: