Python Network Automation with Netmiko - Part 2

Python Network Automation with Netmiko - Part 2
In: Netmiko Python NetDevOps

In the previous post, we have seen how to get started with Netmiko and send a single command to a Cisco device. In this second part, we will learn how to send multiple commands to multiple devices. If you haven't checked my previous post already, I highly recommend reading it first and coming back here.

Python Network Automation with Netmiko - Intro
Netmiko is a Python library developed by Kirk Byers that makes it easier to work and interact with network devices.

Send multiple configuration commands to a single device

Let's get real here, we don't use automation to send a single command to a single device, we want to send multiple commands (a mixture of show and config commands) using a single python script. Netmiko provides a way to achieve this via the send_config_set method.

send_config_set method,

  • Automatically enters to global configuration mode
  • After running the configs, it automatically exists the global configuration mode

As an example, let's say we want to configure a description on the switch-port and then create an ACL. send_config_set method is very useful in this instance.

from netmiko import ConnectHandler
import getpass

passwd = getpass.getpass('Please enter the password: ')

cisco_01 = {
    "device_type": "cisco_ios",
    "host": "10.10.20.17",
    "username": "cisco",
    "password": passwd, # Log in password from getpass
    "secret": passwd # Enable password from getpass
}

connection = ConnectHandler(**cisco_01)
connection.enable()

config_commands = ['interface gi0/0', 'descri WAN', 'exit', 'access-list 1 permit any']
connection.send_config_set(config_commands)

print('Closing Connection')
connection.disconnect()

As you can see above, I created a list of configuration commands that need to be pushed to the device and then used that list with the send_config_set method.

The first command will configure the description on the gi0/0 interface and the second command will create an ACL. After executing the script, we can verify the config on the device.

cisco-01#show interfaces description 
Interface                      Status         Protocol Description
Gi0/0                          up             up       WAN
Gi0/1                          admin down     down     
Gi0/2                          admin down     down     
Gi0/3                          admin down     down     

cisco-01#show access-lists 
Standard IP access list 1
    10 permit any

Connect to multiple devices

So far we've seen how to access a single device using Netmiko. In this example, we will learn how to connect to multiple devices by making a small tweak.

I set up three devices with the same user credentials for the sake of simplicity. First, we will send show commands to all three devices and later in the post, we will send configuration commands.

Send show commands to multiple devices

In Part-1, we defined the device parameters in a Python Dictionary and pass them to the Netmiko ConnectHandler. The same concept applies here, the only difference here is that we will have a list of dictionaries. Each dictionary within the list contains the device parameters. Below is my poor attempt to visualise where the list called device_list contains the dictionaries of all three devices.

Let's say we want Python to login into each device and run show run | incl hostname and print the output. The script will look like the following.

from netmiko import ConnectHandler
import getpass

passwd = getpass.getpass('Please enter the password: ')

my_devices = ['10.10.20.17', '10.10.20.18', '10.10.20.19'] #list of devices
device_list = [] #create an empty list to use it later

for device_ip in my_devices:
    device = {
        "device_type": "cisco_ios",
        "host": device_ip,
        "username": "cisco",
        "password": passwd, # Log in password from getpass
        "secret": passwd # Enable password from getpass
    }
    device_list.append(device)

print(device_list) #list of dictionaries

for each_device in device_list:
    connection = ConnectHandler(**each_device)
    connection.enable()
    print(f'Connecting to {each_device["host"]}')
    output = connection.send_command('show run | incl hostname')
    print(output)

    print(f'Closing Connection on {each_device["host"]}')
    connection.disconnect()

If I print the device_list Python list, it would look like the following.

[{'device_type': 'cisco_ios', 'host': '10.10.20.17', 'username': 'cisco', 'password': 'cisco123', 'secret': 'cisco123'}, {'device_type': 'cisco_ios', 'host': '10.10.20.18', 'username': 'cisco', 'password': 'cisco123', 'secret': 'cisco123'}, {'device_type': 'cisco_ios', 'host': '10.10.20.19', 'username': 'cisco', 'password': 'cisco123', 'secret': 'cisco123'}]

Okay, it looks very unreadable, let's make it 'pretty'. We can use Python json module which converts a Python object (dictionary in our case) into a JSON string. By adding these three lines, we can get a human-readable output.

import json

json_formatted = json.dumps(device_list, indent=4)
print(json_formatted)
[
    {
        "device_type": "cisco_ios",
        "host": "10.10.20.17",
        "username": "cisco",
        "password": "cisco123",
        "secret": "cisco123"
    },
    {
        "device_type": "cisco_ios",
        "host": "10.10.20.18",
        "username": "cisco",
        "password": "cisco123",
        "secret": "cisco123"
    },
    {
        "device_type": "cisco_ios",
        "host": "10.10.20.19",
        "username": "cisco",
        "password": "cisco123",
        "secret": "cisco123"
    }
]

If I run the script now, I will get the following output.

PS C:\Users\vsurr\Documents\Projects\netmiko-multiple-device.py

Please enter the password:
Connecting to 10.10.20.17
hostname cisco-01
Closing Connection on 10.10.20.17
Connecting to 10.10.20.18
hostname cisco-02
Closing Connection on 10.10.20.18
Connecting to 10.10.20.19
hostname cisco-03
Closing Connection on 10.10.20.19

Send configuration commands to multiple devices

In this example, we will learn how to send multiple 'configuration commands' to the three devices.

from netmiko import ConnectHandler
import getpass

passwd = getpass.getpass('Please enter the password: ')

my_devices = ['10.10.20.17', '10.10.20.18', '10.10.20.19']
device_list = list() #create an empty list to use it later

for device_ip in my_devices:
    device = {
        "device_type": "cisco_ios",
        "host": device_ip,
        "username": "cisco",
        "password": passwd, # Log in password from getpass
        "secret": passwd # Enable password from getpass
    }
    device_list.append(device)

print(device_list)

config_commands = ['access-list 5 permit host 1.1.1.1', 'ntp server 192.168.1.1' ]

for each_device in device_list:
    connection = ConnectHandler(**each_device)
    connection.enable()
    print(f'Connecting to {each_device["host"]}')
    output = connection.send_config_set(config_commands)
    print(output)

    print(f'Closing Connection on {each_device["host"]}')
    connection.disconnect()

As you can see below, Python logins to all three routers and ran the configuration commands we specified in the script.

PS C:\Users\vsurr\Documents\Projects\python-learning\multiple-device-config-commands.py
Please enter the password:
Connecting to 10.10.20.17
configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
cisco-01(config)#access-list 5 permit host 1.1.1.1
cisco-01(config)#ntp server 192.168.1.1
cisco-01(config)#end
cisco-01#
Closing Connection on 10.10.20.17
Connecting to 10.10.20.18
configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
cisco-02(config)#access-list 5 permit host 1.1.1.1
cisco-02(config)#ntp server 192.168.1.1
cisco-02(config)#end
cisco-02#
Closing Connection on 10.10.20.18
Connecting to 10.10.20.19
configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
cisco-03(config)#access-list 5 permit host 1.1.1.1
cisco-03(config)#ntp server 192.168.1.1
cisco-03(config)#end
cisco-03#
Closing Connection on 10.10.20.19

Closing up

I hope both articles were easy to follow and helpful in your automation journey. If you have any comments or feedback, please let me know in the comments.

Table of Contents
Written by
Suresh Vina
Tech enthusiast sharing Networking, Cloud & Automation insights. Join me in a welcoming space to learn & grow with simplicity and practicality.
Comments
More from Packetswitch
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Packetswitch.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.