REST / JSON Web API

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.

Info

To make your changes persistent after a reboot, save the configuration in the cluster.

Structure Jump to heading

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:

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

Example of an object returning a list of objects:

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

Input / output Jump to heading

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

Input Jump to heading

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.

Info

The type number is currently ignored.

Example of possible values:

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

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

text
Content-Type: application/json
text
Content-Type: application/json

Equivalence Jump to heading

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

Info

The JSON value true is always ignored on input.

For example, the following JSON input:

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

Output Jump to heading

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:

text
Content-Type: application/json
text
Content-Type: application/json

JSON array Jump to heading

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

Example:

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

JSON object Jump to heading

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 Jump to heading

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:

text
Content-Type: text/plain
text
Content-Type: text/plain

Specific parameters Jump to heading

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 Jump to heading

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

If you do not know X, you can call /api which returns an array of supported API versions.

text
GET /api
[
"2"
]
text
GET /api
[
"2"
]

Info

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

HTTP methods Jump to heading

Each object can understand up to four methods:

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

Info

The PUT method only affects the specified parameters.

Info

When using POST and PUT, the following HTTP header field must be sent: Content-Type: application/json.

Authentication Jump to heading

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

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

text
Authorization: Basic YWRtaW46YWRtaW4=
text
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:

text
Status: 401 Unauthorized
WWW-Authenticate: Basic realm="aloha"
text
Status: 401 Unauthorized
WWW-Authenticate: Basic realm="aloha"

Document convention Jump to heading

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

Information Jump to heading

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

Scopes Jump to heading

  • A scope is a portion of the configuration.

  • It is identified by a name composed by alpha-numeric characters.

  • A specific scope name is reserved: root. It can access any configuration which stands outside of a scope.

Info

  • Each scope is independent, which makes the API multi-tenant.

  • The HAProxy ALOHA GUI LB Admin tab can modify the root scope only.

  • When a request is run in a scope name, it is run automatically and directly applied.

There is no way to list existing scopes through alohactl2 command.

In a HAProxy configuration, a scope is identified by a begin and end tags.

All the frontends and backends between these tags are prefixed by the scope name.

The HAProxy configuration for a scope called bob:

haproxy
defaults bob:l7_begin
frontend bob:newservice
# ...
default_backend bob:newfarm
backend bob:newfarm
# ...
defaults bob:l7_end
haproxy
defaults bob:l7_begin
frontend bob:newservice
# ...
default_backend bob:newfarm
backend bob:newfarm
# ...
defaults bob:l7_end

Create a scope Jump to heading

To create a scope, apply configuration either atomically or through a transaction to a new scope name.

Delete a scope Jump to heading

To delete a scope, remove all configuration belonging to the scope.

Transactions Jump to heading

Transactions allow multiple configuration changes in one atomic operation.

Each transaction is identified by a unique identifier composed by alphanumeric characters.

Example: BrwClcc76t.

  • Each request can be executed either atomically or as part of a transaction

  • Both atomic requests and transactions apply only on a single scope

  • An atomic request immediately applies the changes to the files

  • A transaction must be started before issuing a bunch of requests, then it can be either committed or canceled

  • Canceling a transaction makes no change on files and drops the entire bunch of requests since the beginning of the transaction

  • Committing a transaction consecutively applies the changes to the files for the entire bunch of requests since the beginning of the transaction

Info

A transaction must belong to a scope.

URI HTTP method Action
/api/2/trans GET list all
/api/2/scope/<scopename>/trans GET create
/api/2/trans/<transactionid> POST commit
DELETE cancel
/api/2/scope/<scopename>/<command> cf command run an atomic command in a scope
/api/2/trans/<transactionid>/<command> cf command run an atomic command in a transaction

where:

Variable Definition
<scopename> scope identifier
<transactionid> transaction unique identifier
<command> actions to perform

