实验目的 之前学到了 Paramiko和re模块,前者可以使用SSH协议后者通过正则表达式获取关键信息。那么我想实现通过脚本对所有网路设备的自动化批量检查,如: CPU负载 Memory状况 温度状
实验目的
之前学到了Paramiko和re模块,前者可以使用SSH协议后者通过正则表达式获取关键信息。那么我想实现通过脚本对所有网路设备的自动化批量检查,如:
生成每个设备的数据并进行汇总,如果有异常情况再最后列表显示出不同错误情况的IP地址,同一IP可以归属到不同属性错误列表中。本次实验对象挑选华三交换机。另外随着知识的进一步学习,我希望后期再整合异步多线程、Email自动日报
代码总览
# ********************************************************************# Author: LinWeiWei
# Date: 2022-4-30
# Description: paramiko SSH module and provides H3C switch configuration services
# ********************************************************************
# The standard library
import paramiko
import time
import socket
import threading
import re
# Create an SSH class
class MySSH(object):
# Create init info
def __init__(self):
self.total_devices = None
self.total_port = None
self.ip_file = open(r"C:\python_txt\ManageIP.txt", "r")
self.iplist = self.ip_file.readlines()
self.switch_successful_execution = []
self.switch_with_authentication_issue = []
self.switch_not_reachable = []
self.switch_fan_failure = []
self.switch_environment_failure = []
self.switch_memory_failure = []
self.switch_cpu_failure = []
self.switch_power_failure = []
self.total_switch_fan = 0
self.total_switch_FanStateNormal = 0
self.total_switch_port = 0
self.total_switch_environment_normal = 0
self.total_switch_environment_warning = 0
self.total_switch_environment_alarm = 0
self.total_switch_cpu_normal = 0
self.total_switch_memory_normal = 0
self.total_switch_power_normal = 0
self.start_time = time.time() # Record the start time of execution
# Create an SSH connection
def switch_cmd(self):
for line in self.iplist:
try:
ip = line.strip()
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Trusting SSH Connections
ssh.connect(hostname=ip, port=22, username="admin", password="123456", timeout=3)
print("Successfully connected to " + ip)
cli = ssh.invoke_shell()
cli.send("disp fan \n")
cli.send("disp int brief | i XG \n")
cli.send("disp environment \n")
cli.send("disp memo sum \n")
cli.send("disp cpu sum \n")
cli.send("disp power \n")
self.switch_successful_execution.append(ip)
time.sleep(3)
output = cli.recv(65535).decode('utf-8').replace('\r', '') # decode(ascii)
# cpu check
cpu_state = re.findall(r'(?<=1).+(\%).+(\%).+(..%)', str(output))[0][2]
if float(cpu_state.replace('%', '')) <= 80:
print('Devices cpu last 5 min usage ' + str(cpu_state) + ', state is normal')
self.total_switch_cpu_normal += 1
else:
print('Devices cpu last 5 min usage ' + str(cpu_state) + ', state is abnormal')
self.switch_cpu_failure.append(ip)
# memory check
memory_state = re.findall(r'(?<=1).+(....%)', str(output))[0]
if float(memory_state.replace('%', '')) <= 80:
print('Devices memory usage ' + str(memory_state) + ', state is normal')
self.total_switch_memory_normal += 1
else:
print('Devices memory usage ' + str(memory_state) + ', state is abnormal')
self.switch_memory_failure.append(ip)
# environment check
environment_state = re.findall(r'(?<=hotspot)(.{4})\d+', str(output))[0]
if int(environment_state) <= 50:
print('Devices environment is ' + str(environment_state) + '℃, state is normal')
self.total_switch_environment_normal += int(len(re.findall(r'(?<=hotspot)(.{4})\d+', str(output))))
elif environment_state >= 50 <= 55:
print('Devices environment is ' + str(environment_state) + '℃, state is warning')
self.total_switch_environment_warning += int(len(re.findall(r'(?<=hotspot)(.{4})\d+', str(output))))
self.switch_environment_failure.append(ip)
else:
print('Devices environment is ' + str(environment_state) + '℃, state is alarm')
self.total_switch_environment_alarm += int(len(re.findall(r'(?<=hotspot)(.{4})\d+', str(output))))
self.switch_environment_failure.append(ip)
# fan check
fan_num = re.findall(r'Fan', str(output))
fan_state = re.findall(r'(?<=State).+Normal', str(output))
print(
'Devices has ' + str(len(fan_num)) + ' fans and ' + str(len(fan_state)) + ' in normal running, '
+ 'the number of failure ' + str(len(fan_num) - len(fan_state))
)
self.total_switch_fan += int(len(fan_num))
self.total_switch_FanStateNormal += int(len(fan_state))
if self.total_switch_fan < int(self.total_switch_FanStateNormal):
self.switch_fan_failure.append(ip)
# power check
power_state = len(re.findall(r'(?<=1).+(?=AC)|(?<=2).+(?=AC)', str(output)))
print('Devices has 2 powers and ' + str(power_state) + ' in normal running,'
+ ' the number of failure ' + str(2 - power_state))
self.total_switch_power_normal += int(power_state)
if power_state < 2:
self.switch_power_failure.append(ip)
# ports check
port_state = re.findall(r'UP', str(output))
print('Devices has ' + str(len(port_state)) + ' ports up, port up rate is '
+ str("%.2f%%" % int(len(port_state) / 24 * 100))
)
self.total_switch_port += int(len(port_state))
print()
except paramiko.ssh_exception.AuthenticationException:
print("User authentication failed for " + ip + ".")
self.switch_with_authentication_issue.append(ip)
print(self.switch_with_authentication_issue)
except socket.error:
print(ip + " is not reachable.")
self.switch_not_reachable.append(ip)
finally:
self.ip_file.close()
ssh.close()
# Create result info
def result_info(self):
print('-------------------------------------------------------------------------------------------------------')
print('Running time: ' + time.ctime())
print('Spend time:%s' % (time.time() - self.start_time) + 's')
# Calculate the total number of devices
self.total_devices = len(self.switch_successful_execution)
print('There are totally ' + str(self.total_devices) + ' devices in the network.')
# cpu result
print('1、The cpu has ' + str(self.total_switch_cpu_normal) + ' normal, cpu normal rate is '
+ str("%.2f%%" % int(self.total_switch_cpu_normal / self.total_devices * 100)))
# memory result
print('2、The memory has ' + str(self.total_switch_memory_normal) + ' normal, memory normal rate is '
+ str("%.2f%%" % int(self.total_switch_memory_normal / self.total_devices * 100)))
# environment result
print('3、The environment has ' + str(self.total_switch_environment_normal) + ' normal, has '
+ str(self.total_switch_environment_warning) + ' warning, has '
+ str(self.total_switch_environment_alarm) + ' alarm, environment normal rate is '
+ str("%.2f%%" % int(self.total_switch_environment_normal / self.total_devices * 100))
)
# fan result
print('4、The fan has ' + str(self.total_switch_fan) + ' available, '
+ str(self.total_switch_FanStateNormal) + ' fan are currently normal. Fan normal rate is '
+ str("%.2f%%" % int(self.total_switch_FanStateNormal / self.total_switch_fan * 100))
)
# power result
print('5、The power has ' + str(self.total_devices*2) + ' available, '
+ str(self.total_switch_power_normal) + ' port are currently normal. Port up rate is '
+ str("%.2f%%" % int(self.total_switch_power_normal / (self.total_devices*2) * 100))
)
# port result
self.total_port = len(self.switch_successful_execution) * 24 # Calculate the total number of ports
print('6、The port has ' + str(self.total_port) + ' available, '
+ str(self.total_switch_port) + ' port are currently up. Port up rate is '
+ str("%.2f%%" % int(self.total_switch_port / self.total_port * 100))
)
print()
print('Successful execution list')
print(self.switch_successful_execution)
print('Authentication failure list')
print(self.switch_with_authentication_issue)
print('Network connection failure list')
print(self.switch_not_reachable)
print('Environment failure list')
print(self.switch_environment_failure)
print('Fan failure list')
print(self.switch_fan_failure)
print('Memory failure list')
print(self.switch_memory_failure)
print('Cpu failure list')
print(self.switch_cpu_failure)
print('power failure list')
print(self.switch_power_failure)
if __name__ == '__main__':
MySSH = MySSH()
MySSH.switch_cmd()
MySSH.result_info()
代码解析
初始信息
# Create init infodef __init__(self):
self.total_devices = None
self.total_port = None
self.ip_file = open(r"C:\python_txt\ManageIP.txt", "r")
self.iplist = self.ip_file.readlines()
self.switch_successful_execution = []
self.switch_with_authentication_issue = []
self.switch_not_reachable = []
self.switch_fan_failure = []
self.switch_environment_failure = []
self.switch_memory_failure = []
self.switch_cpu_failure = []
self.switch_power_failure = []
self.total_switch_fan = 0
self.total_switch_FanStateNormal = 0
self.total_switch_port = 0
self.total_switch_environment_normal = 0
self.total_switch_environment_warning = 0
self.total_switch_environment_alarm = 0
self.total_switch_cpu_normal = 0
self.total_switch_memory_normal = 0
self.total_switch_power_normal = 0
self.start_time = time.time() # Record the start time of execution
SSH模块
# Create an SSH connectiondef switch_cmd(self):
for line in self.iplist:
try:
ip = line.strip()
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Trusting SSH Connections
ssh.connect(hostname=ip, port=22, username="admin", password="123456", timeout=3)
print("Successfully connected to " + ip)
cli = ssh.invoke_shell()
cli.send("disp fan \n")
cli.send("disp int brief | i XG \n")
cli.send("disp environment \n")
cli.send("disp memo sum \n")
cli.send("disp cpu sum \n")
cli.send("disp power \n")
self.switch_successful_execution.append(ip)
time.sleep(3)
output = cli.recv(65535).decode('utf-8').replace('\r', '') # decode(ascii)
CPU检查
获得CPU当前负载,如果<=80%认为正常,反之处于异常,不同的状态应有计数
# cpu checkcpu_state = re.findall(r'(?<=1).+(\%).+(\%).+(..%)', str(output))[0][2]
if float(cpu_state.replace('%', '')) <= 80:
print('Devices cpu last 5 min usage ' + str(cpu_state) + ', state is normal')
self.total_switch_cpu_normal += 1
else:
print('Devices cpu last 5 min usage ' + str(cpu_state) + ', state is abnormal')
self.switch_cpu_failure.append(ip)
内存检查
获得memory当前负载,如果<=80%认为正常,反之处于异常,不同的状态应有计数
# memory checkmemory_state = re.findall(r'(?<=1).+(....%)', str(output))[0]
if float(memory_state.replace('%', '')) <= 80:
print('Devices memory usage ' + str(memory_state) + ', state is normal')
self.total_switch_memory_normal += 1
else:
print('Devices memory usage ' + str(memory_state) + ', state is abnormal')
self.switch_memory_failure.append(ip)
温度检查
获得温度状况,如果<=50度认为正常,>=50<=55警告,反之处于严重状态,不同的状态应有计数
# environment checkenvironment_state = re.findall(r'(?<=hotspot)(.{4})\d+', str(output))[0]
if int(environment_state) <= 50:
print('Devices environment is ' + str(environment_state) + '℃, state is normal')
self.total_switch_environment_normal += int(len(re.findall(r'(?<=hotspot)(.{4})\d+', str(output))))
elif environment_state >= 50 <= 55:
print('Devices environment is ' + str(environment_state) + '℃, state is warning')
self.total_switch_environment_warning += int(len(re.findall(r'(?<=hotspot)(.{4})\d+', str(output))))
self.switch_environment_failure.append(ip)
else:
print('Devices environment is ' + str(environment_state) + '℃, state is alarm')
self.total_switch_environment_alarm += int(len(re.findall(r'(?<=hotspot)(.{4})\d+', str(output))))
self.switch_environment_failure.append(ip)
风扇检查
正则求出1台风扇1、2……的数量,匹配每个风扇的运行状态,返回给风扇列表计数,如果有故障单独给故障列表计数
# fan checkfan_num = re.findall(r'Fan', str(output))
fan_state = re.findall(r'(?<=State).+Normal', str(output))
print(
'Devices has ' + str(len(fan_num)) + ' fans and ' + str(len(fan_state)) + ' in normal running, '
+ 'the number of failure ' + str(len(fan_num) - len(fan_state))
)
self.total_switch_fan += int(len(fan_num))
self.total_switch_FanStateNormal += int(len(fan_state))
if self.total_switch_fan < int(self.total_switch_FanStateNormal):
self.switch_fan_failure.append(ip)
电源检查
正则求出1台电源1、2……的数量,匹配每个电源的运行状态,返回给电源列表计数,如果有故障单独给故障列表计数
# power checkpower_state = len(re.findall(r'(?<=1).+(?=AC)|(?<=2).+(?=AC)', str(output)))
print('Devices has 2 powers and ' + str(power_state) + ' in normal running,'
+ ' the number of failure ' + str(2 - power_state))
self.total_switch_power_normal += int(power_state)
if power_state < 2:
self.switch_power_failure.append(ip)
端口检查
获得交换机端口UP数量,探测目前公司设备使用情况,是否需要升级,是否符合设计
# ports checkport_state = re.findall(r'UP', str(output))
print('Devices has ' + str(len(port_state)) + ' ports up, port up rate is '
+ str("%.2f%%" % int(len(port_state) / 24 * 100))
)
self.total_switch_port += int(len(port_state))
异常检查
如果网络或者账户认证失败,记录并继续向下执行脚本
print()except paramiko.ssh_exception.AuthenticationException:
print("User authentication failed for " + ip + ".")
self.switch_with_authentication_issue.append(ip)
print(self.switch_with_authentication_issue)
except socket.error:
print(ip + " is not reachable.")
self.switch_not_reachable.append(ip)
finally:
self.ip_file.close()
ssh.close()
数据汇总
数据进行汇总报告,有故障的情况在不同的清单中记录
# Create result infodef result_info(self):
print('-------------------------------------------------------------------------------------------------------')
print('Running time: ' + time.ctime())
print('Spend time:%s' % (time.time() - self.start_time) + 's')
# Calculate the total number of devices
self.total_devices = len(self.switch_successful_execution)
print('There are totally ' + str(self.total_devices) + ' devices in the network.')
# cpu result
print('1、The cpu has ' + str(self.total_switch_cpu_normal) + ' normal, cpu normal rate is '
+ str("%.2f%%" % int(self.total_switch_cpu_normal / self.total_devices * 100)))
# memory result
print('2、The memory has ' + str(self.total_switch_memory_normal) + ' normal, memory normal rate is '
+ str("%.2f%%" % int(self.total_switch_memory_normal / self.total_devices * 100)))
# environment result
print('3、The environment has ' + str(self.total_switch_environment_normal) + ' normal, has '
+ str(self.total_switch_environment_warning) + ' warning, has '
+ str(self.total_switch_environment_alarm) + ' alarm, environment normal rate is '
+ str("%.2f%%" % int(self.total_switch_environment_normal / self.total_devices * 100))
)
# fan result
print('4、The fan has ' + str(self.total_switch_fan) + ' available, '
+ str(self.total_switch_FanStateNormal) + ' fan are currently normal. Fan normal rate is '
+ str("%.2f%%" % int(self.total_switch_FanStateNormal / self.total_switch_fan * 100))
)
# power result
print('5、The power has ' + str(self.total_devices*2) + ' available, '
+ str(self.total_switch_power_normal) + ' port are currently normal. Port up rate is '
+ str("%.2f%%" % int(self.total_switch_power_normal / (self.total_devices*2) * 100))
)
# port result
self.total_port = len(self.switch_successful_execution) * 24 # Calculate the total number of ports
print('6、The port has ' + str(self.total_port) + ' available, '
+ str(self.total_switch_port) + ' port are currently up. Port up rate is '
+ str("%.2f%%" % int(self.total_switch_port / self.total_port * 100))
)
print()
print('Successful execution list')
print(self.switch_successful_execution)
print('Authentication failure list')
print(self.switch_with_authentication_issue)
print('Network connection failure list')
print(self.switch_not_reachable)
print('Environment failure list')
print(self.switch_environment_failure)
print('Fan failure list')
print(self.switch_fan_failure)
print('Memory failure list')
print(self.switch_memory_failure)
print('Cpu failure list')
print(self.switch_cpu_failure)
print('power failure list')
print(self.switch_power_failure)