Friday, 1 July 2016

Python for Network Engineers - Part 4 - Using Arista EOS eAPI

In previous blog articles we looked at using python to interact with REST APIs using the requests module and looked at Cisco Nexus NX-API.  In this blog post we’ll take a look at Arista EOS.

Blog Series

Python for Network Engineers - Part 1 - Introduction
Python for Network Engineers - Part 2 - Making REST calls
Python for Network Engineers - Part 3 - Using Cisco Nexus NX-API
Python for Network Engineers - Part 4 - Using Arista EOS eAPI
Python for Network Engineers - Part 5 - Using Junos NETCONF interface
Python for Network Engineers - Part 6 - Using Cisco Nexus NETCONF interface
Python for Network Engineers - Part 7 - Using Palo Alto Networks XML API


Arista EOS


For this blog I’m using a Arista vEOS 4.15.2.1F and Ubuntu 16.04 Linux with Python.  Please see references section below for more details of vEOS.  Also please see the second blog article (part2) for details of how to install the requests module.

Arista Setup
On the Arista switch then all we have to do is the following from the configuration prompt
management api http-commands
 no shut
username eosapi privilege 15 role network-admin secret eosapi
Now we can open a web browser to the switch and get a feel for the API.  For example my vEOS VM is using IP 192.168.229.61:

Python Bit
Next let’s open an interactive Python session and create a REST connection to the Arista switch.  In the first instance we’ll just run a show command.  The “s” object is the session to the Arista switch and the “r” object is the response data.
import requests, json
uname = upass = 'eosapi'
uri = 'https://192.168.229.61/command-api'
s = requests.session()
s.auth = (uname,upass)
s.verify = False
s.headers.update({'Content-Type' : 'application/json'})
data = {'jsonrpc': '2.0','method': 'runCmds','params': {'format': 'json','timestamps': False,'cmds': [''], 'version': 1}, 'id': 'PythonScript-1'}
data['params']['cmds'] = ['show hostname']
r = s.request('post', uri, data=json.dumps(data))
We can now do some checks against the session and response data, please see the previous blog posts for details.  However assuming that is all correct, we’ll just dive right into looking at the response data payload:
print json.dumps(r.json(), indent=2)
{
  "jsonrpc": "2.0",
  "result": [
    {
      "hostname": "vEOS1",
      "fqdn": "vEOS1"
    }
  ],
  "id": "PythonScript-1"
}

Example 1
For the next example I’ll just make a small change to the previous JSON payload to run two different show commands and run the REST call again.  With the Arista API then we just pass a list object with our commands so it is very easy to add or pop items as needed:
data['params']['cmds'] = ['show hostname','show interfaces status']
r = s.request('post', uri, data=json.dumps(data))
print json.dumps(r.json(), indent=2)
{
  "jsonrpc": "2.0",
  "result": [
    {
      "hostname": "vEOS1",
      "fqdn": "vEOS1"
    },
    {
      "interfaceStatuses": {
        "Management1": {
          "description": "",
          "duplex": "duplexFull",
          "vlanInformation": {
            "interfaceMode": "routed",
            "interfaceForwardingModel": "routed"
          },
          "bandwidth": 1000000000,
          "interfaceType": "10/100/1000",
          "autoNegotiateActive": true,
          "autoNegotigateActive": true,
          "linkStatus": "connected",
          "lineProtocolStatus": "up"
        }
      }
    }
  ],
  "id": "PythonScript-1"
}

Example 2
For the next example we’ll add a new loopback interface to demonstrate using configuration commands:
data['params']['cmds'] = ['enable','configure','interface loopback99','ip address 10.0.0.1 255.255.255.0']
r = s.request('post', uri, data=json.dumps(data))
print json.dumps(r.json(), indent=2)
{
  "jsonrpc": "2.0",
  "result": [
    {},
    {},
    {},
    {}
  ],
  "id": "PythonScript-1"
}
We don’t get much information back in the response data, however no errors !!  Now if we run a show command we can see the new interface has been created:
data['params']['cmds'] = ['show ip interface']
r = s.request('post', uri, data=json.dumps(data))
print json.dumps(r.json(), indent=2)
{
  "jsonrpc": "2.0",
  "result": [
    {
      "interfaces": {
        "Management1": {
          "proxyArp": false,
          "name": "Management1",
          "urpf": "disable",
          "interfaceStatus": "connected",
          "enabled": true,
          "mtu": 1500,
          "vrf": "default",
          "localProxyArp": false,
          "interfaceAddress": {
            "secondaryIpsOrderedList": [],
            "primaryIp": {
              "maskLen": 24,
              "address": "192.168.229.61"
            },
            "broadcastAddress": "255.255.255.255",
            "secondaryIps": {},
            "virtualIp": {
              "maskLen": 0,
              "address": "0.0.0.0"
            }
          },
          "lineProtocolStatus": "up",
          "description": ""
        },
        "Loopback99": {
          "proxyArp": false,
          "name": "Loopback99",
          "urpf": "disable",
          "interfaceStatus": "connected",
          "enabled": true,
          "mtu": 65535,
          "vrf": "default",
          "localProxyArp": false,
          "interfaceAddress": {
            "secondaryIpsOrderedList": [],
            "primaryIp": {
              "maskLen": 24,
              "address": "10.0.0.1"
            },
            "broadcastAddress": "255.255.255.255",
            "secondaryIps": {},
            "virtualIp": {
              "maskLen": 0,
              "address": "0.0.0.0"
            }
          },
          "lineProtocolStatus": "up",
          "description": ""
        }
      }
    }
  ],
  "id": "PythonScript-1"
}

Recap
To conclude the basic JSON data structure for Arista is:
data = {'jsonrpc': '2.0','method': 'runCmds','params': {'format': 'json','timestamps': False,'cmds': [''], 'version': 1}, 'id': 'PythonScript-1'}
Then to run a show or a configuration command, add either of the following keys:
data['params']['cmds'] = ['show version']
data['params']['cmds'] = ['show hostname','show interfaces status']
data['params']['cmds'] = ['enable','configure','interface loopback99','ip address 10.0.0.1 255.255.255.0']
Like NX-API then the Arista REST API is very easy to use as long as you know what commands you want to run on the cli.
One thing to note is that you must pass the exact command.  For example ‘show interface status’ will not work in the API, even though it works on the CLI (as the CLI auto completes the interface keyword, adding the s on the end).  However ‘show interfaces status’ will work OK.

Resources




No comments:

Post a Comment