Skip to content
Snippets Groups Projects
rapi.rst 37.74 KiB

Ganeti remote API

Documents Ganeti version |version|

Contents

Introduction

Ganeti supports a remote API for enable external tools to easily retrieve information about a cluster's state. The remote API daemon, ganeti-rapi, is automatically started on the master node. By default it runs on TCP port 5080, but this can be changed either in .../constants.py or via the command line parameter -p. SSL mode, which is used by default, can also be disabled by passing command line parameters.

Users and passwords

ganeti-rapi reads users and passwords from a file (usually /var/lib/ganeti/rapi/users) on startup. Changes to the file will be read automatically.

Each line consists of two or three fields separated by whitespace. The first two fields are for username and password. The third field is optional and can be used to specify per-user options. Currently, write is the only option supported and enables the user to execute operations modifying the cluster. Lines starting with the hash sign (#) are treated as comments.

Passwords can either be written in clear text or as a hash. Clear text passwords may not start with an opening brace ({) or they must be prefixed with {cleartext}. To use the hashed form, get the MD5 hash of the string $username:Ganeti Remote API:$password (e.g. echo -n 'jack:Ganeti Remote API:abc123' | openssl md5) [1] and prefix it with {ha1}. Using the scheme prefix for all passwords is recommended. Scheme prefixes are not case sensitive.

Example:

# Give Jack and Fred read-only access
jack abc123
fred {cleartext}foo555

# Give write access to an imaginary instance creation script
autocreator xyz789 write

# Hashed password for Jessica
jessica {HA1}7046452df2cbb530877058712cf17bd4 write
[1] Using the MD5 hash of username, realm and password is described in RFC 2617 ("HTTP Authentication"), sections 3.2.2.2 and 3.3. The reason for using it over another algorithm is forward compatibility. If ganeti-rapi were to implement HTTP Digest authentication in the future, the same hash could be used. In the current version ganeti-rapi's realm, Ganeti Remote API, can only be changed by modifying the source code.

Protocol

The protocol used is JSON over HTTP designed after the REST principle. HTTP Basic authentication as per RFC 2617 is supported.

HTTP requests with a body (e.g. PUT or POST) require the request header Content-type be set to application/json (see RFC 2616 (HTTP/1.1), section 7.2.1).

A note on JSON as used by RAPI

JSON as used by Ganeti RAPI does not conform to the specification in RFC 4627. Section 2 defines a JSON text to be either an object ({"key": "value", …}) or an array ([1, 2, 3, …]). In violation of this RAPI uses plain strings ("master-candidate", "1234") for some requests or responses. Changing this now would likely break existing clients and cause a lot of trouble.

Unlike Python's JSON encoder and decoder, other programming languages or libraries may only provide a strict implementation, not allowing plain values. For those, responses can usually be wrapped in an array whose first element is then used, e.g. the response "1234" becomes ["1234"]. This works equally well for more complex values. Example in Ruby:

require "json"

# Insert code to get response here
response = "\"1234\""

decoded = JSON.parse("[#{response}]").first

Short of modifying the encoder to allow encoding to a less strict format, requests will have to be formatted by hand. Newer RAPI requests already use a dictionary as their input data and shouldn't cause any problems.

PUT or POST?

According to RFC 2616 the main difference between PUT and POST is that POST can create new resources but PUT can only create the resource the URI was pointing to on the PUT request.

Unfortunately, due to historic reasons, the Ganeti RAPI library is not consistent with this usage, so just use the methods as documented below for each resource.

For more details have a look in the source code at lib/rapi/rlib2.py.