(Addition) I wrote the sequel to this article on December 24, 2016. There is a more detailed description, so please take a look if you are interested. Continued, I touched the multi-vendor router control API library NAPALM
A router control API library called NAPALM was introduced in NANOG64. https://www.nanog.org/meetings/abstract?id=2588
NAPALM (reading is "Napalm" in Japanese. It was called "Napalm" in NANOG) is a Python library of OSS provided by Spotify, and the name is "Network Automation and". It seems to be an abbreviation for "Programmability Abstraction Layer with Multivendor support". The source code is available on github. https://github.com/spotify/napalm
As its name suggests, NAPALM can control the devices of the following multiple manufacturers with a unified API. The number of compatible router OSs may increase in the future.
Supported router OS
--Arista Switch OS EOS --JUNOS, a router OS made by Juniper --Cisco router OS IOS-XR --Fortinet appliance OS FortiOS
As far as the commit log on Github is concerned, full-scale development has started around March 2015, and the implemented functions are focused on the config setting part. NAPALM itself seems to position the current software as version 0.12. (It is described in setup.py)
NANOG64 Presentation Material introduces the functions of NAPALM as follows.
Supported Methods v0.1
Supported Methods v0.2(beta)
As of June 7, 2015, it seems that only the v0.1 part is implemented.
In addition to these, an extension module for calling from the configuration management tool Ansible is provided, and in NANOG64, a demonstration of submitting / committing a config utilizing Ansible to the router was performed.
Ansible Modules
The announcement and demonstration of the day are available on NANOG Youtube Channel.
I went through the Official Documentation Tutorial to understand how to use napalm.
Installing NAPALM is easy.
pip install napalm
If you have never used pip, please install pip by referring to this article.
The first packages to include in Python setuptools and pip http://www.lifewithpython.com/2012/11/Python-package-setuptools-pip.html
First try with cisco IOS-XR. In the module called pyIOSXR (https://github.com/fooelisa/pyiosxr) used in NAPALM, CISCO XML API /iosxr_r4-1/xml/programming/guide/xl41apidoc/xl41over.html) is used to implement IOS-XR settings. Therefore, in order to allow XML input on the router running IOS-XR, it is necessary to set the following config in advance. The timer value is appropriate, so change it if necessary.
xml agent tty
session timeout 30
!
I made the following Python application by referring to Tutorial of official documentation.
As an application flow, set the config file (change_hostname_configIOSXR.txt) that changes the router host name to'router1_changed_by_NAPALM'to the router, check the config difference, and if there is no problem, commit or discard. It has become. I wanted to check the progress of each one to see if it was working properly, so it looks bad, but I have a lot of print sentences.
run_napalm.py
#! /usr/bin/env python
from napalm import get_network_driver
driver = get_network_driver('IOSXR')
print 'Step.1 Create ios-xr instance : OK'
device = driver('192.168.0.1', 'test_user', 'test_passwd')
print 'Step.2 Set router information : OK'
device.open()
print 'Step.3 Open session : OK'
device.load_merge_candidate(filename='./change_hostname_configIOSXR.txt')
print 'Step.4 load_merge_candidate : OK'
print '### CHECK CANDIDATE CONFIG ###'
print device.compare_config()
print '### END CONFIG###'
print 'Step.5 Compare_config : OK'
print 'Do you commit? y/n'
choice = raw_input().lower()
if choice == 'y':
device.commit_config()
print 'Step.6 commit_config : OK'
elif choice == 'n':
device.discard_config()
print 'Step.6 Discard_config : OK'
else:
print 'Please input y or n. Discard candidate config'
device.discard_config()
print 'Step.6 Discard_config : OK'
device.close()
print 'Step.7 Close session : OK'
print 'Successful !!'
change_hostname_configIOSXR.txt
hostname router1_changed_by_NAPALM
First, check the configuration status of the IOS-XR router on the router before running the above tools.
RP/0/RSP0/CPU0:router1#show running-config
Sun Jun 7 10:53:33.157 JST
Building configuration...
!! IOS XR Configuration #####
!! Last configuration change at Sun Jun 7 10:42:57 2015 by test_user
!
hostname router1
clock timezone JST 9
logging trap debugging
logging console debugging
...
...
...
Next, let's run the created tool (run_napalm.py). When executed, the result will be output as shown below.
$ python run_napalm.py
Step.1 Create ios-xr instance : OK
Step.2 Set router information : OK
Step.3 Open session : OK
Step.4 load_merge_candidate : OK
### CHECK CANDIDATE CONFIG ###
---
+++
@@ -3 +3 @@
-hostname router1
+hostname router1_changed_by_NAPALM
@@ -280,0 +281 @@
+!
### END CONFIG###
Step.5 Compare_config : OK
Do you commit? y/n
y
Step.6 commit_config : OK
Step.7 Close session : OK
Successful !!
After running the tool, check if the settings are actually reflected on the router.
RP/0/RSP0/CPU0:router1_changed_by_NAPALM#show running-config
Sun Jun 7 10:59:42.313 JST
Building configuration...
!! IOS XR Configuration ######
!! Last configuration change at Sun Jun 7 10:56:07 2015 by test_user!
hostname router1_changed_by_NAPALM
clock timezone JST 9
logging trap debugging
logging console debugging
...
...
...
It seems that you were able to change the host name of the IOS-XR router correctly. By using the functions provided by NAPALM, it was relatively easy to write a router configuration application.
Next, try changing the host name of the JUNOS router using a script that is almost the same as the program used for IOS-XR.
The source code of the implemented application.
run_napalm.py
#! /usr/bin/env python
from napalm import get_network_driver
driver = get_network_driver('JUNOS')
print 'Step.1 Create junos instance : OK'
device = driver('192.168.0.2', 'test_user', 'test_passwd')
print 'Step.2 Set router information : OK'
device.open()
print 'Step.3 Open session : OK'
device.load_merge_candidate(filename='./change_hostname_configJUNOS.txt')
print 'Step.4 load_merge_candidate : OK'
print '### CHECK CANDIDATE CONFIG ###'
print device.compare_config()
print '### END CONFIG###'
print 'Step.5 Compare_config : OK'
print 'Do you commit? y/n'
choice = raw_input().lower()
if choice == 'y':
device.commit_config()
print 'Step.6 commit_config : OK'
elif choice == 'n':
device.discard_config()
print 'Step.6 Discard_config : OK'
else:
print 'Please input y or n. Discard candidate config'
device.discard_config()
print 'Step.6 Discard_config : OK'
device.close()
print 'Step.7 Close session : OK'
print 'Successful !!'
The execution result is here.
$ python run_napalm.py
Step.1 Create junos instance : OK
Step.2 Set router information : OK
No handlers could be found for logger "paramiko.hostkeys"
Traceback (most recent call last):
File "./run_napalm.py", line 14, in <module>
device.open()
File "/usr/lib/python2.7/site-packages/napalm/junos.py", line 32, in open
self.device.open()
File "/usr/lib/python2.7/site-packages/jnpr/junos/device.py", line 433, in open
raise EzErrors.ConnectTimeoutError(self)
jnpr.junos.exception.ConnectTimeoutError: ConnectTimeoutError(192.168.0.2)
That has failed. .. .. It seems that the login authentication part of paramiko, which is an SSH module, has failed. This may be a JUNOS router misconfiguration (netconf part?) Or a program bug, so I will continue to investigate.
If anyone can work well with the JUNOS router, please let me know.
Although NAPALM has just begun to be implemented, it has become very easy to develop tools because it is possible to write applications that operate routers without being aware of the model or manufacturer. Although only the config setting function has been implemented yet, it seems that the implementation at this stage can be used sufficiently in situations where the same settings are entered for multiple routers.
However, at the moment, it seems that functions and bugs that are being implemented are also included, so please perform sufficient verification before using it.
Looking into the source code of NAPALM itself, it is not difficult programmatically, and the basic part (base.py) is about 100 lines, so it seems that I can fully participate in development even at the individual level. was.
What surprised me when I saw the source code of github was that not only this NAPALM but also most of the pyIOSXR, pyEOS, and pyFG called inside were implemented by Auther David Barroso and Elisa Jasinska almost independently. It was what I was doing. From this project, I felt the enthusiasm that "If the manufacturer does not prepare it, let's make our own API!"
Recommended Posts