Building a 'Validator' Program in Python (Part 1)

This blog is for publically working out my studies in network engineering, programming, and automation. For my first project, I’m combining both and bulding a program in Python I can also use in my work as a network engineer.

Executive Summary Link to heading

One of the challenges of upgrading from a switch that is “End of Life” to a new model is making sure all the end devices find themselves attached to all the same VLANs they were before the upgrade. This program will programatically verify all end devices are in the correct VLAN, or provide the information to fix it.

Problem Statement Link to heading

The way I see it, there are three major problems around devices getting in the proper VLAN after a switch upgrade:

  1. I aim to be a master of my craft, so I don’t want to leave the task incomplete by just calling it a day when the new switch is in placed and some cables are plugged into it.

  2. The process for manually verifying is tedious and error prone. If I personally compare the MAC address tables from before and after the upgrade, I will 100% miss something.

  3. It’s just a bad look for the network team when users come in after a big upgrade and they can’t use their phone ore access any resources on the network. Reputation is a part of craftsmanship.

  4. Bonus: In our project we hire a contractor to do the physical upgrades. As an engineer I oversee and, ideally, validate their work. Our team does good work, but again it’s a tedious process to untangle cable and keep track of where everything is patched. This is especially true when the cables are not managed well after years of tangling into a giant copper web of Category 5/6 patch cables of various lengths.

The program I’m building will programatically compare a snapshot of the MAC address table taken shortly before the upgrade with a snapshot of the MAC address table taken after. The comparison will result and a report that tells: 1) what MAC addresses are in different VLANS between reports, and 2) what devices are missing.

The Plan Link to heading

The plan is to develop a CLI tool in Python the performs two basic tasks.

The first task is to collect the MAC address table information from the target switch as structured data. Most likely I’ll do this in JSON. As part of the process the structured data will be output into a timestamped file.

The second task is to take the before and after JSON files and parse them for their differences. The result of this feature will be a list or report that tells the engineer which mac addresses are in the wrong VLAN, what the correct VLAN is, and in which interface the device is currently connected. The report will also list all of the MAC addresses that are missing entirely.

Challenges Link to heading

The first major challenge is getting the MAC address table in a structured data format from a switch model that doesn’t have RESTCONF as a feature. That will leave me with screenscraping the data. I’m thinking I can use TextFSM modules to help here.

The second challenge will be effectively and efficiently parsing the JSON data to produce the report.

And the third challenge will be keeping myself motivated, when I think the better (and more elegant) solution is to use profiles in Cisco’s Identity Services Engine (ISE) to dynamically assign all the devices to their correct VLANs. Though, the validation program would still help with making sure everything that was patched in to the switch before the upgrade is still patched after.

Conclusion Link to heading

A secondary objective of this project is simply to give me experienced building projects with real-world applications to network engineering. I’m too tired to actually finish this post correctly. I’ll circle back around. But for now, let me share the code for the get_credentials() function.

Code-Time! Link to heading

Below is the function I’ve written so far. It’s a module I use with most of my Python work for accessing switches.

from getpass import getpass


def get_credentials():
    """Returns a tuple containing the username and a confirmed password for authenticating to the network device"""

    username = input("Please enter the username for the target network device: \n")
    password = getpass("Please enter the password: \n")
    try_counter = 0
    attempts = 3
    while try_counter < 3:
        confirmed_password = getpass("Confirm the password: \n")
        if password == confirmed_password:
            return username, password
        else:
            try_counter += 1
            attempts -= 1
            print(f"Passwords did not match. You have {attempts} attempts left.")


if __name__ == "__main__":
    get_credentials()