cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
5087
Views
0
Helpful
8
Replies

CUCM 10.5 AXL updateLine - Directory number not found

konradokon
Level 1
Level 1

Hi All,

We have a python scripts to update call forward on the line. It works well for CUCM 8.6.2 but keeps failing for 10.5.2 I have updated AXL scheme but still does not work.

Could you advise on how to get this working for 10.5.2, please?

Code:

  soaprequest = '''

    <soapenv:Envelope

                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

                xmlns:ns="http://www.cisco.com/AXL/API/10.5">

        <soapenv:Header/>

        <soapenv:Body>

            <ns:updateLine sequence="?">

               <pattern>{0}</pattern>

                <routePartitionName>{1}</routePartitionName>

                <callForwardAll><destination>{2}</destination></callForwardAll>

            </ns:updateLine>

        </soapenv:Body>

    </soapenv:Envelope>'''.format(dn,partition,dest)

global AXLRequest

    soapheaders = {'SOAPAction':'CUCM:DB ver=10.5 updateLine', 'Content-length':'427'}

    conn = "https://%s:8443/axl/" % (host)

    authstr = HTTPBasicAuth(usrnm, pw)

    AXLRequest = requests.post(url=conn, data = soaprequest, headers = soapheaders, verify = False, auth=authstr)

    root = ET.fromstring(AXLRequest.text)

error:

<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>Directory Number not found</faultstring><detail><axlError><axlcode>5003</axlcode><axlmessage>Directory Number not found</axlmessage><request>updateLine</request></axlError></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>

<Response [500]>

<Element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope' at 0x1028d9e08>

<Response [500]>

CWDALL failed on DN XXXXXXX

1 Accepted Solution

Accepted Solutions

thedd
Level 1
Level 1

As far as i untestand the log

....
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>Directory Number not found</faultstring><detail><axlError><axlcode>5003</axlcode><axlmessage>Directory Number not found</axlmessage><request>updateLine</request></axlError></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>

<Response [500]>

....

Shows that you actually send a soap message and the AXL interface tryes to da the updateLine request.

So your python code should be working fine.

I would check the XML Part provided via AXL.

Could you create a dump of your soaprequest cretaed and sent via AXL?
Maybe there is somethin wrong.

I have made somethin simmilar but in perl.Even if this is a different language the XML and SOAP Part should be mostly the same.

Below you find how i built my XML and it works.

I can change every single Call Forward setting with this:

<pattern>$dn</pattern><routePartition>$partition</routePartition>

<callForwardAll>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfa</destination>

</callForwardAll>

<callForwardBusy>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfb</destination>

</callForwardBusy>

<callForwardBusy>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination></destination>

</callForwardBusy>

<callForwardBusyInt>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfbi</destination>

</callForwardBusyInt>

<callForwardNoAnswer>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfna</destination>

<duration>$cfnar</duration></callForwardNoAnswer>

<callForwardNoAnswer>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination></destination>

<duration>$cfnar</duration></callForwardNoAnswer>

<callForwardNoAnswerInt>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfnai</destination>

</callForwardNoAnswerInt>

<callForwardNoCoverage>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfnc</destination>

</callForwardNoCoverage>

<callForwardNoCoverageInt>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfnci</destination>

</callForwardNoCoverageInt>

<callForwardOnFailure>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfcti</destination>

</callForwardOnFailure>

<callForwardNotRegistered>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfu</destination>

</callForwardNotRegistered>

<callForwardNotRegisteredInt>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfui</destination>

</callForwardNotRegisteredInt>

View solution in original post

8 Replies 8

Hi konradokon,

i have wrote an Python Script that is building an XML-String for AXL from a Dictionary. If you send the Output from this Function with requests it should work. I have update the Line Pattern from some Lines with this on CUCM 10.5.2 and it worked great. I didn't made a Call Forward yet, but it should still work too.

So if you give the function a Dictionary like: dict_Source = {'PrimaryNode':'updateLine','pattern':'XXXX', 'routePartitionName':'XXXX', 'callForwardAll':'XXXX'}

And use your requests like this:

global AXLRequest

(soapheaders, soaprequest) = do_axl(dict_Source)

    soapheaders = {'SOAPAction':'CUCM:DB ver=10.5 updateLine', 'Content-length':'427'}

    conn = "https://%s:8443/axl/" % (host)

    authstr = HTTPBasicAuth(usrnm, pw)

    AXLRequest = requests.post(url=conn, data = soaprequest, headers = soapheaders, verify = False, auth=authstr)

    root = ET.fromstring(AXLRequest.text)

It should work.

