def lookupByClass(self, classNames, parentDn=None, propFilter=None): """Lookup MO's by class A short-form managed object (MO) query by class. Args: classNames (str or list): The class name list of class names. If parentDn is set, the classNames are used as a filter in a subtree query for the parentDn parentDn (cobra.mit.naming.Dn or str): The distinguished name of the parent object as a :class:`cobra.mit.naming.Dn` or string. propFilter (str): A property filter expression Returns: list: A list of the managed objects found in the query. """ if parentDn: dnQuery = DnQuery(parentDn) dnQuery.classFilter = classNames dnQuery.queryTarget = 'subtree' if propFilter: dnQuery.propFilter = propFilter mos = self.query(dnQuery) else: classQuery = ClassQuery(classNames) if propFilter: classQuery.propFilter = propFilter mos = self.query(classQuery) return mos
def test_ClassQuery_options(self): cid = '1234567890' expectedOptions = '' aq = ClassQuery('fvTenant') aq.id = cid expectedOptions += '_dc=' + cid assert aq.options == expectedOptions
def create_vpc_if_policy_group(self, name, aep_name): """ Creates the virtual port channel interface policy groups :param name: :param aep_name: attachable entity profile name. If it does not exists the system will create a new one :return: """ policy_group_mo = AccBndlGrp('uni/infra/funcprof/', name, lagT='node') self.commit(policy_group_mo) # if attachable entity profile does not exists, creates a new one class_query = ClassQuery('infraAttEntityP') class_query.propFilter = 'eq(infraAttEntityP.name, "' + AEP_PREFIX + aep_name + '")' pd_list = self.moDir.query(class_query) if len(pd_list) == 0: vlan_pool_mo = self.create_vlan_pool(VLAN_POOL_PREFIX + aep_name, 'static') DomP_mo = self.create_physical_domain(PD_PREFIX + aep_name, str(vlan_pool_mo.dn)) AttEntityP_mo = self.create_attachable_entity_profile(AEP_PREFIX + aep_name, str(DomP_mo.dn)) else: AttEntityP_mo = pd_list[0] # Assign attached entity profile self.commit( RsAttEntP(policy_group_mo.dn, tDn=str(AttEntityP_mo.dn)) ) # Assign interface policies. For non-defaults, check if is already created. If not, the system will create them IfPolmo = self.moDir.lookupByDn('uni/infra/cdpIfP-CDP-ON') if not IfPolmo: IfPolmo = IfPol('uni/infra','CDP-ON',adminSt='enabled') self.commit(IfPolmo) self.commit( RsCdpIfPol(policy_group_mo.dn, tnCdpIfPolName=IfPolmo.name) ) self.commit( RsHIfPol(policy_group_mo.dn, tnFabricHIfPolName='default') ) self.commit( RsL2IfPol(policy_group_mo.dn, tnL2IfPolName='default') ) LagPolmo = self.moDir.lookupByDn('uni/infra/lacplagp-LACP') if not LagPolmo: LagPolmo = LagPol('uni/infra', 'LACP', mode='active') self.commit(LagPolmo) self.commit( RsLacpPol(policy_group_mo.dn, tnLacpLagPolName=LagPolmo.name) ) self.commit( RsLldpIfPol(policy_group_mo.dn, tnLldpIfPolName='default') ) self.commit( RsMcpIfPol(policy_group_mo.dn, tnMcpIfPolName='default') ) self.commit( RsMonIfInfraPol(policy_group_mo.dn, tnMonInfraPolName='default') ) self.commit( RsStormctrlIfPol(policy_group_mo.dn, tnStormctrlIfPolName='default') ) self.commit( RsStpIfPol(policy_group_mo.dn, tnStpIfPolName='default') ) return policy_group_mo
def get_fabric_switches(self): """ Returns all switches within the fabric :return: """ # Leafs class_query = ClassQuery('fabricNode') class_query.propFilter = 'eq(fabricNode.role, "leaf")' leafs = self.moDir.query(class_query) # Two lists are created, one for the distinguished names and other for the relative names dns = [] rns = [] for leaf in leafs: dns.append(str(leaf.dn)) rns.append(str(leaf.rn)) # Spines class_query = ClassQuery('fabricNode') class_query.propFilter = 'eq(fabricNode.role, "spine")' spines = self.moDir.query(class_query) for spine in spines: dns.append(str(spine.dn)) rns.append(str(spine.rn)) # Need to be human sorted (e.g 1,2,3,11 and not 1,11,2,3) dns.sort(key=natural_keys) rns.sort(key=natural_keys) return dns, rns
def create_if_policy_group(self, name, aep_name): """ Creates an interface policy group and associates it to an attachable entity profile :param name: interface policy group name :param aep_name: attachable entity profile. If does not exist the system will create it :return: """ # Creates policy group if_policy_group_mo = AccPortGrp('uni/infra/funcprof/', name) self.commit(if_policy_group_mo) # Query the AEP class_query = ClassQuery('infraAttEntityP') class_query.propFilter = 'eq(infraAttEntityP.name, "' + AEP_PREFIX + aep_name + '")' pd_list = self.moDir.query(class_query) if len(pd_list) == 0: # if attachable entity profile does not exists, creates a new one vlan_pool_mo = self.create_vlan_pool('vlan-pool-' + aep_name, 'static') DomP_mo = self.create_physical_domain('pd-' + aep_name, str(vlan_pool_mo.dn)) AttEntityP_mo = self.create_attachable_entity_profile('aep-' + aep_name, str(DomP_mo.dn)) else: AttEntityP_mo = pd_list[0] # Assign attached entity profile to the policy group self.commit( RsAttEntP(if_policy_group_mo.dn, tDn=str(AttEntityP_mo.dn)) ) # Assign interface policies. For non-defaults, check if is already created. If not, the system will create them IfPolmo = self.moDir.lookupByDn('uni/infra/cdpIfP-CDP-ON') if not IfPolmo: IfPolmo = IfPol('uni/infra','CDP-ON',adminSt='enabled') self.commit(IfPolmo) self.commit( RsCdpIfPol(if_policy_group_mo.dn, tnCdpIfPolName=IfPolmo.name) ) HIfPolmo = self.moDir.lookupByDn('uni/infra/hintfpol-1GB') if not HIfPolmo: HIfPolmo = HIfPol('uni/infra', '1GB', speed='1G') self.commit(HIfPolmo) self.commit( RsHIfPol(if_policy_group_mo.dn, tnFabricHIfPolName=HIfPolmo.name) ) self.commit( RsL2IfPol(if_policy_group_mo.dn, tnL2IfPolName='default') ) self.commit( RsLldpIfPol(if_policy_group_mo.dn, tnLldpIfPolName='default') ) self.commit( RsMcpIfPol(if_policy_group_mo.dn, tnMcpIfPolName='default') ) self.commit( RsMonIfInfraPol(if_policy_group_mo.dn, tnMonInfraPolName='default') ) self.commit( RsStormctrlIfPol(if_policy_group_mo.dn, tnStormctrlIfPolName='default') ) self.commit( RsStpIfPol(if_policy_group_mo.dn, tnStpIfPolName='default') ) return if_policy_group_mo
def get_faults_history(self, epg_dn): """ Retrieves a historic list of all faults associated to an EPG :param epg_dn: :return: """ class_query = ClassQuery('faultRecord') class_query.propFilter = 'eq(faultRecord.affected, "' + epg_dn + '")' return self.moDir.query(class_query)
def test_ClassQuery_getUrl(self, sessionUrl, dc, requestType): session = LoginSession(sessionUrl, 'admin', 'password', requestFormat=requestType) klass = 'fvTenant' cq = ClassQuery(klass) expected = sessionUrl + '/api/class/' + klass + '.' + requestType cq.id = dc expected += '?_dc=' + dc assert cq.getUrl(session) == expected
def get_mo_for_interface(nodeid, portid): cq = ClassQuery('fabricPathEpCont') cq.propFilter = 'eq(fabricPathEpCont.nodeId, "{0}")'.format(nodeid) cq.subtree = 'children' cq.subtreeClassFilter = 'fabricPathEp' req = moDir.query(cq) for key in req[0].children: # children method applied to the query result will return a list of child objects # req[0] is fabricPathEpCont (leaf), children are fabricPathEp (ports) if key.name == portid: return format(key.dn)
def delete_group(self, group_o): """ Removes a group/tenant from the fabric :param group_o: :return: """ class_query = ClassQuery('fvTenant') class_query.propFilter = 'eq(fvTenant.name, "' + group_o.name + '")' tenant_list = self.moDir.query(class_query) if len(tenant_list) > 0: tenant_list[0].delete() self.commit(tenant_list[0])
def get_full_aci_config(apic, user, password, outfile): try: url = "https://" + apic ls = cobra.mit.session.LoginSession(url, "apic:ACS\\" + user, password, secure=False, timeout=30) md = cobra.mit.access.MoDirectory(ls) md.login() #Get tenant config cq = ClassQuery('fvTenant') cq.subtree = 'full' cq.propInclude= 'config-only' tenant_config = md.query(cq) #Infra config dq = DnQuery('uni/infra') dq.subtree = 'full' dq.propInclude = 'config-only' infra_config = md.query(dq) #Fabric config dq = DnQuery('uni/fabric') dq.subtree = 'full' dq.propInclude = 'config-only' fabric_config = md.query(dq) file = open(outfile, 'w+') file.write("# " + apic + " #") file.write("\n###########" + '\n') file.write("# TENANTS ") file.write("\n###########" + '\n') for tenant in tenant_config: file.write(toJSONStr(tenant, prettyPrint=True)) file.write("\n###########" + '\n') file.write("# Infra ") file.write("\n###########" + '\n') for infra in infra_config: file.write(toJSONStr(infra, prettyPrint=True)) file.write("\n###########" + '\n') file.write("# Fabric ") file.write("\n###########" + '\n') for fabric in fabric_config: file.write(toJSONStr(fabric, prettyPrint=True)) file.close() except: print "Error in get_full_aci_config() for %s: %s" % (apic, sys.exc_info()[0])
def get_all_bds(self): """ Returns a list of all bridge domains in the fabric :return: """ class_query = ClassQuery('fvBD') bd_list = self.moDir.query(class_query) return bd_list
def get_all_tenants(self): """ Searches all tenants within apic :return: """ class_query = ClassQuery('fvTenant') tn_list = self.moDir.query(class_query) return tn_list
def remove_vlan(self, vlan_number, vlan_pool_name): """ Removes a VLAN from a vlan pool :param vlan_number: :param vlan_pool_name: :return: """ class_query = ClassQuery('fvnsVlanInstP') class_query.propFilter = 'eq(fvnsVlanInstP.name, "' + VLAN_POOL_PREFIX + vlan_pool_name + '")' vp_list = self.moDir.query(class_query) # Check if vlan pool exists if len(vp_list) == 0: vlan_pool_children = self.query_child_objects(str(vp_list[0].dn)) for vlan in vlan_pool_children: if vlan.to == 'vlan-' + str(vlan_number): vlan.delete() self.commit(vlan) break
def home(): #apicUrl = 'https://10.29.198.36' # loginSession = LoginSession(apicUrl, 'admin', 'ins3965!') #loginSession = createCertSession() loginSession = cobra.mit.session.LoginSession('https://10.29.198.36', 'admin', 'ins3965!') moDir = MoDirectory(loginSession) moDir.login() tableList = [] row = ('TN', 'AP/L2OUT', 'EPG/InstP', 'CEP', 'IP', 'Type', 'PATH', 'PORT', 'POD', 'ENCAP', 'BD:CTX') tableList.append(row) q = ClassQuery('fvCEp') q.subtree = 'children' tenantMo = moDir.query(q) for mo in tenantMo: for child in mo.rscEpToPathEp: #print child.dn ip = mo.ip tn, ap, epg, cep, varPod, varStrPath, varStrPort = tDnToPath( child.dn) if 'protpaths' in child.tDn: portType = 'vPC' elif 'paths' in child.tDn and 'eth' in child.tDn: portType = '-' else: portType = 'PC' encap = (mo.encap).split('-')[1] #if args.macSearch: bd,ctx = getAncestorDnStrFromDnString(md, str(mo.dn), 1) #else: bd='-'; ctx='-' bd = '-' ctx = '-' row = (tn, ap, epg, cep, mo.ip, portType, varStrPath, varStrPort, varPod, encap, '%s:%s' % (bd, ctx)) tableList.append(row) moDir.logout() return render_template('home.html', table=tableList)
def get_leaf_prof_dn_by_nodeid(leaf_id): cq = ClassQuery('infraNodeBlk') result = moDir.query(cq) my_results = [] for key in result: if int(key.from_) <= int(leaf_id) <= int(key.to_): child = Dn.fromString(format(key.dn)) my_results.append(format(child.getAncestor(2))) return my_results
def get_int_prof_by_leaf_prof(parm): cq = ClassQuery('infraRsAccPortP') my_result = [] result = moDir.query(cq) for key in result: # temp = format(key.dn) # this is a string child = Dn.fromString(format(key.dn)) parent = format(child.getAncestor(1)) if parent == parm: my_result.append(key.tDn) return my_result
def add_vlan(self, vlan_number, vlan_pool_name): """ Add a vlan to a vlan pool. :param vlan_number: :param vlan_pool_name: Vlan pool name. If it does not exist the system will create one. :return: """ class_query = ClassQuery('fvnsVlanInstP') class_query.propFilter = 'eq(fvnsVlanInstP.name, "' + VLAN_POOL_PREFIX + vlan_pool_name + '")' vp_list = self.moDir.query(class_query) # If the vlan pool does not exists, create it with the physical domain and the attachable entity profile if len(vp_list) == 0: VlanInstP_mo = self.create_vlan_pool(VLAN_POOL_PREFIX + vlan_pool_name, 'static') DomP_mo = self.create_physical_domain(PD_PREFIX + vlan_pool_name, str(VlanInstP_mo.dn)) self.create_attachable_entity_profile(AEP_PREFIX + vlan_pool_name, str(DomP_mo.dn)) else: VlanInstP_mo = vp_list[0] encap_mo = EncapBlk(str(VlanInstP_mo.dn), VLAN_PREFIX + str(vlan_number), VLAN_PREFIX + str(vlan_number), allocMode='static') self.commit(encap_mo)
def associate_epg_physical_domain(self, epg_dn, physical_domain_name): """ Associate a physical domain to an end point group :param epg_dn: :param physical_domain_name: :return: """ # Query the physical domain according to an specific name class_query = ClassQuery('physDomP') class_query.propFilter = 'eq(physDomP.name, "' + PD_PREFIX + physical_domain_name + '")' pd_list = self.moDir.query(class_query) # If the physical domain does not exists, create it with the vlan pool and the attachable entity profile if len(pd_list) == 0: vlan_pool_mo = self.create_vlan_pool(VLAN_POOL_PREFIX + physical_domain_name, 'static') DomP_mo = self.create_physical_domain(PD_PREFIX + physical_domain_name, str(vlan_pool_mo.dn)) self.create_attachable_entity_profile(AEP_PREFIX + physical_domain_name, str(DomP_mo.dn)) else: DomP_mo = pd_list[0] # Creates and commits the association rsdom = RsDomAtt(epg_dn, str(DomP_mo.dn)) self.commit(rsdom)
def get_leafs(self): """ Returns the leafs that are registered in the APIC :return: """ # Query leafs from the fabric class_query = ClassQuery('fabricNode') class_query.propFilter = 'eq(fabricNode.role, "leaf")' leafs = self.moDir.query(class_query) # creates two lists that will include the distinguished names and the relative names result = [] dns = [] rns = [] for leaf in leafs: dns.append(str(leaf.dn)) rns.append(str(leaf.rn)) # The following lines human sort the lists (e.g. 1,2,3,11 and not 1,11,2,3) dns.sort(key=natural_keys) rns.sort(key=natural_keys) result.append(dns) result.append(rns) # The result is a list with two lists inside. One list has distinguished names and the other the relative names return result
def delete_single_access(self, epg_dn, port_dn, if_policy_group_name, switch_p_name): """ Removes the static binding between a port and an end point group. If no other EPGs are using this port the system will remove the switch profiles, interface profiles and interface policy groups associated to the port :param epg_dn: :param port_dn: :param if_policy_group_name: :param switch_p_name: :return: """ fabric_path_dn = port_dn.replace('node', 'paths').replace('sys/phys', 'pathep') # Filters the EPG children in memory looking for the ones that belongs to the RsPathAtt class # and with an specific tDn rspathatt_list = filter(lambda x: type(x).__name__ == 'RsPathAtt' and str(x.tDn) == fabric_path_dn, self.query_child_objects(epg_dn)) if len(rspathatt_list) > 0: # Removes the static binding rspathatt_list[0].delete() self.commit(rspathatt_list[0]) # If there is not other assignment to this port, the switch profiles and policy groups are removed fabric_path_dn = port_dn.replace('node', 'paths').replace('sys/phys', 'pathep') class_query = ClassQuery('fvRsPathAtt') # Filters the all the fvRsPathAtt in memory looking for the ones that are using the port RsPathAtt_list = filter(lambda x: str(fabric_path_dn) in str(x.tDn), self.moDir.query(class_query)) if len(RsPathAtt_list) == 0: # Remove Policy group class_query = ClassQuery('infraAccPortGrp') class_query.propFilter = 'eq(infraAccPortGrp.name, "' + if_policy_group_name + '")' policy_groups = self.moDir.query(class_query) if len(policy_groups) > 0: policy_groups[0].delete() self.commit(policy_groups[0]) # Remove Interface profile port_mo = self.moDir.lookupByDn(port_dn) class_query = ClassQuery('infraAccPortP') class_query.propFilter = 'eq(infraAccPortP.name, "single_access_' + str(port_mo.id).split('/')[1] + '")' interface_profiles = self.moDir.query(class_query) if len(interface_profiles) > 0: interface_profiles[0].delete() self.commit(interface_profiles[0]) # RemoveSwitch profile class_query = ClassQuery('infraNodeP') class_query.propFilter = 'eq(infraNodeP.name, "' + switch_p_name + '")' switch_profiles = self.moDir.query(class_query) if len(switch_profiles) > 0: switch_profiles[0].delete() self.commit(switch_profiles[0])
def get_vpc_assignments(self): """ Returns a dictionary: keys are VPC names and values are the list of EPGs that are associated to the it """ result = {} class_query = ClassQuery('fvRsPathAtt') # Filters the all the fvRsPathAtt in memory looking for the ones that are using a VPC RsPathAtt_list = filter(lambda x: 'topology/pod-1/protpaths' in str(x.tDn), self.moDir.query(class_query)) for RsPathAtt_mo in RsPathAtt_list: vpc_name = str(RsPathAtt_mo.tDn).split('[')[1][:-1] epg_mo = self.moDir.lookupByDn(RsPathAtt_mo.parentDn) if vpc_name not in result.keys(): result[vpc_name] = [] result[vpc_name].append(epg_mo.name) return result
def home(): with open("/home/app/data/logs.txt", "a") as log_file: log_file.write("==================================================" + "\n") log_file.write("Received API Request from Client. Sending Response" + "\n") log_file.write("==================================================" + "\n") reply = None try: apicUrl = 'https://172.17.0.1/' loginSession = createCertSession() #loginSession = cobra.mit.session.LoginSession('https://10.22.47.171', 'admin', 'ins3965!') moDir = MoDirectory(loginSession) moDir.login() tableList = [] #row = ('TN', 'AP/L2OUT', 'EPG/InstP', 'CEP', 'IP', 'Type', 'PATH', 'PORT', 'POD', 'ENCAP', 'BD:CTX') #tableList.append(row) try: row ={} q = ClassQuery('fvCEp') q.subtree = 'children' tenantMo = moDir.query(q) except cobra.mit.request.QueryError as e: log('Reason: ' + e.reason) log('Error: ' + e.error) log('HTTP code: ' + e.httpCode) log(traceback.format_exc()) data = {} for mo in tenantMo: for child in mo.rscEpToPathEp: #print child.dn ip = mo.ip tn, ap, epg, cep, varPod, varStrPath, varStrPort = tDnToPath(child.dn) if 'protpaths' in child.tDn: portType = 'vPC' elif 'paths' in child.tDn and 'eth' in child.tDn: portType = '-' else: portType = 'PC' encap = (mo.encap).split('-')[1] #if args.macSearch: bd,ctx = getAncestorDnStrFromDnString(md, str(mo.dn), 1) #else: bd='-'; ctx='-' bd='-'; ctx='-' #row = (tn,ap,epg,cep,mo.ip,portType,varStrPath,varStrPort,varPod,encap,'%s:%s' %(bd,ctx)) row = { "tn": tn, "ap/l2out":ap, "epg":epg, "cep":cep, "ip":mo.ip, "type":portType, "path":varStrPath, "port":varStrPort, "pod":varPod, "encap":encap, "bd":"-:-" } tableList.append(row) #data[child.tDn]= row moDir.logout() #print json.dumps(data) #return render_template('home.html', table=tableList) #return respFormatJsonMos(data, len(data)) log(tableList) reply = jsonify({'results': tableList}) except Exception as e: log(traceback.format_exc()) return reply
if __name__ == '__main__': if len(sys.argv) != 5: print 'Usage: apic_show-mac-address.py <hostname> <username> <password> <mac-address>' sys.exit() else: hostname, username, password, macaddress = sys.argv[1:] url = 'https://' + hostname print "Logging on APIC..." try: # lls = LoginSession(url, username, password, secure=False) md = MoDirectory(lls) md.login() q = ClassQuery('fvCEp') q.subtree = 'children' q.subtreeClassFilter = 'fvRsCEpToPathEp' mos = md.query(q) #Other variables hasmacaddress = False epglists = {} i = -1 ## Verifying all mac address: for mo in mos: for child in mo.rscEpToPathEp: line = str(child.dn) i = i + 1 if (macaddress in line):
def get_class_mo(session, refClass, propFilter): #help(ClassQuery) classQuery = ClassQuery(refClass) classQuery.queryTarget = 'subtree' classQuery.propFilter = propFilter return session.query(classQuery)