From 33dd28003c7c4e328cd6b744590d1d120a8eb988 Mon Sep 17 00:00:00 2001
From: Gary Kotton <gkotton@vmware.com>
Date: Thu, 8 Feb 2018 06:33:49 -0800
Subject: [PATCH] NSX|V3: validate external subnet has no DHCP enabled

Ensure that DHCP is disabaled for an external subnet.

Change-Id: I4e1f643a940903d57ee68232b3863d5d4e26957e
---
 vmware_nsx/plugins/common/plugin.py | 7 +++++++
 vmware_nsx/plugins/nsx_v/plugin.py  | 8 ++------
 vmware_nsx/plugins/nsx_v3/plugin.py | 2 ++
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/vmware_nsx/plugins/common/plugin.py b/vmware_nsx/plugins/common/plugin.py
index 01b2dc3bfb..9d3422dd2b 100644
--- a/vmware_nsx/plugins/common/plugin.py
+++ b/vmware_nsx/plugins/common/plugin.py
@@ -337,6 +337,13 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
         net_res[az_def.AZ_HINTS] = az_validator.convert_az_string_to_list(
             net_db[az_def.AZ_HINTS])
 
+    def _validate_external_subnet(self, context, network_id):
+        filters = {'id': [network_id], 'router:external': [True]}
+        nets = self.get_networks(context, filters=filters)
+        if len(nets) > 0:
+            err_msg = _("Can not enable DHCP on external network")
+            raise n_exc.InvalidInput(error_message=err_msg)
+
 
 # Register the callback
 def _validate_network_has_subnet(resource, event, trigger, **kwargs):
diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py
index eb1bca0771..88b6c0c9ee 100644
--- a/vmware_nsx/plugins/nsx_v/plugin.py
+++ b/vmware_nsx/plugins/nsx_v/plugin.py
@@ -2637,12 +2637,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
         """
         self._validate_host_routes_input(subnet)
         if subnet['subnet']['enable_dhcp']:
-            filters = {'id': [subnet['subnet']['network_id']],
-                       'router:external': [True]}
-            nets = self.get_networks(context, filters=filters)
-            if len(nets) > 0:
-                err_msg = _("Can not enable DHCP on external network")
-                raise n_exc.InvalidInput(error_message=err_msg)
+            self._validate_external_subnet(context,
+                                           subnet['subnet']['network_id'])
             data = subnet['subnet']
             if (data.get('ip_version') == 6 or
                 (data['cidr'] not in (constants.ATTR_NOT_SPECIFIED, None)
diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py
index 0a32ef4ab3..3d27b0aca0 100644
--- a/vmware_nsx/plugins/nsx_v3/plugin.py
+++ b/vmware_nsx/plugins/nsx_v3/plugin.py
@@ -1580,6 +1580,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
         # TODO(berlin): public external subnet announcement
         if (cfg.CONF.nsx_v3.native_dhcp_metadata and
             subnet['subnet'].get('enable_dhcp', False)):
+            self._validate_external_subnet(context,
+                                           subnet['subnet']['network_id'])
             lock = 'nsxv3_network_' + subnet['subnet']['network_id']
             with locking.LockManager.get_lock(lock):
                 # Check if it is on an overlay network and is the first