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
This commit is contained in:
Shih-Hao Li 2016-11-03 05:46:24 -07:00
parent a4c8dd570b
commit 30caa7c895
2 changed files with 59 additions and 17 deletions

View File

@ -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,

View File

@ -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: