Welcome to my first post which happens to be on network automation. I’ve got a large number of network hardware replacements coming up so I’ve created a (fairly basic) script that uses Netmiko to do the following:
- Import a list of IP addresses from an external file (routers.txt)
- SSH to each IP address (with error handling)
- Run a list of commands specified from an external file (commands.txt)
- Output the result of the commands in an individual text file named with each devices hostname and IP address
- Output the IP addresses of devices it was unable to connect to into a file which is named based on the error. Examples are:
- Connection Timeouts.txt
- Auth Failures.txt
- SSH Failures.txt
- EOF Errors.txt
- UnknownError.txt
At the moment the script is only working for Cisco equipment as that’s the current use-case I have for it, however, it should be pretty easy to call the Aruba or other vendor Netmiko library instead.
I’ve attached the initial release of the code below, however, the most current version will always be located on my GitHub.
#!/usr/bin/env python
# Script by Mitch Bradford
# Dependencies - Netmiko, Python 3
# Instructions - List IP addresses in routers.txt and commands to run in commands.txt
# === Formatting ===
# routers.txt:
# [ip address]
# [ip address]
#
# commands.txt:
# exit
# [enable priv command]
# [enable priv command]
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetMikoTimeoutException
from paramiko.ssh_exception import SSHException
from netmiko.ssh_exception import AuthenticationException
from getpass import getpass
from pprint import pprint
with open('commands.txt') as f:
commands_list = f.read().splitlines()
with open('routers.txt') as f:
router_list = f.read().splitlines()
username=input('Enter your username:')
password=getpass()
for routers in router_list:
print ('Connecting to device ' + routers)
ip_address_of_device = routers
ios_device = {
'device_type': 'cisco_ios',
'ip': ip_address_of_device,
'username': username,
'password': password
}
#Define the error handling files to reference if/when something fails
Timeouts=open("Connection time outs.txt", "a")
Authfailure=open("Auth failures.txt", "a")
SSHException=("SSH Failure.txt", 'a')
EOFError=("EOFerrors.txt",'a')
UnknownError=("UnknownError.txt",'a')
try:
# Actually connect to the device
net_connect = ConnectHandler(**ios_device)
# Grab the hostname of the device, so it can be used as a filename
hostname = net_connect.send_command("show run | i hostname")
hostname = hostname[9:]
#open file to write command output
file = open('1 - ' + hostname + " - " + ip_address_of_device + " " + '.txt', 'w')
# Print output to console screen
print('-------------- Running script on ' + ip_address_of_device + ' - ' + hostname + ' ------------------')
file.write('======== ' + ip_address_of_device + ' @ ' + hostname + ' ========')
file.write("\n")
output=net_connect.send_config_set(commands_list)
#print(output)
file.write(output)
# Close the file
file.close()
# Cleanly disconnect SSH session
net_connect.disconnect()
except (AuthenticationException):
print ('Authentication Failure: ' + ip_address_of_device)
Authfailure.write('\n' + ip_address_of_device)
continue
except (NetMikoTimeoutException):
print ('\n' + 'Timeout to device: ' + ip_address_of_device)
Timeouts.write('\n' + ip_address_of_device)
continue
except (SSHException):
print ('SSH might not be enabled: ' + ip_address_of_device)
SSHException.write('\n' + ip_address_of_device)
continue
except (EOFError):
print ('\n' + 'End of attempting device: ' + ip_address_of_device)
EOFError.write('\n' + ip_address_of_device)
continue
except unknown_error:
print ('Some other error: ' + str(unknown_error))
continue
The routers.txt file should be formatted as such:
IP Address 1
IP Address 2
The commands.txt file should be formatted as such:
Config Level Command 1
Config Level Command 2
exit
Enable Mode Command 1
Enable Mode Command 2