This document describes usage of the Nuage Virtualized Services Directory (VSD) northbound ReST API. Topics covered include:
The Nuage VSD ReST API request uses HTTP headers for various purposes like authentication, filtering, ordering, pagination etc. HTTP headers are used instead of query parameters for several reasons, mostly because it keeps the resource URI clean, short and easy to read. Use of HTTP headers also allows the server to reply with useful metadata, like the current page number and the total number of objects, without affecting the JSON or XML objects that is sent to clients.
The server response will be formatted in JSON. Content-Type is a required header field for HTTP POST and PUT as mentioned below to either create or modify an entity:
Each API call must be authenticated, so the Authorization header must be sent with each request:
$AUTHORIZATION_STRING is defined below.
For all API calls, this Nuage custom HTTP header is used to indicate the associated enterprise (CSP — the data center administrative enterprise — is also a standard enterprise) for the request:
For a GET request, this header allows the client to ask for a given page number as all object lists are paginated:
For a GET request, this allows the client to ask for a filtered list of objects:
The filter can be either plain text, or a predicate. How predicates work later is explained later.
This optional header instructs the server on how to order the results:
Ordering follows the basic SQL Order By statement. For example, the X-Nuage-OrderBy: name DESC, login ASC header will result in entities ordered first by descending name, then by ascending login.
X-Nuage-Count indicates the total count of objects requested.
X-Nuage-Page indicates the actual page number just received.
X-Nuage-PageSize indicates the internal page size. The page size can be configured on the server. By default, it is 50 objects.
X-Nuage-Filter is an echo of the filter in the request, if any
X-Nuage-FilterType indicates how the server has interpreted your filter. Return values are plain or predicate.
X-Nuage-OrderBy indicates how the objects in the reply are ordered.
There is no "authentication" in the sense of a strong server-side session, the VSD uses an API key that serves as an authenticated password for all subsequent calls.
This section describes how to get and use an API key.To obtain and API key, the first step is to make a /me API call. This API call returns information about the account being used.
The authorization string for the /me API MUST be formatted like the following:
Note that with Basic authentication, the password is not encrypted before transfer. This is part of the HTTP standard for Basic authentication, and is also required in order to support an LDAP internal authentication mechanism. However, all communication is over a secure channel (SSL/TLS).
NOTE: Many web browsers display Basic authentication requests and error responses in dialog boxes. Depending on the API client being developed, this may not be desirable. Instead of using the Basic authentication method, the XREST authentication method can be specified to prevent the browser from displaying a login dialog box or error dialog. The semantics are identical, but the keyword "Basic" is replaced with "XREST" in the AUTHORIZATION_STRING
The server will answer the request with:
The APIKey value should be used for all subsequent API calls. The APIKey is valid until APIKeyExpiry. APIKeyExpiry is specified as a POSIX time (seconds since the epoch: 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970), and is provided as a convenience, to allow the client application to renew its API key before expiry rather than waiting for a request to fail due to API key timeout.
Once an API key has been obtained, the key acts like a password for all subsequent requests. For example, to get all enterprises:
where the authorization string must be formatted like the following:
The main philosophy of the API is to allow users to develop a simple and consistent model and feed it with the server replies without having to deal with complexities like sending only modified values, etc. For example, when requesting an enterprise, a JSON object is returned. To change an object.name, you can send only the modified attribute and its value or the entire object including the modified value to the server.
Note that the server can deal with null values. For example, when creating an enterprise, the request can have only the name and description properties with all other object attributes like ID, creationDate, owner, etc., set to null. Alternatively, the request may only send the name and description depending on preference. The main advantage is that the object model can easily be mirrored in the client.
Note that in the following examples, not all required the HTTP headers are displayed to improve readability, but those headers are still required in a properly formed request.
To get list of objects, one uses the GET request. For example, to get all enterprises:
To get all groups in the company named Nuage Networks (ID: 25149097-1e23-47f3-ae5e-589b4c27a158):
Querying deeper in the example above, a request to get all users in the group Administrators by issuing a request for /enterprises/$ID/groups/$ID will fail because the API only supports three levels of depth, for example,
To query deeper into the hierarchy, one can request:
So to get all users in Nuage Networks' group named Administrators (ID: a296bef5-ff10-46ab-acbb-650281edbcf4), the request would be:
Note that not all objects can be queried directly. For example, one cannot ask for /users or /groups.
To create an object, use a POST request.
For example, to create a new enterprise:
To create a child object, like a group inside an enterprise:
To update an object, use a PUT request.
The example below updates the enterprise description:
To delete an object use a DELETE request.
The example below will delete the enterprise $ENTERPRISE_ID:
Each request you or other users send to the server are actually pushed back to all other users (filtered by permissions) via HTTP Server Push using Long Polling. Use of the push channel is optional.
To start listening to the Push channel, send an /events call:
This is a long polling request, with a timeout set to a certain amount of time (about 1 min). If something happens during this period, the server will send you back a push. A push can contains several events. Pushes are always grouped by events type (CREATE, DELETE, UPDATE, GRANT, REVOKE) and by entity type (enterprise, group, etc).
The output above indicates Bob has created a new enterprise named The Company.
If nothing happened during the timeout period, the following is returned:
Whether something happened or not, one can ask for the next event by simply resending the /event request, with the last push uuid as query parameter as follows:
This UUID ensures that events are not lost if something else happened during the time between the response and the next request.
VSD provides a very simple, yet very advanced way to filter entities. Filter can be defined using plain text or using a predicate. The server is able to determine by itself the type of filter requested: a plain text filter or a predicate.
Plain text filtering is simple and only requires setting the X-Nuage-Filter: the filter. The server will return only entities that have any of their properties containing the text the filter.
Predicate is a more advance way to use filters. The syntax is based on the Cocoa Predicate, and allows to build complex queries.
For example, one can send complex filters like:
See Filtering, Sorting and Paging for more information on what is supported on VSD
More information about predicate syntax is available from (Apple Cocoa documentation)[https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/predicates.html#//apple_ref/doc/uid/TP40001789]
The server replies using standard HTTP response codes.
2XX codes indicate that the request was processed:
3XX codes indicate the server needs more information from the client and will be offer different choices:
For example, sending a request to delete a parent object with children under it:
The server will reply:
The server is presenting two choices:
To validate, resend the same request, with an HTTP query parameter set to the selected choice: