1 of 57

Network Programmability using Netmiko for those New to Python

Rick Graziani

Cabrillo College

University of California Santa Cruz

2023

2 of 57

  • Why Netmiko? (quick)
  • Netmiko's 3 basic commands (methods)
    • Import Netmiko
    • Connect to your device
    • Disconnect from your device
  • Sending an IOS command with:
    • send_command()
    • send_command_expect()
  • 'copy run start' with save_config()
  • Configuring your IOS device with:
    • send_command()
    • send_command_set()
    • send_command_from_file()
  • Summary (NAPALM?)

Python

  • Keeping code and terms simple for those NEW to Python
  • Many options and variations including use of dictionaries, functions, etc.
    • Contact me offline or see coming YouTube channel and code
  • Just using: print() and a variable
  • One 'for loop' to show accessing multiple devices

At the end:

  • Access to my Python code for Netmiko and TCP/IP (code and videos)

Agenda

3 of 57

Cisco Routing and Switching

CCNA or Net Essentials or Net Basics

Besides DevNet…

Future of networking

Cisco IOS

Python

Netmiko/NAPALM

(and others)

Cisco IT students

Network Programmability and Automation

NETCONF, RESTCONF, YANG, APIs

Software Developers

  • Is DevNet the only or best option to learn network automation?
  • I would like to learn coding but I'm not sure how it relates to networking?

4 of 57

Python

Netmiko

Structured Data

Dictionaries-JSON *JSON XML JSON-XML

Ansible

NAPALM

Cisco IOS or XR/XE/NX-OS

Cisco XR/XE/NX-OS

NETCONF

RESTCONF

Models

YANG/XSD YANG

Python

NORNIR

* Python

Netmiko offers an easy introduction to network programmability (a higher-level abstraction) with features tailored specifically for network automation.

Netmiko (NAPLAM and NORNIR too)

  • No API needed
  • No VM needed
  • No agent software needed
  • Works on any IOS

Telnet/SSH

SSH

* SSH

SSH

HTTPS

APIs

RPC API RESTFUL API

Postman

CLI commands/output

+ Netmiko

Vendor agnostic

NAPALM

CLI commands/output

+ YAML Inventory

YANG/XSD Models

YANG Models

Netmiko/NAPALM (YAML Inventory)

5 of 57

Python

Netmiko

(Start Here)

Structured Data

Dictionaries-JSON-YAML-XML

Ansible

(YAML, Python)

NAPALM

(Intermediate)

Cisco IOS or XR/XE/NX-OS

+ SSH (Telnet – Netmiko only)

Cisco XR/XE/NX-OS

+ API support

NETCONF

(XML)

RESTCONF

(JSON/XML)

YANG

Python

Generic commands

IOS commands

+ Inventory

NETCONF RPC (SSH)

REST API (Postman)

NORNIR

(Advanced)

IOS commands

Netmiko or NAPALM

+Inventory (Ansible)

Python

Netmiko offers an easy introduction to network programmability (a higher-level abstraction) with features tailored specifically for network automation.

Netmiko (NAPLAM and NORNIR too)

  • No API needed
  • No VM needed
  • No agent software needed
  • Works on any IOS

6 of 57

Automation, Programmability, and Beyond

IOS

Python

Netmiko

NAPALM

Dictionaries

ITN or SWRE

"Okay, I have everything I need to START learning about network automation and programmability…"

loads/dumps

JSON - XML

RPC API

REST API

Python

urlib

Client VM

RESTCONF

NETCONF

ENSA

Exactly what the experts say where NOT to start

Light boxes

Cisco VM

VirtualBox

My first lab

dictionaries

7 of 57

Automation, Programmability, and Beyond

IOS

Python

Netmiko

NAPALM

Dictionaries

ITN or SWRE

"Okay, I have everything I need to START learning about network automation and programmability…"

JSON

YAML

API

REST

DNA

IBN

Agents

SDN

Python

urlib

Postman

RESTCONF

NETCONF

Ansible

SD-WAN

ENSA

Exactly what the experts say where NOT to start

Light boxes

8 of 57

  1. Students with minimum knowledge of Python get to do some cool coding!
  2. Students with even a very limited knowledge of IOS, get to "program" routers/switches!
    • Uses Cisco IOS commands (advantage for beginner)
  3. Minimal Requirements: Requires only Telnet or SSH connectivity

