4. Python网络自动化基础
在真正让脚本登录一台 Catalyst 交换机之前,需要先补齐 Python 的几项基础能力:用合适的数据类型承载设备信息与命令输出,用文件操作保存配置和日志,用异常处理应对 SSH 超时、认证失败等现实问题,再借助 requests 与 ncclient 两类库分别完成 RESTCONF/NETCONF 交互。本节围绕“第一次自动化交互”这一目标,把这些基础能力串成一条可执行的路径。
一、用数据类型描述网络对象
网络自动化中,最常用的数据类型是字符串、整数、布尔值、列表和字典。字符串用于设备名、IP、接口名;整数用于 VLAN ID、端口号;布尔值用于表示接口是否启用;列表适合存放多台设备或多条命令;字典则适合描述一台设备的多个属性。例如一台 Catalyst 设备的登录信息可以写成:
device = {
"host": "10.10.10.21",
"username": "netadmin",
"password": "C1sco!2024",
"port": 22,
"device_type": "cisco_ios"
}
当需要批量操作时,把多台设备的字典放进列表,就形成了设备清单:
devices = [
{"host": "10.10.10.21", "name": "C9300-Core-1"},
{"host": "10.10.10.22", "name": "C9300-Core-2"},
{"host": "10.10.10.23", "name": "C9200-Access-1"}
]
这里要特别注意:字典取值用 device["host"],列表遍历用 for d in devices。如果键名写错,Python 会抛出 KeyError,这正是后面异常处理要覆盖的场景。
二、文件操作:让配置与日志落地
自动化脚本不能只把结果打印在屏幕上,通常需要把设备回显、配置备份或执行日志写入文件。推荐使用 with open(...) 上下文管理器,确保文件在异常时也能正确关闭:
with open("backup/C9300-Core-1.cfg", "w", encoding="utf-8") as f:
f.write(running_config)
读取设备清单时,常用 JSON 文件保存结构化数据:
import json
with open("devices.json", "r", encoding="utf-8") as f:
devices = json.load(f)
文件路径建议使用相对路径配合目录创建,例如 os.makedirs("backup", exist_ok=True),避免因目录不存在导致 FileNotFoundError。写入模式 "w" 会覆盖原文件,追加日志应使用 "a"。
三、异常处理:让脚本在故障中可控
网络自动化的最大现实问题是“设备不一定按预期响应”。因此需要用 try/except/finally 包裹关键操作。典型结构如下:
from netmiko import ConnectHandler
try:
conn = ConnectHandler(**device)
output = conn.send_command("show version")
except TimeoutError:
print(f"{device['host']} 连接超时")
except Exception as e:
print(f"{device['host']} 连接失败: {e}")
finally:
if 'conn' in locals():
conn.disconnect()
这里 TimeoutError 对应 SSH 无响应,Exception 兜底捕获认证失败、协议不匹配等错误。finally 保证无论成功与否都断开连接,避免会话残留。实际排障时,建议把异常信息写入日志文件,而不是只打印到终端。
四、requests 与 ncclient:两条交互路径
Catalyst 设备支持多种管理接口。若设备启用了 RESTCONF,可用 requests 发送 HTTP 请求:
import requests
url = "https://10.10.10.21/restconf/data/ietf-interfaces:interfaces"
headers = {"Accept": "application/yang-data+json"}
resp = requests.get(url, headers=headers,
auth=("netadmin", "C1sco!2024"), verify=False)
print(resp.status_code, resp.json())
若设备启用 NETCONF,则用 ncclient 建立会话并获取配置:
from ncclient import manager
with manager.connect(host="10.10.10.21", port=830,
username="netadmin", password="C1sco!2024",
hostkey_verify=False) as m:
cfg = m.get_config(source="running")
print(cfg.xml)
requests 适合 RESTCONF 的 JSON 数据流,ncclient 适合 NETCONF 的 XML 数据流。两者都需要先确认设备已开启对应服务,并注意 verify=False 仅用于实验环境。
五、首次自动化交互的完整示例
把上述能力组合起来,一个最小可用的首次交互脚本如下。它读取设备清单、逐台连接、执行 show version、保存回显,并对异常做记录:
import json, os
from netmiko import ConnectHandler
os.makedirs("output", exist_ok=True)
with open("devices.json", "r", encoding="utf-8") as f:
devices = json.load(f)
for dev in devices:
try:
conn = ConnectHandler(
device_type="cisco_ios",
host=dev["host"],
username="netadmin",
password="C1sco!2024",
timeout=10
)
ver = conn.send_command("show version")
with open(f"output/{dev['name']}_version.txt", "w", encoding="utf-8") as out:
out.write(ver)
print(f"{dev['name']} 采集成功")
conn.disconnect()
except Exception as e:
print(f"{dev['name']} 失败: {e}")
判断脚本是否成功,可以看三个信号:终端是否逐台打印“采集成功”;output/ 目录下是否生成对应文件;文件内容是否包含 Cisco IOS Software 与版本号。若某台设备失败,异常信息会指出是超时、认证还是协议问题,便于针对性排查。
verify=False 与 ncclient 的 hostkey_verify=False 会跳过证书/主机密钥校验,仅限实验环境使用,生产环境应导入正确证书。