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
413 lines
16 KiB
Python
413 lines
16 KiB
Python
# 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
|