From 0fedc7a583397da3e1183bc8e5e4ba25d381e8bc Mon Sep 17 00:00:00 2001 From: Damien Arnodo Date: Wed, 1 Apr 2026 09:51:05 +0000 Subject: [PATCH] docs: add README --- README.md | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a5ebcf..f67c1ac 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,138 @@ # gnmi-eos -gNMI CLI tool and Python library for Arista EOS devices — get, set, subscribe, discover YANG paths \ No newline at end of file +gNMI CLI tool and Python library for Arista EOS devices. + +Interact with Arista EOS devices via gNMI/YANG: get configuration and state, push changes, subscribe to counters and events. + +## Features + +- **CLI** — usable via `uvx gnmi-eos` or installed globally +- **Library** — importable as `from gnmi_eos import GNMIClient` +- **Validated YANG paths** for EOS 4.35.0F (OpenConfig + Arista experimental models) + +## Installation + +```bash +# As a CLI tool with uvx (no install needed) +uvx --from git+https://gitea.arnodo.fr/Damien/gnmi-eos gnmi-eos --help + +# Or install permanently +uv tool install git+https://gitea.arnodo.fr/Damien/gnmi-eos +``` + +## CLI Usage + +Credentials can be passed as options or via environment variables: + +```bash +export GNMI_TARGET=leaf1:6030 +export GNMI_USERNAME=admin +export GNMI_PASSWORD=admin +``` + +### Get capabilities + +```bash +gnmi-eos capabilities --target leaf1:6030 +``` + +### Get data + +```bash +# Get interface state +gnmi-eos get --target leaf1:6030 --path "/interfaces/interface[name=Ethernet1]/state" + +# Get config only +gnmi-eos get --target leaf1:6030 --path "/interfaces" --type config + +# Output as raw JSON or save to file +gnmi-eos get --target leaf1:6030 --path "/" --output json +gnmi-eos get --target leaf1:6030 --path "/" --output file:dump.json +``` + +### Subscribe + +```bash +# Subscribe to interface state changes (on-change) +gnmi-eos subscribe --target leaf1:6030 \ + --path "/interfaces/interface/state/oper-status" \ + --mode on-change + +# Sample interface counters every 10s +gnmi-eos subscribe --target leaf1:6030 \ + --path "/interfaces/interface[name=Ethernet1]/state/counters" \ + --mode sample --interval 10 + +# Multiple paths, stop after 5 updates +gnmi-eos subscribe --target leaf1:6030 \ + --path "/interfaces/interface/state/oper-status" \ + --path "/network-instances/network-instance[name=default]/protocols/protocol[identifier=BGP][name=BGP]/bgp/neighbors/neighbor/state/session-state" \ + --count 5 +``` + +### Set configuration + +```bash +# Dry-run (default — safe) +gnmi-eos set --target leaf1:6030 \ + --path "/interfaces/interface[name=Ethernet1]/config/description" \ + --value "Uplink to Spine" + +# Actually apply +gnmi-eos set --target leaf1:6030 \ + --path "/interfaces/interface[name=Ethernet1]/config/description" \ + --value "Uplink to Spine" \ + --no-dry-run +``` + +### Show known YANG paths + +```bash +gnmi-eos paths +``` + +## Library Usage + +```python +from gnmi_eos import GNMIClient +from gnmi_eos.yang.paths import Interfaces, BGP, FabricSubscriptions + +with GNMIClient(host="leaf1", port=6030, username="admin", password="admin") as client: + # Get capabilities + caps = client.capabilities() + + # Get interface counters + counters = client.get(Interfaces.counters("Ethernet1")) + + # Get BGP neighbor state + state = client.get(BGP.neighbor_state("10.0.0.1")) + + # Subscribe to interface changes + for update in client.subscribe( + paths=[str(FabricSubscriptions.INTERFACE_STATE)], + stream_mode="on-change", + ): + print(update) +``` + +## YANG Models + +Validated against **Arista EOS 4.35.0F** with ContainerLab (cEOS). + +| Category | Model | +|----------|-------| +| Interfaces, VLANs, BGP | `openconfig-*` | +| VXLAN | `arista-exp-eos-vxlan` | +| MLAG | `arista-exp-eos-mlag` | +| EVPN | `arista-exp-eos-evpn` | + +> **Note:** MLAG and EVPN state (peer status, learned routes) is not exposed via gNMI — use eAPI for operational state. + +## Subscription Notes + +For Arista EOS, use native paths **without** module prefixes for `ON_CHANGE` subscriptions: + +``` +✅ /interfaces/interface[name=Ethernet1]/state +❌ /openconfig-interfaces:interfaces/... +```