Cisco DevNet Genie | Quickstart

Jeremy Schulman
Network Automaniac
Published in
6 min readOct 12, 2019

https://github.com/jeremyschulman/genie-quickstart

As a network automation engineer responsible for creating tools for use with Cisco devices I am always on the lookout for software products and technologies. I’ve been following the Cisco DevNet open-source projects pyATS and Genie for some time, and I finally had an opportunity to try them out. This article details my first experience using the software— but not as it is intended for test automation purposes.

My Motivation

While I can understand how important this software can be for network test automation purposes, this was not my motivation for trying it out. I need to build troubleshooting tools, and I found Genie was the best software for my use:

  • I work with a large network of Cisco devices of varying OS versions, and these systems can only be automated by “screen scraping” the CLI
  • I don’t want to write CLI text parsers if I don’t have to, and the pyATS/Genie software provides the software to connect with the devices and over 500+ parsers
  • The pyATS/Genie software is extremely extensible and well documented so that I can create any parsers using their SDK when necessary
  • Cisco is committed to constantly updating and supporting these projects as they are used internally as well as for the community

So with that in mind I wanted to see what it would take to use the software to do the following quick-start activity:

  1. Connect to any arbitrary device using credentials obtained from Environment variables, but without having to create a complex pyATS Testbed (YAML) file listing all of the devices in my network
  2. Execute show commands to obtain the text CLI output
  3. Execute show commands using the Genie parsers to determine if such a parser was supported for the command, and if the parser exists allow me to examine the structure of data so I can write my tools accordingly

My Journey

Step 1

The first step was understanding how to create the testbed YAML file. I immediately looked for an example which I found here. There was a lot to understand in this deeply nested structure of data. All I wanted to do was setup some common credentials that pulled my username/password from environment variables. The testbed topology file allows you to use markups to do this. Ultimately I created a testbed file that looks like this:

This empty testbed file is used to set the default credentials pulling from my environment variables $PYATS_USERNAME and $PYATS_PASSWORD. The testbed file requires the devices keyword (line 8), but I have not listed any device entries since I will create them programmatically.

https://pubhub.devnetcloud.com/media/pyats/docs/topology/creation.html#manual-creation

Step 2

The next step is loading the Testbed YAML file — and importantly ensuring that the environment variables were actually set. I made the mistake once of not setting them. When running my quickstart.py program no errors were reported during the load, but when I attempted to connect to the device it failed because I didn’t have credentials.

The following code checks that the environment variables exist and are not empty. If that test fails, then the program exists, otherwise the variable testbed is ready for use.

https://ipython-books.github.io/

When I load my quickstart.py file into ipython I see that the empty-testbed.yaml file is loaded OK, and I can examine the testbed variable.

A neat feature of pyATS / Genie is how they handle credentials — as you can see the password value is shown as stars rather than plaint-text.

Step 3

The next step is programmatically creating Device instances so I can interact with my network. The add_device() function is used to create a Device instance and add it to the Testbed instance. When the Device is added to the Testbed it will automatically pick up the credentials for login purposes.

quickstart.py — Function to create a Device instance

I’ve collapsed the comments (line 88–121) for brevity. The os_type argument (line 87) must be one of the supported operating systems listed in the docs, “nxos” for example, which is passed as the Device os parameter (line 124)

A tricky bit was line 125 — this is necessary so that Genie can determine which parser library to use, mapping the Device os parameter to the parser library. While the documentation describes the general architecture of parser mapping here, it does not document the use of the Device custom parameter as shown above.

The Device connections parameter defines how to connect with the device. The pyATS framework is very, very comprehensive to allow many different ways to connect, but I only need SSH. The function make_ssh_conn() generates the dictionary of information required for this purpose:

quickstart.py — Function to define SSH connection

The tricky bit here was the arguments options (line 82) . This instructs Genie *NOT* to perform any configuration commands on login — I initially found that when I connected to the device Genie would by default configure cli settings (i.e. enter config mode), and I wanted to disable this behavior.

I can then interactively create an NXOS device in my network in ipython:

Step 4

Now that I have the device instance variable dev, I can connect to it using the dev.connect() method. Genie will log output to the console during the connect process, which is interesting but sometimes not desired. You can pass the argument dev.connect(log_stdout=False) to disable this behavior.

When you execute the dev.connect() method, the device CLI output will be returned. Generally speaking this is likely going to be your login banner. You can capture the output into a variable. You can check if the device is connected OK using the dev.is_connected() method.

Step 5

Next I executed my first command, “show version”. To get the response as the CLI text string you use the dev.execute() method.

I then ran the same command through the Genie parser using the dev.parse() method so that I have the structured data in a python dictionary.

Genie parser structures the CLI output into dictionary

Step 6

Finally I tried to run a show command via the dev.parse() method to see if Genie provides a parser I want. If Genie does not have a parser you will see an Exception error.

At which point this means I get to learn how to write my own parser for this specific command — a work in progress and subject of another article!

Start Your Journey

The Cisco DevNet pyATS and Genie projects are incredibly sophisticated, well developed, and well documented. Getting started can be overwhelming. If you’d like to try out the quickstart code you can find it on Github:

https://github.com/jeremyschulman/genie-quickstart

Now that I’ve explored the parts of the projects that I needed I am even more encouraged to try out the other features.

Reference Links

--

--

Jeremy Schulman
Network Automaniac

Senior Network Automation Engineer, Major League Baseball