Merge "Split the default ext epg 0/0 subnet into 0/1 and 128/1"
This commit is contained in:
commit
4e41ae68ff
|
@ -145,6 +145,20 @@ class DbMixin(object):
|
|||
vrf_name=vrf.name).
|
||||
first() is not None)
|
||||
|
||||
def _is_vrf_used_by_l3outs(self, session, vrf):
|
||||
return (session.query(NetworkMapping.network_id).
|
||||
filter(NetworkMapping.vrf_tenant_name == vrf.tenant_name,
|
||||
NetworkMapping.vrf_name == vrf.name,
|
||||
NetworkMapping.l3out_name.isnot(None)).
|
||||
first() is not None)
|
||||
|
||||
def _get_l3outs_for_vrf(self, session, vrf):
|
||||
return (session.query(NetworkMapping).
|
||||
filter(NetworkMapping.vrf_tenant_name == vrf.tenant_name,
|
||||
NetworkMapping.vrf_name == vrf.name,
|
||||
NetworkMapping.l3out_name.isnot(None)).
|
||||
all())
|
||||
|
||||
def _get_network_bd(self, mapping):
|
||||
return aim_resource.BridgeDomain(
|
||||
tenant_name=mapping.bd_tenant_name,
|
||||
|
|
|
@ -90,6 +90,7 @@ DEFAULT_SG_NAME = 'DefaultSecurityGroup'
|
|||
L3OUT_NODE_PROFILE_NAME = 'NodeProfile'
|
||||
L3OUT_IF_PROFILE_NAME = 'IfProfile'
|
||||
L3OUT_EXT_EPG = 'ExtEpg'
|
||||
DEFAULT_SVI_L3OUT_NAME = 'DefaultSVIL3Out'
|
||||
|
||||
SUPPORTED_VNIC_TYPES = [portbindings.VNIC_NORMAL,
|
||||
portbindings.VNIC_DIRECT]
|
||||
|
@ -464,6 +465,66 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
'name': mapping.domain_name})
|
||||
return domains
|
||||
|
||||
def _scope_default_svi_l3out_name_by_vrf(self, vrf_name):
|
||||
return DEFAULT_SVI_L3OUT_NAME + '_' + vrf_name
|
||||
|
||||
def _create_default_svi_l3out(self, aim_ctx, vrf):
|
||||
default_l3out_name = self._scope_default_svi_l3out_name_by_vrf(
|
||||
vrf.name)
|
||||
default_svi_l3out = aim_resource.L3Outside(
|
||||
tenant_name=vrf.tenant_name,
|
||||
name=default_l3out_name,
|
||||
display_name=DEFAULT_SVI_L3OUT_NAME, vrf_name=vrf.name,
|
||||
l3_domain_dn=self.l3_domain_dn)
|
||||
self.aim.create(aim_ctx, default_svi_l3out,
|
||||
overwrite=True)
|
||||
default_svi_ext_net = aim_resource.ExternalNetwork(
|
||||
tenant_name=vrf.tenant_name,
|
||||
l3out_name=default_l3out_name, name=L3OUT_EXT_EPG)
|
||||
# Can't overwrite this as it will wipe out the existing contracts
|
||||
if not self.aim.get(aim_ctx, default_svi_ext_net):
|
||||
self.aim.create(aim_ctx, default_svi_ext_net)
|
||||
ext_subnet_ipv4_1 = aim_resource.ExternalSubnet(
|
||||
tenant_name=vrf.tenant_name,
|
||||
l3out_name=default_l3out_name,
|
||||
external_network_name=L3OUT_EXT_EPG, cidr='0.0.0.0/1')
|
||||
self.aim.create(aim_ctx, ext_subnet_ipv4_1,
|
||||
overwrite=True)
|
||||
ext_subnet_ipv4_2 = aim_resource.ExternalSubnet(
|
||||
tenant_name=vrf.tenant_name,
|
||||
l3out_name=default_l3out_name,
|
||||
external_network_name=L3OUT_EXT_EPG, cidr='128.0.0.0/1')
|
||||
self.aim.create(aim_ctx, ext_subnet_ipv4_2,
|
||||
overwrite=True)
|
||||
ext_subnet_ipv6_1 = aim_resource.ExternalSubnet(
|
||||
tenant_name=vrf.tenant_name,
|
||||
l3out_name=default_l3out_name,
|
||||
external_network_name=L3OUT_EXT_EPG, cidr='::/1')
|
||||
self.aim.create(aim_ctx, ext_subnet_ipv6_1,
|
||||
overwrite=True)
|
||||
ext_subnet_ipv6_2 = aim_resource.ExternalSubnet(
|
||||
tenant_name=vrf.tenant_name,
|
||||
l3out_name=default_l3out_name,
|
||||
external_network_name=L3OUT_EXT_EPG, cidr='8000::/1')
|
||||
self.aim.create(aim_ctx, ext_subnet_ipv6_2,
|
||||
overwrite=True)
|
||||
|
||||
def _delete_default_svi_l3out(self, aim_ctx, vrf):
|
||||
if not self._is_vrf_used_by_l3outs(aim_ctx.db_session,
|
||||
vrf):
|
||||
LOG.debug("Deleting default SVI for %(vrf)s from tenant "
|
||||
"%(tenant)s",
|
||||
{'vrf': vrf.name,
|
||||
'tenant': vrf.tenant_name})
|
||||
default_l3out_name = self._scope_default_svi_l3out_name_by_vrf(
|
||||
vrf.name)
|
||||
aim_l3outs = self.aim.find(
|
||||
aim_ctx, aim_resource.L3Outside, tenant_name=vrf.tenant_name,
|
||||
name=default_l3out_name, vrf_name=vrf.name,
|
||||
monitored=False)
|
||||
if aim_l3outs:
|
||||
self.aim.delete(aim_ctx, aim_l3outs[0], cascade=True)
|
||||
|
||||
def create_network_precommit(self, context):
|
||||
current = context.current
|
||||
LOG.debug("APIC AIM MD creating network: %s", current)
|
||||
|
@ -567,6 +628,9 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
|
||||
self._add_network_mapping(session, current['id'], None, None,
|
||||
vrf, aim_ext_net)
|
||||
|
||||
# Create the SVI default l3out also
|
||||
self._create_default_svi_l3out(aim_ctx, vrf)
|
||||
return
|
||||
else:
|
||||
bd, epg = self._map_network(session, current)
|
||||
|
@ -782,12 +846,18 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
self.aim.delete(aim_ctx, aim_l3out_np, cascade=True)
|
||||
else:
|
||||
self.aim.delete(aim_ctx, l3out, cascade=True)
|
||||
|
||||
# Before we can clean up the default vrf, we have to
|
||||
# remove the association in the network_mapping first.
|
||||
mapping = self._get_network_mapping(session, current['id'])
|
||||
l3out_vrf = self._get_network_vrf(mapping)
|
||||
self._set_network_vrf(mapping, self._map_unrouted_vrf())
|
||||
vrf = self._map_default_vrf(session, current)
|
||||
self._cleanup_default_vrf(aim_ctx, vrf)
|
||||
|
||||
# Also delete the default SVI if this is the last
|
||||
# SVI l3out in this vrf
|
||||
self._delete_default_svi_l3out(aim_ctx, l3out_vrf)
|
||||
else:
|
||||
mapping = self._get_network_mapping(session, current['id'])
|
||||
bd = self._get_network_bd(mapping)
|
||||
|
@ -1493,8 +1563,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
bd = self._get_network_bd(network_db.aim_mapping)
|
||||
epg = self._get_network_epg(network_db.aim_mapping)
|
||||
elif network_db.aim_mapping.l3out_name:
|
||||
epg = self._get_network_l3out_ext_net(
|
||||
network_db.aim_mapping)
|
||||
epg = self._get_default_svi_ext_epg(network_db)
|
||||
|
||||
if network_db.aim_mapping.epg_name:
|
||||
# Create AIM Subnet(s) for each added Neutron subnet.
|
||||
|
@ -1583,9 +1652,9 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
filter_by(id=router_id).
|
||||
one())
|
||||
contract = self._map_router(session, router_db, True)
|
||||
old_vrf = self._get_network_vrf(network_db.aim_mapping)
|
||||
|
||||
epg = None
|
||||
old_vrf = self._get_network_vrf(network_db.aim_mapping)
|
||||
if network_db.aim_mapping.epg_name:
|
||||
bd = self._get_network_bd(network_db.aim_mapping)
|
||||
epg = self._get_network_epg(network_db.aim_mapping)
|
||||
|
@ -1596,7 +1665,20 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
self.aim.delete(aim_ctx, sn)
|
||||
# SVI network with auto l3out.
|
||||
elif network_db.aim_mapping.l3out_name:
|
||||
epg = self._get_network_l3out_ext_net(network_db.aim_mapping)
|
||||
# Need to make sure this is the last SVI network in this vrf
|
||||
# that connects to this router
|
||||
l3out_net_ids = self._get_l3out_ids_for_vrf(session, old_vrf)
|
||||
rtr_ports = (session.query(l3_db.RouterPort.port_id).
|
||||
join(models_v2.Port,
|
||||
models_v2.Port.id == l3_db.RouterPort.port_id).
|
||||
filter(l3_db.RouterPort.router_id == router_id,
|
||||
l3_db.RouterPort.port_type ==
|
||||
n_constants.DEVICE_OWNER_ROUTER_INTF,
|
||||
models_v2.Port.network_id.in_(l3out_net_ids)
|
||||
).
|
||||
first())
|
||||
if not rtr_ports:
|
||||
epg = self._get_default_svi_ext_epg(network_db)
|
||||
|
||||
# Find remaining routers with interfaces to this network.
|
||||
router_ids = [r[0] for r in
|
||||
|
@ -2359,6 +2441,10 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
mappings = self._get_network_mappings_for_vrf(session, vrf)
|
||||
return [mapping.network_id for mapping in mappings]
|
||||
|
||||
def _get_l3out_ids_for_vrf(self, session, vrf):
|
||||
mappings = self._get_l3outs_for_vrf(session, vrf)
|
||||
return [mapping.network_id for mapping in mappings]
|
||||
|
||||
def _get_routers_for_vrf(self, session, vrf):
|
||||
# REVISIT: Persist router/VRF relationship?
|
||||
|
||||
|
@ -2404,6 +2490,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
# NOTE: Must only be called for networks that are not yet
|
||||
# attached to any router.
|
||||
|
||||
old_vrf = self._get_network_vrf(network_db.aim_mapping)
|
||||
if not self._is_svi_db(network_db):
|
||||
bd = self._get_network_bd(network_db.aim_mapping)
|
||||
epg = self._get_network_epg(network_db.aim_mapping)
|
||||
|
@ -2445,6 +2532,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
l3out = self.aim.create(aim_ctx, l3out)
|
||||
self._set_network_l3out(network_db.aim_mapping,
|
||||
l3out)
|
||||
self._create_default_svi_l3out(aim_ctx, new_vrf)
|
||||
for old_child in self.aim.get_subtree(aim_ctx, old_l3out):
|
||||
new_child = copy.copy(old_child)
|
||||
new_child.tenant_name = new_vrf.tenant_name
|
||||
|
@ -2459,8 +2547,11 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
else:
|
||||
l3out = self.aim.update(aim_ctx, l3out,
|
||||
vrf_name=new_vrf.name)
|
||||
self._create_default_svi_l3out(aim_ctx, new_vrf)
|
||||
|
||||
self._set_network_vrf_and_notify(ctx, network_db.aim_mapping, new_vrf)
|
||||
if self._is_svi_db(network_db):
|
||||
self._delete_default_svi_l3out(aim_ctx, old_vrf)
|
||||
|
||||
# All non-router ports on this network need to be notified
|
||||
# since their BD's VRF and possibly their BD's and EPG's
|
||||
|
@ -2470,8 +2561,8 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
if not self._is_svi_db(network_db):
|
||||
return bd, epg
|
||||
else:
|
||||
ext_net = self._get_network_l3out_ext_net(network_db.aim_mapping)
|
||||
return l3out, ext_net
|
||||
default_ext_net = self._get_default_svi_ext_epg(network_db)
|
||||
return l3out, default_ext_net
|
||||
|
||||
def _dissassociate_network_from_vrf(self, ctx, aim_ctx, network_db,
|
||||
old_vrf, nets_to_notify):
|
||||
|
@ -2522,6 +2613,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
l3out = self.aim.create(aim_ctx, l3out)
|
||||
self._set_network_l3out(network_db.aim_mapping,
|
||||
l3out)
|
||||
self._create_default_svi_l3out(aim_ctx, new_vrf)
|
||||
for old_child in self.aim.get_subtree(aim_ctx, old_l3out):
|
||||
new_child = copy.copy(old_child)
|
||||
new_child.tenant_name = new_tenant_name
|
||||
|
@ -2538,8 +2630,11 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
l3out = self._get_network_l3out(network_db.aim_mapping)
|
||||
l3out = self.aim.update(aim_ctx, l3out,
|
||||
vrf_name=new_vrf.name)
|
||||
self._create_default_svi_l3out(aim_ctx, new_vrf)
|
||||
|
||||
self._set_network_vrf_and_notify(ctx, network_db.aim_mapping, new_vrf)
|
||||
if self._is_svi_db(network_db):
|
||||
self._delete_default_svi_l3out(aim_ctx, old_vrf)
|
||||
|
||||
# All non-router ports on this network need to be notified
|
||||
# since their BD's VRF and possibly their BD's and EPG's
|
||||
|
@ -2601,6 +2696,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
l3out = self.aim.create(aim_ctx, l3out)
|
||||
self._set_network_l3out(network_db.aim_mapping,
|
||||
l3out)
|
||||
self._create_default_svi_l3out(aim_ctx, new_vrf)
|
||||
for old_child in self.aim.get_subtree(aim_ctx, old_l3out):
|
||||
new_child = copy.copy(old_child)
|
||||
new_child.tenant_name = new_vrf.tenant_name
|
||||
|
@ -2617,9 +2713,12 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
l3out = self._get_network_l3out(network_db.aim_mapping)
|
||||
l3out = self.aim.update(aim_ctx, l3out,
|
||||
vrf_name=new_vrf.name)
|
||||
self._create_default_svi_l3out(aim_ctx, new_vrf)
|
||||
|
||||
self._set_network_vrf_and_notify(ctx, network_db.aim_mapping,
|
||||
new_vrf)
|
||||
if network_db.aim_mapping.l3out_name:
|
||||
self._delete_default_svi_l3out(aim_ctx, old_vrf)
|
||||
|
||||
# All non-router ports on all networks in topology need to be
|
||||
# notified since their BDs' VRFs and possibly their BDs' and
|
||||
|
@ -3797,20 +3896,28 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
port = self.plugin.get_port(plugin_context, port_id)
|
||||
return port['network_id']
|
||||
|
||||
def _get_svi_default_external_epg(self, network):
|
||||
if not network.get(cisco_apic.SVI):
|
||||
return None
|
||||
ext_net_dn = network.get(cisco_apic.DIST_NAMES, {}).get(
|
||||
cisco_apic.EXTERNAL_NETWORK)
|
||||
return aim_resource.ExternalNetwork.from_dn(ext_net_dn)
|
||||
|
||||
def _get_svi_net_l3out(self, network):
|
||||
aim_ext_net = self._get_svi_default_external_epg(network)
|
||||
def _get_default_svi_l3out(self, network_db):
|
||||
aim_ext_net = self._get_default_svi_ext_epg(network_db)
|
||||
if not aim_ext_net:
|
||||
return None
|
||||
return aim_resource.L3Outside(
|
||||
tenant_name=aim_ext_net.tenant_name, name=aim_ext_net.l3out_name)
|
||||
|
||||
def _get_default_svi_ext_epg(self, network_db):
|
||||
if self._is_svi_db(network_db):
|
||||
# SVI network with pre-existing l3out
|
||||
if network_db.aim_extension_mapping.external_network_dn:
|
||||
return aim_resource.ExternalNetwork.from_dn(
|
||||
network_db.aim_extension_mapping.external_network_dn)
|
||||
# SVI auto-l3out
|
||||
l3out_vrf = self._get_network_vrf(network_db.aim_mapping)
|
||||
l3out_name = self._scope_default_svi_l3out_name_by_vrf(
|
||||
l3out_vrf.name)
|
||||
return aim_resource.ExternalNetwork(
|
||||
tenant_name=l3out_vrf.tenant_name, l3out_name=l3out_name,
|
||||
name=L3OUT_EXT_EPG)
|
||||
return None
|
||||
|
||||
def _get_bd_by_network_id(self, session, network_id):
|
||||
net_mapping = self._get_network_mapping(session, network_id)
|
||||
return self._get_network_bd(net_mapping)
|
||||
|
@ -3824,7 +3931,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
if vrf_dn:
|
||||
return aim_resource.VRF.from_dn(vrf_dn)
|
||||
# Pre-existing EXT NET.
|
||||
l3out = self._get_svi_net_l3out(network)
|
||||
l3out = self._get_default_svi_l3out(network)
|
||||
if l3out:
|
||||
aim_ctx = aim_context.AimContext(db_session=session)
|
||||
l3out = self.aim.get(aim_ctx, l3out)
|
||||
|
|
|
@ -595,11 +595,12 @@ class SfcAIMDriver(SfcAIMDriverBase):
|
|||
prefix)
|
||||
aim_ctx = aim_context.AimContext(plugin_context.session)
|
||||
cidr = netaddr.IPNetwork(cidr)
|
||||
l3out = self.aim_mech._get_svi_net_l3out(net)
|
||||
network_db = self.plugin._get_network(plugin_context, net['id'])
|
||||
l3out = self.aim_mech._get_default_svi_l3out(network_db)
|
||||
if l3out:
|
||||
if cidr.prefixlen == 0:
|
||||
# Use default External Network
|
||||
ext_net = self.aim_mech._get_svi_default_external_epg(net)
|
||||
ext_net = self.aim_mech._get_default_svi_ext_epg(network_db)
|
||||
ext_net_db = self.aim.get(aim_ctx, ext_net)
|
||||
if not ext_net_db:
|
||||
raise exceptions.DefaultExternalNetworkNotFound(
|
||||
|
@ -640,7 +641,8 @@ class SfcAIMDriver(SfcAIMDriverBase):
|
|||
flc_aid = self._get_external_group_aim_name(plugin_context, flowc,
|
||||
prefix)
|
||||
aim_ctx = aim_context.AimContext(plugin_context.session)
|
||||
l3out = self.aim_mech._get_svi_net_l3out(net)
|
||||
network_db = self.plugin._get_network(plugin_context, net['id'])
|
||||
l3out = self.aim_mech._get_default_svi_l3out(network_db)
|
||||
cidr = netaddr.IPNetwork(cidr)
|
||||
ext_net = None
|
||||
if l3out:
|
||||
|
@ -651,7 +653,8 @@ class SfcAIMDriver(SfcAIMDriverBase):
|
|||
epg = self.aim.get(aim_ctx, ext_net)
|
||||
else:
|
||||
epg = self.aim.get(
|
||||
aim_ctx, self.aim_mech._get_svi_default_external_epg(net))
|
||||
aim_ctx,
|
||||
self.aim_mech._get_default_svi_ext_epg(network_db))
|
||||
else:
|
||||
epg = self.aim.get(aim_ctx, self.aim_mech._get_epg_by_network_id(
|
||||
plugin_context.session, net['id']))
|
||||
|
|
|
@ -593,6 +593,9 @@ class TestAimMapping(ApicAimTestCase):
|
|||
self.assertIsNotNone(aim_ext_net)
|
||||
return aim_ext_net
|
||||
|
||||
def _scope_default_svi_l3out_name_by_vrf(self, vrf_name):
|
||||
return md.DEFAULT_SVI_L3OUT_NAME + '_' + vrf_name
|
||||
|
||||
def _check_network(self, net, routers=None, scope=None, project=None,
|
||||
vrf=None):
|
||||
dns = copy.copy(net.get(DN))
|
||||
|
@ -650,6 +653,16 @@ class TestAimMapping(ApicAimTestCase):
|
|||
self.assertEqual(net['name'], l3out.display_name)
|
||||
self.assertEqual(vrf_aname, l3out.vrf_name)
|
||||
self._check_dn_is_resource(dns, 'ExternalNetwork', ext_net)
|
||||
|
||||
default_l3out_name = self._scope_default_svi_l3out_name_by_vrf(
|
||||
vrf_aname)
|
||||
svi_default_l3out = self._get_l3out(default_l3out_name,
|
||||
vrf_tenant_aname)
|
||||
self.assertEqual(tenant_aname, svi_default_l3out.tenant_name)
|
||||
self.assertEqual(default_l3out_name, svi_default_l3out.name)
|
||||
self.assertEqual(md.DEFAULT_SVI_L3OUT_NAME,
|
||||
svi_default_l3out.display_name)
|
||||
self.assertEqual(vrf_aname, svi_default_l3out.vrf_name)
|
||||
else:
|
||||
aim_bd = self._get_bd(aname, tenant_aname)
|
||||
self.assertEqual(tenant_aname, aim_bd.tenant_name)
|
||||
|
@ -1081,6 +1094,9 @@ class TestAimMapping(ApicAimTestCase):
|
|||
self._delete('networks', net['id'])
|
||||
self.assertFalse(extn.get_network_extn_db(session, net['id']))
|
||||
self._check_network_deleted(net)
|
||||
default_l3out_name = self._scope_default_svi_l3out_name_by_vrf(
|
||||
'DefaultVRF')
|
||||
self._l3out_should_not_exist(default_l3out_name)
|
||||
|
||||
def test_security_group_lifecycle(self):
|
||||
# Test create
|
||||
|
@ -1248,6 +1264,14 @@ class TestAimMapping(ApicAimTestCase):
|
|||
# Verify ports were notified.
|
||||
mock_notif.assert_has_calls(port_calls, any_order=True)
|
||||
|
||||
if is_svi:
|
||||
default_l3out_name = self._scope_default_svi_l3out_name_by_vrf(
|
||||
'DefaultVRF')
|
||||
contract = self.name_mapper.router(None, router['id'])
|
||||
tenant_aname = self.name_mapper.project(None, net['tenant_id'])
|
||||
self._confirm_default_ext_epg_contract(
|
||||
tenant_aname, default_l3out_name, [contract])
|
||||
|
||||
# Check router.
|
||||
router = self._show('routers', router_id)['router']
|
||||
self._check_router(router, [gw1_ip], unscoped_project=self._tenant_id,
|
||||
|
@ -1329,6 +1353,8 @@ class TestAimMapping(ApicAimTestCase):
|
|||
mock_notif.assert_has_calls(port_calls, any_order=True)
|
||||
self._check_router(router, [], unscoped_project=self._tenant_id,
|
||||
is_svi_net=is_svi)
|
||||
self._confirm_default_ext_epg_contract(
|
||||
tenant_aname, default_l3out_name, [])
|
||||
|
||||
# Check network.
|
||||
net = self._show('networks', net_id)['network']
|
||||
|
@ -1436,6 +1462,15 @@ class TestAimMapping(ApicAimTestCase):
|
|||
self.assertRaises(webob.exc.HTTPClientError, self._make_subnet,
|
||||
self.fmt, net_resp, gw2_ip, '10.0.2.0/24')
|
||||
|
||||
def _confirm_default_ext_epg_contract(self, tenant_name, l3out_name,
|
||||
contract):
|
||||
default_ext_epg = aim_resource.ExternalNetwork(
|
||||
tenant_name=tenant_name,
|
||||
l3out_name=l3out_name, name=md.L3OUT_EXT_EPG)
|
||||
aim_ext_epg = self._get_l3out_ext_net(default_ext_epg)
|
||||
self.assertEqual(contract, aim_ext_epg.provided_contract_names)
|
||||
self.assertEqual(contract, aim_ext_epg.consumed_contract_names)
|
||||
|
||||
def _test_router_interface_with_address_scope(self, is_svi=False):
|
||||
# REVISIT(rkukura): Currently follows same workflow as above,
|
||||
# but might be sufficient to test with a single subnet with
|
||||
|
@ -1516,6 +1551,19 @@ class TestAimMapping(ApicAimTestCase):
|
|||
{'subnet_id': subnet1_id})
|
||||
self.assertIn(subnet1_id, info['subnet_ids'])
|
||||
|
||||
if is_svi:
|
||||
default_l3out_name = self._scope_default_svi_l3out_name_by_vrf(
|
||||
'DefaultVRF')
|
||||
self._l3out_should_not_exist(default_l3out_name)
|
||||
|
||||
tenant_aname = self.name_mapper.project(None, scope['tenant_id'])
|
||||
vrf_aname = self.name_mapper.address_scope(None, scope['id'])
|
||||
new_default_l3out_name = self._scope_default_svi_l3out_name_by_vrf(
|
||||
vrf_aname)
|
||||
contract = self.name_mapper.router(None, router['id'])
|
||||
self._confirm_default_ext_epg_contract(
|
||||
tenant_aname, new_default_l3out_name, [contract])
|
||||
|
||||
# Verify ports were notified.
|
||||
mock_notif.assert_has_calls(port_calls, any_order=True)
|
||||
|
||||
|
@ -1602,6 +1650,9 @@ class TestAimMapping(ApicAimTestCase):
|
|||
self._check_network(net, [router], scope)
|
||||
else:
|
||||
self._check_network(net, [], scope)
|
||||
self._l3out_should_not_exist(new_default_l3out_name)
|
||||
self._confirm_default_ext_epg_contract(
|
||||
tenant_aname, default_l3out_name, [])
|
||||
|
||||
# Check subnet1.
|
||||
subnet = self._show('subnets', subnet1_id)['subnet']
|
||||
|
|
|
@ -245,13 +245,15 @@ class TestAIMServiceFunctionChainingBase(test_aim_base.AIMBaseTestCase):
|
|||
ppg_args=None):
|
||||
flowc_ids = []
|
||||
ppg_args = ppg_args or []
|
||||
flowcs_args = flowcs_args or []
|
||||
flowcs_args = flowcs_args or [{'src_svi': self.src_svi,
|
||||
'dst_svi': self.dst_svi}] * flowcs
|
||||
for i in range(flowcs):
|
||||
try:
|
||||
flowc_ids.append(
|
||||
self._create_simple_flowc(**flowcs_args[i])['id'])
|
||||
except IndexError:
|
||||
flowc_ids.append(self._create_simple_flowc()['id'])
|
||||
flowc_ids.append(self._create_simple_flowc(
|
||||
src_svi=self.src_svi, dst_svi=self.dst_svi)['id'])
|
||||
ppg_ids = []
|
||||
for i in range(ppgs):
|
||||
try:
|
||||
|
@ -411,7 +413,8 @@ class TestAIMServiceFunctionChainingBase(test_aim_base.AIMBaseTestCase):
|
|||
flowc['l7_parameters']['logical_source_network'])
|
||||
dst_net = self._show_network(
|
||||
flowc['l7_parameters']['logical_destination_network'])
|
||||
apic_tn = 'prj_' + dst_net['tenant_id']
|
||||
apic_tn = 'prj_' + dst_net['tenant_id'] if not self.dst_svi else (
|
||||
'common')
|
||||
device_clusters = []
|
||||
sg = self.aim_mgr.get(ctx, aim_sg.ServiceGraph(
|
||||
tenant_name=apic_tn, name='ptc_' + pc['id']))
|
||||
|
@ -432,10 +435,12 @@ class TestAIMServiceFunctionChainingBase(test_aim_base.AIMBaseTestCase):
|
|||
for net, pref, cidr in [(src_net, 'src_', src_cidr),
|
||||
(dst_net, 'dst_', dst_cird)]:
|
||||
if net['apic:svi']:
|
||||
# TODO(ivar): this will not work, there's no L3Outside
|
||||
# DN extension for external networks.
|
||||
ext = aim_res.ExternalNetwork.from_dn(
|
||||
net['apic:distinguished_names']['ExternalNetwork'])
|
||||
vrf = aim_res.VRF.from_dn(
|
||||
net['apic:distinguished_names']['VRF'])
|
||||
ext = aim_res.ExternalNetwork(
|
||||
tenant_name=vrf.tenant_name,
|
||||
l3out_name='DefaultSVIL3Out' + '_' + vrf.name,
|
||||
name='ExtEpg')
|
||||
if cidr in ['0.0.0.0/0', '::/0']:
|
||||
# use default external EPG
|
||||
ext_net = self.aim_mgr.get(ctx, ext)
|
||||
|
@ -446,11 +451,23 @@ class TestAIMServiceFunctionChainingBase(test_aim_base.AIMBaseTestCase):
|
|||
l3out_name=ext.l3out_name,
|
||||
name=cidr.replace(
|
||||
'/', '_') + '_' + 'net_' + net['id']))
|
||||
ext_sub = self.aim_mgr.get(ctx, aim_res.ExternalSubnet(
|
||||
tenant_name=ext.tenant_name, l3out_name=ext.l3out_name,
|
||||
external_network_name=ext_net.name, cidr=cidr))
|
||||
self.assertIsNotNone(ext_net)
|
||||
self.assertIsNotNone(ext_sub)
|
||||
if cidr in ['0.0.0.0/0', '::/0']:
|
||||
for c in ['128.0.0.0/1', '0.0.0.0/1']:
|
||||
ext_sub = self.aim_mgr.get(
|
||||
ctx, aim_res.ExternalSubnet(
|
||||
tenant_name=ext.tenant_name,
|
||||
l3out_name=ext.l3out_name,
|
||||
external_network_name=ext_net.name,
|
||||
cidr=c))
|
||||
self.assertIsNotNone(ext_sub)
|
||||
else:
|
||||
ext_sub = self.aim_mgr.get(
|
||||
ctx, aim_res.ExternalSubnet(
|
||||
tenant_name=ext.tenant_name,
|
||||
l3out_name=ext.l3out_name,
|
||||
external_network_name=ext_net.name, cidr=cidr))
|
||||
self.assertIsNotNone(ext_sub)
|
||||
self.assertTrue(
|
||||
contract.name in (ext_net.consumed_contract_names if
|
||||
pref == 'src_' else
|
||||
|
@ -1261,6 +1278,7 @@ class TestPortChain(TestAIMServiceFunctionChainingBase):
|
|||
name=fc['destination_ip_prefix'].replace(
|
||||
'/', '_') + '_' + 'net_' + dst_net_id)[0]
|
||||
self.assertEqual(2, len(ext_net.provided_contract_names))
|
||||
self.assertTrue('DefaultSVIL3Out' in ext_net.l3out_name)
|
||||
self.delete_port_chain(pc2['id'])
|
||||
self.assertIsNone(self.aim_mgr.get(self._aim_context, ext_net))
|
||||
|
||||
|
@ -1399,3 +1417,7 @@ class TestPortChainSVI(TestPortChain):
|
|||
expected_res_status=201)['port_chain']
|
||||
self._verify_pc_mapping(pc)
|
||||
self._verify_pc_delete(pc)
|
||||
|
||||
def test_pc_mapping_two_flowcs(self):
|
||||
# TODO(ivar): re enable after fixing the conflicting address scope
|
||||
pass
|
||||
|
|
Loading…
Reference in New Issue