Hi all, welcome back to the Packetswitch blog. In today's post, we'll explore how to use NAPALM for managing device configurations. We'll focus on Arista EOS as our example. We'll cover the methods available in NAPALM and how to push, commit and revert configurations on Arista devices.
We'll start by explaining what NAPALM is and why you might want to use it. Then we'll move on to a few examples and take a look at what happens behind the scenes. This approach will give you a clear understanding of NAPALM's role in network configuration management and how it works with Arista EOS devices.
What is Napalm?
NAPALM stands for Network Automation and Programmability Abstraction Layer with Multivendor support. It's a Python library that helps network engineers manage and automate different network devices using a common set of functions. NAPALM solves the problem of dealing with multiple vendor-specific interfaces by providing a unified way to interact with network devices from various manufacturers. This means you can use the same code to manage devices from Cisco, Juniper, Arista, and others, saving time and reducing the complexity of network automation tasks.
If you're new to NAPALM and want to learn the basics, feel free to check out my introductory post above. In this article, we'll focus specifically on configuration management using NAPALM. You can install NAPALM by running a simple pip command.
pip install napalm
A quick note on Arista Configure Sessions
Please note that NAPALM's method uses Arista's configure session to make config changes, show you the diffs, and commit or revert the changes. I wrote a blog post on configure sessions, so feel free to check it out. It's not mandatory, but it's good to know what's happening behind the scenes.
NAPALM Configuration Methods
NAPALM exposes several methods for managing configurations.
• get_config()
- Retrieves the device configuration
• load_replace_candidate()
- Replaces the full configuration
• load_merge_candidate()
- Merges partial configurations
• commit_config()
- Applies the loaded configuration
• discard_config()
- Discards the loaded configuration
• commit_config(revert_in=300)
with timer - Commits changes with a timer.
I'll explain these in detail later, but this overview gives you a sense of the key operations NAPALM provides for configuration management.
get_config()
In this first example, we use NAPALM to retrieve the configuration from an Arista EOS device. We start by importing the necessary function and setting up the EOS driver. We then create a dictionary with the device's connection details, including its IP address, username, and password.
from napalm import get_network_driver
driver = get_network_driver('eos')
aggr_01 = {
"hostname": '192.168.100.210',
"username": "admin",
"password": 'admin',
"optional_args": {"secret": 'admin'}
}
aggr_01_conn = driver(**aggr_01)
aggr_01_conn.open()
output = aggr_01_conn.get_config()
aggr_01_conn.close()
print(output['running'])
Using these details, we establish a connection to the device. Once connected, we call the get_config()
method to fetch the device's configuration. After retrieving the config, we close the connection.
Finally, we print the running configuration. It's worth noting that while NAPALM fetches both the running and startup configurations, we're only printing the running config in this example.
If you are wondering how NAPALM retrieves the configuration, it's simple. It uses Arista's eAPI to connect and execute the typical commands, as shown below.
load_replace_candidate()
For the second example, let’s see how to replace the existing configuration with a new one. This process requires a completely new configuration file. In our example, I've copied the current running configuration and made a slight modification by adding VLAN 99.
from napalm import get_network_driver
driver = get_network_driver('eos')
aggr_01 = {
"hostname": '192.168.100.210',
"username": "admin",
"password": 'admin',
"optional_args": {"secret": 'admin'}
}
device = driver(**aggr_01)
device.open()
output = device.load_replace_candidate('full_config.conf')
print(device.compare_config())
device.close()
In the script, we are using the load_replace_candidate()
method. After opening a connection to the device, this method loads a new configuration file specified as full_config.conf
. The script then uses compare_config()
method to display the differences between the current running configuration and the new configuration we loaded.
#output
python replace_config.py
+vlan 99
+ name test
It’s important to note that we are not committing these changes; we are only reviewing the differences. This means the actual configuration on the device remains unchanged, and we close the connection without making any changes.
Again, if we look behind the scenes, NAPALM connects to the device and uses a configure session to reset to a clean configuration, essentially a factory reset, before applying our new config. Remember, all this occurs within a configure session, which doesn't impact the live running configuration. NAPALM then closes the connection, automatically discards the candidate configuration, and exits the device.
device.discard_config()
method. Committing the Configuration
If you decide to apply the changes, use the commit_config()
method, which updates the live device with the new configuration. Behind the scenes, the process remains the same except that NAPALM now commits the configuration changes.
device = driver(**aggr_01)
device.open()
output = device.load_replace_candidate('full_config.conf')
print(device.compare_config())
device.commit_config()
device.close()
Now you can see VLAN 99 in the running-configuration.
aggr-01#show vlan
VLAN Name Status Ports
----- -------------------------------- --------- -------------------------------
1 default active
10 finance active Cpu, Et5, Et6, Po1
20 sales active Cpu, Et5, Et6, Po1
30 cctv active Cpu, Et5, Et6, Po1
99 test active
load_merge_candidate()
Similar to load_replace_candidate()
, the load_merge_candidate()
method merges a partial configuration with the existing running configuration. This process is helpful when you want to add or modify a specific part of the configuration without replacing the entire configuration. Here’s an example where we add a new VLAN.
#vlan.conf
vlan 105
name test5
!
from napalm import get_network_driver
driver = get_network_driver('eos')
aggr_01 = {
"hostname": '192.168.100.210',
"username": "admin",
"password": 'admin',
"optional_args": {"secret": 'admin'}
}
device = driver(**aggr_01)
device.open()
output = device.load_merge_candidate('vlan.conf')
print(device.compare_config())
device.commit_config()
device.close()
Committing With a Timer
Arista supports a commit timer feature that allows for scheduled commits with a built-in rollback if not reconfirmed. When you use the commit timer feature, the configuration changes are initially committed with a timer. If you do not reconfirm the commit before the timer expires, the changes are automatically rolled back. This ensures that if the changes have unintended effects, they won't remain unless explicitly confirmed within the given timeframe.
from napalm import get_network_driver
driver = get_network_driver('eos')
aggr_01 = {
"hostname": '192.168.100.210',
"username": "admin",
"password": 'admin',
}
device = driver(**aggr_01)
device.open()
output = device.load_merge_candidate('vlan.conf')
print(device.compare_config())
device.commit_config(revert_in=300)
print(device.has_pending_commit())
device.confirm_commit()
device.close()
In this example, the commit_config(revert_in=300)
method initially applies the changes but schedules an automatic rollback after 300 seconds unless the commit is confirmed. You can use the has_pending_commit()
method to check if the initial commit is still pending. This is useful to verify that the commit needs confirming. If the tests pass and you are satisfied with the changes, you can permanently commit them using the confirm_commit()
method before the timer expires.
This method is particularly useful in environments where you can test the applied changes within the delay window. If something goes wrong, or if the timer expires without confirmation, the device automatically reverts to the previous configuration, minimizing the risk of disruptions.