Network Programmability using Netmiko for those New to Python
Rick Graziani
Cabrillo College
University of California Santa Cruz
2023
Python
At the end:
Agenda
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
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)
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)
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)
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
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
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?
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."
MacOS% pip3 install netmiko
3. Verify SSH/Telnet connectivity to device
Getting Started
Setup
ME
# 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!
# 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
# 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
Let’s try it! send_command()
netmiko_1a_
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:
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%
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
Let’s try it! send_command_expect()
Insignificant Python Change:
Added some print commands for readability
Output (Backup)
MacOS%
192.168.1.1 copy running-config startup-config
-----------
Destination filename [startup-config]?
Success!
MacOS%
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'
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%
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…
So far…
show commands, saving config
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
1f_sendcmd_config.py
Let’s try it! send_command(): Configuring Devices
Added some print commands for readability
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%
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?)
4a_sendconfigset_fromlist.py
Let’s try it! send_command_set(): Configuring Devices
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%
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
4b_sendconfigset_fromlist_displaycommands.py
Let’s try it! send_command_set(): Display Commands
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%
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()
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
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
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%
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)
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.
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>
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%
Some ideas for those familiar with some of this…�(Otherwise, ignore this ☺)
Here are some report types you might consider generating using Netmiko (and some parsing):
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.
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
# 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…
NAPALM offers an easy introduction to network programmability and structured data without requiring an API on the device.
Netmiko, NAPLAM and NORNIR
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)
As you grow with IOS or as you grow with Python you can do more network automation with NAPALM
SSH
Why NAPALM?
NAPALM
NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support),
MacOS% pip3 install napalm
MacOS% pip3 install pprint (optional)
3. Verify SSH connectivity to device
Getting Started
# 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
{
"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"
]
}
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
You are welcome to any of my Python networking programs.
Real-time, specific TCP/IP information:
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)
Netmiko developed by Kirk Byers
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
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