Introduction to NAPALM Network Automation on Cisco IOS

, November 26th 2019

(UPDATE: We now have a video demo to accompany this post! Check it out on YouTube.)

The challenge of automating network configuration is compounded in multi-vendor environments. A solution to this challenge is NAPALM, an open-source Python library. Today, let's take a look at the library and see how we can use it to push configuration to a Cisco router.

Engineers interested in network automation should definitely check out NAPALM. The library is far easier to use than the acronym is to remember (Network Automation and Programmability Abstraction Layer with Multivendor support).

Expect scripts are sloppy

Imagine writing an "expect" script to push configuration to a Cisco router over an SSH session. This script would require a huge amount of refactoring to make it work with the hardware of another vendor.

NAPALM fixes this challenge by abstracting away the driver for interacting with network infrastructure. A NAPALM program written for a Cisco router will work on a Juniper router with only minimal changes.

A practical approach to learning is always best so let's configure an interface on a Cisco router using NAPALM.

How to install NAPALM

The VM I'm using for this tutorial is Ubuntu 18.04. Let's begin by opening up a terminal and installing the NAPALM library.

pip install napalm

We also require a few other packages for the napalm-ios driver.

sudo apt-get install -y libssl-dev libffi-dev python-dev python-cffi

Importing the NAPALM library

Let's now create a new file for our python program and import the required dependencies.

#!/usr/bin/env python

# Filename:                     napalm-tutorial.py
# Command to run the program:   python napalm-tutorial.py

# Import dependencies
from napalm import get_network_driver
import json

HOW TO CONNECT TO A CISCO ROUTER WITH NAPALM

I'm running a Cisco CSR router on GNS3 for this tutorial. Let's add python code to connect to the device and fetch some basic facts about it.

driver = get_network_driver('ios')
device = driver('192.168.159.10', 'admin', 'ultraconfig')
device.open()
print(json.dumps(device.get_facts(), indent=2))
device.close()

The NAPALM API is very readable. We set our driver to "ios", establish a connection, and fetch the desired details.

Executing a NAPALM program

Executing the program yields the output below.

{
  "os_version": "Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.9.3, RELEASE SOFTWARE (fc2)",
  "uptime": 840,
  "interface_list": [
    "GigabitEthernet1",
    "GigabitEthernet2",
    "GigabitEthernet3",
    "GigabitEthernet4"
  ],
  "vendor": "Cisco",
  "serial_number": "9HAWG2NZF95",
  "model": "CSR1000V",
  "hostname": "Router",
  "fqdn": "Router.not set"
}

How to fetch config using NAPALM

We can also fetch the running configuration of the router using the get_config() method.

driver = get_network_driver('ios')
device = driver('192.168.159.10', 'admin', 'ultraconfig')
device.open()
print(device.get_config()['running'])
device.close()

Executing the program now yields the running-config.

Building configuration...

Current configuration : 3743 bytes
!
! Last configuration change at 21:36:22 UTC Fri Nov 22 2019
!
version 16.9
service timestamps debug datetime msec
service timestamps log datetime msec
platform qfp utilization monitor load 80
no platform punt-keepalive disable-kernel-core
platform console serial
!
...

Exploring the NAPALM API

The NAPALM library offers a huge range of methods we can invoke on a device object. Check them out in the official docs.

Let's fetch the active IP interfaces using the get_interfaces_ip() method.

driver = get_network_driver('ios')
device = driver('192.168.159.10', 'admin', 'ultraconfig')
device.open()
print(json.dumps(device.get_interfaces_ip(), indent=2))
device.close()

The output is a nicely formatted JSON object.

{
  "GigabitEthernet1": {
    "ipv4": {
      "192.168.159.10": {
        "prefix_length": 24
      }
    }
  }
}

How to change the running-config using NAPALM

So, how can we modify the running configuration on the router using NAPALM? The NAPALM IOS driver works best with SCP so let's first ensure our router is correctly staged.

conf t
ip scp server enable
end

We'll now modify our python program to configure an interface.

driver = get_network_driver('ios')
device = driver('192.168.159.10', 'admin', 'ultraconfig')
device.open()
device.load_merge_candidate(config='interface GigabitEthernet2\n ip address 10.0.0.1 255.255.255.0\n no shutdown\n end\n')
print(device.compare_config())
device.commit_config()
device.close()

Executing the python program will print the config changes to the terminal.

+interface GigabitEthernet2
+ ip address 10.0.0.1 255.255.255.0
- no shutdown

Finally, we can verify the config changes were made on the router.

Router#show running-config interface GigabitEthernet 2
Building configuration...

Current configuration : 117 bytes
!
interface GigabitEthernet2
 ip address 10.0.0.1 255.255.255.0
 negotiation auto
 no mop enabled
 no mop sysid
end

That concludes the tutorial! Stay tuned for more!

ULTRA CONFIG GENERATOR

NAPALM is great at pushing configuration to network devices. But how can we automate the generation of network config?

Have you heard of Ultra Config Generator? If you haven't, I highly recommend you check it out.

We designed the product to allow network engineers to generate and automate network configuration in a highly flexible, efficient and elegant manner. Our users love the application and I hope that you will too.

Take care until next time!

Ultra Config


JOIN THE DISCUSSION

Subscribe to the Blog

Subscribe now and never miss a new post!