--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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)
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