Arista EOS eAPI and pyeapi Automation Guide - 夜莺博客

Arista EOS eAPI and pyeapi Automation Guide

Every Arista EOS box ships with an automation interface that most teams never turn on. eAPI is a JSON-RPC API served by the switch itself: send a list of CLI commands, get structured JSON back — and because show output arrives as data rather than text, you stop writing regular expressions to parse tables. This guide covers enabling eAPI securely, driving it with pyeapi, and using the resource APIs so that changes are idempotent rather than append-only.

Enabling eAPI on the Switch

switch# configure terminal
switch(config)# management api http-commands
switch(config-mgmt-api-http-cmds)# protocol https
switch(config-mgmt-api-http-cmds)# no shutdown
switch(config-mgmt-api-http-cmds)# end

switch# show management api http-commands
   Enabled:            Yes
   HTTPS server:       running, set to use port 443
   VRF:                default
   ...
   Hits:               0
   Bytes in:           0
   Bytes out:          0

Three hardening steps belong in the same change window. Restrict the API to the management VRF so it is not reachable from a data VLAN. Bind it to a specific address or interface where the platform supports it. And generate a proper certificate rather than accepting the self-signed default:

switch(config)# security pki key generate rsa 4096 mykey.pem
switch(config)# security pki certificate generate self-signed my_cert.pem key mykey.pem validity 3650 parameters common-name sw01

switch(config)# management security
switch(config-mgmt-security)# ssl profile MY_CUSTOM_PROFILE
switch(config-mgmt-sec-ssl-profile-MY_CUSTOM_PROFILE)# tls versions 1.2
switch(config-mgmt-sec-ssl-profile-MY_CUSTOM_PROFILE)# certificate my_cert.pem key mykey.pem

switch(config)# management api http-commands
switch(config-mgmt-api-http-cmds)# protocol https ssl profile MY_CUSTOM_PROFILE
switch(config-mgmt-api-http-cmds)# vrf MGMT
switch(config-mgmt-api-http-cmds)# no shutdown

Skipping the certificate step produces the single most common pyeapi error: SSLV3_ALERT_HANDSHAKE_FAILURE. eAPI with TLS 1.2 and a modern Python client will not negotiate against the old defaults.

Raw JSON-RPC with jsonrpclib

pip install jsonrpclib-pelix

from jsonrpclib import Server
from pprint import pprint as pp

url = "https://arista:secret@sw01.example.com/command-api"
switch = Server(url)

# enable-mode commands return a list of results, one per command
result = switch.runCmds(1, ["show version", "show hostname"])
pp(result)

# configuration commands are executed in config mode by default
switch.runCmds(1, ["interface Ethernet1", "description uplink-to-spine-01"])

# request a specific revision of a command whose JSON schema changed
switch.runCmds(1, [{"cmd": "show interfaces", "revision": 2}])

The runCmds method is the whole API surface you need for 90% of automation: a version number, a list of commands, and JSON back. Command output that EOS already understands as structured data comes back as dictionaries and lists, which is why eAPI-based audits are so much shorter than screen-scraping equivalents.

pyeapi: Python Bindings and Resource APIs

# ~/.eapi.conf  (or nodes.conf, loaded explicitly)
[connection:veos01]
host: 192.0.2.11
username: arista
password: secret
transport: https
import pyeapi

pyeapi.load_config("nodes.conf")
node = pyeapi.connect_to("veos01")

node.enable("show hostname")
# [{'command': 'show hostname', 'encoding': 'json',
#   'result': {'hostname': 'veos01', 'fqdn': 'veos01.example.com'}}]

node.config("hostname veos01")                 # single config line
node.config(["interface Ethernet1", "description uplink"])   # list form

node.running_config
node.startup_config

Idempotent changes with resource modules

vlans = node.api("vlans")
vlans.getall()
# {'1': {'state': 'active', 'name': 'default', 'vlan_id': 1}}
vlans.create(100)
vlans.set_name(100, "servers")

interfaces = node.api("ipinterfaces")
interfaces.getall()
# {'Management0': {'address': '192.168.100.210/24'}, 'Vlan10': {'address': '10.125.10.2/24'}}
interfaces.create("Vlan100")
interfaces.set_address("Vlan100", "10.125.100.1/24")

This is the difference that matters in production. Sending CLI lines is declarative in intent but imperative in execution: running vlan 100 twice is harmless, but switchport trunk allowed vlan add 100 twice is not a no-op, and building VLAN lists by appending is how trunks end up with stale VLANs. Resource APIs (and Ansible's arista.eos modules, which use eAPI under the hood) compare desired state with actual state and send only what differs.

Practical Patterns

  • Audit before you change. Write the "gather" script first — inventory, interface state, BGP summary, LLDP neighbours — and store the JSON. You will need the before-state within the hour.
  • Batch sensibly. One runCmds call with thirty commands is far faster than thirty calls, but a failed command aborts the rest of the list by default; keep configuration sessions short and verifiable.
  • Use config sessions for multi-step changes. node.config(["configure session mychange", ...]) gives you EOS's own commit/abort semantics — see EOS configuration sessions.
  • Do not store credentials in .eapi.conf on disk. Render the config file at runtime from a secret store, or pass credentials to pyeapi.connect() directly.
  • Rate-limit your pollers. eAPI commands are handled by the switch CPU; a 30-second poll of show interfaces across 200 leaf switches is measurable load.

Verification Checklist

  1. show management api http-commands shows HTTPS running, bound to the intended VRF, with hit counters incrementing.
  2. TLS certificate valid and trusted by the client; no handshake errors.
  3. A read-only script produces identical JSON before and after a change you make by hand (proves the API is reporting reality).
  4. Resource-API runs are re-runnable without producing diffs (idempotence test).
  5. Credentials pulled from a vault, and the API restricted to management networks.

Related reading: Arista EOS CLI cheat sheet, Netmiko SSH-based automation and declarative VLAN automation with Ansible.

原文链接:https://pyeapi.readthedocs.io/en/master/quickstart.html