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
This commit is contained in:
Kevin Benton 2013-10-28 23:06:42 -07:00
parent 29e93f2248
commit 17924af7a8
5 changed files with 112 additions and 33 deletions

View File

@ -60,6 +60,8 @@ from neutron.common import rpc as q_rpc
from neutron.common import topics from neutron.common import topics
from neutron.common import utils from neutron.common import utils
from neutron import context as qcontext 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 api as db
from neutron.db import db_base_plugin_v2 from neutron.db import db_base_plugin_v2
from neutron.db import dhcp_rpc_base 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 l3
from neutron.extensions import portbindings from neutron.extensions import portbindings
from neutron.openstack.common import excutils 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 log as logging
from neutron.openstack.common import rpc from neutron.openstack.common import rpc
from neutron.plugins.bigswitch.db import porttracker_db from neutron.plugins.bigswitch.db import porttracker_db
@ -426,16 +429,19 @@ class RpcProxy(dhcp_rpc_base.DhcpRpcCallbackMixin):
RPC_API_VERSION = '1.1' RPC_API_VERSION = '1.1'
def create_rpc_dispatcher(self): 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, class NeutronRestProxyV2(db_base_plugin_v2.NeutronDbPluginV2,
external_net_db.External_net_db_mixin, external_net_db.External_net_db_mixin,
routerrule_db.RouterRule_db_mixin, routerrule_db.RouterRule_db_mixin,
extradhcpopt_db.ExtraDhcpOptMixin): extradhcpopt_db.ExtraDhcpOptMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin):
supported_extension_aliases = ["external-net", "router", "binding", 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): def __init__(self, server_timeout=None):
LOG.info(_('NeutronRestProxy: Starting plugin. Version=%s'), LOG.info(_('NeutronRestProxy: Starting plugin. Version=%s'),
@ -469,6 +475,13 @@ class NeutronRestProxyV2(db_base_plugin_v2.NeutronDbPluginV2,
# init dhcp support # init dhcp support
self.topic = topics.PLUGIN 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.conn = rpc.create_connection(new=True)
self.callbacks = RpcProxy() self.callbacks = RpcProxy()
self.dispatcher = self.callbacks.create_rpc_dispatcher() self.dispatcher = self.callbacks.create_rpc_dispatcher()
@ -479,7 +492,6 @@ class NeutronRestProxyV2(db_base_plugin_v2.NeutronDbPluginV2,
if sync_data: if sync_data:
self._send_all_data() self._send_all_data()
self._dhcp_agent_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
LOG.debug(_("NeutronRestProxyV2: initialization done")) LOG.debug(_("NeutronRestProxyV2: initialization done"))
def create_network(self, context, network): def create_network(self, context, network):

View File

@ -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()

View File

@ -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()

View File

@ -15,38 +15,27 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
from mock import patch from mock import patch
from oslo.config import cfg from oslo.config import cfg
import webob.exc import webob.exc
import neutron.common.test_lib as test_lib
from neutron import context from neutron import context
from neutron.extensions import portbindings from neutron.extensions import portbindings
from neutron.manager import NeutronManager from neutron.manager import NeutronManager
from neutron.plugins.bigswitch.plugin import RemoteRestError from neutron.plugins.bigswitch.plugin import RemoteRestError
from neutron.tests.unit import _test_extension_portbindings as test_bindings 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 fake_server
from neutron.tests.unit.bigswitch import test_base
from neutron.tests.unit import test_api_v2 from neutron.tests.unit import test_api_v2
import neutron.tests.unit.test_db_plugin as test_plugin import neutron.tests.unit.test_db_plugin as test_plugin
RESTPROXY_PKG_PATH = 'neutron.plugins.bigswitch.plugin'
class BigSwitchProxyPluginV2TestCase(test_base.BigSwitchTestBase,
class BigSwitchProxyPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): test_plugin.NeutronDbPluginV2TestCase):
_plugin_name = ('%s.NeutronRestProxyV2' % RESTPROXY_PKG_PATH)
def setUp(self): def setUp(self):
etc_path = os.path.join(os.path.dirname(__file__), 'etc') self.setup_config_files()
test_lib.test_config['config_files'] = [os.path.join(etc_path, self.setup_patches()
'restproxy.ini.test')]
self.httpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock)
self.addCleanup(self.httpPatch.stop)
self.httpPatch.start()
super(BigSwitchProxyPluginV2TestCase, super(BigSwitchProxyPluginV2TestCase,
self).setUp(self._plugin_name) self).setUp(self._plugin_name)

View File

@ -33,6 +33,7 @@ from neutron.openstack.common.notifier import api as notifier_api
from neutron.openstack.common.notifier import test_notifier from neutron.openstack.common.notifier import test_notifier
from neutron.plugins.bigswitch.extensions import routerrule from neutron.plugins.bigswitch.extensions import routerrule
from neutron.tests.unit.bigswitch import fake_server 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_api_v2
from neutron.tests.unit import test_extension_extradhcpopts as test_extradhcp from neutron.tests.unit import test_extension_extradhcpopts as test_extradhcp
from neutron.tests.unit import test_l3_plugin from neutron.tests.unit import test_l3_plugin
@ -71,33 +72,29 @@ class RouterRulesTestExtensionManager(object):
return [] return []
class DHCPOptsTestCase(test_extradhcp.TestExtraDhcpOpt): class DHCPOptsTestCase(test_base.BigSwitchTestBase,
test_extradhcp.TestExtraDhcpOpt):
def setUp(self, plugin=None): def setUp(self, plugin=None):
self.httpPatch = patch('httplib.HTTPConnection', create=True, self.setup_patches()
new=fake_server.HTTPConnectionMock) self.setup_config_files()
self.httpPatch.start() super(test_extradhcp.ExtraDhcpOptDBTestCase,
self.addCleanup(self.httpPatch.stop) self).setUp(plugin=self._plugin_name)
p_path = 'neutron.plugins.bigswitch.plugin.NeutronRestProxyV2'
super(test_extradhcp.ExtraDhcpOptDBTestCase, self).setUp(plugin=p_path)
class RouterDBTestCase(test_l3_plugin.L3NatDBIntTestCase): class RouterDBTestCase(test_base.BigSwitchTestBase,
test_l3_plugin.L3NatDBIntTestCase):
def setUp(self): def setUp(self):
self.httpPatch = patch('httplib.HTTPConnection', create=True, self.setup_patches()
new=fake_server.HTTPConnectionMock)
self.httpPatch.start()
test_l3_plugin.L3NatDBIntTestCase.setUp = new_L3_setUp test_l3_plugin.L3NatDBIntTestCase.setUp = new_L3_setUp
super(RouterDBTestCase, self).setUp() super(RouterDBTestCase, self).setUp()
self.plugin_obj = NeutronManager.get_plugin() self.plugin_obj = NeutronManager.get_plugin()
def tearDown(self): def tearDown(self):
self.httpPatch.stop()
super(RouterDBTestCase, self).tearDown() super(RouterDBTestCase, self).tearDown()
del test_config['plugin_name_v2'] del test_config['plugin_name_v2']
del test_config['config_files'] del test_config['config_files']
cfg.CONF.reset()
test_l3_plugin.L3NatDBIntTestCase.setUp = origSetUp test_l3_plugin.L3NatDBIntTestCase.setUp = origSetUp
def test_router_remove_router_interface_wrong_subnet_returns_400(self): def test_router_remove_router_interface_wrong_subnet_returns_400(self):