06-27-2017 07:10 PM - edited 03-01-2019 04:20 AM
The REST API (or RESTful API) is one of the Northbound APIs supported by NSO, and the client can operate NSO using HTTP(S).
The REST API itself is used not only in NSO but also in other products, and because it is easy to call from Javascript, it is often used in web portals and so on.
NSO can use JSON or XML for the payload. By , client applications can choose either easily by specifying the Content-type to include in the HTTP header.
The REST API and RESTCONF are similar in name and behavior but they are different northbound APIs. Although RESTCONF is defined in RFC 8040, there is no standardized specification in the REST API itself, and it is implemented by NSO (and software supporting REST API) by itself.
In NSO, RESTCONF protocol is supported by NSO 4.3 or later.
This document explains about REST API.
In the REST API, operations are performed on a object (node) that can be identified by URI. Each object belongs to one of the resources.
http://xxxx:8080/api/<resource>
Field | Description |
---|---|
version | REST API version |
config | Config resource (alias of running) |
running | Running (config data) resource |
operational | Operational data resource |
operations | Defined operations container such as YANG rpc and NSO action |
rollbacks | Rollback file container |
(From NSO 4.4 Northbound APIs manual)
Example of URIs
http://localhost:8080/api/running
http://localhost:8080/api/operations
NSO supports the following methods.
Method | Description |
GET | Get objects |
POST | Create a new list instance |
PUT | Create a new object or change (replace) it |
PATCH | Make changes to the object |
DELETE | Delete the object |
HEAD | Get only header information of GET method |
OPTIONS | Get a list of available methods for the specified resource |
By adding the query parameter to the URI followed by "?" (Question Mark), you can change the normal behavior and make various differences. Note that it is not related to the REST Query API which will be explained later.
For example, if you wish to do "commit dry-run" on the commit action from REST, we use this feature
Since many types of query parameters are defined, only some of them are listed here. For other parameters, refer to the following in the manual.
NSO 4.4 Northbound APIs -> The REST API -> Getting started -> Query Parameters
dryrun | When changing data, commit dry-run equivalent will be done. Do not make changes to Southbound equipment or CDB at all, only calculate data to be changed. |
no-networking | When changing data, do commit no-networking equivalent. Do not change to Southbound equipment, only change CDB. |
with-defaults | When acquiring data, execute show running-config | detail equivalent. Include default values in retrieved data. |
* dry-run example is included in later examples of REST calls.
The below all examples are using curl commands.
To check what method is available, use OPTIONS method. We now know that GET and HEAD method is usable.
$ curl -i -X OPTIONS http://localhost:8080/api -u admin:admin
HTTP/1.1 200 OK
Server:
Allow: GET, HEAD
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 0
Content-Type: text/html
Pragma: no-cache
$
This example returns what resources are available by using GET method on /api. curl command actually performs GET when -X option is missing, however it is used to show GET is used. -i option shows the HTTP response headers together.
The default data format is in XML.
$ curl -i -X GET http://localhost:8080/api -u admin:admin
HTTP/1.1 200 OK
Server:
Date: Thu, 27 Apr 2017 07:23:06 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 181
Content-Type: application/vnd.yang.api+xml
Vary: Accept-Encoding
Pragma: no-cache
<api xmlns="http://tail-f.com/ns/rest" xmlns:y="http://tail-f.com/ns/rest">
<version>0.5</version>
<config/>
<running/>
<operational/>
<operations/>
<rollbacks/>
</api>
$
Let's do the same with JSON format.
$ curl -i -X GET http://localhost:8080/api -u admin:admin -H "Accept: application/vnd.yang.api+json"
HTTP/1.1 200 OK
Server:
Date: Thu, 27 Apr 2017 07:29:34 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 98
Content-Type: application/vnd.yang.api+json
Vary: Accept-Encoding
Pragma: no-cache
{"api":{"version":"0.5","config":{},"running":{},"operational":{},"operations":{},"rollbacks":{}}}
$
This example is showing how to get aaa objects. This is equivalent to 'show running-config aaa' on NCS CLI. If you need to get the all data recursively, add "?deep" in the URL.
$ curl -i -X GET http://localhost:8080/api/running/aaa -u admin:admin
HTTP/1.1 200 OK
Server:
Date: Thu, 27 Apr 2017 07:33:45 GMT
Last-Modified: Wed, 19 Apr 2017 11:24:25 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Etag: 1493-188275-346474
Content-Type: application/vnd.yang.data+xml
Transfer-Encoding: chunked
Pragma: no-cache
<aaa xmlns="http://tail-f.com/ns/aaa/1.1" xmlns:y="http://tail-f.com/ns/rest" xmlns:aaa="http://tail-f.com/ns/aaa/1.1">
<authentication>
<users>
<user>
<name>admin</name>
</user>
<user>
<name>oper</name>
</user>
<user>
<name>private</name>
</user>
<user>
<name>public</name>
</user>
</users>
</authentication>
</aaa>
Here's how to add user using REST. POST method can create list instance, so we use POST on /aaa/authentication/users/user list object to add a user "test". JSON payload format is used.
$ curl -i -X POST http://localhost:8080/api/running/aaa/authentication/users -u admin:admin -H "Content-Type: application/vnd.yang.data+json" -d '
{ "tailf-aaa:user": {
"name" : "test",
"uid" : "0",
"gid" : "0",
"password" : "",
"ssh_keydir" : "",
"homedir" : ""
}
}'
HTTP/1.1 201 Created
Server:
Location: http://localhost:8080/api/running/aaa/authentication/users/user/test
Date: Thu, 27 Apr 2017 07:56:08 GMT
Last-Modified: Thu, 27 Apr 2017 07:56:08 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Etag: 1493-247351-147821
Content-Length: 0
Content-Type: text/html
Pragma: no-cache
$
We created a user test in the above example. Let's delete, but we want to do dry-run now.
$ curl -i -X DELETE http://localhost:8080/api/running/aaa/authentication/users/user/test?dryrun=cli -u admin:admin
HTTP/1.1 200 OK
Server:
Date: Thu, 27 Apr 2017 10:03:15 GMT
Last-Modified: Thu, 27 Apr 2017 08:38:55 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Etag: 1493-249943-225197
Content-Length: 375
Content-Type: text/xml
Vary: Accept-Encoding
Pragma: no-cache
<dryrun-result xmlns='http://tail-f.com/ns/rest/dryrun'>
<cli>
<local-node>
<data>
aaa {
authentication {
users {
- user test {
- uid 0;
- gid 0;
- password "";
- ssh_keydir "";
- homedir "";
- }
}
}
}
</data>
</local-node>
</cli>
</dryrun-result>
$
$ curl -i -X DELETE http://localhost:8080/api/running/aaa/authentication/users/user/test -u admin:admin
HTTP/1.1 204 No Content
Server:
Date: Thu, 27 Apr 2017 08:01:55 GMT
Last-Modified: Thu, 27 Apr 2017 08:01:55 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Etag: 1493-247701-159346
Content-Length: 0
Content-Type: text/html
Pragma: no-cache
$
This example performs sync-from on a device c0. To invoke actions, use operations resource.
$ curl -i -X POST http://localhost:8080/api/operations/devices/device/c0/sync-from -u admin:admin
HTTP/1.1 200 OK
Server:
Date: Thu, 27 Apr 2017 08:42:53 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 76
Content-Type: application/vnd.yang.operation+xml
Vary: Accept-Encoding
Pragma: no-cache
<output xmlns='http://tail-f.com/ns/ncs'>
<result>true</result>
</output>
$
In different way using running resource, we can do the same using _operations tag.
$ curl -i -X POST http://localhost:8080/api/running/devices/device/c0/_operations/sync-from -u admin:admin
HTTP/1.1 200 OK
Server:
Date: Thu, 27 Apr 2017 08:40:23 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 76
Content-Type: application/vnd.yang.operation+xml
Vary: Accept-Encoding
Pragma: no-cache
<output xmlns='http://tail-f.com/ns/ncs'>
<result>true</result>
</output>
$
Many examples are found in NSO documents, so you can refer more there.
REST Query API is used for different purpose from the above. REST API is to get, create, update, and delete on a specific object, and REST Query API is to search data.
Search formula or keywords are needed to search. By sending those in the specified format, NSO searches data and we can obtain the result.
For REST Query API, we use the below URI.
http://localhost:8080/api/query
Protocol (http or https), host and port number needs to be matched to your environment.
Query data is in a format specified in "http://tail-f.com/ns/tailf-rest-query" namespace. start-query container has the model of search data.
For "foreach", you can use XPATH, and this example is searching a user whose name is "admin". Note that XPATH 1.0 is supported, and XPATH 2.0 is not supported.
Also, as you can see, "select" tag is specifying what leafs to be returned.
<start-query xmlns="http://tail-f.com/ns/tailf-rest-query">
<foreach>
/aaa/authentication/users/user[name = "admin"]
</foreach>
<select>
<expression>name</expression>
<result-type>string</result-type>
</select>
<select>
<expression>homedir</expression>
<result-type>string</result-type>
</select>
<sort-by>name</sort-by>
<limit>100</limit>
<offset>1</offset>
</start-query>
Running Example:
$ curl -i -X POST http://localhost:8080/api/query -u admin:admin -d '
> <start-query xmlns="http://tail-f.com/ns/tailf-rest-query">
> <foreach>
> /aaa/authentication/users/user[name = "admin"]
> </foreach>
> <select>
> <expression>name</expression>
> <result-type>string</result-type>
> </select>
> <select>
> <expression>homedir</expression>
> <result-type>string</result-type>
> </select>
> <sort-by>name</sort-by>
> <limit>100</limit>
> <offset>1</offset>
> </start-query>
> '
HTTP/1.1 200 OK
Server:
Date: Thu, 27 Apr 2017 09:04:56 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 125
Content-Type: application/yang-data+xml
Vary: Accept-Encoding
Pragma: no-cache
<start-query-result xmlns="http://tail-f.com/ns/tailf-rest-query">
<query-handle>4</query-handle>
</start-query-result>
$
If you wanted to search users that have "admin" is contained in the name, we can use contains XPATH function in foreach tag.
Reference: XML Path Language (XPath)
/aaa/authentication/users/user[contains("admin", name)]
The search is done in Async because the search may take long time. As you see, query-handle is returned, and we use this number for fetching the result.
Using the query-handle returned in query call, we can fetch the result. The payload format needs to be in start-query-result container.
<fetch-query-result xmlns="http://tail-f.com/ns/tailf-rest-query">
<query-handle>4</query-handle>
</fetch-query-result>
Running example
$ curl -i -X POST http://localhost:8080/api/query -u admin:admin -d '
> <fetch-query-result xmlns="http://tail-f.com/ns/tailf-rest-query">
> <query-handle>4</query-handle>
> </fetch-query-result>
> '
HTTP/1.1 200 OK
Server:
Date: Thu, 27 Apr 2017 09:10:33 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 233
Content-Type: application/yang-data+xml
Vary: Accept-Encoding
Pragma: no-cache
<query-result xmlns="http://tail-f.com/ns/tailf-rest-query">
<result>
<select>
<value>admin</value>
</select>
<select>
<value>/var/ncs/homes/admin</value>
</select>
</result>
</query-result>
$
Regardless of which HTTP request you send, the status code is attached to the response. What is defined in NSO 4.4 is as follows.
Code | Text | Description |
---|---|---|
200 | OK | The request is processed normally and the requested content is included in the reply content. |
201 | Created | A new resource (instance) has been created. In the Location header, the URI of the object is included. |
204 | No Content | Request processed successfully. The reply content is empty. |
400 | Bad Request | Abnormal termination due to problem in request content. |
401 | Unauthorized | Authentication failed. |
403 | Forbidden | Access to the requested object was not approved. (Authorization failed) |
404 | Not Found | The requested object did not exist. |
405 | Method Not Allowed | The requested method is not allowed for this resource. |
406 | Not Acceptable | You can not generate reply contents of processing results in the format specified by "Accept" header or "format" query parameter. |
409 | Conflict | The object you are trying to create already exists. |
415 | Unsupported Media Type | The requested media type (MIME format) is not supported. |
500 | Internal Error | An error occurred. |
501 | Not Implemented | The requested content is not implemented. |
503 | Unavailable | Processing for the requested object can not be completed due to reasons such as its being used or server load high. |
(From NSO 4.4 Northbound APIs manual)
Great guide and definitely needed. Thanks!
Excellent document!
Very useful, thanks your effort!
Hi,
This is really helpful, how ever would you be able to do the same but for RESTCONF examples
Thanks
Regards
Yale
Hello all,
I am new to all this but have looked through the acitoolkit and seen the details of EPG's , contracts and so on......
I am looking to spin up a whole tenant in one shot !!
What I cannot understand is how to attach a VMware server into a EPG. Cannot see any sign of this in the acitoolkit
i go to the
http://IP/api - i get the page downloaded instead of displayed - how i browse the api ? or some swagger type tool so i try the curl inside a tool ? @Akira Iwamoto
Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the NSO Developer community: