3. eAPI与JSON-RPC实战
eAPI(Arista eAPI)是 EOS 内置的 HTTP/HTTPS 管理接口,它把 CLI 命令封装成 JSON-RPC 请求,让 Python 等外部程序可以像在设备上敲命令一样执行 show 和配置操作,同时拿到结构化 JSON 结果。理解 eAPI 的关键,是把它看成一个“命令—请求—响应”的翻译层:客户端提交 JSON-RPC 报文,EOS 解析后执行对应命令,再把结果按 JSON 返回。本节围绕 Python requests 的实际调用展开,覆盖 show 命令、配置命令、JSON 解析和错误码处理四个环节。
一、eAPI 的请求结构与认证方式
eAPI 使用 JSON-RPC 2.0 协议,请求体固定包含 jsonrpc、method、params 和 id 四个字段。其中 method 通常为 "runCmds",params 包含 version、cmds 和 format。认证通过 HTTP Basic Auth 完成,即把用户名和密码放在请求头中。EOS 默认在 443 端口提供 HTTPS eAPI,也可启用 HTTP(不推荐生产使用)。
import requests
import json
url = "https://10.0.0.1/command-api"
auth = ("admin", "password")
headers = {"Content-Type": "application/json"}
payload = {
"jsonrpc": "2.0",
"method": "runCmds",
"params": {
"version": 1,
"cmds": ["show version"],
"format": "json"
},
"id": "req-1"
}
resp = requests.post(url, data=json.dumps(payload),
headers=headers, auth=auth, verify=False)
print(resp.status_code)
print(resp.json())
这里 verify=False 用于跳过自签名证书校验,仅建议在实验环境使用;生产环境应导入 CA 证书或指定 verify="/path/ca.pem"。请求成功后,返回体同样是 JSON-RPC 格式,包含 result 或 error 字段。
二、执行 show 命令并解析 JSON 响应
show 命令的返回结果位于 result 数组中,数组元素与 cmds 顺序一一对应。以 show version 为例,返回的 result[0] 是一个字典,包含 modelName、version、serialNumber 等字段。若命令本身不支持 JSON 输出,EOS 会返回文本,此时需要把 format 设为 "text",或改用 | json 管道。
data = resp.json()
if "result" in data:
ver = data["result"][0]
print("型号:", ver.get("modelName"))
print("版本:", ver.get("version"))
print("序列号:", ver.get("serialNumber"))
对于多命令批量执行,只需在 cmds 中追加命令,返回结果按索引对应。例如同时执行 show version 和 show hostname,则 result[0] 是版本信息,result[1] 是主机名信息。这种批量方式能显著减少 HTTP 往返次数,适合采集类任务。
三、执行配置命令
配置命令通过 enable 和 configure 两个特殊命令进入配置模式,再提交具体配置。EOS eAPI 要求配置命令必须显式包含模式切换,否则会返回权限或模式错误。典型写法如下:
payload = {
"jsonrpc": "2.0",
"method": "runCmds",
"params": {
"version": 1,
"cmds": [
"enable",
"configure",
"interface Ethernet1",
"description uplink-to-core",
"exit"
],
"format": "json"
},
"id": "cfg-1"
}
配置命令的返回结果通常为空数组或仅包含模式切换的确认信息,因此判断配置是否成功,主要看 HTTP 状态码和 error 字段是否存在。若配置命令语法错误,EOS 会在 error 中返回 code 和 message,例如 code: 1002 表示命令无效。实际工程中,建议把配置命令拆成“进入模式—配置—退出”的完整序列,避免模式残留导致后续命令失败。
四、错误码与异常处理
eAPI 的错误分为两层:HTTP 层和 JSON-RPC 层。HTTP 层常见状态码包括 200(成功)、401(认证失败)、403(权限不足)、404(URL 错误)、500(服务端异常)。JSON-RPC 层的错误则体现在返回体的 error 对象中,包含 code、message 和 data。常见错误码如 1000(命令执行失败)、1002(无效命令)、1003(配置模式错误)。
def call_eapi(cmds):
payload = {
"jsonrpc": "2.0",
"method": "runCmds",
"params": {"version": 1, "cmds": cmds, "format": "json"},
"id": "auto-1"
}
try:
r = requests.post(url, json=payload, auth=auth,
headers=headers, verify=False, timeout=10)
except requests.exceptions.Timeout:
return {"ok": False, "reason": "请求超时"}
except requests.exceptions.ConnectionError:
return {"ok": False, "reason": "连接失败"}
if r.status_code == 401:
return {"ok": False, "reason": "认证失败"}
if r.status_code != 200:
return {"ok": False, "reason": f"HTTP {r.status_code}"}
body = r.json()
if "error" in body:
err = body["error"]
return {"ok": False, "code": err.get("code"),
"reason": err.get("message")}
return {"ok": True, "result": body["result"]}
这段封装把网络异常、HTTP 异常和 JSON-RPC 异常统一成 ok 字段,调用方只需判断 ok 即可决定后续流程。对于配置类操作,建议在失败时记录 code 和 message,便于定位是权限问题、语法问题还是模式问题。
五、实战中的几个关键细节
第一,format 字段决定返回结构。设为 "json" 时,EOS 会尽量把命令输出转成 JSON;若命令不支持,则返回文本字符串。此时若仍按字典解析会报错,因此建议先判断 isinstance(result, dict) 再取值。第二,version 字段目前固定为 1,未来若 EOS 升级协议版本,需同步调整。第三,配置命令执行后建议追加一条 show running-config 或 show interface 进行回读验证,确认配置已生效。第四,批量命令中若某条失败,EOS 默认会中断后续命令并返回错误,因此对可靠性要求高的场景,可把命令拆成多个请求分别处理。
verify=False,也不要把密码硬编码在脚本中。推荐使用环境变量或密钥管理服务读取凭据,并为 eAPI 配置 HTTPS 证书。掌握以上内容后,你已经可以用 Python requests 完成 eAPI 的 show 查询、配置下发和错误处理。下一步的关键是把这些调用组织成可复用的函数,并结合实际网络对象进行批量操作,为后续的自动化验证打下基础。