[dvs] Enable vlan-transparent extension
This patch allows guest vlan tagging with VMware DVS which is required functionality for many NFV functions. Change-Id: I588617e6f87afb2397d37a330e656117209630de
This commit is contained in:
parent
35ebca02d2
commit
cc2dfe2aa4
@ -60,9 +60,10 @@ class SingleDvsManager(object):
|
||||
results = vim_util.continue_retrieval(session.vim, results)
|
||||
raise nsx_exc.DvsNotFound(dvs=dvs_name)
|
||||
|
||||
def add_port_group(self, net_id, vlan_tag=None):
|
||||
def add_port_group(self, net_id, vlan_tag=None, trunk_mode=False):
|
||||
return self._dvs.add_port_group(self._dvs_moref, net_id,
|
||||
vlan_tag=vlan_tag)
|
||||
vlan_tag=vlan_tag,
|
||||
trunk_mode=trunk_mode)
|
||||
|
||||
def delete_port_group(self, net_id):
|
||||
return self._dvs.delete_port_group(self._dvs_moref, net_id)
|
||||
@ -98,26 +99,51 @@ class DvsManager(VCManagerBase):
|
||||
def _get_dvs_moref_by_id(self, dvs_id):
|
||||
return vim_util.get_moref(dvs_id, 'VmwareDistributedVirtualSwitch')
|
||||
|
||||
def _get_port_group_spec(self, net_id, vlan_tag):
|
||||
def _get_vlan_spec(self, vlan_tag):
|
||||
"""Gets portgroup vlan spec."""
|
||||
# Create the spec for the vlan tag
|
||||
client_factory = self._session.vim.client.factory
|
||||
spec_ns = 'ns0:VmwareDistributedVirtualSwitchVlanIdSpec'
|
||||
vl_spec = client_factory.create(spec_ns)
|
||||
vl_spec.vlanId = vlan_tag
|
||||
vl_spec.inherited = '0'
|
||||
return vl_spec
|
||||
|
||||
def _get_trunk_vlan_spec(self, start=0, end=4094):
|
||||
"""Gets portgroup trunk vlan spec."""
|
||||
client_factory = self._session.vim.client.factory
|
||||
spec_ns = 'ns0:VmwareDistributedVirtualSwitchTrunkVlanSpec'
|
||||
range = client_factory.create('ns0:NumericRange')
|
||||
range.start = start
|
||||
range.end = end
|
||||
vlan_tag = range
|
||||
vl_spec = client_factory.create(spec_ns)
|
||||
vl_spec.vlanId = vlan_tag
|
||||
vl_spec.inherited = '0'
|
||||
return vl_spec
|
||||
|
||||
def _get_port_group_spec(self, net_id, vlan_tag, trunk_mode=False,
|
||||
pg_spec=None):
|
||||
"""Gets the port groups spec for net_id and vlan_tag."""
|
||||
client_factory = self._session.vim.client.factory
|
||||
pg_spec = client_factory.create('ns0:DVPortgroupConfigSpec')
|
||||
if not pg_spec:
|
||||
pg_spec = client_factory.create('ns0:DVPortgroupConfigSpec')
|
||||
pg_spec.name = net_id
|
||||
pg_spec.type = 'ephemeral'
|
||||
config = client_factory.create('ns0:VMwareDVSPortSetting')
|
||||
if vlan_tag:
|
||||
# Create the spec for the vlan tag
|
||||
spec_ns = 'ns0:VmwareDistributedVirtualSwitchVlanIdSpec'
|
||||
vl_spec = client_factory.create(spec_ns)
|
||||
vl_spec.vlanId = vlan_tag
|
||||
vl_spec.inherited = '0'
|
||||
config.vlan = vl_spec
|
||||
if trunk_mode:
|
||||
config.vlan = self._get_trunk_vlan_spec()
|
||||
elif vlan_tag:
|
||||
config.vlan = self._get_vlan_spec(vlan_tag)
|
||||
|
||||
pg_spec.defaultPortConfig = config
|
||||
return pg_spec
|
||||
|
||||
def add_port_group(self, dvs_moref, net_id, vlan_tag=None):
|
||||
def add_port_group(self, dvs_moref, net_id, vlan_tag=None,
|
||||
trunk_mode=False):
|
||||
"""Add a new port group to the configured DVS."""
|
||||
pg_spec = self._get_port_group_spec(net_id, vlan_tag)
|
||||
pg_spec = self._get_port_group_spec(net_id, vlan_tag,
|
||||
trunk_mode=trunk_mode)
|
||||
task = self._session.invoke_api(self._session.vim,
|
||||
'CreateDVPortgroup_Task',
|
||||
dvs_moref,
|
||||
|
@ -30,11 +30,13 @@ from neutron.db import models_v2
|
||||
from neutron.db import portbindings_db
|
||||
from neutron.db import portsecurity_db
|
||||
from neutron.db import securitygroups_db
|
||||
from neutron.db import vlantransparent_db as vlan_ext_db
|
||||
from neutron.extensions import allowedaddresspairs as addr_pair
|
||||
from neutron.extensions import multiprovidernet as mpnet
|
||||
from neutron.extensions import portsecurity as psec
|
||||
from neutron.extensions import providernet
|
||||
from neutron.extensions import securitygroup as ext_sg
|
||||
from neutron.extensions import vlantransparent as vlan_ext
|
||||
from neutron.plugins.common import constants
|
||||
from neutron.plugins.common import utils
|
||||
from neutron.quota import resource_registry
|
||||
@ -64,7 +66,8 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
l3_db.L3_NAT_dbonly_mixin,
|
||||
portbindings_db.PortBindingMixin,
|
||||
portsecurity_db.PortSecurityDbMixin,
|
||||
securitygroups_db.SecurityGroupDbMixin):
|
||||
securitygroups_db.SecurityGroupDbMixin,
|
||||
vlan_ext_db.Vlantransparent_db_mixin):
|
||||
|
||||
supported_extension_aliases = ["allowed-address-pairs",
|
||||
"binding",
|
||||
@ -74,7 +77,8 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
"provider",
|
||||
"quotas",
|
||||
"router",
|
||||
"security-group"]
|
||||
"security-group",
|
||||
"vlan-transparent"]
|
||||
|
||||
__native_bulk_support = True
|
||||
__native_pagination_support = True
|
||||
@ -149,6 +153,11 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
if net_data.get(pnet.NETWORK_TYPE) == c_utils.NetworkTypes.VLAN:
|
||||
vlan_tag = net_data.get(pnet.SEGMENTATION_ID, 0)
|
||||
|
||||
trunk_mode = False
|
||||
# vlan transparent can be an object if not set.
|
||||
if net_data.get(vlan_ext.VLANTRANSPARENT) is True:
|
||||
trunk_mode = True
|
||||
|
||||
net_id = None
|
||||
if net_data.get(pnet.NETWORK_TYPE) == c_utils.NetworkTypes.PORTGROUP:
|
||||
net_id = net_data.get(pnet.PHYSICAL_NETWORK)
|
||||
@ -162,7 +171,7 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
dvs_id = dvpg_moref.value
|
||||
else:
|
||||
dvs_id = self._dvs_get_id(net_data)
|
||||
self._dvs.add_port_group(dvs_id, vlan_tag)
|
||||
self._dvs.add_port_group(dvs_id, vlan_tag, trunk_mode=trunk_mode)
|
||||
|
||||
try:
|
||||
with context.session.begin(subtransactions=True):
|
||||
@ -172,6 +181,12 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
self._process_network_port_security_create(
|
||||
context, net_data, new_net)
|
||||
|
||||
# Process vlan transparent extension
|
||||
net_db = self._get_network(context, new_net['id'])
|
||||
net_db['vlan_transparent'] = trunk_mode
|
||||
net_data['vlan_transparent'] = trunk_mode
|
||||
self._apply_dict_extend_functions('networks', net_data, net_db)
|
||||
|
||||
nsx_db.add_network_binding(
|
||||
context.session, new_net['id'],
|
||||
net_data.get(pnet.NETWORK_TYPE),
|
||||
|
@ -68,8 +68,8 @@ class DvsTestCase(base.BaseTestCase):
|
||||
@mock.patch.object(dvs.DvsManager, '_get_port_group_spec',
|
||||
return_value='fake-spec')
|
||||
def test_add_port_group(self, fake_get_spec):
|
||||
self._dvs.add_port_group('fake-uuid', 7)
|
||||
fake_get_spec.assert_called_once_with('fake-uuid', 7)
|
||||
self._dvs.add_port_group('fake-uuid', vlan_tag=7)
|
||||
fake_get_spec.assert_called_once_with('fake-uuid', 7, trunk_mode=False)
|
||||
|
||||
@mock.patch.object(dvs.DvsManager, '_get_port_group_spec',
|
||||
return_value='fake-spec')
|
||||
@ -80,8 +80,10 @@ class DvsTestCase(base.BaseTestCase):
|
||||
):
|
||||
self.assertRaises(exp.NeutronException,
|
||||
self._dvs.add_port_group,
|
||||
'fake-uuid', 7)
|
||||
fake_get_spec.assert_called_once_with('fake-uuid', 7)
|
||||
'fake-uuid', 7,
|
||||
trunk_mode=False)
|
||||
fake_get_spec.assert_called_once_with('fake-uuid', 7,
|
||||
trunk_mode=False)
|
||||
|
||||
@mock.patch.object(dvs.DvsManager, '_net_id_to_moref',
|
||||
return_value='fake-moref')
|
||||
@ -113,7 +115,7 @@ class DvsTestCase(base.BaseTestCase):
|
||||
self._dvs.add_port_group(net_id, vlan)
|
||||
self._dvs.net_id_to_moref(net_id)
|
||||
fake_get_moref.assert_called_once_with(mock.ANY, net_id)
|
||||
fake_get_spec.assert_called_once_with(net_id, vlan)
|
||||
fake_get_spec.assert_called_once_with(net_id, vlan, trunk_mode=False)
|
||||
|
||||
@mock.patch.object(dvs.DvsManager, '_update_net_port_groups_config')
|
||||
@mock.patch.object(dvs.DvsManager, '_get_port_group_spec',
|
||||
@ -127,7 +129,7 @@ class DvsTestCase(base.BaseTestCase):
|
||||
self._dvs.add_port_group(net_id, vlan)
|
||||
self._dvs.net_id_to_moref(net_id)
|
||||
fake_get_moref.assert_called_once_with(mock.ANY, net_id)
|
||||
fake_get_spec.assert_called_once_with(net_id, vlan)
|
||||
fake_get_spec.assert_called_once_with(net_id, vlan, trunk_mode=False)
|
||||
|
||||
|
||||
class NeutronSimpleDvsTest(test_plugin.NeutronDbPluginV2TestCase):
|
||||
@ -148,17 +150,22 @@ class NeutronSimpleDvsTest(test_plugin.NeutronDbPluginV2TestCase):
|
||||
super(NeutronSimpleDvsTest, self).setUp(plugin=PLUGIN_NAME)
|
||||
self._plugin = directory.get_plugin()
|
||||
|
||||
def _create_and_delete_dvs_network(self, network_type='flat', vlan_tag=0):
|
||||
def _create_and_delete_dvs_network(self, network_type='flat', vlan_tag=0,
|
||||
trunk_mode=False):
|
||||
params = {'provider:network_type': network_type,
|
||||
'provider:physical_network': 'fake-moid',
|
||||
'name': 'fake-name'}
|
||||
if network_type == 'vlan':
|
||||
params['provider:segmentation_id'] = vlan_tag
|
||||
if trunk_mode:
|
||||
params['vlan_transparent'] = True
|
||||
params['arg_list'] = tuple(params.keys())
|
||||
with mock.patch.object(self._plugin._dvs,
|
||||
'add_port_group') as mock_add,\
|
||||
mock.patch.object(self._plugin._dvs,
|
||||
'delete_port_group') as mock_delete:
|
||||
'delete_port_group') as mock_delete,\
|
||||
mock.patch.object(dvs.DvsManager,
|
||||
'_get_trunk_vlan_spec') as mock_trunk_vlan:
|
||||
with self.network(**params) as network:
|
||||
ctx = context.get_admin_context()
|
||||
id = network['network']['id']
|
||||
@ -180,10 +187,15 @@ class NeutronSimpleDvsTest(test_plugin.NeutronDbPluginV2TestCase):
|
||||
else:
|
||||
self.fail()
|
||||
if network_type != 'portgroup':
|
||||
mock_add.assert_called_once_with(dvs_id, vlan_tag)
|
||||
mock_add.assert_called_once_with(dvs_id, vlan_tag,
|
||||
trunk_mode=trunk_mode)
|
||||
else:
|
||||
mock_add.call_count = 0
|
||||
mock_delete.call_count = 0
|
||||
if trunk_mode:
|
||||
mock_trunk_vlan.called_once_with(start=0, end=4094)
|
||||
else:
|
||||
mock_trunk_vlan.call_count = 0
|
||||
|
||||
def test_create_and_delete_dvs_network_tag(self):
|
||||
self._create_and_delete_dvs_network(network_type='vlan', vlan_tag=7)
|
||||
@ -191,6 +203,9 @@ class NeutronSimpleDvsTest(test_plugin.NeutronDbPluginV2TestCase):
|
||||
def test_create_and_delete_dvs_network_flat(self):
|
||||
self._create_and_delete_dvs_network()
|
||||
|
||||
def test_create_and_delete_dvs_network_flat_vlan_transparent(self):
|
||||
self._create_and_delete_dvs_network(trunk_mode=True)
|
||||
|
||||
@mock.patch.object(dvs.DvsManager, 'get_port_group_info')
|
||||
@mock.patch.object(dvs.DvsManager, '_net_id_to_moref')
|
||||
def test_create_and_delete_dvs_network_portgroup(self, fake_get_moref,
|
||||
|
Loading…
x
Reference in New Issue
Block a user