June 6, 2012

Classes
Tags blog

OS Reload, OS Reload, OS Reload...

<p>Need to OS Reload many servers you say!?!</p> <p>Do you have a large number of servers whom could use fresh start? A

Need to OS Reload many servers you say!?!

Do you have a large number of servers whom could use fresh start? A 1/2 dozen boxes which can now be re-purposed? Maybe want to upgrade to the latest version of Debian and just couldn't be bothered with apt?

What ever the series of events which have led to this moment, you now find yourself in need of a way to submit a seemingly limitless number of OS Reloads and the threat of carpel tunnel makes you weary of accomplishing this task the old(or would that be new) fashioned way.

Difficulty bonus: providing primary IP addresses to identify servers, have all servers provisioned with the same operating system.

Let us start by getting the usual out of the way...
API Library: Check
API User: Check
API Key: Check
API Service: SoftLayer_Hardware_Server


require_once('SoftLayer/SoapClient.class.php');
 
/**
 * Set your SoftLayer API username and key.
 */
$apiUsername = '';
$apiKey = '';
 
$hardwareClient = SoftLayer_SoapClient::getClient('SoftLayer_Hardware_Server', NULL, $apiUsername, $apiKey);

Add in a pinch of IP addresses, set aside some space to store information about our servers and define what OS we want.

$ipsToReload = array('1.1.1.1', '2.2.2.2', '3.3.3.3');
$operatingSystem = 'CentOS 6.0 - Minimal Install (32 bit)';
$serversToReload = array();

When an OS Reload is submitted, by default it will use the pre-existing operating system. If we wish to change that operating system during the reload, we need to submit the itemPrice associated with the operating system. Each package has unique IDs for each item, so it is necessary that our script is not specific to any one package.

This object mask and accompanying foreach loops will get the item price specific to the package of the server. We then store this price ID in $serversToReload along with the server's ID.

$objectMask = new SoftLayer_ObjectMask();
$objectMask->billingItem->package->items->prices;
$hardwareClient->setObjectMask($objectMask);
foreach ($ipsToReload as $key => $ipToReload) {
    $server = $hardwareClient->findByIpaddress($ipToReload);
    $serversToReload[$key]['id'] = $server->id;
    foreach ($server->billingItem->package->items as $item) {
        if ($item->description = = $operatingSystem) {
            $serversToReload[$key]['priceId'] = $item->prices[0]->id;
            break;
        } else {
            $serversToReload[$key]['priceId'] = 'None found';
        }
    }
}

We now have everything we need to give these servers a makeover. So let's create a place to put those servers which have decided not to join the party.

$failedReloads = array();

Loop through our array which is holding all of our server and price IDs. We only need to perform a reload if we have a price ID

foreach ($serversToReload as $soonToBeReloadedServer) {
    if ($soonToBeReloadedServer['priceId'] != 'None found') {

Nifty trick: When needing to call a method which requires init parameters on multiple objects it is not necessary to create a SOAP client for each object. You can reuse a previously defined client by calling setInitParameter with a parameter of the new init parameter.

        $hardwareClient->setInitParameter($soonToBeReloadedServer['id']);

Time to create our configuration object, which will contain an array which defines the priceId for the new operating system. We then pass that config into SoftLayer_Hardware_Server::reloadOperatingSystem. The first parameter we pass is the string 'FORCE'. This is necessary only if we wish to bypass the confirmation step which can be read about in more detail here. Also, don't forget to group the ID-less servers.

        $config = new stdClass();
        $config->itemPrices = array();
        $config->itemPrices[] = (object)array('id' => $soonToBeReloadedServer['priceId']);
        $hardwareClient->reloadOperatingSystem('FORCE', $config); 
    } else {
        $failedReloads[] = $soonToBeReloadedServer;
    }
}

You can find the full version of this script here and checkout our other projects on our GitHub profile.

Have a SLAPI problem that needs solving? Let me know!