4. Nexus网络自动化中的Python基础

在Nexus网络自动化体系中,Python承担的是“把网络意图翻译成设备可执行动作”的角色。无论是批量下发VLAN、采集接口状态,还是解析show命令输出,最终都落在Python的数据类型、控制流、函数、文件操作、异常处理,以及调用NX-OS CLI的subprocess与paramiko这两条路径上。本节围绕这些基础能力,结合Nexus真实对象展开讲解。

一、数据类型:网络配置的“容器”

网络自动化中最常用的Python数据类型有四类:字符串、列表、字典、元组。字符串用于承载接口名、IP地址、命令文本;列表用于保存一组VLAN ID或一组接口;字典用于表达“键—值”映射,例如{"Eth1/1": "up", "Eth1/2": "down"};元组用于表达不可变的固定组合,如("10.0.0.1", "255.255.255.0")。

以Nexus接口清单为例,常见写法如下:

interfaces = ["Ethernet1/1", "Ethernet1/2", "Ethernet1/3"]
vlans = {"10": "MGMT", "20": "APP", "30": "DB"}
ip_info = ("192.168.10.1", "255.255.255.0")

字典在自动化中尤其重要,因为NX-OS的JSON输出天然是嵌套字典。例如show interface经| json转换后,接口名是键,状态、MTU、MAC地址是值。理解字典的keys()、values()、items()遍历方式,是后续解析设备输出的前提。

二、条件与循环:批量操作的骨架

条件判断用于根据设备状态做分支。例如判断接口是否up,只有up才继续配置:

for intf, state in vlans.items():
    if state == "up":
        print(f"{intf} 可用,准备下发配置")
    else:
        print(f"{intf} 不可用,跳过")

循环则用于遍历设备列表、VLAN列表或命令列表。在Nexus自动化中,典型场景是“多设备 × 多命令”的双层循环:外层遍历设备IP,内层遍历待执行命令。需要注意,循环中应避免对同一设备重复建立连接,通常把连接建立放在外层,命令执行放在内层。

三、函数:把重复动作封装成可复用单元

当同一段“连接设备—执行命令—返回结果”的逻辑被多次使用时,应封装为函数。函数参数建议包含设备IP、用户名、密码、命令列表,返回值统一为字符串或字典,便于上层判断。

def run_cmd(host, user, pwd, cmd):
    # 伪代码:建立连接并执行命令
    output = execute(host, user, pwd, cmd)
    return output

函数的价值在于:把“怎么连”和“连什么”分离。后续更换连接方式(subprocess换paramiko)时,只需修改函数内部,调用方不变。

四、文件操作与异常处理:让脚本可重复运行

自动化脚本通常需要读取设备清单、写入执行日志。读取清单可用open("devices.txt", "r")逐行读取,写入结果可用open("result.log", "a")追加。异常处理用try/except/finally包裹连接与命令执行,捕获超时、认证失败、命令不存在等异常,并在finally中关闭连接或记录日志。

建议把设备清单、命令模板、日志路径都放在外部文件中,脚本只负责逻辑,这样同一脚本可复用于不同项目。

五、调用NX-OS CLI:subprocess与paramiko

调用NX-OS CLI有两条常见路径。第一条是subprocess,适合在已具备SSH免密或本地执行环境的场景下,直接调用系统ssh命令:

import subprocess
result = subprocess.run(
    ["ssh", "admin@10.0.0.1", "show version"],
    capture_output=True, text=True, timeout=30
)
print(result.stdout)

第二条是paramiko,它是纯Python的SSH库,适合在脚本内部控制交互式会话、处理enable密码、读取回显。典型流程是:创建SSHClient、设置AutoAddPolicy、connect、invoke_shell、send命令、recv回显。

import paramiko
cli = paramiko.SSHClient()
cli.set_missing_host_key_policy(paramiko.AutoAddPolicy())
cli.connect("10.0.0.1", username="admin", password="***", timeout=10)
shell = cli.invoke_shell()
shell.send("show interface brief\n")
import time; time.sleep(2)
print(shell.recv(65535).decode())
cli.close()

两者对比:subprocess简单、依赖系统ssh,适合一次性命令;paramiko可控性强、可处理交互,适合复杂会话。选择依据是“是否需要交互”和“是否允许依赖外部ssh客户端”。

Nexus Python自动化:从脚本到NX-OS CLI的两条调用路径 Python脚本层 数据类型:list / dict / str 条件与循环:if / for 函数:run_cmd() 封装 文件操作:读清单 / 写日志 异常处理:try / except 统一调用入口 run_cmd(host, cmd) 路径A:subprocess 调用系统 ssh 客户端 subprocess.run([...]) 适合:一次性命令 依赖:系统 ssh 可用 路径B:paramiko 纯 Python SSH 库 invoke_shell() 交互会话 适合:enable / 多步交互 依赖:pip install paramiko 可控性强 NX-OS 设备 Nexus 9000 / 3000 show version show interface brief configure terminal vlan 10 / name MGMT copy running-config startup-config 结果处理:解析回显 → 写入日志 → 判断成功/失败 → 异常重试或告警

六、实践要点与判断依据

在真实Nexus环境中,脚本执行后应观察三类结果:一是命令回显是否包含预期关键字,例如show vlan输出中是否出现目标VLAN;二是设备配置是否生效,可用show running-config | include vlan核对;三是日志中是否记录异常。若paramiko回显为空,常见原因是命令未加换行符或等待时间不足;若subprocess返回非零码,应检查ssh认证与目标地址可达性。

paramiko的recv()是阻塞式读取,实际脚本中应结合time.sleep()或循环读取直到出现提示符,避免只读到部分回显就误判命令失败。

把上述能力组合起来,一个最小可用的Nexus自动化脚本应包含:读取设备清单、遍历设备、建立连接、执行命令、捕获异常、写入日志。数据类型决定“怎么存”,条件循环决定“怎么走”,函数决定“怎么复用”,文件与异常决定“怎么稳定运行”,subprocess与paramiko决定“怎么连上NX-OS”。这五部分共同构成后续更复杂自动化框架的基础。