As you grow with IOS or as you grow with Python you can do more network automation with Netmiko (developed by Kirk Byers)

SSH

Telnet

Why Netmiko?

9 of 57

Ivan Pepelnjak

“Do not underestimate the utility of the SSH Netmiko library, as it’s proven useful in providing a smooth transition from traditional network CLI management to network automation, and it’s heavily used and developed

"Netmiko is a Python library built on top of Paramiko that addresses these problems. If you want to connect to a wide variety of network devices without losing your sanity Netmiko is your best bet."

10 of 57

  1. Install Python
  2. Install Netmiko

MacOS% pip3 install netmiko

3. Verify SSH/Telnet connectivity to device

Getting Started

11 of 57

Setup

  • Routers and switches preconfigured
  • IPv4 static routes for reachability
  • Can SSH to any device

ME

12 of 57

# Our first Netmiko program

import netmiko

 

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios',

username='admin',

password='cisco’)

 

print(connection.send_command('show ip interface brief'))

 

connection.disconnect()

Note: For telnet, use:

device_type='cisco_ios_telnet'

Can you figure out what this does?

It really is that easy!

13 of 57

# Required: Imports the Netmiko library

import netmiko

# Required: Netmiko ConnectHandler handles the SSH connection using specified 'arguments'

# The connection object (variable) represents the connection to the specified device

# Allows you to interact with it using various Netmiko methods like the send_command.

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios',

username='admin',

password='cisco’)

# Using the connection object, the send_command method sends a command

# to a network device and retrieves the corresponding output.  

print(connection.send_command('show ip interface brief’))

# Required: The disconnect method in Netmiko is used to close the SSH connection

# to a network device, ensuring proper cleanup 

connection.disconnect()

netmiko_1a_

This is the basic framework.

Just add Netmiko/IOS commands!

1

2

3

Device IP address

Device OS

SSH username &password

14 of 57

# Imports the Netmiko library

import netmiko

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios',

username='admin',

password='cisco’)

# Previous command: Prints the output (if any) from the command

# print(connection.send_command('show ip interface brief'))

# Send output to a variable (output) and then print the (string) variable

output = connection.send_command('show ip interface brief')

print(output)

connection.disconnect()

netmiko_1a_

Same result when using send_command() but differences with other methods

send_command() Another option

15 of 57

Let’s try it! send_command()

netmiko_1a_

16 of 57

An optional Python tangent…

In Python, both objects and variables play distinct roles, but understanding the difference requires a closer look at how Python handles them:

  • Object:
    • An object is a data structure that represents a particular instance of a class or data type.
    • Everything in Python is an object, including integers, strings, lists, dictionaries, functions, and custom-defined classes.
    • Objects have attributes and methods associated with them.
  • Variable:
    • A variable is a name that refers to a specific object in memory.
    • It acts as a reference or a label for an object.
    • Variables are assigned values (objects) using the assignment operator (=).

17 of 57

Output (Backup)

Interface IP-Address OK? Method Status Protocol

Embedded-Service-Engine0/0 unassigned YES NVRAM administratively down down

GigabitEthernet0/0 192.168.1.1 YES NVRAM up up

GigabitEthernet0/1 192.168.2.1 YES NVRAM up up

Serial0/0/0 unassigned YES NVRAM administratively down down

Serial0/0/1 unassigned YES NVRAM administratively down down

Interface IP-Address OK? Method Status Protocol

Embedded-Service-Engine0/0 unassigned YES NVRAM administratively down down

GigabitEthernet0/0 192.168.1.1 YES NVRAM up up

GigabitEthernet0/1 192.168.2.1 YES NVRAM up up

Serial0/0/0 unassigned YES NVRAM administratively down down

Serial0/0/1 unassigned YES NVRAM administratively down down

MacOS%

18 of 57

import netmiko

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios',

username='admin',

password='cisco’)

 

# send_command_expect() method is used to specify a string that Netmiko should

# expect to see in the command's output before considering the command as complete.

# Used for confirmation and automatically responds to prompt

# expect_string should be unique enough to identify the point at which the script

# needs to take action, ex. Destination filename [startup-config]?

print(connection.send_command_expect('copy running-config startup-config',

expect_string='Destination filename'))

 

connection.disconnect()

send_command_expect() When IOS expects input/confirmation

19 of 57

Let’s try it! send_command_expect()

Insignificant Python Change:

  • Assigned IPv4 address of the device to a string variable so I can print the IPv4 address later.

Added some print commands for readability

20 of 57

Output (Backup)

MacOS%

192.168.1.1 copy running-config startup-config

-----------

Destination filename [startup-config]?

Success!

MacOS%

21 of 57

import netmiko

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios',

username='admin',

password='cisco')

print("\n")

print("Save running-config to startup-config...")

connection.save_config()

print("Success!")

print("\n")

print("show startup-config...")

print(connection.send_command('show startup-config'))

connection.disconnect()

save_config() Same as 'copy run start'

22 of 57

Output (Backup)

MacOS%

Save running-config to startup-config...

Success!

show startup-config...

Using 1942 out of 262136 bytes

!

version 15.4

service timestamps debug datetime msec

service timestamps log datetime msec

no service password-encryption

!

hostname R2

!

boot-start-marker

boot-end-marker

!

<output omitted>

MacOS%

23 of 57

import netmiko

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios',

username='admin',

password='cisco')

