10-12-2015 03:03 AM
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
Solved! Go to Solution.
04-20-2016 06:54 AM
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>
10-14-2015 03:30 AM
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'))
10-14-2015 05:59 AM
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,
10-14-2015 07:32 AM
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)
04-20-2016 06:54 AM
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>
08-07-2019 06:47 AM
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')
08-07-2019 09:44 AM
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')
08-07-2019 02:07 PM
08-07-2019 02:08 PM
Hi David, thanks for your reply -- it lead me down the correct path and issue fixed as follows:
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide