Add agent-side driver scaffolding for trunk functionality
The agent code is enhanced to allow the trunk agent-side counterpart to be activated seamlessly by means or local registry notifications. Some integration with the server side is provided by loading the RPC agent-side skeleton. Basic unit testing provides some coverage. More effective functional and system coverage will be provided once everything comes together. Partially-implements: blueprint vlan-aware-vms Co-Authored-By: Adolfo Duarte <adolfo.duarte@hpe.com> Change-Id: Id70553e8980593f99548a4d2b0a78355933f7c2c
This commit is contained in:
parent
e47da4edf5
commit
e354599134
29
neutron/plugins/ml2/drivers/agent/capabilities.py
Normal file
29
neutron/plugins/ml2/drivers/agent/capabilities.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# 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.callbacks import events
|
||||||
|
from neutron.callbacks import registry
|
||||||
|
|
||||||
|
|
||||||
|
def notify_init_event(agent_type, agent):
|
||||||
|
"""Notify init event for the specified agent."""
|
||||||
|
registry.notify(agent_type, events.AFTER_INIT, agent, agent=agent)
|
||||||
|
|
||||||
|
|
||||||
|
def register(callback, agent_type):
|
||||||
|
"""Subscribe callback to init event for the specified agent.
|
||||||
|
|
||||||
|
:param agent_type: an agent type as defined in neutron_lib.constants.
|
||||||
|
:param callback: a callback that can process the agent init event.
|
||||||
|
"""
|
||||||
|
registry.subscribe(callback, agent_type, events.AFTER_INIT)
|
@ -0,0 +1,23 @@
|
|||||||
|
# Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# 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_lib import constants
|
||||||
|
|
||||||
|
from neutron.plugins.ml2.drivers.agent import capabilities
|
||||||
|
from neutron.services.trunk.drivers.openvswitch.agent import driver
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
"""Register OVS capabilities."""
|
||||||
|
# Add capabilities to be loaded during agent initialization
|
||||||
|
capabilities.register(driver.init_handler, constants.AGENT_TYPE_OVS)
|
@ -52,11 +52,14 @@ from neutron import context
|
|||||||
from neutron.extensions import portbindings
|
from neutron.extensions import portbindings
|
||||||
from neutron.plugins.common import constants as p_const
|
from neutron.plugins.common import constants as p_const
|
||||||
from neutron.plugins.common import utils as p_utils
|
from neutron.plugins.common import utils as p_utils
|
||||||
|
from neutron.plugins.ml2.drivers.agent import capabilities
|
||||||
from neutron.plugins.ml2.drivers.l2pop.rpc_manager import l2population_rpc
|
from neutron.plugins.ml2.drivers.l2pop.rpc_manager import l2population_rpc
|
||||||
from neutron.plugins.ml2.drivers.openvswitch.agent.common \
|
from neutron.plugins.ml2.drivers.openvswitch.agent.common \
|
||||||
import constants
|
import constants
|
||||||
from neutron.plugins.ml2.drivers.openvswitch.agent \
|
from neutron.plugins.ml2.drivers.openvswitch.agent \
|
||||||
import ovs_agent_extension_api as ovs_ext_api
|
import ovs_agent_extension_api as ovs_ext_api
|
||||||
|
from neutron.plugins.ml2.drivers.openvswitch.agent \
|
||||||
|
import ovs_capabilities
|
||||||
from neutron.plugins.ml2.drivers.openvswitch.agent \
|
from neutron.plugins.ml2.drivers.openvswitch.agent \
|
||||||
import ovs_dvr_neutron_agent
|
import ovs_dvr_neutron_agent
|
||||||
from neutron.plugins.ml2.drivers.openvswitch.agent import vlanmanager
|
from neutron.plugins.ml2.drivers.openvswitch.agent import vlanmanager
|
||||||
@ -2152,10 +2155,12 @@ def prepare_xen_compute():
|
|||||||
|
|
||||||
def main(bridge_classes):
|
def main(bridge_classes):
|
||||||
prepare_xen_compute()
|
prepare_xen_compute()
|
||||||
|
ovs_capabilities.register()
|
||||||
validate_tunnel_config(cfg.CONF.AGENT.tunnel_types, cfg.CONF.OVS.local_ip)
|
validate_tunnel_config(cfg.CONF.AGENT.tunnel_types, cfg.CONF.OVS.local_ip)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
agent = OVSNeutronAgent(bridge_classes, cfg.CONF)
|
agent = OVSNeutronAgent(bridge_classes, cfg.CONF)
|
||||||
|
capabilities.notify_init_event(n_const.AGENT_TYPE_OVS, agent)
|
||||||
except (RuntimeError, ValueError) as e:
|
except (RuntimeError, ValueError) as e:
|
||||||
LOG.error(_LE("%s Agent terminated!"), e)
|
LOG.error(_LE("%s Agent terminated!"), e)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
46
neutron/services/trunk/drivers/openvswitch/agent/driver.py
Normal file
46
neutron/services/trunk/drivers/openvswitch/agent/driver.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# 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 as logging
|
||||||
|
|
||||||
|
from neutron.api.rpc.callbacks.consumer import registry
|
||||||
|
from neutron.api.rpc.callbacks import resources
|
||||||
|
from neutron.services.trunk.rpc import agent
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
TRUNK_SKELETON = None
|
||||||
|
|
||||||
|
|
||||||
|
class OVSTrunkSkeleton(agent.TrunkSkeleton):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(OVSTrunkSkeleton, self).__init__()
|
||||||
|
registry.unsubscribe(self.handle_trunks, resources.TRUNK)
|
||||||
|
|
||||||
|
def handle_trunks(self, trunk, event_type):
|
||||||
|
"""This method is not required by the OVS Agent driver.
|
||||||
|
|
||||||
|
Trunk notifications are handled via local OVSDB events.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def handle_subports(self, subports, event_type):
|
||||||
|
# TODO(armax): call into TrunkManager to wire the subports
|
||||||
|
LOG.debug("Event %s for subports: %s", event_type, subports)
|
||||||
|
|
||||||
|
|
||||||
|
def init_handler(resource, event, trigger, agent=None):
|
||||||
|
"""Handler for agent init event."""
|
||||||
|
# Set up agent-side RPC for receiving trunk events; we may want to
|
||||||
|
# make this setup conditional based on server-side capabilities.
|
||||||
|
global TRUNK_SKELETON
|
||||||
|
TRUNK_SKELETON = OVSTrunkSkeleton()
|
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from neutron.callbacks import events
|
||||||
|
from neutron.plugins.ml2.drivers.agent import capabilities
|
||||||
|
from neutron.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
class CapabilitiesTest(base.BaseTestCase):
|
||||||
|
|
||||||
|
@mock.patch("neutron.callbacks.manager.CallbacksManager.notify")
|
||||||
|
def test_notify_init_event(self, mocked_manager):
|
||||||
|
mock_agent_type = mock.Mock()
|
||||||
|
mock_agent = mock.Mock()
|
||||||
|
capabilities.notify_init_event(mock_agent_type, mock_agent)
|
||||||
|
mocked_manager.assert_called_with(mock_agent_type,
|
||||||
|
events.AFTER_INIT,
|
||||||
|
mock_agent,
|
||||||
|
agent=mock_agent)
|
||||||
|
|
||||||
|
@mock.patch("neutron.callbacks.manager.CallbacksManager.subscribe")
|
||||||
|
def test_register(self, mocked_subscribe):
|
||||||
|
mock_callback = mock.Mock()
|
||||||
|
mock_agent_type = mock.Mock()
|
||||||
|
capabilities.register(mock_callback, mock_agent_type)
|
||||||
|
mocked_subscribe.assert_called_with(mock_callback,
|
||||||
|
mock_agent_type,
|
||||||
|
events.AFTER_INIT)
|
@ -0,0 +1,30 @@
|
|||||||
|
# Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from neutron.callbacks import events
|
||||||
|
from neutron.plugins.ml2.drivers.openvswitch.agent import ovs_capabilities
|
||||||
|
from neutron.services.trunk.drivers.openvswitch.agent import driver
|
||||||
|
from neutron.tests import base
|
||||||
|
from neutron_lib import constants
|
||||||
|
|
||||||
|
|
||||||
|
class CapabilitiesTest(base.BaseTestCase):
|
||||||
|
|
||||||
|
@mock.patch("neutron.callbacks.manager.CallbacksManager.subscribe")
|
||||||
|
def test_register(self, mocked_subscribe):
|
||||||
|
ovs_capabilities.register()
|
||||||
|
mocked_subscribe.assert_called_with(driver.init_handler,
|
||||||
|
constants.AGENT_TYPE_OVS,
|
||||||
|
events.AFTER_INIT)
|
@ -0,0 +1,28 @@
|
|||||||
|
# Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from neutron.api.rpc.callbacks import resources
|
||||||
|
from neutron.services.trunk.drivers.openvswitch.agent import driver
|
||||||
|
from neutron.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
class OvsTrunkSkeletonTest(base.BaseTestCase):
|
||||||
|
|
||||||
|
@mock.patch("neutron.api.rpc.callbacks.resource_manager."
|
||||||
|
"ConsumerResourceCallbacksManager.unregister")
|
||||||
|
def test___init__(self, mocked_unregister):
|
||||||
|
test_obj = driver.OVSTrunkSkeleton()
|
||||||
|
mocked_unregister.assert_called_with(test_obj.handle_trunks,
|
||||||
|
resources.TRUNK)
|
Loading…
Reference in New Issue
Block a user