How to configure CUCM via the AXL SOAP API with Python

How to configure CUCM via the AXL SOAP API with Python

Are you running Cisco Unified Communications Manager (previously Cisco CallManager) for your voice and video? Are you tired of manually configuring all your users, directory numbers and devices by hand? Whether you manage 100 phones or a megacluster with 100.000 users, you can easily automate the provisioning of your CUCM cluster.

What you will need

  • Access to a Cisco UCM cluster, I'm using CUCM 11.5 but the AXL interface is available on all currently supported software versions.

  • The Cisco AXL Web Service Activated and Started from the Cisco Unified Serviceability pages.

  • An End-User or Application user with the Standard AXL API Access role assigned.

  • An environment to run Python code, for this post I'm using a stand-alone Python 3 script.

Getting set up

The Administrative XML Web Service (AXL) is a XML/SOAP based interface that provides a mechanism for inserting, retrieving, updating and removing data from the Unified Communication configuration database. Developers can send and receive SOAP messages that adhere to the CUCM Web Service Description Language (WSDL) definition.

First download the AXL WSDL files for your version of CUCM from the Plugins page, for more information refer to this page on Cisco DevNet. Extract the files in the ZIP file in a folder called schema under your working directory.  Next you'll need a Python SOAP client called suds. That package is no longer maintained by its original author, but there is a well-maintained fork called suds-jurko that you can use.

$ sudo pip3 install suds-jurko

Creating a SOAP connection

First I import suds as well as a few other modules to deal with URLs and SSL connections.

from os.path import abspath
from urllib.parse import urljoin
from urllib.request import pathname2url
import ssl
from suds.client import Client

Then I point to the CUCM AXL WSDL schema that we previously downloaded and setup a SOAP CLIENT object.

WSDL = urljoin('file:', pathname2url(abspath('schema/AXLAPI.wsdl')))

# Allow insecure connections
if hasattr(ssl, '_create_unverified_context'):
    ssl._create_default_https_context = ssl._create_unverified_context

CLIENT = Client(WSDL, location='https://%s:8443/axl/' % ('192.168.0.5'),
                username='admin', password='cisco123')

With that CLIENT object I can directly retrieve information from CUCM, such as a list of all End Users with their telephone number.

try:
    response = CLIENT.service.listUser(
        searchCriteria={
            'userid': '%'
        },
        returnedTags={
            'userid': True,
            'telephoneNumber': True
        })
    print(response['return']['user'])

except Exception:
    print('CUCM AXL login failed, incorrect host or username/password ?')
    return None

But I can also create new entries in the database, such as a Directory Number (DN) 3001 in the Phones partition.

resp = CLIENT.service.addLine(line={
    'pattern': '3001',
    'routePartitionName': 'Phones',
    'shareLineAppearanceCssName': 'Phones'})
line_id = resp['return']

And then I can create a new Phone, here a CSF (Cisco Jabber) Device, using that line.

CLIENT.service.addPhone(phone={
    'name': '%s%s' % ('CSF', 'klambrec'),
    'ownerUserName': 'klambrec',
    'product': 'Cisco Unified Client Services Framework',
    'class': 'Phone',
    'protocol': 'SIP',
    'protocolSide': 'User',
    'devicePoolName': 'Default',
    'sipProfileName':
        'Jabber Desktop SIP Profile',
    'lines': {
        'line': {
            'index': 1,
            'dirn': {
                '_uuid': line_id
            },
            'associatedEndusers': {
                'enduser': {
                    'userId': 'klambrec'
                }
            }
        }}
})

In conclusion

The CUCM database schema and the resulting SOAP message structure definitely take some getting used to. Once you get the hang of it, you'll be deploying and checking CUCM configuration in no-time. You should definitely check out the Cisco AXL DevNet pages that contain many more examples as well as a full API reference.

Of course this is just the beginning. Depending on your IT workflows you could automatically provision CUCM user accounts and phones when a new hire joins or you could build out a custom web portal for end-user self-service. Please do reach out if you are interested in learning more!

How to integrate Django REST Framework and Angular

How to integrate Django REST Framework and Angular

What is an MTP / MPO connector?

What is an MTP / MPO connector?