# Secret password not required (enable secret class) for these commands

# However, there are ways to 'secure' these commands within Cisco IOS

print(connection.send_command('User Exec IOS Command'))

print(connection.send_command('show running-config'))

print(connection.send_command_expect('copy running-config startup-config',

expect_string='Destination filename'))

connection.save_config()

 

connection.disconnect()

Related code you can download from Rick…

  • Do an extended ping with send_command_expect()
  • Display the prompt with find_prompt()

So far…

show commands, saving config

24 of 57

import netmiko

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios',

username='admin',

password='cisco',

secret='class') # Enable password

# send_command() for configuration is similar to CLI - secret password is required

connection.enable() # Privileged exec mode

connection.config_mode() # Global config mode

connection.send_command('access-list 1 permit any') # Global configuration command

connection.exit_config_mode() # Exit global config mode

print(connection.send_command('show running-config | section access-list 1')) # Verify

connection.disconnect()

send_command() Using config mode to configure device

25 of 57

1f_sendcmd_config.py

Let’s try it! send_command(): Configuring Devices

Added some print commands for readability

26 of 57

Output (Backup)

MacOS%

Using send_command() create an access list...

Done...Verify with 'show running-config | section access-list 1'

access-list 1 permit any

MacOS%

27 of 57

import netmiko

device = '192.168.1.1'

ipv6_interface_list = [

'ipv6 unicast-routing',

'interface g0/0',

'ipv6 address 2001:db8:cafe:1::1/64',

'ipv6 address fe80::1:1 link-local',

'exit',

'interface g0/1',

'ipv6 address 2001:db8:cafe:2::1/64',

'ipv6 address fe80::1:2 link-local'

]

connection = netmiko.ConnectHandler(

ip=‘device',

device_type='cisco_ios',

username='admin',

password='cisco',

secret='class')

# send_config_set() method can use commands

# from a list, a string, or from a file to a

# list.

# Requires privileged exec access

# Handles configuration mode

# connection.enable() not needed

connection.send_config_set(ipv6_interface_list)

# Verify

print(device)

print(connection.send_command('show ipv6 interface brief'))

connection.disconnect()

send_command_set() Using a list of commands (a better way?)

28 of 57

4a_sendconfigset_fromlist.py

Let’s try it! send_command_set(): Configuring Devices

29 of 57

Output (Backup)

MacOS%

192.168.1.1

-----------

Em0/0 [administratively down/down]

unassigned

GigabitEthernet0/0 [up/up]

FE80::1:1

2001:DB8:CAFE:1::1

GigabitEthernet0/1 [up/up]

FE80::1:2

2001:DB8:CAFE:2::1

Serial0/0/0 [administratively down/down]

unassigned

Serial0/0/1 [administratively down/down]

unassigned

MacOS%

30 of 57

import netmiko

device = '192.168.2.1'

ipv6_interface_list = [

'ipv6 unicast-routing',

'interface g0/0',

'ipv6 address 2001:db8:cafe:3::1/64',

'ipv6 address fe80::3:3 link-local',

'exit',

'interface g0/1',

'ipv6 address 2001:db8:cafe:2::2/64',

'ipv6 address fe80::3:2 link-local'

]

connection = netmiko.ConnectHandler(

ip=‘device',

device_type='cisco_ios',

username='admin',

password='cisco',

secret='class')

