我有一个简单的程序,使用 Netmiko Library 通过SSH连接从交换机/路由器cisco获取信息。
程序效果很好,但程序会冻结,直到过程完成。
我的代码:
当我按下'生成'按钮会在sshConnection
运行我的应用程序突然冻结后调用sshConnection
功能
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from netmiko import ConnectHandler
from paramiko import SSHException
import jtextfsm as textfsm
import ipaddress
import matplotlib.pyplot as plt
import numpy as np
import io
import time
class Stream(QObject):
newText = pyqtSignal(str)
def write(self, text):
self.newText.emit(str(text))
def flush(self):
pass
class MyClass(object):
def __init__(self, device_type=None, ip=None, username=None, password=None, secret=None, command=None):
self.device_type = device_type
self.ip = ip
self.username = username
self.password = password
self.secret = secret
self.command = command
class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.device_list = [] # object array
self.setWindowTitle("Network Automation")
self.setFixedSize(350,500)
############################# Input IP
sys.stdout = Stream(newText=self.onUpdateText)
# Device Type
lb_device_list = QLabel(self)
lb_device_list.setText('Device Type')
self.cb_device_list = QComboBox(self)
self.cb_device_list.addItem('cisco_ios')
self.cb_device_list.addItem('cisco_s300')
# Ip Device
lb_ip = QLabel(self)
lb_ip.setText('IP Address')
self.le_ip = QLineEdit(self)
self.le_ip.setText('')
self.le_ip.setPlaceholderText('Input Device IP')
self.le_ip.setFixedWidth(150)
# username
lb_username = QLabel(self)
self.le_username = QLineEdit(self)
lb_username.setText('Username')
self.le_username.setText('')
self.le_username.setPlaceholderText('Input Username')
self.le_username.setFixedWidth(150)
# password
lb_password = QLabel(self)
self.le_password = QLineEdit(self)
lb_password.setText('Password')
self.le_password.setText('')
self.le_password.setPlaceholderText('Input Password')
self.le_password.setFixedWidth(150)
# Privilage Password
lb_enable = QLabel(self)
lb_enable.setText('Privilege Mode Password')
self.le_enable = QLineEdit(self)
self.le_enable.setText('')
self.le_enable.setPlaceholderText('Input Enable Password')
self.le_enable.setFixedWidth(150)
# button generate and add
btgenerate = QPushButton(self)
btgenerate.setText('Generate')
btgenerate.setFixedWidth(70)
btadd = QPushButton(self)
btadd.setText('Add')
# button delete
btdel = QPushButton(self)
btdel.setFixedWidth(70)
btdel.setText('Remove')
# line
line = QFrame(self)
line.setFrameShape(QFrame.VLine)
line.setFrameShadow(QFrame.Sunken)
line.setLineWidth(3)
#line 2
line2 = QFrame(self)
line2.setFrameShape(QFrame.HLine)
line2.setFrameShadow(QFrame.Sunken)
line2.setLineWidth(3)
########################### Layout Ip Device List
lb3 = QLabel(self)
lb3.setText('IP Device List')
self.ip_device_list = QListWidget(self)
self.ip_device_list.setFixedWidth(150)
# self.combobox_ip_list = QComboBox(self)
# self.combobox_ip_list.setFixedWidth(170)
############################## SubLayout and Layout
hblayout = QHBoxLayout()
hblayout.addWidget(btgenerate)
hblayout.addWidget(btadd)
############################### Processs
processlabel = QLabel("Process",self)
self.process = QTextEdit(self)
self.process.setLineWrapColumnOrWidth(400)
self.process.setLineWrapMode(QTextEdit.FixedPixelWidth)
self.process.setReadOnly(True)
sublayout = QVBoxLayout()
sublayout.addWidget(lb_device_list)
sublayout.addWidget(self.cb_device_list)
sublayout.addWidget(lb_ip)
sublayout.addWidget(self.le_ip)
sublayout.addWidget(lb_username)
sublayout.addWidget(self.le_username)
sublayout.addWidget(lb_password)
sublayout.addWidget(self.le_password)
sublayout.addWidget(lb_enable)
sublayout.addWidget(self.le_enable)
sublayout.addLayout(hblayout)
sublayout2 = QVBoxLayout()
sublayout2.addWidget(lb3)
sublayout2.addWidget(self.ip_device_list)
#sublayout2.addWidget(self.combobox_ip_list)
sublayout2.addWidget(btdel)
sublayout2.addStretch(1)
sublayout3 = QVBoxLayout()
sublayout3.addWidget(processlabel)
sublayout3.addWidget(self.process)
layout = QGridLayout(self)
layout.addLayout(sublayout, 0, 0)
layout.addWidget(line, 0, 1)
layout.addWidget(line2, 1, 0, 1, 3)
#layout.addWidget(processlabel,2,0)
layout.addLayout(sublayout3,2,0,2,3)
layout.addLayout(sublayout2, 0, 2)
btadd.clicked.connect(self.addDevice)
btdel.clicked.connect(self.remove)
btgenerate.clicked.connect(self.sshConection)
def onUpdateText(self, text):
cursor = self.process.textCursor()
cursor.movePosition(QTextCursor.End)
cursor.insertText(text)
self.process.setTextCursor(cursor)
self.process.ensureCursorVisible()
def __del__(self):
sys.stdout = sys.__stdout__
# ----------- AddDevice Process
def addDevice(self):
try:
ip = self.le_ip.text()
ipaddress.ip_address(ip)
device_type = str(self.cb_device_list.currentText())
username = self.le_username.text()
password = self.le_password.text()
secret = self.le_enable.text()
command = 'show tech'
coomand2 = ''
self.device_list.append(MyClass(device_type, ip, username, password, secret, command))
# self.combobox_ip_list.addItem(ip)# Add Ip to ComboBox
self.ip_device_list.addItem(ip)
self.le_ip.clear()
self.le_username.clear()
self.le_password.clear()
self.le_enable.clear()
for list in self.device_list:
print(list.ip, list.device_type)
except ValueError:
print("insert you're ip correctly")
QMessageBox.question(self, 'Warning', "Insert You're IP Corecctly")
def remove(self):
index = self.ip_device_list.currentRow()
if index != -1:
self.ip_device_list.takeItem(index)
del self.device_list[index]
# ------------- TEXTFSM Process
def TextFSM(self, nameFile, nameFile2):
try:
input_file = open(nameFile + '.txt', encoding='utf-8') # show version
raw_text_data = input_file.read()
input_file.close()
input_file2 = open(nameFile + '.txt', encoding='utf-8') # show env
raw_text_data2 = input_file2.read()
input_file2.close()
input_file3 = open(nameFile + '.txt', encoding='utf-8') # show flash
raw_text_data3 = input_file3.read()
input_file3.close()
input_file4 = open(nameFile + '.txt', encoding='utf-8') # show memory statistic
raw_text_data4 = input_file4.read()
input_file4.close()
input_file5 = open(nameFile + '.txt', encoding='utf-8') # show process cpu
raw_text_data5 = input_file5.read()
input_file5.close()
template = open("show-version.textfsm") # show version
re_table = textfsm.TextFSM(template)
fsm_results = re_table.ParseText(raw_text_data)
template2 = open("show-env.textfsm") # show env
re_table2 = textfsm.TextFSM(template2)
fsm_results2 = re_table2.ParseText(raw_text_data2)
template3 = open("show-flash.textfsm") # show flash
re_table3 = textfsm.TextFSM(template3)
fsm_results3 = re_table3.ParseText(raw_text_data3)
template4 = open("show-memory-statistic.textfsm") # show memory statistic
re_table4 = textfsm.TextFSM(template4)
fsm_results4 = re_table4.ParseText(raw_text_data4)
template5 = open("show-process-cpu.textfsm") # show process cpu
re_table5 = textfsm.TextFSM(template5)
fsm_results5 = re_table5.ParseText(raw_text_data5)
outfile_name = open(nameFile2 + "-show-version.csv", "w+") # show version
outfile = outfile_name
outfile_name2 = open(nameFile2 + "-show-env.csv", "w+") # show env
outfile2 = outfile_name2
outfile_name3 = open(nameFile2 + "-show-flash.csv", "w+") # show flash
outfile3 = outfile_name3
outfile_name4 = open(nameFile2 + "-show-memory-statistic.csv", "w+") # show memory statistic
outfile4 = outfile_name4
outfile_name5 = open(nameFile2 + "-show-process-cpu.csv", "w+") # show process cpu
outfile5 = outfile_name5
print(re_table.header) # show version
for s in re_table.header:
outfile.write("%s;" % s)
outfile.write("\n")
counter = 0
for row in fsm_results: # show version
print(row)
for s in row:
outfile.write("%s;" % s)
outfile.write("\n")
counter += 1
print("Write %d records" % counter)
print(re_table2.header) # show env
for s in re_table2.header:
outfile2.write("%s;" % s)
outfile2.write("\n")
counter = 0
for row in fsm_results2: # show env
print(row)
for s in row:
outfile2.write("%s;" % s)
outfile2.write("\n")
counter += 1
print("Write %d records" % counter)
print(re_table3.header) # show flash
for s in re_table3.header:
outfile3.write("%s;" % s)
outfile3.write("\n")
counter = 0
for row in fsm_results3: # show flash
print(row)
for s in row:
outfile3.write("%s;" % s)
outfile3.write("\n")
counter += 1
print("Write %d records" % counter)
print(re_table4.header) # show memory statistics
for s in re_table4.header:
outfile4.write("%s;" % s)
outfile4.write("\n")
counter = 0
for row in fsm_results4: # show memory statistics
print(row)
for s in row:
outfile4.write("%s;" % s)
outfile4.write("\n")
counter += 1
print("Write %d records" % counter)
print(re_table5.header) # show process cpu
for s in re_table5.header:
outfile5.write("%s;" % s)
outfile5.write("\n")
counter = 0
for row in fsm_results5: # show process cpu
print(row)
for s in row:
outfile5.write("%s;" % s)
outfile5.write("\n")
counter += 1
print("Write %d records" % counter)
except IOError:
print("Error: There Have File does not appear to exist.")
QMessageBox.question(self, 'Warning', "ERROR:Please check you're '.txt' file and TextFSM File.")
# ------------- Convert Data to Graphic
def Graph(self, fileName2):
fig = plt.figure(figsize=(8.8, 5.5), dpi=150) # ukuran frame gambar (L X P)
plt.rcParams['text.color'] = 'k' # warna tulisan
plt.rcParams.update({'font.size': 6}) # font size
plt.subplots_adjust(hspace=.4, right=.8, bottom=.2) # jarak antar gambar (margin)
# 1 - show flash
plt.subplot(2, 2, 1)
try:
data = np.loadtxt(fileName2 + '-show-flash.csv', dtype=bytes, delimiter=';', usecols=(0, 1))\
.astype(str, io.StringIO())
slices = data[1]
labels = data[0]
colors = ['lightskyblue', 'lightcoral']
explode = [0.08, 0.01]
pie = plt.pie(slices, labels=labels, colors=colors, explode=explode, startangle=90, shadow=True,
autopct='%1.1f%%')
plt.title('Flash Memory\n(Bytes)')
plt.legend(pie[0], [" ".join(a) for a in zip(labels, slices)], loc='upper right')
plt.axis('equal')
except IOError:
print("Error: There Have File does not appear to exist.")
QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
# 2 - show memory statistic
plt.subplot(2, 2, 2)
try:
data = np.loadtxt(fileName2 + '-show-memory-statistic.csv', dtype=bytes, delimiter=';',
usecols=(3, 4)).astype(str, io.StringIO())
slices = data[1]
labels = data[0]
colors = ['lightskyblue', 'lightcoral']
explode = [0.08, 0.01]
pie = plt.pie(slices, labels=labels, colors=colors, explode=explode, startangle=90, shadow=True,
autopct='%1.1f%%')
plt.title('Memory Statistic\n(Bytes)')
plt.legend(pie[0], [" ".join(a) for a in zip(labels, slices)], loc='upper right')
plt.axis('equal')
except IOError:
print("Error: There Have File does not appear to exist.")
QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
# 3 - show cpu utilization
plt.subplot(2, 2, 3)
def autolabel(rects):
for rect in rects:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height - 2, '%1.1f%%' % int(height), ha='center',
va='bottom')
N = 3
try:
data = np.loadtxt(fileName2 + '-show-process-cpu.csv', dtype=bytes, delimiter=';',
usecols=(0, 1, 2)).astype(str)
my_xticks = data[0]
utilization = data[1]
utilization_int = [int(x) for x in utilization]
ind = np.arange(N)
width = 0.5
rects1 = plt.bar(ind, utilization_int, width, color='lightblue', )
plt.title("CPU Utilization\n ('%') ")
plt.xticks(ind, my_xticks)
plt.xlabel("CPU Utilization")
plt.ylabel("Percent(%)")
autolabel(rects1)
except IOError:
print("Error: There Have File does not appear to exist.")
QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
# 4 - CPU Environtment
plt.subplot(2, 2, 4)
def autolabel(rects):
for rect in rects:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height - 5, '%d C' % int(height), ha='center',
va='bottom')
N = 3
try:
data = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=2).astype(str)
value = data[1]
if value == '':
try:
fan = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=0).astype(str)
system_temp = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=1).astype(
str)
power = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=6).astype(str)
rps = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=7).astype(str)
uptime = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=3).astype(
str)
pid = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=5).astype(str)
sn = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=6).astype(str)
uptime_title = uptime[0]
uptime_value = uptime[1]
pid_title = pid[0]
pid_value = pid[1]
sn_title = sn[0]
sn_value = sn[1]
fan_title = fan[0]
fan_status = fan[1]
system_temp_title = system_temp[0]
system_temp_value = system_temp[1]
power_tile = power[0]
power_value = power[1]
rps_tile = rps[0]
rps_value = rps[1]
text = fan_title + ' : ' + fan_status + '\n' + system_temp_title + ' : ' + system_temp_value + '\n' \
+ power_tile + ' : ' + power_value + '\n' + rps_tile + ' : ' + rps_value + ' PRESENT' + '\n\n' \
+ uptime_title + ' : ' + uptime_value + '\n' + pid_title + ' : ' + pid_value + '\n' + sn_title\
+ ' : ' + sn_value
plt.title("Cpu Environment\n ('Celcius') ")
plt.xlabel('CPU Environment')
plt.ylabel('Celcius')
plt.text(.15, 1 / 3, text, style='oblique', bbox={'facecolor': 'white', 'alpha': 0.5, 'pad': 5})
# plt.show('')
plt.savefig(fileName2 + '.png', bbox_inches='tight')
except (IOError):
print("Error: There Have File does not appear to exist.")
QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
plt.savefig(fileName2 + '.png', bbox_inches='tight')
else:
try:
data = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';',
usecols=(2, 4, 5)).astype(str)
fan = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=0).astype(str)
system_temp = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=1).astype(
str)
system_temp_state = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';',
usecols=3).astype(str)
uptime = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=3).astype(
str)
pid = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=5).astype(str)
sn = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=6).astype(str)
y_height = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, skiprows=1, delimiter=';',
usecols=5).astype(int)
uptime_title = uptime[0]
uptime_value = uptime[1]
pid_title = pid[0]
pid_value = pid[1]
sn_title = sn[0]
sn_value = sn[1]
fan_title = fan[0]
fan_status = fan[1]
system_temp_title = system_temp[0]
system_temp_value = system_temp[1]
system_temp_state_title = system_temp_state[0]
system_temp_state_status = system_temp_state[1]
my_xticks = data[0]
utilization = data[1]
utilization_int = [int(x) for x in utilization]
ind = np.arange(N)
width = 0.5
text = fan_title + ': ' + fan_status + '\n' + system_temp_title + ': ' + system_temp_value + \
'\n' + system_temp_state_title + ': ' + system_temp_state_status
text2 = pid_title + ' : ' + pid_value + '\n' + sn_title + ' : ' + sn_value +\
'\n\n' + uptime_title + ' : ' + uptime_value
rects1 = plt.bar(ind, utilization_int, width, color='r')
plt.title("CPU Environment\n ('Celcius') ")
plt.xticks(ind, my_xticks)
plt.xlabel('CPU Environment')
plt.ylabel('Celcius')
plt.text(2.4, y_height / 2, text)
plt.text(-1.59, -y_height / 1.77, text2, style='oblique',
bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 5})
autolabel(rects1)
# plt.show()
plt.savefig(fileName2 + '.png', bbox_inches='tight')
except (IOError, ValueError):
print("Error: There Have File does not appear to exist.")
QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
plt.savefig(fileName2 + '.png', bbox_inches='tight')
except (IOError):
print("Error: There Have File does not appear to exist.")
QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
plt.savefig(fileName2 + '.png', bbox_inches='tight')
# ------------- SSH Connection
def sshConection(self):
for list in self.device_list:
# time.sleep(0.2)
# Cisco IOS
if list.device_type == 'cisco_ios':
try:
print("SSH Connection Establishing---111")
net_connect = ConnectHandler(device_type=list.device_type, ip=list.ip, username=list.username,
password=list.password, secret=list.secret)
net_connect.enable()
print("SSH Connection Established---222")
output = net_connect.find_prompt()
hostname = output[:-1]
result = net_connect.send_command_expect(list.command, delay_factor=50)
try:
file = open(hostname + "-" + list.command + ".txt", "w", encoding="utf-8")
file.write(result)
print("Write File Sucess")
nameFile = hostname + "-" + list.command
nameFile2 = hostname
self.TextFSM(nameFile, nameFile2)
self.Graph(nameFile2)
except EOFError:
print("Faild Write Text File")
QMessageBox.question(self, 'Warning', "Faild Write Text File")
net_connect.disconnect()
except (EOFError, SSHException):
print("\nError: Connection Faild.")
QMessageBox.question(self, 'Warning', "Error: Connection Faild.")
# CISCO_S300 (SF300)
elif list.device_type == 'cisco_s300':
try:
net_connect = ConnectHandler(device_type=list.device_type, ip=list.ip, username=list.username,
password=list.password)
output = net_connect.find_prompt()
hostname = output[:-1]
result = net_connect.send_command(list.command, delay_factor=50)
file = open(hostname + "-" + list.command + ".txt", "w", encoding="utf-8")
file.write(result)
nameFile = hostname + "-" + list.command
nameFile2 = hostname
self.TextFSM(nameFile, nameFile2)
self.Graph(nameFile2)
net_connect.disconnect()
except (EOFError, SSHException):
print("\nError: Connection Faild.")
##################################
app = QApplication(sys.argv)
QApplication.processEvents()
app.setStyle('cleanlooks')
window = Widget()
window.show()
sys.exit(app.exec_())