Merge "NSX|V3: ensure external subnet does not conflicts with T0 address"

This commit is contained in:
Zuul 2018-03-28 09:27:33 +00:00 committed by Gerrit Code Review
commit 3ea32b0293
2 changed files with 48 additions and 2 deletions

View File

@ -1638,7 +1638,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
LOG.error("Unable to delete DHCP server mapping for " LOG.error("Unable to delete DHCP server mapping for "
"network %s", network_id) "network %s", network_id)
def _validate_address_space(self, subnet): def _validate_address_space(self, context, subnet):
cidr = subnet.get('cidr') cidr = subnet.get('cidr')
if (not validators.is_attr_set(cidr) or if (not validators.is_attr_set(cidr) or
netaddr.IPNetwork(cidr).version != 4): netaddr.IPNetwork(cidr).version != 4):
@ -1649,6 +1649,28 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
msg = _("Subnet overlaps with shared address space 100.64.0.0/10") msg = _("Subnet overlaps with shared address space 100.64.0.0/10")
LOG.error(msg) LOG.error(msg)
raise n_exc.InvalidInput(error_message=msg) raise n_exc.InvalidInput(error_message=msg)
# Ensure that the NSX uplink does not lie on the same subnet as
# the external subnet
filters = {'id': [subnet['network_id']],
'router:external': [True]}
nets = self.get_networks(context, filters=filters)
for net in nets:
tier0 = net.get(pnet.PHYSICAL_NETWORK)
if tier0:
ports = self.nsxlib.logical_router_port.get_by_router_id(tier0)
for port in ports:
if (port.get('resource_type') ==
'LogicalRouterUpLinkPort'):
for subnet in port.get('subnets', []):
for ip_address in subnet.get('ip_addresses'):
if (netaddr.IPAddress(ip_address) in
netaddr.IPNetwork(cidr)):
msg = _("External subnet cannot "
"overlap with T0 router "
"address!")
LOG.error(msg)
raise n_exc.InvalidInput(
error_message=msg)
def _create_bulk_with_callback(self, resource, context, request_items, def _create_bulk_with_callback(self, resource, context, request_items,
post_create_func=None, rollback_func=None): post_create_func=None, rollback_func=None):
@ -1746,7 +1768,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
return self._create_bulk('subnet', context, subnets) return self._create_bulk('subnet', context, subnets)
def create_subnet(self, context, subnet): def create_subnet(self, context, subnet):
self._validate_address_space(subnet['subnet']) self._validate_address_space(context, subnet['subnet'])
# TODO(berlin): public external subnet announcement # TODO(berlin): public external subnet announcement
if (cfg.CONF.nsx_v3.native_dhcp_metadata and if (cfg.CONF.nsx_v3.native_dhcp_metadata and
subnet['subnet'].get('enable_dhcp', False)): subnet['subnet'].get('enable_dhcp', False)):

View File

@ -616,6 +616,30 @@ class TestSubnetsV2(test_plugin.TestSubnetsV2, NsxV3PluginTestCaseMixin):
self.plugin.create_subnet, self.plugin.create_subnet,
context.get_admin_context(), data) context.get_admin_context(), data)
def _create_external_network(self):
data = {'network': {'name': 'net1',
'router:external': 'True',
'tenant_id': 'tenant_one',
'provider:physical_network': 'stam'}}
network_req = self.new_create_request('networks', data)
network = self.deserialize(self.fmt,
network_req.get_response(self.api))
return network
def test_create_subnet_with_conflicting_t0_address(self):
network = self._create_external_network()
data = {'subnet': {'network_id': network['network']['id'],
'cidr': '172.20.1.0/24'}}
ports = [{'subnets': [{'ip_addresses': [u'172.20.1.60'],
'prefix_length': 24}],
'resource_type': 'LogicalRouterUpLinkPort'}]
with mock.patch.object(self.plugin.nsxlib.logical_router_port,
'get_by_router_id',
return_value=ports):
self.assertRaises(n_exc.InvalidInput,
self.plugin.create_subnet,
context.get_admin_context(), data)
def test_subnet_update_ipv4_and_ipv6_pd_v6stateless_subnets(self): def test_subnet_update_ipv4_and_ipv6_pd_v6stateless_subnets(self):
self.skipTest('Multiple fixed ips on a port are not supported') self.skipTest('Multiple fixed ips on a port are not supported')