NSX|V3: Block subnets with host routes and DHCP disabled

Do not allow to create or update a subnet with disabled DHCP and
host routes.
Since the NSX-V plugin already had this code, reusing the same code.

Change-Id: Iedc58c37cc5930e4269b6225f1c52ae911e31268
This commit is contained in:
Adit Sarfaty 2018-07-30 10:24:05 +03:00
parent 5e5d708b38
commit 567d3dcb95
4 changed files with 63 additions and 21 deletions

View File

@ -359,6 +359,27 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
err_msg = _("Can not enable DHCP on external network")
raise n_exc.InvalidInput(error_message=err_msg)
def _validate_host_routes_input(self, subnet_input,
orig_enable_dhcp=None,
orig_host_routes=None):
s = subnet_input['subnet']
request_host_routes = (validators.is_attr_set(s.get('host_routes')) and
s['host_routes'])
clear_host_routes = (validators.is_attr_set(s.get('host_routes')) and
not s['host_routes'])
request_enable_dhcp = s.get('enable_dhcp')
if request_enable_dhcp is False:
if (request_host_routes or
not clear_host_routes and orig_host_routes):
err_msg = _("Can't disable DHCP while using host routes")
raise n_exc.InvalidInput(error_message=err_msg)
if request_host_routes:
if not request_enable_dhcp and orig_enable_dhcp is False:
err_msg = _("Host routes can only be supported when DHCP "
"is enabled")
raise n_exc.InvalidInput(error_message=err_msg)
def get_housekeeper(self, context, name, fields=None):
# run the job in readonly mode and get the results
self.housekeeper.run(context, name, readonly=True)

View File

@ -2660,27 +2660,6 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
return False
return bool(subnet['enable_dhcp'] and self.metadata_proxy_handler)
def _validate_host_routes_input(self, subnet_input,
orig_enable_dhcp=None,
orig_host_routes=None):
s = subnet_input['subnet']
request_host_routes = (validators.is_attr_set(s.get('host_routes')) and
s['host_routes'])
clear_host_routes = (validators.is_attr_set(s.get('host_routes')) and
not s['host_routes'])
request_enable_dhcp = s.get('enable_dhcp')
if request_enable_dhcp is False:
if (request_host_routes or
not clear_host_routes and orig_host_routes):
err_msg = _("Can't disable DHCP while using host routes")
raise n_exc.InvalidInput(error_message=err_msg)
if request_host_routes:
if not request_enable_dhcp and orig_enable_dhcp is False:
err_msg = _("Host routes can only be supported when DHCP "
"is enabled")
raise n_exc.InvalidInput(error_message=err_msg)
def create_subnet_bulk(self, context, subnets):
collection = "subnets"

View File

@ -1923,6 +1923,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
return self._create_bulk('subnet', context, subnets)
def create_subnet(self, context, subnet):
self._validate_host_routes_input(subnet)
# TODO(berlin): public external subnet announcement
if (cfg.CONF.nsx_v3.native_dhcp_metadata and
subnet['subnet'].get('enable_dhcp', False)):
@ -2013,6 +2014,10 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
def update_subnet(self, context, subnet_id, subnet):
updated_subnet = None
orig = self._get_subnet(context, subnet_id)
self._validate_host_routes_input(subnet,
orig_enable_dhcp=orig['enable_dhcp'],
orig_host_routes=orig['routes'])
if cfg.CONF.nsx_v3.native_dhcp_metadata:
orig_subnet = self.get_subnet(context, subnet_id)
enable_dhcp = subnet['subnet'].get('enable_dhcp')

View File

@ -875,6 +875,43 @@ class TestSubnetsV2(test_plugin.TestSubnetsV2, NsxV3PluginTestCaseMixin):
self.plugin.create_subnet,
context.get_admin_context(), data)
def test_create_subnet_disable_dhcp_with_host_route_fails(self):
with self.network() as network:
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '172.20.1.0/24',
'name': 'sub1',
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'enable_dhcp': False,
'host_routes': [{
'destination': '135.207.0.0/16',
'nexthop': '1.2.3.4'}],
'ip_version': 4}}
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_subnet,
context.get_admin_context(), data)
def test_update_subnet_disable_dhcp_with_host_route_fails(self):
with self.network() as network:
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '172.20.1.0/24',
'name': 'sub1',
'dns_nameservers': None,
'allocation_pools': None,
'tenant_id': 'tenant_one',
'enable_dhcp': True,
'host_routes': [{
'destination': '135.207.0.0/16',
'nexthop': '1.2.3.4'}],
'ip_version': 4}}
subnet = self.plugin.create_subnet(
context.get_admin_context(), data)
data['subnet']['enable_dhcp'] = False
self.assertRaises(n_exc.InvalidInput,
self.plugin.update_subnet,
context.get_admin_context(), subnet['id'], data)
class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin,
test_bindings.PortBindingsTestCase,