# 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
'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,
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 = [
'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
'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)
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.")
"""
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):
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.
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):
# 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)
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'])
# 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'])
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",
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]
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'}}
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)