Adding VLAN Transparency support for ML2 along with REST API changes
* Exposing vlan transparency attributes via the network api calls so POST and GET operations can be performed. * Tied in the vlan transparency attribute with create network call and use the config default. * Update the unit test to cover vlan tranparency. * Add support for ml2 to take advantage of vlan transparency attribute. DocImpact APIImpact Partially Implements: blueprint nfv-vlan-trunks Change-Id: Ie87087a70b83dab589419aa5c17ce7ccafd64cbd
This commit is contained in:
parent
87a534f9b0
commit
7dbe0d0486
|
@ -207,6 +207,13 @@ lock_path = $state_path/lock
|
|||
# l3_ha_net_cidr = 169.254.192.0/18
|
||||
# =========== end of items for l3 extension =======
|
||||
|
||||
# ========== items for VLAN trunking networks ==========
|
||||
# Setting this flag to True will allow plugins that support it to
|
||||
# create VLAN transparent networks. This flag has no effect for
|
||||
# plugins that do not support VLAN transparent networks.
|
||||
# vlan_transparent = False
|
||||
# ========== end of items for VLAN trunking networks ==========
|
||||
|
||||
# =========== WSGI parameters related to the API server ==============
|
||||
# Number of separate worker processes to spawn. The default, 0, runs the
|
||||
# worker thread in the current process. Greater than 0 launches that number of
|
||||
|
|
|
@ -698,6 +698,9 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||
'validate': {'type:string': None},
|
||||
'required_by_policy': True,
|
||||
'is_visible': True},
|
||||
'vlan_transparent': {'allow_post': True, 'allow_put': False,
|
||||
'convert_to': convert_to_boolean,
|
||||
'default': False, 'is_visible': True},
|
||||
SHARED: {'allow_post': True,
|
||||
'allow_put': True,
|
||||
'default': False,
|
||||
|
|
|
@ -125,6 +125,9 @@ core_opts = [
|
|||
help=_('If True, effort is made to advertise MTU settings '
|
||||
'to VMs via network methods (DHCP and RA MTU options) '
|
||||
'when the network\'s preferred MTU is known.')),
|
||||
cfg.BoolOpt('vlan_transparent', default=False,
|
||||
help=_('If True, then allow plugins that support it to '
|
||||
'create VLAN transparent networks.')),
|
||||
]
|
||||
|
||||
core_cli_opts = [
|
||||
|
|
|
@ -784,6 +784,7 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
|
|||
'mtu': network.get('mtu', constants.DEFAULT_NETWORK_MTU),
|
||||
'status': network['status'],
|
||||
'shared': network['shared'],
|
||||
'vlan_transparent': network['vlan_transparent'],
|
||||
'subnets': [subnet['id']
|
||||
for subnet in network['subnets']]}
|
||||
# Call auxiliary extend functions, if any
|
||||
|
@ -872,6 +873,7 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
|
|||
'admin_state_up': n['admin_state_up'],
|
||||
'mtu': n.get('mtu', constants.DEFAULT_NETWORK_MTU),
|
||||
'shared': n['shared'],
|
||||
'vlan_transparent': n.get('vlan_transparent', False),
|
||||
'status': n.get('status', constants.NET_STATUS_ACTIVE)}
|
||||
network = models_v2.Network(**args)
|
||||
context.session.add(network)
|
||||
|
|
|
@ -21,3 +21,8 @@ from neutron.common import exceptions
|
|||
class MechanismDriverError(exceptions.NeutronException):
|
||||
"""Mechanism driver call failed."""
|
||||
message = _("%(method)s failed.")
|
||||
|
||||
|
||||
class VlanTransparencyError(exceptions.NeutronException):
|
||||
"""Vlan Transparency not supported by all mechanism drivers."""
|
||||
message = _("Backend does not support VLAN Transparency.")
|
||||
|
|
|
@ -811,6 +811,15 @@ class MechanismDriver(object):
|
|||
"""
|
||||
pass
|
||||
|
||||
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
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ExtensionDriver(object):
|
||||
|
|
|
@ -293,6 +293,19 @@ class MechanismManager(stevedore.named.NamedExtensionManager):
|
|||
LOG.info(_LI("Initializing mechanism driver '%s'"), driver.name)
|
||||
driver.obj.initialize()
|
||||
|
||||
def _check_vlan_transparency(self, context):
|
||||
"""Helper method for checking vlan transparecncy support.
|
||||
|
||||
:param context: context parameter to pass to each method call
|
||||
:raises: neutron.plugins.ml2.common.VlanTransparencyError
|
||||
if any mechanism driver doesn't support vlan transparency.
|
||||
"""
|
||||
if not cfg.CONF.vlan_transparent:
|
||||
return
|
||||
for driver in self.ordered_mech_drivers:
|
||||
if driver.obj.check_vlan_transparency(context) is False:
|
||||
raise ml2_exc.VlanTransparencyError()
|
||||
|
||||
def _call_on_drivers(self, method_name, context,
|
||||
continue_on_failure=False):
|
||||
"""Helper method for calling a method across all mechanism drivers.
|
||||
|
@ -332,6 +345,7 @@ class MechanismManager(stevedore.named.NamedExtensionManager):
|
|||
to the caller, triggering a rollback. There is no guarantee
|
||||
that all mechanism drivers are called in this case.
|
||||
"""
|
||||
self._check_vlan_transparency(context)
|
||||
self._call_on_drivers("create_network_precommit", context)
|
||||
|
||||
def create_network_postcommit(self, context):
|
||||
|
|
|
@ -65,6 +65,7 @@ class PluginClient(base_v2.BaseNeutronClient):
|
|||
# Supply defaults that are expected to be set by the api
|
||||
# framwork
|
||||
kwargs.setdefault('admin_state_up', True)
|
||||
kwargs.setdefault('vlan_transparent', False)
|
||||
kwargs.setdefault('shared', False)
|
||||
data = dict(network=kwargs)
|
||||
result = self.plugin.create_network(self.ctx, data)
|
||||
|
|
|
@ -768,6 +768,7 @@ class JSONV2TestCase(APIv2TestBase, testlib_api.WebTestCase):
|
|||
net_id = _uuid()
|
||||
initial_input = {'network': {'name': 'net1', 'tenant_id': _uuid()}}
|
||||
full_input = {'network': {'admin_state_up': True,
|
||||
'vlan_transparent': False,
|
||||
'shared': False}}
|
||||
full_input['network'].update(initial_input['network'])
|
||||
|
||||
|
@ -802,6 +803,7 @@ class JSONV2TestCase(APIv2TestBase, testlib_api.WebTestCase):
|
|||
# tenant_id should be fetched from env
|
||||
initial_input = {'network': {'name': 'net1'}}
|
||||
full_input = {'network': {'admin_state_up': True,
|
||||
'vlan_transparent': False,
|
||||
'shared': False, 'tenant_id': tenant_id}}
|
||||
full_input['network'].update(initial_input['network'])
|
||||
|
||||
|
@ -1411,7 +1413,8 @@ class ExtensionTestCase(base.BaseTestCase, testlib_plugin.PluginSetupHelper):
|
|||
net_id = _uuid()
|
||||
initial_input = {'network': {'name': 'net1', 'tenant_id': _uuid(),
|
||||
'v2attrs:something_else': "abc"}}
|
||||
data = {'network': {'admin_state_up': True, 'shared': False}}
|
||||
data = {'network': {'admin_state_up': True, 'shared': False,
|
||||
'vlan_transparent': False}}
|
||||
data['network'].update(initial_input['network'])
|
||||
|
||||
return_value = {'subnets': [], 'status': "ACTIVE",
|
||||
|
|
|
@ -296,8 +296,8 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase,
|
|||
data = {'network': {'name': name,
|
||||
'admin_state_up': admin_state_up,
|
||||
'tenant_id': self._tenant_id}}
|
||||
for arg in (('admin_state_up', 'tenant_id', 'shared') +
|
||||
(arg_list or ())):
|
||||
for arg in (('admin_state_up', 'tenant_id', 'shared',
|
||||
'vlan_transparent') + (arg_list or ())):
|
||||
# Arg must be present
|
||||
if arg in kwargs:
|
||||
data['network'][arg] = kwargs[arg]
|
||||
|
@ -2033,6 +2033,12 @@ class TestNetworksV2(NeutronDbPluginV2TestCase):
|
|||
self.assertEqual(net['network']['mtu'],
|
||||
constants.DEFAULT_NETWORK_MTU)
|
||||
|
||||
def test_create_network_vlan_transparent(self):
|
||||
name = "vlan_transparent"
|
||||
cfg.CONF.set_override('vlan_transparent', True)
|
||||
with self.network(name=name, vlan_transparent=True) as net:
|
||||
self.assertEqual(net['network']['vlan_transparent'], True)
|
||||
|
||||
def test_update_network(self):
|
||||
with self.network() as network:
|
||||
data = {'network': {'name': 'a_brand_new_name'}}
|
||||
|
|
|
@ -141,6 +141,7 @@ class ProvidernetExtensionTestCase(testlib_api.WebTestCase,
|
|||
exp_input = {'network': data}
|
||||
exp_input['network'].update({'admin_state_up': True,
|
||||
'tenant_id': 'an_admin',
|
||||
'vlan_transparent': False,
|
||||
'shared': False})
|
||||
instance.create_network.assert_called_with(mock.ANY,
|
||||
network=exp_input)
|
||||
|
|
Loading…
Reference in New Issue