Merge "NEC plugin support for dhcp network and router scheduling"
This commit is contained in:
commit
efe86e7759
@ -59,6 +59,7 @@ TYPE_DICT = "dict"
|
|||||||
AGENT_TYPE_DHCP = 'DHCP agent'
|
AGENT_TYPE_DHCP = 'DHCP agent'
|
||||||
AGENT_TYPE_OVS = 'Open vSwitch agent'
|
AGENT_TYPE_OVS = 'Open vSwitch agent'
|
||||||
AGENT_TYPE_LINUXBRIDGE = 'Linux bridge agent'
|
AGENT_TYPE_LINUXBRIDGE = 'Linux bridge agent'
|
||||||
|
AGENT_TYPE_NEC = 'NEC plugin agent'
|
||||||
AGENT_TYPE_L3 = 'L3 agent'
|
AGENT_TYPE_L3 = 'L3 agent'
|
||||||
L2_AGENT_TOPIC = 'N/A'
|
L2_AGENT_TOPIC = 'N/A'
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ migration_for_plugins = [
|
|||||||
'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2',
|
'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2',
|
||||||
'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2',
|
'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2',
|
||||||
'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2',
|
'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2',
|
||||||
|
'quantum.plugins.nec.nec_plugin.NECPluginV2',
|
||||||
]
|
]
|
||||||
|
|
||||||
from alembic import op
|
from alembic import op
|
||||||
|
@ -33,6 +33,7 @@ migration_for_plugins = [
|
|||||||
'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2',
|
'quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2',
|
||||||
'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2',
|
'quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2',
|
||||||
'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2',
|
'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2',
|
||||||
|
'quantum.plugins.nec.nec_plugin.NECPluginV2',
|
||||||
]
|
]
|
||||||
|
|
||||||
from alembic import op
|
from alembic import op
|
||||||
|
@ -32,10 +32,12 @@ from quantum.agent.linux import ovs_lib
|
|||||||
from quantum.agent import rpc as agent_rpc
|
from quantum.agent import rpc as agent_rpc
|
||||||
from quantum.agent import securitygroups_rpc as sg_rpc
|
from quantum.agent import securitygroups_rpc as sg_rpc
|
||||||
from quantum.common import config as logging_config
|
from quantum.common import config as logging_config
|
||||||
|
from quantum.common import constants as q_const
|
||||||
from quantum.common import topics
|
from quantum.common import topics
|
||||||
from quantum import context as q_context
|
from quantum import context as q_context
|
||||||
from quantum.extensions import securitygroup as ext_sg
|
from quantum.extensions import securitygroup as ext_sg
|
||||||
from quantum.openstack.common import log as logging
|
from quantum.openstack.common import log as logging
|
||||||
|
from quantum.openstack.common import loopingcall
|
||||||
from quantum.openstack.common.rpc import dispatcher
|
from quantum.openstack.common.rpc import dispatcher
|
||||||
from quantum.openstack.common.rpc import proxy
|
from quantum.openstack.common.rpc import proxy
|
||||||
from quantum.plugins.nec.common import config
|
from quantum.plugins.nec.common import config
|
||||||
@ -124,8 +126,18 @@ class NECQuantumAgent(object):
|
|||||||
'''
|
'''
|
||||||
self.int_br = ovs_lib.OVSBridge(integ_br, root_helper)
|
self.int_br = ovs_lib.OVSBridge(integ_br, root_helper)
|
||||||
self.polling_interval = polling_interval
|
self.polling_interval = polling_interval
|
||||||
|
self.cur_ports = []
|
||||||
|
|
||||||
self.datapath_id = "0x%s" % self.int_br.get_datapath_id()
|
self.datapath_id = "0x%s" % self.int_br.get_datapath_id()
|
||||||
|
|
||||||
|
self.agent_state = {
|
||||||
|
'binary': 'quantum-nec-agent',
|
||||||
|
'host': config.CONF.host,
|
||||||
|
'topic': q_const.L2_AGENT_TOPIC,
|
||||||
|
'configurations': {},
|
||||||
|
'agent_type': q_const.AGENT_TYPE_NEC,
|
||||||
|
'start_flag': True}
|
||||||
|
|
||||||
self.setup_rpc()
|
self.setup_rpc()
|
||||||
|
|
||||||
def setup_rpc(self):
|
def setup_rpc(self):
|
||||||
@ -137,6 +149,7 @@ class NECQuantumAgent(object):
|
|||||||
self.context = q_context.get_admin_context_without_session()
|
self.context = q_context.get_admin_context_without_session()
|
||||||
|
|
||||||
self.plugin_rpc = NECPluginApi(topics.PLUGIN)
|
self.plugin_rpc = NECPluginApi(topics.PLUGIN)
|
||||||
|
self.state_rpc = agent_rpc.PluginReportStateAPI(topics.PLUGIN)
|
||||||
self.sg_agent = SecurityGroupAgentRpc(self.context)
|
self.sg_agent = SecurityGroupAgentRpc(self.context)
|
||||||
|
|
||||||
# RPC network init
|
# RPC network init
|
||||||
@ -154,6 +167,22 @@ class NECQuantumAgent(object):
|
|||||||
self.topic,
|
self.topic,
|
||||||
consumers)
|
consumers)
|
||||||
|
|
||||||
|
report_interval = config.CONF.AGENT.report_interval
|
||||||
|
if report_interval:
|
||||||
|
heartbeat = loopingcall.LoopingCall(self._report_state)
|
||||||
|
heartbeat.start(interval=report_interval)
|
||||||
|
|
||||||
|
def _report_state(self):
|
||||||
|
try:
|
||||||
|
# How many devices are likely used by a VM
|
||||||
|
num_devices = len(self.cur_ports)
|
||||||
|
self.agent_state['configurations']['devices'] = num_devices
|
||||||
|
self.state_rpc.report_state(self.context,
|
||||||
|
self.agent_state)
|
||||||
|
self.agent_state.pop('start_flag', None)
|
||||||
|
except Exception:
|
||||||
|
LOG.exception(_("Failed reporting state!"))
|
||||||
|
|
||||||
def _vif_port_to_port_info(self, vif_port):
|
def _vif_port_to_port_info(self, vif_port):
|
||||||
return dict(id=vif_port.vif_id, port_no=vif_port.ofport,
|
return dict(id=vif_port.vif_id, port_no=vif_port.ofport,
|
||||||
mac=vif_port.vif_mac)
|
mac=vif_port.vif_mac)
|
||||||
@ -167,7 +196,6 @@ class NECQuantumAgent(object):
|
|||||||
|
|
||||||
def daemon_loop(self):
|
def daemon_loop(self):
|
||||||
"""Main processing loop for NEC Plugin Agent."""
|
"""Main processing loop for NEC Plugin Agent."""
|
||||||
old_ports = []
|
|
||||||
while True:
|
while True:
|
||||||
new_ports = []
|
new_ports = []
|
||||||
|
|
||||||
@ -175,12 +203,12 @@ class NECQuantumAgent(object):
|
|||||||
for vif_port in self.int_br.get_vif_ports():
|
for vif_port in self.int_br.get_vif_ports():
|
||||||
port_id = vif_port.vif_id
|
port_id = vif_port.vif_id
|
||||||
new_ports.append(port_id)
|
new_ports.append(port_id)
|
||||||
if port_id not in old_ports:
|
if port_id not in self.cur_ports:
|
||||||
port_info = self._vif_port_to_port_info(vif_port)
|
port_info = self._vif_port_to_port_info(vif_port)
|
||||||
port_added.append(port_info)
|
port_added.append(port_info)
|
||||||
|
|
||||||
port_removed = []
|
port_removed = []
|
||||||
for port_id in old_ports:
|
for port_id in self.cur_ports:
|
||||||
if port_id not in new_ports:
|
if port_id not in new_ports:
|
||||||
port_removed.append(port_id)
|
port_removed.append(port_id)
|
||||||
|
|
||||||
@ -192,7 +220,7 @@ class NECQuantumAgent(object):
|
|||||||
else:
|
else:
|
||||||
LOG.debug(_("No port changed."))
|
LOG.debug(_("No port changed."))
|
||||||
|
|
||||||
old_ports = new_ports
|
self.cur_ports = new_ports
|
||||||
time.sleep(self.polling_interval)
|
time.sleep(self.polling_interval)
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ from oslo.config import cfg
|
|||||||
from quantum.agent.common import config
|
from quantum.agent.common import config
|
||||||
# import rpc config options
|
# import rpc config options
|
||||||
from quantum.openstack.common import rpc
|
from quantum.openstack.common import rpc
|
||||||
|
from quantum import scheduler
|
||||||
|
|
||||||
|
|
||||||
ovs_opts = [
|
ovs_opts = [
|
||||||
@ -54,7 +55,9 @@ ofc_opts = [
|
|||||||
cfg.CONF.register_opts(ovs_opts, "OVS")
|
cfg.CONF.register_opts(ovs_opts, "OVS")
|
||||||
cfg.CONF.register_opts(agent_opts, "AGENT")
|
cfg.CONF.register_opts(agent_opts, "AGENT")
|
||||||
cfg.CONF.register_opts(ofc_opts, "OFC")
|
cfg.CONF.register_opts(ofc_opts, "OFC")
|
||||||
|
config.register_agent_state_opts_helper(cfg.CONF)
|
||||||
config.register_root_helper(cfg.CONF)
|
config.register_root_helper(cfg.CONF)
|
||||||
|
cfg.CONF.register_opts(scheduler.AGENTS_SCHEDULER_OPTS)
|
||||||
|
|
||||||
# shortcuts
|
# shortcuts
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
@ -17,11 +17,15 @@
|
|||||||
# @author: Akihiro MOTOKI
|
# @author: Akihiro MOTOKI
|
||||||
|
|
||||||
from quantum.agent import securitygroups_rpc as sg_rpc
|
from quantum.agent import securitygroups_rpc as sg_rpc
|
||||||
|
from quantum.api.rpc.agentnotifiers import dhcp_rpc_agent_api
|
||||||
|
from quantum.api.rpc.agentnotifiers import l3_rpc_agent_api
|
||||||
from quantum.common import constants as q_const
|
from quantum.common import constants as q_const
|
||||||
from quantum.common import exceptions as q_exc
|
from quantum.common import exceptions as q_exc
|
||||||
from quantum.common import rpc as q_rpc
|
from quantum.common import rpc as q_rpc
|
||||||
from quantum.common import topics
|
from quantum.common import topics
|
||||||
from quantum import context
|
from quantum import context
|
||||||
|
from quantum.db import agents_db
|
||||||
|
from quantum.db import agentschedulers_db
|
||||||
from quantum.db import dhcp_rpc_base
|
from quantum.db import dhcp_rpc_base
|
||||||
from quantum.db import extraroute_db
|
from quantum.db import extraroute_db
|
||||||
from quantum.db import l3_rpc_base
|
from quantum.db import l3_rpc_base
|
||||||
@ -30,6 +34,7 @@ from quantum.db import quota_db
|
|||||||
from quantum.db import securitygroups_rpc_base as sg_db_rpc
|
from quantum.db import securitygroups_rpc_base as sg_db_rpc
|
||||||
from quantum.extensions import portbindings
|
from quantum.extensions import portbindings
|
||||||
from quantum.extensions import securitygroup as ext_sg
|
from quantum.extensions import securitygroup as ext_sg
|
||||||
|
from quantum.openstack.common import importutils
|
||||||
from quantum.openstack.common import log as logging
|
from quantum.openstack.common import log as logging
|
||||||
from quantum.openstack.common import rpc
|
from quantum.openstack.common import rpc
|
||||||
from quantum.openstack.common.rpc import proxy
|
from quantum.openstack.common.rpc import proxy
|
||||||
@ -60,7 +65,8 @@ class OperationalStatus:
|
|||||||
|
|
||||||
class NECPluginV2(nec_plugin_base.NECPluginV2Base,
|
class NECPluginV2(nec_plugin_base.NECPluginV2Base,
|
||||||
extraroute_db.ExtraRoute_db_mixin,
|
extraroute_db.ExtraRoute_db_mixin,
|
||||||
sg_db_rpc.SecurityGroupServerRpcMixin):
|
sg_db_rpc.SecurityGroupServerRpcMixin,
|
||||||
|
agentschedulers_db.AgentSchedulerDbMixin):
|
||||||
"""NECPluginV2 controls an OpenFlow Controller.
|
"""NECPluginV2 controls an OpenFlow Controller.
|
||||||
|
|
||||||
The Quantum NECPluginV2 maps L2 logical networks to L2 virtualized networks
|
The Quantum NECPluginV2 maps L2 logical networks to L2 virtualized networks
|
||||||
@ -75,7 +81,9 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
supported_extension_aliases = ["router", "quotas", "binding",
|
supported_extension_aliases = ["router", "quotas", "binding",
|
||||||
"security-group", "extraroute"]
|
"security-group", "extraroute",
|
||||||
|
"agent", "agent_scheduler",
|
||||||
|
]
|
||||||
|
|
||||||
binding_view = "extension:port_binding:view"
|
binding_view = "extension:port_binding:view"
|
||||||
binding_set = "extension:port_binding:set"
|
binding_set = "extension:port_binding:set"
|
||||||
@ -97,17 +105,24 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
|
|||||||
|
|
||||||
self.setup_rpc()
|
self.setup_rpc()
|
||||||
|
|
||||||
|
self.network_scheduler = importutils.import_object(
|
||||||
|
config.CONF.network_scheduler_driver)
|
||||||
|
self.router_scheduler = importutils.import_object(
|
||||||
|
config.CONF.router_scheduler_driver)
|
||||||
|
|
||||||
def setup_rpc(self):
|
def setup_rpc(self):
|
||||||
self.topic = topics.PLUGIN
|
self.topic = topics.PLUGIN
|
||||||
self.conn = rpc.create_connection(new=True)
|
self.conn = rpc.create_connection(new=True)
|
||||||
self.notifier = NECPluginV2AgentNotifierApi(topics.AGENT)
|
self.notifier = NECPluginV2AgentNotifierApi(topics.AGENT)
|
||||||
|
self.dhcp_agent_notifier = dhcp_rpc_agent_api.DhcpAgentNotifyAPI()
|
||||||
|
self.l3_agent_notifier = l3_rpc_agent_api.L3AgentNotify
|
||||||
|
|
||||||
self.callback_nec = NECPluginV2RPCCallbacks(self)
|
# NOTE: callback_sg is referred to from the sg unit test.
|
||||||
self.callback_dhcp = DhcpRpcCallback()
|
|
||||||
self.callback_l3 = L3RpcCallback()
|
|
||||||
self.callback_sg = SecurityGroupServerRpcCallback()
|
self.callback_sg = SecurityGroupServerRpcCallback()
|
||||||
callbacks = [self.callback_nec, self.callback_dhcp,
|
callbacks = [NECPluginV2RPCCallbacks(self),
|
||||||
self.callback_l3, self.callback_sg]
|
DhcpRpcCallback(), L3RpcCallback(),
|
||||||
|
self.callback_sg,
|
||||||
|
agents_db.AgentExtRpcCallback()]
|
||||||
self.dispatcher = q_rpc.PluginRpcDispatcher(callbacks)
|
self.dispatcher = q_rpc.PluginRpcDispatcher(callbacks)
|
||||||
self.conn.create_consumer(self.topic, self.dispatcher, fanout=False)
|
self.conn.create_consumer(self.topic, self.dispatcher, fanout=False)
|
||||||
# Consume from all consumers in a thread
|
# Consume from all consumers in a thread
|
||||||
|
34
quantum/tests/unit/nec/test_agent_scheduler.py
Normal file
34
quantum/tests/unit/nec/test_agent_scheduler.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013 NEC Corporation. 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 quantum.tests.unit.openvswitch import test_agent_scheduler
|
||||||
|
from quantum.tests.unit.nec import test_nec_plugin
|
||||||
|
|
||||||
|
|
||||||
|
class NecAgentSchedulerTestCase(
|
||||||
|
test_agent_scheduler.OvsAgentSchedulerTestCase):
|
||||||
|
plugin_str = test_nec_plugin.PLUGIN_NAME
|
||||||
|
|
||||||
|
|
||||||
|
class NecDhcpAgentNotifierTestCase(
|
||||||
|
test_agent_scheduler.OvsDhcpAgentNotifierTestCase):
|
||||||
|
plugin_str = test_nec_plugin.PLUGIN_NAME
|
||||||
|
|
||||||
|
|
||||||
|
class NecL3AgentNotifierTestCase(
|
||||||
|
test_agent_scheduler.OvsL3AgentNotifierTestCase):
|
||||||
|
plugin_str = test_nec_plugin.PLUGIN_NAME
|
@ -18,9 +18,12 @@ from quantum.tests.unit import _test_extension_portbindings as test_bindings
|
|||||||
from quantum.tests.unit import test_db_plugin as test_plugin
|
from quantum.tests.unit import test_db_plugin as test_plugin
|
||||||
|
|
||||||
|
|
||||||
|
PLUGIN_NAME = 'quantum.plugins.nec.nec_plugin.NECPluginV2'
|
||||||
|
|
||||||
|
|
||||||
class NecPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase):
|
class NecPluginV2TestCase(test_plugin.QuantumDbPluginV2TestCase):
|
||||||
|
|
||||||
_plugin_name = 'quantum.plugins.nec.nec_plugin.NECPluginV2'
|
_plugin_name = PLUGIN_NAME
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(NecPluginV2TestCase, self).setUp(self._plugin_name)
|
super(NecPluginV2TestCase, self).setUp(self._plugin_name)
|
||||||
|
Loading…
Reference in New Issue
Block a user