基于netmiko模块实现支持SSH or Telnet的多线程多厂商网络设备自动化巡检脚本

自动化巡检的需求

巡检工作通常包含大量的重复性操作,而这些重复性特征意味着其背后存在明确的规则和逻辑。这种规律性为实现自动化提供了理想的前提条件。

自动化工具

我们这里采用python作为自动化的执行工具。

过程

安装 netmiko

python 复制代码
pip install netmiko

模块的使用

python 复制代码
import os
from concurrent.futures import ThreadPoolExecutor
from os import makedirs
from netmiko import ConnectHandler
import csv
import chardet

厂商识别与协议识别

python 复制代码
    if i['厂商'] == '华为' and i['协议'] == 'ssh':
        device_type = 'huawei'
        cmd_txt = '华为巡检命令.txt'
    elif i['厂商'] == '华为' and i['协议'] == 'telnet':
        device_type = 'huawei_telnet'
        cmd_txt = '华为巡检命令.txt'
    elif i['厂商'] == '华三' and i['协议'] == 'ssh':
        device_type = 'hp_comware'
        cmd_txt = 'H3C巡检命令.txt'
    elif i['厂商'] == '华三' and i['协议'] == 'telnet':
        device_type = 'hp_comware_telnet'
        cmd_txt = 'H3C巡检命令.txt'
    elif i['厂商'] == '锐捷' and i['协议'] == 'ssh':
        device_type = 'ruijie_os'
        cmd_txt = '锐捷巡检命令.txt'
    elif i['厂商'] == '锐捷' and i['协议'] == 'telnet':
        device_type = 'ruijie_os_telnet'
        cmd_txt = '锐捷巡检命令.txt'

创建设备字典

python 复制代码
device = {
        'device_type': device_type,
        'host': i['ip'],
        'username': i['username'],
        'password': i['password'],
    }

调用构造函数并传参,**表示将字典解包并逐一传参

python 复制代码
conn = ConnectHandler(**device)

巡检记录之path变量为True

python 复制代码
dir = os.path.join('./巡检命令文件/', cmd_txt)
    path = './巡检记录/'
    if os.path.exists(path): #表示如果path变量中存储的路径存在则运行
        with open(dir, mode='rb') as ffile: #这段open是为了识别字符集编码
            data_bs = ffile.read()
            result_dict = chardet.detect(data_bs)
            encoding_cmd_txt = result_dict['encoding']
        with open(dir, mode='r', encoding=encoding_cmd_txt) as cmd_read:
            for cmd in cmd_read:
                stdout = conn.send_command(cmd.strip())
                with open(f'{path}{i['ip']}的巡检记录.txt', mode='a', encoding='utf-8') as addwrite:
                    addwrite.write(stdout)

巡检记录之path变量为false

python 复制代码
    else:
        makedirs(path)  #因为path变量中存储的路径不存在,因此创建一个
        with open(dir, mode='rb') as ffile:
            data_bs = ffile.read()
            result_dict = chardet.detect(data_bs)
            encoding_cmd_txt = result_dict['encoding']
        with open(dir, mode='r', encoding=encoding_cmd_txt) as cmd_read:
            for cmd in cmd_read:
                stdout = conn.send_command(cmd.strip())
                with open(f'{path}{i['ip']}的巡检记录.txt', mode='a', encoding='utf-8') as addwrite:
                    addwrite.write(stdout)

并且以上所有代码细节都封装进一个函数里以方便代码的抽象化引用和减少代码的重复性。

python 复制代码
def xijie(i):
    if i['厂商'] == '华为' and i['协议'] == 'ssh':
        device_type = 'huawei'
        cmd_txt = '华为巡检命令.txt'
    elif i['厂商'] == '华为' and i['协议'] == 'telnet':
        device_type = 'huawei_telnet'
        cmd_txt = '华为巡检命令.txt'
    elif i['厂商'] == '华三' and i['协议'] == 'ssh':
        device_type = 'hp_comware'
        cmd_txt = 'H3C巡检命令.txt'
    elif i['厂商'] == '华三' and i['协议'] == 'telnet':
        device_type = 'hp_comware_telnet'
        cmd_txt = 'H3C巡检命令.txt'
    elif i['厂商'] == '锐捷' and i['协议'] == 'ssh':
        device_type = 'ruijie_os'
        cmd_txt = '锐捷巡检命令.txt'
    elif i['厂商'] == '锐捷' and i['协议'] == 'telnet':
        device_type = 'ruijie_os_telnet'
        cmd_txt = '锐捷巡检命令.txt'
    device = {
        'device_type': device_type,
        'host': i['ip'],
        'username': i['username'],
        'password': i['password'],
    }
    conn = ConnectHandler(**device)
    dir = os.path.join('./巡检命令文件/', cmd_txt)
    path = './巡检记录/'
    if os.path.exists(path):
        with open(dir, mode='rb') as ffile:
            data_bs = ffile.read()
            result_dict = chardet.detect(data_bs)
            encoding_cmd_txt = result_dict['encoding']
        with open(dir, mode='r', encoding=encoding_cmd_txt) as cmd_read:
            for cmd in cmd_read:
                stdout = conn.send_command(cmd.strip())
                with open(f'{path}{i['ip']}的巡检记录.txt', mode='a', encoding='utf-8') as addwrite:
                    addwrite.write(stdout)
    else:
        makedirs(path)
        with open(dir, mode='rb') as ffile:
            data_bs = ffile.read()
            result_dict = chardet.detect(data_bs)
            encoding_cmd_txt = result_dict['encoding']
        with open(dir, mode='r', encoding=encoding_cmd_txt) as cmd_read:
            for cmd in cmd_read:
                stdout = conn.send_command(cmd.strip())
                with open(f'{path}{i['ip']}的巡检记录.txt', mode='a', encoding='utf-8') as addwrite:
                    addwrite.write(stdout)

