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.
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.
- Get boolean of
changed
:response["fw02"][0].changed
- 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
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.
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.