对华三设备日常巡检,使用python中的netmiko模块,通过线程池实现多线程执行。

import os
import sys
import time
import easygui
import netmiko
import encodings.idna
from concurrent.futures import ThreadPoolExecutor


def get_user_info():
    """获取用户输入信息"""
    while True:
        dev_type = str()
        # 定义用户输入的字段
        fields = ['设备厂商', '只读账号', '只读密码']
        default_values = ['H3C', '123456', 'abcd123']
        vendor, username, password = easygui.multpasswordbox('请输入用户信息', '', fields, default_values)

        # 验证用户的输入正确与否
        if not all(input_value.strip() for input_value in (vendor, username, password)):
            easygui.msgbox("\n\n输入信息不能为空。", "error", "ok")
            continue

        # 判断设备厂商
        if (vendor.strip().upper() == "H3C") or (vendor.strip() == "华三"):
            dev_type = "hp_comware"
            break
        elif (vendor.strip().upper() == "CISCO") or (vendor.strip() == "思科"):
            dev_type = "cisco_ios"
            break
        elif (vendor.strip().upper() == "HUAWEI") or (vendor.strip() == "华为"):
            dev_type = "huawei"
            break
        else:
            easygui.msgbox(f"\n\n无效的设备厂商:{vendor}", "Error", "OK")
            continue
    return dev_type, username, password


def get_resource_path(relative_path):
    """实现外部资源路径的定位"""
    # 获取当前执行文件的绝对路径
    base_path = os.path.realpath(sys.argv[0])
    # 获取非临时缓存文件路径的上一级目录,即实际resource文件夹路径
    base_dir = os.path.dirname(base_path)
    return os.path.join(base_dir, relative_path)  # 返回resources绝对路径


def get_dev_ip_info():
    """从本地文档中获取所有设备的管理地址信息"""
    ip_list = list()  # 保存设备IP地址的列表
    # 获取存放设备IP地址resource的路径
    dev_ip_path = get_resource_path(os.path.join("resources", "devs_ip.yhw"))
    try:
        # 遍历设备管理地址,并保存到列表中
        with open(dev_ip_path, mode="r", encoding="utf-8") as f:
            dev_ip_info = f.read()  # 读取设备管理地址信息
            for ip in dev_ip_info.split():  # 对读取到的管理地址进行格式清除
                ip_list.append(ip)
        ip_list = list(set(ip_list))  # 去重
    except Exception as e:
        print(f"发生错误:{e}")
    return ip_list


def make_dir():
    """创建一个文件夹,用来保存巡检数据"""
    # 获取当前日期
    date_time = time.strftime("%Y.%m.%d", time.localtime())
    # 判断当前目录下是否存在该文件目录,不存在则创建
    if not os.path.exists(f"巡检数据_{date_time}"):
        os.makedirs(f"巡检数据_{date_time}")
    file_path = f"巡检数据_{date_time}"
    return file_path  # 返回创建的文件夹相对路径


def append_to_exception_file(error_info, file_path):
    """将异常设备信息写入异常设备log文件中"""
    with open(os.path.join(file_path, "异常设备log.txt"), mode="a", encoding="utf-8") as f:
        f.write(error_info + "\n" + "*" * 60 + "\n")


def create_connect_info(dev_type, ip_list, username, password):
    """整合设备厂商、用户信息、设备管理地址,满足netmiko连接设备所需的参数"""
    devs_ssh_list = list()  # 用列表保存所有设备的SSH登录参数信息
    # 用于保存单台设备的SSH登录信息的字典
    for ip in ip_list:
        devs_dict = {
            "device_type": dev_type,
            "host": ip,
            "username": username,
            "password": password,
            "conn_timeout": 20,
            "timeout": 600,
        }
        # 将字典添加到列表中
        devs_ssh_list.append(devs_dict)
    return devs_ssh_list


