You are on page 1of 16

CVP APIs: A Non-Programmer’s Guide

eos.arista.com/cvp-apis-a-non-programmers-guide

Olufemi Komolafe August 31, 2017

Contents [hide]

1. What are CVP APIs?


2. Why are CVP APIs useful?
3. How are CVP APIs used?
4. Which approach of using the CVP APIs is best?
5. What information is actually exchanged when using CVP APIs?
6. What CVP API documentation exists?
6.1 What documentation gives an overview of all the APIs?
6.2 What documentation exists for using the Python CVP REST API client?
6.3 What documentation exists about the underlying CVP implementation?
7. What do some illustrative examples look like?
7.1 What is the Python with requests library implementation?
7.2 What is the Python with CVPRAC implementation?
8. What are some recommended first steps in actually getting started using the APIs?

1. What are CVP APIs?


Most CloudVision Portal (CVP) users are familiar with the web user interface (UI) that
facilitates network provisioning, inventory management, tasks management, change control
and so on. CVP application programming interfaces (APIs) offer an alternative means of
realizing the same functionality. The key difference is that, with the CVP APIs, the
functionality is realized over a programmatic interface (i.e typically by a piece of software
communicating with another piece of software) rather than by a user navigating over a web
page and clicking and/or typing. Figure 1 shows a simplified example of these two methods
of using CVP.

So, for example, to get information about the current devices that CVP knows about, a user
can access the CVP website and click on the “Inventory” tab. Doing so, will result in the
user’s web browser sending a HTTPS request to the web server running on the CVP node.
The web server will communicate with the CVP infrastructure (CVPI) to retrieve the
inventory information and return this to the web browser over HTTPS, where the information
will be displayed to the user.

On the other hand, this same functionality can be realized by writing some software, typically
running on a remote server, that will connect to the CVP node and invoke the appropriate
CVP API to retrieve the inventory. The CVP APIs handlers will retrieve the inventory

1/16
information and return this data to the program that invoked the API. An obvious questions
that arises from this description is “What information actually flows between the program and
the CVP node?” This question is best answered by considering the nature of the CVP APIs.

Figure 1: Simplified view of interacting with CVP via the web UI or APIs

The CVP APIs are REpresentational State Transfer (REST) APIs. REST APIs are used to
build lightweight and maintainable web services to facilitate interoperability between clients
and servers in the Internet. (In this example, the client is the program that invokes the CVP
API and the server is the CVP node.) In general, the server has some resources that it

2/16
wishes the client to access or manipulate via REST APIs. These resources are mapped to
an underlying data model and each resource has an associated URL. Therefore, the client
can use conventional HTTP methods such as GET, POST, DELETE etc along with this URL,
to invoke particular APIs to access or manipulate the resource.

The data sent in the response from the server may be encoded in HTML, XML or JSON.
The CVP APIs use JSON for the data encoding. JSON (JavaScript Object Notation) is a
lightweight data format designed to be easily understood by humans and also easily
generated and interpreted by software. The two key structures in JSON are a collection of
name/value pairs and an ordered list of values. These two structures are easily realized in
most programming languages, making it easy to write software that handles JSON data.

Thus, the program in Figure 1 that wishes to invoke the CVP API to retrieve the inventory
must issue a HTTPS request to the specific URL for retrieving the inventory and then parse
the inventory information, which will be encoded in JSON, from the CVP node.

2. Why are CVP APIs useful?


The main use of CVP APIs is the ability to drive CVP from software, allowing CVP to be
easily integrated with other applications. For example, Figure 1 shows a program on a
remote server interacting with CVP over the CVP APIs. This program could actually be part
of a user’s application that mostly executes user-specific tasks, with the occasional
invocation of the CVP APIs as/when needed. Thus, the interaction with CVP is integrated
into the user’s software, rather than requiring ad hoc CVP-specific interactions. For
example, CVP has been integrated with ServiceNow, Ansible and even Amazon’s Echo
using this approach.

3. How are CVP APIs used?


A potential source of confusion when becoming familiar with the CVP APIs lies in the fact
that there are a number of different options for using the APIs. A reason for this variety of
approaches is that invoking the APIs requires pretty mundane operations: essentially, send a
HTTPS request to a URL that maps to a specific API, pass in the necessary parameters or
data, and process the JSON data in the HTTPS response. There are numerous ways to
carry out such commonplace operations. Popular approaches to using the CVP APIs
include to:

