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,便于定位是权限问题、语法问题还是模式问题。

eAPI JSON-RPC 调用与错误处理链路 Python requests 构造 JSON-RPC 报文 Basic Auth 认证 请求体字段 jsonrpc / method / params cmds / format / id EOS eAPI 解析并执行命令 返回 JSON 结果 HTTP 状态码 200 / 401 / 403 / 500 JSON-RPC error code / message / data result 数组 按 cmds 顺序对应 统一异常处理判断顺序 网络异常捕获 HTTP 状态码判断 error 字段检查 提取 result 失败时记录 code 与 message,区分认证、权限、语法、模式四类问题 成功时按 cmds 索引读取 result,配置类命令通常返回空数组

五、实战中的几个关键细节

第一,format 字段决定返回结构。设为 "json" 时,EOS 会尽量把命令输出转成 JSON;若命令不支持,则返回文本字符串。此时若仍按字典解析会报错,因此建议先判断 isinstance(result, dict) 再取值。第二,version 字段目前固定为 1,未来若 EOS 升级协议版本,需同步调整。第三,配置命令执行后建议追加一条 show running-config 或 show interface 进行回读验证,确认配置已生效。第四,批量命令中若某条失败,EOS 默认会中断后续命令并返回错误,因此对可靠性要求高的场景,可把命令拆成多个请求分别处理。

建议把 eAPI 调用封装成独立函数,统一处理认证、超时、重试和错误码映射。这样在后续章节编写自动化脚本时,可以直接复用,避免重复代码。
生产环境不要使用 verify=False,也不要把密码硬编码在脚本中。推荐使用环境变量或密钥管理服务读取凭据,并为 eAPI 配置 HTTPS 证书。

掌握以上内容后,你已经可以用 Python requests 完成 eAPI 的 show 查询、配置下发和错误处理。下一步的关键是把这些调用组织成可复用的函数,并结合实际网络对象进行批量操作,为后续的自动化验证打下基础。