diff --git a/vmware_nsx/plugins/dvs/plugin.py b/vmware_nsx/plugins/dvs/plugin.py index e3364018a2..d1d4ea1ad6 100644 --- a/vmware_nsx/plugins/dvs/plugin.py +++ b/vmware_nsx/plugins/dvs/plugin.py @@ -272,6 +272,14 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin, network_type_set = validators.is_attr_set(network_type) segmentation_id = net_data.get(pnet.SEGMENTATION_ID) segmentation_id_set = validators.is_attr_set(segmentation_id) + physical_network = net_data.get(pnet.PHYSICAL_NETWORK) + if network_type == 'vlan': + bindings = nsx_db.get_network_bindings_by_vlanid_and_physical_net( + context.session, segmentation_id, physical_network) + if bindings: + err_msg = _("Network with that dvs-id and vlan tag already " + "exists") + raise n_exc.InvalidInput(error_message=err_msg) if not context.is_admin: err_msg = _("Only an admin can create a DVS provider " "network") diff --git a/vmware_nsx/tests/unit/dvs/test_plugin.py b/vmware_nsx/tests/unit/dvs/test_plugin.py index c81674b2c6..1d1b9a0049 100644 --- a/vmware_nsx/tests/unit/dvs/test_plugin.py +++ b/vmware_nsx/tests/unit/dvs/test_plugin.py @@ -381,3 +381,25 @@ class NeutronSimpleDvsTest(NeutronSimpleDvsTestCase): 'admin_state_up': True}} self.assertRaises(exp.BadRequest, self._plugin.create_network, context.get_admin_context(), data) + + def test_create_vlan_network_fail_duplicate_dvs(self): + params = {'provider:network_type': 'vlan', + 'admin_state_up': True, + 'name': 'test_net', + 'tenant_id': 'fake_tenant', + 'shared': False, + 'provider:physical_network': 'fake-moid', + 'provider:segmentation_id': 7, + 'port_security_enabled': False} + + with mock.patch.object(self._plugin._dvs, + 'add_port_group'),\ + mock.patch.object(dvs.DvsManager, + 'add_port_group'),\ + mock.patch.object(dvs.DvsManager, + 'get_dvs_moref_by_name', + return_value=mock.MagicMock()): + ctx = context.get_admin_context() + self._plugin.create_network(ctx, {'network': params}) + self.assertRaises(exp.InvalidInput, self._plugin.create_network, + ctx, {'network': params})