1. Write a Python script which uses the inbuilt Requests or URL library

2. Write a Python script which uses the Python CVP Restful API Client (CVPRAC)
developed by the EOS+ Consulting Team.

3. Use the CVP API web page (via the link highlighted in Figure 2 or directly at https://<IP
address of CVP server>/web/api/)

3/16
4. Use curl directly from a Linux CLI

5. Copy the URL into a browser address bar

Figure 3 highlights the key differences between (1) and (2), specifically that CVPRAC is
essentially a wrapper around the CVP REST APIs, allowing implementation to simply invoke
CVPRAC APIs (i.e. conventional Python methods) without having to become concerned with
the fine details of using REST APIs, constructing/interpreting JSON data etc. This
complexity is handled by CVPRAC.

Figure 2: Link to access CVP API documentation

Note that, although Python is the language cited in (1) and (2), in practice most programming
languages may be used. In fact, the EOS+ Consulting Team has also implemented
CVPRAC in Go and Ruby.

4/16
Figure 3: Some alternative means of invoking CVP APIs

4. Which approach of using the CVP APIs is best?


Unsurprisingly, the answer to the question of “Which approach of using the CVP APIs is
best?” is “It depends”. The following table summarizes some of the strengths and
weaknesses of the listed approaches:

Approach Strengths Weaknesses

Python with Minimal dependencies on other packages Need to understand and


inbuilt implement REST API
Requests or calls
URL library
Need to understand and
handle JSON data
returned from API

5/16
Python with Uses common CVPRAC code to handle Dependency on CVPRAC
CVPRAC REST API calls, manipulate JSON data etc package
so simpler and quicker to implement.

Less bugs due to using common and mature


CVPRAC code

CVP API web Good documentation and overview of APIs Output displayed on web
page page so can be hard to
No programming expertise needed to use use in a program
APIs

Curl from Quick and simple to use so well-suited for Output typically written to
terminal debugging or testing, terminal so can be hard to
use in a program
Output formatted conveniently

Browser Quick and simple to use so well-suited for Output typically displayed
debugging or testing in browser so can be hard
to use in a program

Output typically not


formatted conveniently

5. What information is actually exchanged when using CVP APIs?


As previously mentioned, CVP APIs are REST APIs which use HTTPS for communication.
Therefore, the APIs are invoked by the client sending conventional HTTP request messages
to the CVP node (i.e. the server). The request messages from the client indicate the HTTP
method. GET and POST are the two most common methods used in the CVP APIs. Figure
4 illustrates a simplified view of the different HTTP messages exchanged when the CVP API
client invokes an API using GET or POST. The CVP node processes the request message
and replies with HTTP response messages.

GET, unsurprisingly, is used to retrieve information from the CVP node. Often there are
parameters that accompany this request. These are typically appended to the URL. So, for
example, the API to retrieve information about a specific task by its ID is invoked by issuing a
GET to https://<IP address of CVP node>/cvpservice/task/getTaskById.do?taskId=<task
number>. Hence, this API requires the caller to specify the required task ID when invoking
the API. As shown in Figure 4, the HTTP request message will consist of a header which
indicates the HTTP method (GET in this case), the URL (including the parameters) and
some other fields. The message body is typically empty for GET requests. And the CVP
node responds with a HTTP response message, either containing the required data or
indicating a failure.

6/16
POST is used to submit data to be processed to the CVP node. This data is usually
encoded in JSON and delivered as part of the HTTP request message body. Therefore,
before issuing a POST request, there is an additional stage of formatting (or marshalling) the
data into JSON, which is easily done using inbuilt libraries in most programming languages.
So, for example, the API to login to CVP is invoked by issuing a POST request to https://<IP
address of CVP node>/cvpservice/login/authenticate.do. The body of the request message
must contain the following JSON data:

“userId”: “string”,

“password”: “string”

The message is sent to the CVP node where it processes the contained information and
sends an appropriate response.

Figure 4: Contents of messages exchanged between client and CVP node

6. What CVP API documentation exists?


When writing software to run on the CVP API client to invoke the APIs some key questions to
be answered, implicit from Figure 4, are:

7/16
1. Which API should be used?

2. What data must be supplied when invoking the APIs?

1. What are the input parameters and their types?

2. What is the structure of the JSON data that must be supplied?

3. What data is returned in response to invoking the APIs?

1. What are the different possible outcomes?

2. What is the structure of the JSON data returned for success or failure and what
do the different fields mean?

These questions all highlight the importance of having good quality documentation. In fact, it
is not unreasonable to claim that the popularity and usefulness of any suite of APIs is closely
correlated to the quality of the accompanying documentation.

Unfortunately, there is not a single definitive and comprehensive document about the CVP
APIs and so pertinent information must be gleaned from a number of sources, as described
in the following sections.

6.1 What documentation gives an overview of all the APIs?


From the CVP homepage, the API documentation may be conveniently accessed by clicking
on the “?” in the top right corner and then “Supported APIs”, as shown in Figure 2. The URL
for the linked page is https://<IP address of CVP server>/web/api/. The APIs are grouped by
category and so this page is often a good starting point when trying to answer question (1),
i.e. to decide which API should be used to meet a specific objective.

This web page enumerates all the different APIs and for each:

briefly states its purpose

8/16
indicates if the associated HTTP method is GET or POST

for APIs using GET, indicates

the input parameters & their types

the structure of the JSON data that will be returned for success

the different error codes that may be returned

for APIs using POST, indicates

the structure of the input JSON data

the structure of the JSON data that will be returned for success

the different error codes that may be returned

It is worth noting that, as alluded to in Figure 4, there are essentially two levels at which
errors can exist when a CVP API is invoked: the HTTP protocol level or the CVP application
level. The error codes listed on this web page mostly related to CVP-specific errors and so
are especially helpful in debugging CVP issues.

This web page also gives the option of supplying the required data and invoking a specific
API, allowing the results to be examined, as mentioned in Section 3. Also, the URL that may
be copied into the browser’s address bar to invoke the API and the Curl CLI statement to
invoke the API are also given.

Consequently, this web page is a good starting point for becoming familiar with the APIs and
the information available here (specifically about the input and output data when invoking the
APIs) gives many of the answers to questions (2) and (3) above.

6.2 What documentation exists for using the Python CVP REST API
client?
As illustrated in Figure 3, CVPRAC avoids the implementer having to become overly
concerned with the fine details of using REST APIs. Therefore, while providing some useful
background, the documentation described in Section 6.1 does not specify exactly how to use
CVPRAC. The best source of documentation about CVPRAC is actually to look at the code
within the Github repository:
https://github.com/aristanetworks/cvprac/blob/develop/cvprac/cvp_api.py. The CVPRAC
APIs are implemented in this file and there are comments to identify the input parameters
and responses. CVPRAC converts the JSON received from the CVP node to Python
dictionaries (i.e. key-value pairs) and so the software using CVPRAC must know how to
interpret these dictionaries.

9/16
Another source of documentation is the API documentation (named something like
CloudVisionPortal-Python-API-<release>.pdf) available under the Cloudvision Portal link at
https://www.arista.com/en/support/software-download. The document lists all the CVPRAC
APIs, the input parameters and responses.

6.3 What documentation exists about the underlying CVP


implementation?
Again, the best/only source of documentation is to look at the actual implementation. From a
terminal, if the CVP node is accessed by SSH, the code that actually implements the APIs
can be viewed at /cvpi/tools/cvpServices.py and /cvpi/tools/cvp.py. These files list all the
different CVP APIs and indicate the different responses, describing the structure of the data
(although not the meaning of the different fields).

Additionally, /cvpi/apps/cvp-frontend/web/api/api_json contains the information used to


generate https://<IP address of CVP server>/web/api/ and /cvpi/apps/cvp-
frontend/web/api/api_doc/api_doc.pdf contains some more information about the APIs, with
some examples of the JSON data that must be supplied when invoking the APIs and the
expected responses.

7. What do some illustrative examples look like?


In order to see what examples of how the different approaches actually use the CVP APIs,
consider a simple hypothetical problem in which it is required that an application uses the
CVP APIs to

Login to CVP

Retrieve a list of all the tasks

Find the task with the highest numerical ID in this list and attach a note to this task
saying “This task currently has the highest numerical ID”