# Stores the output of the configuration commands (prompts and commands) to the variable output.

output =

connection.send_config_set(ipv6_interface_list)

# Print output: prompts and commands

print(output)

# Verify

print(connection.send_command('show ipv6 interface brief'))

connection.disconnect()

output = send_command_set() Display Commands

31 of 57

4b_sendconfigset_fromlist_displaycommands.py

Let’s try it! send_command_set(): Display Commands

32 of 57

Output (Backup)

MacOS%

configure terminal

Enter configuration commands, one per line. End with CNTL/Z.

R1(config)#ipv6 unicast-routing

R1(config)#interface g0/0

R1(config-if)#ipv6 address 2001:db8:cafe:1::1/64

R1(config-if)#ipv6 address fe80::1:1 link-local

R1(config-if)#exit

R1(config)#interface g0/1

R1(config-if)#ipv6 address 2001:db8:cafe:2::1/64

R1(config-if)#ipv6 address fe80::1:2 link-local

R1(config-if)#end

R1#

R1#

192.168.1.1

-----------

Em0/0 [administratively down/down]

unassigned

GigabitEthernet0/0 [up/up]

FE80::1:1

2001:DB8:CAFE:1::1

GigabitEthernet0/1 [up/up]

FE80::1:2

2001:DB8:CAFE:2::1

Serial0/0/0 [administratively down/down]

unassigned

Serial0/0/1 [administratively down/down]

unassigned

MacOS%

33 of 57

import netmiko

# File containing configuration commands

config_file = 'r1-ipv6-config.txt'

device = '192.168.1.1'

# Define device parameters

connection = netmiko.ConnectHandler(

ip=‘device',

device_type='cisco_ios',

username='admin',

password='cisco',

secret='class')

# Use send_config_from_file() to send

# configuration commands from a file

output = connection.send_config_from_file(config_file)

print(f"Config Output:\n{output}\n")

print("Verify configuration")

print(connection.send_command('show ipv6 interface brief'))

output = send_command_from_file()

34 of 57

import netmiko

import os

# Get the directory of the current script

script_directory = os.path.dirname(os.path.abspath(__file__))

# Specify the file containing configuration commands

config_file = os.path.join(script_directory, 'r1-ipv6-config.txt')

# Define device parameters

device = {

'device_type': 'cisco_ios',

'ip': '192.168.1.1',

'username': 'admin',

'password': 'cisco',

'secret': 'class'

}

# Establish SSH connection

connection = netmiko.ConnectHandler(**device)

print("SSH Connection Successful\n")

print("\nBefore configuration")

print(connection.send_command('show ipv6 interface brief'))

# Use send_config_from_file() to send configuration commands from a file

output = connection.send_config_from_file(config_file)

print(f"Config Output:\n{output}\n")

print("After configuration")

print(connection.send_command('show ipv6 interface brief'))

output = send_command_from_file()

4c_send_config_from_file_output_simple.py

Actual file

35 of 57

interface gig 0/0

ipv6 address 2001:db8:cafe:1::1/64

ipv6 address fe80::1:1 link-local

exit

interface gig 0/1

ipv6 address 2001:db8:cafe:2::1/64

ipv6 address fe80::1:2 link-local

exit

'r1-ipv6-config.txt

36 of 57

Output (Backup)

MacOS%

Config Output:

configure terminal

Enter configuration commands, one per line. End with CNTL/Z.

R1(config)#interface gig 0/0

R1(config-if)#ipv6 address 2001:db8:cafe:1::1/64

R1(config-if)#ipv6 address fe80::1:1 link-local

R1(config-if)#exit

R1(config)#

R1(config)#interface gig 0/1

R1(config-if)#ipv6 address 2001:db8:cafe:2::1/64

R1(config-if)#ipv6 address fe80::1:2 link-local

R1(config-if)#exit

R1(config)#end

R1#

After configuration

GigabitEthernet0/0 [up/up]

FE80::1:1

2001:DB8:CAFE:1::1

GigabitEthernet0/1 [down/down]

FE80::1:2

2001:DB8:CAFE:2::1

GigabitEthernet0/2 [administratively down/down]

unassigned

MacOS%

37 of 57

import netmiko

# Assign devices to a list of IP addresses used to SSH into each device

devices = ['192.168.1.1', '192.168.2.2', '192.168.3.2']

# Loop through the IP addresses, assign device to each item in the list of devices

