From 30caa7c895966777a17033fff17bf3941ca321c7 Mon Sep 17 00:00:00 2001 From: Shih-Hao Li Date: Thu, 3 Nov 2016 05:46:24 -0700 Subject: [PATCH] NSXv3: Native DHCP is not supported for non-overlay networks Since NSX backend does not support native DHCP on non-overlay networks, the plugin will throw exception if users add a DHCP-enabled subnet in such network. Change-Id: Id234aedd1296c63be9999bf27cf3f0f577c9cb93 --- vmware_nsx/plugins/nsx_v3/plugin.py | 59 +++++++++++++------ .../tests/unit/nsx_v3/test_dhcp_metadata.py | 17 ++++++ 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 49a7cc9842..795e34ff1e 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -641,6 +641,12 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, vlan_id, nsx_result['id']) + def _is_overlay_network(self, context, network_id): + bindings = nsx_db.get_network_bindings(context.session, network_id) + # With NSX plugin, "normal" overlay networks will have no binding + return (not bindings or + bindings[0].binding_type == utils.NsxV3NetworkTypes.VXLAN) + def _extend_network_dict_provider(self, context, network, bindings=None): if not bindings: bindings = nsx_db.get_network_bindings(context.session, @@ -1143,16 +1149,26 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, subnet['subnet'].get('enable_dhcp', False)): lock = 'nsxv3_network_' + subnet['subnet']['network_id'] with locking.LockManager.get_lock(lock): - # Check if it is the first DHCP-enabled subnet to create. - network = self._get_network(context, - subnet['subnet']['network_id']) - if self._has_no_dhcp_enabled_subnet(context, network): - created_subnet = super(NsxV3Plugin, self).create_subnet( - context, subnet) - self._enable_native_dhcp(context, network, created_subnet) + # Check if it is on an overlay network and is the first + # DHCP-enabled subnet to create. + if self._is_overlay_network( + context, subnet['subnet']['network_id']): + network = self._get_network( + context, subnet['subnet']['network_id']) + if self._has_no_dhcp_enabled_subnet(context, network): + created_subnet = super( + NsxV3Plugin, self).create_subnet(context, subnet) + self._enable_native_dhcp(context, network, + created_subnet) + msg = None + else: + msg = (_("Can not create more than one DHCP-enabled " + "subnet in network %s") % + subnet['subnet']['network_id']) else: - msg = _("Can not create more than one DHCP-enabled subnet " - "in network %s") % subnet['subnet']['network_id'] + msg = _("Native DHCP is not supported for non-overlay " + "network %s") % subnet['subnet']['network_id'] + if msg: LOG.error(msg) raise n_exc.InvalidInput(error_message=msg) else: @@ -1188,16 +1204,25 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, network = self._get_network( context, orig_subnet['network_id']) if enable_dhcp: - if self._has_no_dhcp_enabled_subnet(context, network): - updated_subnet = super( - NsxV3Plugin, self).update_subnet( - context, subnet_id, subnet) - self._enable_native_dhcp(context, network, - updated_subnet) + if self._is_overlay_network( + context, orig_subnet['network_id']): + if self._has_no_dhcp_enabled_subnet( + context, network): + updated_subnet = super( + NsxV3Plugin, self).update_subnet( + context, subnet_id, subnet) + self._enable_native_dhcp(context, network, + updated_subnet) + msg = None + else: + msg = (_("Multiple DHCP-enabled subnets is " + "not allowed in network %s") % + orig_subnet['network_id']) else: - msg = (_("Multiple DHCP-enabled subnets is not " - "allowed in network %s") % + msg = (_("Native DHCP is not supported for " + "non-overlay network %s") % orig_subnet['network_id']) + if msg: LOG.error(msg) raise n_exc.InvalidInput(error_message=msg) elif self._has_single_dhcp_enabled_subnet(context, diff --git a/vmware_nsx/tests/unit/nsx_v3/test_dhcp_metadata.py b/vmware_nsx/tests/unit/nsx_v3/test_dhcp_metadata.py index abd83a8b97..1d144a926c 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_dhcp_metadata.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_dhcp_metadata.py @@ -17,6 +17,7 @@ import mock import netaddr from neutron import context +from neutron.extensions import providernet as pnet from neutron.extensions import securitygroup as secgrp from neutron_lib import constants @@ -258,6 +259,22 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin): network2['network']['id'], nsx_constants.SERVICE_DHCP) self.assertFalse(dhcp_service) + def test_dhcp_service_with_create_dhcp_subnet_in_vlan_network(self): + # Test if a DHCP-enabled subnet cannot be created in a vlan network. + povidernet_args = {pnet.NETWORK_TYPE: 'vlan', + pnet.PHYSICAL_NETWORK: 'tzuuid', + pnet.SEGMENTATION_ID: 100} + with self.network(providernet_args=povidernet_args, + arg_list=(pnet.NETWORK_TYPE, + pnet.PHYSICAL_NETWORK, + pnet.SEGMENTATION_ID)) as network: + subnet = {'subnet': {'network_id': network['network']['id'], + 'cidr': '10.0.0.0/24', + 'enable_dhcp': True}} + self.assertRaises( + n_exc.InvalidInput, self.plugin.create_subnet, + context.get_admin_context(), subnet) + def test_dhcp_service_with_create_multiple_dhcp_subnets(self): # Test if multiple DHCP-enabled subnets cannot be created in a network. with self.network() as network: