Xrdocs Io Programmability Tutorials Pyats Series Collecting Many Show Commands
Xrdocs Io Programmability Tutorials Pyats Series Collecting Many Show Commands
Antoine Orsoni
Programmability enthusiast and Systems Engineer, Cisco Follow
Save to PDF
TA B L E O F C O NT E NT S
INTRODUCTION
G E T T I N G YO U R H A N D S D I R T Y
CONCLUSION
RESOURCES
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 rst created as an internal project,
to ease the validation of two OS versions. It has been made public in 2017 through Cisco Devnet.
This is the 4th blog post of the pyATS series. Today, we will cover our rst use case: how to collect many show
commands on many devices?
1 - Install and use pyATS Link What’s pyATS, Install pyATS, Collect a raw CLI output
2 - Parsing like a pro Link Explore pyATS libraries, Collect and parse a CLI output
4 - Collecting many show commands Link How to collect many show commands on many devices?
6 - Pushing and removing con guration Link How to push and remove con guration using pyATS?
pyATS installation has been covered in the First episode. Check it out to learn how to install pyATS.
Today’s code will be available here.
We will rst explain the code in a high level view. We will then explain each building block individually.
In order for everyone to be able to run the code, we will use the IOS XR always-on sandbox on Cisco Devnet.
Below the sandbox information.
Key Value
SSH Port 22
Username admin
Password C1sco12345
Use case
I had this use case a couple of months ago. We had a thermal issue on a device. We wanted to know if the other
devices (400) also su ered the same root cause. To verify, the TAC Engineer asked us to collect 4 show
commands on 400 devices.
Without optimizing the script (ex: using threads) it took us 20 minutes to collect such outputs. We were more
than ready when the Engineer asked for a couple more commands.
For each device, we will have an output le with the show commands collected.
Extract the IP address of each device
The list of IP addresses is stored in templates/list_ip.yaml. We can add extra IP addresses by adding a new item
in the yaml le, as below.
- ip_1
- ip_2
- ip_n
To create a list out of a yaml le, we are using the PyYAML package.
import yaml
Jinja2 is a templating engine. You can create a sample structure with keywords. Jinja2 will nd and replace these
keywords with your own values. For example, you could have this sample IOS XR interface template.
1 interface {{name}}
2 ipv6 address {{ipv6}}/{{mask}}
3 !
In the above example, you would give Jinja2 three arguments: name , ipv6 and mask .
What’s interesting with Jinja2 is that it can have its own logic such as condition, loops and blocks. Using a
Jinja2 loop, the above interface template could be reused multiple times. You could loop 50 times, to create 50
loopbacks with a unique ID (name) and a unique IPv6 address.
Here, we are using Jinja2 to create a template for our pyATS testbed. You can nd the pyATS testbed template in
templates/testbed.tpl.
The testbed construction has been covered in the First episode. Have a look to understand how to build a testbed from scratch.
The below outputs presents the Jinja2 logic used for our pyATS testbed. For brievity, we are not showing the full
template le.
Jinja2 logic with pyATS testbed
1 devices:
2 {% for ip, id in list_ip_id %}
3 Node_{{id}}:
4 type: iosxr-devnet
5 os: iosxr
6 connections:
7 vty:
8 protocol: ssh
9 ip: {{ip}}
10 settings:
11 GRACEFUL_DISCONNECT_WAIT_SEC: 0
12 POST_DISCONNECT_WAIT_SEC: 0
13 arguments:
14 connection_timeout: 10
15 {% endfor %}
We are giving Jinja2 a list of lists: list_ip_id . Each sub-list contains the ip address of a device and a unique
id to identify the node’s name in the testbed. This value has to be unique. For each list in list_ip_id we will
Now, we need to write Python logic to give this list_ip_id to Jinja2 template. That’s how you do it.
# Instance of the Environment class. Gives the loader (above), optionally parameters
# block strings, variable strings etc.
template_env = jinja2.Environment(loader=template_loader)
In Python, the zip() function takes iterables (can be zero or more), aggregates them in a tuple, and returns it.
More information here.
The testbed information is speci c to the Devnet sandbox: login, password, protocol, operating system… Feel free to change it.
First, we need to connect to each device. In case we cannot connect to a device, Unicon will send a
ConnectionError . We are catching such error to print in the terminal if we cannot connect to a device. In the
below logic, if we cannot connect to a device, it doesn’t fail the script. We will still iterate through the other
devices, as long as we have devices in the testbed. Feel free to change this behavior if needed.
try:
device.connect(learn_hostname=True,
init_exec_commands=[],
init_config_commands=[],
log_stdout=False)
except ConnectionError:
print("-- ERROR --")
print(f" Can't connect to {device.connections.vty.ip}")
continue
The connect() method has been covered in the First episode. Have a look to understand how it works.
Last, we need to collect each CLI output and write it in a le. File name will be the device’s hostname (learned
with pyATS).
In case a command is invalid, Unicon will send a SubCommandFailure . We are cathing this error, to tell in the
terminal which show command failed. We will still iterate through the other show commands , as long as we have show
Conclusion
In the next post, we will learn more about pyATS Dq (dictionnary querry) and how pyATS can nd a pair of key:
Resources
SHARE ON
Leave a Comment
What do you think?
7 Responses
0 Comments
1 Login
Name
This site is maintained by Cisco Systems, Inc. employees. Powered by Jekyll & Minimal Mistakes.