From ea02f25fbef43580c619eb778aab3dc874427eef Mon Sep 17 00:00:00 2001 From: Moshe Levi Date: Wed, 15 Jul 2015 11:13:50 +0300 Subject: [PATCH] Update OVS Agent to work with Agent Extension Mgr Change-Id: I1887d402a4377babb648182727cf51b9f2627e1c --- neutron/agent/l2/agent_extension.py | 6 +- neutron/agent/l2/agent_extensions_manager.py | 9 ++- neutron/agent/l2/extensions/qos_agent.py | 8 +-- neutron/agent/l2/l2_agent.py | 55 ------------------- .../openvswitch/agent/ovs_neutron_agent.py | 8 +++ .../agent/l2/extensions/test_qos_agent.py | 7 +-- .../agent/test_ovs_neutron_agent.py | 7 ++- 7 files changed, 29 insertions(+), 71 deletions(-) delete mode 100644 neutron/agent/l2/l2_agent.py diff --git a/neutron/agent/l2/agent_extension.py b/neutron/agent/l2/agent_extension.py index 50137d49f..4cc3d35d5 100644 --- a/neutron/agent/l2/agent_extension.py +++ b/neutron/agent/l2/agent_extension.py @@ -25,16 +25,14 @@ class AgentCoreResourceExtension(object): An agent extension extends the agent core functionality. """ - def initialize(self, resource_rpc): + def initialize(self): """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 + pass def handle_network(self, context, data): """handle agent extension for network. diff --git a/neutron/agent/l2/agent_extensions_manager.py b/neutron/agent/l2/agent_extensions_manager.py index 622dbc0bd..869849e78 100644 --- a/neutron/agent/l2/agent_extensions_manager.py +++ b/neutron/agent/l2/agent_extensions_manager.py @@ -25,10 +25,13 @@ LOG = log.getLogger(__name__) class AgentExtensionsManager(stevedore.named.NamedExtensionManager): """Manage agent extensions.""" - def __init__(self, agent_extensions): + def __init__(self): # Ordered list of agent extensions, defining # the order in which the agent extensions are called. + #TODO(QoS): get extensions from config + agent_extensions = ('qos', ) + LOG.info(_LI("Configured agent extensions names: %s"), agent_extensions) @@ -49,11 +52,11 @@ class AgentExtensionsManager(stevedore.named.NamedExtensionManager): {'name': extension.name, 'method': method_name} ) - def initialize(self, resource_rpc): + def initialize(self): # 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) + extension.obj.initialize() def handle_network(self, context, data): """Notify all agent extensions to handle network.""" diff --git a/neutron/agent/l2/extensions/qos_agent.py b/neutron/agent/l2/extensions/qos_agent.py index a013ed8de..d39c60041 100644 --- a/neutron/agent/l2/extensions/qos_agent.py +++ b/neutron/agent/l2/extensions/qos_agent.py @@ -21,6 +21,7 @@ import six from neutron.agent.l2 import agent_extension from neutron.api.rpc.callbacks import resources +from neutron.api.rpc.handlers import resources_rpc from neutron import manager @@ -69,14 +70,13 @@ class QosAgentDriver(object): class QosAgentExtension(agent_extension.AgentCoreResourceExtension): - def initialize(self, resource_rpc): + def initialize(self): """Perform Agent Extension initialization. - :param resource_rpc: the agent side rpc for getting - resource by type and id """ - super(QosAgentExtension, self).initialize(resource_rpc) + super(QosAgentExtension, self).initialize() + self.resource_rpc = resources_rpc.ResourcesServerRpcApi() self.qos_driver = manager.NeutronManager.load_class_for_provider( 'neutron.qos.agent_drivers', cfg.CONF.qos.agent_driver)() self.qos_driver.initialize() diff --git a/neutron/agent/l2/l2_agent.py b/neutron/agent/l2/l2_agent.py deleted file mode 100644 index 0ee6c9c74..000000000 --- a/neutron/agent/l2/l2_agent.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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) diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py index 4ca342360..ead0f59e4 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py @@ -30,6 +30,7 @@ from six import moves from neutron.agent.common import ovs_lib from neutron.agent.common import polling from neutron.agent.common import utils +from neutron.agent.l2 import agent_extensions_manager from neutron.agent.linux import ip_lib from neutron.agent import rpc as agent_rpc from neutron.agent import securitygroups_rpc as sg_rpc @@ -226,6 +227,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, # keeps association between ports and ofports to detect ofport change self.vifname_to_ofport_map = {} self.setup_rpc() + self.init_agent_extensions_mgr() self.bridge_mappings = bridge_mappings self.setup_physical_bridges(self.bridge_mappings) self.local_vlan_map = {} @@ -361,6 +363,11 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, consumers, start_listening=False) + def init_agent_extensions_mgr(self): + self.agent_extensions_mgr = ( + agent_extensions_manager.AgentExtensionsManager()) + self.agent_extensions_mgr.initialize() + def get_net_uuid(self, vif_id): for network_id, vlan_mapping in six.iteritems(self.local_vlan_map): if vif_id in vlan_mapping.vif_ports: @@ -1237,6 +1244,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, if need_binding: details['vif_port'] = port need_binding_devices.append(details) + self.agent_extensions_mgr.handle_port(self.context, details) else: LOG.warn(_LW("Device %s not defined on plugin"), device) if (port and port.ofport != -1): diff --git a/neutron/tests/unit/agent/l2/extensions/test_qos_agent.py b/neutron/tests/unit/agent/l2/extensions/test_qos_agent.py index 46c2f061d..36098caf4 100755 --- a/neutron/tests/unit/agent/l2/extensions/test_qos_agent.py +++ b/neutron/tests/unit/agent/l2/extensions/test_qos_agent.py @@ -39,13 +39,12 @@ class QosAgentExtensionTestCase(base.BaseTestCase): return_value=lambda: mock.Mock(spec=qos_agent.QosAgentDriver) ).start() + self.qos_agent.initialize() self._create_fake_resource_rpc() - self.qos_agent.initialize(self.resource_rpc_mock) def _create_fake_resource_rpc(self): self.get_info_mock = mock.Mock(return_value=TEST_GET_INFO_RULES) - self.resource_rpc_mock = mock.Mock() - self.resource_rpc_mock.get_info = self.get_info_mock + self.qos_agent.resource_rpc.get_info = self.get_info_mock def _create_test_port_dict(self): return {'port_id': uuidutils.generate_uuid(), @@ -82,7 +81,7 @@ class QosAgentExtensionTestCase(base.BaseTestCase): def test_handle_known_port_change_policy_id(self): port = self._create_test_port_dict() self.qos_agent.handle_port(self.context, port) - self.resource_rpc_mock.get_info.reset_mock() + self.qos_agent.resource_rpc.get_info.reset_mock() port['qos_policy_id'] = uuidutils.generate_uuid() self.qos_agent.handle_port(self.context, port) self.get_info_mock.assert_called_once_with( diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py index 19bcd520d..ca1f48a3c 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py @@ -374,7 +374,12 @@ class TestOvsNeutronAgent(object): return_value=None): self.assertFalse(get_dev_fn.called) - def test_treat_devices_added_updated_updates_known_port(self): + #TODO(QoS) that this mock should go away once we don't hardcode + #qos extension. + @mock.patch('neutron.api.rpc.handlers.resources_rpc.' + 'ResourcesServerRpcApi.get_info', return_value=[]) + def test_treat_devices_added_updated_updates_known_port( + self, *args): details = mock.MagicMock() details.__contains__.side_effect = lambda x: True self.assertTrue(self._mock_treat_devices_added_updated( -- 2.45.2