commit
9546ee7d92
@ -0,0 +1,204 @@
|
||||
# Copyright (c) 2016 IBM Corp.
|
||||
#
|
||||
# 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
|
||||
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NetworkSegment(object):
|
||||
"""Represents a Neutron network segment"""
|
||||
def __init__(self, network_type, physical_network, segmentation_id):
|
||||
self.network_type = network_type
|
||||
self.physical_network = physical_network
|
||||
self.segmentation_id = segmentation_id
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CommonAgentManagerRpcCallBackBase(object):
|
||||
"""Base class for managers RPC callbacks.
|
||||
|
||||
This class must be inherited by a RPC callback class that is used
|
||||
in combination with the common agent.
|
||||
"""
|
||||
def __init__(self, context, agent, sg_agent):
|
||||
self.context = context
|
||||
self.agent = agent
|
||||
self.sg_agent = sg_agent
|
||||
self.network_map = {}
|
||||
# stores received port_updates and port_deletes for
|
||||
# processing by the main loop
|
||||
self.updated_devices = set()
|
||||
|
||||
@abc.abstractmethod
|
||||
def security_groups_rule_updated(self, context, **kwargs):
|
||||
"""Callback for security group rule update.
|
||||
|
||||
:param security_groups: list of updated security_groups
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def security_groups_member_updated(self, context, **kwargs):
|
||||
"""Callback for security group member update.
|
||||
|
||||
:param security_groups: list of updated security_groups
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def security_groups_provider_updated(self, context, **kwargs):
|
||||
"""Callback for security group provider update."""
|
||||
|
||||
def add_network(self, network_id, network_segment):
|
||||
"""Add a network to the agent internal network list
|
||||
|
||||
:param network_id: The UUID of the network
|
||||
:param network_segment: The NetworkSegment object for this network
|
||||
"""
|
||||
self.network_map[network_id] = network_segment
|
||||
|
||||
def get_and_clear_updated_devices(self):
|
||||
"""Get and clear the list of devices for which a update was received.
|
||||
|
||||
:return: set - A set with updated devices. Format is ['tap1', 'tap2']
|
||||
"""
|
||||
|
||||
# Save and reinitialize the set variable that the port_update RPC uses.
|
||||
# This should be thread-safe as the greenthread should not yield
|
||||
# between these two statements.
|
||||
updated_devices = self.updated_devices
|
||||
self.updated_devices = set()
|
||||
return updated_devices
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CommonAgentManagerBase(object):
|
||||
"""Base class for managers that are used with the common agent loop.
|
||||
|
||||
This class must be inherited by a manager class that is used
|
||||
in combination with the common agent.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def ensure_port_admin_state(self, device, admin_state_up):
|
||||
"""Enforce admin_state for a port
|
||||
|
||||
:param device: The device for which the admin_state should be set
|
||||
:param admin_state_up: True for admin_state_up, False for
|
||||
admin_state_down
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_agent_configurations(self):
|
||||
"""Establishes the agent configuration map.
|
||||
|
||||
The content of this map is part of the agent state reports to the
|
||||
neutron server.
|
||||
|
||||
:return: map -- the map containing the configuration values
|
||||
:rtype: dict
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_agent_id(self):
|
||||
"""Calculate the agent id that should be used on this host
|
||||
|
||||
:return: str -- agent identifier
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_all_devices(self):
|
||||
"""Get a list of all devices of the managed type from this host
|
||||
|
||||
A device in this context is a String that represents a network device.
|
||||
This can for example be the name of the device or its MAC address.
|
||||
This value will be stored in the Plug-in and be part of the
|
||||
device_details.
|
||||
|
||||
Typically this list is retrieved from the sysfs. E.g. for linuxbridge
|
||||
it returns all names of devices of type 'tap' that start with a certain
|
||||
prefix.
|
||||
|
||||
:return: set -- the set of all devices e.g. ['tap1', 'tap2']
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_extension_driver_type(self):
|
||||
"""Get the agent extension driver type.
|
||||
|
||||
:return: str -- The String defining the agent extension type
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_rpc_callbacks(self, context, agent, sg_agent):
|
||||
"""Returns the class containing all the agent rpc callback methods
|
||||
|
||||
:return: class - the class containing the agent rpc callback methods.
|
||||
It must reflect the CommonAgentManagerRpcCallBackBase Interface.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_rpc_consumers(self):
|
||||
"""Get a list of topics for which an RPC consumer should be created
|
||||
|
||||
:return: list -- A list of topics. Each topic in this list is a list
|
||||
consisting of a name, an operation, and an optional host param
|
||||
keying the subscription to topic.host for plugin calls.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def plug_interface(self, network_id, network_segment, device,
|
||||
device_owner):
|
||||
"""Plug the interface (device).
|
||||
|
||||
:param network_id: The UUID of the Neutron network
|
||||
:param network_segment: The NetworkSegment object for this network
|
||||
:param device: The device that should be plugged
|
||||
:param device_owner: The device owner of the port
|
||||
:return: bool -- True if the interface is plugged now. False if the
|
||||
interface could not be plugged.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def setup_arp_spoofing_protection(self, device, device_details):
|
||||
"""Setup the arp spoofing protection for the given port.
|
||||
|
||||
:param device: The device to set up arp spoofing rules for, where
|
||||
device is the device String that is stored in the Neutron Plug-in
|
||||
for this Port. E.g. 'tap1'
|
||||
:param device_details: The device_details map retrieved from the
|
||||
Neutron Plugin
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_arp_spoofing_protection(self, devices):
|
||||
"""Remove the arp spoofing protection for the given ports.
|
||||
|
||||
:param devices: List of devices that have been removed, where device
|
||||
is the device String that is stored for this port in the Neutron
|
||||
Plug-in. E.g. ['tap1', 'tap2']
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_unreferenced_arp_protection(self, current_devices):
|
||||
"""Cleanup arp spoofing protection entries.
|
||||
|
||||
:param current_devices: List of devices that currently exist on this
|
||||
host, where device is the device String that could have been stored
|
||||
in the Neutron Plug-in. E.g. ['tap1', 'tap2']
|
||||
"""
|
@ -0,0 +1,48 @@
|
||||
# Copyright (c) 2016 IBM Corp.
|
||||
#
|
||||
# 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 oslo_config import cfg
|
||||
|
||||
from neutron.agent.common import config
|
||||
|
||||
agent_opts = [
|
||||
cfg.IntOpt('polling_interval', default=2,
|
||||
help=_("The number of seconds the agent will wait between "
|
||||
"polling for local device changes.")),
|
||||
cfg.IntOpt('quitting_rpc_timeout', default=10,
|
||||
help=_("Set new timeout in seconds for new rpc calls after "
|
||||
"agent receives SIGTERM. If value is set to 0, rpc "
|
||||
"timeout won't be changed")),
|
||||
# TODO(kevinbenton): The following opt is duplicated between the OVS agent
|
||||
# and the Linuxbridge agent to make it easy to back-port. These shared opts
|
||||
# should be moved into a common agent config options location as part of
|
||||
# the deduplication work.
|
||||
cfg.BoolOpt('prevent_arp_spoofing', default=True,
|
||||
help=_("Enable suppression of ARP responses that don't match "
|
||||
"an IP address that belongs to the port from which "
|
||||
"they originate. Note: This prevents the VMs attached "
|
||||
"to this agent from spoofing, it doesn't protect them "
|
||||
"from other devices which have the capability to spoof "
|
||||
"(e.g. bare metal or VMs attached to agents without "
|
||||
"this flag set to True). Spoofing rules will not be "
|
||||
"added to any ports that have port security disabled. "
|
||||
"For LinuxBridge, this requires ebtables. For OVS, it "
|
||||
"requires a version that supports matching ARP "
|
||||
"headers."))
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(agent_opts, "AGENT")
|
||||
config.register_agent_state_opts_helper(cfg.CONF)
|
@ -0,0 +1,48 @@
|
||||
# Copyright (c) 2016 IBM Corp.
|
||||
#
|
||||
# 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 neutron.plugins.ml2.drivers.agent import _agent_manager_base as amb
|
||||
from neutron.tests import base
|
||||
|
||||
|
||||
class RPCCallBackImpl(amb.CommonAgentManagerRpcCallBackBase):
|
||||
def security_groups_rule_updated(self, context, **kwargs):
|
||||
pass
|
||||
|
||||
def security_groups_member_updated(self, context, **kwargs):
|
||||
pass
|
||||
|
||||
def security_groups_provider_updated(self, context, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class Test_CommonAgentManagerRpcCallBackBase(base.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(Test_CommonAgentManagerRpcCallBackBase, self).setUp()
|
||||
self.rpc_callbacks = RPCCallBackImpl(None, None, None)
|
||||
|
||||
def test_get_and_clear_updated_devices(self):
|
||||
updated_devices = ['tap1', 'tap2']
|
||||
self.rpc_callbacks.updated_devices = updated_devices
|
||||
self.assertEqual(updated_devices,
|
||||
self.rpc_callbacks.get_and_clear_updated_devices())
|
||||
self.assertEqual(set(), self.rpc_callbacks.updated_devices)
|
||||
|
||||
def test_add_network(self):
|
||||
segment = amb.NetworkSegment('vlan', 'physnet1', 100)
|
||||
network_id = "foo"
|
||||
self.rpc_callbacks.add_network(network_id, segment)
|
||||
self.assertEqual(segment, self.rpc_callbacks.network_map[network_id])
|
Loading…
Reference in new issue