Python - Error querying Solarwinds N-Central via SOAP

Viewed 782

I'm using python 3 to write a script that generates a customer report for Solarwinds N-Central. The script uses SOAP to query N-Central and I'm using zeep for this project. While not new to python I am new to SOAP.

When calling the CustomerList fuction I'm getting the TypeError: __init__() got an unexpected keyword argument 'listSOs'

import zeep

wsdl = 'http://' + <server url> + '/dms/services/ServerEI?wsdl'
client = zeep.CachingClient(wsdl=wsdl)

config = {'listSOs': 'true'}

customers = client.service.CustomerList(Username=nc_user, Password=nc_pass, Settings=config)

Per the perameters below 'listSOs' is not only a valid keyword, its the only one accepted.

CustomerList

public com.nable.nobj.ei.Customer[] CustomerList(String username, String password, com.nable.nobj.ei.T_KeyPair[] settings) throws RemoteException

Parameters:

  • username - MSP N-central username
  • password - Corresponding MSP N-central password
  • settings - A list of non default settings stored in a T_KeyPair[]. Below is a list of the acceptable Keys and Values. If not used leave null
    • (Key) listSOs - (Value) "true" or "false". If true only SOs with be shown, if false only customers and sites will be shown. Default value is false.

I've also tried passing the dictionary as part of a list:

config = []
key = {'listSOs': 'true'}
config += key

TypeError: Any element received object of type 'str', expected lxml.etree._Element or builtins.dict or zeep.objects.T_KeyPair

Omitting the Settings value entirely:

customers = client.service.CustomerList(Username=nc_user, Password=nc_pass)

zeep.exceptions.ValidationError: Missing element Settings (CustomerList.Settings)

And trying zeep's SkipValue:

customers = client.service.CustomerList(Username=nc_user, Password=nc_pass, Settings=zeep.xsd.SkipValue)

zeep.exceptions.Fault: java.lang.NullPointerException

I'm probably missing something simple but I've been banging my head against the wall off and on this for awhile I'm hoping someone can point me in the right direction.

1 Answers

Here's my source code from my getAssets.py script. I did it in Python2.7, easily upgradeable though. Hope it helps someone else, N-central's API documentation is really bad lol.

#pip2.7 install zeep
import zeep, sys, csv, copy
from zeep import helpers

api_username = 'your_ncentral_api_user'
api_password='your_ncentral_api_user_pw'

wsdl = 'https://(yourdomain|tenant)/dms2/services2/ServerEI2?wsdl'
client = zeep.CachingClient(wsdl=wsdl)

response = client.service.deviceList(
    username=api_username,
    password=api_password,
    settings=
    {
        'key': 'customerId',
        'value': 1
    }
)

# If you can't tell yet, I code sloppy

devices_list = []
device_dict = {}
dev_inc = 0
max_dict_keys = 0
final_keys = []

for device in response:
    # Iterate through all device nodes
    for device_properties in device.items:
        # Iterate through each device's properties and add it to a dict (keyed array)
        device_dict[device_properties.first]=device_properties.second

    # Dig further into device properties
    device_properties = client.service.devicePropertyList(
        username=api_username,
        password=api_password,
        deviceIDs=device_dict['device.deviceid'],
        reverseOrder=False
    )

    prop_ind = 0 # This is a hacky thing I did to make my CSV writing work
    for device_node in device_properties:
        for prop_tree in device_node.properties:
            for key, value in helpers.serialize_object(prop_tree).items():
                prop_ind+=1
                device_dict["prop" + str(prop_ind) + "_" + str(key)]=str(value)

    # Append the dict to a list (array), giving us a multi dimensional array, you need to do deep copy, as .copy will act like a pointer
    devices_list.append(copy.deepcopy(device_dict))

    # check to see the amount of keys in the last item
    if len(devices_list[-1].keys()) > max_dict_keys:
        max_dict_keys = len(devices_list[-1].keys())
        final_keys = devices_list[-1].keys()

print "Gathered all the datas of N-central devices count: ",len(devices_list)

# Write the data out to a CSV
with open('output.csv', 'w') as csvfile:
    fieldnames = final_keys
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()
    
    for csv_line in devices_list:
        writer.writerow(csv_line)

Related