Cisco NSO is a powerful configuration engine, but it also has the capability to send operational commands to the network devices it manages. This is often very helpful when you are building services or scripts to include some verification steps or to gather additional data about the state of the network to feed into your decision-making logic in your code.
NSO’s features are equally accessible across all the APIs (aka “feature parity”), which is uncommon in a lot of network automation tools, so you can explore the functions of NSO in a more interactive way in the CLI or GUI first before using the API. Because the CLI structure is modeled after the same YANG application data model as the API, the naming conventions and logical hierarchy in the CLI will be present in the API. This will give you a mental picture of what to expect when you see the Python code after using the NSO CLI.
After your NSO Sandbox reservation is up, log into the 10.10.20.49
system install server. It already has a populated device list and a running instance. The device we will be working with is an IOS XE device called dist-rtr01
.
Issue the ncs_cli
command in the Linux shell prompt to enter into the NSO CLI, and then view the device list with the show devices list
command:
[developer@nso ~]$ ncs_cli
User developer last logged in 2022-07-26T10:23:16.057236-07:00, to nso, from 10.10.20.49 using rest-https
developer connected from 192.168.254.11 using ssh on nso
developer@ncs# show devices list
NAME ADDRESS DESCRIPTION NED ID ADMIN STATE
-----------------------------------------------------------------------------
core-rtr01 10.10.20.173 - cisco-iosxr-cli-7.32 unlocked
core-rtr02 10.10.20.174 - cisco-iosxr-cli-7.32 unlocked
dist-rtr01 10.10.20.175 - cisco-ios-cli-6.67 unlocked
dist-rtr02 10.10.20.176 - cisco-ios-cli-6.67 unlocked
dist-sw01 10.10.20.177 - cisco-nx-cli-5.20 unlocked
dist-sw02 10.10.20.178 - cisco-nx-cli-5.20 unlocked
edge-firewall01 10.10.20.171 - cisco-asa-cli-6.12 unlocked
edge-sw01 10.10.20.172 - cisco-ios-cli-6.67 unlocked
internet-rtr01 10.10.20.181 - cisco-ios-cli-6.67 unlocked
developer@ncs#
Now if you want to see the capabilities of what NSO can do with a device outside of configuration mode, use the ?
to see the options (where live-status
will show up):
developer@ncs# devices device dist-rtr01 ?
Possible completions:
add-capability This action adds a capability to the
list of capabilities.
capability A list of capabilities supported by
the device
check-sync Check if the NCS config is in sync
with the device
check-yang-modules Check if NCS and the device have
compatible YANG modules
compare-config Compare the actual device config with
the NCS copy
config NCS copy of the device configuration
connect Connect to the device
copy-capabilities Note: this action overwrites existing
list of capabilities.
delete-config Delete the config in NCS without
deleting it on the device
disconnect Close all sessions to the device
find-capabilities This action overwrites existing list
of capabilities.
live-status Status data fetched from the device
live-status-protocol Additional protocols for the
live-tree (read-only)
migrate Migrate the device to a new NED type
netconf-notifications NETCONF notifications from the device
ping ICMP ping the device
scp-from Secure copy file to the device
scp-to Secure copy file to the device
ssh SSH connection configuration
sync-from Synchronize the config by pulling
from the device
sync-to Synchronize the config by pushing to
the device
developer@ncs# devices device dist-rtr01
After selecting live-status
, the only option after that is exec
, and then see what the options are at that point:
developer@ncs# devices device dist-rtr01 live-status ?
Possible completions:
exec Execute commands on device
developer@ncs# devices device dist-rtr01 live-status exec ?
Possible completions:
any Execute any command(s) on device.
any-hidden Execute any command(s) on device, nothing will
be logged.
clear Reset functions.
copy Copy from one file to another.
license Smart licensing Commands.
ping Send echo messages.
reload Halt and perform a cold restart.
show Execute show commands.
traceroute Trace route to destination.
verify Verify a file.
developer@ncs# devices device dist-rtr01 live-status exec
At this point, you could use the show
option, but the any
option will also allow us to send show commands. Type in any
and the command you want to be sent (show ip interface brief
), such as devices device dist-rtr01 live-status exec any show ip interface brief
:
developer@ncs# devices device dist-rtr01 live-status exec any show ip interface brief
result
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 10.10.20.175 YES NVRAM up up
GigabitEthernet2 172.16.252.21 YES NVRAM up up
GigabitEthernet3 172.16.252.25 YES NVRAM up up
GigabitEthernet4 172.16.252.2 YES NVRAM up up
GigabitEthernet5 172.16.252.10 YES NVRAM up up
GigabitEthernet6 172.16.252.17 YES NVRAM up up
Loopback0 unassigned YES unset administratively down down
dist-rtr01#
developer@ncs#
One trick to note is that at this point, you can also save the output using the | save
option appended at the end of your command. It will save the file in the directory where you initiated the NSO CLI, such as devices device dist-rtr01 live-status exec any show ip interface brief | save sh-ip-br.txt
:
developer@ncs# devices device dist-rtr01 live-status exec any show ip interface brief | save sh-ip-br.txt
developer@ncs# exit
[developer@nso ~]$ ls
Desktop shutdown.sh
Downloads sh-ip-br.txt
[developer@nso ~]$ cat sh-ip-br.txt
result
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 10.10.20.175 YES NVRAM up up
GigabitEthernet2 172.16.252.21 YES NVRAM up up
GigabitEthernet3 172.16.252.25 YES NVRAM up up
GigabitEthernet4 172.16.252.2 YES NVRAM up up
GigabitEthernet5 172.16.252.10 YES NVRAM up up
GigabitEthernet6 172.16.252.17 YES NVRAM up up
Loopback0 unassigned YES unset administratively down down
dist-rtr01#
[developer@nso ~]$
Now that you have some familiarity with the live-status
feature, let’s see it in action in the Python API.
The Python library for NSO is not something you can install. It automatically is inserted into the Python path for the Linux host where NSO is installed. The library can only be run on the same host as the NSO instance. It is called ncs
, and recent releases only allow it to be used with Python 3.
First, create a file called nso_show_commands.py
in the current working directory. I used VS Code Remote Explorer, but you can use vim
or nano
as well:
[developer@nso ~]$ ls
Desktop nso_show_commands.py shutdown.sh
Downloads sh-ip-br.txt
[developer@nso ~]$
In that file, import the NSO ncs
Python library and start with the following statement:
import ncs
with ncs.maapi.single_read_trans('admin', 'python', groups=['ncsadmin']) as t:
That first statement basically opens a transaction into NSO using the object t
as the transaction handler. Even though we are not going to make any configuration changes to the device, we still need to get access to the NSO application to send the show commands.
Now let’s add two more lines to the script:
import ncs
with ncs.maapi.single_read_trans('admin', 'python', groups=['ncsadmin']) as t:
root = ncs.maagic.get_root(t)
device_cdb = root.devices.device["dist-rtr01"]
We pass the t
transaction object into the get_root
method to get to the root of the NSO application data model. Think of this as getting to the base of the NSO CLI prompt and saving that place in the hierarchy into root
. Now that we have access to NSO and are at the root, we can navigate to certain parts of the application hierarchy and save variable names as shortcuts that make it easier to read. The device_cdb
is basically a device object that looks at the device list and then looks up the particular device dist-rtr01
. We used the name device_cdb
as a shorthand to remind us that this is an object in the NSO CDB referring to a device.
We are at this point in the CLI:
developer@ncs# devices device dist-rtr01 ?
So now we need to access the live-status
feature and feed in the inputs. I am not going to explain all the details at this point for the sake of brevity, but you can refer to the CLI portion and compare it to the Python lines:
developer@ncs# devices device dist-rtr01 live-status exec any show ip interface brief
Finish the script with the following lines:
import ncs
with ncs.maapi.single_read_trans('admin', 'python', groups=['ncsadmin']) as t:
root = ncs.maagic.get_root(t)
device_cdb = root.devices.device["dist-rtr01"]
input1 = device_cdb.live_status.ios_stats__exec.any.get_input()
input1.args = ["show ip interface brief"]
show_command = device_cdb.live_status.ios_stats__exec.any(input1).result
print (show_command)
Run the script with python3 nso_show_commands.py
, and you can see the output:
[developer@nso ~]$ python3 nso_show_commands.py
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 10.10.20.175 YES NVRAM up up
GigabitEthernet2 172.16.252.21 YES NVRAM up up
GigabitEthernet3 172.16.252.25 YES NVRAM up up
GigabitEthernet4 172.16.252.2 YES NVRAM up up
GigabitEthernet5 172.16.252.10 YES NVRAM up up
GigabitEthernet6 172.16.252.17 YES NVRAM up up
Loopback0 unassigned YES unset administratively down down
dist-rtr01#
[developer@nso ~]$
Once you have that output, you can then put it through other industry-standard parsing engines to get structured data from the show command output (example: TextFSM or Genie and others).
You can also include similar code within your Python service code or put them in NSO actions.