Use Netmiko to loop through file and get switch ARP entries - python

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

Related

multithread pinging of IP address in Python

I have a list of IP addresses like 1000 no's. I am reading the ip_file.txt and storing the result file as result_date.txt. Below is the code that I achieved the result. But my issue is it's taking too long to execute the entire files. Can anyone suggest multithreading, please so that the desired result can be achieved quickly? Thanks in advance.
#!/usr/bin/env python
import os
import csv
import paramiko
from datetime import datetime
import time
import sys
import re
from collections import defaultdict
# Verifies your os type
from paramiko import file
OS_TYPE = os.name
# Sets the count modifier to the os type
count = '-n' if OS_TYPE == 'nt' else '-c'
def create_ip_list():
ip_list = []
with open("ip_file.txt", "r") as file:
for line in file:
ip_list.append(line.strip())
return ip_list
# fetching data
now = datetime.now()
dat = now.strftime("%d/%m/%Y")
# time = now.strftime("%H:%M:%S")
date_string = dat.replace('/', '-')
timestr = time.strftime("%d%m%Y-%H%M%S")
def ping_device(ip_list):
"""Ping ip_list and return results
return: None
rtype: None
"""
results_file = open("results_" + str(timestr) + ".txt", "w")
for ip in ip_list:
response = os.popen(f"ping {ip} {count} 1").read()
time.sleep(1.5)
#fetch Average time
print(response)
for i in response.split("\n"):
para = i.split("=")
try:
if para[0].strip() == "Minimum":
latency = para[3].strip()
print(latency)
# output1=latency[0:8].split(" ")
# test=output1[0]
# print(test)
except:
print("time run")
if "Received = 1" and "Approximate" in response:
#print(f"UP {ip} Ping Successful")
results_file.write(f"{ip},UP,{latency}" + "\n")
else:
print(f"Down {ip} Ping Unsuccessful")
results_file.write(f"{ip} Down" + "\n")
results_file.close()
if __name__ == "__main__":
ping_device(create_ip_list())
Write a function ping_one_device that takes a single ip and returns a single string giving the status. It should be easy to pull this out of ping_device.
Then
with open(results_file, "w") as results_file:
with ThreadPoolExecutor() as executor:
for result in map(ping_one_device, ip_list):
results_file.write(result)

How to get rid of dictionary number when dynamically building on

device_total={}
user_n="Cisco"
pwd= "test"
count=1
for i in range(0,31):
ip_addr= input('Please enter the device IP address' + ' : ')
dev_type = input (" Enter device type" + ' : ')
dsum = {'device type':dev_type,'host':ip_addr,'username':user_n,'password':pwd}
device_total[i] = dsum
i+1
query_user=input('Do you want to add additional devices? (y/n)' )
if query_user != 'y':
break
print(device_total)
I am trying to dynamically create multiple dictionaries based on a user input to be used to configure network devices with Netmiko, the dictionaries are built but every one of them is numbered which causes a line error when the Netmiko functions are trying to use them to log in a make configuration changes. Please let me know if there is a way to create the dictionary without them. I would like to create a separate dictionary for each device entered by the user not one with multiple entries. Thanks.
See example below:
{0: {'device type': 'cisco', 'host': '1.1.1.1', 'username': 'Cisco', 'password': 'test'}, 1: {'device type': 'Arista', 'host': '2.2.2.2', 'username': 'Cisco', 'password': 'test'}}
device_total=[]
user_n="Cisco"
pwd= "test"
count=1
for i in range(0,31):
ip_addr= input('Please enter the device IP address' + ' : ')
dev_type = input (" Enter device type" + ' : ')
dsum = {'device type':dev_type,'host':ip_addr,'username':user_n,'password':pwd}
device_total.append( dsum)
i+1
query_user=input('Do you want to add additional devices? (y/n)' )
if query_user != 'y':
break
print(device_total)
Here is the solution I came up with for anyone else that may in the same situation and stuck.
from getpass import getpass
from netmiko import ConnectHandler
from netmiko import NetmikoAuthenticationException
def user_input():
""" Getting user credentials """
usr_n = input("username: ")
pwd = getpass()
cred = (usr_n, pwd)
return cred
def net_devices():
login_info = user_input()
username = login_info[0]
password = login_info[1]
with open("districts devices.txt") as f:
net_devices = f.read().splitlines()
for device in net_devices:
try:
netw_devices = {"device_type": 'cisco_ios', 'host': device, 'username': username, 'password': password}
net_connect = ConnectHandler(**netw_devices)
except NetmikoAuthenticationException:
print(f"Unable to login to {device}. Verify you have the right credentials or it is added to ISE.")
continue
""" Verifying the access-list has been applied to the device. """
print('Verifying ACL the is on: ' + device)
verification = net_connect.send_command('show run | b line vty')
if "access-class" not in verification:
print("\nThe access-class is missing from this device's configuration. Configuring the ACL on: "
+ device)
acl_cmds = ['service password-encryption', 'ip access-list standard Sample-ONLY',
'permit 10.0.0.0 0.255.255.255',
' permit 172.16.0.0 0.0.255.255', 'line vty 0 15', 'transport in ssh',
'access-class sample in', 'do write memory']
commands = net_connect.send_config_set(acl_cmds)
print(commands)
else:
print("\nNo update necessary.\n")
# print(" \nVerifying the ACL is now in place.")
# re_verification = net_connect.send_command('\nshow run | b line vty')
# print(re_verification)
net_connect.disconnect()
net_devices()

