Python3.8实战:三分钟搞定华为/H3C/Cisco交换机批量巡检(附完整代码)
每次月初或者重大节假日前,看着机房里那一排排沉默的交换机,心里是不是就有点发怵?手动一台台登录,敲命令,记录结果,再对比分析,一个下午就这么过去了,还容易看花眼。这种重复、繁琐但又至关重要的巡检工作,正是自动化脚本大显身手的地方。今天,我们就来聊聊如何用Python3.8,快速搭建一个属于自己的多品牌交换机批量巡检工具,把“体力活”交给代码,把时间留给更有价值的故障分析和优化思考。无论你是刚接触Python的网络运维新手,还是想优化现有流程的老手,这篇实战指南都将提供一套清晰、可落地的解决方案。
1. 巡检工具的核心架构与准备工作
在动手写代码之前,我们先得把工具的整体思路理清楚。一个高效的批量巡检脚本,其核心目标无非是:安全连接、高效执行、准确解析、清晰呈现。为了实现这个目标,我们的工具架构可以划分为几个清晰的模块。
首先,我们需要一个可靠的连接引擎。对于现代网络设备,SSH(Secure Shell)是远程管理的标准协议。Python中有几个库可以处理SSH连接,比如经典的paramiko和更现代的asyncssh。考虑到稳定性和广泛的社区支持,我们选择paramiko作为本次实战的基础。它能够稳定地处理与华为、H3C、Cisco等主流厂商设备的SSH会话。
其次,命令执行与结果捕获模块。不同品牌的交换机,其命令语法和回显格式各有差异。我们的脚本需要能够适配这种差异,发送正确的命令,并完整地捕获设备返回的文本信息。这里的关键在于处理交互式提示,比如--More--分页,以及可能出现的错误信息。
最后,结果解析与报告生成模块。原始的命令输出是杂乱的文本,我们需要从中提取出关键指标(如CPU利用率、内存使用率、端口状态、告警信息等),并将其结构化,最终生成一份人类可读的报告(如Markdown、HTML)或机器可读的数据(如JSON、CSV),便于后续分析和归档。
注意:在实际生产环境中操作前,务必在实验室或非核心设备上进行充分测试,确保脚本行为符合预期,避免因脚本错误对现网造成影响。
接下来,我们搭建基础的Python环境。确保你安装了Python3.8或更高版本。然后,通过pip安装必要的依赖库:
pip install paramiko
此外,为了后续可能的数据处理和报告生成,我们也可以一并安装pandas和openpyxl(用于生成Excel报告)或jinja2(用于生成HTML报告),但这并非必需,我们可以先从简单的文本报告开始。
pip install pandas openpyxl
准备工作就绪后,我们先来创建一个简单的设备信息配置文件。将待巡检的交换机信息(IP地址、品牌、登录凭证)组织在一个结构化的文件里,比如CSV或JSON,这样便于管理和扩展。这里我们使用JSON格式,因为它更易于Python直接读取。
创建一个名为devices.json的文件,内容如下:
[
{
"ip": "192.168.1.10",
"vendor": "huawei",
"username": "admin",
"password": "YourPassword123",
"port": 22
},
{
"ip": "192.168.1.11",
"vendor": "h3c",
"username": "admin",
"password": "YourPassword123",
"port": 22
},
{
"ip": "192.168.1.12",
"vendor": "cisco",
"username": "admin",
"password": "YourPassword123",
"port": 22
}
]
2. 构建健壮的多厂商SSH连接器
有了设备清单,下一步就是实现与它们的对话。不同品牌的交换机在SSH交互细节上略有不同,比如登录后的初始提示符、分页处理方式等。一个健壮的连接器需要妥善处理这些细节。
我们将创建一个SSHClient类,它封装了paramiko的连接、命令执行和断开逻辑,并针对不同厂商进行微调。核心方法是执行命令并获取完整输出。
import paramiko
import time
import json
from typing import List, Dict, Optional
class NetworkDeviceSSH:
def __init__(self, ip: str, username: str, password: str, port=22, vendor='generic', timeout=10):
self.ip = ip
self.port = port
self.username = username
self.password = password
self.vendor = vendor.lower()
self.timeout = timeout
self.client = None
self.shell = None
self.prompt = '' # 用于匹配命令提示符
def connect(self) -> bool:
"""建立SSH连接并进入特权模式(如果需要)"""
try:
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client.connect(
hostname=self.ip,
port=self.port,
username=self.username,
password=self.password,
timeout=self.timeout,
look_for_keys=False
)
# 获取交互式shell通道,用于处理分页等交互
self.shell = self.client.invoke_shell()
time.sleep(1) # 等待初始欢迎信息
# 读取初始输出,清空缓冲区
self._recv_until_prompt()
# 针对不同厂商,可能需要发送特定命令进入正确模式
if self.vendor in ['cisco', 'ios', 'nxos']:
self._send_command('terminal length 0\n') # 禁用分页
self.prompt = r'[#>]\s*$'
elif self.vendor in ['huawei', 'h3c', 'hp']:
self._send_command('screen-length 0 temporary\n')
self.prompt = r'[>#]\s*$'
return True
except Exception as e:
print(f"连接设备 {self.ip} 失败: {e}")
return False
def _recv_until_prompt(self, timeout=5) -> str:
"""接收数据,直到检测到命令提示符"""
output = ''
start_time = time.time()

3000

被折叠的 条评论
为什么被折叠?



