pyATS series - Parsing like a pro
Introduction
Ever dreamed of a test framework that could be used across multiple platforms, OS and vendors, which could do regression, sanity and feature testing; already used by thousands of engineers and developers worldwide? Guess what, it exists, it’s free, and you can start using it right now!
pyATS (Python Automated Test Systems, to be pronounced “py A. T. S.”) was first created as an internal project, to ease the validation of two OS versions. It has been made public in 2017 through Cisco Devnet.
This blog post will be the second one of a series on pyATS. Today, we will explore pyATS libraries (also known as Genie), and we will collect our first parsed output. More use cases are going to be covered in the next posts.
Other pyATS episodes
You’ve missed the first episode? You would like to read more? Below the list of published episodes:
pyATS librairies overview
pyATS building blocks
pyATS is made of three main building blocks:
- pyATS, the core block of this ecosystem. It’s a Python framework which leverages multiple Python libraries such as Unicon, providing a simplified connection experience to network devices. It supports CLI, NETCONF, RESTCONF and gRPC. It enables network engineers and developers to start with small and simple test cases.
- pyATS libraries (also known as Genie) which provides everything you need for network testing such as parsers, triggers and APIs.
- XPRESSO, the pyATS Web UI Dashboard.
You can read more about pyATS ecosystem in the official documentation.
pyATS libraries are the pyATS SDK (Software Development Kit, a big toolbox) which contains all the tools that you need for Network Test Automation. It has been used internally at Cisco since 2010 for our automated testing. Yes! You can use the same tools that we use to automate the validation of your network.
You can read more about pyATS librairies in the official documentation.
pyATS libraries in a nutshell
- 2800+ parsers accross 11 OS (as of April 2021),
- 32 supported models (more to come about them in a coming episode),
- Multiple tools for Test Harness such as triggers or traffic,
- Ansible and Robot libraries for easy integration with other tools.
You can find supported parsers and models in the official documentation.
Getting your hands dirty
Enough talking, let’s code!
pyATS installation has been covered in the First episode. Check it out to learn how to install pyATS.
Parsing a CLI output from a device
In the first use case, we saw how we can get a simple CLI output (show ip interface brief
) from an IOS XR device.
In this second use case, we are going to see how we can collect and parse a CLI output (show ip interface brief
).
In order for everyone to be able to run the code, we will use the IOS XR always-on sandbox on Cisco Devnet. Feel free to adapt the code to use your own device(s). Below the sandbox information.
Key | Value |
---|---|
IOS XRv 9000 host | sbx-iosxr-mgmt.cisco.com |
SSH Port | 8181 |
Username | admin |
Password | C1sco12345 |
Building a testbed
The simplest way to connect to a device is through a pyATS testbed file, written in YAML. This information will be used by Unicon to connect to the device and send the requested commands.
You can find the complete documentation on how to build a testbed here.
testbed.yaml
# Step 0: list of devices
devices:
iosxr1:
# Step 1: OS and Type
type: iosxr-devnet
os: iosxr
# Step 2: credentials
credentials:
default:
username: admin
password: C1sco12345
# Step 3: connection parameters
connections:
vty:
protocol: ssh
ip: sbx-iosxr-mgmt.cisco.com
port: 8181
The testbed.yaml
file is available here.
The testbed construction has been covered in the First episode. Have a look to understand how to build a testbed from scratch
Raw output vs Parsed output
Now, you know how to get a CLI output using pyATS. Getting a specific information in this big text output is easy for a human; but what about a computer? You got it, that’s the power of the pyATS libraries: converting this raw output (string) into a parsed output (dictionary) where you can easily get a value by accessing a specific key.
Let’s take an example. Below the CLI output you would get by typing show ip interface brief
.
Raw CLI output
Interface IP-Address Status Protocol Vrf-Name
Loopback100 1.1.1.100 Up Up default
Loopback200 1.1.1.200 Down Down Red
And now, the same output, of the same CLI command show ip interface brief
, parsed with pyATS libraries. Note that you can see the exact same information compared to the raw output above. Nothing more, nothing less.
Parsed CLI output
{
"interface": {
"Loopback100": {
"ip_address": "1.1.1.100",
"interface_status": "Up",
"protocol_status": "Up",
"vrf_name": "default",
},
"Loopback200": {
"ip_address": "1.1.1.200",
"interface_status": "Down",
"protocol_status": "Down",
"vrf_name": "Red",
}
}
Collecting and parsing your first CLI output with pyATS libraries
Now that we understand the difference between a raw output (a string) and a parsed output (a dictionary), let’s look at the code. This script will collect a parsed output of the show ip interface brief
command. It will extract the interface name
and the interface ip address
from the dictionary, then print each couple. The script will be further detailed and explained below.
1_parsed_output.py
# New module! Now using Genie!
from genie import testbed
# Step 0: load the testbed
testbed = testbed.load('./testbed.yaml')
# Step 1: testbed is a dictionary. Extract the device iosxr1
iosxr1 = testbed.devices["iosxr1"]
# Step 2: Connect to the device
iosxr1.connect(init_exec_commands=[], init_config_commands=[], log_stdout=False)
# Step 3: saving the `show ip interface brief` output in a variable
show_interface = iosxr1.parse('show ip interface brief')
# Step 4: iterating through the parsed output. Extracting interface name and IP
for interface in show_interface['interface']:
print(f"{interface} -- {show_interface['interface'][interface]['ip_address']}")
# Step 5: disconnect from the device
iosxr1.disconnect()
The 1_parsed_output.py
file is available here.
Executing the script
From your bash terminal
python 1_parsed_output.py
In this example, the testbed.yaml
file need to be in the same folder as the 1_parsed_output.py
file. Also, you need to execute the Python script in the folder where you have these two files.
Let’s now explain the building blocks of the Python script. The parts below will refer to each inline comment of the code block above.
Output example
Here is an output example of the above script. It might slightly vary according to the configuration of the device.
Python console
Loopback333 -- 3.3.3.3
Loopback99 -- 99.99.99.99
Loopback11 -- 1.2.3.1
GigabitEthernet2 -- Unassigned
GigabitEthernet1 -- 10.10.20.48
GigabitEthernet3 -- Unassigned
Step 0: load the testbed
From the genie
module, we import the testbed.load()
function. This function will be used to load the testbed file we have created.
We load the testbed
information, stored in our testbed.yaml
file. We assign it to an object: testbed
.
Step 1: extract device information
testbed
is a Python dictionary. We are extracting the device iosxr1
information. We assign it to an object: iosxr1
.
You can name the object with the name you want. The object name does not need to match the hostname of you device.
Step 2: connect to the device
We use the connect()
method on the iosxr1
object to connect to the device.
By default, pyATS will send exec and configuration commands to the device (such as terminal length 0
and show version
). To avoid such behavior, we are passing arguments to the conect()
method. We are also disabling the logging to standard output. More information in the [documentation].(https://pubhub.devnetcloud.com/media/unicon/docs/user_guide/connection.html)
Step 3: save the "show ip interface brief"
output in a variable
This step is the most important step in our script. It will collect the show ip interface brief
output and parse it. Each information of the CLI output will be mapped either as a dictionary key or a value. There should be no entropy loss between the raw CLI output and the parsed output.
To do so, we are using the parse()
method on the device
object. The parse method takes a string as parameter, which is the IOS XR command we would like to collect and parse. We are saving this parsed output in a variable show_interface
.
You can find all available pyATS parsers in the [documentation].(More information in the documentation.
A parsed output example (i.e. the dictionary saved in the variable show_interface
) can be seen in Step 4.
Step 4: Python logic to print interface name and IP
Below an example of parsed output for the show ip interface brief
command. Most interfaces are missing, for conciseness.
Parsed CLI output
{
"interface": {
"Loopback100": {
"ip_address": "1.1.1.100",
"interface_status": "Up",
"protocol_status": "Up",
"vrf_name": "default",
},
"Loopback200": {
"ip_address": "1.1.1.200",
"interface_status": "Down",
"protocol_status": "Down",
"vrf_name": "Red",
}
}
In the above output, we have a list of interfaces: Loopback100
and Loopback200
. We are iterating through this list. For each interface, we are accessing the ip_address
value. We’re then printting the interface name
and IP
.
It might not be useful in a real life use case. Goal here is to take a concise example, to show how easy it is to extract values of a CLI output when parsed with pyATS libraries.
Step 5: disconnect from the device
We use the disconnect()
method to properly disconnect from the device.
It’s important to properly disconnect from the device, otherwise the vty connection will remain open on the device, until it times out.
Parsing an output you already have
If you want to parse an ouput you already have (i.e. without the need to have a device to extract the output), it’s also possible. You can use the code below.
Conclusion
In this second episode of the pyATS series, we learnt:
- The difference between a raw and parsed output,
- Why pyATS libraries are powerful,
- How to collect and parse a CLI output from a device,
- How to get a value from a parsed output.
In the next post, we will learn what’s a Model, why it’s powerful when parsing from multiple OS at once and how to use them.
The code used for each blog post can be found here. This link will include the code for all posts.
Resources
Below a few useful pyATS resources.
Leave a Comment