banshee is under active development: collectors will keep changing, and a version you publish will likely need adjustments. For stable use, wait for version 1.0.0.

Cloud

banshee/cloud-collection/cloud/scaleway/https/

databases

The status of each managed database (PostgreSQL, MySQL) of a Scaleway region, by its API.

  • cloud
  • scaleway
  • databases
  • rdb
  • postgresql
  • mysql
  • https
  • api

by banshee1 installation1 version

v1Latest

Published on October 27, 2026. First version.

Keen 1.0.0 · 74 lines
// The managed databases of a Scaleway region (Managed Databases for PostgreSQL and MySQL), by their API with an
// API key: the status of each database instance.
// Reads GET https://api.scaleway.com/rdb/v1/regions/<region>/instances, page after page.
need('protocol:http');
$key = need('protocol:http:token');
$region = variable('scaleway:region', 'text', array(
    'label'   => 'Region',
    'help'    => 'The region of the databases: fr-par, nl-ams or pl-waw.',
    'default' => 'fr-par',
));

per('database', 'Databases');
output('status', 'text', array('label' => 'Status', 'per' => 'database'));

watch.state('down', 'Database in error', 'status', array('critical' => array('error', 'disk_full', 'locked')));
watch.expect('not-ready', 'Database not ready', 'status', array(
    'warning' => array('ready', 'backuping', 'snapshotting'),
    'for'     => '3 runs',
));
watch.missing('missing', 'Database missing', 'status', array('enabled' => false));

// One GET on the API of Scaleway, the secret key of the API key in the header X-Auth-Token; the answer is not
// secret, its body having carried none.
function api_get($url, $key) {
    $answer = http.get($url, headers=array('X-Auth-Token' => $key));
    if ($answer['status'] == 401) {
        fail('misconfigured', 'Scaleway refuses the API key, code 401');
    }
    if ($answer['status'] == 403) {
        fail('misconfigured', 'The API key may not list the databases, code 403');
    }
    if ($answer['status'] == 400 || $answer['status'] == 404) {
        fail('misconfigured', 'Scaleway refuses to list the databases, code ' . $answer['status'], 'Check the region.');
    }
    if ($answer['status'] != 200) {
        fail('unreachable', 'Scaleway answers the list of the databases with code ' . $answer['status']);
    }
    return json.read($answer['body']);
}

// The region goes into the path of the address: it must be a name.
if (list.count(text.match($region, '^[a-z0-9-]+$')) == 0) {
    fail('misconfigured', 'The region holds other characters than lower-case letters, digits and hyphens');
}

// {"instances": [{"id": "…", "name": "main-db", "status": "ready", "engine": "PostgreSQL-16", …}],
// "total_count": 3}, a page of 100 at a time: a page shorter than that is the last. status is ready,
// provisioning, configuring, initializing, deleting, error, autohealing, locked, disk_full, backuping,
// snapshotting, restarting or unknown.
$databases = array();
$page = 1;
while (true) {
    $answer = api_get('https://api.scaleway.com/rdb/v1/regions/' . $region . '/instances?'
        . url.query(array('page' => $page, 'page_size' => 100)), $key);
    $found = list.get($answer, 'instances', array());
    foreach ($found as $database) {
        $databases = list.add($databases, $database);
    }
    if (list.count($found) < 100) {
        break;
    }
    $page = $page + 1;
}

// A database is named by its name; two of one name each keep their own, the second carrying its id.
$seen = array();
foreach ($databases as $database) {
    $name = $database['name'];
    if (list.has($seen, $name)) {
        $name = $name . ' #' . $database['id'];
    }
    $seen[$name] = true;
    value('status', $database['status'], $name);
}