[python]How to capture results with nornir

Introduction

Nornir is a framework for network automation, it gels popular automation tools such as napalm, netmiko, paramiko and Ansible. However I could not find good examples on how to parse the result if I use show access-list with netmiko_send_command during task.run.

There is a built in print_result() function which shows the status and output of the command on the console, however I need to store the information so that I can convert the result to dictionary hence print_result is not useful to me.

A read at the documentation, did not give me enough insight on how to capture the result, hence I did experiment and refer back to the documentation to understand what the sections were trying to tell me.

In this experiment, I am using FW02 and send show access-list abcd where abcd is the access-list name.

I will be using my own written python package to get the acl.

Show the result on console

On first experiment, use the print_result function to show the results after the command was executed, however print_result only shows you the result but the result is not captured.
This is the code for the experiment:

from network.ciscoasa import read_acl, connect_asa_host, get_asa_credential
from nornir.plugins.functions.text import print_result


credential = get_asa_credential(hostname="fw02")
fw02 = connect_asa_host(hostname="fw02", username=credential["username"], password=credential["password"])

response = fw02.run(task=read_acl, acl_name="abcd")
print_result(response)

The output will look like this, but still no result is captured.
nor22

AggregatedResult object

According to this, AggregatedResult is a dict-like object, hence it has properties of a dictionary. The entire result looks like this:
AggregatedResult (read_acl): {'fw02': MultiResult: [Result: "read_acl", Result: "Sending single command"]}

To get the information of fw02, according to the documentation is to refer to the hostname, hence in this context to get to fw02 I simply need to do response["fw01"] where response is the object from task.run

This is the code for testing:

from network.ciscoasa import read_acl, connect_asa_host, get_asa_credential


credential = get_asa_credential(hostname="fw02")
fw02 = connect_asa_host(hostname="fw02", username=credential["username"], password=credential["password"])

response = fw02.run(task=read_acl, acl_name="abcd")
print(response)

MultiResult

According to the documentation the MultiResult is a list-like object.

Because nornir is supporting configuration for multiple device, to refer to the MultiResult object on a specific hostname you simply need to do response["fw01"] where response is the object of task.run and “fw01” is the hostname my firewall which I want to access the results.

This code gives access to “fw01″‘s MultiResult object:

from network.ciscoasa import read_acl, connect_asa_host, get_asa_credential


credential = get_asa_credential(hostname="fw02")
fw02 = connect_asa_host(hostname="fw02", username=credential["username"], password=credential["password"])

response = fw02.run(task=read_acl, acl_name="abcd")
print(response["fw02"])

And the MultiResult object looks like this:
MultiResult: [Result: "read_acl", Result: "Sending single command"]
To get the “read_acl”, use index 0, to get the result of “sending single command” use index 1.

Index 0 has two useful methods namely – changed and failed both returns boolean value, refer to this.

Accessing changed and failed methods of index 0 of MultiResult

To know the command is executed successfully check the boolean of failed and to check if the changed was done use the changed boolean.

  1. Get boolean of changed: response["fw02"][0].changed
  2. Get boolean of failed: response["fw02"][0].failed

Accessing the output of show access-list abcd

Index 1 of MultiResult contains the result from the command sent by nornir.

response["fw02"][1]

The below is the output of show access-list abcd
nor23

Although the output of the command has displayed in the console and it seemed to be string but it is not string object but Result object, read this documentation. To get the string object use the result method hence the response has to be like this result = response["fw02"][1].result. It is important to use string object and not Result object as string object you can utilize encode, split, rsplit, splitlines methods.

Advertisement

2 thoughts on “[python]How to capture results with nornir

  1. Hey. I hope you see this. I have been looking to do exactly this with Nornir and I was shocked that I couldn’t find anything on the topic. I am a complete amateur with programming and scripting and such, and i’m on day 9 of searching before I came to this post. This helped tremendously so thank you.

    The ONLY question I have is this – how can you do this against ALL of your hosts, rather than specifying one host?

    What i’m trying to do is run a “show version” against all of my Cisco devices for example. I just wanted to parse out the firmware version number that is being used, and not everything else. So with your guide, I was able to get that to work, but it’s only for one device. I don’t know how to run it against multiple devices. I cant use for-loops with the AggregatedResult or any of the usual stuff. I tried using regex, but same thing. To convert it to a string, you have to reference the host and then index from there, so that’s where i’m stuck.

    Any help would be appreciated. Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s