Skip to content

5 Efficient Ways to Collect Show Commands Output From Network Devices

21 Aug 2022 by Denis Mulyalin

Problem Statement#

Getting show commands output from network devices, what can be simpler - login into device, issue show commands, copy output, create text file on a local file system, paste copied output, save file, exit. And after doing 7 steps above, required output happily sits on the hard drive in a convenient spot ready for processing.

Above process is certainly doable and likely sounds very familiar to many Network Engineers. However, what if we tasked to collect not 1 or 2 but 5, 10 or 100 commands and need to get them not from 1 or 2 but 2000 devices? That is there above process quickly falls short and the benefit of automation becomes apparent - hand it over to relentless robots running on our computer systems, happily doing any mundane task we throw at them as many times as we need in as big volumes as we want to.

With that, let me introduce 5 solutions to the problem of collecting show commands output from network devices using Salt-Nornir proxy minion.

1 - Using nr.cli Inline Commands Arguments#

The simplest, exploratory way to get show commands output from network devices with Salt-Nornir is by using nr.cli function supplied with inline commands arguments:

salt nrp1 nr.cli "show clock" "show version" FL="ceos1, ceos2"

That should print similar output to the terminal:

[root@salt-master /]# salt nrp1 nr.cli "show clock" "show version" FL="ceos1, ceos2"
nrp1:
    ----------
    ceos1:
        ----------
        show clock:
            Fri Jul 29 19:03:41 2022
            Timezone: UTC
            Clock source: local
        show version:
             cEOSLab
            Hardware version:
            Serial number:

            <omitted for brevity>
    ceos2:
        ----------
        show clock:
            Fri Jul 29 19:03:41 2022
            Timezone: UTC
            Clock source: local
        show version:
             cEOSLab
            Hardware version:
            Serial number:

            <omitted for brevity>

Copy and save output to per-host text files on your local file system. This time it took around 2 seconds to collect 2 commands from 2 devices, not bad.

To get it one step further, instruct nrp1 proxy minion to save output into the files on the local (in relation to the minion process) file system, ready to be copied over.

salt nrp1 nr.cli "show clock" "show version" FL="ceos1, ceos2" tf="my_commands"

Salt-Nornir will save output to /var/salt-nonir/nrp1/files/ folder:

[root@salt-master /]# salt nrp1 cmd.run "ls -l /var/salt-nornir/nrp1/files"
nrp1:
    total 12
    -rw-r--r--. 1 root root  532 Jul 29 17:09 my_commands__29_July_2022_17_09_10__22__ceos2.txt
    -rw-r--r--. 1 root root  532 Jul 29 17:09 my_commands__29_July_2022_17_09_10__875__ceos1.txt

Can copy files from proxy minion or use nr.file function to retrieve output at any time. For example to read file content for ceos1 host only:

salt nrp1 nr.file read filegroup="my_commands" FB=ceos1

2 - Source Show Commands From Files#

While you certainly can do this:

salt nrp1 nr.cli "show clock" "show version" "show ip int brief" "show ntp" "show lldp neighbor" "show bgp sum" FL="ceos1, ceos2" tf="my_commands"

Its certainly going to take a lot of typing. More efficient way is to save commands into a text file on salt-master machine and request proxy minions to source commands to collect form that file.

For example, this is /etc/salt/cli/commands.txt file content:

show clock
show version
show ip int brief
show ntp
show lldp neighbor
show bgp sum

And this is how to point proxy minion to that file:

salt nrp1 nr.cli commands="salt://cli/commands.txt" FL="ceos1, ceos2" tf="my_commands"

Same outcome as before, but less typing and easy to reuse later.

3 - Generate Show Commands From Jinja2 Templates#

What if command need to contain per host details like source IP address as in ping or traceroute commands, solution is to use Jinja2 templates:

salt nrp1 "traceroute 192.168.2.4 source {{ host.lo0_ip }}" FL="ceos1, ceos2"

