AgentExtensionsManager and AgentCoreResourceExtension
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
This commit is contained in:
parent
2d38c742e8
commit
c26142be33
|
@ -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
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue