Virtualization
banshee/virtualization-collection/virtualization/vsphere/https/vcenter-7.0u2/
datastores
Whether each datastore of a VMware vCenter is accessible, and its space, by the vCenter REST API.
by banshee1 installation2 versions
v2Latest
Published on October 28, 2026. One naming convention across collections; documentation completed.
// The datastores of a VMware vCenter, by its REST API (GET /api/vcenter/datastore, then GET
// /api/vcenter/datastore/<id> for each), which vCenter serves under /api from vSphere 7.0 U2: whether each is
// accessible, and its space.
// The address of the API is the vCenter's, the host's: https://<host:address>/api/.
need('protocol:http');
$address = need('host:address');
$user = need('protocol:http:user');
$password = need('protocol:http:password');
per('datastore', 'Datastores');
output('state', 'text', array('label' => 'State', 'per' => 'datastore'));
output('used-percent', 'number', array('label' => 'Used space', 'unit' => '%', 'per' => 'datastore'));
output('free', 'number', array('label' => 'Free space', 'unit' => 'GiB', 'per' => 'datastore'));
output('size', 'number', array('label' => 'Size', 'unit' => 'GiB', 'per' => 'datastore'));
watch.state('inaccessible', 'Datastore inaccessible', 'state', array('critical' => array('inaccessible')));
watch.above('used', 'Used space', 'used-percent', array('warning' => 80, 'critical' => 90));
watch.above('full-soon', 'Full within a week', 'used-percent', array('warning' => 99, 'ahead' => '7 d'));
watch.missing('missing', 'Datastore missing', 'state', array('enabled' => false));
// Log in: POST /api/session, the account in Basic, answers 201 and the id of the session as a JSON text. The
// answer is not secret by itself, the password having gone in Basic, but the id is: secret.mark keeps it out
// of every value and message, and the cache keeps it encrypted on the poller, 50 minutes at most.
function login($address, $user, $password) {
$answer = http.post('https://' . $address . '/api/session', '', user=$user, password=$password);
if ($answer['status'] == 401 || $answer['status'] == 403) {
fail('misconfigured', 'vCenter refuses the account, code ' . $answer['status']);
}
if ($answer['status'] != 201) {
fail('unreachable', 'vCenter answers the login with code ' . $answer['status'],
'vCenter serves its REST API under /api from vSphere 7.0 U2.');
}
$session = secret.mark(json.read($answer['body']));
cache.set('session', $session, 3000);
return $session;
}
// One GET with the session kept in the cache; a session vCenter no longer knows (expired, vCenter restarted)
// answers 401, and the collector logs in again, once.
function api_get($address, $path, $user, $password) {
if (cache.has('session')) {
$session = cache.get('session');
} else {
$session = login($address, $user, $password);
}
$answer = http.get('https://' . $address . $path, headers=array('vmware-api-session-id' => $session));
if ($answer['status'] == 401) {
$session = login($address, $user, $password);
$answer = http.get('https://' . $address . $path, headers=array('vmware-api-session-id' => $session));
}
if ($answer['status'] == 403) {
fail('misconfigured', 'The account may not read ' . $path . ', code 403');
}
if ($answer['status'] != 200) {
fail('unreachable', 'vCenter answers ' . $path . ' with code ' . $answer['status']);
}
return json.read($answer['body']);
}
// The list: [{"datastore": "datastore-12", "name": "ds-ssd-01", "type": "VMFS", "free_space": 536870912000,
// "capacity": 1099511627776}], in bytes. Each datastore then: {"name": ..., "accessible": true, "free_space":
// ...}, the only place the API says whether it is accessible. Two datastores of one name in two
// datacenters each keep their own, the second carrying its id.
$datastores = api_get($address, '/api/vcenter/datastore', $user, $password);
if (list.count($datastores) == 0) {
fail('misconfigured', 'vCenter lists no datastore', 'The account sees only the datastores its role is set on.');
}
$seen = array();
foreach ($datastores as $datastore) {
$name = $datastore['name'];
if (list.has($seen, $name)) {
$name = $name . ' #' . $datastore['datastore'];
}
$seen[$name] = true;
$info = api_get($address, '/api/vcenter/datastore/' . url.encode($datastore['datastore']), $user, $password);
$state = 'inaccessible';
if (list.get($info, 'accessible', false)) {
$state = 'accessible';
}
value('state', $state, $name);
// vCenter leaves the space out while it does not know it, an inaccessible datastore among them.
if (!list.has($datastore, 'capacity') || !list.has($datastore, 'free_space') || $datastore['capacity'] <= 0) {
continue;
}
$size = $datastore['capacity'];
$free = $datastore['free_space'];
value('used-percent', number.round(100 * ($size - $free) / $size, 1), $name);
value('free', number.round($free / 1073741824, 1), $name);
value('size', number.round($size / 1073741824, 1), $name);
}