Where host.lo0_ip sourced from host inventory data:

hosts:
  ceos1:
    data:
      lo0_ip: 10.0.0.1
  ceos2:
    data:
      lo0_ip: 10.0.0.2

But what if need to collect different commands output from different device types, Jinja2 conditionals certainly can handle it, here is /etc/salt/cli/conditional_commands.txt file content:

{% if "CORE" in host.name %}
show clock
show version
{% elif "eos" in host.name %}
show ip int brief
show ntp
show lldp neighbor
show bgp sum
{% endif %}

To render above template and run generated commands:

salt nrp1 nr.cli commands="salt://cli/conditional_commands.txt" FL="ceos1, ceos2" tf="my_commands"

Another use case - what if I need to run commands on a per host basis, do I need to use Jinja2 conditionals as well - yes, can rely on Jinja2 conditional or can supply per-host files with commands. For example, this is the content of /etc/salt/cli/commands_ceos1.txt and /etc/salt/cli/commands_ceos2.txt files respectively:

show clock
show version

and

show ip int brief
show ntp
show lldp neighbor
show bgp sum

nr.cli supports templating to source commands from different files:

salt nrp1 nr.cli commands="salt://cli/commands_{{ host.name }}.txt"

4 - Collecting Commands in a Loop#

Troubleshooting network problems often can benefit from collecting show commands output from multiple devices simultaneously. This can be easily accomplished using above tricks. But Salt-Nornir does not stop there allowing to collect show commands output from devices in a loop up to a certain number of times with predefined intervals. This comes in handy when problem is reproducible but only lasts for seconds

This is how commands can be run in a loop:

salt nrp1 nr.cli "show clock" "show ip route" repeat=10 repeat_interval=1 table=brief

table=brief instructs Salt-Nornir to return nicely formatted text table to make it easier to read through the output.

Another feature is capability to stop collecting show commands after certain pattern found in the output. Made up example - you want to collect "show ip route" output in a loop but stop if certain route becomes visible in the routing table.

salt nrp1 nr.cli "show ip route" repeat=100 stop_pattern="10.1.2.3/24" table=brief

5 - Using Different Connection Plugins#

Salt-Nornir makes it extremely easy to switch between connection methods making sure you have flexibility to choose what works best for you.

For example this is how output can be collected using Netmiko plugin:

salt nrp1 nr.cli "show ip route"

Since Netmiko is a default connection method, no need to specify plugin to use. However, this is how different plugins can be invoked:

salt nrp1 nr.cli "show ip route" plugin=netmiko
salt nrp1 nr.cli "show ip route" plugin=napalm
salt nrp1 nr.cli "show ip route" plugin=scrapli
salt nrp1 nr.cli "show ip route" plugin=pyats

Salt-Nornir nr.cli supports Netmiko, NAPALM, Scrapli and PyATS to communicate with devices using CLI. Connection plugins parameters can be provided using Nornir inventory, refer to documentation examples for more details.

Besides using different plugins, nr.cli also support promptless (ps) mechanism to collect output from devices. This mechanism based on Netmiko library but adds several enhancements to make process of collecting big amount of output from network devices more reliable.

To use promptless mode specify use_ps=True for Netmiko plugin:

salt nrp1 nr.cli "show ip route" plugin=netmiko use_ps=True

Promptless mode has these features:

  • does not timeout on big chunks of data as long as device keeps transmitting data thanks to using read and absolute timeouts
  • supports device prompt change while collecting show commands output
  • multi line commands can be send to device
  • using nowait=True allows to send commands without waiting for prompt to come back

In Conclusion#

With above arsenal it should be easier to tackle the task of collecting show commands output from network devices. To automate that process even further, SaltStack supports Python API and REST API, Salt-Nornir inherits those capabilities as well.

Hope you enjoyed reading this blog post. For comments and suggestions feel free to open an issue.

Back to top