private static function associateIpAddress(\DBServer $dbServer, $ipAddress, $allocationId = null)
{
$platform = PlatformFactory::NewPlatform($dbServer->platform);
$cs = $dbServer->GetEnvironmentObject()->cloudstack($dbServer->platform);
$assign_retries = 1;
$retval = false;
// Remove OLD static NAT
if ($dbServer->remoteIp) {
try {
$requestObject = new ListIpAddressesData();
$requestObject->ipaddress = $dbServer->remoteIp;
$info = $cs->listPublicIpAddresses($requestObject);
$info = $info[0];
if ($info->issystem && $info->isstaticnat) {
$cs->firewall->disableStaticNat($info->id);
\Scalr::getContainer()->logger('Cloudstack_Helper')->warn("[STATIC_NAT] Removed old IP static NAT from IP: {$info->id}");
}
} catch (Exception $e) {
\Scalr::getContainer()->logger('Cloudstack_Helper')->error("[STATIC_NAT] Unable to disable old static NAT: {$e->getMessage()}");
}
}
$requestObject = new ListIpAddressesData();
$requestObject->ipaddress = $ipAddress;
$info = $cs->listPublicIpAddresses($requestObject);
$info = $info[0];
$oldVM = $info->virtualmachinedisplayname;
if ($info->isstaticnat) {
\Scalr::getContainer()->logger('Cloudstack_Helper')->warn("[STATIC_NAT] IP {$ipAddress} associated with another VM. Disabling Static NAT.");
try {
$result = $cs->firewall->disableStaticNat($allocationId);
for ($i = 0; $i <= 20; $i++) {
$res = $cs->queryAsyncJobResult($result->jobid);
if ($res->jobstatus != 0) {
\Scalr::getContainer()->logger('Cloudstack_Helper')->warn("[STATIC_NAT] After {$i}x2 seconds, IP {$ipAddress} is free and ready to use.");
//UPDATING OLD SERVER
try {
$oldDbServer = \DBServer::LoadByID($oldVM);
$ips = $platform->GetServerIPAddresses($oldDbServer);
$oldDbServer->remoteIp = $ips['remoteIp'];
$oldDbServer->save();
} catch (Exception $e) {
}
break;
}
sleep(2);
}
} catch (Exception $e) {
\Scalr::getContainer()->logger('Cloudstack_Helper')->error("[STATIC_NAT] Unable to disable static NAT: {$e->getMessage()}");
}
}
$assignRetries = 0;
while (true) {
try {
$assignRetries++;
$cs->firewall->enableStaticNat(array('ipaddressid' => $allocationId, 'virtualmachineid' => $dbServer->GetCloudServerID()));
$retval = true;
break;
} catch (Exception $e) {
if (!stristr($e->getMessage(), "already assigned to antoher vm") || $assignRetries == 3) {
\Scalr::getContainer()->logger('Cloudstack_Helper')->error("[STATIC_NAT] Unable to enable static NAT ({$assignRetries}): {$e->getMessage()}");
throw new Exception($e->getMessage());
} else {
sleep(1);
}
}
}
return $retval;
}