A Brief Interlude

In my first post in this series, I dove into utilizing Regular Expressions (Regex) to parse network device output. Before I continue with some of the other parsing options, I thought it would be worthwhile to post a short blog laying out some definitions that I’ll be relying on. Specifically, I’ll be using them for delineation among the different parsing options and their use cases.

At the heart of this problem, is that when interacting with traditional network devices there aren’t many programmatic options, such as a REST API, to return structured data. Sure, you could use SNMP for some things, but not for everything. In addition, working with SNMP can be its type of nightmare, believe me, I’ve fought that fight many times in the past. This is changing as the industry matures, Cisco even has an entire certification track around utilizing their APIs now, however even today most Network Engineers’ first foray into automation uses SSH to query a device for information. This brings us to output.

What is Output?

For our purposes, “Output” will be defined as any response that a network device returns when given a command via its Command Line Interface (CLI). This could be accomplished by many means; depending on the network device in question the CLI could be reached via Telnet, SSH, or even HTTPS. No matter the access method, the network device is still returning the same data, our output.

Execute show version on a Cisco-like device, and it will return some form of the status of the version as that device understands it. It will be structured, loosely, for human consumption with perhaps headings/titles or indentation/punctuation for legibility. It will not generally be structured in a way that would easily allow a computer program to understand and interact with it.

Just as you can issue show version and get output, you can similarly on most network devices execute a command akin to show running-config and get output. This would return some form of data about the configuration that was currently in use on that network device. Again, it will have some form of structure, usually either delineated by indentation or curly braces ({}), but mostly it will be in a form that is not easily understood or manipulated by a computer program that you are writing.

I make the specific call out that it may not easily be understood by a program that you are writing because of course the network device itself can take that configuration and turn it into actionable information. However, that does us no good, as most vendors aren’t open sourcing their internal operating systems’ parsing logic.

Status vs. Configuration

In the two examples above, we received output from a network device after we issued a command via the CLI. One gave us some sort of status about the device, and the other gave us information about its configuration. Broadly speaking, all CLI commands on a network device fall into these two categories. You are either gathering or changing the status of the device with commands such as show version, show flash, or clear counters. Or you are gathering or changing the configuration of the device with commands such as show running-config, or config t;interface e1/0;no shutdown.

It is vital to keep in mind which type of information you’re looking for or what changes you are trying to make, and whether it involves the device’s status or configuration. This will heavily influence how you parse/interact with the output that the device has given you. Some parsing methods or libraries are made specifically for turning configuration into something easy to manipulate/change in Python (CiscoConfParse, Heir Config), and some are more generic and can parse both status and configuration (Regex, TextFSM, Genie).

In the next post, I’ll dive into CiscoConfParse first, and we’ll see how it can make the act of understanding and manipulating traditional unstructured network device configuration much simpler.