PaaS API

Introduction

The Gandi PaaS API provides a set of remote requests to manage your PaaS instances.

Connect to the API server

The Gandi PaaS API is accessible through a set of XML-RPC calls:

>>> import xmlrpc.client
>>> api = xmlrpc.client.ServerProxy('https://rpc.gandi.net/xmlrpc/')
>>>
>>> apikey = 'my 24-character API key'
>>>
>>> # Now you can call API methods.
>>> # You must authenticate yourself by passing
>>> # the API key as the first method's argument
>>> version = api.version.info(apikey)

Note

In Python, use the xmlrpcclient module from the standard library.

<?php
// Library installed from PEAR
require_once 'XML/RPC2/Client.php';

// The first step is to connect to the API
$version_api = XML_RPC2_Client::create(
    'https://rpc.gandi.net/xmlrpc/',
    array( 'prefix' => 'version.', 'sslverify' => True )
);

// Warning !
// PEAR::XML_RPC2 checks the SSL certificate with Curl
// Curl has its own CA bundle so you may :
// * disable the 'sslverify' option: leads to security issue
// * enable the 'sslverify' option (default) and add the Gandi
// SSL certificate to the Curl bundle: best choice for security
// See: https://curl.haxx.se/docs/sslcerts.html

$apikey = 'my 24-character API key';

// Now you can call API method
// You must authenticate yourself by passing the API key
// as the first method's argument
$result = $version_api->info($apikey);

// Warning !
// PEAR::XML_RPC2 has known bugs on methods calls
// See https://pear.php.net/bugs/bug.php?id=13963
// You may use this call instead of the above one :
// $result = $version_api->__call("info", $apikey);

// dump the result
print_r($result);
?>

Note

In PHP 5, use the XML_RPC2 package from pear.

XML_RPC2 works with ‘prefix’ in order to bind to namespace. The ‘prefix’ isn’t editable, so you have to instanciante a client by namespace.

> var xmlrpc = require('xmlrpc')
> var api = xmlrpc.createSecureClient({
...  host: 'rpc.gandi.net',
...  port: 443,
...  path: '/xmlrpc/'
... })
>
> var apikey = 'my 24-character API key'
>
> // Now you can call API methods.
> // You must authenticate yourself by passing the API key
> // as the first method's argument
> api.methodCall('version.info', [apikey], function (error, value) {
...  console.dir(value)
... })

Note

With NodeJS, use the npm xmlrpc package.

use XML::RPC;

my $api = XML::RPC->new('https://rpc.gandi.net/xmlrpc/');

my $apikey = 'my 24-character API key';

# Now you can call API methods.
# You must authenticate yourself by passing the API key
# as the first method's argument
my $version = $api->call( 'version.info', $apikey );

Note

With perl, use the cpan xml::rpc package.

require 'xmlrpc/client'

server = XMLRPC::Client.new2('https://rpc.gandi.net/xmlrpc/')

apikey = 'my 24-character API key'

# Now you can call API methods.
# You must authenticate yourself by passing the API key
# as the first method's argument
version = server.call("version.info", apikey)

Note

With ruby, use the xmlrpc/client module from the standard library. Ruby does not support gzip by default, the ZlibParserDecorator is used to enabled with Ruby >1.9.

For older ruby version, neither set the http_header_extra nor the parser.

Note

To avoid RuntimeError with ruby >= 1.9, add:

