Integrating OCS Inventory with Rundeck

I’ve been on a DevOps journey for a while now. If you’re in a similar place – am I just a dullard, or is it slow going?!

I work mainly at the Ops side of the equation, in an environment that strongly favours open source solutions. Most recently I’ve been focusing on automating asset management/inventory. For this, OCS Inventory NG fits the bill well. The interface isn’t that slick, and I couldn’t for the life of me get the Active Directory integration working, but for collecting software and hardware inventory, it’s the bomb.

In a mixed estate (Windows/Linux/Mac), I can use Group Policy, Rudder and Meraki respectively to force the OCS agent onto endpoints. Which means I can just sit back and let my CMDB populate itself. Awesome. (Because who’s got time to keep these things updated themselves, right?)

This inventory automation was a prerequisite for Rundeck. Since you’re here, you probably already know, but just in case you don’t: Rundeck is a fantastic tool for wrapping policies around any task you can dream of. You can use it for centralised job scheduling, you can use it to allow your developers to reboot servers without giving them SSH access, and you have ACLs and a full audit trail for everything.

For Rundeck to be any use, it needs a list of servers to control, which brings me back to OCS Inventory. OCS knows about my servers, so let’s just get Rundeck talking to OCS. Then Rundeck will have an always-up-to-date list of server endpoints, with no human input required. Marvellous.

My weapon of choice here is PHP, because I know it and because all the required components for this script are already installed on the OCS Inventory server. The simple prerequisites:

  1. Ensure all servers are tagged on their way into OCS Inventory. I use the installation switch /TAG="SERVER" with the OCS agent.
  2. On the OCS Inventory server, create a read-only MySQL user for the script. I created the user “[email protected]” (so its purpose was clear) and gave it the minimum permissions – SELECT on the accountinfo and hardware OCS tables.

I created a PHP script in the OCS Inventory web root. For me that’s at /usr/share/ocsinventory-reports/ocsreports. I called the script rundeck-xml.php. And here’s the code:

<?php
// OCS inventory integration into Rundeck.
$host = "127.0.0.1";
$db = "ocsweb";
$user = "rundeck";
$pwd = "PASSWORD GOES HERE";

$link = mysqli_connect($host, $user, $pwd, $db);

if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}


// Select all devices tagged as "SERVER" in the OCS database
$query = "
    SELECT `NAME`, `WORKGROUP`, `OSNAME`, `OSVERSION`, `OSCOMMENTS`, `IPADDR`, `DESCRIPTION`, `ARCH` FROM hardware
    LEFT JOIN accountinfo ON hardware.`ID` = accountinfo.`HARDWARE_ID`
    WHERE accountinfo.`TAG` LIKE '%SERVER%'
    ORDER BY `NAME`
";


if($result = mysqli_query($link, $query)) {
    // Start XML
    header('Content-type: text/xml');
    echo "<project>\n";

    while($row = mysqli_fetch_object($result))
    {
        echo "    <node name=\"{$row->NAME}\" type=\"node\"\n";
        echo "        hostname=\"{$row->NAME}.{$row->WORKGROUP}\"\n";
        echo "        osName=\"{$row->OSNAME}\"\n";
        echo "        osVersion=\"{$row->OSVERSION}\"\n";
        // Architecture is either in the DESCRIPTION field (for Ubuntu) or ARCH field (for Windows)
        $arch = (isset($row->ARCH) ? $row->ARCH : $row->DESCRIPTION);
        echo "        osArch=\"$arch\"\n";
        echo "    />\n";
    }
    mysqli_free_result($result);

    echo "</project>\n";
}
?>

Possibly not the most elegant code, but it gets the job done. Further security is left as an exercise for the reader. 😉

Referring to the database and the RESOURCE-XML Rundeck schema, you can extend this script to suit your needs. Add this to your Rundeck project configuration as an external resource model, with the URL of the above script. E.g. http://ocsserver.domain.com/ocsreports/rundeck-xml.php. All being well, every server from OCS Inventory will now appear as a node in Rundeck.

Leave a Reply

Your email address will not be published. Required fields are marked *