The information provided in this post is for educational and informational purposes only. All rights to the software used belong to their respective owners.
I’ve read quite a few tutorials on Netmiko with GNS3, but none of them show you how to directly utilize the console connection as the management interface for Cisco devices.
In addition to the CiscoIosSSH driver, Kirk Byers also implemented the CiscoIosTelnet driver for establishing a connection to a Cisco device. This is perfect for GNS3 because the default console connection is essentially a Telnet connection without authentication.
What are some of the benefits? Well, for starters, the following are not required:
- A dedicated management switch connected to a host adapter
- Telnet or SSH configuration on each of the Cisco devices
- The GNS3 network automation appliance
This drastically reduces the friction for staging labs in GNS3 while providing a simple approach to learning network automation with Python.
Prerequisites
- Basic knowledge of Python
- Text Editor or IDE (e.g., Visual Studio Code , Zed , PyCharm , Vim , etc.)
- Bourne-compatible shell for Linux, macOS, or Windows Subsystem for Linux (WSL) on Windows
- GNS3 server on Linux (local, remote, or GNS3 VM)
- Python >= 3.9
- Git
Steps
Open your favorite terminal emulator.
Clone the netmiko-gns3 repo from GitHub.
git clone https://github.com/mweisel/netmiko-gns3.git
- Change to the
netmiko-gns3
directory.
cd netmiko-gns3
- Create a Python virtual environment for Netmiko.
Debian-based Linux distros may require the Python package installer before running the script:
sudo apt update && sudo apt install python3-pip
source init_venv.sh
- Verify the
netmiko
package is available.
pip show netmiko
GNS3
I am using GNS3 on Apple Silicon , but the following steps are platform agnostic. The OSPF lab is intentionally simple to allow us to focus on the core concepts. The network topology contains two routers:
Open the GNS3 application.
Create a new project.
Drag and drop a c7200 Router from the Devices toolbar onto the Workspace.
Drag and drop an IOL Router from the Devices toolbar onto the Workspace.
Add a link between the
f0/0
interface of R1 ande0/0
interface of R2.Start the devices.
Identify the GNS3 server IP address (or name) in the Topology Summary dock.
- Identify the Telnet port number for R1 and R2 in the Topology Summary dock.
Text Editor and Terminal Emulator
Open the
netmiko-gns3
project directory in your favorite text editor or IDE.Open the
devices.yaml
file.
|
|
If you’re familiar with Ansible , this file is analogous to the inventory file.
Remember the GNS3 server IP address (or name), and the device Telnet port numbers, from a few steps back? This is where we use those values for the device connection attributes.
Note the default_enter
variable on line 10. Netmiko implicitly uses "\r\n"
for the characters to send correlated with the enter key. A Cisco IOL device expects"\n"
.
- Open the
display_version.py
script file.
|
|
A general outline of what the script does:
- Import the R1 and R2 routers from the
devices.yaml
file. - Establish concurrent Telnet connections to the routers.
- Return unstructured output of the Cisco
show version
command from each router. - Print the output for each router.
- Run the
display_version.py
script from the terminal.
python display_version.py
output:
// 1
Cisco IOS Software, 7200 Software (C7200-ADVENTERPRISEK9-M), Version 12.4(24)T5, RELEASE SOFTWARE (fc3)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2011 by Cisco Systems, Inc.
Compiled Fri 04-Mar-11 06:49 by prod_rel_team
ROM: ROMMON Emulation Microcode
BOOTLDR: 7200 Software (C7200-ADVENTERPRISEK9-M), Version 12.4(24)T5, RELEASE SOFTWARE (fc3)
R1 uptime is 6 hours, 39 minutes
System returned to ROM by unknown reload cause - suspect boot_data[BOOT_COUNT] 0x0, BOOT_COUNT 0, BOOTDATA 19
System image file is "tftp://255.255.255.255/unknown"
This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.
A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html
If you require further assistance please contact us by sending email to
[email protected].
Cisco 7206VXR (NPE400) processor (revision A) with 491520K/32768K bytes of memory.
Processor board ID 4279256517
R7000 CPU at 150MHz, Implementation 39, Rev 2.1, 256KB L2 Cache
6 slot VXR midplane, Version 2.1
Last reset from power-on
PCI bus mb0_mb1 (Slots 0, 1, 3 and 5) has a capacity of 600 bandwidth points.
Current configuration on bus mb0_mb1 has a total of 200 bandwidth points.
This configuration is within the PCI bus capacity and is supported.
PCI bus mb2 (Slots 2, 4, 6) has a capacity of 600 bandwidth points.
Current configuration on bus mb2 has a total of 0 bandwidth points
This configuration is within the PCI bus capacity and is supported.
Please refer to the following document "Cisco 7200 Series Port Adaptor
Hardware Configuration Guidelines" on Cisco.com <http://www.cisco.com>
for c7200 bandwidth points oversubscription and usage guidelines.
1 FastEthernet interface
509K bytes of NVRAM.
8192K bytes of Flash internal SIMM (Sector size 256K).
Configuration register is 0x2102
// 2
Cisco IOS Software [IOSXE], Linux Software (X86_64BI_LINUX-ADVENTERPRISEK9-M), Version 17.15.1, RELEASE SOFTWARE (fc4)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2024 by Cisco Systems, Inc.
Compiled Sun 11-Aug-24 22:07 by mcpre
ROM: Bootstrap program is Linux
R2 uptime is 6 hours, 40 minutes
System returned to ROM by unknown reload cause - suspect boot_data[BOOT_COUNT] 0x9, BOOT_COUNT 0, BOOTDATA 19
System image file is "unix:/opt/gns3/images/IOU/x86_64_crb_linux-adventerprisek9-ms.iol"
Last reload reason: Unknown reason
This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.
A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html
If you require further assistance please contact us by sending email to
[email protected].
Linux Unix (i686) processor with 538788K bytes of memory.
Processor board ID 2045953
8 Ethernet interfaces
8 Serial interfaces
20K bytes of NVRAM.
Configuration register is 0x0
- Open the
display_router_info.py
script file.
|
|
This script combines the power of Netmiko with NTC Templates
for structured output. The show version
and show interfaces
commands will map to the cisco_ios_show_version.textfsm
and cisco_ios_show_interfaces.textfsm
templates respectively.
A general outline of what the script does:
- Import the R1 and R2 routers from the
devices.yaml
file. - Establish concurrent Telnet connections to the routers.
- Return structured output of the Cisco
show version
andshow interfaces
commands from each router. - Print a couple of statements with f-strings using embedded values from the structured output for each router.
- Run the
display_router_info.py
script from the terminal.
python display_router_info.py
output:
R1 is version 12.4(24)T5 using the C7200-ADVENTERPRISEK9-M image.
The first interface of R1 is FastEthernet0/0 (ca01.0421.0000).
R2 is version 17.15.1 using the X86_64BI_LINUX-ADVENTERPRISEK9-M image.
The first interface of R2 is Ethernet0/0 (aabb.cc00.0100).
- Open the
configure_devices.py
script file.
|
|
A general outline of what the script does:
- Import the R1 and R2 routers from the
devices.yaml
file. - Establish concurrent Telnet connections to the routers.
- Capture the current configuration of the router.
- Send a list of configuration commands, from a file, to be entered on each of the routers.
- Capture the modified configuration of the router.
- Return a diff output of the configuration changes from each router.
- Print the output for each router.
- Run the following from the terminal to display the configuration commands sent to each router:
tail -n +1 configs/R?.txt
output:
==> configs/R1.txt <==
interface Loopback0
ip address 1.1.1.1 255.255.255.255
exit
interface FastEthernet0/0
duplex full
ip address 10.0.0.1 255.255.255.252
no shutdown
exit
router ospf 1
passive-interface Loopback0
exit
interface Loopback0
ip ospf 1 area 0
exit
interface FastEthernet0/0
ip ospf 1 area 0
ip ospf network point-to-point
exit
==> configs/R2.txt <==
ip cef
interface Loopback0
ip address 2.2.2.2 255.255.255.255
exit
interface Ethernet0/0
ip address 10.0.0.2 255.255.255.252
no shutdown
exit
router ospf 1
passive-interface Loopback0
exit
interface Loopback0
ip ospf 1 area 0
exit
interface Ethernet0/0
ip ospf 1 area 0
ip ospf network point-to-point
exit
- Run the
configure_devices.py
script from the terminal.
python configure_devices.py
output:
--- R1-> before
+++ R1-> after
@@ -1,6 +1,6 @@
Building configuration...
-Current configuration : 901 bytes
+Current configuration : 1107 bytes
!
upgrade fpd auto
version 12.4
@@ -56,10 +56,19 @@
!
!
!
+interface Loopback0
+ ip address 1.1.1.1 255.255.255.255
+ ip ospf 1 area 0
+!
interface FastEthernet0/0
- no ip address
- shutdown
- duplex half
+ ip address 10.0.0.1 255.255.255.252
+ ip ospf network point-to-point
+ ip ospf 1 area 0
+ duplex full
+!
+router ospf 1
+ log-adjacency-changes
+ passive-interface Loopback0
!
ip forward-protocol nd
no ip http server
--- R2-> before
+++ R2-> after
@@ -1,6 +1,8 @@
Building configuration...
-Current configuration : 1767 bytes
+Current configuration : 2008 bytes
+!
+! Last configuration change at 12:11:52 PST Sat Dec 14 2024
!
version 17.15
service timestamps debug datetime msec
@@ -29,7 +31,7 @@
!
!
no ip domain lookup
-no ip cef
+ip cef
login on-success log
no ipv6 cef
!
@@ -72,9 +74,14 @@
!
!
!
+interface Loopback0
+ ip address 2.2.2.2 255.255.255.255
+ ip ospf 1 area 0
+!
interface Ethernet0/0
- no ip address
- shutdown
+ ip address 10.0.0.2 255.255.255.252
+ ip ospf network point-to-point
+ ip ospf 1 area 0
!
interface Ethernet0/1
no ip address
@@ -144,6 +151,9 @@
shutdown
serial restart-delay 0
!
+router ospf 1
+ passive-interface Loopback0
+!
ip forward-protocol nd
!
ip tcp synwait-time 5
- Open the
display_cdp_ospf_info.py
script file.
|
|
Verify the CDP and OSPF neighborship after the configuration change.
A general outline of what the script does:
- Import the R1 and R2 routers from the
devices.yaml
file. - Establish concurrent Telnet connections to the routers.
- Return structured output of the Cisco
show cdp neighbors detail
andshow ip ospf neighbor
commands from each router. - Print the output for each router.
- Run the
display_cdp_ospf_info.py
script from the terminal.
python display_cdp_ospf_info.py
output:
{'show cdp neighbors detail': [{'capabilities': 'Router',
'local_interface': 'FastEthernet0/0',
'mgmt_address': '10.0.0.2',
'neighbor_description': 'Cisco IOS Software '
'[IOSXE], Linux '
'Software '
'(X86_64BI_LINUX-ADVENTERPRISEK9-M), '
'Version 17.15.1, '
'RELEASE SOFTWARE '
'(fc4)',
'neighbor_interface': 'Ethernet0/0',
'neighbor_name': 'R2',
'platform': 'Linux Unix'}],
'show ip ospf neighbor': [{'dead_time': '00:00:38',
'interface': 'FastEthernet0/0',
'ip_address': '10.0.0.2',
'neighbor_id': '2.2.2.2',
'priority': '0',
'state': 'FULL/ -'}]}
{'show cdp neighbors detail': [{'capabilities': 'Router',
'local_interface': 'Ethernet0/0',
'mgmt_address': '10.0.0.1',
'neighbor_description': 'Cisco IOS Software, '
'7200 Software '
'(C7200-ADVENTERPRISEK9-M), '
'Version 12.4(24)T5, '
'RELEASE SOFTWARE '
'(fc3)',
'neighbor_interface': 'FastEthernet0/0',
'neighbor_name': 'R1',
'platform': 'Cisco 7206VXR'}],
'show ip ospf neighbor': [{'dead_time': '00:00:37',
'interface': 'Ethernet0/0',
'ip_address': '10.0.0.1',
'neighbor_id': '1.1.1.1',
'priority': '0',
'state': 'FULL/ -'}]}
- Keep going.
Ideally, we would take this a step further by verifying the configuration and operational state with a Python testing framework.