Merge "Split the default ext epg 0/0 subnet into 0/1 and 128/1"

This commit is contained in:
Zuul 2018-04-10 19:41:51 +00:00 committed by Gerrit Code Review
commit 4e41ae68ff
5 changed files with 228 additions and 31 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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']))

View File

@ -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']

View File

@ -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