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.

Hardware

banshee/hardware-collection/hardware/ibm/https/hmc/

memory-allocation

The share of the memory taken, and the memory free, of each IBM Power server an HMC manages, by the HMC REST API.

  • hardware
  • ibm
  • power
  • hmc
  • managed-system
  • memory
  • capacity
  • https

by banshee0 installations2 versions

v2Latest

Published on October 28, 2026. One naming convention across collections; documentation completed.

Keen 1.0.0 · 121 lines
// The memory of the IBM Power servers a Hardware Management Console (HMC) manages, by its REST API: for each
// managed system, the share of its configurable memory already taken, and the memory still free to assign
// to a partition. It is an allocation, not a load: the use of the memory inside the
// partitions is not read. The address is the HMC's, the host's: https://<host:address>/rest/api/.
need('protocol:http');
$address = need('host:address');
$user = need('protocol:http:user');
$password = need('protocol:http:password');

per('system', 'Managed systems');
output('assigned', 'number', array('label' => 'Memory assigned', 'unit' => '%', 'per' => 'system'));
output('available', 'number', array('label' => 'Memory free', 'unit' => 'MiB', 'per' => 'system'));

watch.above('assigned-high', 'Memory nearly all assigned', 'assigned', array(
    'help'    => 'Raises when little memory is left to start or grow a partition.',
    'warning' => 90,
    'enabled' => false,
));
watch.missing('missing', 'System missing', 'assigned', array('enabled' => false));

// Opens a session: PUT /rest/api/web/Logon, the account in the XML body IBM documents, each value passed by
// xml.escape. The HMC answers a LogonResponse whose X-API-Session is the session; the answer is secret, its
// body having carried the password. The session is kept in the cache, encrypted on the poller, so that one
// session serves every run: IBM warns that sessions opened and never closed wear the HMC's memory.
function logon($address, $user, $password) {
    $body = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
        . '<LogonRequest xmlns="http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/" schemaVersion="V1_1_0">'
        . '<Metadata><Atom/></Metadata>'
        . '<UserID kb="CUR" kxe="false">' . xml.escape($user) . '</UserID>'
        . '<Password kb="CUR" kxe="false">' . xml.escape($password) . '</Password>'
        . '</LogonRequest>';
    $answer = http.put('https://' . $address . '/rest/api/web/Logon', $body,
        headers=array('Content-Type' => 'application/vnd.ibm.powervm.web+xml; type=LogonRequest'));
    if ($answer['status'] == 401 || $answer['status'] == 403) {
        fail('misconfigured', 'The HMC refuses the account, code ' . $answer['status']);
    }
    if ($answer['status'] != 200) {
        fail('unreachable', 'The HMC answers the logon with code ' . $answer['status']);
    }
    $logon = xml.read($answer['body']);
    $session = $logon['LogonResponse'][0]['X-API-Session'][0]['#text'];
    cache.set('session', $session, 604800);
    return $session;
}

// Returns the entries of an Atom feed of the HMC, read by its path (/rest/api/uom/...), with the session kept
// in the cache. A session the HMC no longer knows (expired, HMC restarted) is refused, 401 or 403: it is
// closed by DELETE /rest/api/web/Logon, whatever its answer, and replaced by a new one, once. The HMC answers
// 204, without a body, for a feed with no entry. Each success keeps the session in the cache seven more days.
function hmc_entries($address, $path, $user, $password) {
    if (cache.has('session')) {
        $session = cache.get('session');
    } else {
        $session = logon($address, $user, $password);
    }
    $answer = http.get('https://' . $address . $path, headers=array('X-API-Session' => $session));
    if ($answer['status'] == 401 || $answer['status'] == 403) {
        http.delete('https://' . $address . '/rest/api/web/Logon', headers=array('X-API-Session' => $session), errors=$err);
        $session = logon($address, $user, $password);
        $answer = http.get('https://' . $address . $path, headers=array('X-API-Session' => $session));
    }
    if ($answer['status'] == 401 || $answer['status'] == 403) {
        fail('misconfigured', 'The account may not read ' . $path . ', code ' . $answer['status']);
    }
    if ($answer['status'] == 204) {
        cache.set('session', $session, 604800);
        return array();
    }
    if ($answer['status'] != 200) {
        fail('unreachable', 'The HMC answers ' . $path . ' with code ' . $answer['status']);
    }
    cache.set('session', $session, 604800);
    $feed = xml.read($answer['body']);
    return list.get($feed['feed'][0], 'entry', array());
}

// Returns the first child of that name, an empty array when the HMC does not give it.
function child($element, $name) {
    $children = list.get($element, $name, array());
    if (list.count($children) == 0) {
        return array();
    }
    return $children[0];
}

// Returns the text of the first child of that name, '' when the HMC does not give it. The HMC writes each
// value with its attributes: <InstalledSystemMemory kb="ROR" kxe="false">98304</InstalledSystemMemory>.
function child_text($element, $name) {
    return list.get(child($element, $name), '#text', '');
}

// <ManagedSystem:ManagedSystem ...> <SystemName>p10-a</SystemName> <AssociatedSystemMemoryConfiguration>
// <ConfigurableSystemMemory>98304</...> <CurrentAvailableSystemMemory>88832</...>, in the HMC's MB, whole
// numbers of memory regions of 256, powers of two: returned as MiB, the binary unit they point to. The
// configurable memory that is not available is taken. A system that gives no configurable memory (powered
// off) returns nothing. Two systems of one name each keep their own, the second carrying
// its UUID.
$systems = hmc_entries($address, '/rest/api/uom/ManagedSystem', $user, $password);
if (list.count($systems) == 0) {
    fail('misconfigured', 'The HMC lists no managed system', 'The account sees only the systems its resource role is set on.');
}
$seen = array();
foreach ($systems as $entry) {
    $system = $entry['content'][0]['ManagedSystem:ManagedSystem'][0];
    $name = child_text($system, 'SystemName');
    if ($name == '' || list.has($seen, $name)) {
        $name = $name . ' #' . $entry['id'][0];
    }
    $seen[$name] = true;
    $memory = child($system, 'AssociatedSystemMemoryConfiguration');
    $configurable = child_text($memory, 'ConfigurableSystemMemory');
    $available = child_text($memory, 'CurrentAvailableSystemMemory');
    if ($configurable == '' || $available == '') {
        continue;
    }
    if ($configurable + 0 == 0) {
        continue;
    }
    value('assigned', number.round(($configurable - $available) * 100 / $configurable, 1), $name);
    value('available', $available, $name);
}