In my previous posts about the ArubaOS API, I’ve given a general framework for pulling data from the AOS Mobility Conductor or a Mobility Controller. Today I’m going to show how to retrieve the AP database and dump it into a CSV file which you can then open in Excel or anything else and work all kinds of magic (yes, I know, Excel is not a database engine, but it still works rather well with tabular data)
The long-form AP database command (show ap database long) provides lots of useful information about the APs in the system:
- AP Name
- AP Group
- AP Model
- AP IP Address
- Status (and uptime if it’s up)
- Flags
- Switch IP (primary AP Anchor Controller)
- Standby IP (standby AAC)
- AP Wired MAC Address
- AP Serial #
- Port
- FQLN
- Outer IP (Public IP when it is a RAP)
- User
This script will take the human-readable uptime string (“100d:12h:34m:28s”) and convert that to seconds so uptime can be sorted in your favorite spreadsheet. It will also create a grid of all the AP flags so that you can sort/filter on those after converting the CSV to a data table.
The code is extensively commented so you should be able to follow along. Also available on github.
#!/usr/bin/python3
# ArubaOS 8 AP Database to CSV output via API call
# (c) 2021 Ian Beyer, Aruba Networks <canerdian@hpe.com>
# This code is provided as-is with no warranties. Use at your own risk.
import requests
import json
import csv
import sys
import warnings
import sys
import xmltodict
import datetime
aosDevice = "1.2.3.4"
username = "admin"
password = "password"
httpsVerify = False
outfile="outputfilename.csv"
#Set things up
if httpsVerify == False :
warnings.filterwarnings('ignore', message='Unverified HTTPS request')
baseurl = "https://"+aosDevice+":4343/v1/"
headers = {}
payload = ""
cookies = ""
session=requests.Session()
## Log in and get session token
loginparams = {'username': username, 'password' : password}
response = session.get(baseurl+"api/login", params = loginparams, headers=headers, data=payload, verify = httpsVerify)
jsonData = response.json()['_global_result']
if response.status_code == 200 :
#print(jsonData['status_str'])
sessionToken = jsonData['UIDARUBA']
else :
sys.exit("Login Failed")
reqParams = {'UIDARUBA':sessionToken}
def showCmd(command, datatype):
showParams = {
'command' : 'show '+command,
'UIDARUBA':sessionToken
}
response = session.get(baseurl+"configuration/showcommand", params = showParams, headers=headers, data=payload, verify = httpsVerify)
if datatype == 'JSON' :
#Returns JSON
returnData=response.json()
elif datatype == 'XML' :
# Returns XML as a dict
returnData = xmltodict.parse(response.content)['my_xml_tag3xxx']
elif datatype == 'Text' :
# Returns an array
returnData =response.json()['_data']
return returnData
apdb=showCmd('ap database long', 'JSON')
# This is the list of status flags in 'show ap database long'
apflags=['1','1+','1-','2','B','C','D','E','F','G','I','J','L','M','N','P','R','R-','S','U','X','Y','c','e','f','i','o','s','u','z','p','4']
# Create file handle and open for write.
with open(outfile, 'w') as csvfile:
write=csv.writer(csvfile)
# Get list of data fields from the returned list
fields=apdb['_meta']
# Add new fields for parsed Data
fields.insert(5,"Uptime")
fields.insert(6,"Uptime_Seconds")
# Add fields for expanding flags
for flag in apflags:
fields.append("Flag_"+flag)
write.writerow(fields)
# Iterate through the list of APs
for ap in apdb["AP Database"]:
# Parse Status field into status, uptime, and uptime in seconds
utseconds=0
ap['Uptime']=""
ap['Uptime_Seconds']=""
# Split the status field on a space - if anything other than "Up", it will only contain one element, first element is status description.
status=ap['Status'].split(' ')
ap['Status']=status[0]
# Additional processing of the status field if the AP is up as it will report uptime in human-readable form in the second half of the Status field we just split
if len(status)>1:
ap['Uptime']=status[1]
#Split the Uptime field into each time field and strip off the training character, multiply by the requisite number of seconds an tally it up.
timefields=status[1].split(':')
# If by some stroke of luck you have an AP that's been up for over a year, you might have to add a row here - I haven't seen how it presents it in that case
if len(timefields)>3 :
days=int(timefields.pop(0)[0:-1])
utseconds+=days*86400
if len(timefields)>2 :
hours=int(timefields.pop(0)[0:-1])
utseconds+=hours*3600
if len(timefields)>1 :
minutes=int(timefields.pop(0)[0:-1])
utseconds+=minutes*60
if len(timefields)>0 :
seconds=int(timefields.pop(0)[0:-1])
utseconds+=seconds
ap['Uptime_Seconds']=utseconds
# FUN WITH FLAGS
# Bust apart the flags into their own fields
for flag in apflags:
# Set field to None so that it exists in the dict
ap["Flag_"+flag]=None
# Check to see if the flags field contains data
if ap['Flags'] != None :
# Iterate through the list of possible flags and mark that field with an X if present
if flag in ap['Flags'] :
ap["Flag_"+flag]="X"
# Start assembling the row to write out to the CSV, and maintain order and tranquility.
datarow=[]
# Iterate through the list of fields used to create the header row and append each one
for f in fields:
datarow.append(ap[f])
# Put it in the CSV
write.writerow(datarow)
#Move on to the next AP
# Close the file handle
csvfile.close()
## Log out and remove session
response = session.get(baseurl+"api/logout", verify=False)
jsonData = response.json()['_global_result']
if response.status_code == 200 :
#remove
token = jsonData['UIDARUBA']
del sessionToken
else :
del sessionToken
sys.exit("Logout failed:")
The human-readable output of the show ap database gives you a list of what the flags are, but the API call does not, so in case you want a handy reference, here it is in JSON format so that you can easily adapt it. (Github)
sheldon={
'1':'802.1x authenticated AP use EAP-PEAP',
'1+':'802.1x use EST',
'1-':'802.1x use factory cert',
'2':'Using IKE version 2',
'B':'Built-in AP',
'C':'Cellular RAP',
'D':'Dirty or no config',
'E':'Regulatory Domain Mismatch',
'F':'AP failed 802.1x authentication',
'G':'No such group',
'I':'Inactive',
'J':'USB cert at AP',
'L':'Unlicensed',
'M':'Mesh node',
'N':'Duplicate name',
'P':'PPPoe AP',
'R':'Remote AP',
'R-':'Remote AP requires Auth',
'S':'Standby-mode AP',
'U':'Unprovisioned',
'X':'Maintenance Mode',
'Y':'Mesh Recovery',
'c':'CERT-based RAP',
'e':'Custom EST cert',
'f':'No Spectrum FFT support',
'i':'Indoor',
'o':'Outdoor',
's':'LACP striping',
'u':'Custom-Cert RAP',
'z':'Datazone AP',
'p':'In deep-sleep status',
'4':'WiFi Uplink'
}
I don’t know how much time I spend doing show ap database > coping to excel and then having to clean up the data. Thanks for sharing. This script looks great.
I’m getting the error (both the ap database script and the ArubaOS API: Reading Data script. Any idea why the connection is refused? Do I need to enable the API?
No connection could be made because the target machine actively refused it
I’ve recently tweaked an updated version that will take the CLI outputs and dump them into an excel named table directly. I haven’t done the API integration on it yet, but if you can’t get the API to work (it should work without any additional config on the controller), you can try this approach.
https://github.com/canerdianeh/aruba-campus/blob/main/controller_data_to_xl.py