Python SDK for Cisco CUCM SOAP APIs
Project description
cucmapi
The cucmapi package is inspired by Levensailor's ciscoaxl, Presidio's ciscoris, and Jonathanelscpt's ciscocucmapi.
cucmapi runs on python-zeep and 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 Documentation
- AXL: https://developer.cisco.com/docs/axl-schema-reference/
- RisPort70 API: https://developer.cisco.com/docs/sxml/#!risport70-api-reference
- Control Center Services API: https://developer.cisco.com/docs/sxml/#!control-center-services-api-reference
- Log Collection API: https://developer.cisco.com/docs/sxml/#!log-collection-and-dimegetfileservice-api-reference
- CDRonDemand API: https://developer.cisco.com/docs/sxml/#!cdrondemand-api-reference
- PerfMon API: https://developer.cisco.com/docs/sxml/#!perfmon-api-reference
Installation
git clone git@github.com:awetomate/cucmapi.git
Testing in a lab is highly recommended. You can reserve a DevNet Sandbox free of charge!
Enable AXL SOAP Service on CUCM:
Enable the AXL SOAP interface
Browse to the CUCM Serviceability page on https://<IP_CUCM>/ccmservice
Tools > Service Activation:
Enable the "Cisco AXL Web Service"
Create an AXL Service Account
Step 1 - Create an AXL User Group
CUCM > User Management > User Group > Add.
Step 2 - Assign the AXL role to the group
On the top right drop down list "Related Links".
Select "Assign Role to User Group" and
- for 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 User
CUCM > User Management > Application User > Add.
Add the new User Group you created in step 1 and 2 to this user.
Quick Start
from cucmapi import axl, ris, ccs, log, cdr, pfm
username = "username"
password = "supersecret"
cucm = "fqdn" #or IP address
cucm_version = "11.5"
AXL = axl(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for SOAP AXL
RIS = ris(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for RisPort70
CCS = ccs(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for Control Center Services
LOG = log(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for Log Collection
CDR = cdr(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for CDRonDemand
PFM = pfm(username=username, password=password, cucm=cucm, cucm_version=cucm_version) # for PerfMon
# get phone
phone = AXL.getPhone(name="CSFjohn")
print(phone.description)
>>>
Johns test description
>>>
# update phone description
AXL.updatePhone(name="CSFjohn", description="Johns proper phone description")
# verify the new description has been set
phone = AXL.getPhone(name="CSFjohn")
print(phone.description)
>>>
Johns proper phone description
>>>
# 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 queried
reg = RIS.selectCmDeviceExt(devices=["CSFjohn"])
print(reg[0].Status)
>>>
Registered
>>>
# delete phone
AXL.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 queried
node_names = [node.name for node in AXL.listProcessNode(returnedTags={"name": ""}) if "Enterprise" not in node.name]
# Step 2, get a list of all Cisco IP Communicators via Thin SQL > returns list of dictionaries
cipcs = AXL.executeSQLQuery(sql="SELECT name FROM device WHERE tkclass=1 and tkmodel=30016")
device_names = [ipc["name"] for ipc in cipcs]
# Alternative to step 2 using axl
phone_list = AXL.listPhone(returnedTags={"name": "", "model": ""})
device_names = [phone.name for phone in phone_list if "Communicator" in phone.model]
# Step 3, find all 'Registered' devices via RIS
registration = RIS.selectCmDeviceExt(devices=device_names, subs=node_names, status="Registered")
# or
registration = 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} for node in node_names if "Enterprise" not in node.name]
# Step 2, get the services info for each of the nodes and add them to the services list
services = []
for node in nodes:
# create a Control Center Services client instance for each node
CCS = ccs(username=username, password=password, cucm=node["name"], cucm_version=version)
# get the services for the node
services_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" not in s.ReasonCodeString else "Deactivated",
"StartTime": "" if not s.StartTime else s.StartTime
} for s in services_status]
# add the node's services to the services list
services += services_clean
# now you have a list of all services for each node in the cluster
print(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'},
...
]
>>>
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file cucmapi-0.0.2.tar.gz
.
File metadata
- Download URL: cucmapi-0.0.2.tar.gz
- Upload date:
- Size: 2.3 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c04609e64602799eb50ebddcb58b3fd8d54dda35f6205dc236b14a1f0818938c |
|
MD5 | 94cd8b6707cfafaa417fe4cea7b3d22a |
|
BLAKE2b-256 | aed94e5030e5c9aeb3b041574f6b328b2dd2338de717c85d0c29cac57986af62 |
File details
Details for the file cucmapi-0.0.2-py3-none-any.whl
.
File metadata
- Download URL: cucmapi-0.0.2-py3-none-any.whl
- Upload date:
- Size: 2.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cebe753de2284f6893e010251823423683ced9af6ca1caf699dc1cbd6a53b5c5 |
|
MD5 | 7cd482252dfbff1474c961c18de7065e |
|
BLAKE2b-256 | baaaedca8a615244546ac406fd520f9936b0bcadc7519b28b966178b004f3110 |