Add no nat cidrs network extension
The no-NAT CIDRs extension is applied to the network resource in neutron. When applied, it affects the list of subnets that should be reachable without NAT that are delivered in the RPC calls to agents. The agents can then use this information to ensure that specific destination CIDRs will never use NAT. The extension can be applied to both tenant and external/public networks. The extension should be used judiciously, as placing it on a network will cause those CIDRs to be added to all RPC calls requesting subnets within that VRF (e.g. the extension could be added to a shared network or to a network that uses a subnetpool relating to a shared address scope, which would be seen by all other networks that report to that same address scope or shared network). Change-Id: Ic2cdd501933cc21c286ca36218361aadef1878b8
This commit is contained in:
@@ -7133,6 +7133,49 @@ class TestExtensionAttributes(ApicAimTestCase):
|
||||
network_id=net_id).all())
|
||||
self.assertEqual([], db_masters)
|
||||
|
||||
def test_network_with_no_nat_cidrs_lifecycle(self):
|
||||
session = db_api.get_reader_session()
|
||||
extn = extn_db.ExtensionDbMixin()
|
||||
|
||||
# Create network with default no nat cidrs extension
|
||||
net = self._make_network(
|
||||
self.fmt, 'net1', True)['network']
|
||||
net_id = net['id']
|
||||
self.assertItemsEqual([],
|
||||
net['apic:no_nat_cidrs'])
|
||||
|
||||
# Test show.
|
||||
net = self._show('networks', net_id)['network']
|
||||
self.assertItemsEqual([],
|
||||
net['apic:no_nat_cidrs'])
|
||||
|
||||
# Test list.
|
||||
net = self._list(
|
||||
'networks', query_params=('id=%s' % net_id))['networks'][0]
|
||||
self.assertItemsEqual([],
|
||||
net['apic:no_nat_cidrs'])
|
||||
|
||||
# Test update with no nat cidrs extension
|
||||
net = self._update(
|
||||
'networks', net_id,
|
||||
{'network':
|
||||
{'apic:no_nat_cidrs': ['10.10.10.0/24']}})['network']
|
||||
self.assertItemsEqual(['10.10.10.0/24'],
|
||||
net['apic:no_nat_cidrs'])
|
||||
|
||||
# Test show after update.
|
||||
net = self._show('networks', net_id)['network']
|
||||
self.assertItemsEqual(['10.10.10.0/24'],
|
||||
net['apic:no_nat_cidrs'])
|
||||
|
||||
# Test delete.
|
||||
self._delete('networks', net_id)
|
||||
self.assertFalse(extn.get_network_extn_db(session, net_id))
|
||||
db_masters = (session.query(
|
||||
extn_db.NetworkExtensionNoNatCidrsDb).filter_by(
|
||||
network_id=net_id).all())
|
||||
self.assertEqual([], db_masters)
|
||||
|
||||
def test_external_network_lifecycle(self):
|
||||
session = db_api.get_reader_session()
|
||||
extn = extn_db.ExtensionDbMixin()
|
||||
@@ -12776,3 +12819,340 @@ class TestUpdateRouterSubnet(ApicAimTestCase):
|
||||
self._check_ip_in_cidr(router
|
||||
['external_gateway_info']['external_fixed_ips'][0]['ip_address'],
|
||||
fip_sub['cidr'])
|
||||
|
||||
|
||||
class TestExtensionNoNatCidrsScenarios(TestOpflexRpc, ApicAimTestCase):
|
||||
def _get_vrfid_from_net(self, net):
|
||||
kwargs = {}
|
||||
vrf_dn = net['network']['apic:distinguished_names']['VRF']
|
||||
_, tenant_rn, vrf_rn = vrf_dn.split('/')
|
||||
tenant = tenant_rn.split('tn-')[1]
|
||||
vrf = vrf_rn.split('ctx-')[1]
|
||||
kwargs['vrf_id'] = '%s %s' % (tenant, vrf)
|
||||
return kwargs
|
||||
|
||||
def test_no_nat_cidrs_isolated_private_net(self):
|
||||
# test no nat cidrs extension for isolated private network
|
||||
host = 'host1'
|
||||
kwargs = {'apic:no_nat_cidrs': ['10.10.10.0/24']}
|
||||
net = self._make_network(
|
||||
self.fmt, 'net10', True,
|
||||
arg_list=tuple(list(kwargs.keys())), **kwargs)
|
||||
net_id = net['network']['id']
|
||||
|
||||
self._make_subnet(self.fmt, net, '10.0.1.1', '10.0.1.0/24')
|
||||
|
||||
port = self._make_port(self.fmt, net_id)['port']
|
||||
port_id = port['id']
|
||||
port = self._bind_port_to_host(port_id, host)['port']
|
||||
self.assertEqual('ovs', port['binding:vif_type'])
|
||||
|
||||
# Call the RPC handler.
|
||||
request = {
|
||||
'device': 'tap' + port_id,
|
||||
'timestamp': 12345,
|
||||
'request_id': 'a_request'
|
||||
}
|
||||
response = self.driver.request_endpoint_details(
|
||||
n_context.get_admin_context(), request=request, host=host)
|
||||
self.assertEqual(set(['10.0.1.0/24', '10.10.10.0/24']),
|
||||
set(response['gbp_details']['vrf_subnets']))
|
||||
kwargs = self._get_vrfid_from_net(net)
|
||||
response = self.driver.get_vrf_details(
|
||||
n_context.get_admin_context(), **kwargs)
|
||||
self.assertEqual(set(['10.0.1.0/24', '10.10.10.0/24']),
|
||||
set(response['vrf_subnets']))
|
||||
|
||||
def test_no_nat_cidrs_external_network(self):
|
||||
# test no nat cidrs extension for external network
|
||||
ext_net = self._make_ext_network('ext-net1',
|
||||
dn=self.dn_t1_l1_n1)
|
||||
ext_net = self._update(
|
||||
'networks', ext_net['id'],
|
||||
{'network':
|
||||
{'apic:no_nat_cidrs': ['50.50.50.0/24']}})
|
||||
self._make_subnet(
|
||||
self.fmt, {'network': ext_net['network']}, '100.100.100.1',
|
||||
'100.100.100.0/24')
|
||||
|
||||
host = 'host1'
|
||||
port = self._make_port(self.fmt, ext_net['network']['id'])['port']
|
||||
port_id = port['id']
|
||||
port = self._bind_port_to_host(port_id, host)['port']
|
||||
self.assertEqual('ovs', port['binding:vif_type'])
|
||||
|
||||
# Call the RPC handler.
|
||||
request = {
|
||||
'device': 'tap' + port_id,
|
||||
'timestamp': 12345,
|
||||
'request_id': 'a_request'
|
||||
}
|
||||
response = self.driver.request_endpoint_details(
|
||||
n_context.get_admin_context(), request=request, host=host)
|
||||
self.assertEqual(['100.100.100.0/24', '50.50.50.0/24'],
|
||||
response['gbp_details']['vrf_subnets'])
|
||||
net = self._show('networks', ext_net['network']['id'])
|
||||
kwargs = self._get_vrfid_from_net(net)
|
||||
response = self.driver.get_vrf_details(
|
||||
n_context.get_admin_context(), **kwargs)
|
||||
self.assertEqual(['100.100.100.0/24', '50.50.50.0/24'],
|
||||
response['vrf_subnets'])
|
||||
|
||||
def test_no_nat_cidrs_private_net_router(self):
|
||||
# test no nat cidrs extension for private network connected to a
|
||||
# router with out external gateway
|
||||
host = 'host1'
|
||||
kwargs = {'apic:no_nat_cidrs': ['10.10.10.0/24']}
|
||||
net = self._make_network(
|
||||
self.fmt, 'net10', True,
|
||||
arg_list=tuple(list(kwargs.keys())), **kwargs)
|
||||
net_id = net['network']['id']
|
||||
|
||||
subnet_id = self._make_subnet(
|
||||
self.fmt, net, '10.0.1.1', '10.0.1.0/24')['subnet']['id']
|
||||
|
||||
rtr = self._make_router(
|
||||
self.fmt, net['network']['tenant_id'], 'router1')['router']
|
||||
self._router_interface_action('add', rtr['id'], subnet_id, None)
|
||||
|
||||
port = self._make_port(self.fmt, net_id)['port']
|
||||
port_id = port['id']
|
||||
port = self._bind_port_to_host(port_id, host)['port']
|
||||
self.assertEqual('ovs', port['binding:vif_type'])
|
||||
|
||||
# Call the RPC handler.
|
||||
request = {
|
||||
'device': 'tap' + port_id,
|
||||
'timestamp': 12345,
|
||||
'request_id': 'a_request'
|
||||
}
|
||||
response = self.driver.request_endpoint_details(
|
||||
n_context.get_admin_context(), request=request, host=host)
|
||||
self.assertEqual(set(['10.0.1.0/24', '10.10.10.0/24']),
|
||||
set(response['gbp_details']['vrf_subnets']))
|
||||
net = self._show('networks', net['network']['id'])
|
||||
kwargs = self._get_vrfid_from_net(net)
|
||||
response = self.driver.get_vrf_details(
|
||||
n_context.get_admin_context(), **kwargs)
|
||||
self.assertEqual(set(['10.0.1.0/24', '10.10.10.0/24']),
|
||||
set(response['vrf_subnets']))
|
||||
|
||||
def test_no_nat_cidrs_private_net_router_with_gw_case1(self):
|
||||
# test no nat cidrs extension for private network connected to a
|
||||
# router with an external gateway.
|
||||
# extension available in private network, but not in external network
|
||||
ext_net = self._make_ext_network('ext-net1',
|
||||
dn=self.dn_t1_l1_n1)
|
||||
self._make_subnet(
|
||||
self.fmt, {'network': ext_net}, '100.100.100.1',
|
||||
'100.100.100.0/24')
|
||||
|
||||
host = 'host1'
|
||||
kwargs = {'apic:no_nat_cidrs': ['10.10.10.0/24']}
|
||||
net = self._make_network(
|
||||
self.fmt, 'net10', True,
|
||||
arg_list=tuple(list(kwargs.keys())), **kwargs)
|
||||
net_id = net['network']['id']
|
||||
|
||||
subnet_id = self._make_subnet(
|
||||
self.fmt, net, '10.0.1.1', '10.0.1.0/24')['subnet']['id']
|
||||
|
||||
rtr = self._make_router(
|
||||
self.fmt, net['network']['tenant_id'], 'router1',
|
||||
external_gateway_info={'network_id': ext_net['id']})['router']
|
||||
self._router_interface_action('add', rtr['id'], subnet_id, None)
|
||||
|
||||
port = self._make_port(self.fmt, net_id)['port']
|
||||
port_id = port['id']
|
||||
port = self._bind_port_to_host(port_id, host)['port']
|
||||
self.assertEqual('ovs', port['binding:vif_type'])
|
||||
|
||||
# Call the RPC handler.
|
||||
request = {
|
||||
'device': 'tap' + port_id,
|
||||
'timestamp': 12345,
|
||||
'request_id': 'a_request'
|
||||
}
|
||||
response = self.driver.request_endpoint_details(
|
||||
n_context.get_admin_context(), request=request, host=host)
|
||||
self.assertEqual(['10.0.1.0/24', '10.10.10.0/24'],
|
||||
response['gbp_details']['vrf_subnets'])
|
||||
net = self._show('networks', net['network']['id'])
|
||||
kwargs = self._get_vrfid_from_net(net)
|
||||
response = self.driver.get_vrf_details(
|
||||
n_context.get_admin_context(), **kwargs)
|
||||
self.assertEqual(['10.0.1.0/24', '10.10.10.0/24'],
|
||||
response['vrf_subnets'])
|
||||
|
||||
def test_no_nat_cidrs_private_net_router_with_gw_case2(self):
|
||||
# test no nat cidrs extension for private network connected to a
|
||||
# router with an external gateway.
|
||||
# extension available in external network, but not in private network
|
||||
ext_net = self._make_ext_network('ext-net1',
|
||||
dn=self.dn_t1_l1_n1)
|
||||
ext_net = self._update(
|
||||
'networks', ext_net['id'],
|
||||
{'network':
|
||||
{'apic:no_nat_cidrs': ['50.50.50.0/24']}})
|
||||
self._make_subnet(
|
||||
self.fmt, {'network': ext_net['network']}, '100.100.100.1',
|
||||
'100.100.100.0/24')
|
||||
|
||||
host = 'host1'
|
||||
net = self._make_network(
|
||||
self.fmt, 'net10', True)
|
||||
net_id = net['network']['id']
|
||||
|
||||
subnet_id = self._make_subnet(
|
||||
self.fmt, net, '10.0.1.1', '10.0.1.0/24')['subnet']['id']
|
||||
|
||||
rtr = self._make_router(
|
||||
self.fmt, net['network']['tenant_id'], 'router1',
|
||||
external_gateway_info={'network_id': ext_net['network']['id']})
|
||||
self._router_interface_action('add', rtr['router']['id'],
|
||||
subnet_id, None)
|
||||
|
||||
port = self._make_port(self.fmt, net_id)['port']
|
||||
port_id = port['id']
|
||||
port = self._bind_port_to_host(port_id, host)['port']
|
||||
self.assertEqual('ovs', port['binding:vif_type'])
|
||||
|
||||
# Call the RPC handler.
|
||||
request = {
|
||||
'device': 'tap' + port_id,
|
||||
'timestamp': 12345,
|
||||
'request_id': 'a_request'
|
||||
}
|
||||
response = self.driver.request_endpoint_details(
|
||||
n_context.get_admin_context(), request=request, host=host)
|
||||
self.assertEqual(['10.0.1.0/24', '50.50.50.0/24'],
|
||||
response['gbp_details']['vrf_subnets'])
|
||||
net = self._show('networks', net['network']['id'])
|
||||
kwargs = self._get_vrfid_from_net(net)
|
||||
response = self.driver.get_vrf_details(
|
||||
n_context.get_admin_context(), **kwargs)
|
||||
self.assertEqual(['10.0.1.0/24', '50.50.50.0/24'],
|
||||
response['vrf_subnets'])
|
||||
|
||||
def test_no_nat_cidrs_private_net_router_with_gw_case3(self):
|
||||
# test no nat cidrs extension for private network connected to a
|
||||
# router with an external gateway.
|
||||
# extension available in both external network and private network
|
||||
ext_net = self._make_ext_network('ext-net1',
|
||||
dn=self.dn_t1_l1_n1)
|
||||
ext_net = self._update(
|
||||
'networks', ext_net['id'],
|
||||
{'network':
|
||||
{'apic:no_nat_cidrs': ['50.50.50.0/24']}})
|
||||
self._make_subnet(
|
||||
self.fmt, {'network': ext_net['network']}, '100.100.100.1',
|
||||
'100.100.100.0/24')
|
||||
|
||||
host = 'host1'
|
||||
kwargs = {'apic:no_nat_cidrs': ['10.10.10.0/24']}
|
||||
net = self._make_network(
|
||||
self.fmt, 'net10', True,
|
||||
arg_list=tuple(list(kwargs.keys())), **kwargs)
|
||||
net_id = net['network']['id']
|
||||
|
||||
subnet_id = self._make_subnet(
|
||||
self.fmt, net, '10.0.1.1', '10.0.1.0/24')['subnet']['id']
|
||||
|
||||
rtr = self._make_router(
|
||||
self.fmt, net['network']['tenant_id'], 'router1',
|
||||
external_gateway_info={'network_id': ext_net['network']['id']})
|
||||
self._router_interface_action('add', rtr['router']['id'],
|
||||
subnet_id, None)
|
||||
|
||||
port = self._make_port(self.fmt, net_id)['port']
|
||||
port_id = port['id']
|
||||
port = self._bind_port_to_host(port_id, host)['port']
|
||||
self.assertEqual('ovs', port['binding:vif_type'])
|
||||
|
||||
# Call the RPC handler.
|
||||
request = {
|
||||
'device': 'tap' + port_id,
|
||||
'timestamp': 12345,
|
||||
'request_id': 'a_request'
|
||||
}
|
||||
response = self.driver.request_endpoint_details(
|
||||
n_context.get_admin_context(), request=request, host=host)
|
||||
self.assertEqual(
|
||||
set(['10.0.1.0/24', '50.50.50.0/24', '10.10.10.0/24']),
|
||||
set(response['gbp_details']['vrf_subnets']))
|
||||
net = self._show('networks', net['network']['id'])
|
||||
kwargs = self._get_vrfid_from_net(net)
|
||||
response = self.driver.get_vrf_details(
|
||||
n_context.get_admin_context(), **kwargs)
|
||||
self.assertEqual(
|
||||
set(['10.0.1.0/24', '50.50.50.0/24', '10.10.10.0/24']),
|
||||
set(response['vrf_subnets']))
|
||||
|
||||
def test_no_nat_cidrs_with_address_scope(self):
|
||||
# test no nat cidrs extension when address scope available
|
||||
# Create address scope.
|
||||
scope = self._make_address_scope(
|
||||
self.fmt, 4, name='as1')['address_scope']
|
||||
scope_id = scope['id']
|
||||
|
||||
# Create subnet pool.
|
||||
pool = self._make_subnetpool(self.fmt, ['10.0.0.0/8'], name='sp1',
|
||||
tenant_id=self._tenant_id,
|
||||
address_scope_id=scope_id,
|
||||
default_prefixlen=24)['subnetpool']
|
||||
pool_id = pool['id']
|
||||
|
||||
# Create network.
|
||||
kwargs = {'apic:no_nat_cidrs': ['10.10.10.0/24']}
|
||||
net = self._make_network(
|
||||
self.fmt, 'net10', True,
|
||||
arg_list=tuple(list(kwargs.keys())), **kwargs)
|
||||
net_id = net['network']['id']
|
||||
|
||||
# Create subnet1.
|
||||
subnet = self._make_subnet(
|
||||
self.fmt, net, '10.0.1.1', '10.0.1.0/24',
|
||||
subnetpool_id=pool_id)['subnet']
|
||||
subnet_id = subnet['id']
|
||||
|
||||
# Create an external network and make it as a gateway to router
|
||||
ext_net = self._make_ext_network('ext-net1',
|
||||
dn=self.dn_t1_l1_n1)
|
||||
ext_net = self._update(
|
||||
'networks', ext_net['id'],
|
||||
{'network':
|
||||
{'apic:no_nat_cidrs': ['50.50.50.0/24']}})
|
||||
self._make_subnet(
|
||||
self.fmt, {'network': ext_net['network']}, '100.100.100.1',
|
||||
'100.100.100.0/24')
|
||||
|
||||
rtr = self._make_router(
|
||||
self.fmt, self._tenant_id, 'router1',
|
||||
external_gateway_info={'network_id': ext_net['network']['id']})
|
||||
self._router_interface_action('add', rtr['router']['id'],
|
||||
subnet_id, None)
|
||||
|
||||
host = 'host1'
|
||||
port = self._make_port(self.fmt, net_id)['port']
|
||||
port_id = port['id']
|
||||
port = self._bind_port_to_host(port_id, host)['port']
|
||||
self.assertEqual('ovs', port['binding:vif_type'])
|
||||
|
||||
# Call the RPC handler.
|
||||
request = {
|
||||
'device': 'tap' + port_id,
|
||||
'timestamp': 12345,
|
||||
'request_id': 'a_request'
|
||||
}
|
||||
response = self.driver.request_endpoint_details(
|
||||
n_context.get_admin_context(), request=request, host=host)
|
||||
self.assertEqual(
|
||||
set(['10.0.0.0/8', '50.50.50.0/24', '10.10.10.0/24']),
|
||||
set(response['gbp_details']['vrf_subnets']))
|
||||
net = self._show('networks', net['network']['id'])
|
||||
kwargs = self._get_vrfid_from_net(net)
|
||||
response = self.driver.get_vrf_details(
|
||||
n_context.get_admin_context(), **kwargs)
|
||||
self.assertEqual(
|
||||
set(['10.0.0.0/8', '50.50.50.0/24', '10.10.10.0/24']),
|
||||
set(response['vrf_subnets']))
|
||||
|
||||
Reference in New Issue
Block a user