rehome ml2 MechanismDriver class
The ML2 MechanismDriver from neutron is pluggable and widely used by sub-projects [1]. This patch proposes we rehome the class into neutron-lib to break this dependency. UTs and a release note are also included. [1] http://codesearch.openstack.org/?q=MechanismDriver Change-Id: Ia1459103a96e293a05f04b1db16c53673eb2e37c
This commit is contained in:
parent
2295713383
commit
0328e63fb3
|
@ -0,0 +1,412 @@
|
|||
# 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
|
||||
import six
|
||||
|
||||
|
||||
# The following keys are used in the segment dictionaries passed via
|
||||
# the driver API.
|
||||
ID = 'id'
|
||||
NETWORK_TYPE = 'network_type'
|
||||
PHYSICAL_NETWORK = 'physical_network'
|
||||
SEGMENTATION_ID = 'segmentation_id'
|
||||
MTU = 'mtu'
|
||||
|
||||
# The following keys are used in the binding level dictionaries
|
||||
# available via the binding_levels and original_binding_levels
|
||||
# PortContext properties.
|
||||
BOUND_DRIVER = 'bound_driver'
|
||||
BOUND_SEGMENT = 'bound_segment'
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class MechanismDriver(object):
|
||||
"""Define stable abstract interface for ML2 mechanism drivers.
|
||||
|
||||
A mechanism driver is called on the creation, update, and deletion
|
||||
of networks and ports. For every event, there are two methods that
|
||||
get called - one within the database transaction (method suffix of
|
||||
_precommit), one right afterwards (method suffix of _postcommit).
|
||||
|
||||
Exceptions raised by methods called inside the transaction can
|
||||
rollback, but should not make any blocking calls (for example,
|
||||
REST requests to an outside controller). Methods called after
|
||||
transaction commits can make blocking external calls, though these
|
||||
will block the entire process. Exceptions raised in calls after
|
||||
the transaction commits may cause the associated resource to be
|
||||
deleted.
|
||||
|
||||
Because rollback outside of the transaction is not done in the
|
||||
update network/port case, all data validation must be done within
|
||||
methods that are part of the database transaction.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def initialize(self):
|
||||
"""Perform driver initialization.
|
||||
|
||||
Called after all drivers have been loaded and the database has
|
||||
been initialized. No abstract methods defined below will be
|
||||
called prior to this method being called.
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_network_precommit(self, context):
|
||||
"""Allocate resources for a new network.
|
||||
|
||||
:param context: NetworkContext instance describing the new
|
||||
network.
|
||||
|
||||
Create a new network, allocating resources as necessary in the
|
||||
database. Called inside transaction context on session. Call
|
||||
cannot block. Raising an exception will result in a rollback
|
||||
of the current transaction.
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_network_postcommit(self, context):
|
||||
"""Create a network.
|
||||
|
||||
:param context: NetworkContext instance describing the new
|
||||
network.
|
||||
|
||||
Called after the transaction commits. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Raising an exception will
|
||||
cause the deletion of the resource.
|
||||
"""
|
||||
pass
|
||||
|
||||
def update_network_precommit(self, context):
|
||||
"""Update resources of a network.
|
||||
|
||||
:param context: NetworkContext instance describing the new
|
||||
state of the network, as well as the original state prior
|
||||
to the update_network call.
|
||||
|
||||
Update values of a network, updating the associated resources
|
||||
in the database. Called inside transaction context on session.
|
||||
Raising an exception will result in rollback of the
|
||||
transaction.
|
||||
|
||||
update_network_precommit is called for all changes to the
|
||||
network state. It is up to the mechanism driver to ignore
|
||||
state or state changes that it does not know or care about.
|
||||
"""
|
||||
pass
|
||||
|
||||
def update_network_postcommit(self, context):
|
||||
"""Update a network.
|
||||
|
||||
:param context: NetworkContext instance describing the new
|
||||
state of the network, as well as the original state prior
|
||||
to the update_network call.
|
||||
|
||||
Called after the transaction commits. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Raising an exception will
|
||||
cause the deletion of the resource.
|
||||
|
||||
update_network_postcommit is called for all changes to the
|
||||
network state. It is up to the mechanism driver to ignore
|
||||
state or state changes that it does not know or care about.
|
||||
"""
|
||||
pass
|
||||
|
||||
def delete_network_precommit(self, context):
|
||||
"""Delete resources for a network.
|
||||
|
||||
:param context: NetworkContext instance describing the current
|
||||
state of the network, prior to the call to delete it.
|
||||
|
||||
Delete network resources previously allocated by this
|
||||
mechanism driver for a network. Called inside transaction
|
||||
context on session. Runtime errors are not expected, but
|
||||
raising an exception will result in rollback of the
|
||||
transaction.
|
||||
"""
|
||||
pass
|
||||
|
||||
def delete_network_postcommit(self, context):
|
||||
"""Delete a network.
|
||||
|
||||
:param context: NetworkContext instance describing the current
|
||||
state of the network, prior to the call to delete it.
|
||||
|
||||
Called after the transaction commits. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Runtime errors are not
|
||||
expected, and will not prevent the resource from being
|
||||
deleted.
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_subnet_precommit(self, context):
|
||||
"""Allocate resources for a new subnet.
|
||||
|
||||
:param context: SubnetContext instance describing the new
|
||||
subnet.
|
||||
|
||||
Create a new subnet, allocating resources as necessary in the
|
||||
database. Called inside transaction context on session. Call
|
||||
cannot block. Raising an exception will result in a rollback
|
||||
of the current transaction.
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_subnet_postcommit(self, context):
|
||||
"""Create a subnet.
|
||||
|
||||
:param context: SubnetContext instance describing the new
|
||||
subnet.
|
||||
|
||||
Called after the transaction commits. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Raising an exception will
|
||||
cause the deletion of the resource.
|
||||
"""
|
||||
pass
|
||||
|
||||
def update_subnet_precommit(self, context):
|
||||
"""Update resources of a subnet.
|
||||
|
||||
:param context: SubnetContext instance describing the new
|
||||
state of the subnet, as well as the original state prior
|
||||
to the update_subnet call.
|
||||
|
||||
Update values of a subnet, updating the associated resources
|
||||
in the database. Called inside transaction context on session.
|
||||
Raising an exception will result in rollback of the
|
||||
transaction.
|
||||
|
||||
update_subnet_precommit is called for all changes to the
|
||||
subnet state. It is up to the mechanism driver to ignore
|
||||
state or state changes that it does not know or care about.
|
||||
"""
|
||||
pass
|
||||
|
||||
def update_subnet_postcommit(self, context):
|
||||
"""Update a subnet.
|
||||
|
||||
:param context: SubnetContext instance describing the new
|
||||
state of the subnet, as well as the original state prior
|
||||
to the update_subnet call.
|
||||
|
||||
Called after the transaction commits. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Raising an exception will
|
||||
cause the deletion of the resource.
|
||||
|
||||
update_subnet_postcommit is called for all changes to the
|
||||
subnet state. It is up to the mechanism driver to ignore
|
||||
state or state changes that it does not know or care about.
|
||||
"""
|
||||
pass
|
||||
|
||||
def delete_subnet_precommit(self, context):
|
||||
"""Delete resources for a subnet.
|
||||
|
||||
:param context: SubnetContext instance describing the current
|
||||
state of the subnet, prior to the call to delete it.
|
||||
|
||||
Delete subnet resources previously allocated by this
|
||||
mechanism driver for a subnet. Called inside transaction
|
||||
context on session. Runtime errors are not expected, but
|
||||
raising an exception will result in rollback of the
|
||||
transaction.
|
||||
"""
|
||||
pass
|
||||
|
||||
def delete_subnet_postcommit(self, context):
|
||||
"""Delete a subnet.
|
||||
|
||||
:param context: SubnetContext instance describing the current
|
||||
state of the subnet, prior to the call to delete it.
|
||||
|
||||
Called after the transaction commits. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Runtime errors are not
|
||||
expected, and will not prevent the resource from being
|
||||
deleted.
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_port_precommit(self, context):
|
||||
"""Allocate resources for a new port.
|
||||
|
||||
:param context: PortContext instance describing the port.
|
||||
|
||||
Create a new port, allocating resources as necessary in the
|
||||
database. Called inside transaction context on session. Call
|
||||
cannot block. Raising an exception will result in a rollback
|
||||
of the current transaction.
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_port_postcommit(self, context):
|
||||
"""Create a port.
|
||||
|
||||
:param context: PortContext instance describing the port.
|
||||
|
||||
Called after the transaction completes. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Raising an exception will
|
||||
result in the deletion of the resource.
|
||||
"""
|
||||
pass
|
||||
|
||||
def update_port_precommit(self, context):
|
||||
"""Update resources of a port.
|
||||
|
||||
:param context: PortContext instance describing the new
|
||||
state of the port, as well as the original state prior
|
||||
to the update_port call.
|
||||
|
||||
Called inside transaction context on session to complete a
|
||||
port update as defined by this mechanism driver. Raising an
|
||||
exception will result in rollback of the transaction.
|
||||
|
||||
update_port_precommit is called for all changes to the port
|
||||
state. It is up to the mechanism driver to ignore state or
|
||||
state changes that it does not know or care about.
|
||||
"""
|
||||
pass
|
||||
|
||||
def update_port_postcommit(self, context):
|
||||
"""Update a port.
|
||||
|
||||
:param context: PortContext instance describing the new
|
||||
state of the port, as well as the original state prior
|
||||
to the update_port call.
|
||||
|
||||
Called after the transaction completes. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Raising an exception will
|
||||
result in the deletion of the resource.
|
||||
|
||||
update_port_postcommit is called for all changes to the port
|
||||
state. It is up to the mechanism driver to ignore state or
|
||||
state changes that it does not know or care about.
|
||||
"""
|
||||
pass
|
||||
|
||||
def delete_port_precommit(self, context):
|
||||
"""Delete resources of a port.
|
||||
|
||||
:param context: PortContext instance describing the current
|
||||
state of the port, prior to the call to delete it.
|
||||
|
||||
Called inside transaction context on session. Runtime errors
|
||||
are not expected, but raising an exception will result in
|
||||
rollback of the transaction.
|
||||
"""
|
||||
pass
|
||||
|
||||
def delete_port_postcommit(self, context):
|
||||
"""Delete a port.
|
||||
|
||||
:param context: PortContext instance describing the current
|
||||
state of the port, prior to the call to delete it.
|
||||
|
||||
Called after the transaction completes. Call can block, though
|
||||
will block the entire process so care should be taken to not
|
||||
drastically affect performance. Runtime errors are not
|
||||
expected, and will not prevent the resource from being
|
||||
deleted.
|
||||
"""
|
||||
pass
|
||||
|
||||
def bind_port(self, context):
|
||||
"""Attempt to bind a port.
|
||||
|
||||
:param context: PortContext instance describing the port
|
||||
|
||||
This method is called outside any transaction to attempt to
|
||||
establish a port binding using this mechanism driver. Bindings
|
||||
may be created at each of multiple levels of a hierarchical
|
||||
network, and are established from the top level downward. At
|
||||
each level, the mechanism driver determines whether it can
|
||||
bind to any of the network segments in the
|
||||
context.segments_to_bind property, based on the value of the
|
||||
context.host property, any relevant port or network
|
||||
attributes, and its own knowledge of the network topology. At
|
||||
the top level, context.segments_to_bind contains the static
|
||||
segments of the port's network. At each lower level of
|
||||
binding, it contains static or dynamic segments supplied by
|
||||
the driver that bound at the level above. If the driver is
|
||||
able to complete the binding of the port to any segment in
|
||||
context.segments_to_bind, it must call context.set_binding
|
||||
with the binding details. If it can partially bind the port,
|
||||
it must call context.continue_binding with the network
|
||||
segments to be used to bind at the next lower level.
|
||||
|
||||
If the binding results are committed after bind_port returns,
|
||||
they will be seen by all mechanism drivers as
|
||||
update_port_precommit and update_port_postcommit calls. But if
|
||||
some other thread or process concurrently binds or updates the
|
||||
port, these binding results will not be committed, and
|
||||
update_port_precommit and update_port_postcommit will not be
|
||||
called on the mechanism drivers with these results. Because
|
||||
binding results can be discarded rather than committed,
|
||||
drivers should avoid making persistent state changes in
|
||||
bind_port, or else must ensure that such state changes are
|
||||
eventually cleaned up.
|
||||
|
||||
Implementing this method explicitly declares the mechanism
|
||||
driver as having the intention to bind ports. This is inspected
|
||||
by the QoS service to identify the available QoS rules you
|
||||
can use with ports.
|
||||
"""
|
||||
pass
|
||||
|
||||
@property
|
||||
def _supports_port_binding(self):
|
||||
return self.__class__.bind_port != MechanismDriver.bind_port
|
||||
|
||||
def check_vlan_transparency(self, context):
|
||||
"""Check if the network supports vlan transparency.
|
||||
|
||||
:param context: NetworkContext instance describing the network.
|
||||
|
||||
Check if the network supports vlan transparency or not.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_workers(self):
|
||||
"""Get any NeutronWorker instances that should have their own process
|
||||
|
||||
Any driver that needs to run processes separate from the API or RPC
|
||||
workers, can return a sequence of NeutronWorker instances.
|
||||
"""
|
||||
return ()
|
||||
|
||||
@classmethod
|
||||
def is_host_filtering_supported(cls):
|
||||
return (cls.filter_hosts_with_segment_access !=
|
||||
MechanismDriver.filter_hosts_with_segment_access)
|
||||
|
||||
def filter_hosts_with_segment_access(
|
||||
self, context, segments, candidate_hosts, agent_getter):
|
||||
"""Filter hosts with access to at least one segment.
|
||||
|
||||
:returns: a set with a subset of candidate_hosts.
|
||||
|
||||
A driver can overload this method to return a subset of candidate_hosts
|
||||
with the ones with access to at least one segment.
|
||||
|
||||
Default implementation returns all hosts to disable filtering
|
||||
(backward compatibility).
|
||||
"""
|
||||
return candidate_hosts
|
|
@ -0,0 +1,39 @@
|
|||
# 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_lib.plugins.ml2 import api
|
||||
from neutron_lib.tests import _base as base
|
||||
|
||||
|
||||
class _MechanismDriver(api.MechanismDriver):
|
||||
bind_port = lambda s, c: c
|
||||
|
||||
def initialize(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestMechanismDriver(base.BaseTestCase):
|
||||
|
||||
def test__supports_port_binding(self):
|
||||
self.assertTrue(_MechanismDriver()._supports_port_binding)
|
||||
|
||||
def test_get_workers(self):
|
||||
self.assertEqual((), _MechanismDriver().get_workers())
|
||||
|
||||
def test_filter_hosts_with_segment_access(self):
|
||||
dummy_token = ["X"]
|
||||
self.assertEqual(
|
||||
dummy_token,
|
||||
_MechanismDriver().filter_hosts_with_segment_access(
|
||||
dummy_token, dummy_token, dummy_token, dummy_token))
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
features:
|
||||
- The ML2 ``MechanismDriver`` class from ``neutron.plugins.ml2.driver_api``
|
||||
is now available in ``neutron_lib.plugins.ml2.api``.
|
Loading…
Reference in New Issue