def ensure_external_network_configured(self, network_id, address_scope_name, delete=False): tenant = self.get_tenant(network_id) scope_config = self._get_address_scope_config(address_scope_name) l3_outs = scope_config['l3_outs'] vrf_name = scope_config['vrf'] # prepare bridge domain bd = fv.BD(tenant, network_id) # We don't need the out profiles for now # out_profile = RsBDToProfile(bd,tnL3extOutName=l3_out_name) vrf = fv.RsCtx(bd, vrf_name, tnFvCtxName=vrf_name) bd_outs = [] for l3_out in l3_outs.split(','): out = self._find_l3_out(network_id, l3_out) if out: LOG.info('Configure L3 out for network, {}'.format(out.name)) bd_out = fv.RsBDToOut(bd, out.name) if delete: bd_out.delete() bd_outs.append(bd_out) else: LOG.error( 'Cannot configure L3 out for BD, {} not found in ACI configuration' .format(l3_out)) #if delete: # vrf.delete() #TODO: the RsCtx object cannot be deleted, need to find out how to clear on the BD # Prepare EPG app = fv.Ap(tenant, self.apic_application_profile) epg = fv.AEPg(app, network_id) epg_contracts = [] contract_def = ast.literal_eval(scope_config['contracts']) for type, contracts in contract_def.iteritems(): if type == 'consumed': for contract in contracts: contract = fv.RsCons(epg, contract) if delete: contract.delete() epg_contracts.append(contract) elif type == 'provided': for contract in contracts: contract = fv.RsProv(epg, contract) if delete: contract.delete() epg_contracts.append(contract) self.apic.commit([vrf] + bd_outs + epg_contracts)
def delete_domain_and_epg(self, network_id, transaction=None): tenant = self.get_tenant(network_id) bd = fv.BD(tenant, network_id) bd.delete() app = fv.Ap(tenant, self.apic_application_profile) epg = fv.AEPg(app, network_id) epg.delete() self.apic.commit(epg) self.apic.commit(bd) if (len(self.get_tenant_bridge_domains(tenant)) == 0 and len(self.get_tenant_epgs(tenant)) == 0): tenant.delete() self.apic.commit(tenant)
def ensure_domain_and_epg(self, network_id): tenant = self.get_or_create_tenant(network_id) bd = fv.BD(tenant, network_id, arpFlood=1, unkMacUcastAct=0) app = fv.Ap(tenant, self.apic_application_profile) epg = fv.AEPg(app, network_id) # Add EPG to BD domain rsbd = fv.RsBd(epg, network_id, tnFvBDName=bd.name) # We have to make seperate config requests because cobra can't # handle MOs with different root contexts self.apic.commit(bd) self.apic.commit([app, epg, rsbd]) return network_id
def ensure_static_bindings_configured(self, network_id, host_config, encap=None, delete=False, clear_phys_dom=False): tenant = self.get_tenant(network_id) if tenant: LOG.info("Using host config for bindings {}".format(host_config)) bindings = host_config['bindings'] segment_type = host_config['segment_type'] LOG.info("Preparing static bindings {} in tenant {}".format( bindings, tenant.name)) encap = self.get_static_binding_encap(segment_type, encap) app = fv.Ap(tenant, self.apic_application_profile) epg = fv.AEPg(app, network_id) ports = [] for binding in bindings: binding_config = binding.split("/") pdn = None if binding_config[0] == 'port': pdn = PORT_DN_PATH % (binding_config[1], binding_config[2], binding_config[3]) elif binding_config[0] == 'node': pdn = NODE_DN_PATH % (binding_config[1], binding_config[1], binding_config[2], binding_config[3]) elif binding_config[0] == 'dpc': pdn = DPCPORT_DN_PATH % (binding_config[1], binding_config[2]) elif binding_config[0] == 'vpc': pdn = VPCPORT_DN_PATH % (binding_config[1], binding_config[2]) LOG.info("Preparing static binding {}".format(pdn)) port = fv.RsPathAtt(epg, pdn, encap=encap) if delete: port.delete() ports.append(port) self.apic.commit(ports) # Associate to Physical Domain phys_dom = phys.DomP('uni', host_config['physical_domain']) rs_dom_att = fv.RsDomAtt(epg, phys_dom.dn) if delete and clear_phys_dom: rs_dom_att.delete() self.apic.commit(rs_dom_att) else: LOG.error( "Network {} does not appear to be avilable in ACI, expected in tenant {}" .format(network_id, self.tenant_manager.get_tenant_name(network_id)))
def create_overlay_policy(apic=None, policy=None): mo = aciPol.Uni('') for name, data in policy.items(): # Create tenant behind the scenes tenantName = '{0}_Tenant'.format(name) fvTenant = aciFv.Tenant(mo, name=tenantName) # Create the required VRF as well vrfName = '{0}_VRF'.format(name) fvCtx = aciFv.Ctx(fvTenant, name=vrfName) # Create BD for vlan in data['vlans']: vlanName = 'VLAN_{0}'.format(vlan['id']) if vlan['optimized']: fvBD = aciFv.BD(fvTenant, name=vlanName, OptimizeWanBandwidth='no', arpFlood='no', epClear='no', hostBasedRouting='yes', intersiteBumTrafficAllow='no', intersiteL2Stretch='no', ipLearning='yes', limitIpLearnToSubnets='yes', llAddr='::', mac='00:22:BD:F8:19:FF', mcastAllow='no', multiDstPktAct='encap-flood', type='regular', unicastRoute='yes', unkMacUcastAct='proxy', unkMcastAct='opt-flood', v6unkMcastAct='flood', vmac='not-applicable') else: fvBD = aciFv.BD(fvTenant, name=vlanName, OptimizeWanBandwidth='no', arpFlood='yes', epClear='no', hostBasedRouting='no', intersiteBumTrafficAllow='no', intersiteL2Stretch='no', ipLearning='yes', limitIpLearnToSubnets='yes', llAddr='::', mac='00:22:BD:F8:19:FF', mcastAllow='no', multiDstPktAct='bd-flood', type='regular', unicastRoute='yes', unkMacUcastAct='flood', unkMcastAct='flood', v6unkMcastAct='flood', vmac='not-applicable') aciFv.Subnet(fvBD, ip=vlan['subnet'], preferred='no', scope='private', virtual='no') aciFv.RsCtx(fvBD, tnFvCtxName='{0}_VRF'.format(name)) fvAp = aciFv.Ap(fvTenant, name='{0}_AppProf'.format(vlanName)) aciFv.RsApMonPol(fvAp, tnMonEPGPolName='default') # REMAINING TASKS # Create EPGs # aciFv.EPg(fvAp, name, matchT, etc...) # Contracts return mo