for device in devices:

connection = netmiko.ConnectHandler(ip=device,

device_type='cisco_ios',

username='admin',

password='cisco')

# Print current value of device (IPv4 address) and output from send_command()

print(device)

print(connection.send_command('show ip route static'))

connection.disconnect()

for loop - Accessing multiple devices

(For those more familiar with Python)

38 of 57

Let’s try it! For Loop and a List of Devices

2a_forloop_listip_sendcmd.py

For those who are familiar with dictionaries, each device can be a dictionary with its own usernames, passwords, device types:

See Rick’s stuff for more information.

39 of 57

Output (Backup)

MacOS%

192.168.1.1

-----------

Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP

D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area

N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2

E1 - OSPF external type 1, E2 - OSPF external type 2

i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2

ia - IS-IS inter area, * - candidate default, U - per-user static route

o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP

+ - replicated route, % - next hop override

Gateway of last resort is not set

S 192.168.3.0/24 [1/0] via 192.168.2.2

S 192.168.4.0/24 [1/0] via 192.168.2.2

<Next slide>

40 of 57

Output (Backup)

192.168.2.2

-----------

Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP

<output omitted>

S 192.168.1.0/24 [1/0] via 192.168.2.1

S 192.168.4.0/24 [1/0] via 192.168.3.2

192.168.3.2

-----------

Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP

<output omitted>

S 192.168.1.0/24 [1/0] via 192.168.3.1

S 192.168.2.0/24 [1/0] via 192.168.3.1

MacOS%

41 of 57

Some ideas for those familiar with some of this…�(Otherwise, ignore this ☺)

  • Configure multiple devices using a separate files with IOS commands for each device
  • Include Cisco EEM (Embedded Event Manager) files for connection-sensitive configurations such as ACLs, IP addressing and routing
  • Require SSH and privileged passwords to be entered manually
  • Use a JSON file for list of devices
  • Use Netmiko with TextFSM and NTC Templates that converts semi-formatted text (the CLI output) to structured data
  • Etc.

42 of 57

Here are some report types you might consider generating using Netmiko (and some parsing):

  • IOS Versions Report: Gather the IOS version from each device to ensure they are up to date and to identify devices that need an upgrade.
  • Device Inventory Report: Collect information such as serial numbers, model types, uptime, and other hardware details from each device.
  • Interface Status Report: Generate a list of all interfaces, their status (up/down), speed, and description for quick identification of issues or unused ports.
  • Configuration Compliance Report: Compare the running configurations against a standard template to ensure compliance with your organization's policies.
  • Network Utilization and Performance Report: Retrieve and analyze interface statistics like input/output rates, errors, and discards to spot potential network issues.
  • Security Report: Check for security configurations such as access lists, SNMP community strings, or user accounts and their privilege levels.
  • Error and Events Report: Collect logs or error messages from devices to identify patterns or recurring issues that need attention.
  • Routing Information Report: Summarize the routing table entries, protocol status, and peering information to understand the network's routing behavior and efficiency.
  • VLAN Report: List all VLANs across switches, including names, IDs, and associated ports, to manage VLAN distribution and assignment.
  • Backup Configurations: Regularly backup and report on the configuration files of devices to track changes and recover quickly from failures.

43 of 57

Here are some troubleshooting tasks you can automate using Netmiko (and some parsing):

Connectivity Checks: Automate pinging or tracing routes to hosts or devices from various points in the network to identify connectivity issues.

Interface Errors and Status: Retrieve and analyze interface statistics such as input/output errors, CRC errors, and up/down status to pinpoint faulty or flapping interfaces.

CPU and Memory Utilization: Monitor and log CPU and memory usage over time to spot devices that are consistently running hot, which could indicate a problem.

Configuration Changes Tracking: Compare current configurations with previous ones to detect recent changes that might have caused issues.

Log Retrieval and Analysis: Collect logging messages and analyze them for recurring patterns or specific error messages that indicate problems.

Environment Check: Gather environmental information such as temperature, power supply status, and fan status, especially in cases where hardware failure is suspected.

Routing Issues: Extract and analyze routing tables and protocols status to ensure routes are as expected and that routing protocols are in the correct state.

Checking VPN Status: For networks utilizing VPNs, automate the collection of tunnel status and statistics to ensure all tunnels are up and performing as expected.