How can I make my current code use Multithreading/concurrent.futures?

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)

Python | Netmiko | Auto ping

im beginner and i have tried for a lot
code :
conn = netmiko.ConnectHandler(ip='10.254.60.10', device_type='cisco_ios',
username='user', password='P#ssw0rd')
print (conn.send_command('show interface Ethernet0/0 | i line|Des|Int'))
output like this
Ethernet0/0 is up, line protocol is up
Description: CUSTOMER A
Internet address is 10.254.60.69/30
how to auto ping to IP PtP using conn.send_command() based on result of show interface command?
example ping to 10.254.60.70
You get text
text = '''Ethernet0/0 is up, line protocol is up Description: CUSTOMER A
Internet address is 10.254.60.70/30'''
and you can get IP/MASK using string functions
address = text.split(' ')[-1]
print(address) # 10.254.60.70/30
and then you can use standard module ipaddress
import ipaddress
net = ipaddress.ip_interface(address)
ip = str(net.network.broadcast_address)
print( ip ) # 10.254.60.71
or not standard module netaddr
import netaddr
net = netaddr.IPNetwork(address)
ip = str(net.broadcast)
print( ip ) # 10.254.60.71
EDIT: Minimal working code
text = '''Ethernet0/0 is up, line protocol is up Description: CUSTOMER A
Internet address is 10.254.60.69/30'''
address = text.split(' ')[-1]
print(address) # 10.254.60.69/30
print('\n--- ipaddress ---\n')
import ipaddress
net = ipaddress.ip_interface(address)
print('ip :', net.ip ) # 10.254.60.69
print('ip+1:', net.ip+1 ) # 10.254.60.70
print('ip-1:', net.ip-1 ) # 10.254.60.68
#bip = net.network.broadcast_address
bip = str(net.network.broadcast_address)
print('bip :', bip ) # 10.254.60.71
print('\n--- netaddr ---\n')
import netaddr
net = netaddr.IPNetwork(address)
print('ip :', net.ip ) # 10.254.60.69
print('ip+1:', net.ip+1 ) # 10.254.60.70
print('ip-1:', net.ip-1 ) # 10.254.60.68
bip = net.broadcast
#bip = str(net.broadcast)
print('bip :', bip ) # 10.254.60.71
Result:
10.254.60.69/30
--- ipaddress ---
ip : 10.254.60.69
ip+1: 10.254.60.70
ip-1: 10.254.60.68
bip : 10.254.60.71
--- netaddr ---
ip : 10.254.60.69
ip+1: 10.254.60.70
ip-1: 10.254.60.68
bip : 10.254.60.71
This could be your sample and so easy minimal code with Netmiko :
from netmiko import ConnectHandler
cisco_Router = {
"device_type": "cisco_ios",
"host": "your_router_ip",
"username": "your_username",
"password": "your_password"}
with ConnectHandler(**cisco_Router) as net_connect:
result = net_connect.send_command("ping 4.2.2.4")
net_connect.disconnect()
print(result)
I haven't write it for netmiko yet, but I often use this code for paramiko.
import threading
from ping3 import ping
from queue import Queue
from ipaddress import ip_network, ip_address
import paramiko
import time
from termcolor import colored
import sys
import os
import subprocess
file1 = open('PING_OK.txt', 'w')
file2 = open('PING_NOK.txt', 'w')
hosts=[]
f1 = open('hostfile.txt', 'r')
devices= f1.readlines()
#print(devices)
for i in devices:
i = i.split()
hosts.append(i[0])
hosts_live = []
q = Queue()
for host in hosts:
q.put(host)
enter = "\r\n"
def ping2(ip_address):
from pythonping import ping
output = ping(ip_address, verbose=True)
output_list =output.rtt_avg_ms
print(output_list)
if output_list == 2000:
print("erişim yok"+ip_address)
file2.write(ip_address+"\n")
else:
print ("erişim var"+ip_address)
file1.write(ip_address + "\n")
def worker():
while True:
host = q.get()
ping2(host)
time.sleep(2)
q.task_done()
for i in range(1):#aynı anda bağlantı 15 ten fazla girilmemeli #
t = threading.Thread(target=worker)
t.deamon = True
t.start()
q.join()
file1.close()
file2.close()

How to print and send changing IDs though python to another computer with sockets

Basically, I have my code, which finds the Lobby ID of a video-game, which then sends to my laptop. This then opens the exe with a argument and that certain Lobby ID. I want it to change when I start up another game/server. I have the script to output when the lobby ID changes, but when I plug it into my socket script. It only outputs the first one.
If I hash out all the s= socket... part and under it functions correctly
import socket
import glob
import os
import re
placeholder = ''
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '192.168.0.17'
port = 50502
s.connect((host,port))
while True:
GAME_DIRECTORY = 'C:/Program Files/Oculus/Software/Software/ready-at-dawn-echo-arena'
logs = glob.glob(GAME_DIRECTORY + '/_local/r14logs/*')
log = max(logs, key = os.path.getctime)
with open(log, 'r') as f:
file = f.read()
lobbyid = re.findall(r'........-....-....-....-............', file)[-1]
if lobbyid != placeholder:
if lobbyid != ('00000000-0000-0000-0000-000000000000'):
placeholder = lobbyid
print (lobbyid)
def ts(str):
s.send(lobbyid.encode())
data = ''
data = s.recv(1024).decode()
s.close ()
ts(s)

Categories

Resources