Merge "Support for extensions in ML2"
This commit is contained in:
commit
603cda9696
@ -22,6 +22,11 @@
|
||||
# Example: mechanism_drivers = linuxbridge,brocade
|
||||
# Example: mechanism_drivers = openvswitch,cisco_dfa
|
||||
|
||||
# (ListOpt) Ordered list of extension driver entrypoints
|
||||
# to be loaded from the neutron.ml2.extension_drivers namespace.
|
||||
# extension_drivers =
|
||||
# Example: extension_drivers = anewextensiondriver
|
||||
|
||||
[ml2_type_flat]
|
||||
# (ListOpt) List of physical_network names with which flat networks
|
||||
# can be created. Use * to allow flat networks with arbitrary
|
||||
|
@ -679,6 +679,6 @@ def get_extensions_path():
|
||||
|
||||
|
||||
def append_api_extensions_path(paths):
|
||||
paths = [cfg.CONF.api_extensions_path] + paths
|
||||
paths = list(set([cfg.CONF.api_extensions_path] + paths))
|
||||
cfg.CONF.set_override('api_extensions_path',
|
||||
':'.join([p for p in paths if p]))
|
||||
|
@ -807,6 +807,8 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
|
||||
for route in subnet['routes']],
|
||||
'shared': subnet['shared']
|
||||
}
|
||||
# Call auxiliary extend functions, if any
|
||||
self._apply_dict_extend_functions(attributes.SUBNETS, res, subnet)
|
||||
return self._fields(res, fields)
|
||||
|
||||
def _make_port_dict(self, port, fields=None,
|
||||
|
@ -30,6 +30,11 @@ ml2_opts = [
|
||||
help=_("An ordered list of networking mechanism driver "
|
||||
"entrypoints to be loaded from the "
|
||||
"neutron.ml2.mechanism_drivers namespace.")),
|
||||
cfg.ListOpt('extension_drivers',
|
||||
default=[],
|
||||
help=_("An ordered list of extension driver "
|
||||
"entrypoints to be loaded from the "
|
||||
"neutron.ml2.extension_drivers namespace.")),
|
||||
]
|
||||
|
||||
|
||||
|
@ -649,3 +649,158 @@ class MechanismDriver(object):
|
||||
that such state changes are eventually cleaned up.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ExtensionDriver(object):
|
||||
"""Define stable abstract interface for ML2 extension drivers.
|
||||
|
||||
An extension driver extends the core resources implemented by the
|
||||
ML2 plugin with additional attributes. Methods that process create
|
||||
and update operations for these resources validate and persist
|
||||
values for extended attributes supplied through the API. Other
|
||||
methods extend the resource dictionaries returned from the API
|
||||
operations with the values of the extended attributes.
|
||||
"""
|
||||
|
||||
@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
|
||||
|
||||
@abc.abstractproperty
|
||||
def extension_alias(self):
|
||||
"""Supported extension alias.
|
||||
|
||||
Return the alias identifying the core API extension supported
|
||||
by this driver.
|
||||
"""
|
||||
pass
|
||||
|
||||
def process_create_network(self, session, data, result):
|
||||
"""Process extended attributes for create network.
|
||||
|
||||
:param session: database session
|
||||
:param data: dictionary of incoming network data
|
||||
:param result: network dictionary to extend
|
||||
|
||||
Called inside transaction context on session to validate and
|
||||
persist any extended network attributes defined by this
|
||||
driver. Extended attribute values must also be added to
|
||||
result.
|
||||
"""
|
||||
pass
|
||||
|
||||
def process_create_subnet(self, session, data, result):
|
||||
"""Process extended attributes for create subnet.
|
||||
|
||||
:param session: database session
|
||||
:param data: dictionary of incoming subnet data
|
||||
:param result: subnet dictionary to extend
|
||||
|
||||
Called inside transaction context on session to validate and
|
||||
persist any extended subnet attributes defined by this
|
||||
driver. Extended attribute values must also be added to
|
||||
result.
|
||||
"""
|
||||
pass
|
||||
|
||||
def process_create_port(self, session, data, result):
|
||||
"""Process extended attributes for create port.
|
||||
|
||||
:param session: database session
|
||||
:param data: dictionary of incoming port data
|
||||
:param result: port dictionary to extend
|
||||
|
||||
Called inside transaction context on session to validate and
|
||||
persist any extended port attributes defined by this
|
||||
driver. Extended attribute values must also be added to
|
||||
result.
|
||||
"""
|
||||
pass
|
||||
|
||||
def process_update_network(self, session, data, result):
|
||||
"""Process extended attributes for update network.
|
||||
|
||||
:param session: database session
|
||||
:param data: dictionary of incoming network data
|
||||
:param result: network dictionary to extend
|
||||
|
||||
Called inside transaction context on session to validate and
|
||||
update any extended network attributes defined by this
|
||||
driver. Extended attribute values, whether updated or not,
|
||||
must also be added to result.
|
||||
"""
|
||||
pass
|
||||
|
||||
def process_update_subnet(self, session, data, result):
|
||||
"""Process extended attributes for update subnet.
|
||||
|
||||
:param session: database session
|
||||
:param data: dictionary of incoming subnet data
|
||||
:param result: subnet dictionary to extend
|
||||
|
||||
Called inside transaction context on session to validate and
|
||||
update any extended subnet attributes defined by this
|
||||
driver. Extended attribute values, whether updated or not,
|
||||
must also be added to result.
|
||||
"""
|
||||
pass
|
||||
|
||||
def process_update_port(self, session, data, result):
|
||||
"""Process extended attributes for update port.
|
||||
|
||||
:param session: database session
|
||||
:param data: dictionary of incoming port data
|
||||
:param result: port dictionary to extend
|
||||
|
||||
Called inside transaction context on session to validate and
|
||||
update any extended port attributes defined by this
|
||||
driver. Extended attribute values, whether updated or not,
|
||||
must also be added to result.
|
||||
"""
|
||||
pass
|
||||
|
||||
def extend_network_dict(self, session, result):
|
||||
"""Add extended attributes to network dictionary.
|
||||
|
||||
:param session: database session
|
||||
:param result: network dictionary to extend
|
||||
|
||||
Called inside transaction context on session to add any
|
||||
extended attributes defined by this driver to a network
|
||||
dictionary to be used for mechanism driver calls and/or
|
||||
returned as the result of a network operation.
|
||||
"""
|
||||
pass
|
||||
|
||||
def extend_subnet_dict(self, session, result):
|
||||
"""Add extended attributes to subnet dictionary.
|
||||
|
||||
:param session: database session
|
||||
:param result: subnet dictionary to extend
|
||||
|
||||
Called inside transaction context on session to add any
|
||||
extended attributes defined by this driver to a subnet
|
||||
dictionary to be used for mechanism driver calls and/or
|
||||
returned as the result of a subnet operation.
|
||||
"""
|
||||
pass
|
||||
|
||||
def extend_port_dict(self, session, result):
|
||||
"""Add extended attributes to port dictionary.
|
||||
|
||||
:param session: database session
|
||||
:param result: port dictionary to extend
|
||||
|
||||
Called inside transaction context on session to add any
|
||||
extended attributes defined by this driver to a port
|
||||
dictionary to be used for mechanism driver calls and/or
|
||||
returned as the result of a port operation.
|
||||
"""
|
||||
pass
|
||||
|
@ -573,3 +573,107 @@ class MechanismManager(stevedore.named.NamedExtensionManager):
|
||||
LOG.warning(_("Failed to bind port %(port)s on host %(host)s"),
|
||||
{'port': context._port['id'],
|
||||
'host': binding.host})
|
||||
|
||||
|
||||
class ExtensionManager(stevedore.named.NamedExtensionManager):
|
||||
"""Manage extension drivers using drivers."""
|
||||
|
||||
def __init__(self):
|
||||
# Ordered list of extension drivers, defining
|
||||
# the order in which the drivers are called.
|
||||
self.ordered_ext_drivers = []
|
||||
|
||||
LOG.info(_("Configured extension driver names: %s"),
|
||||
cfg.CONF.ml2.extension_drivers)
|
||||
super(ExtensionManager, self).__init__('neutron.ml2.extension_drivers',
|
||||
cfg.CONF.ml2.extension_drivers,
|
||||
invoke_on_load=True,
|
||||
name_order=True)
|
||||
LOG.info(_("Loaded extension driver names: %s"), self.names())
|
||||
self._register_drivers()
|
||||
|
||||
def _register_drivers(self):
|
||||
"""Register all extension drivers.
|
||||
|
||||
This method should only be called once in the ExtensionManager
|
||||
constructor.
|
||||
"""
|
||||
for ext in self:
|
||||
self.ordered_ext_drivers.append(ext)
|
||||
LOG.info(_("Registered extension drivers: %s"),
|
||||
[driver.name for driver in self.ordered_ext_drivers])
|
||||
|
||||
def initialize(self):
|
||||
# Initialize each driver in the list.
|
||||
for driver in self.ordered_ext_drivers:
|
||||
LOG.info(_("Initializing extension driver '%s'"), driver.name)
|
||||
driver.obj.initialize()
|
||||
|
||||
def extension_aliases(self):
|
||||
exts = []
|
||||
for driver in self.ordered_ext_drivers:
|
||||
alias = driver.obj.extension_alias
|
||||
exts.append(alias)
|
||||
LOG.info(_("Got %(alias)s extension from driver '%(drv)s'"),
|
||||
{'alias': alias, 'drv': driver.name})
|
||||
return exts
|
||||
|
||||
def _call_on_ext_drivers(self, method_name, session, data, result):
|
||||
"""Helper method for calling a method across all extension drivers."""
|
||||
for driver in self.ordered_ext_drivers:
|
||||
try:
|
||||
getattr(driver.obj, method_name)(session, data, result)
|
||||
except Exception:
|
||||
LOG.exception(
|
||||
_("Extension driver '%(name)s' failed in %(method)s"),
|
||||
{'name': driver.name, 'method': method_name}
|
||||
)
|
||||
|
||||
def process_create_network(self, session, data, result):
|
||||
"""Notify all extension drivers during network creation."""
|
||||
self._call_on_ext_drivers("process_create_network", session, data,
|
||||
result)
|
||||
|
||||
def process_update_network(self, session, data, result):
|
||||
"""Notify all extension drivers during network update."""
|
||||
self._call_on_ext_drivers("process_update_network", session, data,
|
||||
result)
|
||||
|
||||
def process_create_subnet(self, session, data, result):
|
||||
"""Notify all extension drivers during subnet creation."""
|
||||
self._call_on_ext_drivers("process_create_subnet", session, data,
|
||||
result)
|
||||
|
||||
def process_update_subnet(self, session, data, result):
|
||||
"""Notify all extension drivers during subnet update."""
|
||||
self._call_on_ext_drivers("process_update_subnet", session, data,
|
||||
result)
|
||||
|
||||
def process_create_port(self, session, data, result):
|
||||
"""Notify all extension drivers during port creation."""
|
||||
self._call_on_ext_drivers("process_create_port", session, data, result)
|
||||
|
||||
def process_update_port(self, session, data, result):
|
||||
"""Notify all extension drivers during port update."""
|
||||
self._call_on_ext_drivers("process_update_port", session, data, result)
|
||||
|
||||
def extend_network_dict(self, session, result):
|
||||
"""Notify all extension drivers to extend network dictionary."""
|
||||
for driver in self.ordered_ext_drivers:
|
||||
driver.obj.extend_network_dict(session, result)
|
||||
LOG.info(_("Extended network dict for driver '%(drv)s'"),
|
||||
{'drv': driver.name})
|
||||
|
||||
def extend_subnet_dict(self, session, result):
|
||||
"""Notify all extension drivers to extend subnet dictionary."""
|
||||
for driver in self.ordered_ext_drivers:
|
||||
driver.obj.extend_subnet_dict(session, result)
|
||||
LOG.info(_("Extended subnet dict for driver '%(drv)s'"),
|
||||
{'drv': driver.name})
|
||||
|
||||
def extend_port_dict(self, session, result):
|
||||
"""Notify all extension drivers to extend port dictionary."""
|
||||
for driver in self.ordered_ext_drivers:
|
||||
driver.obj.extend_port_dict(session, result)
|
||||
LOG.info(_("Extended port dict for driver '%(drv)s'"),
|
||||
{'drv': driver.name})
|
||||
|
@ -35,6 +35,7 @@ from neutron.common import utils
|
||||
from neutron.db import agents_db
|
||||
from neutron.db import agentschedulers_db
|
||||
from neutron.db import allowedaddresspairs_db as addr_pair_db
|
||||
from neutron.db import api as db_api
|
||||
from neutron.db import db_base_plugin_v2
|
||||
from neutron.db import dvr_mac_db
|
||||
from neutron.db import external_net_db
|
||||
@ -110,6 +111,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
def supported_extension_aliases(self):
|
||||
if not hasattr(self, '_aliases'):
|
||||
aliases = self._supported_extension_aliases[:]
|
||||
aliases += self.extension_manager.extension_aliases()
|
||||
sg_rpc.disable_security_group_extension_by_config(aliases)
|
||||
self._aliases = aliases
|
||||
return self._aliases
|
||||
@ -117,9 +119,11 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
def __init__(self):
|
||||
# First load drivers, then initialize DB, then initialize drivers
|
||||
self.type_manager = managers.TypeManager()
|
||||
self.extension_manager = managers.ExtensionManager()
|
||||
self.mechanism_manager = managers.MechanismManager()
|
||||
super(Ml2Plugin, self).__init__()
|
||||
self.type_manager.initialize()
|
||||
self.extension_manager.initialize()
|
||||
self.mechanism_manager.initialize()
|
||||
# bulk support depends on the underlying drivers
|
||||
self.__native_bulk_support = self.mechanism_manager.native_bulk_support
|
||||
@ -411,6 +415,31 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
|
||||
attributes.PORTS, ['_ml2_extend_port_dict_binding'])
|
||||
|
||||
# Register extend dict methods for network and port resources.
|
||||
# Each mechanism driver that supports extend attribute for the resources
|
||||
# can add those attribute to the result.
|
||||
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
|
||||
attributes.NETWORKS, ['_ml2_md_extend_network_dict'])
|
||||
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
|
||||
attributes.PORTS, ['_ml2_md_extend_port_dict'])
|
||||
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
|
||||
attributes.SUBNETS, ['_ml2_md_extend_subnet_dict'])
|
||||
|
||||
def _ml2_md_extend_network_dict(self, result, netdb):
|
||||
session = db_api.get_session()
|
||||
with session.begin(subtransactions=True):
|
||||
self.extension_manager.extend_network_dict(session, result)
|
||||
|
||||
def _ml2_md_extend_port_dict(self, result, portdb):
|
||||
session = db_api.get_session()
|
||||
with session.begin(subtransactions=True):
|
||||
self.extension_manager.extend_port_dict(session, result)
|
||||
|
||||
def _ml2_md_extend_subnet_dict(self, result, subnetdb):
|
||||
session = db_api.get_session()
|
||||
with session.begin(subtransactions=True):
|
||||
self.extension_manager.extend_subnet_dict(session, result)
|
||||
|
||||
# Note - The following hook methods have "ml2" in their names so
|
||||
# that they are not called twice during unit tests due to global
|
||||
# registration of hooks in portbindings_db.py used by other
|
||||
@ -460,6 +489,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
with session.begin(subtransactions=True):
|
||||
self._ensure_default_security_group(context, tenant_id)
|
||||
result = super(Ml2Plugin, self).create_network(context, network)
|
||||
self.extension_manager.process_create_network(session, net_data,
|
||||
result)
|
||||
self._process_l3_create(context, result, net_data)
|
||||
net_data['id'] = result['id']
|
||||
self.type_manager.create_network_segments(context, net_data,
|
||||
@ -487,6 +518,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
updated_network = super(Ml2Plugin, self).update_network(context,
|
||||
id,
|
||||
network)
|
||||
self.extension_manager.process_update_network(session, network,
|
||||
original_network)
|
||||
self._process_l3_update(context, updated_network,
|
||||
network['network'])
|
||||
self.type_manager._extend_network_dict_provider(context,
|
||||
@ -627,6 +660,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
session = context.session
|
||||
with session.begin(subtransactions=True):
|
||||
result = super(Ml2Plugin, self).create_subnet(context, subnet)
|
||||
self.extension_manager.process_create_subnet(session, subnet,
|
||||
result)
|
||||
mech_context = driver_context.SubnetContext(self, context, result)
|
||||
self.mechanism_manager.create_subnet_precommit(mech_context)
|
||||
|
||||
@ -645,6 +680,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
original_subnet = super(Ml2Plugin, self).get_subnet(context, id)
|
||||
updated_subnet = super(Ml2Plugin, self).update_subnet(
|
||||
context, id, subnet)
|
||||
self.extension_manager.process_update_subnet(session, subnet,
|
||||
original_subnet)
|
||||
mech_context = driver_context.SubnetContext(
|
||||
self, context, updated_subnet, original_subnet=original_subnet)
|
||||
self.mechanism_manager.update_subnet_precommit(mech_context)
|
||||
@ -737,6 +774,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
sgids = self._get_security_groups_on_port(context, port)
|
||||
dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, [])
|
||||
result = super(Ml2Plugin, self).create_port(context, port)
|
||||
self.extension_manager.process_create_port(session, attrs, result)
|
||||
self._process_port_create_security_group(context, result, sgids)
|
||||
network = self.get_network(context, result['network_id'])
|
||||
binding = db.add_port_binding(session, result['id'])
|
||||
@ -791,6 +829,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
original_port = self._make_port_dict(port_db)
|
||||
updated_port = super(Ml2Plugin, self).update_port(context, id,
|
||||
port)
|
||||
self.extension_manager.process_update_port(session, attrs,
|
||||
original_port)
|
||||
if addr_pair.ADDRESS_PAIRS in port['port']:
|
||||
need_port_update_notify |= (
|
||||
self.update_address_pairs_on_port(context, id, port,
|
||||
|
0
neutron/tests/unit/ml2/extensions/__init__.py
Normal file
0
neutron/tests/unit/ml2/extensions/__init__.py
Normal file
69
neutron/tests/unit/ml2/extensions/test_extension.py
Normal file
69
neutron/tests/unit/ml2/extensions/test_extension.py
Normal file
@ -0,0 +1,69 @@
|
||||
# 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.api import extensions
|
||||
from neutron.api.v2 import attributes as attr
|
||||
|
||||
|
||||
EXTENDED_ATTRIBUTES_2_0 = {
|
||||
'networks': {
|
||||
'network_extension': {'allow_post': True,
|
||||
'allow_put': True,
|
||||
'default': attr.ATTR_NOT_SPECIFIED,
|
||||
'is_visible': True,
|
||||
'enforce_policy': True},
|
||||
},
|
||||
'subnets': {
|
||||
'subnet_extension': {'allow_post': True,
|
||||
'allow_put': True,
|
||||
'default': attr.ATTR_NOT_SPECIFIED,
|
||||
'is_visible': True,
|
||||
'enforce_policy': True},
|
||||
},
|
||||
'ports': {
|
||||
'port_extension': {'allow_post': True,
|
||||
'allow_put': True,
|
||||
'default': attr.ATTR_NOT_SPECIFIED,
|
||||
'is_visible': True,
|
||||
'enforce_policy': True},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class Test_extension(extensions.ExtensionDescriptor):
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "ML2 test extension"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "test_extension"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return _("Adds test attributes to core resources.")
|
||||
|
||||
@classmethod
|
||||
def get_namespace(cls):
|
||||
return ("http://docs.openstack.org/ext/neutron/ml2/test/"
|
||||
"test_extension/api/v1.0")
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2014-07-16T10:00:00-00:00"
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
return EXTENDED_ATTRIBUTES_2_0
|
||||
else:
|
||||
return {}
|
66
neutron/tests/unit/ml2/test_extension_driver_api.py
Normal file
66
neutron/tests/unit/ml2/test_extension_driver_api.py
Normal file
@ -0,0 +1,66 @@
|
||||
# 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.api import extensions
|
||||
from neutron.plugins.ml2 import config
|
||||
from neutron.plugins.ml2 import driver_api as api
|
||||
from neutron.tests.unit.ml2 import extensions as test_extensions
|
||||
from neutron.tests.unit.ml2 import test_ml2_plugin
|
||||
|
||||
|
||||
class ExtensionDriverTestCase(test_ml2_plugin.Ml2PluginV2TestCase):
|
||||
|
||||
_extension_drivers = ['test']
|
||||
|
||||
def setUp(self):
|
||||
config.cfg.CONF.set_override('extension_drivers',
|
||||
self._extension_drivers,
|
||||
group='ml2')
|
||||
super(ExtensionDriverTestCase, self).setUp()
|
||||
|
||||
def test_network_attr(self):
|
||||
with self.network() as network:
|
||||
ent = network['network'].get('network_extension')
|
||||
self.assertIsNotNone(ent)
|
||||
|
||||
def test_subnet_attr(self):
|
||||
with self.subnet() as subnet:
|
||||
ent = subnet['subnet'].get('subnet_extension')
|
||||
self.assertIsNotNone(ent)
|
||||
|
||||
def test_port_attr(self):
|
||||
with self.port() as port:
|
||||
ent = port['port'].get('port_extension')
|
||||
self.assertIsNotNone(ent)
|
||||
|
||||
|
||||
class TestExtensionDriver(api.ExtensionDriver):
|
||||
_supported_extension_alias = 'test_extension'
|
||||
|
||||
def initialize(self):
|
||||
self.network_extension = 'Test_Network_Extension'
|
||||
self.subnet_extension = 'Test_Subnet_Extension'
|
||||
self.port_extension = 'Test_Port_Extension'
|
||||
extensions.append_api_extensions_path(test_extensions.__path__)
|
||||
|
||||
@property
|
||||
def extension_alias(self):
|
||||
return self._supported_extension_alias
|
||||
|
||||
def process_create_network(self, session, data, result):
|
||||
result['network_extension'] = self.network_extension
|
||||
|
||||
def process_create_subnet(self, session, data, result):
|
||||
result['subnet_extension'] = self.subnet_extension
|
||||
|
||||
def process_create_port(self, session, data, result):
|
||||
result['port_extension'] = self.port_extension
|
@ -177,6 +177,8 @@ neutron.ml2.mechanism_drivers =
|
||||
fslsdn = neutron.plugins.ml2.drivers.mechanism_fslsdn:FslsdnMechanismDriver
|
||||
sriovnicswitch = neutron.plugins.ml2.drivers.mech_sriov.mech_driver:SriovNicSwitchMechanismDriver
|
||||
nuage = neutron.plugins.ml2.drivers.mech_nuage.driver:NuageMechanismDriver
|
||||
neutron.ml2.extension_drivers =
|
||||
test = neutron.tests.unit.ml2.test_extension_driver_api:TestExtensionDriver
|
||||
neutron.openstack.common.cache.backends =
|
||||
memory = neutron.openstack.common.cache._backends.memory:MemoryBackend
|
||||
# These are for backwards compat with Icehouse notification_driver configuration values
|
||||
@ -187,7 +189,6 @@ oslo.messaging.notify.drivers =
|
||||
neutron.openstack.common.notifier.rpc_notifier = oslo.messaging.notify._impl_messaging:MessagingDriver
|
||||
neutron.openstack.common.notifier.test_notifier = oslo.messaging.notify._impl_test:TestDriver
|
||||
|
||||
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
build-dir = doc/build
|
||||
|
Loading…
x
Reference in New Issue
Block a user