• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Rowell Dionicio

Get Techie With It

  • Home
  • About
  • Resources
    • Archives
    • Book List
    • YouTube
  • Learn
    • DevNet Associate
    • PCNSA Certified
  • Blog
  • Contact
  • Show Search
Hide Search

python

Listing Cisco DNA Center Devices Using the API (DevNet)

November 19, 2020 By Rowell 6 Comments

DNA Center (DNAC) is an essential component of Cisco’s intent-based networking. It serves as the central point for network management and network provisioning. There are different functions of DNA Center such as network assurance which provides you with the overall health of the network. 

Included with DNA Center are APIs for further extensibility and network automation. DNAC’s capabilities include intent and integration APIs. 

Intent APIs provide a method of access to automation and assurance workflows. These actions can include configuring interfaces consistently across network devices or configuring security policies network wide.

Integration APIs integrate other applications with DNA Center such as a ticket system or change management and approvals through WebEx Teams.

DNA Center and DevNet Associate Objective

An objective of the DevNet Associate is to construct code to obtain a list of network devices using DNA Center. 

But don’t worry if you don’t have access to DNA Center. We have the DevNet Sandbox to help us out. 

DNA Center Always-On Lab

The DevNet Sandbox is perfect for learning how to use Python against the DNA Center lab. All the information is located on https://developer.cisco.com.

But here are the details of the DNA Center lab environment:

Server URL: https://sandboxdnac.cisco.com
username: devnetuser
password: Cisco123!

Start in Postman

We’ll begin in Postman to interact with DNA Center. Because DNA Center API uses token-based authentication we need to generate a token. This token will be used for our API calls. 

Taking a look at the DNA Center API, we create our token by creating a POST method using the URL, https://sandboxdnac.cisco.com/dna/system/api/v1/auth/token. 

We must add our authentication token to the header, which I grabbed from the DevNet Sandbox. Click on Headers and create an Authorization key with the value of Basic ZGV2bmV0dXNlcjpDaXNjbzEyMyE=

Once you click on Send your should get a response containing our token.

Save that token because we’ll need to include it in our GET requests.

We need to browse the DNA Center API documentation to find out how we’re going to list the devices. Conveniently, there’s an API call just for retrieving the device list.

With Postman, we’ll create a GET request to the url based on the API documentation for getting the device list. That URL is https://sandboxdnac.cisco.com/dna/intent/api/v1/network-device.

Before sending the request, we must add our token to the header. Add a new key, X-AUTH-TOKEN, and paste the token from earlier into the Value field.

The response from DNA Center lists the devices in a pretty JSON format. We can start constructing our Python script with our current scenario by clicking on Code and copying the generated code to Atom.

Python Script

In Atom, we’re going to import the json library. I’m going to take the response and deserialize it so we can get it in json format. This is a method  I’ve learned in previous lessons from DevNet labs. 

The response we receive from DNA Center is a dictionary. We have a key, response, with a value of all the data we need, which is contained in a list. I’m going to pass that value into its own variable with an intent to iterate through the list.

Now that we have our data in a list, I can iterate through the data and create a list of all the devices in DNA Center with a for loop.

import requests
import json

# API URL TO GET A LIST OF NETWORK DEVICES
url = "https://sandboxdnac.cisco.com/dna/intent/api/v1/network-device"

payload = {}

# WE MUST ADD OUR AUTHENTICATION TOKEN TO THE HEADERS
headers = {
    'X-Auth-Token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI1ZTlkYmI3NzdjZDQ3ZTAwNGM2N2RkMGUiLCJhdXRoU291cmNlIjoiaW50ZXJuYWwiLCJ0ZW5hbnROYW1lIjoiVE5UMCIsInJvbGVzIjpbIjVkYzQ0NGQ1MTQ4NWM1MDA0YzBmYjIxMiJdLCJ0ZW5hbnRJZCI6IjVkYzQ0NGQzMTQ4NWM1MDA0YzBmYjIwYiIsImV4cCI6MTYwNTA1MjYzOSwiaWF0IjoxNjA1MDQ5MDM5LCJqdGkiOiI3MmM5ZDY0Yy0xNjBhLTRlYzAtYTJmYi1mMzQyOGJlY2I4N2QiLCJ1c2VybmFtZSI6ImRldm5ldHVzZXIifQ.GCiuhxuWOPFmqjFSa6PRnqztDlGTTAjV22HdinMY27CAGAelCRcZx1sw9idhzesv538cIFx6XxHdffipIroBGu-a1IG0L6YRnECsMYBG4F_uDLuXPSgXJfZ0hkXB6qawXdtLJtzB9-bQ7hXAn9H_EdD_fW5nX7znTKImuiik70xMo9P0Rb2bOUPn7h0qT6hmwGfa7IMwk11sU-UBm73vt8-c6-2bqWBGiP2DcOcD_r6sIwpUPX4Go9B2fmA5AV4O5Aepa2sMVIfSYrRZv9FP1YwejbOXPq1mck_h31J1nRki8iRwgfTk0n0QoLNgvO2KVPTIxQQqe6rbEHrZYqFiMg'
 }
 