As mentioned in Section 6, the key questions to be answered when seeking to solve a


problem using the CVP APIs are:

1. Which API should be used?

2. What data must be supplied when invoking the APIs?

1. What are the input parameters and their types?

2. What is the structure of the JSON data that must be supplied?

10/16
3. What data is returned in response to invoking the APIs?

1. What are the different possible outcomes?

2. What is the structure of the JSON data returned for success or failure and what
do the different fields mean?

The answers to these questions are obtained primarily by researching the API
documentation, as described in Section 6. The following snippets give a couple of Python
solutions to this problem, one using the requests library and one using CVPRAC. The
answers to these questions for each approach is discussed in the subsequent sections.

Note that the problem being solved here is a hypothetical one, chosen simply to show how a
number of different kinds of CVP APIs may be used, how parameters are handled and how
the output from CVP may be processed. Also note that the code examples are simply meant
to give an example of possible solutions; the code is not necessarily optimized for
performance, does not necessarily handle all the possible errors etc.

7.1 What is the Python with requests library implementation?


The following table describes the APIs to use to solve the problem, the HTTP method, input
data and output data. Once these are all known, writing the Python code to solve the
problem using the requests library is simply a case of investigating how GET and POST
requests are made via the requests library and understanding how JSON data is constructed
and parsed using Python libraries. Note the use of json.dumps() to convert the input data
(from a Python dictionary) to JSON before the invoking the APIs which use POST. Hopefully,
when viewed alongside the table, the sample implementation is pretty clear. Incidentally, note
the storage of cookies from the initial authentication API call and the use of these cookies in
subsequent API calls, thus allowing the subsequent API calls to be associated with the CVP
session create by the API call to authenticate.

API Method Input data Relevant excerpt from output


data

