How to use NAPALM (Python library) to Manage IOS Devices
NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support) is a Python library that eases configuration management and data collection for various types of network devices. It uses vendor specific APIs such as eAPI for Arista and NETCONF for Juniper, as two examples, but has a pluggable architecture, so it's quite extensible should you want to add different drivers for each device type. Further more, it's actually re-using existing Python libraries such as Juniper's PyEZ for Junos, Arista's pyeapifor EOS, and netmiko for IOS support. It has immense value because it unifies networks operations for various tasks across a large number device platforms.
This tutorial is focused on providing a jump start on using the NAPALM Python library specifically for managing configurations on IOS devices. In follow up tutorials, we'll look at gathering data, using other vendors, and then using Ansible + NAPALM together.
The first thing you need to do is ensure you have NAPALM installed.
This is already done on our jump host in the pre-built NAPALM IOS environment.
pip install napalm # sudo if you must
For instructions on how to perform upgrades and selectively install certain drivers and upgrades, see here.
Each IOS device needs to have a basic configuration before you can use NAPALM.
Ensure each device has a proper user account with privileges, SCP enabled, a management IP address, and the archive feature enabled.
Here is a base configuration we use in our labs to prepare the CSR 1000V for NAPALM.
username ntc privilege 15 password 0 ntc123 ! ip scp server enable ! archive path bootflash:archive ! interface GigabitEthernet1 description MANAGEMENT vrf forwarding Mgmt-Intf ip address dhcp ! line vty 0 4 privilege level 15 login local transport input ssh !
Note: this is already done on our jump host in the pre-built NAPALM IOS environment.
Create New Config File
The goal is to push a new configuration file to the device and activate it as the new running configuration in real time. First, we need to create our new configuration.
SSH into csr1, do a show run, and save the output into a file called
newconfig.cfg. When you save the new config, ensure these lines are NOT in the new config:
Building configuration... Current configuration : 1745 bytes
The only change you should make is for Gig4 (in reality, it could be a complete new configuration). This is the interface that connects to csr2.
Ensure the following section is included in
interface GigabitEthernet4 description CONNECTS_TO_CSR2_GI4 ip address 10.1.12.1 255.255.255.0 no shutdown negotiation auto cdp enable !
Save it in the home directory (
Create Device Object
We need to establish a connection to the device, but before that, we need to select the right driver to use in NAPALM. You can just drop right into the Python shell from the home directory (
/home/ntc) on the jump host to try it out.
>>> from napalm import get_network_driver >>> driver = get_network_driver('ios') `
Now we can create the device object and connect to the device.
>>> device = driver('csr1', 'ntc', 'ntc123') >>> device.open() `
Load New Configuration (REPLACE)
The next step is to load the actual configuration onto the router. Behind the scenes,
newconfig.cfg is being SCP'd to csr1 and saves it as the filename
If you do a
dir on csr1 now, you'll see this file:
20 -rw- 1836 Apr 28 2016 14:42:06 +00:00 candidate_config.txt
It's officially loaded (copied) onto the device.
Compare New Configuration with Running Configuration
It's time to compare the new candidate configuration, i.e.
candidate_config.txt with the existing running configuration. We'll use the
>>> diffs = device.compare_config() >>> >>> print diffs interface GigabitEthernet4 +description CONNECTS_TO_CSR2_GI4 +ip address 10.1.12.1 255.255.0 +no shutdown interface GigabitEthernet2 -no ip address
You can now see exactly what WILL get applied when this configuration is committed to the device.
Commit the New Configuration
If you are okay with the diffs, the next step is to commit the configuration.
>>> device.commit_config() >>>
Once it completes, you can check the router and view the new configuration:
csr1#show run int gi4 Building configuration... Current configuration : 134 bytes ! interface GigabitEthernet4 description CONNECTS_TO_CSR2_GI4 ip address 10.1.12.1 255.255.255.0 negotiation auto cdp enable end
And that's it! That is how you use the configuration replace functionality using NAPALM. This offers a way to declaratively push a configuration to a network device and only apply the diffs, required to get the device into the desired state.
After the configuration is committed, you'll see a new file on the router file system called
rollback_config.txt. This file is used just in case you must rollback.
To rollback, you use the
>>> device.rollback() >>>
If you choose to rollback, your initial configuration is re-applied to the device. If you SSH back into the device, you'll see this.
We'll now briefly look at how to do a merge of a configuration as compared to a full replacement. This may be needed if you don't or can't push a full configuration to the device.
Create Config File for Merge Operation
We'll configure csr2 using the configuration merge method to establish IP connectivity between csr1 and csr2.
In the home directory, create a new config file called
csr2-interface.cfg. It should ONLY have the following in it. It should NOT be a full configuration.
interface GigabitEthernet4 description CONNECTS_TO_CSR1_GI4 ip address 10.1.12.2 255.255.255.0 no shutdown negotiation auto cdp enable !
Establish Connectivity to CSR2
>>> csr2 = driver('csr2', 'ntc', 'ntc123') >>> csr2.open()
Load New Configuration (MERGE)
When you're doing a merge, just a partial config, and not a full replace, you use the
>>> csr2.load_merge_candidate(filename='csr2-interface.cfg') >>>
This method SCPs the file to the router. On the router, it'll have the filename
NOTE: CURRENTLY, YOU CANNOT VIEW DIFFS / COMPARE CONFIGS FOR IOS DEVICES.
Commit the Configuration
>>> device.commit_config() >>> csr2#show run int gi4 Building configuration... Current configuration : 135 bytes ! interface GigabitEthernet4 description CONNECTS_TO_CSR1_GI4 ip address 10.1.12.2 255.255.255.0 negotiation auto cdp enable end
You should now be able to ping 10.1.12.1 from csr2 and 10.1.12.2 from csr1.