Port Security Violations: If port security is configured, check for violation statuses or err-disabled interfaces that might indicate unauthorized access or configuration issues.

Bandwidth Utilization: Measure and report on interface bandwidth utilization to identify links that are overutilized or underutilized.

44 of 57

import netmiko # Import Netmiko library

ipv6_interface_list = [ List of commands ]

config_file = 'r1-ipv6-config.txt'

connection = netmiko.ConnectHandler(ip='192.168.1.1’, device_type='cisco_ios',

username='admin’, password='cisco’, secret='class’)

print(connection.send_command('show ip interface brief'))

print(connection.send_command_expect('copy run start’, expect_string=‘filename'))

connection.enable() # Privileged exec mode

connection.config_mode() # Global config mode

connection.send_command('access-list 1 permit any') # Global configuration command

connection.exit_config_mode() # Exit global config mode

connection.send_config_set(ipv6_interface_list) # Send commands from a list

connection.send_config_from_file(config_file) # Send commands from a file

connection.save_config() # Same as 'copy run start'

connection.disconnect() # Close SSH connection

Summary

45 of 57

# Our first Netmiko program

import netmiko

 

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios',

username='admin',

password='cisco’)

 

print(connection.send_command('show ip interface brief'))

 

connection.disconnect()

And you can start right here…

46 of 57

NAPALM offers an easy introduction to network programmability and structured data without requiring an API on the device.

Netmiko, NAPLAM and NORNIR

  • No API needed
  • No VM needed
  • No agent software needed
  • Works on any IOS

Python

Netmiko

Structured Data

Dictionaries-JSON *JSON XML JSON-XML

Ansible

NAPALM

Cisco IOS or XR/XE/NX-OS

Cisco XR/XE/NX-OS

NETCONF

RESTCONF

Models

YANG/XSD YANG

Python

NORNIR

* Python

Telnet/SSH

SSH

* SSH

SSH

HTTPS

APIs

RPC API RESTFUL API

Postman

CLI commands/output

+ Netmiko

Vendor agnostic

NAPALM

CLI commands/output

+ YAML Inventory

YANG/XSD Models

YANG Models

Netmiko/NAPALM (YAML Inventory)

47 of 57

  1. Students with some knowledge of Python get to do some cool coding!
  2. Students with a limited knowledge of IOS, get to "program" routers/switches!
    • Uses vendor agnostic commands
    • Some basic IOS is helpful
    • Supports CLI commands/output
    • Minimal Requirements: Requires only SSH connectivity
  3. An easy introduction to using structured data - dictionaries (JSON)

As you grow with IOS or as you grow with Python you can do more network automation with NAPALM

SSH

Why NAPALM?

48 of 57

NAPALM

NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support),

  • Open-source Python library
  • Provides a consistent and vendor-agnostic interface for interacting with various networking devices (NOS).
  • Created by a community of network engineers and developers.
  • Provides information in a structured format using dictionaries.
  • The structured data format simplifies parsing and analysis in automation scripts.
    • This makes it easier for developers to extract and utilize specific details about network configurations, states, and statistics in a programmatic and efficient manner.

49 of 57

  1. Install Python
  2. Install NAPALM

MacOS% pip3 install napalm

MacOS% pip3 install pprint (optional)

3. Verify SSH connectivity to device

Getting Started

50 of 57

# Imports the NAPALM library, for interacting with different network devices

import napalm

# Function that selects network driver,'ios', and returns driver object

driver = napalm.get_network_driver('ios')

# Creates a device object using the previously selected driver. Provides connection details.

# Can have different network drivers (ios_driver), and assign them to different device objects (ios_device).

device = driver( hostname='192.168.1.1',

username='admin',

password='cisco',

optional_args={'secret':'class'} )

# Establishes a connection to the specified network device using the details provided.

device.open()

# Your tasks here: get_facts() method retrieves information about the device (hostname, model,)

print(device.get_facts())

# Closes the connection to the network device (good practice)

device.close()

1

2

3

4

5

1a_introduction.py

51 of 57

{

"uptime": 240.0,

"vendor": "Cisco",

"os_version": "C2900 Software (C2900-UNIVERSALK9-M),

Version 15.0(1)M4,

RELEASE SOFTWARE (fc1)",

"serial_number": "FCZ150425YC",

"model": "CISCO2911/K9",

"hostname": "R1",

"fqdn": "R1.ssh-key.com",

"interface_list": [

"GigabitEthernet0/0",

"GigabitEthernet0/1",

"GigabitEthernet0/2"

]

}

