Python3 Netmiko 和多线程?

问题描述

我正在努力构建一个包含多线程的脚本。

[我的目标:][1] [1]:https://i.stack.imgur.com/P4yuy.png

此脚本的目标是使用线程连接到多个设备并使用顺序方法执行命令,以便我可以有一个干净的输出,以便输出可以有序。

# ~~~~~~~~
# Import modules
# ~~~~~~~~
import subprocess,logging,re,getpass
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetMikoTimeoutException,NetMikoAuthenticationException
from paramiko.ssh_exception import SSHException
import threading,time
from queue import Queue

logging.basicConfig(level=logging.INFO,format="{asctime} {levelname:<8} {message}",style='{',filename='%slog' % __file__[:-2],filemode='a'
                    )
##logging.info("this is a message")

# ~~~~~~~~
# Define functions
# ~~~~~~~~
dev_list = []
success_dev = []
Failed_dev = []

def ping_ip(ip):
    global gips
    rstlongstr = ''
    (output,error) = subprocess.Popen((['ping',ip,'-c','2']),stdin=subprocess.PIPE,stdout=subprocess.PIPE,universal_newlines=True).communicate()
    if 'bytes from' in output:
        dev_list.append(ip)
        logging.info(output)
        print (output)
        reg_rttavg = re.findall(r'(?=rtt.*=\s[\d.]+\/([\d.]+))',output)
        strpreg_rttavg = [test2.strip() for test2 in reg_rttavg]
        str_rttavg = '\n'.join(strpreg_rttavg)
        reg_ploss = re.findall(r'[\d%.]+(?= packet loss)',output)
        strpreg_ploss = [test2.strip() for test2 in reg_ploss]
        str_ploss = '\n'.join(strpreg_ploss)
        #return ".....Device is Reachable - " + ip
        return "[ " + ip + " ] Reachable - rtt(avg): %s ploss: %s" % (str_rttavg,str_ploss)
    elif 'Host Unreachable' in output:
        print (output)
        return "[ " + ip + " ] Unreachable"
    else:
        #return "Unreachable"
        print (output)
        return "[ " + ip + " ] Unreachable"
    thread_q.put

def connect_Now(ip_a,username,password,enable_s):
    global success_dev,Failed_dev,output_dict
    output_dict = {}
    print ('[ ' + ip_a + ' ] Loging into IP')
    try:
        device_conn = ConnectHandler(device_type='cisco_ios_ssh',ip=ip_a,username=username,password=password,secret=enable_s,verbose=True)
        output_q.put(output_dict)
        
        device_conn.enable()
        hostname = device_conn.find_prompt()
        print ("hostname:",hostname)
        with open('out.txt','a') as DATAFILE:
            print(hostname,file=DATAFILE)
            sh_commands  = ['show run | i hostname','show clock']
            for cmd in sh_commands:
                print ("Sending command: ",cmd)
                time.sleep(2)
                result_out = device_conn.send_command(cmd)
                output_dict = {}
                output_dict[hostname].append(result_out)
                print ("## ## ## dict: ",output_dict)
                #output_dict[hostname].append(result_out)
                

##                print(result_out,file=DATAFILE)
            device_conn.disconnect()
            print ('[ ' + ip_a + ' ] Logged out')
            success_dev.append(hostname)
    except:
        print ('[ ' + ip_a + ' ] Unable to access')
        Failed_dev.append(ip_a)
##    output_q.put    


#~~~~~~~~~~~~~~
#MAIN
#~~~~~~~~~~~~~~
ipadd = ['192.168.2.111',"192.168.2.113",'9.9.9.222','192.168.2.112',"192.168.2.66",]
thread_q = Queue()
for x in ipadd:
    print ("Pinging: ",x)
    m_thread = threading.Thread(target=ping_ip,args=(x,))
    m_thread.start()
m_thread.join()    
print (dev_list)   


uname = "test"
pswd = "test"
ena = "test"

if uname == "" or pswd == "" or ena == "":
    print('username,password or enable_secret cannot be empty. Please enter valid credentials!!!')
    logging.info("username,password or enable_secret cannot be empty. Please enter valid credentials!!!")
    sys.exit()

logging.info("List of reachable device: " + str(dev_list))

NUM_THREADS = 3  # TARGET NUMBER OF DEVICES
num_threads = min(NUM_THREADS,len(dev_list))
start = time.time()
output_q = Queue()
for ip in dev_list:
    print ("Processing: ",ip)
    worker = threading.Thread(target=connect_Now,args=(ip,uname,pswd,ena))
    worker.start()
worker.join()  
print (output_dict)
end = time.time()
total = int(end - start)
print("\n Elapsd Time: " + str(total) + " Sec\n")

除此之外就是把输出放到字典output_dict中,所以我用这个代码output_dict[hostname].append(result_out)把值放到列表格式中,但是没有用。

问题:

  1. 如何修复或正确使用线程,我可以看到一些输出,但由于线程的原因,大部分无法看到。
  2. 如何将输出添加为字典值但作为列表。 ex {'CSRV#': ['outputa','outputb']}

先谢谢你。希望你能帮助我。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)