Trying out Nornir automation
- Trying out the NORNIR network automation and documenting few way to capture data from networking devices.
- I like the way we can import its different module into the python program that you might already be working on.
- Nornir is supported with Python 3.6 version and above.
- Using Nornir, we can call netmiko module to capture data from router using command, we can also use napalm module as well for same task.
#Required imports
from nornir import InitNornir
from nornir.plugins.tasks.networking import netmiko_send_command
from nornir.plugins.tasks.networking import napalm_get, napalm_cli
from nornir.plugins.functions.text import print_result
from pprint import pprint as pprint
'''
Create nornir object which will use the hosts.yaml and
groups.yaml files to
'''
nr = InitNornir()
print(nr.inventory.hosts)
print(nr.inventory.groups)
Output:
{'r1': Host: r1}
{'mylab': Group: mylab}
Output:
{'r1': Host: r1}
{'mylab': Group: mylab}
Using netmiko module in nornir to capture BGP summary output:
result = nr.run(
task=netmiko_send_command,
command_string="show bgp summary"
)
print_result(result)
Output:
Output:
netmiko_send_command************************************************************
* r1 ** changed : False ********************************************************
vvvv netmiko_send_command ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
Groups: 4 Peers: 5 Down peers: 3
Table Tot Paths Act Paths Suppressed History Damp State Pending
inet.0
0 0 0 0 0 0
bgp.l3vpn.0
2 2 0 0 0 0
...
Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
1.1.11.2 200 0 0 0 0 1w3d 8:25:11 Idle
2.1.1.2 200 0 0 0 0 1w3d 8:25:11 Idle
192.168.1.2 100 102189 102311 0 2 3d 5:04:01 Establ
inet.0: 0/0/0/0
bgp.l3vpn.0: 1/1/1/0
bgp.l2vpn.0: 0/0/0/0
bgp.evpn.0: 0/0/0/0
bgp.mvpn.0: 0/0/0/0
bgp.mdt.0: 0/0/0/0
mvpn.inet.0: 1/1/1/0
192.168.200.1 100 103606 103169 0 1 3d 5:42:45 Establ
inet.0: 0/0/0/0
bgp.l3vpn.0: 1/1/1/0
bgp.l2vpn.0: 0/0/0/0
bgp.evpn.0: 0/0/0/0
bgp.mvpn.0: 0/0/0/0
bgp.mdt.0: 0/0/0/0
mvpn.inet.0: 1/1/1/0
2001:1:1::1 1 0 0 0 0 1w3d 8:25:11 Idle
^^^^ END netmiko_send_command ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using napalm in nornir to execult the JUNOS cli command:
result = nr.run(
napalm_cli,
commands=['show system processes extensive | match rpd', 'show system processes extensive | match mem'])
print_result(result)
Output:
=======
napalm_cli**********************************************************************
* r1 ** changed : False ********************************************************
vvvv napalm_cli ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
{ 'show system processes extensive | match mem': 'Mem: 146M Active, 3462M '
'Inact, 927M Wired, 530M Buf, '
'11G Free',
'show system processes extensive | match rpd': '96074 root 20 0 '
'1152M 176M kqread 1 '
'7:58 0.00% rpd{rpd}\n'
'96074 root 20 0 '
'1152M 176M kqread 0 '
'7:37 0.00% '
'rpd{TraceThread}\n'
'96074 root 20 0 '
'1152M 176M kqread 1 '
'1:27 0.00% rpd{rsvp-io}\n'
'96074 root 20 0 '
'1152M 176M kqread 1 '
'1:11 0.00% '
'rpd{bgpio-0-th}\n'
'96074 root 20 0 '
'1152M 176M kqread 0 '
'0:09 0.00% rpd{krtio-th}'}
^^^^ END napalm_cli ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
=======
Identify type of result to read output further:
print(type(result))
Output:
<class 'nornir.core.task.AggregatedResult'>
Using napalm getters in nornir:
cmd = "show version"
result = nr.run(
napalm_get,
getters = ['bgp_neighbors'])
print_result(result)
Output:
=======
napalm_get**********************************************************************
* r1 ** changed : False ********************************************************
vvvv napalm_get ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
{ 'bgp_neighbors': { 'global': { 'peers': { '1.1.11.2': { 'address_family': { 'ipv4': { 'accepted_prefixes': -1,
'received_prefixes': -1,
...
'local_as': 100,
'remote_as': 200,
'remote_id': '',
'uptime': 894325},
...
'router_id': ''},
'mvpn': { 'peers': { '2.1.1.2': { 'address_family': { 'ipv4': { 'accepted_prefixes': -1,
'received_prefixes': -1,
...
'local_as': 100,
'remote_as': 200,
'remote_id': '',
'uptime': 894325}},
'router_id': ''}}}
^^^^ END napalm_get ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
print(result)
Output:
AggregatedResult (napalm_get): {'r1': MultiResult: [Result: "napalm_get"]}
Pythonic way to extract the specific details of BGP neighbor:
print(type((result['r1'][0].result)))
print((((result['r1'][0].result)['bgp_neighbors'])).keys())
pprint((((result['r1'][0].result)['bgp_neighbors']))['mvpn'])
Output:
=======
<class 'dict'>
dict_keys(['global', 'mvpn'])
{'peers': {'2.1.1.2': {'address_family': {'ipv4': {'accepted_prefixes': -1,
'received_prefixes': -1,
...
'local_as': 100,
'remote_as': 200,
'remote_id': '',
'uptime': 894325}},
'router_id': ''}