From 93a8dc3dbe4faae6efd017105fb407d7dfca1d32 Mon Sep 17 00:00:00 2001 From: Nate Johnston Date: Thu, 7 Jul 2016 21:32:28 +0000 Subject: [PATCH] Implement L3 Agent Extension Manager Using the generalized agent extension mechanism, create an agent extension manager in the L3 agent, so that the L3 agent can load agent extensions. Co-Authored-By: Margaret Frances Implements: blueprint l3-agent-extensions Needed-By: Iff506bd11b83d396305e631f3dd95d44cf38fd63 Change-Id: I6da92cb8b9fcbb603e120eababcf4ce711da3e30 --- neutron/agent/l3/agent.py | 13 ++++ neutron/agent/l3/l3_agent_extension.py | 55 ++++++++++++++ .../agent/l3/l3_agent_extensions_manager.py | 72 +++++++++++++++++++ .../l3-agent-extensions-b348ff26aec0fe88.yaml | 5 ++ 4 files changed, 145 insertions(+) create mode 100644 neutron/agent/l3/l3_agent_extension.py create mode 100644 neutron/agent/l3/l3_agent_extensions_manager.py create mode 100644 releasenotes/notes/l3-agent-extensions-b348ff26aec0fe88.yaml diff --git a/neutron/agent/l3/agent.py b/neutron/agent/l3/agent.py index 95c8a97cdf3..f69bc748748 100644 --- a/neutron/agent/l3/agent.py +++ b/neutron/agent/l3/agent.py @@ -32,6 +32,7 @@ from neutron.agent.l3 import dvr_edge_router as dvr_router from neutron.agent.l3 import dvr_local_router as dvr_local_router from neutron.agent.l3 import ha from neutron.agent.l3 import ha_router +from neutron.agent.l3 import l3_agent_extensions_manager as l3_ext_manager from neutron.agent.l3 import legacy_router from neutron.agent.l3 import namespace_manager from neutron.agent.l3 import namespaces @@ -223,6 +224,8 @@ class L3NATAgent(ha.AgentMixin, continue break + self.init_extension_manager(self.plugin_rpc) + self.metadata_driver = None if self.conf.enable_metadata_proxy: self.metadata_driver = metadata_driver.MetadataDriver(self) @@ -341,6 +344,7 @@ class L3NATAgent(ha.AgentMixin, try: self._router_removed(router_id) + self.l3_ext_manager.delete_router(self.context, router_id) except Exception: LOG.exception(_LE('Error while deleting router %s'), router_id) return False @@ -363,6 +367,13 @@ class L3NATAgent(ha.AgentMixin, registry.notify(resources.ROUTER, events.AFTER_DELETE, self, router=ri) + def init_extension_manager(self, connection): + l3_ext_manager.register_opts(self.conf) + self.l3_ext_manager = ( + l3_ext_manager.L3AgentExtensionsManager(self.conf)) + self.l3_ext_manager.initialize( + connection, l3_constants.L3_AGENT_MODE) + def router_deleted(self, context, router_id): """Deal with router deletion RPC message.""" LOG.debug('Got router deleted notification for %s', router_id) @@ -426,6 +437,7 @@ class L3NATAgent(ha.AgentMixin, ri.router = router ri.process(self) registry.notify(resources.ROUTER, events.AFTER_CREATE, self, router=ri) + self.l3_ext_manager.add_router(self.context, router) def _process_updated_router(self, router): ri = self.router_info[router['id']] @@ -434,6 +446,7 @@ class L3NATAgent(ha.AgentMixin, self, router=ri) ri.process(self) registry.notify(resources.ROUTER, events.AFTER_UPDATE, self, router=ri) + self.l3_ext_manager.update_router(self.context, router) def _resync_router(self, router_update, priority=queue.PRIORITY_SYNC_ROUTERS_TASK): diff --git a/neutron/agent/l3/l3_agent_extension.py b/neutron/agent/l3/l3_agent_extension.py new file mode 100644 index 00000000000..ed9f0cec09a --- /dev/null +++ b/neutron/agent/l3/l3_agent_extension.py @@ -0,0 +1,55 @@ +# 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 import agent_extension + + +@six.add_metaclass(abc.ABCMeta) +class L3AgentCoreResourceExtension(agent_extension.AgentCoreResourceExtension): + """Define stable abstract interface for l3 agent extensions. + + An agent extension extends the agent core functionality. + """ + + @abc.abstractmethod + def add_router(self, context, data): + """add agent extension for router. + + Called on router create. + + :param context: rpc context + :param data: router data + """ + + @abc.abstractmethod + def update_router(self, context, data): + """Handle agent extension for update. + + Called on router update. + + :param context: rpc context + :param data: router data + """ + + @abc.abstractmethod + def delete_router(self, context, data): + """Delete router from agent extension. + + :param context: rpc context + :param data: router data + """ diff --git a/neutron/agent/l3/l3_agent_extensions_manager.py b/neutron/agent/l3/l3_agent_extensions_manager.py new file mode 100644 index 00000000000..37e8a9e9bc4 --- /dev/null +++ b/neutron/agent/l3/l3_agent_extensions_manager.py @@ -0,0 +1,72 @@ +# 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 + +from neutron._i18n import _LE +from neutron.agent import agent_extensions_manager as agent_ext_manager + +LOG = log.getLogger(__name__) + + +L3_AGENT_EXT_MANAGER_NAMESPACE = 'neutron.agent.l3.extensions' + + +def register_opts(conf): + agent_ext_manager.register_opts(conf) + + +class L3AgentExtensionsManager(agent_ext_manager.AgentExtensionsManager): + """Manage l3 agent extensions.""" + + def __init__(self, conf): + super(L3AgentExtensionsManager, self).__init__(conf, + L3_AGENT_EXT_MANAGER_NAMESPACE) + + def add_router(self, context, data): + """Notify all agent extensions to add router.""" + for extension in self: + if hasattr(self, 'add_router'): + extension.obj.add_router(context, data) + else: + LOG.error( + _LE("Agent Extension '%(name)s' does not " + "implement method add_router"), + {'name': extension.name} + ) + + def update_router(self, context, data): + """Notify all agent extensions to update router.""" + for extension in self: + if hasattr(self, 'update_router'): + extension.obj.update_router(context, data) + else: + LOG.error( + _LE("Agent Extension '%(name)s' does not " + "implement method update_router"), + {'name': extension.name} + ) + + def delete_router(self, context, data): + """Notify all agent extensions to delete router.""" + for extension in self: + if hasattr(self, 'delete_router'): + extension.obj.delete_router(context, data) + else: + LOG.error( + _LE("Agent Extension '%(name)s' does not " + "implement method delete_router"), + {'name': extension.name} + ) diff --git a/releasenotes/notes/l3-agent-extensions-b348ff26aec0fe88.yaml b/releasenotes/notes/l3-agent-extensions-b348ff26aec0fe88.yaml new file mode 100644 index 00000000000..1c2b75bd176 --- /dev/null +++ b/releasenotes/notes/l3-agent-extensions-b348ff26aec0fe88.yaml @@ -0,0 +1,5 @@ +--- +features: + - The neutron L3 agent now has the ability to load + agent extensions, which allows other services to + integrate without additional agent changes.