def connect_dev(dev_info, file_path, normal_devs_list):
    """通过SSH连接到设备,读取巡检信息并保存到本地"""
    # 获取巡检命令文件绝对路径
    comm_info_path = get_resource_path(os.path.join("resources", "com_info.yhw"))
    try:
        with netmiko.ConnectHandler(**dev_info) as conn_dev:
            # 获取设备名称
            dev_name = conn_dev.send_command("display current-configuration | include sysname").strip().split(" ")[1]
            with open(os.path.join(file_path, dev_name + ".txt"), mode="w", encoding="utf-8") as dev_file:
                with open(comm_info_path, mode="r", encoding="utf-8") as command_info:
                    for com_info in command_info:
                        """
                        strip_command=False 表示不从返回的输出中移除发送的命令; 
                        strip_prompt=False 表示不从返回的输出中移除设备的提示符;
                        read_timeout=300 表示读取超时为300秒
                        """
                        dev_file.write(
                            conn_dev.send_command(com_info, strip_command=False, strip_prompt=False, read_timeout=300))
            normal_devs_list.append(dev_info["host"])
            print(f"设备{dev_name}命令配置收集完成")
    except netmiko.NetMikoAuthenticationException as e:
        print(f"设备{dev_info['host']}身份认证失败,请确认用户名和密码是否正确")
        append_to_exception_file(f"设备{dev_info['host']}身份认证失败,错误信息:\n{e}", file_path)
    except netmiko.NetMikoTimeoutException as e:
        print(f"设备{dev_info['host']}连接超时")
        append_to_exception_file(f"设备{dev_info['host']}连接超时,错误信息:\n{e}", file_path)
    except Exception as e:
        print(f"无法连接到设备{dev_info['host']}")
        append_to_exception_file(f"无法连接到设备{dev_info['host']},错误信息:\n{e}", file_path)


def thread_pool_ssh(devs_ssh_list, file_path, normal_devs_list):
    """多线程执行SSH连接"""
    print("信息收集中......", "\n")
    with ThreadPoolExecutor(5) as pool:
        for dev_info in devs_ssh_list:
            pool.submit(connect_dev, dev_info, file_path, normal_devs_list)


def main():
    """主函数"""
    normal_devs_list = list()  # 统计正常设备数量
    dev_type, username, password = get_user_info()  # 获取用户输入的设备厂商、用户名、密码
    start_time = time.time()  # 记录程序开始时间
    ip_list = get_dev_ip_info()  # 获取设备管理地址信息
    file_path = make_dir()  # 创建一个文件夹,用来保存巡检数据
    # 整合设备厂商、用户信息、设备管理地址,满足netmiko连接设备所需的参数
    devs_ssh_list = create_connect_info(dev_type, ip_list, username, password)
    thread_pool_ssh(devs_ssh_list, file_path, normal_devs_list)  # 开启多线程,并发执行SSH连接
    end_time = time.time()  # 程序结束时间
    used_time = int(end_time - start_time)  # 耗时时间
    # 提示退出系统
    while 1:
        res_info = easygui.msgbox(
            f"设备巡检信息收集完成。\n\n\n本次巡检共涉及{len(ip_list)}台设备,正常收集{len(normal_devs_list)}台,存在连接异常设备{len(ip_list) - len(normal_devs_list)}台,共计用时{used_time}秒。\n\n\n异常设备信息请查看'异常设备log'文档,确认无误后可退出!",
            "收集完成提示信息", "退出")
        if res_info == '退出':
            break


if __name__ == '__main__':
    print("华三设备display命令收集工具", "\n", "编辑:YHW", "\n", "联系方式:136****0032", sep="")
    print("*" * 40)
    main()
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华三交换机v5版本是一种常用的网络设备,针对这种交换机,可以利用Pythonnetmiko库编写巡检代码。netmiko是一个用于连接和控制网络设备Python库,它支持各种厂商的设备,包括华三交换机。 要编写巡检代码,可以首先使用netmiko库连接到华三交换机,然后执行一系列命令来获取设备的各种状态信息。例如,可以获取交换机的端口状态、VLAN配置、路由表信息、硬件运行状况等。获取这些信息可以帮助网络管理员监控设备的运行状况,及时发现并解决问题。 在编写巡检代码时,需要考虑到不同情况下的异常处理和错误处理,例如连接超时、命令执行失败等情况。另外,为了使代码更易读和易维护,可以封装一些常用的操作为函数,例如获取端口状态的函数、获取路由表信息的函数等。这样可以提高代码的复用性和可扩展性。 此外,为了方便使用和管理,可以将巡检代码与其他功能代码分离,或者将其封装成一个单独的工具,供网络管理员使用。这样就可以将巡检代码集成到自动化运维系统实现定时、自动地对华三交换机进行巡检,提高网络运维的效率和可靠性。 总之,利用Pythonnetmiko库可以很方便地编写华三交换机v5版本的巡检代码,帮助网络管理员监控设备状态,及时发现并解决问题,提高网络的可靠性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值