response = requests.request("GET", url, verify=False, headers=headers, data=payload)

# TAKE THE RESPONSE AND TURN IT INTO PYTHON OBJECTS
raw_output = json.loads(response.text)

# raw_output IS A DICTIONARY. TAKE THE VALUE OF response AND ASSIGN TO devices
devices = raw_output["response"]
 
# ITERATE THROUGH THE LIST TO PRINT OUT HOSTNAMES OF DEVICES
for device in devices:
    print("Hostname: {}".format(device["hostname"]))

Python – Basic API Access with Mist Wi-Fi

November 17, 2020 By Rowell Leave a Comment

The Mist access points were designed with API first. The information you’re able to retrieve from their API is quite impressive. It’s enough for you to build your own dashboard, if you dare to take that leap.

The Mist API architecture is simple. It starts with the REST API client, which in this example, is my computer running a script. That request is made via HTTPS to the Mist cloud and processed. In return, the Mist API sends a response.

https://www.mist.com/documentation/mist-api-architecture/

Here’s a simple script that makes a request for the WLANs I have enabled. I then print it out the result to screen.

import json
import requests

site_id = '<your-site-id>'
url = "https://api.mist.com/api/v1/sites/{}/wlans".format(site_id)

headers = {
  'Authorization': 'Token <your-token>'
}

response = requests.request("GET", url, headers=headers)
r = json.loads(response.text)

for wlans in r:
    wlan_name = wlans['ssid']
    wlan_enabled = str(wlans['enabled'])
    wlan_vlan = str(wlans['vlan_id'])
    print("SSID: " + wlan_name, "\t Enabled: " + wlan_enabled, "\t VLAN: " + wlan_vlan )

Here is the output:

% python3 get_wlans.py
SSID: D-NET  Enabled: True 	 VLAN: 2
SSID: CTS 	 Enabled: True 	 VLAN: 2

Listing Meraki Network Devices Using the API (DevNet)

November 11, 2020 By Rowell Leave a Comment

Starting with the basics of network automation involves learning how to construct code. The DevNet Associate will test against your ability to perform this task. 

In this example, I will leverage the Meraki API in order to get a list of devices part of a network within an Organization.

Anyone can get started with this as Meraki provides a DevNet Sandbox for people to test their Python capabilities. 

I’ll be using just three things for this lab:

  • Postman
  • Meraki Sandbox
  • Atom

Postman will help us construct our script with ease. By exploring the API with Postman, we can see which API to use that will give us the results we require. Atom is my text editor of choice.

When writing the script, we’ll eventually need to include a few libraries. Here’s what we’ll be using:

Libraries

  • Requests
  • json

The requests library is exactly how we’re going to make our request to the Meraki API. We want to request a list of devices from a network that is part of an organization.

When we make the request, we’ll get data in return and it will be in json format. We need a way to work with that json data and that’s wha the json library is for.

Meraki has their API documented very well. If our goal is to get a list of devices then we simply need to find which API call needs to be made.

There is a GET request called getNetworkDevices and we’re given the URL needed to make that request. 

From that URL, we need to pass a network ID. To find the network ID we can list all networks in an organization. 

To make a request to the Meraki API, we need to provide an API key. In this example, the API key being used was provided by Meraki from their own examples.

We have a variable defined which will contain the GET response of our request.

I’ll pass the variable into the json library and decode it into a Python object which will be a list in this case. We can tell this is a list if we pass devicesXML into the type function.

Now that we have our data in a Python object, we an iterate through it. This is where we tackle the core objective of listing devices in Meraki. We’ll do this with a for loop.

import requests
import json

url = "https://api.meraki.com/api/v1/networks/L_646829496481105433/devices"