11/16
login/authenticate.do POST { {

“userId”: “<user ID>”, “userName”: “user ID”,

“password”: “sessionId”: “<ID for CVP


“<password>” session>”,

} additional authentication
data

task/getTask.do GET queryparam=<get {


tasks with only this
status> (Optional) “total”: <number of tasks>,

startindex=<lowest “data”: [
internal task index to
display> (Default = 0) {

endIndex=<largest “workOrderId”: “<task


internal task index to ID>”,
display>
additional task data
(Default = 0, returns all
task) },

“workOrderId”: “<task
ID>”,

additional task data

task/addNoteToTask.do POST { {

“workOrderId”: “<task “data”: “<comment>”


ID>”,
}
“note”: “<note to add
to task>”

12/16
import requests
import json

CVP_HOST = "10.85.121.119"
CVP_USER = "cvpadmin"
CVP_PWD = "cvp123"

auth_data = json.dumps({'userId':CVP_USER,'password':CVP_PWD})
auth_url = "https://%s/cvpservice/login/authenticate.do" % CVP_HOST
auth_response = requests.post(auth_url, data=auth_data, verify=False)
assert auth_response.ok
cookies = auth_response.cookies

tasks_params = {'startIndex':'0','endIndex':'0'}
tasks_url = "https://%s/cvpservice/task/getTasks.do?" % CVP_HOST
tasks_response = requests.get(tasks_url, cookies=cookies, params=tasks_params,
verify=False)
assert tasks_response.ok
tasks_json = tasks_response.json()

tasks_data = tasks_json['data']
max_task_id = 0
for task in tasks_data:
task_id = int(task['workOrderId'])
if task_id > max_task_id:
max_task_id = task_id

note_string = 'This task currently has the highest numerical ID'


note_data = json.dumps({'workOrderId':str(max_task_id),'note':note_string})
note_url = "https://%s/cvpservice/task/addNoteToTask.do" % CVP_HOST
note_response = requests.post(note_url, cookies=cookies, data=note_data,
verify=False)
assert note_response.ok

7.2 What is the Python with CVPRAC implementation?


The following table lists the CVPRAC APIs needed to solve the problem, the input
parameters and outputs. When viewed alongside the table, the example implementation
should be pretty straightforward.

API Input parameters Outputs

13/16
client.connect() nodes (list): A list of CvpLoginError: A
hostname/IP addresses CvpLoginError is raised if
for CVP nodes a connection could not
be established to any of
username (str): The the nodes.
CVP username
TypeError: A TypeError is
password (str): The raised if the nodes
CVP password argument is not a list.

connect_timeout (int): ValueError: A ValueError


The number of seconds is raised if a port is not
to wait for a connection specified and the
(default is 10s) protocol is not http or
https.
protocol (str): The type
of protocol to use for the
connection (default is
‘http’).

port (int): The TCP port


of the endpoint for the
connection (default
transport dependent)

client.api.get_tasks() start (int): Lowest tasks (dict): The ‘total’


internal task index to key contains the number
display (default is 0). of tasks, the ‘data’ key
contains a list of the
end (int): Highest tasks.
internal task index to
display (default is 0).

client.api.add_note_to_task() task_id (str): Task ID

note (str): Note to add to


the task

14/16
import json
from cvprac.cvp_client import CvpClient

CVP_HOST = "10.85.121.119"
CVP_USER = "cvpadmin"
CVP_PW = "cvp123"

client = CvpClient()
client.connect([CVP_HOST], CVP_USER, CVP_PW, protocol='https')

result = client.api.get_tasks()
data = result['data']

max_task_id = 0
for task in data:
task_id = int(task['workOrderId'])
if task_id > max_task_id:
max_task_id = task_id

note = 'This task currently has the highest numerical ID'


client.api.add_note_to_task(str(max_task_id), note)

8. What are some recommended first steps in actually getting started


using the APIs?
1. Pick the programming language to use. Often this choice is constrained by the
expertise or preferences of the implementer or the language used in the existing
software being integrated with CVP. If there are no such constraints, then it is
recommended that Python should be used.

2. Decide whether or not to use CVPRAC. If the language chosen in (1) is Python, Go, or
Ruby then there is an option of using CVPRAC. If the choice of language precludes
using CVPRAC or the decision is made not to use CVPRAC, then it is imperative for
the implementer to become familiar with the mechanics of using REST APIs and
handling JSON data in the language. In order to avoid such challenges, it is
recommended that CVPRAC is used.

3. Install any necessary software.

If using CVPRAC in a particular language, it needs to be installed. Installation information is


usually available at the corresponding Github repositories:

1. Python (https://github.com/aristanetworks/cvprac)

2. Ruby (https://github.com/aristanetworks/cvprac-rb)

3. Go (https://github.com/aristanetworks/go-cvprac)

15/16
If CVPRAC is not being used and the programming language does not natively support the
handling of HTTP messages or JSON data, some additional bespoke software may need to
be installed before writing the new software to use the CVP APIs.

4. Select a couple of simple APIs and experiment with them. For completeness, it is
prudent to pick an API that uses GET and one that uses POST. First of all, an overview
of the behaviour of the APIs may be gained by experimenting with them at https://<IP
address of CVP server>/web/api/. Thereafter, if CVPRAC is being used, the examples
usually available on the CVPRAC Github repository should be used as a starting point
to write new software to invoke these APIs. If CVPRAC is not used, the procedures for
sending HTTP messages and handling JSON data in the programming language
chosen should be used to write new software to invoke the CVP APIs.

5. Identify the actual APIs that are needed to meet the goals. Again, the listing at that
may be accessed as illustrated in Figure 2 is a good place to peruse all the APIs and
identify the ones needed to solve the problem at hand which necessitates the use of
the CVP APIs. Additionally, as previously mentioned all the APIs are documented in a
file named something like CloudVisionPortal-Python-API-<release>.pdf available under
the Cloudvision Portal link at https://www.arista.com/en/support/software-download.
(Incidentally, if no individual or collection of CVP APIs is viewed as being adequate, it
could be that the problem being solved is novel and unique or, alternatively, that the
problem and/or CVP’s capabilities are misunderstood.)

6. Identify the API’s input data and output data. Trying to draw out the kind of tables in
Sections 7.1 and 7.2 will probably be valuable in understanding how the API behaves
and, critically, how to use the data returned to solve the problem at hand.

7. Write the code to invoke the API and test. Verify that the API can be invoked
successfully, supplying the correct input data. If an error is returned, check if it is an
HTTP error or CVP error before deciding on possible solutions. If the API is invoked
without error, print out the data returned to verify the contents match the expectations
detailed in Section 6. Once the data returned is as expected, use the attributes of
interest as required to solve the problem.

16/16

You might also like