• CVP APIs: A Non-Programmer’s Guide

 
 
Print Friendly, PDF & Email

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 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.

CVP-Options.jpg

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 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/)

  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.

 

CVP-API-Doc-Link.jpg

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.

 

CVP-APIs-Usage-2.jpg

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 inbuilt Requests or URL library

Minimal dependencies on other packages

Need to understand and implement REST API calls

Need to understand and handle JSON data returned from API

Python with CVPRAC

Uses common CVPRAC code to handle REST API calls, manipulate JSON data etc so simpler and quicker to implement.

Less bugs due to using common and mature CVPRAC code

Dependency on CVPRAC package

CVP API web page

Good documentation and overview of APIs

No programming expertise needed to use APIs

Output displayed on web page so can be hard to use in a program

Curl from terminal

Quick and simple to use so  well-suited for debugging or testing,

Output formatted conveniently

Output typically written to terminal so can be hard to use in a program

Browser

Quick and simple to use so well-suited for debugging or testing

Output typically displayed 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.  

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.

 

CVP-APIs-GET-POST.jpg

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:

  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

  • 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.

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?

  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

login/authenticate.do

POST

{

 “userId”: “<user ID>”,

 “password”: “<password>”

}

{

 “userName”: “user ID”,

 “sessionId”: “<ID for CVP session>”,

  additional authentication data

}

task/getTask.do

GET

queryparam=<get tasks with only this status> (Optional)

startindex=<lowest internal task index to display> (Default = 0)

endIndex=<largest internal task index to display>

(Default = 0, returns all task)

{

 “total”: <number of tasks>,

 “data”: [

   {

     “workOrderId”: “<task ID>”,

      additional task data

   },

   {

     “workOrderId”: “<task ID>”,

      additional task data

   }

   …

 ]

}

task/addNoteToTask.do

POST

{

 “workOrderId”: “<task ID>”,

 “note”: “<note to add to task>”

}

{

 “data”: “<comment>”

}


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

client.connect()

nodes (list): A list of hostname/IP addresses for CVP nodes

username (str): The CVP username

password (str): The CVP password

connect_timeout (int): The number of seconds to wait for a connection (default is 10s)

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)

CvpLoginError: A CvpLoginError is raised if a connection could not be established to any of the nodes.

TypeError: A TypeError is raised if the nodes argument is not a list.

ValueError: A ValueError is raised if a port is not specified and the protocol is not http or https.

client.api.get_tasks()

start (int): Lowest internal task index to display (default is 0).

end (int): Highest internal task index to display (default is 0).

tasks (dict): The ‘total’ key contains the number of tasks, the ‘data’ key contains a list of the tasks.

client.api.add_note_to_task()

task_id (str): Task ID

note (str): Note to add to the task

 

 

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)

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.

  1. 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.

  2. 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.)

  3. 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.

  4. 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.

Follow

Get every new post on this blog delivered to your Inbox.

Join other followers: