Using the REST / JSON Web API

Rest/JSON usage

This is a simple REST-like API over HTTP(s) protocol.

Objects are located in a hierarchical namespace and identified by a unique URI.

Structure

An object is identified by a URI in the namespace. Each object can be either a file or a directory.

  • The last element of a URI provides the name of the object
  • A directory is a collection of objects
  • A file is a list of key/value parameters

Example of an object returning a list of key/value parameters:

{
	"key1": "value1",
	"key2": "value2",
	...
}

Example of an object returning a list of objects:

{
	"object1",
	"object2",
	...
}

Input / Output

Both input and output are always text, encoded in the US-ASCII character set.

Input

One advantage of using JSON is the ability to use the exact JSON output as an input, thus allowing convenient manipulation of objects.

The JSON format is specified in RFC 4627.

Input is formatted as a JSON object. Keys are always string and values can be either string or null.

The type number is currently ignored.

Example of possible values:

	{
	"key1": "value",
	"key5": null,
	...
}

The following HTTP header field must be specified in the request POST and PUT request when sending a JSON file:

Content-Type: application/json
Equivalence

The following table gives the equivalence between JSON, HTTP query and low-level alohactl tool formats:

JSON alohactl
“key”: “value” –key value
“key”: null –reset-key
“key”: true  
The JSON value true is always ignored on input.

For example, the following JSON input:

{
	"protocol": "http",
	"log": "enabled",
	"log_format": "http",
	"default_farm": "bk_myappli"
}

Output

Output is always formatted as JSON, it can be either a single object or an array of string.

The following HTTP header is set in the response:

Content-Type: application/json
JSON array

A directory returns an array containing the names of the objects it owns.

Example:

{
	"object1",
	"object2",
...
}
JSON object

The JSON object output format is identical to the JSON input format, so that the output from an object can be used directly as an input for another object of the same family.

However, an output of a JSON object can also contain the value true.

For a description of the JSON object format, read section about JSON input.

Text

Some files return plain text, encoded in the US-ASCII character set.

In this case, the following HTTP header field is set in the response:

Content-Type: text/plain

Specific parameters

Some parameters have specific meanings. They are written in uppercase letters. They are only used with a few HTTP methods and can sometime depend on another parameter.

Parameter Value Method Depends on Description
DEFAULT a template POST nothing Specify a default template
METHOD “clone” POST SOURCE Specify a special sub-method to call
SOURCE an object POST METHOD=clone Specify an object to clone from

URI

All URIs must start by the string/api/X/ where X indicates the version of the API.

If you don’t know X, you can call /api which returns an array of supported API versions.

GET /api

[
	"2"
]
If incompatible changes appear in the future, this format would allow use of different API versions concurrently.

HTTP Methods

Each object can understand up to four methods:

  • GET: display (returns a JSON object, a JSON array or plain text)
  • POST: create (requires a JSON object)
  • PUT: update (requires a JSON object)
  • DELETE: delete

When available, PUT accepts exactly the same format as POST but can accept a partial content.

The PUT method only affects the specified parameters.
When using POST and PUT, the following HTTP header field must be sent: Content-Type: application/json.

Authentication

Each command requires an HTTP Basic Authentication, as described in RFC 2616.

An HTTP Basic Authentication appears as an HTTP header in the form:

Authorization: Basic YWRtaW46YWRtaW4=

Authentication is only permitted for the user admin with the password specified in /etc/passwd.

It is the same password used to connect to the GUI and the CLI.

An authentication failure returns the following HTTP headers:

Status: 401 Unauthorized
WWW-Authenticate: Basic realm="ALOHA"

Document convention

Most JSON API calls must be run in a scope or in a transaction.

In the URL example provided below, scope and trans keywords as well as <scopename> and <transactionid> are replaced by the character *.

Error codes

Success

In case of success, the following HTTP header is returned:

Status: 200 OK

Errors

On error, the HTTP header Status should be set and the following HTTP header can be sent (optional):

X-Alctl-Errno
X-Alctl-Errstr

Three different types of error can occur:

  • errors returned by the HTTP server, returning Status
  • errors returned by the high-layer API, returning Status and optionally X-Alctl-Errno andX-Alctl-Errstr
  • errors returned by the low-layer API, returning Status, X-Alctl-Errno and X-Alctl-Errstr

HTTP Status

These messages can be returned by WAPI service to show statuses and reasons :

Status Reason
1.1 Continue
101 Switching Protocols
   
200 OK
201 Created
202 Accepted
203 Non-Authoritative Information
204 No Content
205 Reset Content
206 Partial Content
   
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
306 (Unused)
307 Temporary Redirect
   
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Request Entity Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
   
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported

High-layer errors

These errors are returned by the high-layer of the API.

Status Reason Usual cause
400 Bad Request Client error, see below
404 Not Found This object does not exist
405 Method Not Allowed This method does not exist for this object
415 Unsupported Media Type This file type is not supported by this object
500 Internal Server Error Server error, see below

HTTP errors 400 and 500 are completed by the HTTP headers X-Alctl-Errno and X-Alctl-Errstr.

Status Reason X-Alctl-Errno X-Alctl-Errstr
500 Internal Server Error 1001 should not happen
500 Internal Server Error 1011 read error
500 Internal Server Error 1012 write error
500 Internal Server Error 1013 execution error
500 Internal Server Error 1014 child timeout error
500 Internal Server Error 1021 lckpwdf failed
400 Bad Request 1101 missing scope name
400 Bad Request 1102 missing transaction id
400 Bad Request 1103 missing scope name or transaction id
400 Bad Request 1111 bad input format
400 Bad Request 1112 empty input
400 Bad Request 1113 too much input
The X-Alctl-Errstr header field string is only available for information purposes and the results can differ. You should only consider X-Alctl-Errno.

These errors follows a categorization rule:

Type X-Alctl-Errno Category
Server error10xx    
  100x General
  101x File system
  102x Locking
Client error 11x    
  110x Identification
  111x Input format

Low-layer errors

These errors are returned by the low-layer of the API, i. e. the alohactl command-line utility.

Status Reason X-Alctl-Errno X-Alctl-Errstr
400 Bad Request 0  
400 Bad Request 99  
503 Service Unavailable 100 API is locked
500 Internal Server Error 101 Configuration validation failure
500 Internal Server Error 110 Configuration apply failure
500 Internal Server Error 111 Unable to create transaction context
500 Internal Server Error 112 Unable to create transaction context for sub-module
500 Internal Server Error 113 Unable to re-create transaction context
500 Internal Server Error 114 Unable to backup configuration
500 Internal Server Error 115 Unable to install configuration
500 Internal Server Error 120 Unable to restore configuration
The X-Alctl-Errstr header field string is only available for information purposes and the results can differ. You should only consider X-Alctl-Errno.

Information

URI HTTP method Action
/api/2/version GET API version

System

URI HTTP method Action
/api/2/sys/local/save POST Save local configuration
/api/2/sys/peers/0/save POST Tell a peer to save its configuration
/api/2/sys/peers/0/push POST Push local configuration to the peer

Examples Using Curl

CURL (curl) is a simple Linux command line tool that can be used to run requests on the HAPEE or ALOHA API.

Main curl options

The following options are required when manipulating the API using curl:

curl option Description
-d, --data <data> Send the specified data in a POST or PUT request using the content-type application/x-www-form-urlen‐coded. Prefix <data> by a @ to load its content from a file.
-D, --dump-header <file> Write the HTTP headers to the specified file. use – to print stdout (for debug purposes)
-H,--header <header> Add custom HTTP headers to the request
-k, --insecure Do not perform SSL server certificate validation.
-u, --user<user:password> Send HTTP Basic authentication credentials
-X, --request <method> Specify the HTTP method to use for the request

The following is a minimum curl request:

curl -k -u admin:admin https://10.0.0.1:4444/api

The following is a minimum POST request to create a new L7 farm:

curl -X POST -H "Content-Type: application/json" -d @/tmp/content.txt -k --user admin:admin https://10.0.0.3:4444/api/2/scope/root/l7/farm/newfarm

Complete example over a transaction

This example creates a new frontendft_web which points to a new backendbk_web in scope root using the API, as shown in the following procedure:

  1. Create the backend.
  2. Add srv1 to the backend.
  3. Add srv2 to the backend.
  4. Create the frontend.
  5. Add a listener to the frontend.

There are two options:

  • using the atomic method: the configuration is updated and applied, and HAProxy is reloaded after each step.
  • using a transaction: a single configuration update is processed; HAProxy is reloaded only once.
In the examples below, we consider that the CURL string is equivalent to curl -k -D - --user admin:admin.
  1. Create a new transaction in the scope root:
$CURL https://10.0.0.3:4444/api/2/scope/root/trans

