public static function setEipForServer(DBServer $dbServer)
{
$db = \Scalr::getDb();
try {
$dbFarm = DBFarm::LoadByID($dbServer->farmId);
$dbFarmRole = $dbServer->GetFarmRoleObject();
if (!$dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_USE_ELASIC_IPS)) {
return false;
}
$aws = $dbFarm->GetEnvironmentObject()->aws($dbFarmRole->CloudLocation);
$isVPC = $dbFarm->GetSetting(Entity\FarmSetting::EC2_VPC_ID);
} catch (Exception $e) {
\Scalr::getContainer()->logger(\LOG_CATEGORY::FARM)->fatal(new \FarmLogMessage($dbServer, sprintf(_("Cannot allocate elastic ip address for instance %s on farm %s (0)"), !empty($dbServer->serverId) ? $dbServer->serverId : null, !empty($dbFarm->Name) ? $dbFarm->Name : null)));
return false;
}
$ip = $db->GetRow("\n SELECT * FROM elastic_ips WHERE farmid=? AND ((farm_roleid=? AND instance_index=?) OR server_id = ?) LIMIT 1\n ", array($dbServer->farmId, $dbFarmRole->ID, $dbServer->index, $dbServer->serverId));
if ($ip['ipaddress']) {
if (!self::checkElasticIp($ip['ipaddress'], $aws)) {
\Scalr::getContainer()->logger(\LOG_CATEGORY::FARM)->warn(new \FarmLogMessage($dbServer, sprintf(_("Elastic IP '%s' does not belong to you. Allocating new one."), !empty($ip['ipaddress']) ? $ip['ipaddress'] : null)));
$db->Execute("DELETE FROM elastic_ips WHERE ipaddress=?", array($ip['ipaddress']));
$ip = false;
}
}
if ($ip && $ip['ipaddress'] == $dbServer->remoteIp) {
return $ip['ipaddress'];
}
// If free IP not found we must allocate new IP
if (!$ip) {
$alocatedIps = $db->GetOne("SELECT COUNT(*) FROM elastic_ips WHERE farm_roleid = ?", array($dbFarmRole->ID));
// Check elastic IPs limit. We cannot allocate more than 'Max instances' option for role
if (!$dbFarmRole->GetSetting(Entity\FarmRoleSetting::SCALING_ENABLED) || $alocatedIps < $dbFarmRole->GetSetting(Entity\FarmRoleSetting::SCALING_MAX_INSTANCES)) {
try {
$domain = null;
if ($isVPC) {
$domain = 'vpc';
}
$address = $aws->ec2->address->allocate($domain);
} catch (Exception $e) {
\Scalr::getContainer()->logger(\LOG_CATEGORY::FARM)->error(new \FarmLogMessage($dbServer, sprintf(_("Cannot allocate new elastic ip for instance '%s': %s"), !empty($dbServer->serverId) ? $dbServer->serverId : null, $e->getMessage())));
return false;
}
// Add allocated IP address to database
$db->Execute("\n INSERT INTO elastic_ips\n SET env_id=?,\n farmid=?,\n farm_roleid=?,\n ipaddress=?,\n clientid=?,\n instance_index=?,\n allocation_id=?,\n state='0', server_id=''\n ", array($dbServer->envId, $dbServer->farmId, $dbServer->farmRoleId, $address->publicIp, $dbServer->clientId, $dbServer->index, $address->allocationId));
$ip = array('ipaddress' => $address->publicIp, 'allocation_id' => $address->allocationId);
\Scalr::getContainer()->logger(\LOG_CATEGORY::FARM)->info(new \FarmLogMessage($dbServer, sprintf(_("Allocated new IP: %s"), $ip['ipaddress'])));
// Waiting...
sleep(5);
} else {
\Scalr::getContainer()->logger(__CLASS__)->fatal(_("Limit for elastic IPs reached. Check zomby records in database."));
}
}
if ($ip['ipaddress']) {
$allocationId = null;
if ($isVPC) {
$allocationId = $ip['allocation_id'];
}
self::associateIpAddress($dbServer, $ip['ipaddress'], $allocationId);
// Update leastic IPs table
$db->Execute("UPDATE elastic_ips SET state='1', server_id=? WHERE ipaddress=?", array($dbServer->serverId, $ip['ipaddress']));
/*
* DO NOT FIRE THIS EVENT AND LET POLLER TO FIND OUT THAT IP WAS CHANGED AND
* FIRE EVENT. BY THIS TIME MOST LIKELY IP WILL BE ROUTABLE
\Scalr::FireEvent($dbServer->farmId, new \IPAddressChangedEvent(
$dbServer, $ip['ipaddress'], $dbServer->localIp
));
*/
} else {
\Scalr::getContainer()->logger(\LOG_CATEGORY::FARM)->fatal(new \FarmLogMessage($dbServer, sprintf(_("Cannot allocate elastic ip address for instance %s on farm %s (2)"), !empty($dbServer->serverId) ? $dbServer->serverId : null, !empty($dbFarm->Name) ? $dbFarm->Name : null)));
return false;
}
return $ip['ipaddress'];
}