52 of 57

hostname vendor model uptime serial_number

---------- -------- ------- -------- ---------------------

IOS-SW2 Cisco IOSv 34080 9162JOW336J

IOS-R2 Cisco IOSv 34140 9MJNBPR604WW2WN1QPABR

IOS-R3 Cisco IOSv 34140 9BO8LXD6KLX8ZSB7M0PPF

IOSXR-R1 Cisco 34223

IOS-SW1 Cisco IOSv 34140 9CGHIOOXX08

hostname interface is_up is_enabled description speed mtu mac_address

---------- ------------------------- ------- ------------ ------------------------------ ------- ----- -----------------

IOS-SW2 GigabitEthernet0/0 True True 1000 1500 50:00:00:03:00:00

IOS-SW2 GigabitEthernet0/1 True True Connected to IOSXR-R1 L2-Trunk 1000 1500 50:00:00:03:00:01

IOS-SW2 GigabitEthernet0/2 True True 1000 1500 50:00:00:03:00:02

IOS-SW2 GigabitEthernet0/3 True True to_PC_1 1000 1500 50:00:00:03:00:03

IOS-SW2 GigabitEthernet1/0 True True 1000 1500 50:00:00:03:00:04

IOS-SW2 GigabitEthernet1/1 True True 1000 1500 50:00:00:03:00:05

IOS-SW2 GigabitEthernet1/2 True True 1000 1500 50:00:00:03:00:06

IOS-SW2 GigabitEthernet1/3 True True 1000 1500 50:00:00:03:00:07

IOS-SW2 Vlan10 True True Management 10.10.10.10/24 1000 1500 50:00:00:03:80:0A

IOS-R2 GigabitEthernet0/0 True True to_IOS-SW2 Gi0/1 1000 1500 50:00:00:01:00:00

IOS-R2 GigabitEthernet0/0.30 True True to_IOS-SW2 Gi0/1 Vlan 30 1000 1500 50:00:00:01:00:00

IOS-R2 GigabitEthernet0/1 False False 1000 1500 50:00:00:01:00:01

IOS-R2 GigabitEthernet0/2 True True to_IOSXR-R1 Gi0/0/0/2 External 1000 1500 50:00:00:01:00:02

IOS-R2 GigabitEthernet0/3 False False 1000 1500 50:00:00:01:00:03

IOS-R2 Loopback0 True True 8000 1514

IOS-R3 GigabitEthernet0/0 True True to_IOSXR-R1 Gi0/0/0/0 External 1000 1500 50:00:00:02:00:00

IOS-R3 GigabitEthernet0/1 False False 1000 1500 50:00:00:02:00:01

NAPALM used to print a table with all the interfaces of each device with information about each one such as its status, description, mtu, among others

53 of 57

You are welcome to any of my Python networking programs.

Real-time, specific TCP/IP information:

  • YouTube: What it does
  • GitHub: The code

One condition, same as I tell all my students…

You can’t criticize my code ☺

Netmiko playlist and GitHub repository coming soon! (Will post of Facebook IPD)

54 of 57

55 of 57

Netmiko developed by Kirk Byers

https://github.com/ktbyers/netmiko

56 of 57

import netmiko

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios', username='admin', password='cisco', secret='class')

connection.enable() # Required: Privileged exec mode

connection.config_mode() # Global config mode – Not required for other sub-modes

connection.exit_config_mode() # Exit global config mode

connection.interface_mode() # Followed by sending a list of interface commands

connection.exit_interface_mode() # Exit interface mode

connection.line_mode() # Followed by sending a list of VTY or con commands

connection.exit_line_mode() # Exit line mode

connection.disconnect()

send_command_set() and other sub-modes

57 of 57

import netmiko

connection = netmiko.ConnectHandler(ip='192.168.1.1',

device_type='cisco_ios', username='admin', password='cisco', secret='class')

console_config_commands = [

'line con 0', # Access the console line

'logging synchronous' # Enable synchronous logging

]

connection.enable() # Required: Privileged exec mode

connection.line_mode()

output = connection.send_config_set(console_config_commands)

print(f"Configuration Output:\n{output}\n")

connection.exit_line_mode() # Exit line mode (optional here)

connection.disconnect()

send_command_set() and other sub-modes