#!/usr/bin/python
# -*- coding: utf-8 -*-

__author__ = 'Benjamin Schaumburg'

import xml.etree.ElementTree as eTree

import sys

# Namespaces
soap_soap = '{http://schemas.xmlsoap.org/soap/envelope/}'
soap_cisco_axl = '{http://www.cisco.com/AXL/API/10.5}'


def do_axl(elements_dict):

   if "PrimaryNode" in elements_dict:

       axlfunction = elements_dict.pop('PrimaryNode')

   else:

        print('No PrimaryNode, please check!')

       sys.exit()

   if "SecondaryNode" in elements_dict:

       axlsubfunction = elements_dict.pop('SecondaryNode')

   else:

       axlsubfunction = ''

   # SOAP Headers for request
   soapheaders = {'Content-type': 'text/xml;charset=UTF-8', 'SOAPAction': 'CUCM:DB ver=10.5 ' + axlfunction}

   # Build SOAP Envelope
  # SOAP Envelope, with Namespace SOAP
   soap_root = eTree.Element(soap_soap + 'Envelope')

   # SOAP Body, Header are optional
   soap_body = eTree.SubElement(soap_root, soap_soap + 'Body')

   # AXL Function, in Namespace Cisco
   soap_function = eTree.SubElement(soap_body, soap_cisco_axl + axlfunction)

   # Wenn noch ein Unterelement benötigt wird, füge es hier ein
   if axlsubfunction:

        soap_subfunction = eTree.SubElement(soap_function, axlsubfunction)

  
   for key in elements_dict:

       soap_axlelement = eTree.SubElement(soap_subfunction, key)

       soap_axlelement.text = elements_dict[key]

   else:

        for key in elements_dict:

            soap_axlelement = eTree.SubElement(soap_function, key)

            soap_axlelement.text = elements_dict[key]

   return soapheaders, (eTree.tostring(soap_root, encoding='UTF-8', method='xml'))

Hi,

Thanks for coming back to me. I am trying to implement it but I am not sure where did you take do_axl from.

(soapheaders, soaprequest) = do_axl(dict_source)

NameError: name 'do_axl' is not defined

Could you advise, please? I am python beginner.

Thanks,

Hi,

do_axl is the defined function "def do_axl(elements_dict):". You have to define it, before you use it.

