]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
AgentExtensionsManager and AgentCoreResourceExtension
authorMoshe Levi <moshele@mellanox.com>
Wed, 24 Jun 2015 15:10:05 +0000 (18:10 +0300)
committerIhar Hrachyshka <ihrachys@redhat.com>
Thu, 2 Jul 2015 13:51:34 +0000 (13:51 +0000)
This patch introduces the following classes:
L2Agent - abstract class for common L2Agent implementions.
AgentExtensionsManager - to load AgentCoreResourceExtension.
AgentCoreResourceExtension - interface class to define
the AgentCoreResourceExtension API.
This allows better segregation between L2 Agent Core
and L2 Agent Extensions.

The patch is missing unit test but it was tested manually.
I added a unit tests @TODO comments to come back
to them later.

Change-Id: I813de7ff1bee188f4294f4b3eb3645ebd903297b

neutron/agent/l2/__init__.py [new file with mode: 0644]
neutron/agent/l2/agent_extension.py [new file with mode: 0644]
neutron/agent/l2/agent_extensions_manager.py [new file with mode: 0644]
neutron/agent/l2/l2_agent.py [new file with mode: 0644]
setup.cfg

diff --git a/neutron/agent/l2/__init__.py b/neutron/agent/l2/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/neutron/agent/l2/agent_extension.py b/neutron/agent/l2/agent_extension.py
new file mode 100644 (file)
index 0000000..50137d4
--- /dev/null
@@ -0,0 +1,61 @@
+# Copyright (c) 2015 Mellanox Technologies, Ltd
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import abc
+
+import six
+
+
+@six.add_metaclass(abc.ABCMeta)
+class AgentCoreResourceExtension(object):
+    """Define stable abstract interface for Agent extension.
+
+    An agent extension extends the agent core functionality.
+    """
+
+    def initialize(self, resource_rpc):
+        """Perform agent core resource extension initialization.
+
+        Called after all extensions have been loaded.
+        No abstract methods defined below will be
+        called prior to this method being called.
+        :param resource_rpc - the agent side rpc for getting
+        resource by type and id
+        """
+        self.resource_rpc = resource_rpc
+
+    def handle_network(self, context, data):
+        """handle agent extension for network.
+
+        :param context - rpc context
+        :param data - network data
+        """
+        pass
+
+    def handle_subnet(self, context, data):
+        """handle agent extension for subnet.
+
+        :param context - rpc context
+        :param data - subnet data
+        """
+        pass
+
+    def handle_port(self, context, data):
+        """handle agent extension for port.
+
+        :param context - rpc context
+        :param data - port data
+        """
+        pass
diff --git a/neutron/agent/l2/agent_extensions_manager.py b/neutron/agent/l2/agent_extensions_manager.py
new file mode 100644 (file)
index 0000000..622dbc0
--- /dev/null
@@ -0,0 +1,70 @@
+# Copyright (c) 2015 Mellanox Technologies, Ltd
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from oslo_log import log
+import stevedore
+
+from neutron.i18n import _LE, _LI
+
+LOG = log.getLogger(__name__)
+
+
+# TODO(QoS) add unit tests to Agent extensions mgr
+class AgentExtensionsManager(stevedore.named.NamedExtensionManager):
+    """Manage agent extensions."""
+
+    def __init__(self, agent_extensions):
+        # Ordered list of agent extensions, defining
+        # the order in which the agent extensions are called.
+
+        LOG.info(_LI("Configured agent extensions names: %s"),
+                 agent_extensions)
+
+        super(AgentExtensionsManager, self).__init__(
+            'neutron.agent.l2.extensions', agent_extensions,
+            invoke_on_load=True, name_order=True)
+        LOG.info(_LI("Loaded agent extensions names: %s"), self.names())
+
+    def _call_on_agent_extensions(self, method_name, context, data):
+        """Helper method for calling a method across all agent extensions."""
+        for extension in self:
+            try:
+                getattr(extension.obj, method_name)(context, data)
+            # TODO(QoS) add agent extensions exception and catch them here
+            except AttributeError:
+                LOG.exception(
+                    _LE("Agent Extension '%(name)s' failed in %(method)s"),
+                    {'name': extension.name, 'method': method_name}
+                )
+
+    def initialize(self, resource_rpc):
+        # Initialize each agent extension in the list.
+        for extension in self:
+            LOG.info(_LI("Initializing agent extension '%s'"), extension.name)
+            extension.obj.initialize(resource_rpc)
+
+    def handle_network(self, context, data):
+        """Notify all agent extensions to handle network."""
+        self._call_on_agent_extensions("handle_network", context, data)
+
+    def handle_subnet(self, context, data):
+        """Notify all agent extensions to handle subnet."""
+        self._call_on_agent_extensions("handle_subnet", context, data)
+
+    def handle_port(self, context, data):
+        """Notify all agent extensions to handle port."""
+        self._call_on_agent_extensions("handle_port", context, data)
+    #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
diff --git a/neutron/agent/l2/l2_agent.py b/neutron/agent/l2/l2_agent.py
new file mode 100644 (file)
index 0000000..0ee6c9c
--- /dev/null
@@ -0,0 +1,55 @@
+# Copyright (c) 2015 Mellanox Technologies, Ltd
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import abc
+
+import six
+
+from neutron.agent.l2 import agent_extensions_manager
+
+
+#TODO(QoS): add unit tests to L2 Agent
+@six.add_metaclass(abc.ABCMeta)
+class L2Agent(object):
+    """Define stable abstract interface for L2 Agent
+
+    This class initialize the agent extension manager and
+    provides API for calling the extensions manager process
+    extensions methods.
+    """
+    def __init__(self, polling_interval):
+        self.polling_interval = polling_interval
+        self.agent_extensions_mgr = None
+        self.resource_rpc = None
+
+    def initialize(self):
+        #TODO(QoS): get extensions from server ????
+        agent_extensions = ('qos', )
+        self.agent_extensions_mgr = (
+            agent_extensions_manager.AgentExtensionsManager(
+                agent_extensions))
+        self.agent_extensions_mgr.initialize(self.resource_rpc)
+
+    def process_network_extensions(self, context, network):
+        self.agent_extensions_mgr.handle_network(
+            context, network)
+
+    def process_subnet_extensions(self, context, subnet):
+        self.agent_extensions_mgr.handle_subnet(
+            context, subnet)
+
+    def process_port_extensions(self, context, port):
+        self.agent_extensions_mgr.handle_port(
+            context, port)
index 7c636307500a335f876b8e3d470b3b0b82f72730..90f75e1d2cb6216f22034f9112867eadfc955b3e 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -202,6 +202,7 @@ neutron.openstack.common.cache.backends =
 neutron.ipam_drivers =
     fake = neutron.tests.unit.ipam.fake_driver:FakeDriver
     internal = neutron.ipam.drivers.neutrondb_ipam.driver:NeutronDbPool
+neutron.agent.l2.extensions =
 # These are for backwards compat with Icehouse notification_driver configuration values
 oslo.messaging.notify.drivers =
     neutron.openstack.common.notifier.log_notifier = oslo_messaging.notify._impl_log:LogDriver