08-02-2018 08:45 PM
Trying to add a trunk port using Pythons and suds to do it. Question is I do not know how to tell it to program the destination in the IPV4 address area within the added trunk call. Below is a sample of a working sip profile and the none work add sip trunk.
code that works:
# Add Sip Profile
print("")
print("Adding SIP Profile to Call Manager")
print("")
client = Client(wsdl,location=location, username=username, password=password)
ap = client.service.addSipProfile({
'name': sProfileName + " Cisco Unity SIP Profile",
'description' : sProfileName + " Cisco Unity SIP Profile",
'enableOutboundOptionsPing': 'True'
})
print("Command completed successfully! ")
code that does not work.
# Add Sip Trunk
print("")
print("Adding SIP Trunk to Call Manager")
print("")
client = Client(wsdl,location=location, username=username, password=password)
ap = client.service.addsipTrunk({
'name' : sProfileName + " Cisco Unity SIP Trunk",
'description' : sProfileName + " Cisco Unity SIP Trunk",
'devicePoolName' : "Phoenix",
'location' : "Phoenix",
'sipProfileName' : sProfileName + " Cisco Unity SIP Trunk",
'securityProfileName' : sProfileName + " Cisco Unity SIP Trunk",
'addressIpv4' : "10.10.10.10"
})
Error with code:
Traceback (most recent call last):
File "C:/Users/rwykoff/Documents/testing/voiceadd.py", line 38, in versioncheck
login(wsdl,location,username,password,imp)
File "C:/Users/rwykoff/Documents/testing/voiceadd.py", line 123, in login
mainMenu(wsdl,location,username,password,imp)
File "C:/Users/rwykoff/Documents/testing/voiceadd.py", line 148, in mainMenu
addCiscoUnity(wsdl,location,username,password,newbuild)
File "C:/Users/rwykoff/Documents/testing/voiceadd.py", line 279, in addCiscoUnity
'addressIpv4' : "10.10.10.10"
File "C:\Program Files\Python36\lib\site-packages\suds\client.py", line 521, in __call__
return client.invoke(args, kwargs)
File "C:\Program Files\Python36\lib\site-packages\suds\client.py", line 576, in invoke
soapenv = binding.get_message(self.method, args, kwargs)
File "C:\Program Files\Python36\lib\site-packages\suds\bindings\binding.py", line 109, in get_message
content = self.bodycontent(method, args, kwargs)
File "C:\Program Files\Python36\lib\site-packages\suds\bindings\document.py", line 95, in bodycontent
add_param, self.options().extraArgumentErrors)
File "C:\Program Files\Python36\lib\site-packages\suds\argparser.py", line 83, in parse_args
return arg_parser(args, kwargs, extra_parameter_errors)
File "C:\Program Files\Python36\lib\site-packages\suds\argparser.py", line 108, in __call__
self.__process_parameters()
File "C:\Program Files\Python36\lib\site-packages\suds\argparser.py", line 299, in __process_parameters
self.__process_parameter(*pdef)
File "C:\Program Files\Python36\lib\site-packages\suds\argparser.py", line 294, in __process_parameter
self.__in_choice_context(), value)
File "C:\Program Files\Python36\lib\site-packages\suds\bindings\document.py", line 86, in add_param
p = self.mkparam(method, pdef, value)
File "C:\Program Files\Python36\lib\site-packages\suds\bindings\document.py", line 130, in mkparam
return Binding.mkparam(self, method, pdef, object)
File "C:\Program Files\Python36\lib\site-packages\suds\bindings\binding.py", line 225, in mkparam
return marshaller.process(content)
File "C:\Program Files\Python36\lib\site-packages\suds\mx\core.py", line 59, in process
self.append(document, content)
File "C:\Program Files\Python36\lib\site-packages\suds\mx\core.py", line 72, in append
self.appender.append(parent, content)
File "C:\Program Files\Python36\lib\site-packages\suds\mx\appender.py", line 88, in append
appender.append(parent, content)
File "C:\Program Files\Python36\lib\site-packages\suds\mx\appender.py", line 229, in append
Appender.append(self, child, cont)
File "C:\Program Files\Python36\lib\site-packages\suds\mx\appender.py", line 168, in append
self.marshaller.append(parent, content)
File "C:\Program Files\Python36\lib\site-packages\suds\mx\core.py", line 71, in append
if self.start(content):
File "C:\Program Files\Python36\lib\site-packages\suds\mx\literal.py", line 86, in start
raise TypeNotFound(content.tag)
suds.TypeNotFound: Type not found: 'location'
Thanks in Advance.
08-03-2018 04:07 AM
08-03-2018 06:04 AM
Sorry, yes it is addSipTrunk but I forgot to add that. My main issue seems to be that the IPv4 address is in a separate group called destination but I do not know how to add that in Python as I am just a beginner at Python and API.
08-13-2018 07:53 PM
The portion of the WSDL for the destination shows nested format
allowing for multiple destinations:
destinations [ANON-destinations]
destination [XSipTrunkDestination] Max: 16
addressIpv4 [String255]
addressIpv6 [String255]
port [XInteger]
sortOrder [XInteger] REQUIRED
So I think you want to replace the IPv4 argument with something like this
'destinations': [
'destination':
{ 'addressIpv4': '1.1.1.1',
'port': 433,
'sortOrder': 1}
]
( I haven't tested it myself)
05-16-2019 01:23 PM
Did anyone ever get this question solved? I am also trying to add a sip trunk using the code below and cannot get it to add. I get a different error, but any help would be very much appreciated.
def add_trunk(service,gw,dp,loc,mrgl,vip):
try:
data = {'sipTrunk':{
'name': gw,
'description': gw,
'model': 'SIP Trunk',
'class': 'Trunk',
'callingSearchSpaceName': 'INTERNAL_CSS',
'devicePoolName': dp,
'locationName': loc,
'mediaResourceListName': mrgl,
'securityProfileName': 'Non Secure SIP Voice Gateway Trunk Profile',
'sipProfileName': 'Standard SIP Voice Gateway Profile',
'callingPartySelection': 'First Redirect Number',
'sipTrunkType': 'None(Default)',
'pstnAccess': 1,
'destinations': {'destination': []}
}}
[data['sipTrunk']['destinations']['destination'].append({'addressIpv4':ip,'port': '5060', 'sortOrder': 1})]
resp = service.addSipTrunk( data )
print(resp)
except Fault as err:
resp=''
show_history()
return resp
vip = '1.1.1.1'
dp = 'Test_DP'
srst = siteID + "-" + city + '_SRST'
loc = 'Hub_None'
mrgl = 'Test_MRGL'
gw = 'TestTrunk'
resp=add_trunk(service,gw,dp,loc,mrgl,vip)
File "C:\Python37\lib\site-packages\zeep\xsd\elements\element.py", line 248, in validate
"Missing element %s" % (self.name), path=render_path)
zeep.exceptions.ValidationError: Missing element name (addSipTrunk.sipTrunk)
05-17-2019 09:27 AM
This was a tricky one, as there are some unexpected required fields...here is my complete working sample for 11.5:
from zeep import Client from zeep.cache import SqliteCache from zeep.transports import Transport from zeep.plugins import HistoryPlugin from requests import Session from requests.auth import HTTPBasicAuth from lxml import etree import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) username = 'Administrator' password = 'ciscopsdt' wsdl = 'file:///home/dstaudt/Downloads/Zeep Sample/AXLAPI.wsdl' session = Session() session.verify = False session.auth = HTTPBasicAuth(username, password) transport = Transport(cache=SqliteCache(), session=session, timeout=20) history = HistoryPlugin() client = Client(wsdl=wsdl, transport=transport, plugins=[history]) service = client.create_service("{http://www.cisco.com/AXLAPIService/}AXLAPIBinding", "https://ds-ucm115-1.cisco.com/axl/") #factory = client.type_factory('ns0') # data = factory.XSipTrunk( # name = 'testSipTrunk', # product = 'SIP Trunk', # # _class = 'Trunk', # protocol = 'SIP', # protocolSide = 'Network', # devicePoolName = 'Default', # locationName = 'Hub_None', # securityProfileName = 'Non Secure SIP Trunk Profile', # sipProfileName = 'Standard SIP Profile', # callingPartySelection = 'First Redirect Number', # pstnAccess = 1, # presenceGroupName = 'Standard Presence group', # destinations = [] # ) # # Cant specify class in the factory constructor above due to collision with Python 'class' reserved word # data['class'] = 'Trunk' data = { 'name': 'testSipTrunk', 'description': 'testDescription', 'product': 'SIP Trunk', 'class': 'Trunk', 'protocol': 'SIP', 'protocolSide': 'Network', 'devicePoolName': 'Default', 'locationName': 'Hub_None', 'securityProfileName': 'Non Secure SIP Trunk Profile', 'sipProfileName': 'Standard SIP Profile', 'presenceGroupName': 'Standard Presence group', 'callingAndCalledPartyInfoFormat': 'Deliver DN only in connected party', 'destinations': [], } data['destinations'].append( {'destination': {'addressIpv4': '1.1.1.1', 'port': '5060', 'sortOrder': 1}}) result = service.addSipTrunk( data ) #troubleshooting soap envelope for hist in [history.last_sent, history.last_received]: print(etree.tostring(hist["envelope"], encoding="unicode", pretty_print=True))
05-20-2019 09:57 AM
Thank you sooo much!!! That worked like a charm.
05-20-2019 10:44 AM
I wonder if you could help me with another issue. I am trying to update a device pool with a few values. I don't get an error and everything updates except it doesn't update the "local router group". It just remains as "Standard Local Route Group" <None>
def update_devpool(service,dp,rg):
try:
#print(rg)
data = {
'name': dp,
'locationName': 'HUB_None',
'localRouteGroupName': {'name': rg}
#'localRouteGroupName': rg,
#'localRouteGroup': rg
}
resp = service.updateDevicePool(**data)
print(dp + ' updated')
except Fault as err:
resp = ''
print(err)
return resp
username = 'user'
password = 'pass'
host = '<cucm axl server>'
wsdl = 'file://C:/Documents/Playbooks/axlsqltoolkit/schema/current/AXLAPI.wsdl'
location = 'https://{host}:8443/axl/'.format(host=host)
binding = "{http://www.cisco.com/AXLAPIService/}AXLAPIBinding"
session = Session()
session.verify = False
session.auth = HTTPBasicAuth(username, password)
transport = Transport(cache=SqliteCache(), session=session, timeout=20)
history = HistoryPlugin()
client = Client(wsdl=wsdl, transport=transport, plugins=[history])
service = client.create_service(binding, location)
rg='000-Test' #and this rg does show up as a valid local route group in the drop down in CUCM
update_devpool(service,dp,rg)
05-21-2019 05:41 AM
Sorry, I forgot to list the error I am getting. Here it is:
Traceback (most recent call last):
File "AddCUCMSite_v3.py", line 445, in <module>
update_devpool(service,dp,uuid,mrgl,srst,rg)
File "AddCUCMSite_v3.py", line 136, in update_devpool
resp = service.updateDevicePool(**data)
File "C:\Python37\lib\site-packages\zeep\proxy.py", line 42, in __call__
self._op_name, args, kwargs)
File "C:\Python37\lib\site-packages\zeep\wsdl\bindings\soap.py", line 121, in send
options=options)
File "C:\Python37\lib\site-packages\zeep\wsdl\bindings\soap.py", line 68, in _create
serialized = operation_obj.create(*args, **kwargs)
File "C:\Python37\lib\site-packages\zeep\wsdl\definitions.py", line 200, in create
return self.input.serialize(*args, **kwargs)
File "C:\Python37\lib\site-packages\zeep\wsdl\messages\soap.py", line 72, in serialize
body_value = self.body(*args, **kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\elements\element.py", line 48, in __call__
instance = self.type(*args, **kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\types\complex.py", line 42, in __call__
return self._value_class(*args, **kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\valueobjects.py", line 90, in __init__
items = _process_signature(self._xsd_type, args, kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\valueobjects.py", line 204, in _process_signature
values = element.parse_kwargs(kwargs, None, available_kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\elements\indicators.py", line 204, in parse_kwargs
sub_result = element.parse_kwargs(kwargs, elm_name, available_kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\elements\element.py", line 118, in parse_kwargs
kwargs, name or self.attr_name, available_kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\types\complex.py", line 282, in parse_kwargs
value = self._create_object(value, name)
File "C:\Python37\lib\site-packages\zeep\xsd\types\complex.py", line 303, in _create_object
return self(**value)
File "C:\Python37\lib\site-packages\zeep\xsd\types\complex.py", line 42, in __call__
return self._value_class(*args, **kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\valueobjects.py", line 90, in __init__
items = _process_signature(self._xsd_type, args, kwargs)
File "C:\Python37\lib\site-packages\zeep\xsd\valueobjects.py", line 231, in _process_signature
xsd_type.signature(standalone=False)))
TypeError: {http://www.cisco.com/AXL/API/11.5}XFkType() got an unexpected keyword argument 'name'. Signature: `xsd:string, uuid: {http://www.cisco.com/AXL/API/11.5}XUUID`
06-07-2019 02:41 PM
I got this working with Zeep, and added the code to this new AXL sample collection project...hope it helps!
06-14-2019 11:39 AM
Thank you so much for providing the script example. It worked perfect!
02-24-2020 10:47 PM
Hi dstaudt,
I've gone through your script and I wanted to ask you one thing, Is it possible to update MRGL field using update device pool script ?
Also have you managed to get add route pattern script working using zeep or ciscoaxl.
I tried all possible options with ciscoaxl library but no success so far :(
Please help if you managed to add route pattern using python script.
Vikas
02-25-2020 10:51 AM
Added samples to cover add/update Device Pool MRGL and add Route Pattern: https://github.com/CiscoDevNet/axl-python-zeep-samples
02-25-2020 09:09 PM
Hi dstaudt,
Your script worked perfect.
Thank You very much.
+5
Regards,
Vikas
08-26-2020 06:13 AM
Hi dstaudt,
Two questions please.
1. Anything changed in update device pool part of code ? I want to update my MRGL using update device pool code and somehow it is not working with below error.
173 name = 'DP-'+name+'-IPT', --> 174 mediaResourceListName = 'MRGL-'+name
NameError: name 'Fault' is not defined
2. Do we've any option to perform bulk jobs using this or any other lib ?
I want to insert phones, update users, etc jobs.
Please help.
Thanks.
Vikas
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