When committing a transaction, the following steps happen:

  1. Re-creates working context from current configuration

  2. Re-plays all update actions recorded on transaction identified by on newly re-created context

Then, 2 options:

  • If re-play is successful: configuration is locked, validated, applied, and finally unlocked

  • If error occurs during locked phase, it processes a configuration rollback and lock is removed

L7 farms Jump to heading

URI HTTP method Action
/api/2/*/*/l7/farm GET list all
DELETE delete all
/api/2/*/*/l7/farm/<farmname> GET show configuration
POST create
PUT update
DELETE delete

where:

Variable Definition
<farmname> name of a L7 farm

L7 servers Jump to heading

URI HTTP method Action
/api/2/*/*/l7/farm/<farmname>/server GET list all
DELETE delete all
/api/2/*/*/l7/farm/<farmname>/server/<servername> GET show configuration
POST create
PUT update
DELETE delete

where:

Variable Definition
<farmname> name of a L7 farm
<servername> name of a L7 server

L7 services Jump to heading

URI HTTP method Action
/api/2/*/*/l7/service GET list all
DELETE delete all
/api/2/*/*/l7/service/<servicername> GET show configuration
POST create
PUT update
DELETE delete

where:

Variable Definition
<servicename> name of an L7 service

L7 listeners Jump to heading

URI HTTP method Action
/api/2/*/*/l7/service/<servicename>/listener GET list all
DELETE delete all
/api/2/*/*/l7/service/<servicename>/listener/<listenername> GET show configuration
POST create
PUT update
DELETE delete

where:

Variable Definition
<servicename> name of a L7 service
<listenername> name of a L7 listener

L7 rules Jump to heading

URI HTTP method Action
/api/2/*/*/l7/<objecttype>/<objectname>/rule/<ruletype> GET list all
DELETE delete all
/api/2/*/*/l7/<objecttype>/<objectname>/rule/<ruletype>/<number> GET show configuration
POST create
PUT update
DELETE delete

The <objecttype> can be one of:

Value Description
service if the rule applies to a L7 service
farm if the rule applies to a L7 farm
<objectname> name of the object to apply the action on
<ruletype> depends on <objecttype>:

For service object type:

- tcpreqconn - with the following list: L7 tcpreqconn rule attributes
- tcpreqcont - with the following list: L7 tcpreqcont rule attributes
- httpreq - with the following list: L7 httpreq rule parameters
- redirect - with the following list: L7 redirect rule parameters
- usefarm - with the following list: L7 usefarm rule parameters

For farm object type:

- tcpreqcont - with the following list: L7 tcpreqcont rule attributes
- httpreq - with the following list: L7 httpreq rule parameters
- redirect - with the following list: L7 redirect rule parameters
- useserver - with the following list: L7 useserver rule parameters
- tcprspcont - with the following list: L7 tcprspcont rule parameters
- tcpcheck - with the following list: L7 tcpcheck rule parameters

A <number> can be one of:

Value Description
tail get the first rule of the list
head get the last rule of the list
a positive integer get the rule pointed by the integer

When deleting a rule, the following applies:

  • to delete the latest rule of the list, set <number> to tail

  • to delete the first rule of the list, set <number> to either 1 or head

  • to delete the Xth rule, set <number> to X

When creating a new rule, the following applies:

  • to add a rule at the bottom of the list, set <number> to tail

  • to add a rule at the top of the list, set <number> to either 1 or head

  • to insert a rule before Xth one, set <number> to X

L4 farms Jump to heading

URI HTTP method Action
/api/2/*/*/l4/farm GET list all
DELETE delete all
/api/2/*/*/l4/farm/<farmname> GET show configuration
POST create
PUT update
DELETE delete

where:

Variable Definition
<farmname> name of a L4 farm

L4 servers Jump to heading

URI HTTP method Action
/api/2/*/*/l4/farm/<farmname>/server GET list all
DELETE delete all
/api/2/*/*/l4/farm/<farmname>/server/<servername> GET show configuration
POST create
PUT update
DELETE delete