XMLRPC::Config.module_eval {
    remove_const(:ENABLE_NIL_PARSER)
    const_set(:ENABLE_NIL_PARSER, true)
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <xmlrpc.h>
#include <xmlrpc_client.h>

#define CLIENT_NAME             "Documentation Client"
#define CLIENT_VERSION          "0.1"
#define CLIENT_USERAGENT        CLIENT_NAME "/" CLIENT_VERSION

#define SERVER_URL              "https://rpc.gandi.net/xmlrpc/"

int     client_connect(xmlrpc_env *);
void    client_check_fault(xmlrpc_env *);

int
main(int argc, char **argv)
{
        xmlrpc_env      env;
        xmlrpc_value    *apikey, *rv;

        client_connect(&env);

        apikey = xmlrpc_build_value(&env, "(s)", "my 24-character API key");
        rv = xmlrpc_client_call_params(&env, SERVER_URL, "version.info", apikey);
        client_check_fault(&env);

        xmlrpc_DECREF(rv);
        xmlrpc_DECREF(apikey);

        xmlrpc_env_clean(&env);
        xmlrpc_client_cleanup();

        return (0);
}

int
client_connect(xmlrpc_env *env)
{
        struct xmlrpc_clientparms clientp;
        struct xmlrpc_curl_xportparms curlp;

        curlp.network_interface = NULL;         /* use curl's default */
        curlp.ssl_verifypeer = 1;               /* Gandi API CA must be present */
        curlp.ssl_verifyhost = 2;
        curlp.user_agent = CLIENT_USERAGENT;    /* XML-RPC requirement */

        clientp.transport = "curl";
        clientp.transportparmsP = &curlp;
        clientp.transportparm_size = XMLRPC_CXPSIZE(user_agent);

        xmlrpc_env_init(env);
        xmlrpc_client_init2(env, XMLRPC_CLIENT_NO_FLAGS, CLIENT_NAME,
            CLIENT_VERSION, &clientp, XMLRPC_CPSIZE(transportparm_size));
        client_check_fault(env);

        return (1);
}

void
client_check_fault(xmlrpc_env *env)
{
        if (env->fault_occurred) {
                fprintf(stderr, "XML-RPC Fault: %s (%d)\n", env->fault_string,
                    env->fault_code);
                exit(1);
        }
}

Note

With C, use the xmlrpc-c library.

Note

the Gandi PaaS API does not use the HTTP authentication scheme. It uses a custom authentication mechanism based on the API key.

PaaS Management

List your PaaS Instances

To list the PaaS instances associated to an Account you can use the method paas.list().

paas.list() returns a list of dictionnary that each describe a Paas instance.

You can filter the result by providing the function with a dictionnary of filter terms, such as the size of the instance.

>>> api.paas.list(apikey)
[{ 'catalog_name': 'phpmysql_m',
   'data_disk_additional_size': 0,
   'datacenter_id': 1,
   'date_end': <DateTime '20111014T14:36:30' at 7f96c47a0368>,
   'date_end_commitment': None,
   'date_start': <DateTime '20110914T14:36:30' at 7f96c47a03b0>,
   'id': 1,
   'name': 'Mon PaaS',
   'need_upgrade': True,
   'servers': [{'id': 1}],
   'size': 'm',
   'state': 'running',
   'type': 'phpmysql'
}]
>>> api.paas.list(apikey, {'size':'s'})
[]

Count your PaaS Instances

To count the PaaS instances you own, just call the paas.count() method:

You can filter the result returned by paas.count() by providing it with a dictionnary of filter terms, such as the size of the instance.

>>> api.paas.count(apikey)
1
>>> api.paas.count(apikey, {'size':'s'})
0

Get info on a PaaS Instance

Get info on an instance with method paas.info() method:

>>> api.paas.info(apikey, 1)
{
    'autorenew': None,
    'catalog_name': 'phpmysql_m',
    'data_disk_additional_size': 0,
    'datacenter': {'country': 'France', 'id': 1, 'iso': 'FR', 'name': 'eqx pa2'},
    'date_end': <DateTime '20111014T14:36:30' at 7f96c47a0440>,
    'date_start': <DateTime '20110914T14:36:30' at 7f96c47a0488>,
    'ftp_server': '10.0.0.10',
    'id': 1,
    'name': 'Mon PaaS',
    'owner': {'handle': 'XXX-GANDI', 'id': 1},
    'servers': [{
        'graph_urls':  {'vcpu': [''], 'vdi': [''], 'vif': ['']},
        'id': 1,
        'uuid':1}],
    'size': 'm',
    'state': 'running',
    'type': 'phpmysql',
    'user': 2316,
    'vhosts': [{
        'date_creation': <DateTime '20110914T14:36:30' at 7f96c47a03f8>,
        'id': 1,
        'name': 'vhost.test.fr',
        'state': 'running'
    }
]}

Create a PaaS Instance

To create a PaaS instance, use the paas.create() method by specifying a name, a size (one of s, m, l, xl, xxl), a type (phpmysql), a list of vhosts, a duration, and a password. paas.create() can also take an optional disk size via the quantity attribute:

>>> paas_spec = {
    'name': 'My PaaS',
    'size': 'm',
    'type': 'phpmysql',
    'datacenter_id': 1,
    'vhosts': ['vhost.test.fr'],
    'quantity': 0,
    'duration': '3m',
    'password': 'xxxxxxxxxx'}
>>> ops = api.paas.create(apikey, paas_spec)
>>> len(ops)
3
>>> ops[0]['type']
'paas_vm_create'
>>> ops[1]['type']
'paas_disk_create'
>>> ops[2]['type']
'rproxy_create'

This will create an instance called “My PaaS” of type “phpmysql”, size “m”. You can refer to this document for a full description of the different sizes. The default is 10 GB of disk for 3 Months on one attached host.

Update a PaaS Instance

To update an instance, use the paas.update() method. You can specify a size, a quantity (of additional disk size in Go) and a password: paas.update() is given an apikey, the id of a PaaS instance and a dictionnary of updatable items.

The items can be either the size of the instance, the password used on it, or

>>> op = api.paas.update(apikey, paas_id, {'size':'xl'})
>>> ops[0]['type']
'paas_vm_update'

Delete a PaaS Instance

To delete an instance, use the paas.delete() method:

>>> op = api.paas.delete(apikey, paas_id)
>>> op['type']
'paas_delete'

Additional information about security

You can run a PaaS instance hosted at Gandi even if your domain is not registered with Gandi and/or if it is not using Gandi’s nameservers. However, Gandi must verify that you have administrative privileges on the domain. Thus, Gandi will check for a DNS record on the vhost address that you want to bind to a PaaS instance.

>>> paas_spec = {
    'name': 'My PaaS',
    'size': 'm',
    'type': 'phpmysql',
    'datacenter_id': 1,
    'vhosts': ['vhost.test.fr'],
    'quantity': 0,
    'duration': '3m',
    'password': 'xxxxxxxxxx',
    '--dry-run': True}
>>> ops = api.paas.create(apikey, paas_spec)
[{'attr': ['vhost.test.fr', 'vhost=2e5d8f0899053fffcd3ecf4ac5a6433b'],
  'error': 'EC_TXT+EC_MISSINGMANDATORY',
  'field': 'vhosts',
  'field_type': None,
  'reason': 'You must put a TXT value in your zone'}]

The DNS zone must be modified to contain a record like the one below:

10800 IN TXT "vhost=2e5d8f0899053fffcd3ecf4ac5a6433b"

You can also add a new virtual host:

>>> api.paas.vhost.create(key, {'paas_id': 1,
    'vhost': 'vhost.test.fr',
    '--dry-run': True})