Arista Command API
The Arista Command API is a simple and complete API that allows you to configure and monitor your Arista switches. Once the API is enabled, the switch accepts commands using the industry standard CLI syntax, and responds with machine readable output and errors serialized in JSON, served over HTTP.
The Command API is easy to use...
from jsonrpclib import Server switch = Server( "https://username:passw0rd@myswitch/command-api" ) response = switch.runCmds( 1, ["show version"] ) print "The switch's system MAC addess is", response[0]["systemMacAddress"]
... and easy to configure!
bash$ ssh username@myswitch Password: <passw0rd> myswitch> enable myswitch# configure terminal myswitch(config)# management api http-commands myswitch(config-mgmt-api-http-cmds)# no shutdown myswitch(config-mgmt-api-http-cmds)# show management api http-commands Enabled: Yes HTTPS server: running, set to use port 443 HTTP server: shutdown, set to use port 80 Local HTTP server: shutdown, no authentication, set to use port 8080 Unix Socket server: shutdown, no authentication VRFs: default ...
Configuring the Command API Agent
Although disabled by default, it is very simple to get the Command API server running on your switch. From configure
mode, enter management api http-commands
mode. In this submode, you can turn on or off the server by typing [no] shutdown
.
The configuration of the protocol itself in done in HttpServer mode. From configure
mode, enter management http-server
mode. In this submode, you can switch between accepting HTTP or HTTPS traffic via [no] protocol http[s]
, and adjust the ports the server should listen on using protocol http[s] port <portNumber>
. You can also configure the API to only accept connections from scripts running on the switch itself. To enable this feature, see On-box Usage of Command API
In any CLI mode, you can issue the show management api http-commands
command to view the status of the agent, including server information, attached users, last request time and other details.
myswitch> enable myswitch# configure terminal myswitch(config)# management api http-commands myswitch(config-mgmt-api-http-cmds)# [no] shutdown myswitch(config-mgmt-api-http-cmds)# management http-server myswitch(config-mgmt-http-server)# [no] protocol https [port <portNumber>] myswitch(config-mgmt-http-server)# [no] protocol http [port <portNumber>] myswitch(config-mgmt-http-server)# [no] protocol http localhost [port <portNumber>] myswitch(config-mgmt-http-server)# [no] protocol unix-socket
Configuring a Certificate
Because clients use HTTP basic authentication to send usernames and passwords to the switch, we recommend using HTTPS so no passwords are sent in the clear over the network. By default a self-signed certificate will be used.
myswitch> enable myswitch# copy scp:<username>@<server>//<serverCertificate> certificate:eapiServerCert myswitch# copy scp:<username>@<server>//<serverKey> sslkey:eapiServerKey myswitch# configure terminal myswitch(config)# management security myswitch(config-mgmt-security)# ssl profile eapi myswitch(config-mgmt-sec-ssl-profile-eapi)# certificate eapiServerCert key eapiServerKey myswitch(config-mgmt-sec-ssl-profile-eapi)# management http-server myswitch(config-mgmt-http-server)# protocol https ssl profile eapi
Configuring multiple VRFs
Since release 4.20, you can configure multiple VRFs in management api http-commands
mode. By entering submode vrf <vrfName>
, you can enable or disable Command API server in multiple VRFs by typing [no] shutdown
inside each VRF submode. If no VRF specified and Command API server is enabled, it will start in default VRF automatically. When you enable Command API server in the first user VRF, it will be removed from default VRF. You can run Command API server in default VRF by explicitly configuring in submode vrf default
, with command no shutdown
(this behavior is for reasons of backwards compatibility).
myswitch> enable myswitch# configure terminal myswitch(config)# management api http-commands myswitch(config-mgmt-api-http-cmds)# vrf foo myswitch(config-mgmt-api-http-cmds-vrf-foo)# no shutdown myswitch(config-mgmt-api-http-cmds-vrf-foo)# exit myswitch(config-mgmt-api-http-cmds)# vrf bar myswitch(config-mgmt-api-http-cmds-vrf-bar)# no shutdown myswitch(config-mgmt-api-http-cmds-vrf-bar)# exit myswitch(config-mgmt-api-http-cmds)# vrf default myswitch(config-mgmt-api-http-cmds-vrf-default)# no shutdown myswitch(config-mgmt-api-http-cmds-vrf-default)# exit myswitch(config-mgmt-api-http-cmds)# show management api http-commands Enabled: Yes HTTPS server: running, set to use port 443 HTTP server: shutdown, set to use port 80 Local HTTP server: shutdown, no authentication, set to use port 8080 Unix Socket server: shutdown, no authentication VRFs: bar,default,foo ...
The Spec
The Command API uses the lightweight, standardized protocol JSON-RPC 2.0 to communicate between your program (the client) and the switch (the server). Although most languages have client libraries which abstract away the JSON-RPC internals, it is useful to understand the communication mechanism between the client and the switch.
Exploring the Command API
To explore the API, point your web browser to http[s]://myswitch/
, after enabling Command API. This web-app lets you interactively explore the protocol, return values, and model documentation. Please note that if you visit the tool using HTTPS, your browser may emit a warning; this is because by default the agent uses a locally signed certificate for encryption purposes and can be ignored. You may always set a certificate and key issued by your own CA for enhanced security.
An annotated example
The client starts by sending a JSON-RPC request via an HTTP POST request
to http://<yourswitch>/command-api, which encapsulates a list of CLI
commands it wishes to run, and the switch replies with a JSON-RPC response
containing the result of each CLI command that was executed. The commands
in the request are run in order on the switch. After the switch has
executed all commands, it exits back to unprivileged mode. If any of the
commands emit an error, no further commands from that request are executed,
and the response from the switch will contain an error
object containing the details of the error that occurred.
To illustrate, here are annotated versions of the underlying Request and Response messages sent between the client and switch.
The Request
{ | |
"jsonrpc": "2.0", |
The protocol version. Always "2.0" , and usually set by a client library.
|
"method": "runCmds", |
The method to run on the switch. At this time runCmds is the only method supported.
|
"params": { | |
"version": 1, |
version is a mandatory parameter representing the API version. Currently always has the value 1 .
|
"cmds": [ |
cmds is a mandatory parameter which contains a list of CLI commands. Commands may either be a string or a complex object type. For more details, see the command specification
|
"enable", | |
"configure", | |
"interface Ethernet1", | |
"switchport access vlan 3", | |
"show vlan 3", | |
], | |
"format": "json" |
format is an optional parameter specifying response format. Can be text or json , and defaults to json .
|
}, | |
"id": 1 | A unique identifier that will be echoed back by the switch. May be a string or number. |
} |
The Response: success case
This response is returned by the switch after receiving the above request. All responses conform JSON-RPC 2.0 specifications.
{ | |
"jsonrpc": "2.0", |
The protocol version. Always "2.0" .
|
"result": [ |
The result list. Contains one object for each CLI command executed, and the position of the result corresponds to the original command list. If the request specified a text format, however, result will contain a list of strings.
|
{}, | |
{}, | |
{}, | |
{ "warnings": [ |
Most non-show commands produce no output and thus return an empty JSON object. However, in some cases, a command may produce warnings or errors which will be stored in arrays of the same name.
|
"Access VLAN does not exist. Creating vlan 3" | |
] | |
}, | |
{ "sourceDetail": "", |
show commands will return formatted JSON objects containing all information seen in the ASCII output in the normal CLI. In this case, show vlan 3 will give you a mapping from VLAN id to VLAN model.
|
"vlans": { | |
"3": { | |
"status": "active", | |
"name": "VLAN0003", | |
"interfaces": { | |
"Ethernet1": { | |
"annotation": null, | |
"privatePromoted": false | |
} | |
}, | |
"dynamic": false | |
} | |
} | |
} | |
], | |
"id": 1 | The same id (string/number) that was provided by the request. |
} |
The Response: failure case
In this case, let's assume our account does not have the appropriate AAA permissions to enter configure
mode.
{ | |
"jsonrpc": "2.0", | |
"error": { |
On an error, no result object is present, only an error object, which is guaranteed to have the following attributes: code , messages , and data .
|
"code": 1005, | Command API error code. |
"message": "CLI command 2 of 5 'configure' failed: permission to run command denied", | General high-level error message. |
"data": [ |
Similar to the result object in the successful response, the data object is a list of objects corresponding to the results of all commands up to, and including, the failed command. If there was a an error before any commands were executed (e.g. bad credentials), data will be empty.
|
{}, |
The enable command passed without incident.
|
{ "errors": [ | |
"Authorization denied for command 'configure'" |
In this case, we failed on the second command. The last object in the data array will always correspond to the failed command. The command failure details are always stored in the errors array.
|
] } | |
] | |
}, | |
"id": 1 | |
} |
Getting more detailed error information
If more detailed information regarding the particular failed commands is desired, one can specify the includeErrorDetail
param, as mentioned briefly above. In this case, the response will be the same as specified above, except that the data
member will contain two members: a result
member with the command results, and an errorDetail
member containing detailed information for each failed command, as shown in the example below.
{ | |
"jsonrpc": "2.0", | |
"error": { | |
"code": 1005, | Value is the same as in the previous example. |
"message": "CLI command 2 of 5 'configure' failed: permission to run command denied", | Value is the same as in the previous example. |
"data": { | |
"result": [ |
The result member contains the command results, same as those that populated the data member in the previous example.
|
{}, | |
{ "errors": [ | |
"Authorization denied for command 'configure'" | |
] } | |
], | |
"errorDetail": [ | |
{ "index": 1, | Index of the failed command. |
"code": 1005, | Command API error code of the failed command. |
"message": "permission to run command denied", | Error message associated with the failed command. |
"cmd": "configure" } | The text of the failed command. |
], | |
}, | |
"id": 1 | Value is the same as in the previous example. |
} |
Command Specification
In most cases, the client will use a simple string to specify the CLI command in the cmds
parameter in the request. In certain cases, however, clients may wish to specify additional parameters during the command's execution. To use complex commands, pass a JSON object in lieu of a string, with the following attributes:
cmd
(mandatory): specify the CLI command to run.input
(optional): specify a string to be provided as standard input while running thecmd
revision
(optional): in the case of 'show' commands that have been modified over the course of different EOS releases, this parameter allows clients to request an old model format. At this time, all models are at revision 1, and this attribute will be ignored.
Hello World!
, the client should set cmds
to [ "enable", "configure", { "cmd": "banner motd", "input": "Hello World!\nEOF" } ]
Similarly, if the switch requires an enable password, the following cmds
value would let you enter exec mode and clear interface counters [ { "cmd": "enable", "input": "hunter2" }, "clear counters" ]
Error Codes
The following errors are generated if there is an issue with the request. Do note that new error codes may be introduced in future releases.
JSON-RPC 2.0 Defined Errors | |
---|---|
Code | Description |
-32700 | Parse Error |
-32600 | Invalid Request |
-32601 | Method not found |
-32602 | Invalid params |
-32603 | Internal server error |
Command API Errors | |
---|---|
Code | Description |
1000 | General error |
1001 | Command caused internal exception |
1002 | Invalid command: the string does not match any command |
1003 | Command not ready: attempted to get json from a show command, however the command has not been converted to be compatible with the Command API yet. Use format = text to run this command and get ASCII output. |
1004 | Command incompatible: cannot run command over the Command API |
1005 | Command unauthorized: user has insufficient permissions to run the command |
1006 | Configuration locked: another CLI session has the configuration lock |
Using the Command API
In practice, most libraries hide the JSON-RPC version, id and protocol details. Instead you only need to call the runCmds
method with the version
and cmds
parameters and, optionally, the format
parameter. The responses generated by the client library usually follow language conventions. For example, in Python, an error response results in an Exception being thrown, while Javascript expects an error handler callback.
Unsupported commands
Certain commands are not permitted and will always return an error. The largest class of such commands are interactive commands; watch
is a prime example. Other commands, like reload
must use their non-interactive versions: such as reload now
. The bash
command is only allowed with the timeout <timeout>
argument, ie. bash timeout <timeout> <ARG>
.
Commands that attempt to use CLI pipes (e.g. show interfaces | grep Ethernet1
) are also not allowed. In addition, no abbreviations are allowed in commands. This is necessary because future versions of EOS may add more commands, rendering previous abbreviations ambiguous.
Unconverted commands
Although you can access almost any CLI command via the Command API, not all show
commands have been converted to return formatted data, and trying to run the command with the format
parameter set to json
will result in an error. However, you can still get the CLI ASCII output for the unconverted command by setting the format
parameter to text
. With this parameter set, the response will contain an array of strings (rather than an array of objects), each representing the text output of the corresponding command. When operating with format
set to text
, no errors will be generated; rather they will be included in the ASCII output, the same way they are printed in a standard CLI session. To view converted commands visit the command documentation center.
Using JSON-RPC
The JSON-RPC spec is well documented at JSON-RPC Specification, and there are libraries in almost every language that make dealing with JSON-RPC a breeze. Here are a list of some recommended client libraries:
- Python: jsonrpclib
- Perl: JSON-RPC2 Client
- Javascript: jsonrpc.js
- And many more here
On-box Usage of Command API
It is often useful to run scripts that use Command API directly on the switch itself, without configuring them with AAA credentials. EOS provides three mechanisms to accomplish this. The preferred way is to use the EapiClientLib library, however other methods are also supported.
Using EapiClientLib (requires no configuration)
from EapiClientLib import EapiClient switch = EapiClient( disableAaa=True, privLevel=15 ) response = switch.runCmds( 1, ["show version"] ) print "The switch's system MAC addess is", response["result"][0]["systemMacAddress"]
Other Methods (requires configuration)
The first is an HTTP server bound to localhost (on port 8080 by default), which only accepts connections arriving from the same machine. The other solution is a Unix domain socket. To enable one or both, use the following commands:
myswitch> enable myswitch# configure terminal myswitch(config)# management api http-commands myswitch(config-mgmt-api-http-cmds)# protocol http localhost myswitch(config-mgmt-api-http-cmds)# protocol unix-socket myswitch(config-mgmt-api-http-cmds)# no shutdown
Once Command API is enabled then you access via the local domain socket unix:/var/run/command-api.sock
switch = Server( "unix:/var/run/command-api.sock" )
If configured to use HTTP over localhost, your script can access the API as follows:
switch = Server( "http://localhost:8080/command-api" )
Using Websockets with Command API
Command API can also be used over Websockets, allowing for a stateful approach, which jsonrpc does not provide on its own. Commands executed over Websockets do not create a new session for each request. One use case is if multiple requests needs to be performed while holding the configuration lock. There is a reference implementation of the protocol in the python site-packages named EapiWebsocketLib.py. This is an example usage if it were done on-box:
import websocket from EapiWebsocketLib import EapiWebsocketClient ws = websocket.WebSocket() with EapiWebsocketClient( ws, '127.0.0.1', username, password ) as switch: response = switch.runCmds( 1, ["show version"] ) print "The switch's system MAC addess is", response["result"][0]["systemMacAddress"]
Server Certificates
Creating a self-signed certificate
The simplest way to setup the server is to use a self-signed certificate, because this does not require adding a Certificate Authority (CA) to the client. Below is the command to create a self-signed certificate and key.
openssl req -new -nodes -x509 -days <number-of-days> \ -subj '/CN=self.signed' \ -out <server-certificate-filename> \ -keyout <server-key-filename>
Creating a certificate authority/server server certificate
A more secure of setting up the https is to not have a self-signed certificate, but instead have a Certificate Authority (CA) sign the server certificate. If you do not have a CA you can create a CA Root yourself.
openssl req -new -nodes -x509 -days <number-of-days> \ -subj '/CN=CA ROOT' \ -out <ca-certificate-filename> \ -keyout <ca-key-filename>
Once you have a CA Root then you can create the private key for the server and a Certificate Signing Request (CSR).
openssl req -new -nodes \ -subj '/CN=<switch-name>' \ -out <server-signing-request-filename> \ -keyout <server-key-filename>
Given the CSR and the CA certificate and private key, we can create the server certificate as below.
openssl x509 -req -sha256 -days <valid-for-days> \ -in <server-signing-request-filename> \ -CA <ca-certificate-filename> -CAkey <ca-key-filename> \ -set_serial <serial-number> \ -out <server-certificate-filename>
Client-Side Certificates
Client authentication can be accomplished via X.509 public key certificates.
What is this good for? Imagine you have a general purpose script that does some operations on an Arista switch using eAPI. That script will need your EOS username/password. Since the various users of that script might have their own EOS usernames/passwords, putting them into the script makes little sense; having the script collect them from a well-known password file relative to $HOME makes more sense. The public key certificates is simply the standard way of dealing with such a well-known password file.
Public key certificates are digitally signed by a Certificate Authority (CA). If you trust that CA, then you must trust the certificates it signed. The trusted CA(s) has to be configured into the Arista switch. Then any client certificate signed by that trusted CA will be accepted by eAPI, but only if the CA directly signed it, that is, a client cannot create "sub-clients" (the CA plays the role of the admin that creates the account for which the certificate stands). Client certificates can also be self-signed, in which case each client certificate has to be configured into the Arista switch as trusted.
The certificate will need to contain the username in the common name field of the certificate's subject field (see openssl command syntax below for more details). If a connection with this certificate is accepted, then on the switch it will be accounted against that username. Note that this will not work with RADIUS.
If you configure trusted CA/clients, then you also need to configure the
HTTPS server's certificate/privateKey using the management security
ssl profile
commands as illustrated below (server keys are no longer auto-generated
in this case -- once you generate the client's certificate, you might as well
generate the server certificate and key). Those certificates/keys are stored in bootflash
under /persist/secure/ssl
, not in the startup-config.
myswitch> enable myswitch(config)# configure myswitch(config)# ! download the client certificates and server certificate/key myswitch(config)# copy scp:<username>@<server>//<certificate1-filename> certificate:ca1 myswitch(config)# copy scp:<username>@<server>//<certificate2-filename> certificate:user1 myswitch(config)# copy scp:<username>@<server>//<certificate3-filename> certificate:httpServer myswitch(config)# copy scp:<username>@<server>//<privateKey3-filename> sslkey:httpServer myswitch(config)# ! create an ssl profile and add those certs/keys into it myswitch(config)# management security myswitch(config-mgmt-security)# ssl profile eapi myswitch(config-mgmt-sec-ssl-profile-eapi)# trust certificate ca1 myswitch(config-mgmt-sec-ssl-profile-eapi)# trust certificate user1 myswitch(config-mgmt-sec-ssl-profile-eapi)# certificate httpServer key httpServer myswitch(config)# ! now configure eAPI to use that ssl profile myswitch(config)# management api http-commands myswitch(config-mgmt-api-http-cmds)# protocol https myswitch(config-mgmt-api-http-cmds)# protocol https ssl profile eapi myswitch# ! some show commands myswitch# show management security ssl certificate myswitch# show management security ssl profile myswitch# show management security ssl key myswitch# ! find more commands with: myswitch# show cli commands all | grep ssl
Above we first downloaded certificates and a private key (key is for the https server). Certificates (that contain the public key) go to the "certificate:" filesystem, (private) keys go to the "sslkey:" filesystem. Then we add those certificates/keys into an ssl profile called "capi", then make command-api use that profile.
A self signed certificate and associated private key (a "pair") can be generated with the openssl tool like so: (replace the <fields> with actual values)
openssl req -new -nodes -x509 -days <number-of-days> \ -subj '/CN=<username> <optional-stuff-to-your-liking>' \ -out <certificate-filename> \ -keyout <key-filename>
You can use the above for generating the certificate:httpServer and sslkey:httpServer or the certificate:user1/ca1 used in the example above. In case of the client/user, the key-file is for the client to install in his account for access by tools like wget/browsers (in the same way as a username/password would be). In case of the CA, you (the admin), would keep that key to sign client certificates with.
You can create a self signed certificate per user, and have EOS trust each one, or you can create a CA, have EOS trust just that CA, then sign the user certificates you generate with the (private) key of the CA. In that case, creating the certificate is a 2 step process: you first create a "signing-request" (similar to creating a cert/key pair, but without the "-x509 -days" options), which is then signed in the second step.
openssl req -new -nodes \ -subj '/CN=<username> ' \ -out <signing-request-filename> \ -keyout <user-key-filename> openssl x509 -req -sha256 -days <valid-for-days> \ -in <signing-request-filename> \ -CA <ca-certificate-filename> -CAkey <ca-key-filename> \ -set_serial <serial-number> \ -out <user-certificate-filename>
An eAPI request can be generated like so by using the wget utility: (the --no-check-certificate is required if the server uses a self-signed certificate)
wget --no-check-certificate \ --private-key=<key-filename> \ --certificate=<certificate-filename> \ -q -O - \ https://<server>/command-api --post-data="$(cat <file-with-json-request>)"
A simple <file-with-json-request> could have this content:
{ "jsonrpc": "2.0", "method": "runCmds", "params": { "version": 1, "cmds": [ "show clock" ], "format": "json" }, "id": "1" }
Session Based Authorization
Some systems use 2-factor authentication where RSA is implemented and keys rotate every 30 seconds. It is cumbersome to authenticate using username and password in these systems. Command API requests use basic authentication by default. This results in high overhead on the switch to verify user credentials for each command request. HTTP sessions can be used to reduce the overhead in the above use cases by caching user authentication. Usage of the session mechanism is explained below.
User Login
A user logs in by sending an HTTP POST request to http[s]://<yourswitch>/login
with an encapsulated JSON user credential.
{The switch will authenticate the user credentials in the request and if successful, send a set cookie response containing a
"username": <user>,
"password": <password>
}
Session=<sessionId>
field and an expiry of 24 hours. The sessionId is an unique session identifier. On failure, a "401 Unauthorized" HTTP response will be sent in lieu of a cookie.
Command Requests
Subsequent command requests to http[s]://<yourswitch>/command-api
need to include Session=<sessionId>
in the cookie header. The format of the command request as well as its response is same as the one using the basic authentication scheme. If the session is invalid, a "401 Unauthorized" response will be sent.
User Logout
A user may logout by sending an HTTP POST request to http[s]://<yourswitch>/logout
with Session=<sessionId>
in the cookie header. On success, a "200 OK" response will be sent, otherwise a "400 Bad Request" response will be sent.
Session Validation
Browser-based applications may find it useful to check if a valid session already exists, thereby avoiding a prompt.
To do this, send a POST request to http[s]://<yourswitch>/login
with an empty JSON body: {}
.
If the cookie included in your request exists and contains a valid sessionId,
the server will send a "200 OK" HTTP response,
otherwise it will reply with a "401 Unauthorized" response.
Versioning
eAPI models are now revisioned. This means that if a model is modified in a non-backwards compatible way, then its revision will be bumped up (revisions are numbers, default value is 1). By default an eAPI request will return revision 1 of the model instance, this ensures that older management software will not suddenly stop working when a switch is upgraded. If a specific revision is required, then that revision must be specified in the json rpc, like illustrated in this example json request below:
{ | ||
"jsonrpc": "2.0", | ||
"method": "runCmds", | ||
"params": { | ||
"version": 1, | ||
"cmds": [ | ||
"enable", | ||
{ "cmd": "show version", "revision": 2 }, | Use a complex command to specify extra attributes like the revision of a command |
|
"show clock", | ||
], | ||
"format": "json" | ||
}, | ||
"id": 1 | ||
} |
Incompatible Model Changes
The following list contains changes that will result in a new revision of a model. In the list below, the term "element" refers to an attribute or submodel.- Changing the type/format of an element (say, from integer to string)
- Removing mandatory elements
- Adding mandatory elements
- Changing the optionality of an element
- Changing help text
- Using a stronger type (from string to any, i.e. number, is compatible)
- Adding/removing optional elements
- Adding/removing an enumerated value
- Obviously: adding a new cli command
Normally, in TLV/schema-less systems (like JSON is), adding new key-value pairs is considered a compatible change, as long as the new pairs are just an "enhancement" that does not affect the meaning of the remaining pairs, since older system will be oblivious to them (they naturally skip over them). So why is adding a mandatory element non-backwards compatible? Because we are talking from the perspective of the published model. If a network management developer looks at the latest model and sees that model X is at revision 1 and attribute Y is mandatory, then he will assume Y to be always present, then get a key error when discovering a switch running an older release! The downside is that you need extra effort to get the newer attributes (specify a later revision), but unless you add code to deal with that extra data, you might as well just continue receiving only the older attributes. If your application can deal with "fuzzy models", then look for "Get Current Revision" further below.
Understanding Revisions And Versions
Do not confuse "revisions" and "versions" as they are not the same. A "revision" applies to a particular CLI command whereas a "version" is global and is internally translated to a specific "revision" for each CLI command in the rpc. At this time, the API remains at version 1, and will do so until many models have progressed to later revisions. Until the version gets a bump, in order to access newer revisions of CLI output, you have to name the revision you desire, per command, or use the "latest" version as documented in the "Accessing a Command's Current Revision" section below. Note that an explicit revision value attached to a command always takes precedence over the version.
Here is how revisions and versions play together. Assume commands C1 and C2 have shipped with those changes across EOS releases (C3 is new and has no revisions yet -- still at revision=1):
Example Commands with Versions and Revisions | |||
---|---|---|---|
Command | EOS-Release | eAPI-Version | Command-Revision |
C1 | 4.13.1 | 1 | 1 |
C1 | 4.13.2 | 2 | 2 |
C1 | 4.13.3 | 2 | 3 |
C1 | 4.13.4 | 3 | 3 |
C1 | 4.13.5 | 3 | 4 |
C2 | 4.13.1 | 1 | 1 |
C2 | 4.13.4 | 3 | 2 |
C3 | 4.13.5 | 1 | 1 |
Resulting Responses | ||
---|---|---|
Command | Version-Requested | Revision-Returned |
C1 | 1 | 1 |
C1 | 2 | 2 |
C1 | 3-* | 3 |
C2 | 1-2 | 1 |
C2 | 3-* | 2 |
C3 | 1-* | 1 |
Note that requiring a version higher than the command knows about will simply return the latest available one.
Accessing a Command's Current Revision
If your code can deal with new output naturally, then you may want to always get output according to the latest revision a switch can provide (its current revision), which is possible by providing the special version value 'latest' (in that case only, the version is a string). For example:
{ | |
"jsonrpc": "2.0", | |
"method": "runCmds", | |
"params": { | |
"version": "latest", | Use the special string value of "latest" for the version to get the current output revision of requested show commands |
"cmds": [ | |
"enable", | |
"show ip interfaces" | |
], | |
"format": "json" | |
}, | |
"id": 1 | |
} |
More Documentation On Revisions
The revisions and corresponding versions (if any) of cli show commands are added to the CommandApiGuide.pdf that is published for each EOS release.
Since there is now infrastructure in place during the software development cycle to detect changes to models and force the bumping up of revision numbers, thus ensuring that eAPI is a stable and predictable API, we eventually could also publish our per revision "Reference Models", as those are a python structures and thus more formally usable than a web-page or pdf.