where:

Variable Definition
<farmname> name of a L4 farm
<servername> name of a L4 server

System Jump to heading

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 Jump to heading

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

Main curl options Jump to heading

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:

nix
curl -k -u admin:admin https://10.0.0.1:4444/api
nix
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:

nix
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
nix
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 Jump to heading

This example creates a new frontend ft_web which points to a new backend bk_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 the load balancer is reloaded after each step.

  • using a transaction: a single configuration update is processed; the load balancer is reloaded only once.

Info

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:

    nix
    $CURL https://10.0.0.3:4444/api/2/scope/root/trans
    nix
    $CURL https://10.0.0.3:4444/api/2/scope/root/trans
    output
    text
    78hm4ySMm0
    output
    text
    78hm4ySMm0
  2. Create the back end bk_web:

    • First, create a file /tmp/content.txt with the JSON parameters necessary:

      /tmp/content.txt
      json
      {
      "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": null
      }
      /tmp/content.txt
      json
      {
      "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": null
      }
    • Next, create the L7 farm:

      nix
      $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
      nix
      $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:

    • First, create a file /tmp/content.txt with the JSON parameters necessary:

      /tmp/content.txt
      json
      {
      "address": "192.168.1.21",
      "port": "80",
      "max_connections": "1000",
      "weight": "10",
      "http_cookie_id": "srv1",
      "sorry": null,
      "check": "enabled",
      "maintenance": null,
      "ssl": null
      }
      /tmp/content.txt
      json
      {
      "address": "192.168.1.21",
      "port": "80",
      "max_connections": "1000",
      "weight": "10",
      "http_cookie_id": "srv1",
      "sorry": null,
      "check": "enabled",
      "maintenance": null,
      "ssl": null
      }
    • Next, create the server in bk_web L7 farm:

      nix
      $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
      nix
      $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:

    • First, create a file /tmp/content.txt with the JSON parameters necessary:

      /tmp/content.txt
      json
      {
      "address": "192.168.1.22",
      "port": "80",
      "max_connections": "1000",
      "weight": "10",
      "http_cookie_id": "srv2",
      "sorry": null,
      "check": "enabled",
      "maintenance": null,
      "ssl": null
      }
      /tmp/content.txt
      json
      {
      "address": "192.168.1.22",
      "port": "80",
      "max_connections": "1000",
      "weight": "10",
      "http_cookie_id": "srv2",
      "sorry": null,
      "check": "enabled",
      "maintenance": null,
      "ssl": null
      }
    • Next, create the server in bk_web L7 farm:

      nix
      $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
      nix
      $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:

    • First, create a file /tmp/content.txt with the JSON parameters necessary:

      /tmp/content.txt
      json
      {
      "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
      }
      /tmp/content.txt
      json
      {
      "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
      }
    • Next, create the L7 service:

      nix
      $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
      nix
      $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:

    • First, create a file /tmp/content.txt with the JSON parameters necessary:

      /tmp/content.txt
      json
      {
      "port": "80",
      "address": "0.0.0.0",
      "transparent": null,
      "ssl": null,
      "ssl_certificate": null
      }
      /tmp/content.txt
      json
      {
      "port": "80",
      "address": "0.0.0.0",
      "transparent": null,
      "ssl": null,
      "ssl_certificate": null
      }
    • Next, create the listener for the L7 service:

      nix
      $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
      nix
      $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:

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

Save the configuration in a cluster Jump to heading

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:

    nix
    $CURL -X POST https://10.0.0.3:4444/api/2/sys/local/save
    nix
    $CURL -X POST https://10.0.0.3:4444/api/2/sys/local/save
  2. Push the master configuration to the slave:

    nix
    $CURL -X POST https://10.0.0.3:4444/api/2/sys/peers/0/push
    nix
    $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:

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

Do you have any suggestions on how we can improve the content of this page?