From bfce2c50b4922bb2c1b2e4ce7caedc4d6371c411 Mon Sep 17 00:00:00 2001
From: Gary Kotton <gkotton@vmware.com>
Date: Wed, 31 Jan 2018 20:44:32 +0200
Subject: [PATCH] NSX|V3: enable VLAN transparent to be configured with VLAN

The plugin will enforce that a VLAN ID should not be configured
with the transparent flag.

Change-Id: I9310e2de62346b805514fdd5cd3507b245e8e0cc
---
 vmware_nsx/plugins/nsx_v3/plugin.py         | 27 ++++++++++++---------
 vmware_nsx/tests/unit/nsx_v3/test_plugin.py |  4 +--
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py
index 5a7ca5deb4..eb6b68a759 100644
--- a/vmware_nsx/plugins/nsx_v3/plugin.py
+++ b/vmware_nsx/plugins/nsx_v3/plugin.py
@@ -773,6 +773,11 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
         if not validators.is_attr_set(vlan_id):
             vlan_id = None
 
+        if vlan_id and transparent_vlan:
+            err_msg = (_("Segmentation ID cannot be set with transparent "
+                         "vlan!"))
+            raise n_exc.InvalidInput(error_message=err_msg)
+
         err_msg = None
         net_type = network_data.get(pnet.NETWORK_TYPE)
         nsxlib_tz = self.nsxlib.transport_zone
@@ -785,11 +790,13 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
                                  "%s network type") %
                                utils.NsxV3NetworkTypes.FLAT)
                 else:
-                    # Set VLAN id to 0 for flat networks
-                    vlan_id = '0'
+                    if not transparent_vlan:
+                        # Set VLAN id to 0 for flat networks
+                        vlan_id = '0'
                     if physical_net is None:
                         physical_net = az._default_vlan_tz_uuid
-            elif net_type == utils.NsxV3NetworkTypes.VLAN:
+            elif (net_type == utils.NsxV3NetworkTypes.VLAN and
+                  not transparent_vlan):
                 # Use default VLAN transport zone if physical network not given
                 if physical_net is None:
                     physical_net = az._default_vlan_tz_uuid
@@ -814,6 +821,11 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
                     if bindings:
                         raise n_exc.VlanIdInUse(
                             vlan_id=vlan_id, physical_network=physical_net)
+            elif (net_type == utils.NsxV3NetworkTypes.VLAN and
+                  transparent_vlan):
+                # Use default VLAN transport zone if physical network not given
+                if physical_net is None:
+                    physical_net = az._default_vlan_tz_uuid
             elif net_type == utils.NsxV3NetworkTypes.GENEVE:
                 if vlan_id:
                     err_msg = (_("Segmentation ID cannot be specified with "
@@ -873,12 +885,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
                         err_msg = (_('%(tz)s transport zone is required for '
                                      'creating a %(net)s provider network') %
                                    {'tz': tz_type, 'net': net_type})
-                    elif (transparent_vlan and
-                          tz_type == nsxlib_tz.TRANSPORT_TYPE_VLAN):
-                        raise NotImplementedError(_(
-                            "Transparent support only for internal overlay "
-                            "networks"))
-
             if not err_msg:
                 switch_mode = nsxlib_tz.get_host_switch_mode(physical_net)
 
@@ -1054,9 +1060,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
 
         nsx_net_id = None
         if validators.is_attr_set(external) and external:
-            if vlt:
-                raise NotImplementedError(_(
-                    "Transparent support only for internal overlay networks"))
             self._assert_on_external_net_with_qos(net_data)
             is_provider_net, net_type, physical_net, vlan_id = (
                 self._validate_external_net_create(net_data))
diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py
index 4885e6eefa..bd017f14a1 100644
--- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py
+++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py
@@ -533,7 +533,6 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxV3PluginTestCaseMixin):
 
     def test_create_provider_vlan_network_with_transparent(self):
         providernet_args = {pnet.NETWORK_TYPE: 'vlan',
-                            pnet.SEGMENTATION_ID: 11,
                             vlan_apidef.VLANTRANSPARENT: True}
         with mock.patch('vmware_nsxlib.v3.core_resources.NsxLibTransportZone.'
                        'get_transport_type', return_value='VLAN'):
@@ -545,8 +544,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxV3PluginTestCaseMixin):
                                               pnet.SEGMENTATION_ID,
                                               vlan_apidef.VLANTRANSPARENT))
             data = self.deserialize('json', result)
-            # should fail
-            self.assertIn('NotImplementedError', data)
+            self.assertEqual('vlan', data['network'].get(pnet.NETWORK_TYPE))
 
 
 class TestSubnetsV2(test_plugin.TestSubnetsV2, NsxV3PluginTestCaseMixin):