payload = {}
headers = {
     'X-Cisco-Meraki-API-Key': '093b24e85df15a3e66f1fc359f4c48493eaa1b73'
 }

response = requests.request("GET", url, headers=headers, data=payload)

allDevices = json.loads(response.text)

for device in allDevices:
    print("Model: {} \t Serial: {}".format(device["model"], device["serial"]))

The output:

% python3 getDevices.py
Model: MX65      Serial: Q2QN-9J8L-SLPD
Model: MS220-8P      Serial: Q2HP-F5K5-R88R
Model: MR53      Serial: Q2MD-BHHS-5FDL

Python – Parsing Cisco AireOS Configuration

February 21, 2020 By Rowell Leave a Comment

I’m beginning to get the hang of Python and it’s capabilities with network operations/monitoring.

My good friend and co-host on the CTS Podcast, François Vergès, has been creating his own scripts to help automate some of the operational tasks he does with Cisco AireOS WLAN controllers.

There was a scenario where I wanted to gather the operating channel and transmit power of a specific number of access points joined to a Cisco 8540 controller.

We can simply look at this via the management GUI or create some sort of Cisco Prime report but I just wanted a simple CLI output.

Cisco AireOS has a CLI command to get this output for the 2.4 GHz and 5 GHz radio:

show advanced 802.11a|b summary

The result of the command is every single access point on the controller but I just wanted a subset of those access points. That’s where I need to match a specific pattern based on the access point name using REGEX.

With this script, I am using Python 3.7 with the Regular expression operations library and netmiko library.

François was able to point me in the right direction with using the ConnectHandler to create a my connection and send the command to the WLAN controller:

import re
from netmiko import ConnectHandler

with ConnectHandler(
    ip = 'big-wlan-controller',
    port = 22,
    username = 'admin',
    password = 'test123',
    device_type = 'cisco_wlc_ssh'
) as ch:

    output = ch.send_command("show advanced 802.11a summary")

The full output of the command is placed into a variable called output.

Now, I wanted to use REGEX to match on specific access points. I create a pattern and use a for loop on each line in the variable of output.

pattern = re.compile("b2", re.IGNORECASE)
for ap in output.splitlines():
    if pattern.search(ap) != None:
        print(ap)

In the pattern variable I am using REGEX to simply search for anything containing “b2” which stands for Building 2 in my scenario.

In the for loop, I am taking the output variable and splitting the string by line and applying the pattern search per line. Then I print the output to the screen.

The full script:

import re
from netmiko import ConnectHandler

with ConnectHandler(
    ip = 'big-wlan-controller',
    port = 22,
    username = 'admin',
    password = 'test123',
    device_type = 'cisco_wlc_ssh'
) as ch:

    output = ch.send_command("show advanced 802.11a summary")

pattern = re.compile("b2", re.IGNORECASE)
for ap in output.splitlines():
    if pattern.search(ap) != None:
        print(ap)

The output (sanitized):

$ python regex-test.py
b2-ap-1                     xx:xx:xx:xx:xx:xx  1   ENABLED  UP          (108,112)           3/6 (11 dBm)
b2-ap-2                     xx:xx:xx:xx:xx:xx  1   ENABLED  UP          (100,104,108,112)  *1/7 (19 dBm)
b2-ap-3                     xx:xx:xx:xx:xx:xx  1   ENABLED  UP          52*                *1/6 (17 dBm)
b2-ap-4                     xx:xx:xx:xx:xx:xx  1   ENABLED  UP          36*                *2/5 (12 dBm)
b2-ap-5                     xx:xx:xx:xx:xx:xx  1   ENABLED  UP          136*               *1/6 (17 dBm)

From the output I can see the AP name, MAC address of the AP, up/down status, operating channel, and transmit power. There’s a bit more work to put into the script but it gave me exactly what I needed at the time.

Parsing XML with Python Minidom

November 29, 2019 By Rowell 1 Comment

A core skill for a DevNet associate is being knowledgeable of how to parse XML into a Python structure.

Data can be retrieved from devices using different data structures such as XML, YAML, or JSON.

In this lab, I’ll look at parsing XML into a useable structure within Python.

First step is to use a Python script to send an HTTP request to our device so we can obtain data which will be returned in XML format.

Cisco provides us with a sandbox to test with using this Python script through their Coding 201 Parsing XML lab. I’ve had to modify it a little to ensure I can ignore the certificate verification. And I had to select another Sandbox due to authorization issues.