主程序入口点

python 复制代码
if __name__ == '__main__':
    with open('host.csv',mode='rb') as file:
            raw_data = file.read()
            result = chardet.detect(raw_data)
            encoding = result['encoding']
    with open('host.csv',mode='r',encoding=encoding) as file:
            reader = csv.DictReader(file)
            max_thread = 10 #定义线程池中使用多少线程
            for i in reader:
               with ThreadPoolExecutor(max_workers=max_thread) as t:
                   t.submit(xijie,i) #提交任务

可以看出,由于将代码细节给抽象化成函数,因此整个代码显得更简洁了,特别是在主程序入口的体现,无需了解代码细节,直接引用即可。

具体代码实现

python 复制代码
import os
from concurrent.futures import ThreadPoolExecutor
from os import makedirs
from netmiko import ConnectHandler
import csv
import chardet

def xijie(i):
    if i['厂商'] == '华为' and i['协议'] == 'ssh':
        device_type = 'huawei'
        cmd_txt = '华为巡检命令.txt'
    elif i['厂商'] == '华为' and i['协议'] == 'telnet':
        device_type = 'huawei_telnet'
        cmd_txt = '华为巡检命令.txt'
    elif i['厂商'] == '华三' and i['协议'] == 'ssh':
        device_type = 'hp_comware'
        cmd_txt = 'H3C巡检命令.txt'
    elif i['厂商'] == '华三' and i['协议'] == 'telnet':
        device_type = 'hp_comware_telnet'
        cmd_txt = 'H3C巡检命令.txt'
    elif i['厂商'] == '锐捷' and i['协议'] == 'ssh':
        device_type = 'ruijie_os'
        cmd_txt = '锐捷巡检命令.txt'
    elif i['厂商'] == '锐捷' and i['协议'] == 'telnet':
        device_type = 'ruijie_os_telnet'
        cmd_txt = '锐捷巡检命令.txt'
    device = {
        'device_type': device_type,
        'host': i['ip'],
        'username': i['username'],
        'password': i['password'],
    }
    conn = ConnectHandler(**device)
    dir = os.path.join('./巡检命令文件/', cmd_txt)
    path = './巡检记录/'
    if os.path.exists(path):
        with open(dir, mode='rb') as ffile:
            data_bs = ffile.read()
            result_dict = chardet.detect(data_bs)
            encoding_cmd_txt = result_dict['encoding']
        with open(dir, mode='r', encoding=encoding_cmd_txt) as cmd_read:
            for cmd in cmd_read:
                stdout = conn.send_command(cmd.strip())
                with open(f'{path}{i['ip']}的巡检记录.txt', mode='a', encoding='utf-8') as addwrite:
                    addwrite.write(stdout)
    else:
        makedirs(path)
        with open(dir, mode='rb') as ffile:
            data_bs = ffile.read()
            result_dict = chardet.detect(data_bs)
            encoding_cmd_txt = result_dict['encoding']
        with open(dir, mode='r', encoding=encoding_cmd_txt) as cmd_read:
            for cmd in cmd_read:
                stdout = conn.send_command(cmd.strip())
                with open(f'{path}{i['ip']}的巡检记录.txt', mode='a', encoding='utf-8') as addwrite:
                    addwrite.write(stdout)

if __name__ == '__main__':
    with open('host.csv',mode='rb') as file:
            raw_data = file.read()
            result = chardet.detect(raw_data)
            encoding = result['encoding']
    with open('host.csv',mode='r',encoding=encoding) as file:
            reader = csv.DictReader(file)
            max_thread = 10
            for i in reader:
               with ThreadPoolExecutor(max_workers=max_thread) as t:
                   t.submit(xijie,i)
相关推荐
火车叼位1 小时前
脚本伪装:让 Python 与 Node.js 像原生 Shell 命令一样运行
运维·javascript·python
L543414461 小时前
告别代码堆砌匠厂架构让你的系统吞吐量翻倍提升
大数据·人工智能·架构·自动化·rpa
孤狼warrior1 小时前
YOLO目标检测 一千字解析yolo最初的摸样 模型下载,数据集构建及模型训练代码
人工智能·python·深度学习·算法·yolo·目标检测·目标跟踪
Katecat996631 小时前
YOLO11分割算法实现甲状腺超声病灶自动检测与定位_DWR方法应用
python
迎仔1 小时前
06-存储设备运维进阶:算力中心的存储管家
运维
心.c2 小时前
TCP协议深入解析
网络·网络协议·tcp/ip
?re?ta?rd?ed?2 小时前
linux中的调度策略
linux·运维·服务器
摇滚侠2 小时前
HTTP 404 - No response body available
网络·网络协议·http
全栈工程师修炼指南2 小时前
Nginx | stream content 阶段:TCP 协议四层反向代理浅析与实践
运维·网络·网络协议·tcp/ip·nginx
hweiyu002 小时前
Linux 命令:tr
linux·运维·服务器