From 17924af7a8b9097bdc7a9082eb99819514498d0a Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Mon, 28 Oct 2013 23:06:42 -0700 Subject: [PATCH] DHCP agent scheduler support for BigSwitch plugin Adds support for the Neutron DHCP agent scheduler to the BigSwitch plugin to support multiple neutron DHCP agents. Implements: blueprint bsn-dhcp-agent-scheduler Change-Id: I629ce73c0b97c2409b37afb85639282a116560b7 --- neutron/plugins/bigswitch/plugin.py | 20 ++++++-- .../unit/bigswitch/test_agent_scheduler.py | 32 ++++++++++++ neutron/tests/unit/bigswitch/test_base.py | 49 +++++++++++++++++++ .../unit/bigswitch/test_restproxy_plugin.py | 21 ++------ .../tests/unit/bigswitch/test_router_db.py | 23 ++++----- 5 files changed, 112 insertions(+), 33 deletions(-) create mode 100644 neutron/tests/unit/bigswitch/test_agent_scheduler.py create mode 100644 neutron/tests/unit/bigswitch/test_base.py diff --git a/neutron/plugins/bigswitch/plugin.py b/neutron/plugins/bigswitch/plugin.py index fe793b6e0..b5e272e73 100644 --- a/neutron/plugins/bigswitch/plugin.py +++ b/neutron/plugins/bigswitch/plugin.py @@ -60,6 +60,8 @@ from neutron.common import rpc as q_rpc from neutron.common import topics from neutron.common import utils from neutron import context as qcontext +from neutron.db import agents_db +from neutron.db import agentschedulers_db from neutron.db import api as db from neutron.db import db_base_plugin_v2 from neutron.db import dhcp_rpc_base @@ -71,6 +73,7 @@ from neutron.extensions import extra_dhcp_opt as edo_ext from neutron.extensions import l3 from neutron.extensions import portbindings from neutron.openstack.common import excutils +from neutron.openstack.common import importutils from neutron.openstack.common import log as logging from neutron.openstack.common import rpc from neutron.plugins.bigswitch.db import porttracker_db @@ -426,16 +429,19 @@ class RpcProxy(dhcp_rpc_base.DhcpRpcCallbackMixin): RPC_API_VERSION = '1.1' def create_rpc_dispatcher(self): - return q_rpc.PluginRpcDispatcher([self]) + return q_rpc.PluginRpcDispatcher([self, + agents_db.AgentExtRpcCallback()]) class NeutronRestProxyV2(db_base_plugin_v2.NeutronDbPluginV2, external_net_db.External_net_db_mixin, routerrule_db.RouterRule_db_mixin, - extradhcpopt_db.ExtraDhcpOptMixin): + extradhcpopt_db.ExtraDhcpOptMixin, + agentschedulers_db.DhcpAgentSchedulerDbMixin): supported_extension_aliases = ["external-net", "router", "binding", - "router_rules", "extra_dhcp_opt"] + "router_rules", "extra_dhcp_opt", + "dhcp_agent_scheduler", "agent"] def __init__(self, server_timeout=None): LOG.info(_('NeutronRestProxy: Starting plugin. Version=%s'), @@ -469,6 +475,13 @@ class NeutronRestProxyV2(db_base_plugin_v2.NeutronDbPluginV2, # init dhcp support self.topic = topics.PLUGIN + self.network_scheduler = importutils.import_object( + cfg.CONF.network_scheduler_driver + ) + self._dhcp_agent_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI() + self.agent_notifiers[const.AGENT_TYPE_DHCP] = ( + self._dhcp_agent_notifier + ) self.conn = rpc.create_connection(new=True) self.callbacks = RpcProxy() self.dispatcher = self.callbacks.create_rpc_dispatcher() @@ -479,7 +492,6 @@ class NeutronRestProxyV2(db_base_plugin_v2.NeutronDbPluginV2, if sync_data: self._send_all_data() - self._dhcp_agent_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI() LOG.debug(_("NeutronRestProxyV2: initialization done")) def create_network(self, context, network): diff --git a/neutron/tests/unit/bigswitch/test_agent_scheduler.py b/neutron/tests/unit/bigswitch/test_agent_scheduler.py new file mode 100644 index 000000000..fe348eb1e --- /dev/null +++ b/neutron/tests/unit/bigswitch/test_agent_scheduler.py @@ -0,0 +1,32 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2013 Big Switch Networks, Inc. +# +# 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 neutron.tests.unit.bigswitch import test_base +from neutron.tests.unit.openvswitch import test_agent_scheduler + + +class BigSwitchDhcpAgentNotifierTestCase( + test_agent_scheduler.OvsDhcpAgentNotifierTestCase, + test_base.BigSwitchTestBase): + + plugin_str = ('%s.NeutronRestProxyV2' % + test_base.RESTPROXY_PKG_PATH) + + def setUp(self): + self.setup_config_files() + self.setup_patches() + super(BigSwitchDhcpAgentNotifierTestCase, self).setUp() diff --git a/neutron/tests/unit/bigswitch/test_base.py b/neutron/tests/unit/bigswitch/test_base.py new file mode 100644 index 000000000..1797c5105 --- /dev/null +++ b/neutron/tests/unit/bigswitch/test_base.py @@ -0,0 +1,49 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2013 Big Switch Networks, Inc. +# 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 os + +from mock import patch +from oslo.config import cfg + +import neutron.common.test_lib as test_lib +from neutron.db import api as db +from neutron.tests.unit.bigswitch import fake_server + +RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.plugin' +NOTIFIER = 'neutron.plugins.bigswitch.plugin.RpcProxy' + + +class BigSwitchTestBase(object): + + _plugin_name = ('%s.NeutronRestProxyV2' % RESTPROXY_PKG_PATH) + + def setup_config_files(self): + etc_path = os.path.join(os.path.dirname(__file__), 'etc') + test_lib.test_config['config_files'] = [os.path.join(etc_path, + 'restproxy.ini.test')] + self.addCleanup(cfg.CONF.reset) + + def setup_patches(self): + self.httpPatch = patch('httplib.HTTPConnection', create=True, + new=fake_server.HTTPConnectionMock) + self.plugin_notifier_p = patch(NOTIFIER) + self.addCleanup(self.plugin_notifier_p.stop) + self.addCleanup(self.httpPatch.stop) + self.addCleanup(db.clear_db) + self.plugin_notifier_p.start() + self.httpPatch.start() diff --git a/neutron/tests/unit/bigswitch/test_restproxy_plugin.py b/neutron/tests/unit/bigswitch/test_restproxy_plugin.py index 6107d9369..a1b49ea00 100644 --- a/neutron/tests/unit/bigswitch/test_restproxy_plugin.py +++ b/neutron/tests/unit/bigswitch/test_restproxy_plugin.py @@ -15,38 +15,27 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os - from mock import patch from oslo.config import cfg import webob.exc -import neutron.common.test_lib as test_lib from neutron import context from neutron.extensions import portbindings from neutron.manager import NeutronManager from neutron.plugins.bigswitch.plugin import RemoteRestError from neutron.tests.unit import _test_extension_portbindings as test_bindings from neutron.tests.unit.bigswitch import fake_server +from neutron.tests.unit.bigswitch import test_base from neutron.tests.unit import test_api_v2 import neutron.tests.unit.test_db_plugin as test_plugin -RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.plugin' - - -class BigSwitchProxyPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): - _plugin_name = ('%s.NeutronRestProxyV2' % RESTPROXY_PKG_PATH) +class BigSwitchProxyPluginV2TestCase(test_base.BigSwitchTestBase, + test_plugin.NeutronDbPluginV2TestCase): def setUp(self): - etc_path = os.path.join(os.path.dirname(__file__), 'etc') - test_lib.test_config['config_files'] = [os.path.join(etc_path, - 'restproxy.ini.test')] - - self.httpPatch = patch('httplib.HTTPConnection', create=True, - new=fake_server.HTTPConnectionMock) - self.addCleanup(self.httpPatch.stop) - self.httpPatch.start() + self.setup_config_files() + self.setup_patches() super(BigSwitchProxyPluginV2TestCase, self).setUp(self._plugin_name) diff --git a/neutron/tests/unit/bigswitch/test_router_db.py b/neutron/tests/unit/bigswitch/test_router_db.py index d7e4a97a7..d062d3882 100644 --- a/neutron/tests/unit/bigswitch/test_router_db.py +++ b/neutron/tests/unit/bigswitch/test_router_db.py @@ -33,6 +33,7 @@ from neutron.openstack.common.notifier import api as notifier_api from neutron.openstack.common.notifier import test_notifier from neutron.plugins.bigswitch.extensions import routerrule from neutron.tests.unit.bigswitch import fake_server +from neutron.tests.unit.bigswitch import test_base from neutron.tests.unit import test_api_v2 from neutron.tests.unit import test_extension_extradhcpopts as test_extradhcp from neutron.tests.unit import test_l3_plugin @@ -71,33 +72,29 @@ class RouterRulesTestExtensionManager(object): return [] -class DHCPOptsTestCase(test_extradhcp.TestExtraDhcpOpt): +class DHCPOptsTestCase(test_base.BigSwitchTestBase, + test_extradhcp.TestExtraDhcpOpt): def setUp(self, plugin=None): - self.httpPatch = patch('httplib.HTTPConnection', create=True, - new=fake_server.HTTPConnectionMock) - self.httpPatch.start() - self.addCleanup(self.httpPatch.stop) - p_path = 'neutron.plugins.bigswitch.plugin.NeutronRestProxyV2' - super(test_extradhcp.ExtraDhcpOptDBTestCase, self).setUp(plugin=p_path) + self.setup_patches() + self.setup_config_files() + super(test_extradhcp.ExtraDhcpOptDBTestCase, + self).setUp(plugin=self._plugin_name) -class RouterDBTestCase(test_l3_plugin.L3NatDBIntTestCase): +class RouterDBTestCase(test_base.BigSwitchTestBase, + test_l3_plugin.L3NatDBIntTestCase): def setUp(self): - self.httpPatch = patch('httplib.HTTPConnection', create=True, - new=fake_server.HTTPConnectionMock) - self.httpPatch.start() + self.setup_patches() test_l3_plugin.L3NatDBIntTestCase.setUp = new_L3_setUp super(RouterDBTestCase, self).setUp() self.plugin_obj = NeutronManager.get_plugin() def tearDown(self): - self.httpPatch.stop() super(RouterDBTestCase, self).tearDown() del test_config['plugin_name_v2'] del test_config['config_files'] - cfg.CONF.reset() test_l3_plugin.L3NatDBIntTestCase.setUp = origSetUp def test_router_remove_router_interface_wrong_subnet_returns_400(self): -- 2.45.2