Skip to content

Combining Everything

In this section, we will combine everything we have learned so far into a final project. We will use functions to read and write API data to and from a JSON file.

Step 1: Importing Libraries

import json
from collections import defaultdict
from getpass import getpass
from pprint import pprint

import pandas as pd
import requests
import urllib3

This section imports the necessary libraries. These libraries are used for handling JSON data, creating default dictionaries, securely getting passwords, pretty-printing data, working with data frames, making HTTP requests, and handling SSL warnings.

Step 2: Loading Base URL

def load_base_url(filename):
    with open(filename) as f:
        data = json.load(f)
    return data["base_url"]

BASE_URL = load_base_url("config.json")

This function reads the base URL from a configuration file (config.json). The BASE_URL variable is then set using this function.

Step 3: Creating a Session

def get_cc_session(base_url=BASE_URL, username="devnetuser", password=getpass()):
    auth_url = base_url + "/dna/system/api/v1/auth/token"
    urllib3.disable_warnings()  # disable SSL warnings requests

    username = "devnetuser"
    password = password or "Cisco123!"
    auth = (username, password)

    session = requests.Session()
    response = requests.post(
        url=auth_url,
        auth=auth,
        verify=False,  # disable SSL verification (self-signed certificate)
    )

    token = response.json()["Token"]
    session.headers.update({"x-auth-token": token})
    return session

This function creates a session with the Cisco DNA Center API. It disables SSL warnings, sets the credentials, and requests an authentication token. The token is then added to the session headers.

Step 4: Getting Interfaces

def get_interfaces(session, base_url=BASE_URL):
    interface_url = base_url + "/dna/intent/api/v1/interface"
    response = session.get(interface_url, verify=False)
    interfaces = response.json()["response"]
    return interfaces

This function retrieves the network interfaces from the Cisco DNA Center API using the session created earlier.

Step 5: Getting Devices

def get_devices(session, base_url=BASE_URL):
    device_url = base_url + "/dna/intent/api/v1/network-device"
    response = session.get(device_url, verify=False)
    devices = response.json()["response"]
    return devices

This function retrieves the network devices from the Cisco DNA Center API using the session created earlier.

Step 6: Filtering Interfaces

def filter_interfaces(interfaces, interface_startwith="Vlan"):
    filtered = []
    for interface in interfaces:
        if interface["portName"].startswith(interface_startwith):
            filtered.append(interface)
    return filtered

This function filters the interfaces to include only those that start with "Vlan".

Step 7: Saving VLAN Interfaces

def save_vlan_interfaces(interfaces, devices, filename="vlan_interfaces.json"):
    vlan_interfaces = filter_interfaces(interfaces, interface_startwith="Vlan")
    payload = defaultdict(list)

    for interface in vlan_interfaces:
        port_device_id = interface["deviceId"]
        ip_address = interface["ipv4Address"]
        portname = interface["portName"]

        for device in devices:
            if device["id"] == port_device_id:
                device_name = device["hostname"]
                break

        payload[device_name].append((portname, ip_address))

    with open(filename, "w") as f:
        json.dump(payload, f, indent=4)

This function saves the filtered VLAN interfaces to a JSON file. It maps the interfaces to their respective devices and writes the data to a file.

Step 8: Loading VLAN Interfaces

def load_vlan_interfaces(filename="vlan_interfaces.json"):
    with open(filename) as f:
        data = json.load(f)
    return data

This function loads the VLAN interfaces from the JSON file created earlier.

Step 9: Exporting to Excel

def to_excel(vlan_interfaces, filename="vlan_interfaces.xlsx"):
    flattened = []
    for device_name, ports in vlan_interfaces.items():
        for portname, ip_address in ports:
            flattened.append(
                {
                    "Device Name": device_name,
                    "Port Name": portname,
                    "IP Address": ip_address,
                }
            )

    pd.DataFrame(flattened).to_excel(filename)

This function exports the VLAN interfaces data to an Excel file.

Step 10: Main Function

