def test_delete_ext_net_with_vrf(self): l3out = a_res.L3Outside(tenant_name='t1', name='o1', display_name='OUT') ext_net = a_res.ExternalNetwork( tenant_name='t1', l3out_name='o1', name='inet1', display_name='INET1') self.mgr.create(self.ctx, a_res.Tenant(name=self.vrf1_tenant_name)) self.mgr.create(self.ctx, a_res.Tenant(name=self.vrf2_tenant_name)) self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.ns.update_external_cidrs(self. ctx, ext_net, ['20.20.20.0/24', '50.50.0.0/16']) # Connect vrf1 & vrf2 to ext_net with external-subnet vrf1 = a_res.VRF(tenant_name=self.vrf1_tenant_name, name='vrf1', display_name='VRF1') self.mgr.create(self.ctx, vrf1) if self.fix_l3out_vrf: self.mgr.update(self.ctx, l3out, vrf_name=vrf1.name) ext_net.provided_contract_names = ['p1_vrf1', 'p2_vrf1'] ext_net.consumed_contract_names = ['c1_vrf1', 'c2_vrf1'] self.ns.connect_vrf(self.ctx, ext_net, vrf1) vrf2 = a_res.VRF(tenant_name=self.vrf2_tenant_name, name='vrf2', display_name='VRF2') self.mgr.create(self.ctx, vrf2) if self.fix_l3out_vrf: self.mgr.update(self.ctx, l3out, vrf_name=vrf2.name) ext_net.provided_contract_names = ['p1_vrf2', 'p2_vrf2'] ext_net.consumed_contract_names = ['c1_vrf2', 'c2_vrf2'] self.ns.connect_vrf(self.ctx, ext_net, vrf2) self._check_delete_ext_net_with_vrf('stage1') self.ns.delete_external_network(self.ctx, ext_net) self._check_delete_ext_net_with_vrf('stage2')
def test_connect_vrfs(self): l3out = a_res.L3Outside(tenant_name='t1', name='o1', display_name='OUT') ext_net = a_res.ExternalNetwork( tenant_name='t1', l3out_name='o1', name='inet1', display_name='INET1') self.mgr.create(self.ctx, a_res.Tenant(name=self.vrf1_tenant_name)) self.mgr.create(self.ctx, a_res.Tenant(name=self.vrf2_tenant_name)) self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.ns.update_external_cidrs(self.ctx, ext_net, ['20.20.20.0/24', '50.50.0.0/16']) # connect vrf_1 vrf1 = a_res.VRF(tenant_name=self.vrf1_tenant_name, name='vrf1', display_name='VRF1') if self.vrf1_tenant_name != self.bd1_tenant_name: self.mgr.create(self.ctx, a_res.Tenant(name='dept1')) if self.fix_l3out_vrf: self.mgr.update(self.ctx, l3out, vrf_name=vrf1.name) bd1 = a_res.BridgeDomain(tenant_name=self.bd1_tenant_name, name='bd1', limit_ip_learn_to_subnets=True, vrf_name='vrf1') self.mgr.create(self.ctx, vrf1) self.mgr.create(self.ctx, bd1) ext_net.provided_contract_names = ['p1_vrf1', 'p2_vrf1'] ext_net.consumed_contract_names = ['c1_vrf1', 'c2_vrf1'] self.ns.connect_vrf(self.ctx, ext_net, vrf1) connected_vrfs = self.ns.read_vrfs(self.ctx, ext_net) self.assertEqual(vrf1, connected_vrfs[0]) self._check_connect_vrfs('stage1') # connect vrf_1 again - should be no-op self.ns.connect_vrf(self.ctx, ext_net, vrf1) self._check_connect_vrfs('stage1') # connect vrf_2 vrf2 = a_res.VRF(tenant_name=self.vrf2_tenant_name, name='vrf2', display_name='VRF2') bd2 = a_res.BridgeDomain(tenant_name=self.vrf2_tenant_name, name='bd2', limit_ip_learn_to_subnets=True, vrf_name='vrf2') self.mgr.create(self.ctx, vrf2) self.mgr.create(self.ctx, bd2) ext_net.provided_contract_names = ['p1_vrf2', 'p2_vrf2'] ext_net.consumed_contract_names = ['c1_vrf2', 'c2_vrf2'] if self.fix_l3out_vrf: self.mgr.update(self.ctx, l3out, vrf_name=vrf2.name) self.ns.connect_vrf(self.ctx, ext_net, vrf2) self._check_connect_vrfs('stage2') # disconnect vrf_1 self.ns.disconnect_vrf(self.ctx, ext_net, vrf1) self._check_connect_vrfs('stage3') # disconnect vrf_2 self.ns.disconnect_vrf(self.ctx, ext_net, vrf2) self._check_connect_vrfs('stage4')
def test_squash_operations(self): # Craft some objects and push them aim_converter = converter.AimToAciModelConverter() tn = a_res.Tenant(name='tn1', display_name='foo') bd = a_res.BridgeDomain(tenant_name='tn1', name='bd1', display_name='bar') vrf = a_res.VRF(tenant_name='tn1', name='vrf1', display_name='pippo') self.manager.push_aim_resources({ 'create': [tn, bd], 'delete': aim_converter.convert([vrf]) }) self.assertEqual(1, len(self.manager.object_backlog.queue)) old = self.manager.object_backlog.queue[0] # Idempotent self.manager.push_aim_resources({ 'create': [tn, bd], 'delete': aim_converter.convert([vrf]) }) self.assertEqual(1, len(self.manager.object_backlog.queue)) curr = self.manager.object_backlog.queue[0] self.assertEqual(old, curr) # Now replace something bd2 = a_res.BridgeDomain(tenant_name='tn1', name='bd2', display_name='bar') bd = copy.deepcopy(bd) bd.display_name = 'foobar' self.manager.push_aim_resources({'create': [bd2, bd], 'delete': []}) self.assertEqual(2, len(self.manager.object_backlog.queue)) self.assertEqual({ 'create': [bd2], 'delete': [] }, self.manager.object_backlog.queue[1]) self.assertEqual( 'foobar', self.manager.object_backlog.queue[0]['create'][1].display_name) # Add something completely different vrf2 = a_res.VRF(tenant_name='tn1', name='vrf2', display_name='pippo') self.manager.push_aim_resources({ 'create': [vrf2], 'delete': aim_converter.convert([bd]) }) self.assertEqual( { 'create': [vrf2], 'delete': aim_converter.convert([bd]) }, self.manager.object_backlog.queue[2])
def test_bd_l3out_vrf_in_tenant(self): self.mgr.create(self.ctx, a_res.Tenant(name='dept1')) vrf = a_res.VRF(tenant_name='dept1', name='default') bd1_dept1 = a_res.BridgeDomain(tenant_name='dept1', name='bd1', limit_ip_learn_to_subnets=True, vrf_name='default') bd2_dept1 = a_res.BridgeDomain(tenant_name='dept1', name='bd2', limit_ip_learn_to_subnets=True, vrf_name='foo') for o in [vrf, bd1_dept1, bd2_dept1]: self.mgr.create(self.ctx, o) l3out = a_res.L3Outside(tenant_name='dept1', name='o1') ext_net = a_res.ExternalNetwork( tenant_name='dept1', l3out_name='o1', name='inet1') self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.mgr.update(self.ctx, l3out, vrf_name='default') self._verify(present=[bd1_dept1, bd2_dept1]) self.ns.connect_vrf(self.ctx, ext_net, vrf) bd1_dept1.l3out_names = ['o1'] self._verify(present=[bd1_dept1, bd2_dept1]) self.ns.disconnect_vrf(self.ctx, ext_net, vrf) bd1_dept1.l3out_names = [] self._verify(present=[bd1_dept1, bd2_dept1])
def test_external_subnet_update(self): l3out = a_res.L3Outside(tenant_name='t1', name='o1', display_name='OUT') ext_net = a_res.ExternalNetwork( tenant_name='t1', l3out_name='o1', name='inet1', display_name='INET1') self.mgr.create(self.ctx, a_res.Tenant(name=self.vrf1_tenant_name)) self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.ns.update_external_cidrs(self.ctx, ext_net, ['20.20.20.0/24', '50.50.0.0/16']) # Connect vrf1 to ext_net vrf1 = a_res.VRF(tenant_name=self.vrf1_tenant_name, name='vrf1', display_name='VRF1') self.mgr.create(self.ctx, vrf1) if self.fix_l3out_vrf: self.mgr.update(self.ctx, l3out, vrf_name=vrf1.name) ext_net.provided_contract_names = ['p1_vrf1', 'p2_vrf1'] ext_net.consumed_contract_names = ['c1_vrf1', 'c2_vrf1'] self.ns.connect_vrf(self.ctx, ext_net, vrf1) self._check_external_subnet_update("stage1") # Add & remove external-subnet self.ns.update_external_cidrs(self.ctx, ext_net, ['100.200.0.0/28', '50.50.0.0/16']) self._check_external_subnet_update("stage2") # Remove all external-subnets self.ns.update_external_cidrs(self.ctx, ext_net, []) self._check_external_subnet_update("stage3")
def test_vrf_contract_update(self): l3out = a_res.L3Outside(tenant_name='t1', name='o1', display_name='OUT') ext_net = a_res.ExternalNetwork( tenant_name='t1', l3out_name='o1', name='inet1', display_name='INET1') self.mgr.create(self.ctx, a_res.Tenant(name=self.vrf1_tenant_name)) self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) vrf1 = a_res.VRF(tenant_name=self.vrf1_tenant_name, name='vrf1', display_name='VRF1') self.mgr.create(self.ctx, vrf1) if self.fix_l3out_vrf: self.mgr.update(self.ctx, l3out, vrf_name=vrf1.name) ext_net.provided_contract_names = ['p1_vrf1', 'p2_vrf1'] ext_net.consumed_contract_names = ['c1_vrf1', 'c2_vrf1'] self.ns.connect_vrf(self.ctx, ext_net, vrf1) self._check_vrf_contract_update('stage1') # update contracts ext_net.provided_contract_names = ['arp', 'p2_vrf1'] ext_net.consumed_contract_names = ['arp', 'c2_vrf1'] self.ns.connect_vrf(self.ctx, ext_net, vrf1) self._check_vrf_contract_update('stage2') # unset contracts ext_net.provided_contract_names = [] ext_net.consumed_contract_names = [] self.ns.connect_vrf(self.ctx, ext_net, vrf1) self._check_vrf_contract_update('stage3')
def _get_bds_in_vrf_for_l3out(self, ctx, vrf, l3out): if vrf.tenant_name == 'common' and l3out.tenant_name == 'common': # BDs in all tenants are candidates - locate all BDs whose # vrf_name matches vrf.name, and exclude those that have a # local VRF aliasing the given VRF. all_bds = self.mgr.find(ctx, resource.BridgeDomain, vrf_name=vrf.name) bd_tenants = set([b.tenant_name for b in all_bds]) bd_tenants = [ t for t in bd_tenants if not self.mgr.get( ctx, resource.VRF(tenant_name=t, name=vrf.name)) ] return [b for b in all_bds if b.tenant_name in bd_tenants] elif (vrf.tenant_name == 'common' or vrf.tenant_name == l3out.tenant_name): # VRF and L3out are visible only to BDs in l3out's tenant return self.mgr.find(ctx, resource.BridgeDomain, tenant_name=l3out.tenant_name, vrf_name=vrf.name) # Other combinations of L3Out and VRF are not valid # configurations and can be excluded: # 1. L3out in common, VRF not in common: VRF is not # visible to L3out # 2. L3Out and VRF are in different non-common tenants: # VRF is not visible to L3out return []
def extend_address_scope_dict(self, session, base_model, result): LOG.debug("APIC AIM MD extending dict for address scope: %s", result) tenant_id = result['tenant_id'] tenant_aname = self.name_mapper.tenant(session, tenant_id) LOG.debug("Mapped tenant_id %(id)s to %(aname)s", { 'id': tenant_id, 'aname': tenant_aname }) id = result['id'] name = result['name'] aname = self.name_mapper.address_scope(session, id, name) LOG.debug( "Mapped address_scope_id %(id)s with name %(name)s to " "%(aname)s", { 'id': id, 'name': name, 'aname': aname }) vrf = aim_resource.VRF(tenant_name=tenant_aname, name=aname) aim_ctx = aim_context.AimContext(session) sync_state = cisco_apic.SYNC_SYNCED sync_state = self._merge_status(aim_ctx, sync_state, vrf) result[cisco_apic.DIST_NAMES] = {cisco_apic.VRF: vrf.dn} result[cisco_apic.SYNC_STATE] = sync_state
def _get_example_aim_vrf(cls, **kwargs): example = resource.VRF( tenant_name='test-tenant', name='test', policy_enforcement_pref=resource.VRF.POLICY_ENFORCED) example.__dict__.update(kwargs) return example
def delete_address_scope_precommit(self, context): LOG.debug("APIC AIM MD deleting address scope: %s", context.current) session = context._plugin_context.session tenant_id = context.current['tenant_id'] tenant_aname = self.name_mapper.tenant(session, tenant_id) LOG.debug("Mapped tenant_id %(id)s to %(aname)s", { 'id': tenant_id, 'aname': tenant_aname }) id = context.current['id'] name = context.current['name'] aname = self.name_mapper.address_scope(session, id, name) LOG.debug( "Mapped address_scope_id %(id)s with name %(name)s to " "%(aname)s", { 'id': id, 'name': name, 'aname': aname }) aim_ctx = aim_context.AimContext(session) vrf = aim_resource.VRF(tenant_name=tenant_aname, name=aname) self.aim.delete(aim_ctx, vrf) self.name_mapper.delete_apic_name(session, id)
def update_address_scope_precommit(self, context): LOG.debug("APIC AIM MD updating address_scope: %s", context.current) if context.current['name'] != context.original['name']: session = context._plugin_context.session tenant_id = context.current['tenant_id'] tenant_aname = self.name_mapper.tenant(session, tenant_id) LOG.debug("Mapped tenant_id %(id)s to %(aname)s", { 'id': tenant_id, 'aname': tenant_aname }) id = context.current['id'] name = context.current['name'] aname = self.name_mapper.address_scope(session, id, name) LOG.debug( "Mapped address_scope_id %(id)s with name %(name)s to " "%(aname)s", { 'id': id, 'name': name, 'aname': aname }) dname = aim_utils.sanitize_display_name(name) aim_ctx = aim_context.AimContext(session) vrf = aim_resource.VRF(tenant_name=tenant_aname, name=aname) vrf = self.aim.update(aim_ctx, vrf, display_name=dname)
def test_connect_vrf_change_disallowed(self): vrf = a_res.VRF(tenant_name='t1', name='vrf', display_name='VRF') l3out = a_res.L3Outside(tenant_name='t1', name='o1') ext_net = a_res.ExternalNetwork( tenant_name='t1', l3out_name='o1', name='inet1') self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.assertRaises(nat_strategy.L3OutsideVrfChangeDisallowed, self.ns.connect_vrf, self.ctx, ext_net, vrf) vrf = a_res.VRF(tenant_name='common', name='EXT-o1', display_name='VRF2') self.assertRaises(nat_strategy.L3OutsideVrfChangeDisallowed, self.ns.connect_vrf, self.ctx, ext_net, vrf)
def _get_nat_vrf(self, ctx, l3out): d_name = self._display_name(l3out) vrf_name = self._scope_name_if_common(l3out.tenant_name, 'EXT-%s' % l3out.name) return resource.VRF(tenant_name=l3out.tenant_name, name=vrf_name, display_name=self._scope_name_if_common( l3out.tenant_name, aim_utils.sanitize_display_name('EXT-%s' % d_name)))
def _get_unrouted_vrf(self, aim_ctx): tenant = self._get_common_tenant(aim_ctx) attrs = aim_resource.VRF(tenant_name=tenant.name, name=UNROUTED_VRF_NAME, display_name='Common Unrouted Context') vrf = self.aim.get(aim_ctx, attrs) if not vrf: LOG.info(_LI("Creating common unrouted VRF")) vrf = self.aim.create(aim_ctx, attrs) return vrf
def test_squash_operations_no_key(self): aim_converter = converter.AimToAciModelConverter() tn = a_res.Tenant(name='tn1', display_name='foo') bd = a_res.BridgeDomain(tenant_name='tn1', name='bd1', display_name='bar') vrf = a_res.VRF(tenant_name='tn1', name='vrf1', display_name='pippo') self.manager.push_aim_resources({'create': [tn, bd]}) self.manager.push_aim_resources( {'delete': aim_converter.convert([vrf])}) self.assertEqual(2, len(self.manager.object_backlog.queue))
def _get_vrf(self, vrf_name, tenant_name, should_exist=True): session = db_api.get_session() aim_ctx = aim_context.AimContext(session) vrf = aim_resource.VRF(tenant_name=tenant_name, name=vrf_name) vrf = self.aim_mgr.get(aim_ctx, vrf) if should_exist: self.assertIsNotNone(vrf) else: self.assertIsNone(vrf) return vrf
def read_vrfs(self, ctx, external_network): l3out = self.mgr.get(ctx, self._ext_net_to_l3out(external_network)) result = [] for c in self.db.get_clones(ctx, l3out): l3c = self.mgr.get(ctx, resource.L3Outside(tenant_name=c[0], name=c[1])) if l3c: vrf = self.mgr.get( ctx, resource.VRF(tenant_name=l3c.tenant_name, name=l3c.vrf_name)) if vrf: result.append(vrf) return result
def _get_l3out_objects(self, l3out_name=None, l3out_display_name=None, nat_vrf_name=None, vmm_domains=None, phys_domains=None): name = 'EXT-%s' % (l3out_name or 'o1') d_name = 'EXT-%s' % (l3out_display_name or 'OUT') nat_vrf = a_res.VRF(tenant_name='t1', name=name, display_name=d_name) if vmm_domains is not None: vmm_doms = vmm_domains else: vmm_doms = self.vmm_domains if phys_domains is not None: phys_doms = phys_domains else: phys_doms = self.phys_domains return ([ a_res.Filter(tenant_name='t1', name=name, display_name=d_name), a_res.FilterEntry(tenant_name='t1', filter_name=name, name='Any', display_name='Any'), a_res.Contract(tenant_name='t1', name=name, display_name=d_name), a_res.ContractSubject(tenant_name='t1', contract_name=name, name='Allow', display_name='Allow', bi_filters=[name]), a_res.BridgeDomain(tenant_name='t1', name=name, display_name=d_name, vrf_name=nat_vrf_name or name, limit_ip_learn_to_subnets=True, l3out_names=[l3out_name or 'o1']), a_res.ApplicationProfile(tenant_name='t1', name='myapp', display_name='myapp'), a_res.EndpointGroup(tenant_name='t1', app_profile_name='myapp', name=name, display_name=d_name, bd_name=name, provided_contract_names=[name], consumed_contract_names=[name], # NOTE(ivar): Need to keep both VMM # representations since a GET on the EPG # will also return the domain name list # for backward compatibility openstack_vmm_domain_names=[dom['name'] for dom in vmm_doms if dom['type'] == 'OpenStack'], physical_domain_names=[dom['name'] for dom in phys_doms], vmm_domains=vmm_doms, physical_domains=phys_doms)] + ([nat_vrf] if nat_vrf_name is None else []))
def test_connect_vrf_multiple(self): l3out1 = a_res.L3Outside(tenant_name='t1', name='o1', display_name='OUT') ext_net1 = a_res.ExternalNetwork( tenant_name='t1', l3out_name='o1', name='inet1', display_name='INET1') self.mgr.create(self.ctx, a_res.Tenant(name=self.vrf1_tenant_name)) self.ns.create_l3outside(self.ctx, l3out1) self.ns.create_external_network(self.ctx, ext_net1) self.ns.update_external_cidrs(self. ctx, ext_net1, ['20.20.20.0/24', '50.50.0.0/16']) l3out2 = a_res.L3Outside(tenant_name='t2', name='o2', display_name='OUT2') ext_net2 = a_res.ExternalNetwork( tenant_name='t2', l3out_name='o2', name='inet2', display_name='INET2') self.ns.create_l3outside(self.ctx, l3out2) self.ns.create_external_network(self.ctx, ext_net2) self.ns.update_external_cidrs(self. ctx, ext_net2, ['0.0.0.0/0']) vrf1 = a_res.VRF(tenant_name=self.vrf1_tenant_name, name='vrf1', display_name='VRF1') bd1 = a_res.BridgeDomain(tenant_name=self.vrf1_tenant_name, name='bd1', limit_ip_learn_to_subnets=True, vrf_name='vrf1') self.mgr.create(self.ctx, vrf1) self.mgr.create(self.ctx, bd1) if self.fix_l3out_vrf: self.mgr.update(self.ctx, l3out1, vrf_name=vrf1.name) self.mgr.update(self.ctx, l3out2, vrf_name=vrf1.name) ext_net1.provided_contract_names = ['p1_vrf1', 'p2_vrf1'] ext_net1.consumed_contract_names = ['c1_vrf1', 'c2_vrf1'] ext_net2.provided_contract_names = ['p3_vrf1', 'p4_vrf1'] ext_net2.consumed_contract_names = ['c3_vrf1', 'c4_vrf1'] self.ns.connect_vrf(self.ctx, ext_net1, vrf1) self.ns.connect_vrf(self.ctx, ext_net2, vrf1) self._check_connect_vrf_multiple('stage1') self.ns.disconnect_vrf(self.ctx, ext_net1, vrf1) self._check_connect_vrf_multiple('stage2') self.ns.disconnect_vrf(self.ctx, ext_net2, vrf1) self._check_connect_vrf_multiple('stage3')
def test_connect_vrf_wrong_tenant(self): vrf = a_res.VRF(tenant_name='dept1', name='vrf', display_name='VRF') l3out = a_res.L3Outside(tenant_name='t1', name='o1') ext_net = a_res.ExternalNetwork( tenant_name='t1', l3out_name='o1', name='inet1') self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.assertRaises(nat_strategy.VrfNotVisibleFromExternalNetwork, self.ns.connect_vrf, self.ctx, ext_net, vrf) l3out.tenant_name = 'common' ext_net.tenant_name = 'common' self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.assertRaises(nat_strategy.VrfNotVisibleFromExternalNetwork, self.ns.connect_vrf, self.ctx, ext_net, vrf)
def test_l3outside_pre(self): self.mgr.create(self.ctx, a_res.Tenant(name='t1')) vrf = a_res.VRF(tenant_name='t1', name='ctx1', monitored=True) self.mgr.create(self.ctx, vrf) l3out = a_res.L3Outside(tenant_name='t1', name='o1', display_name='OUT', vrf_name='ctx1', monitored=True) self.mgr.create(self.ctx, l3out) self.ns.create_l3outside(self.ctx, l3out) other_objs = self._get_l3out_objects(nat_vrf_name='ctx1') self._verify(present=[l3out, vrf] + other_objs) get_objs = self.ns.get_l3outside_resources(self.ctx, l3out) self._assert_res_list_eq(other_objs + [l3out, vrf], get_objs) self.ns.delete_l3outside(self.ctx, l3out) self._verify(present=[l3out, vrf], absent=other_objs) get_objs = self.ns.get_l3outside_resources(self.ctx, l3out) self.assertEqual([l3out, vrf], get_objs)
def create_address_scope_precommit(self, context): LOG.debug("APIC AIM MD creating address scope: %s", context.current) session = context._plugin_context.session tenant_id = context.current['tenant_id'] tenant_aname = self.name_mapper.tenant(session, tenant_id) LOG.debug("Mapped tenant_id %(id)s to %(aname)s", { 'id': tenant_id, 'aname': tenant_aname }) id = context.current['id'] name = context.current['name'] aname = self.name_mapper.address_scope(session, id, name) LOG.debug( "Mapped address_scope_id %(id)s with name %(name)s to " "%(aname)s", { 'id': id, 'name': name, 'aname': aname }) dname = aim_utils.sanitize_display_name(name) aim_ctx = aim_context.AimContext(session) vrf = aim_resource.VRF(tenant_name=tenant_aname, name=aname, display_name=dname) self.aim.create(aim_ctx, vrf) # ML2Plus does not extend address scope dict after precommit. sync_state = cisco_apic.SYNC_SYNCED sync_state = self._merge_status(aim_ctx, sync_state, vrf) context.current[cisco_apic.DIST_NAMES] = {cisco_apic.VRF: vrf.dn} context.current[cisco_apic.SYNC_STATE] = sync_state
def _get_address_scope_vrf(self, mapping): return aim_resource.VRF( tenant_name=mapping.vrf_tenant_name, name=mapping.vrf_name)
def _get_network_vrf(self, mapping): return aim_resource.VRF( tenant_name=mapping.vrf_tenant_name, name=mapping.vrf_name)
def test_track_universe_actions(self): # When AIM is the current state, created objects are in ACI form, # deleted objects are in AIM form reset_limit = self.universe.reset_retry_limit purge_limit = self.universe.purge_retry_limit old_backoff_time = self.universe.max_backoff_time self.assertEqual(2 * self.universe.max_create_retry, reset_limit) self.assertEqual(2 * reset_limit, purge_limit) self.assertTrue(self.universe.max_create_retry > 0) self.universe.max_backoff_time = 0 actions = { 'create': [ resource.BridgeDomain(tenant_name='t1', name='b'), resource.BridgeDomain(tenant_name='t1', name='b'), ], 'delete': [] } reset, purge, skip = self.universe._track_universe_actions( actions, 'tn-t1') self.assertEqual(False, reset) self.assertEqual([], purge) # 1 root self.assertEqual(1, len(self.universe._sync_log['tn-t1']['create'])) actions = { 'create': [ resource.VRF(tenant_name='t2', name='c'), ], 'delete': [] } reset, purge, skip = self.universe._track_universe_actions( actions, 'tn-t2') # 2 roots self.assertEqual(1, len(self.universe._sync_log['tn-t2']['create'])) # BD counted only once self.assertEqual( 0, self.universe._sync_log['tn-t1']['create'].values()[0]['retries']) ctrl = resource.VMMController(domain_type='OpenStack', domain_name='os', name='ctrl') actions = { 'create': [], 'delete': [self._get_example_aci_object('vmmCtrlrP', ctrl.dn)] } reset, purge, skip = self.universe._track_universe_actions( actions, 'vmmp-OpenStack') self.assertEqual(False, reset) self.assertEqual([], purge) reset, purge, skip = self.universe._track_universe_actions( { 'create': [], 'delete': [] }, 'tn-t2') # Tenant t2 is off the hook self.assertTrue( 'tn-t2' not in self.universe._sync_log['tn-t2']['create']) self.assertTrue( 'tn-t2' not in self.universe._sync_log['tn-t2']['delete']) actions = { 'create': [ resource.BridgeDomain(tenant_name='t1', name='b'), ], 'delete': [] } reset, purge, skip = self.universe._track_universe_actions( actions, 'tn-t1') # BD count increased self.assertEqual( 1, self.universe._sync_log['tn-t1']['create'].values()[0]['retries']) self.assertEqual( 0, self.universe._sync_log[ctrl.root]['delete'].values()[0] ['retries']) # Retry the above until t1 needs reset for _ in range(reset_limit - 1): reset, purge, skip = self.universe._track_universe_actions( actions, 'tn-t1') self.assertEqual(False, reset) self.assertEqual([], purge) reset, purge, skip = self.universe._track_universe_actions( actions, 'tn-t1') self.assertEqual(True, reset) self.assertEqual([], purge) # with the next run, reset is not required for t1 anymore, but pure # countdown starts reset, purge, skip = self.universe._track_universe_actions( actions, 'tn-t1') self.assertEqual([], purge) for _ in range(purge_limit - reset_limit - 2): reset, purge, skip = self.universe._track_universe_actions( actions, 'tn-t1') self.assertEqual(False, reset) self.assertEqual([], purge) reset, purge, skip = self.universe._track_universe_actions( actions, 'tn-t1') self.assertEqual(False, reset) self.assertEqual(1, len(purge)) self.assertEqual('create', purge[0][0]) self.assertEqual('uni/tn-t1/BD-b', purge[0][1].dn) self.universe.max_backoff_time = old_backoff_time
def test_bd_l3out_vrf_in_common(self): self.mgr.create(self.ctx, a_res.Tenant(name='common')) self.mgr.create(self.ctx, a_res.Tenant(name='dept1')) self.mgr.create(self.ctx, a_res.Tenant(name='dept2')) self.mgr.create(self.ctx, a_res.Tenant(name='dept3')) vrf = a_res.VRF(tenant_name='common', name='default') bd1_dept1 = a_res.BridgeDomain(tenant_name='dept1', name='bd1', limit_ip_learn_to_subnets=True, vrf_name='default') bd2_dept1 = a_res.BridgeDomain(tenant_name='dept1', name='bd2', limit_ip_learn_to_subnets=True, vrf_name='default') bd1_dept2 = a_res.BridgeDomain(tenant_name='dept2', name='bd1', limit_ip_learn_to_subnets=True, vrf_name='default') vrf_dept2 = a_res.VRF(tenant_name='dept2', name='default') bd1_dept3 = a_res.BridgeDomain(tenant_name='dept3', name='bd1', limit_ip_learn_to_subnets=True, vrf_name='default') bd2_dept3 = a_res.BridgeDomain(tenant_name='dept3', name='bd2', limit_ip_learn_to_subnets=True, vrf_name='foo') for o in [vrf, bd1_dept1, bd2_dept1, bd1_dept2, vrf_dept2, bd1_dept3, bd2_dept3]: self.mgr.create(self.ctx, o) # test with 'common' l3out l3out = a_res.L3Outside(tenant_name='common', name='o1') ext_net = a_res.ExternalNetwork( tenant_name='common', l3out_name='o1', name='inet1') self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.mgr.update(self.ctx, l3out, vrf_name='default') self._verify(present=[bd1_dept1, bd2_dept1, bd1_dept2, bd1_dept3, bd2_dept3]) self.ns.connect_vrf(self.ctx, ext_net, vrf) bd1_dept1.l3out_names = ['o1'] bd2_dept1.l3out_names = ['o1'] bd1_dept3.l3out_names = ['o1'] self._verify(present=[bd1_dept1, bd2_dept1, bd1_dept2, bd1_dept3, bd2_dept3]) self.ns.disconnect_vrf(self.ctx, ext_net, vrf) bd1_dept1.l3out_names = [] bd2_dept1.l3out_names = [] bd1_dept3.l3out_names = [] self._verify(present=[bd1_dept1, bd2_dept1, bd1_dept2, bd1_dept3, bd2_dept3]) # test with l3out in specific tenant l3out.tenant_name = 'dept1' ext_net.tenant_name = 'dept1' self.ns.create_l3outside(self.ctx, l3out) self.ns.create_external_network(self.ctx, ext_net) self.mgr.update(self.ctx, l3out, vrf_name='default') self.ns.connect_vrf(self.ctx, ext_net, vrf) bd1_dept1.l3out_names = ['o1'] bd2_dept1.l3out_names = ['o1'] self._verify(present=[bd1_dept1, bd2_dept1, bd1_dept2, bd1_dept3, bd2_dept3]) self.ns.disconnect_vrf(self.ctx, ext_net, vrf) bd1_dept1.l3out_names = [] bd2_dept1.l3out_names = [] self._verify(present=[bd1_dept1, bd2_dept1, bd1_dept2, bd1_dept3, bd2_dept3])