Getting off the Ground with Python and APIs

By Richard McIntosh, Blog Contributor
Share Post

For years we have been hearing about the value of network programmability, how we should all learn Python, and start automating more of our work. For over 30 years, we as network engineers have been using these antiquated CLI methods of design and implementation.  While we have had some improvements through our NMS or creating prebuilt standard templates to copy and paste configurations from, it hasn’t been until recently that our tasks have been truly able to become automated.

Take the Aruba 8400 core switch running ArubaOS-CX. The team at Aruba built AOS-CX with APIs at the forefront of everything they were doing. These APIs provide flexibility to the operators deploying networks and to the tools they connect with. An example of the flexibility within the 8400 is the use of LXC Containers that can run Python scripts as agents on the same hardware, allowing for real-time access to data for analytics. If a problem is detected using the built-in Network Analytics Engine, the agents can repair the problem automatically.

The API and programmability enhancements have spread to other products within the Aruba ecosystem, ushering in a new era of NetOps. For example, ArubaOS 8 introduced the Swagger interface to the Mobility Controllers, exposing their entire API to administrators and allowing operations to be run right within the browser. All on the controller – without the need to run any special software!

Below is a screenshot taken from the Aruba 7005 controller running ArubaOS within the Swagger interface.  To follow along, if you’re running ArubaOS 8.x, simply go to:  https://<MM-IP>/API

ArubaOS JSON API specifications

From here, we can run any variety of commands to gather information from the controller. Here we are asking the controller to GET the configured SSID Profiles from the configuration. Simply expand the GET request under WLAN and /object/ssid_prof and click Try it out!

Note If you are running a standalone controller, you may have to change the default config_path value from /mm to /mm/mynode.

Get configuration requestAfter clicking the Try it out! function, the window expands to review the requested information in JSON format. The output even gives us the curl syntax and request URL if we wanted to request this output from another system.

Review in JSONNow that we can GET data from the controller, let’s make some changes using the POST method. Using the POST /object/vlan_id option under the controller menu, we can add the JSON information to create a new VLAN. If you click the example schema provided, it will auto-populate the body for easy editing. In this example we are creating VLAN 20.

Make changes via POSTSuccess! If you were to look at the UI or GET the vlan_id you should see the new VLAN has not been added. That is because we need to save configuration, just as we typically would if creating the VLAN from the UI or CLI. For that we run the POST /object/write_memory to save the configuration of the controller.

POST to save the configuration of the controller.Finally, we can perform a GET on /object/vlan_id to verify that our change has been successfully issued.

Perform GET to verify the change.Congratulations! You have just programmed your first change! Let’s bring this change into a single Python script and show the flexibility offered through scripting and programmability.  Grab the full script at my GitHub repository.

In this script we will:

  1. Log into the Aruba 7005 Controller on AOS
  2. Retrieve our UID and cookie values
  3. Display the current VLANs
  4. Create a new VLAN
  5. Save the configuration
  6. Display the updated list of VLANs
import requests
import json
import argparse
from pprint import pprint
import urllib3# Surpress error messages for controllers without SSL certificates
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)parser = argparse.ArgumentParser()
parser.add_argument('--ip', type=str, help="Controller IP address")
parser.add_argument('--user', type=str, help="Username")
parser.add_argument('--password', type=str, help="Password")
parser.add_argument('--vlan', type=str, help="VLAN")
args = parser.parse_args()# Log into Aruba Controller and retrieve UIDARUBA for API access
r = requests.get(url='https://' + args.ip + ':4343/v1/api/login?username=' \
+ args.user +'&password=' + args.password, verify=False)
logindata = r.json()
uid = logindata['_global_result']['UIDARUBA']
cookies = {'SESSION': uid}
print("Our UID for this sessions is: " + uid)# GET API to retrieve what VLANs are active on the controller
print("Retreiving Existing VLAN Information \n")
getvlan_id = requests.get(url="https://" + args.ip + ":4343/v1/configuration/object/vlan_id?config_path=%2Fmm&UIDARUBA=" + uid, verify=False, cookies=cookies)
vlandata = getvlan_id.json()
pprint(vlandata, indent=3)

# POST API to create a new VLAN
print("Creating VLAN: " + args.vlan)
body = {'id': args.vlan}
headers = {'content-type': 'application/json'}
postvlan_id ='https://' + args.ip + ":4343/v1/configuration/object/vlan_id?config_path=%2Fmm&UIDARUBA=" + uid, data=json.dumps(body), headers=headers, verify=False, cookies=cookies)

# POST API to save the configuration
print("Saving Configuration")
w ="https://" + args.ip + ":4343/v1/configuration/object/write_memory?config_path=%2Fmm&UIDARUBA=" + uid, verify=False, cookies=cookies)

# Get API to retrieve the updated VLAN list
print("Retreiving Existing VLAN Information \n")
getvlan_id = requests.get(url="https://" + args.ip + ":4343/v1/configuration/object/vlan_id?config_path=%2Fmm&UIDARUBA=" + uid, verify=False, cookies=cookies)
vlandata = getvlan_id.json()
pprint(vlandata, indent=3)

Using the argsparse module, we can pass arguments from the command line to the Python script. In this command we are saying connect to the controller at using the username of admin with a password of password and that we want to create VLAN 30. I hope you have a more secure password than this for your environment.

Pass arguments from the command line to the Python scriptOnce run, the script will sign into the controller’s API login. Here it will retrieve the UID and cookie values required to run any additional API calls during this session. Be sure to note in the script, a cookie is required along with the UID to be sent. If you only send one or the other the operation will fail, and you will receive a 401 Unauthorized error. The UID and Cookie value are the same but do change at every login.

Script signs into the controller's API Success!  As you can see in the output above, we have successfully connected to our controller and created VLAN 30. We can also confirm this by using the WebUI.

I hope this has helped you see the value in Python and how flexible and powerful you can be with it. If you wish to learn more about Python, I recommend you look into Kirk Byers' Python for Network Engineers course.  Kirk also runs a free Python course via email for those who are just starting out. Likewise, be sure to check out the Aruba GitHub and the Aruba Solutions Exchange for more great tools and scripts.

Read My Other Blogs

Cybersecurity in a Zero Trust Architecture

Intelligent Networks Require Intelligent Solutions

IoT Security and Pre-Shared Keys

Gaining Altitude with Python and APIs