if __name__ == "__main__":
    session = get_cc_session(base_url=BASE_URL)
    interfaces = get_interfaces(session)
    devices = get_devices(session)

    save_vlan_interfaces(interfaces, devices)
    vlan_interfaces = load_vlan_interfaces()

    pprint(vlan_interfaces)

    for device_name, ports in vlan_interfaces.items():
        for portname, ip_address in ports:
            print(f"Device Name: {device_name}")
            print(f"Port Name: {portname}")
            print(f"IP Address: {ip_address}")
            print()

    to_excel(vlan_interfaces)

This is the main function that ties everything together. It creates a session, retrieves interfaces and devices, saves the VLAN interfaces, loads them back, prints them, and exports them to an Excel file.

Complete Script

import json
from collections import defaultdict
from getpass import getpass
from pprint import pprint

import pandas as pd
import requests
import urllib3


def load_base_url(filename):
    with open(filename) as f:
        data = json.load(f)
    return data["base_url"]


BASE_URL = load_base_url("config.json")


def get_cc_session(base_url=BASE_URL, username="devnetuser", password=getpass()):
    auth_url = base_url + "/dna/system/api/v1/auth/token"
    urllib3.disable_warnings()  # disable SSL warnings requests

    username = "devnetuser"
    password = password or "Cisco123!"
    auth = (username, password)

    session = requests.Session()
    response = requests.post(
        url=auth_url,
        auth=auth,
        verify=False,  # disable SSL verification (self-signed certificate)
    )

    token = response.json()["Token"]
    session.headers.update({"x-auth-token": token})
    return session


def get_interfaces(session, base_url=BASE_URL):
    interface_url = base_url + "/dna/intent/api/v1/interface"
    response = session.get(interface_url, verify=False)
    interfaces = response.json()["response"]
    return interfaces


def get_devices(session, base_url=BASE_URL):
    device_url = base_url + "/dna/intent/api/v1/network-device"
    response = session.get(device_url, verify=False)
    devices = response.json()["response"]
    return devices


def filter_interfaces(interfaces, interface_startwith="Vlan"):
    filtered = []
    for interface in interfaces:
        if interface["portName"].startswith(interface_startwith):
            filtered.append(interface)
    return filtered


def save_vlan_interfaces(interfaces, devices, filename="vlan_interfaces.json"):
    vlan_interfaces = filter_interfaces(interfaces, interface_startwith="Vlan")
    payload = defaultdict(list)

    for interface in vlan_interfaces:
        port_device_id = interface["deviceId"]
        ip_address = interface["ipv4Address"]
        portname = interface["portName"]

        for device in devices:
            if device["id"] == port_device_id:
                device_name = device["hostname"]
                break

        payload[device_name].append((portname, ip_address))

    with open(filename, "w") as f:
        json.dump(payload, f, indent=4)


def load_vlan_interfaces(filename="vlan_interfaces.json"):
    with open(filename) as f:
        data = json.load(f)
    return data


def to_excel(vlan_interfaces, filename="vlan_interfaces.xlsx"):
    flattened = []
    for device_name, ports in vlan_interfaces.items():
        for portname, ip_address in ports:
            flattened.append(
                {
                    "Device Name": device_name,
                    "Port Name": portname,
                    "IP Address": ip_address,
                }
            )

    pd.DataFrame(flattened).to_excel(filename)


if __name__ == "__main__":
    session = get_cc_session(base_url=BASE_URL)
    interfaces = get_interfaces(session)
    devices = get_devices(session)
    save_vlan_interfaces(interfaces, devices)
    vlan_interfaces = load_vlan_interfaces()
    pprint(vlan_interfaces)
    for device_name, ports in vlan_interfaces.items():
        for portname, ip_address in ports:
            print(f"Device Name: {device_name}")
            print(f"Port Name: {portname}")
            print(f"IP Address: {ip_address}")
            print()
    to_excel(vlan_interfaces)

This is the complete script that combines everything we have learned into a final project. It reads data from the Cisco DNA Center API, saves it to a JSON file, loads it back, prints it, and exports it to an Excel file.

You can run this script to interact with the Cisco DNA Center API and work with the data in a structured manner.