78hm4ySMm0

2. Create the back end `bk_web`:

  1. First, create a file /tmp/content.txt with the JSON parameters necessary:
{
	"balance": "roundrobin",
	"protocol": "http",
	"log": "enabled",	
	"log_format": "http",
	"http_connection_mode": null,
	"http_pretend_keepalive": null,
	"http_xff_header_insert": "enabled",
	"http_cookie": "enabled",
	"http_cookie_name": "bkweb",
	"http_cookie_mode": "set-silent",
	"http_cookie_nocache": "enabled",
	"check_interval": "3",
	"check_rise": "2",
	"check_fall": "3",
	"check_port": null,
	"check_timeout": null,
	"adv_check": "http",
	"adv_check_http_method": "HEAD",
	"adv_check_http_uri": "/",
	"queued_timeout": null,
	"connect_timeout": "4",
	"connect_retries": null,
	"connect_failure_redispatch": null,
	"connect_source": null,
	"connect_transparent": null,
	"server_inactivity_timeout": "25",
	"tcpreq_inspect_delay": null,
	"tcprsp_inspect_delay": nul
}
  1. Next, create the L7 farm:
$CURL -X POST -d @/tmp/content.txt -H "Content-Type: application/json" https://10.0.0.3:4444/api/2/trans/78hm4ySMm0/l7/farm/bk_web

3. Add srv1 in the back end:

  1. First, create a file /tmp/content.txt with the JSON parameters necessary:
{
	"address": "192.168.1.21",
	"port": "80",
	"max_connections": "1000",
	"weight": "10",
	"http_cookie_id": "srv1",
	"sorry": null,
	"check": "enabled",
	"maintenance": null,
	"ssl": null
}
  1. Next, create the server in bk_web L7 farm:
$CURL -X POST -d @/tmp/content.txt -H "Content-Type: application/json" https://10.0.0.3:4444/api/2/trans/78hm4ySMm0/l7/farm/bk_web/server/srv1

4. Add srv2 in the back end:

  1. First, create a file /tmp/content.txt with the JSON parameters necessary:
{
	"address": "192.168.1.22",
	"port": "80",
	"max_connections": "1000",
	"weight": "10",
	"http_cookie_id": "srv2",
	"sorry": null,
	"check": "enabled",
	"maintenance": null,
	"ssl": null
}
  1. Next, create the server in bk_web L7 farm:
$CURL -X POST -d @/tmp/content.txt -H "Content-Type: application/json" https://10.0.0.3:4444/api/2/trans/78hm4ySMm0/l7/farm/bk_web/server/srv2

5. Create the service ft_web:

  1. First, create a file /tmp/content.txt with the JSON parameters necessary:
{
	"protocol": "http",
	"log": "enabled",
	"log_format": "http",
	"log_ignore_null": null,
	"http_connection_mode": null,
	"http_pretend_keepalive": null,
	"client_inactivity_timeout": "25",
	"http_request_timeout": null,
	"http_keepalive_timeout": null,	
	"max_connections": "1000",
	"default_farm": "bk_web",
	"tcpreq_inspect_delay": null
}
  1. Next, create the L7 service:
$CURL -X POST -d @/tmp/content.txt -H "Content-Type: application/json" https://10.0.0.3:4444/api/2/trans/78hm4ySMm0/l7/service/ft_web

6. Create the listener for the L7 service:

  1. First, create a file /tmp/content.txt with the JSON parameters necessary:
{
	"port": "80",
	"address": "0.0.0.0",
	"transparent": null,
	"ssl": null,
	"ssl_certificate": null

}
  1. Next, create the listener for the L7 service:
$CURL -X POST -d @/tmp/content.txt -H "Content-Type: application/json" https://10.0.0.3:4444/api/2/trans/78hm4ySMm0/l7/service/ft_web/listener/http

7. Commit the transaction:

$CURL -X POST https://10.0.0.3:4444/api/2/trans/78hm4ySMm0

Save the configuration in a cluster

In the examples below, we consider that the CURL string is equivalent to curl -k -D - --user admin:admin.

1. Save the configuration on the master:

$CURL -X POST https://10.0.0.3:4444/api/2/sys/local/save

2. Push the master’s configuration to the slave:

$CURL -X POST https://10.0.0.3:4444/api/2/sys/peers/0/push

3. Through the master, tell the slave to save its configuration:

$CURL -X POST https://10.0.0.3:4444/api/2/sys/peers/0/save