from urllib.request import Request, urlopen
import ssl 

req = Request('https://msesandbox.cisco.com/api/contextaware/v1/maps/info/DevNetCampus/DevNetBuilding/DevNetZone')
req.add_header('Authorization', 'Basic bGVhcm5pbmc6bGVhcm5pbmc==')

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

r = urlopen(req, context=ctx)
rString = r.read().decode("utf-8")

print(rString)
r.close()

The following is the output from our UGLY request:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Floor objectVersion="19" name="DevNetZone" isOutdoor="false" floorNumber="1" floorRefId="723413320329068590"><Dimension length="81.9" width="307.0" height="16.5" offsetX="0.0" offsetY="0.0" unit="FEET"/><Image imageName="domain_0_1421088463647.png"/><GPSMarker name="GPS_Marker_17"><GeoCoordinate latitude="36.125859" longitude="-97.066969" unit="DEGREES"/><MapCoordinate x="0.6" y="0.6" unit="FEET"/></GPSMarker><GPSMarker name="GPS_Marker_18"><GeoCoordinate latitude="36.125859" longitude="-97.06595" unit="DEGREES"/><MapCoordinate x="299.77" y="0.6" unit="FEET"/></GPSMarker><GPSMarker name="GPS_Marker_19"><GeoCoordinate latitude="36.125641" longitude="-97.066969" unit="DEGREES"/><MapCoordinate x="0.6" y="80.09" unit="FEET"/></GPSMarker><AccessPoint name="T1-3" radioMacAddress="00:2b:01:00:04:00" ethMacAddress="00:2b:01:00:04:f0" ipAddress="10.10.20.243" numOfSlots="2" apMode="LOCAL"><MapCoordinate x="155.28" y="57.57" unit="FEET"/><ApInterface band="IEEE_802_11_B" slotNumber="0" channelAssignment="1" channelNumber="1" txPowerLevel="1" antennaPattern="Internal-1140-2.4GHz" antennaAngle="1.57" 
**TRUNCATED**

As I’ve described in a previous post, XML is just another data structure. It’s commonly used in other network equipment such as Juniper and Palo Alto Networks.

In order to parse XML data we will need to import a library. There are two libraries we can use, but in this post we’ll look at Minidom:

  • Minidom
  • ElementTree

Parsing XML with Minidom

Minidom is a Python library called Minimal DOM. It’s a minimal implementation of the Document Object Model interface.

To import the library just add the following to the top of the script:

import xml.dom.minidom

Now we modify our script so we can parse the returned XML data.

We’ll add the following lines:

xmlparse = xml.dom.minidom.parseString(rString)
prettyxml = xmlparse.toprettyxml()
print(prettyxml)

The parse() function in xml.dom.minidom.parseString(rString) to parse out the XML data and assign it to xmlparse.

Next, we use a DOM function to pass xmlparse into toprettyxml to make a pretty-printed version of the XML output we just saw.

The following output now looks more readable. We can see the root node, nests, etc.:

<?xml version="1.0" ?>
<Floor floorNumber="1" floorRefId="723413320329068590" isOutdoor="false" name="DevNetZone" objectVersion="19">
    <Dimension height="16.5" length="81.9" offsetX="0.0" offsetY="0.0" unit="FEET" width="307.0"/>
    <Image imageName="domain_0_1421088463647.png"/>
    <GPSMarker name="GPS_Marker_17">
        <GeoCoordinate latitude="36.125859" longitude="-97.066969" unit="DEGREES"/>
        <MapCoordinate unit="FEET" x="0.6" y="0.6"/>
    </GPSMarker>
    <GPSMarker name="GPS_Marker_18">
        <GeoCoordinate latitude="36.125859" longitude="-97.06595" unit="DEGREES"/>
        <MapCoordinate unit="FEET" x="299.77" y="0.6"/>
    </GPSMarker>
    <GPSMarker name="GPS_Marker_19">
        <GeoCoordinate latitude="36.125641" longitude="-97.066969" unit="DEGREES"/>
        <MapCoordinate unit="FEET" x="0.6" y="80.09"/>
    </GPSMarker>
    <AccessPoint apMode="LOCAL" ethMacAddress="00:2b:01:00:04:f0" ipAddress="10.10.20.243" name="T1-3" numOfSlots="2" radioMacAddress="00:2b:01:00:04:00">
        <MapCoordinate unit="FEET" x="155.28" y="57.57"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="0" antennaPattern="Internal-1140-2.4GHz" band="IEEE_802_11_B" channelAssignment="1" channelNumber="1" slotNumber="0" txPowerLevel="1"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="11" antennaPattern="Internal-1140-5.0GHz" band="IEEE_802_11_A" channelAssignment="1" channelNumber="64" slotNumber="1" txPowerLevel="5"/>
    </AccessPoint>
    <AccessPoint apMode="LOCAL" ethMacAddress="00:2b:01:00:05:f0" ipAddress="10.10.20.244" name="T1-4" numOfSlots="2" radioMacAddress="00:2b:01:00:05:00">
        <MapCoordinate unit="FEET" x="213.6" y="12.6"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="0" antennaPattern="Internal-1140-2.4GHz" band="IEEE_802_11_B" channelAssignment="1" channelNumber="1" slotNumber="0" txPowerLevel="1"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="11" antennaPattern="Internal-1140-5.0GHz" band="IEEE_802_11_A" channelAssignment="1" channelNumber="64" slotNumber="1" txPowerLevel="5"/>
    </AccessPoint>
    <AccessPoint apMode="LOCAL" ethMacAddress="00:2b:01:00:06:f0" ipAddress="10.10.20.245" name="T1-5" numOfSlots="2" radioMacAddress="00:2b:01:00:06:00">
        <MapCoordinate unit="FEET" x="253.7" y="58.48"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="0" antennaPattern="Internal-1140-2.4GHz" band="IEEE_802_11_B" channelAssignment="1" channelNumber="1" slotNumber="0" txPowerLevel="1"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="11" antennaPattern="Internal-1140-5.0GHz" band="IEEE_802_11_A" channelAssignment="1" channelNumber="64" slotNumber="1" txPowerLevel="5"/>
    </AccessPoint>
    <AccessPoint apMode="LOCAL" ethMacAddress="00:2b:01:00:03:f0" ipAddress="10.10.20.242" name="T1-2" numOfSlots="2" radioMacAddress="00:2b:01:00:03:00">
        <MapCoordinate unit="FEET" x="98.1" y="11.7"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="0" antennaPattern="Internal-1140-2.4GHz" band="IEEE_802_11_B" channelAssignment="1" channelNumber="1" slotNumber="0" txPowerLevel="1"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="11" antennaPattern="Internal-1140-5.0GHz" band="IEEE_802_11_A" channelAssignment="1" channelNumber="64" slotNumber="1" txPowerLevel="5"/>
    </AccessPoint>
    <AccessPoint apMode="LOCAL" ethMacAddress="00:2b:01:00:02:f0" ipAddress="10.10.20.241" name="T1-1" numOfSlots="2" radioMacAddress="00:2b:01:00:02:00">
        <MapCoordinate unit="FEET" x="43.9" y="57.88"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="0" antennaPattern="Internal-1140-2.4GHz" band="IEEE_802_11_B" channelAssignment="1" channelNumber="1" slotNumber="0" txPowerLevel="1"/>
        <ApInterface antennaAngle="1.57" antennaElevAngle="0.0" antennaGain="11" antennaPattern="Internal-1140-5.0GHz" band="IEEE_802_11_A" channelAssignment="1" channelNumber="64" slotNumber="1" txPowerLevel="5"/>
    </AccessPoint>
    <LocationFilterRegion regionType="OUTSIDE">
        <MapCoordinate unit="FEET" x="0.0" y="0.0"/>
        <MapCoordinate unit="FEET" x="307.0" y="0.0"/>
        <MapCoordinate unit="FEET" x="307.0" y="81.9"/>
        <MapCoordinate unit="FEET" x="0.0" y="81.9"/>
    </LocationFilterRegion>
</Floor>

Now that we have our request we need to identify what we’re looking for. I want to get information about access points.

I do see a sub-object, AccessPoint, which contains attributes of the access point element:

<AccessPoint apMode="LOCAL" ethMacAddress="00:2b:01:00:03:f0" ipAddress="10.10.20.242" name="T1-2" numOfSlots="2" radioMacAddress="00:2b:01:00:03:00"></AccessPoint>

Let’s grab information on each the access point’s elements of name, ethMacAddress, and ipAddress.

Time to parse through the XML data and get only what we need.

