I am new to netmiko/Python scripting , Using online examples was able to make a script to take configuration backup. The backup is copied to the text file and output is saved.
Currently this backup is done sequentially and it does not connect to all device at once and take the backup. I want to connect to all the devices concurrently.
I understand multithreading or concurrent.futures can solve this issueenter code here but I was not able to do it so far.
Can anyone please suggest, how my existing code can be modified to achieve it. Below is the code.
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetMikoTimeoutException
from paramiko.ssh_exception import SSHException
from netmiko.ssh_exception import AuthenticationException
import getpass
import sys
import time
import os
from datetime import datetime
##getting system date
day=time.strftime('%d')
month=time.strftime('%m')
year=time.strftime('%Y')
today=day+"-"+month+"-"+year
enter code here
##initialising device
device = {
'device_type': 'cisco_ios',
'ip': '192.168.100.21',
'username': 'Cisco',
'password': 'Cisco',
'secret':'Cisco',
'session_log': 'log.txt'
}
##opening IP file
ipfile=open("iplist.txt")
print ("Script to take backup of devices, Please enter your credential")
device['username']=input("username ")
device['password']=getpass.getpass()
print("Enter enable password: ")
device['secret']=getpass.getpass()enter code here
##taking backup
for line in ipfile:
try:
device['ip']=line.strip("\n")
print("\n\nConnecting Device ",line)
net_connect = ConnectHandler(**device)
net_connect.enable()
time.sleep(1)
with open('config.txt') as f:
cmd = f.read().splitlines()
print ("Reading the running config ")
output = net_connect.send_config_set(cmd)
output4 = "Failed"
time.sleep(7)
filename=device['ip']+'-'+today+".txt"
folder = os.path.join(today)
file = os.path.join(folder,filename)
os.makedirs(folder,exist_ok=True)
saveconfig=open(file,'w+')
print("Writing Configuration to file")
saveconfig.write(output)
saveconfig.close()
time.sleep(10)
net_connect.disconnect()
print ("Configuration saved to file",filename)
except:
print ("Access to "+device['ip']+" failed,backup did not taken")
output4 = "Failed"
file= device['ip']+'-'+today+"Error"+".txt"
config=open(file,'w+')
config.write(output4)
config.close()
ipfile.close()
print ("\nAll device backup completed")enter code here
You can refer below script and modify it according to your requirement. Here I have used python multiprocessing for connecting devices in pools.
#This script will allow for user pick hosts and enter show commands interactively
#
#Enable Multiprocessing
from multiprocessing import Pool
#
#getpass will not display password
from getpass import getpass
#ConnectionHandler is the function used by netmiko to connect to devices
from netmiko import ConnectHandler
#Time tracker
from time import time
#create variables for username and password
#create variables for configs and hosts
uname = input("Username: ")
passwd = getpass("Password: ")
cmd = input("Enter show commands seperated by ',': ")
host = input("Enter the host IPs seperate with space: ")
#This will put hosts and commands entered into list format
hosts = host.split()
cmds = cmd.split(",")
starting_time = time()
#Each member of the pool of 5 will be run through this function
def run_script(host_ip):
ios_rtr = {
"device_type": "cisco_ios",
"ip": host_ip,
"username": uname,
"password": passwd,
}
#connect to the device via ssh
net_connect = ConnectHandler(**ios_rtr)
#print the device IP or Hostname
print("Connected to host:", host_ip)
#this for loop is used to iterate through the show commands
for show_commands in cmds:
output = net_connect.send_command(show_commands)
print("Connected to host:", host_ip)
print(output)
print('\n---- Elapsed time=', time()-starting_time)
if __name__ == "__main__":
# Pool(5) means 5 process will be run at a time, more hosts will go in the next group
with Pool(5) as p:
print(p.map(run_script, hosts))
#This is the key to sending show commands vs config commands
#show commands --> net_connect.send_command()
#config commmands --> net_connect.send_config_set()
With this code, you can run commands on many devices at the same time. You can also use it by hiding your identity information with user_pass. There is also a device prompt discovery feature.
with open("user_pass.txt", "r") as f5:
user_pass = f5.readlines()
for list_user_pass in user_pass:
if "username" in list_user_pass:
username = list_user_pass.split(":")[1].strip()
if "password" in list_user_pass:
password = list_user_pass.split(":")[1].strip()
def _ssh_(nodeip):
try:
access_mpls = {
'device_type': 'huawei_olt', 'ip': nodeip, 'username':
username, 'password': password, }
net_connect = Netmiko(**access_mpls)
print(nodeip.strip() + " " + "success enter")
except Exception as e:
print(e)
f_3.write(nodeip.strip() + "\n")
return
prompt_gpon_fnk = net_connect.find_prompt()
hostname_fnk = prompt_gpon_fnk.strip("<" + ">")
print(hostname_fnk)
net_connect.send_command_timing("enable")
net_connect.send_command_timing("undo smart")
output = net_connect.send_command_timing("config")
print("config moda girildi")
net_connect.send_command_timing("acl 2010 ")
net_connect.send_command_timing("quit")
net_connect.send_command_timing("save")
print("config done")
with open("MDU_OK_2.txt", "a") as f:
f.write(nodeip + "\n")
f.close()
net_connect.disconnect()
f_2 = open("ip_list_2.txt", "r") ip_list = f_2.readlines()
f_2.close() f_3 = open("ssh_unsuccess_2.txt", "w")
myPool = ThreadPool(100) result = myPool.map(ssh, ip_list)
Related
import scapy.all as scapy
import optparse
def get_arguments():
parser = optparse.OptionParser()
parser.add_option("-r", "--range", dest="range", help="Use --range To Scan your Wifi Clients")
options = parser.parse_args()[0]
if not options.range:
parser.error("Please Specify an Option")
else:
return options
def scan(ip):
Ip_Addr = scapy.ARP(pdst=ip)
Mac_Addr = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
add_IpMac = Mac_Addr/Ip_Addr
(answered, unanswered) = scapy.srp(add_IpMac, timeout=1, verbose=False)
result_list =[]
for list in answered:
result_dic ={
"ip": list[1].psrc,
"mac": list[1].hwsrc
}
result_list.append(result_dic)
return(result_list)
def print_results(result_list):
print("\n")
print(" IP\t\t\t\tMac")
print("\n-----------------------------------------")
for result in result_list:
print(result["ip"]+"\t\t"+ result["mac"])
options = get_arguments()
result_dic = scan(options.range)
print_results(result_dic)
I made a simple IP Scanner which I use to scan the Local Network. I want to get the Hostname like netdiscover. Is there a way to get every Hostname in the local network with scapy.all? Here is my Python Script where I want insert the Hostname:
i want to write a python script that will check for variables in the switch configuration, if the variables are there, the script will not input them, but if the variables aren't there, the script will configure it. after the config, the script should print a CSV of all the commands attached to a particular ip.
from netmiko import ConnectHandler
from getpass import getpass
import readline
import time
import os
from datetime import datetime
from csv import reader
with open("/Users/ben/desktop/ntptest.csv", "r") as f:
devices_list = f.read().splitlines
for devices in devices_list():
print ('connecting to device' + devices)
ip = devices
cisco1 = {
"device_type": "cisco_ios",
"host": devices,
"username": "****",
"password": getpass(),
"port" : 22,
'verbose' : True
}
with ConnectHandler(**devices) as net_connect:
output = net_connect.send_command['sh ntp status', 'sh clock det', 'sh ntp ass']
net_connect.enable()
print("Connected Successfully")
P = '192.168.1.1'
S = '192.1.1.1.'
if output [1] == P and output [2] == S:
print ('Both Primary and Secondary NTP are present')
elif output [1] == None and output [2] == S:
output1 = net_connect.send_config_set('conf t' , 'ntp 192.168.9.9')
print(output, output1)
elif output [1] == P and output [2] == None:
output2 = net_connect.send_config_set('conf t', 'ntp server 192.168.9.9')
print(output, output2)
elif output [1] == None and output [2] == None:
output3 = net_connect.send_config_set('conf t', 'ntp server 192.1.1.1', 'ntp server 134.174.17.6')
print(output, output3)
else:
print('None of the condition exist')
I am trying to output the ARP table of a switch by using Netmiko. I would like to use a file containing IP addresses and then have Python/Netmiko run a "show arp" and then add the IP address from the file I give. I would like it to loop through the IP address file to show all ARP entries for the IP addresses in the file and then output to a file containing both IP and MAC addresses. Below is what I have for a single address any help would be greatly appreciated:
#!/usr/bin/env python3
#CF extract ARP table and send output as text file
from netmiko import ConnectHandler
from datetime import datetime
import time
import sys
##initializing device
device = {
'device_type': 'hp_comware',
'ip': '10.1.10.10',
'username': 'xxxx',
'password': 'xxxx',
}
start_time = datetime.now()
print (start_time)
net_connect = ConnectHandler(**device)
output = net_connect.send_command("dis arp 172.16.100.100")
time.sleep(2)
filename="test-arp.txt"
saveconfig=open(filename, 'w+')
saveconfig.write(output)
saveconfig.close()
time.sleep(2)
net_connect.disconnect()
end_time = datetime.now()
print (end_time)
With the code below, you can perform the operation very quickly on 100 devices at the same time (you can increase it if you want) in accordance with the promt of the device.
from netmiko import Netmiko
from multiprocessing.dummy import Pool as ThreadPool
import time
f_2 = open("multiple_device_list_cisco.txt","r") # You should open a notepad with this name and add all the IPs one under the other.
multiple_device_list = f_2.readlines()
file1 = open("Result.txt", "a") # this will be your automatic output when the code is finished
def _ssh_(nodeip):
try:
hp = {
'device_type': 'hp_comware', 'ip': nodeip, 'username':
xxxx, 'password': xxxx, 'secret':xxxx, "conn_timeout": 20}
hp_connect = Netmiko(**hp)
print(nodeip.strip() + " " + "is reachable")
except Exception as e:
print (e)
f_3.write(nodeip.strip() + "\n")
return
prompt_hp_fnk = hp_connect.find_prompt()
hostname_fnk = prompt_hp_fnk.strip("#") # Here you should put whatever the prompt of your HP device is
print(hostname_fnk)
output = hp_connect.send_command_timing("dis arp "+ nodeip)
file1.write(nodeip +" "+ output+ "\n")
hp_connect.disconnect()
myPool = ThreadPool(100) # you can increase or decrease this value
result = myPool.map(_ssh_,multiple_device_list)
I wrote the necessary changes to the above code. I hope that will be useful
I need to collect some output via ssh from different devices but there are two caveats:
The devices are interactively asking for credentials so login can't be easily automated
The output is paged, so it is required to press "Enter" a number of times to get to the end of it
I've tried using paramiko_expect, I can manage the authentication but then I can't figure out how to loop in a while-like style.
from paramiko_expect import SSHClientInteraction
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(addresses[0], username = username, password = password, look_for_keys = False, allow_agent = False)
output = ""
with SSHClientInteraction(client, timeout = 10, display = False) as interact:
interact.expect(['User:.*'])
interact.send(username)
interact.expect(['Password:.*'])
interact.send(password)
interact.expect(['.*>'])
interact.send('get output')
interact.expect(['.*>','.*More or (q)uit.*'])
keepOnLooping = True
while keepOnLooping == True:
if interact.last_match == '.*More or (q)uit.*':
interact.send(interact.send(' '))
interact.expect(['.*>','.*More or (q)uit.*'])
keepOnLooping = True
elif interact.last_match == '.*>':
interact.send(interact.send(' '))
keepOnLooping = False
output = interact.current_output
I've tried with pexpect (pxssh) but I'm failing at the authentication phase.
from pexpect import pxssh
import getpass
try:
s = pxssh.pxssh()
hostname = input('hostname: ')
username = input('username: ')
password = getpass.getpass('password: ')
s.login(hostname, username, password)
s.expect('User:.*')
s.sendline(username)
s.expect('Password:.*')
s.sendline(password)
Any suggestions on how to automate the mentioned proceedures?
I'm a networking student who has little programming experience and I have simple project on my hands where I need to make a simple notification that notifies the user when an email arrives in gmail. I have been trying to get this to work for the last few weeks and I am honestly stuck and struggling. I'm using the code below and I think the problem is the authentication bit, where I can't connect to the server. All help is appreciated.
import imaplib
import re
import time
import subprocess
## enter your account details bellow!
imapServer = "imap.gmail.com"
port = "993"
username = "example#gmail.com"
password = "password"
##how often to check ? give interval in seconds! Checking too often might performance and stability.
checkInterval = 120
Mailbox = imaplib.IMAP4_SSL(imapServer, port)
rc,resp = Mailbox.login(username,password)
if rc == 'OK':
print("Connected to mail-server " + imapServer)
rc, message = Mailbox.status('INBOX', "(UNSEEN)")
unreadCount = int(re.search("UNSEEN (\d+)",str( message[0])).group(1))
oldValue = 0
file = open("%sytemdrive%\Windows\Temp\mailnotify.tmp", "w+")
file.write(str(unreadCount))
file.close
while(1):
rc, message = Mailbox.status('INBOX', "(UNSEEN)")
unreadCount = int(re.search("UNSEEN (\d+)",str( message[0])).group(1))
file = open("%sytemdrive%\Windows\Temp\mailnotify.tmp", "w+")
oldValue = int(file.readline())
file.close()
if (unreadCount>oldValue):
subprocess.call(["notify-send", "-u", "low", "low", "t", "5000", "New email!", "New email!",
"You have " + str(unreadCount) + " unread " + "emails!" if unreadCount > 1 else "email!",
"--icon=email"])
if oldValue != unreadCount:
file = open("%sytemdrive%\Windows\Temp\mailnotify.tmp", "w+")
file.write(str(unreadCount))
file.close()
time.sleep(checkInterval)
else :
print('Fail to connect')
Mailbox.logout()
file.remove()