Package: cucmapi
cucmapiThe cucmapi package is inspired by Levensailor'sciscoaxl, Presidio'sciscoris, and Jonathanelscpt'sciscocucmapi.cucmapi runs onpython-zeepand offers a complete abstraction from the AXL SOAP API and XML.The package gives you access to all API calls defined in the WSDL file.Currently, only Python 3.6+ is supported.While not Pythonic, I chose to keep all the method names as they are defined in the AXL schema reference, instead of turning them into snake-case variants, to have a 1:1 match between the available methods in this package and Cisco's documentation; i.e. if the WSDL operation is called addSipProfile then the method is called addSipProfile, too.Official Cisco API DocumentationAXL:https://developer.cisco.com/docs/axl-schema-reference/RisPort70 API:https://developer.cisco.com/docs/sxml/#!risport70-api-referenceControl Center Services API:https://developer.cisco.com/docs/sxml/#!control-center-services-api-referenceLog Collection API:https://developer.cisco.com/docs/sxml/#!log-collection-and-dimegetfileservice-api-referenceCDRonDemand API:https://developer.cisco.com/docs/sxml/#!cdrondemand-api-referencePerfMon API:https://developer.cisco.com/docs/sxml/#!perfmon-api-referenceInstallationgitclonegit@github.com:awetomate/cucmapi.gitTesting in a lab is highly recommended. You can reserve a DevNetSandboxfree of charge!Enable AXL SOAP Service on CUCM:Enable the AXL SOAP interfaceBrowse to the CUCM Serviceability page on https://<IP_CUCM>/ccmserviceTools > Service Activation:Enable the "Cisco AXL Web Service"Create an AXL Service AccountStep 1 - Create an AXL User GroupCUCM > User Management > User Group > Add.Step 2 - Assign the AXL role to the groupOn the top right drop down list "Related Links".Select "Assign Role to User Group" andfor full Read/Write access, select:
"Standard AXL API Access"for Read-Only access, select "Standard AXL API Users" and "Standard AXL Read Only API Access"Step 3 - Create a new Application UserCUCM > User Management > Application User > Add.Add the new User Group you created in step 1 and 2 to this user.Quick Startfromcucmapiimportaxl,ris,ccs,log,cdr,pfmusername="username"password="supersecret"cucm="fqdn"#or IP addresscucm_version="11.5"AXL=axl(username=username,password=password,cucm=cucm,cucm_version=cucm_version)# for SOAP AXLRIS=ris(username=username,password=password,cucm=cucm,cucm_version=cucm_version)# for RisPort70CCS=ccs(username=username,password=password,cucm=cucm,cucm_version=cucm_version)# for Control Center ServicesLOG=log(username=username,password=password,cucm=cucm,cucm_version=cucm_version)# for Log CollectionCDR=cdr(username=username,password=password,cucm=cucm,cucm_version=cucm_version)# for CDRonDemandPFM=pfm(username=username,password=password,cucm=cucm,cucm_version=cucm_version)# for PerfMon# get phonephone=AXL.getPhone(name="CSFjohn")print(phone.description)>>>Johnstestdescription>>># update phone descriptionAXL.updatePhone(name="CSFjohn",description="Johns proper phone description")# verify the new description has been setphone=AXL.getPhone(name="CSFjohn")print(phone.description)>>>Johnsproperphonedescription>>># get phone registration from RIS > requires a list of devices as input and returns a list# if no list of subscribers is provided, all nodes in the cluster are queriedreg=RIS.selectCmDeviceExt(devices=["CSFjohn"])print(reg[0].Status)>>>Registered>>># delete phoneAXL.removePhone(name="CSFjohn")# implicit "return all" will all available returnedTags# use sparingly and avoid on larger clusters (limit the returnedTags to what you need)all_devices=AXL.listPhone()# Usecase Example 1: Find out if there are still some registered Cisco IP Communicators (end of support)# Step 1, get process node names, exlude the entry called 'EnterpriseWideData'# This is optional. If you don't provide a list of subs in step3 all nodes in the cluster are queriednode_names=[node.namefornodeinAXL.listProcessNode(returnedTags={"name":""})if"Enterprise"notinnode.name]# Step 2, get a list of all Cisco IP Communicators via Thin SQL > returns list of dictionariescipcs=AXL.executeSQLQuery(sql="SELECT name FROM device WHERE tkclass=1 and tkmodel=30016")device_names=[ipc["name"]foripcincipcs]# Alternative to step 2 using axlphone_list=AXL.listPhone(returnedTags={"name":"","model":""})device_names=[phone.nameforphoneinphone_listif"Communicator"inphone.model]# Step 3, find all 'Registered' devices via RISregistration=RIS.selectCmDeviceExt(devices=device_names,subs=node_names,status="Registered")# orregistration=RIS.selectCmDeviceExt(devices=device_names,status="Registered")# Usecase Example 2: Get services status for each node in the cluster# Step 1, get the process node names plus the nodeUsage; exlude the entry called 'EnterpriseWideData'node_names=AXL.listProcessNode(returnedTags={"name":"","nodeUsage":""})nodes=[{"name":node.name,"nodeUsage":node.nodeUsage}fornodeinnode_namesif"Enterprise"notinnode.name]# Step 2, get the services info for each of the nodes and add them to the services listservices=[]fornodeinnodes:# create a Control Center Services client instance for each nodeCCS=ccs(username=username,password=password,cucm=node["name"],cucm_version=version)# get the services for the nodeservices_status=CCS.soapGetServiceStatus()# Optional: create your own custom view and replace the ReasonCodes with 'Activated/Deactivated'services_clean=[{"ServerName":node["name"],"NodeType":node["nodeUsage"],"ServiceName":s.ServiceName,"ServiceStatus":s.ServiceStatus,"ActivationStatus":"Activated"if"Service Not Activated"notins.ReasonCodeStringelse"Deactivated","StartTime":""ifnots.StartTimeelses.StartTime}forsinservices_status]# add the node's services to the services listservices+=services_clean# now you have a list of all services for each node in the clusterprint(services)>>>[{'ServerName':'servernode01.domain.com','NodeType':'Subscriber','ServiceName':'A Cisco DB','ServiceStatus':'Started','ActivationStatus':'Activated','StartTime':'Sat Nov 20 18:40:52 2021'},{'ServerName':'servernode01.domain.com','NodeType':'Subscriber','ServiceName':'A Cisco DB Replicator','ServiceStatus':'Started','ActivationStatus':'Activated','StartTime':'Sat Nov 20 18:40:53 2021'},{'ServerName':'servernode01.domain.com','NodeType':'Subscriber','ServiceName':'Cisco AMC Service','ServiceStatus':'Started','ActivationStatus':'Activated','StartTime':'Sat Nov 20 18:41:53 2021'},...]>>>