access_points = xmlparse.getElementsByTagName('AccessPoint')
for access_point in access_points:
    ap_name = access_point.getAttribute('name')
    ap_mac = access_point.getAttribute('ethMacAddress')
    ap_ip = access_point.getAttribute('ipAddress')
    print(access_point.tagName + ': ' + ap_name + '\t mac: ' + ap_mac + '\t ip: '+ ap_ip)

What does this do?

Let’s analyze what each line does 🤔

access_points = xmlparse.getElementsByTagName('AccessPoint') – With minidom it is possible to walk through each child node tree. That’s what we’re doing here with xmlparse.getElementsByTagName(‘AccessPoint’). We’re going to find each child of the name AccessPoint.

Next we’ll get into a for loop to cycle through any of the child nodes we’re looking for. In this case, AccessPoint.

Within the for loop there are three variables: ap_name, ap_mac, and ap_ip.

We’re going to use a Minidom element object, getAttribute, to return the value of the attribute named.

access_point.getAttribute(‘name’) – Through each child node with a tag of AccessPoint we want it to return the Name of that access point and assign that value in ap_name.

access_point.GetAttribute(‘ethMacAddress’) – We’re going to return the MAC Address of the access point under the tag of ethMacAddress, if it exists, and assign it to ap_mac.

access_point.getAttribute(‘ipAddress’) – The next attribute I want to collect is the IP address. If returned, it will be assigned to ap_ip.

Next, I want to visualize that information on the screen. With the print statement, print(access_point.tagName + ': ' + ap_name + '\t mac: ' + ap_mac + '\t ip: '+ ap_ip), we’re going to display some of the attributes we found.

The output is much more appealing now:

% python parsing_xml_with_python.py
AccessPoint: T1-3     mac: 00:2b:01:00:04:f0  ip: 10.10.20.243
AccessPoint: T1-4     mac: 00:2b:01:00:05:f0  ip: 10.10.20.244
AccessPoint: T1-5     mac: 00:2b:01:00:06:f0  ip: 10.10.20.245
AccessPoint: T1-2     mac: 00:2b:01:00:03:f0  ip: 10.10.20.242
AccessPoint: T1-1     mac: 00:2b:01:00:02:f0  ip: 10.10.20.241

Final Script

from urllib.request import Request, urlopen
import ssl
import xml.dom.minidom

req = Request('https://msesandbox.cisco.com/api/contextaware/v1/maps/info/DevNetCampus/DevNetBuilding/DevNetZone')
req.add_header('Authorization', 'Basic bGVhcm5pbmc6bGVhcm5pbmc==')

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

r = urlopen(req, context=ctx)
rString = r.read().decode("utf-8")

#print(rString)

xmlparse = xml.dom.minidom.parseString(rString)
prettyxml = xmlparse.toprettyxml()
#print(prettyxml)

access_points = xmlparse.getElementsByTagName('AccessPoint')
for access_point in access_points:
	ap_name = access_point.getAttribute('name')
	ap_mac = access_point.getAttribute('ethMacAddress')
	ap_ip = access_point.getAttribute('ipAddress')
	print(access_point.tagName + ': ' + ap_name + '\t mac: ' + ap_mac + '\t ip: '+ ap_ip)

r.close()

Final Thoughts

I just went through parsing XML data using Python’s Minidom library. I thought it was straightforward with Python’s documentation clearly defining not just Minidom but also the Element Objects.

The Element Object of Element.getAttribute helps us narrow down all the XML data to just the data we need (parsing).

Now, I’d like to try to figure out how I can do this against my Cisco C9800-CL

  • Go to page 1
  • Go to page 2
  • Go to page 3
  • Go to Next Page »

Primary Sidebar

Recent Posts

  • Passed Palo Alto Networks Certified Security Administrator (PCNSA)
  • 5 Years Running
  • Q4 2021 and Yearly Income Report
  • I PASSED JNCIA-MistAI
  • Admins and Role-Based Access Control – PCNSA

Categories

  • bschool
  • Certifications
  • Coding
  • DevNet Associate
  • Events
  • Lab
  • Networking
  • Personal
  • Podcasting
  • Professional
  • Reviews
  • Security
  • Short Stories
  • Uncategorized
  • Wireless

Archives

  • May 2022
  • January 2022
  • December 2021
  • November 2021
  • August 2021
  • July 2021
  • April 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • August 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • November 2018
  • September 2018
  • August 2018

Copyright © 2022 · Written by Rowell Dionicio · You're awesome.

 

Loading Comments...