N-central API with Python

N-central API with Python

If you’ve found yourself here you need to do something with N-central’s API, you poor soul.

After looking at the docs for the API (https://(domain|your_tenant)/dms/javadoc_ei2/index-all.html) you’ve probably thought to yourself (wtf? those aren’t useful API docs). Maybe you reached out to N-central support, they referred you back to “docs”.

Now you’ve taken to the web to try and figure it out. You probably, just like me, found a bunch of stuff on StackOverflow, Reddit, and Github though nothing in Python that works.

Welp, here’s my working source code buckeroo! Hopefully you can take it and make it better.

Note: This will not be an in-depth deep drive into N-central’s API, rather I’m just going to show the code for what I had to do and you can try to decipher the rest of the APIs on your own (good luck, and please put links in the comments).

Firstly, you need to make a user for your API calls: make sure this user doesn’t have MFA, and has the lowest permissions necessary for your script to do it’s thing (e.g. RO). Security in layers and all that jazz.

I’ll be using Python 2.7.15 in my example, but the zeep module is available for Python3 as well.

#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)

Voila! There you have it after much brute forcing and fiddling around with the API. I was able to use it to make a full inventory dump of all nodes in our N-central tenant.

Comments are closed.