Your Script should like this (It is important, that the Function is at the beginning:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import xml.etree.ElementTree as eTree

import sys

import requests

 

# Namespaces
soap_soap = '{http://schemas.xmlsoap.org/soap/envelope/}'
soap_cisco_axl = '{http://www.cisco.com/AXL/API/10.5}'


def do_axl(elements_dict):

   if "PrimaryNode" in elements_dict:

       axlfunction = elements_dict.pop('PrimaryNode')

   else:

        print('No PrimaryNode, please check!')

       sys.exit()

   if "SecondaryNode" in elements_dict:

       axlsubfunction = elements_dict.pop('SecondaryNode')

   else:

       axlsubfunction = ''

   # SOAP Headers for request
   soapheaders = {'Content-type': 'text/xml;charset=UTF-8', 'SOAPAction': 'CUCM:DB ver=10.5 ' + axlfunction}

   # Build SOAP Envelope
  # SOAP Envelope, with Namespace SOAP
   soap_root = eTree.Element(soap_soap + 'Envelope')

   # SOAP Body, Header are optional
   soap_body = eTree.SubElement(soap_root, soap_soap + 'Body')

   # AXL Function, in Namespace Cisco
   soap_function = eTree.SubElement(soap_body, soap_cisco_axl + axlfunction)

   # Wenn noch ein Unterelement benötigt wird, füge es hier ein
   if axlsubfunction:

        soap_subfunction = eTree.SubElement(soap_function, axlsubfunction)

  
   for key in elements_dict:

       soap_axlelement = eTree.SubElement(soap_subfunction, key)

       soap_axlelement.text = elements_dict[key]

   else:

        for key in elements_dict:

            soap_axlelement = eTree.SubElement(soap_function, key)

            soap_axlelement.text = elements_dict[key]

   return soapheaders, (eTree.tostring(soap_root, encoding='UTF-8', method='xml'))

dict_Source = {'PrimaryNode':'updateLine','pattern':'XXXX', 'routePartitionName':'XXXX', 'callForwardAll':'XXXX'}

(soapheaders, soaprequest) = do_axl(dict_Source)

soapheaders = {'SOAPAction':'CUCM:DB ver=10.5 updateLine', 'Content-length':'427'}

conn = "https://%s:8443/axl/" % (host)

authstr = HTTPBasicAuth(usrnm, pw)

AXLRequest = requests.post(url=conn, data = soaprequest, headers = soapheaders, verify = False, auth=authstr)

root = ET.fromstring(AXLRequest.text)

thedd
Level 1
Level 1

As far as i untestand the log

....
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>Directory Number not found</faultstring><detail><axlError><axlcode>5003</axlcode><axlmessage>Directory Number not found</axlmessage><request>updateLine</request></axlError></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>

<Response [500]>

....

Shows that you actually send a soap message and the AXL interface tryes to da the updateLine request.

So your python code should be working fine.

I would check the XML Part provided via AXL.

Could you create a dump of your soaprequest cretaed and sent via AXL?
Maybe there is somethin wrong.

I have made somethin simmilar but in perl.Even if this is a different language the XML and SOAP Part should be mostly the same.

Below you find how i built my XML and it works.

I can change every single Call Forward setting with this:

<pattern>$dn</pattern><routePartition>$partition</routePartition>

<callForwardAll>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfa</destination>

</callForwardAll>

<callForwardBusy>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfb</destination>

</callForwardBusy>

<callForwardBusy>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination></destination>

</callForwardBusy>

<callForwardBusyInt>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfbi</destination>

</callForwardBusyInt>

<callForwardNoAnswer>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfna</destination>

<duration>$cfnar</duration></callForwardNoAnswer>

<callForwardNoAnswer>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination></destination>

<duration>$cfnar</duration></callForwardNoAnswer>

<callForwardNoAnswerInt>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfnai</destination>

</callForwardNoAnswerInt>

<callForwardNoCoverage>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfnc</destination>

</callForwardNoCoverage>

<callForwardNoCoverageInt>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfnci</destination>

</callForwardNoCoverageInt>

<callForwardOnFailure>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfcti</destination>

</callForwardOnFailure>

<callForwardNotRegistered>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfu</destination>

</callForwardNotRegistered>

<callForwardNotRegisteredInt>

    <forwardToVoiceMail>f</forwardToVoiceMail>

    <callingSearchSpace/><destination>$cfui</destination>

</callForwardNotRegisteredInt>

I'm attempting to erase call forward all which also removes the calling search space settings as well. So i wrote some python code to erase the cfw info but update the css per line as follows  -- the outer loop works fine (remove cfw all) but the inner loop to update the css applies the same css for all lines in the list. 

example:
line 887  css=subscriber css
line 888  css=subscriber css
line 889  css=subscriber css

dnToUpdate = list(addressStatus.keys())
callineSearchSpace = list(addressStatus.values())

for line in dnToUpdate:
for css in callineSearchSpace:
service = client.create_service(binding, location)
resp = service.updateLine(pattern=line, callForwardAll= {'destination' : '', 'callingSearchSpaceName' : css})
print(resp)
print (line + ' CFW setting was successfully updated')

 

The problem is likely the nested loop.  You might try something like:

 

service = client.create_service(binding, location)

for x in range( len( dnToUpdate ) ):

  resp = service.updateLine( pattern = dnToUpdate( x ), 
	callForwardAll = { "destination": '', "callingSearchSpaceName": callineSearchSpace( x ) }
  print( resp )
  print ( dnToUpdate( x ) + ' CFW setting was successfully updated')

or perhaps use a dictionary array to store DN+CSS pairs - this may keep things from getting our of sync between lists:

 

lineAndCss = [
	{ 
		"1ine": "1000",
		"Css": "line1Css"
	},
	{
		"1ine": "2000",
		"Css": "line2Css"
	}

service = client.create_service(binding, location)

for line in lineAndCss:

  resp = service.updateLine( pattern = line[ "line" ], 
	callForwardAll = { "destination": '', "callingSearchSpaceName": line[ "Css" ] }
  print( resp )
  print ( line[ "line" ] + ' CFW setting was successfully updated')	

Hi David, thanks for your reply -- it lead me down the correct path and issue fixed as follows:
for address, css in lineAnd_CSS.items():
service = client.create_service(binding, location)
resp = service.updateLine(pattern=address, callForwardAll= {'destination' : '', 'callingSearchSpaceName' : css})
print(resp)
print (address + ' CFW setting was successfully updated')

Hi David, thanks for your reply -- it lead me down the correct path and issue fixed as follows:

for address, css in lineAnd_CSS.items():
service = client.create_service(binding, location)
resp = service.updateLine(pattern=address, callForwardAll= {'destination' : '', 'callingSearchSpaceName' : css})
print(resp)
print (address + ' CFW setting was successfully updated')