public function xGetDetailsAction() { $amazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); $rInstances = $amazonEC2Client->DescribeReservedInstances(); $rInstances = $rInstances->reservedInstancesSet->item; if ($rInstances instanceof stdClass) { $rInstances = array($rInstances); } $result = array(); foreach ($rInstances as $rInstance) { if ($rInstance->state == 'active') { $result[$rInstance->availabilityZone][$rInstance->instanceType]['rCount'] += $rInstance->instanceCount; } } $servers = $this->db->Execute("SELECT servers.server_id FROM `servers` INNER JOIN server_properties ON server_properties.server_id = servers.server_id \r\n\t\t\tWHERE status=? AND name='ec2.region' AND env_id=? AND value=?", array(SERVER_STATUS::RUNNING, $this->getEnvironmentId(), $this->getParam('cloudLocation'))); while ($server = $servers->FetchRow()) { $dbServer = DBServer::LoadByID($server['server_id']); $result[$dbServer->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE)][$dbServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_TYPE)]['iCount']++; } $retval = array(); foreach ($result as $availZone => $i) { foreach ($i as $instanceType => $data) { $retval[] = array('availZone' => $availZone, 'instanceType' => $instanceType, 'scalrInstances' => (int) $data['iCount'], 'reservedInstances' => (int) $data['rCount']); } } $this->response->data(array('success' => true, 'data' => $retval)); }
public function OnStartForking() { $db = Core::GetDBInstance(null, true); // selects rows where the snapshot's time has come to create new snapshot. $resultset = $db->Execute("SELECT * FROM autosnap_settings \r\n\t\t\t\t\t\tWHERE (UNIX_TIMESTAMP(DATE_ADD(dtlastsnapshot, INTERVAL period HOUR)) < UNIX_TIMESTAMP(NOW())\r\n\t\t\t\t\t\tOR dtlastsnapshot IS NULL)\r\n\t\t\t\t\t\tAND objectid \t!= '0' \r\n\t\t\t\t\t\tAND object_type = ?", array(AUTOSNAPSHOT_TYPE::RDSSnap)); while ($snapshotsSettings = $resultset->FetchRow()) { try { $environment = Scalr_Model::init(Scalr_Model::ENVIRONMENT)->loadById($snapshotsSettings['env_id']); $AmazonRDSClient = Scalr_Service_Cloud_Aws::newRds($environment->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $environment->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY), $snapshotsSettings['region']); // Check instance. If instance wasn't found then delete current recrod from settings table try { $AmazonRDSClient->DescribeDBInstances($snapshotsSettings['objectid']); } catch (Exception $e) { if (stristr($e->getMessage(), "not found") || stristr($e->getMessage(), "not a valid") || stristr($e->getMessage(), "security token included in the request is invalid")) { $db->Execute("DELETE FROM autosnap_settings WHERE id = ?", array($snapshotsSettings['id'])); } $this->Logger->error(sprintf(_("RDS instance %s was not found. Auto-snapshot settings for this \r\n\t\t\t\t\t\t\t\tinstance will be deleted. %s."), $snapshotsSettings['objectid'], $e->getMessage())); throw $e; } // snapshot random unique name $snapshotId = "scalr-auto-" . dechex(microtime(true) * 10000) . rand(0, 9); try { // Create new snapshot $AmazonRDSClient->CreateDBSnapshot($snapshotId, $snapshotsSettings['objectid']); // update last snapshot creation date in settings $db->Execute("UPDATE autosnap_settings SET last_snapshotid=?, dtlastsnapshot=NOW() WHERE id=?", array($snapshotId, $snapshotsSettings['id'])); // create new snapshot record in DB $db->Execute("INSERT INTO rds_snaps_info SET \r\n\t\t\t\t\t\t\tsnapid\t\t= ?,\r\n\t\t\t\t\t\t\tcomment\t\t= ?,\r\n\t\t\t\t\t\t\tdtcreated\t= NOW(),\r\n\t\t\t\t\t\t\tregion\t\t= ?,\r\n\t\t\t\t\t\t\tautosnapshotid = ?", array($snapshotId, _("Auto snapshot"), $snapshotsSettings['region'], $snapshotsSettings['id'])); } catch (Exception $e) { $this->Logger->warn(sprintf(_("Cannot create RDS snapshot: %s."), $e->getMessage())); } // Remove old snapshots if ($snapshotsSettings['rotate'] != 0) { $oldSnapshots = $db->GetAll("SELECT * FROM rds_snaps_info WHERE autosnapshotid = ? ORDER BY id ASC", array($snapshotsSettings['id'])); if (count($oldSnapshots) > $snapshotsSettings['rotate']) { while (count($oldSnapshots) > $snapshotsSettings['rotate']) { // takes the oldest snapshot ... $deletingSnapshot = array_shift($oldSnapshots); try { // and deletes it from amazon and from DB $AmazonRDSClient->DeleteDBSnapshot($deletingSnapshot['snapid']); $db->Execute("DELETE FROM rds_snaps_info WHERE id = ?", array($deletingSnapshot['id'])); } catch (Exception $e) { if (stristr($e->getMessage(), "not found") || stristr($e->getMessage(), "not a valid")) { $db->Execute("DELETE FROM rds_snaps_info WHERE id = ?", array($deletingSnapshot['id'])); } $this->Logger->error(sprintf(_("DBsnapshot %s for RDS instance %s was not found \r\n\t\t\t\t\t\t\t\t\t\t\t\tand cannot be deleted . %s."), $deletingSnapshot['snapid'], $snapshotsSettings['objectid'], $e->getMessage())); } } } } } catch (Exception $e) { $this->Logger->warn(sprintf(_("Cannot create snapshot for RDS Instance %s. %s"), $snapshotsSettings['objectid'], $e->getMessage())); } } }
public function xListCertificatesAction() { $iamClient = Scalr_Service_Cloud_Aws::newIam($this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY)); $rowz = array(); $certs = $iamClient->listServerCertificates(); foreach ($certs->ServerCertificateMetadataList as $item) { $rowz[] = array('id' => $item->ServerCertificateId, 'name' => $item->ServerCertificateName, 'path' => $item->Path, 'arn' => $item->Arn, 'upload_date' => $item->UploadDate); } $this->response->data(array('data' => $rowz)); }
public function xRemoveAction() { $this->request->defineParams(array('volumeId' => array('type' => 'json'), 'cloudLocation')); $amazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); foreach ($this->getParam('volumeId') as $volumeId) { $amazonEC2Client->DeleteVolume($volumeId); $this->db->Execute("DELETE FROM ec2_ebs WHERE volume_id=?", array($volumeId)); } $this->response->success('Volume(s) successfully removed'); }
public function xSaveAction() { $this->request->defineParams(array('rules' => array('type' => 'json'))); $amazonRDSClient = Scalr_Service_Cloud_Aws::newRds($this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY), $this->getParam('cloudLocation')); $response = $amazonRDSClient->DescribeDBSecurityGroups($this->getParam('dbSgName')); $result = json_decode(json_encode($response->DescribeDBSecurityGroupsResult), true); $group = $result['DBSecurityGroups']['DBSecurityGroup']; $rules = array(); if ($group) { if ($group['IPRanges']['IPRange']['CIDRIP']) { $group['IPRanges']['IPRange'] = array($group['IPRanges']['IPRange']); } foreach ($group['IPRanges']['IPRange'] as $r) { $r['id'] = md5($r['CIDRIP']); $rules[$r['id']] = $r; } if ($group['EC2SecurityGroups']['EC2SecurityGroup']['EC2SecurityGroupOwnerId']) { $group['EC2SecurityGroups']['EC2SecurityGroup'] = array($group['EC2SecurityGroups']['EC2SecurityGroup']); } foreach ($group['EC2SecurityGroups']['EC2SecurityGroup'] as $r) { $r['id'] = md5($r['EC2SecurityGroupName'] . $r['EC2SecurityGroupOwnerId']); $rules[$r['id']] = $r; } } foreach ($rules as $id => $r) { $found = false; foreach ($this->getParam('rules') as $rule) { if ($rule['Type'] == 'CIDR IP') { $rid = md5($rule['CIDRIP']); } else { $rid = md5($rule['EC2SecurityGroupName'] . $rule['EC2SecurityGroupOwnerId']); } if ($id == $rid) { $found = true; } } if (!$found) { if ($r['CIDRIP']) { $amazonRDSClient->RevokeDBSecurityGroupIngress($this->getParam('dbSgName'), $r['CIDRIP']); } else { $amazonRDSClient->RevokeDBSecurityGroupIngress($this->getParam('dbSgName'), null, $r['EC2SecurityGroupName'], $r['EC2SecurityGroupOwnerId']); } } } foreach ($this->getParam('rules') as $rule) { if ($rule['Status'] == 'new') { if ($rule['Type'] == 'CIDR IP') { $amazonRDSClient->AuthorizeDBSecurityGroupIngress($this->getParam('dbSgName'), $rule['CIDRIP']); } else { $amazonRDSClient->AuthorizeDBSecurityGroupIngress($this->getParam('dbSgName'), null, $rule['EC2SecurityGroupName'], $rule['EC2SecurityGroupOwnerId']); } } } $this->response->success("DB security group successfully updated"); }
public function xListCertificatesAction() { //FIXME This needs to be refactored. We have to use new Scalr\Service\Aws\Iam library. $iamClient = Scalr_Service_Cloud_Aws::newIam($this->getEnvironment()->getPlatformConfigValue(Ec2PlatformModule::ACCESS_KEY), $this->getEnvironment()->getPlatformConfigValue(Ec2PlatformModule::SECRET_KEY)); $rowz = array(); $certs = $iamClient->listServerCertificates(); foreach ($certs->ServerCertificateMetadataList as $item) { $rowz[] = array('id' => $item->ServerCertificateId, 'name' => $item->ServerCertificateName, 'path' => $item->Path, 'arn' => $item->Arn, 'upload_date' => $item->UploadDate); } $this->response->data(array('data' => $rowz)); }
public function OnHostUp(HostUpEvent $event) { try { $DBFarmRole = $event->DBServer->GetFarmRoleObject(); if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_USE_ELB) == 1) { $Client = $event->DBServer->GetClient(); $AmazonELBClient = Scalr_Service_Cloud_Aws::newElb($event->DBServer->GetProperty(EC2_SERVER_PROPERTIES::REGION), $event->DBServer->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $event->DBServer->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY)); $AmazonELBClient->RegisterInstancesWithLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), array($event->DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID))); Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($this->FarmID, sprintf(_("Instance '%s' registered on '%s' load balancer"), $event->DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME)))); } } catch (Exception $e) { //TODO: $this->Logger->fatal(sprintf(_("Cannot register instance with the load balancer: %s"), $e->getMessage())); } }
public function xListEipsAction() { $amazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); // Rows $aws_response = $amazonEC2Client->DescribeAddresses(); $rowz = $aws_response->addressesSet->item; if ($rowz instanceof stdClass) { $rowz = array($rowz); } foreach ($rowz as &$pv) { $item = array('ipaddress' => $pv->publicIp, 'instance_id' => $pv->instanceId); $info = $this->db->GetRow("SELECT * FROM elastic_ips WHERE ipaddress=?", array($pv->publicIp)); if ($info) { $item['farm_id'] = $info['farmid']; $item['farm_roleid'] = $info['farm_roleid']; $item['server_id'] = $info['server_id']; $item['indb'] = true; $item['server_index'] = $info['instance_index']; //WORKAROUND: EIPS not imported correclty from 1.2 to 2.0 if (!$item['server_id'] && $info['state'] == 1) { try { $DBServer = DBServer::LoadByPropertyValue(EC2_SERVER_PROPERTIES::INSTANCE_ID, $item['instance_id']); $item['server_id'] = $DBServer->serverId; } catch (Exception $e) { } } if ($item['farm_roleid']) { try { $DBFarmRole = DBFarmRole::LoadByID($item['farm_roleid']); $item['role_name'] = $DBFarmRole->GetRoleObject()->name; $item['farm_name'] = $DBFarmRole->GetFarmObject()->Name; } catch (Exception $e) { } } } else { try { $DBServer = DBServer::LoadByPropertyValue(EC2_SERVER_PROPERTIES::INSTANCE_ID, $pv->instanceId); $item['server_id'] = $DBServer->serverId; $item['farm_id'] = $DBServer->farmId; } catch (Exception $e) { } } $pv = $item; } $response = $this->buildResponseFromData($rowz); $this->response->data($response); }
public function xGetSnapshotsAction() { $amazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); $response = $amazonEC2Client->DescribeSnapshots(); if ($response->snapshotSet->item instanceof stdClass) { $response->snapshotSet->item = array($response->snapshotSet->item); } $data = array(); foreach ($response->snapshotSet->item as $pk => $pv) { if ($pv->ownerId != $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCOUNT_ID)) { continue; } if ($pv->status == 'completed') { $data[] = array('snapid' => (string) $pv->snapshotId, 'createdat' => Scalr_Util_DateTime::convertTz($pv->startTime), 'size' => (string) $pv->volumeSize); } } $this->response->data(array('data' => $data)); }
public function xListLogsAction() { $amazonRDSClient = Scalr_Service_Cloud_Aws::newRds($this->environment->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $this->environment->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY), $this->getParam('cloudLocation')); $aws_response = $amazonRDSClient->DescribeEvents($this->getParam('name'), $this->getParam('type')); $events = (array) $aws_response->DescribeEventsResult->Events; if (!is_array($events['Event'])) { $events['Event'] = array($events['Event']); } foreach ($events['Event'] as $event) { if ($event->Message) { $logs[] = array('Message' => (string) $event->Message, 'Date' => (string) $event->Date, 'SourceIdentifier' => (string) $event->SourceIdentifier, 'SourceType' => (string) $event->SourceType); } } $response = $this->buildResponseFromData($logs, array('Date', 'Message')); foreach ($response['data'] as &$row) { $row['Date'] = Scalr_Util_DateTime::convertTz($row['Date']); } $this->response->data($response); }
public static function farmUpdateRoleSettings(DBFarmRole $DBFarmRole, $oldSettings, $newSettings) { $db = Core::GetDBInstance(); $DBFarm = $DBFarmRole->GetFarmObject(); if (!$oldSettings[DBFarmRole::SETTING_AWS_USE_ELASIC_IPS] && $newSettings[DBFarmRole::SETTING_AWS_USE_ELASIC_IPS]) { $servers = $DBFarmRole->GetServersByFilter(array('status' => SERVER_STATUS::RUNNING)); if (count($servers) == 0) { return; } $AmazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($DBFarmRole->CloudLocation, $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); foreach ($servers as $DBServer) { $address = $AmazonEC2Client->AllocateAddress(); $db->Execute("INSERT INTO elastic_ips SET env_id=?, farmid=?, farm_roleid=?, ipaddress=?, state='0', instance_id='', clientid=?, instance_index=?", array($DBServer->envId, $DBServer->farmId, $DBServer->farmRoleId, $address->publicIp, $DBServer->clientId, $DBServer->index)); Logger::getLogger(__CLASS__)->info(sprintf(_("Allocated new IP: %s"), $address->publicIp)); // Waiting... Logger::getLogger(__CLASS__)->debug(_("Waiting 5 seconds...")); sleep(5); $assign_retries = 1; while (true) { try { // Associate elastic ip address with instance $AmazonEC2Client->AssociateAddress($DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $address->publicIp); } catch (Exception $e) { if (!stristr($e->getMessage(), "does not belong to you") || $assign_retries == 3) { throw new Exception($e->getMessage()); } else { // Waiting... Logger::getLogger(__CLASS__)->debug(_("Waiting 2 seconds...")); sleep(2); $assign_retries++; continue; } } break; } Logger::getLogger(__CLASS__)->info(sprintf(_("IP: %s assigned to instance '%s'"), $address->publicIp, $DBServer->serverId)); // Update leastic IPs table $db->Execute("UPDATE elastic_ips SET state='1', server_id=? WHERE ipaddress=?", array($DBServer->serverId, $address->publicIp)); Scalr::FireEvent($DBFarmRole->FarmID, new IPAddressChangedEvent($DBServer, $address->publicIp)); } } }
public function xListSnapshotsAction() { $this->request->defineParams(array('sort' => array('type' => 'json', 'default' => array('property' => 'snapshotId', 'direction' => 'ASC')), 'showPublicSnapshots', 'cloudLocation', 'volumeId', 'snapshotId')); $amazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); // Rows $aws_response = $amazonEC2Client->DescribeSnapshots(); $rowz = $aws_response->snapshotSet->item; if ($rowz instanceof stdClass) { $rowz = array($rowz); } $snaps = array(); foreach ($rowz as $pk => $pv) { if ($this->getParam('volumeId') && $pv->volumeId != $this->getParam('volumeId')) { continue; } if ($this->getParam('snapshotId') && $pv->snapshotId != $this->getParam('snapshotId')) { continue; } $item = (array) $pv; if ($pv->ownerId != $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCOUNT_ID)) { $item['comment'] = $pv->description; $item['owner'] = $pv->ownerId; if (!$this->getParam('showPublicSnapshots')) { continue; } } else { $comment = $this->db->GetOne("SELECT comment FROM ebs_snaps_info WHERE snapid=?", array($pv->snapshotId)); $item['comment'] = $comment ? $comment : $pv->description; $item['owner'] = 'Me'; } $item['progress'] = (int) preg_replace("/[^0-9]+/", "", $item['progress']); unset($item['description']); $snaps[] = $item; } $response = $this->buildResponseFromData($snaps, array('snapshotId', 'volumeId', 'comment', 'owner')); foreach ($response['data'] as &$row) { $row['startTime'] = Scalr_Util_DateTime::convertTz($row['startTime']); } $this->response->data($response); }
public function xDeleteSnapshotsAction() { $this->request->defineParams(array('snapshots' => array('type' => 'json'))); $amazonRDSClient = Scalr_Service_Cloud_Aws::newRds($this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY), $this->getParam('cloudLocation')); $i = 0; $errors = array(); foreach ($this->getParam('snapshots') as $snapName) { try { $amazonRDSClient->DeleteDBSnapshot($snapName); $this->db->Execute("DELETE FROM rds_snaps_info WHERE snapid=? ", array($snapName)); $i++; } catch (Exception $e) { $errors[] = sprintf(_("Can't delete db snapshot %s: %s"), $snapName, $e->getMessage()); } } $message = sprintf(_("%s db snapshot(s) successfully removed"), $i); if (count($errors)) { $this->response->warning(nl2br(implode("\n", array_merge(array($message), $errors)))); } else { $this->response->success($message); } }
public function regenerateAction() { $this->request->defineParams(array('sshKeyId' => array('type' => 'int'))); $sshKey = Scalr_SshKey::init()->loadById($this->getParam('sshKeyId')); $this->user->getPermissions()->validate($sshKey); if ($sshKey->type == Scalr_SshKey::TYPE_GLOBAL) { if ($sshKey->platform == 'ec2') { $AmazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($sshKey->cloudLocation, $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); $AmazonEC2Client->DeleteKeyPair($sshKey->cloudKeyName); $result = $AmazonEC2Client->CreateKeyPair($sshKey->cloudKeyName); if ($result->keyMaterial) { $sshKey->setPrivate($result->keyMaterial); $pubKey = $sshKey->generatePublicKey(); if (!$pubKey) { throw new Exception("Keypair generation failed"); } $oldKey = $sshKey->getPublic(); $sshKey->setPublic($pubKey); $sshKey->save(); $dbFarm = DBFarm::LoadByID($sshKey->farmId); $servers = $dbFarm->GetServersByFilter(array('platform' => SERVER_PLATFORMS::EC2, 'status' => array(SERVER_STATUS::RUNNING, SERVER_STATUS::INIT, SERVER_STATUS::PENDING))); foreach ($servers as $dbServer) { if ($dbServer->GetCloudLocation() == $sshKey->cloudLocation) { $msg = new Scalr_Messaging_Msg_UpdateSshAuthorizedKeys(array($pubKey), array($oldKey)); $dbServer->SendMessage($msg); } } $this->response->success(); } } else { //TODO: } } else { //TODO: } }
function handleWork($serverId) { try { $dbserver = DBServer::LoadByID($serverId); if ($dbserver->farmId) { if ($dbserver->GetFarmObject()->Status == FARM_STATUS::TERMINATED) { throw new ServerNotFoundException(""); } } } catch (Exception $e) { $this->db->Execute("DELETE FROM messages WHERE server_id=? AND `type`='in'", array($serverId)); return; } $rs = $this->db->Execute("SELECT * FROM messages \n \t\tWHERE server_id = ? AND type = ? AND status = ? \n \t\tORDER BY id ASC", array($serverId, "in", MESSAGE_STATUS::PENDING)); while ($row = $rs->FetchRow()) { try { $message = $this->serializer->unserialize($row["message"]); $event = null; // Update scalarizr package version if ($message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION]) { $dbserver->SetProperty(SERVER_PROPERTIES::SZR_VESION, $message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION]); } if ($message->meta[Scalr_Messaging_MsgMeta::SZR_UPD_CLIENT_VERSION]) { $dbserver->SetProperty(SERVER_PROPERTIES::SZR_UPD_CLIENT_VERSION, $message->meta[Scalr_Messaging_MsgMeta::SZR_UPD_CLIENT_VERSION]); } try { if ($message instanceof Scalr_Messaging_Msg_OperationResult) { $this->db->Execute("UPDATE server_operations SET `status` = ? WHERE id = ?", array($message->status, $message->id)); if ($message->status == 'error') { if ($message->name == 'Initialization') { $dbserver->SetProperty(SERVER_PROPERTIES::SZR_IS_INIT_FAILED, 1); } if ($message->error) { $msg = $message->error->message; $trace = $message->error->trace; $handler = $message->error->handler; } $this->db->Execute("INSERT INTO server_operation_progress SET \n\t\t\t\t\t\t\t\t\t`operation_id` = ?,\n\t\t\t\t\t\t\t\t\t`timestamp` = ?,\n\t\t\t\t\t\t\t\t\t`phase` = ?,\n\t\t\t\t\t\t\t\t\t`step` = ?,\n\t\t\t\t\t\t\t\t\t`status` = ?,\n\t\t\t\t\t\t\t\t\t`message`= ?,\n\t\t\t\t\t\t\t\t\t`trace` = ?,\n\t\t\t\t\t\t\t\t\t`handler` = ?,\n\t\t\t\t\t\t\t\t\t`progress` = ?,\n\t\t\t\t\t\t\t\t\t`stepno` = ? \n\t\t\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE status = ?, progress = ?, trace = ?, handler = ?, message = ?\n\t\t\t\t\t\t\t\t", array($message->id, $message->getTimestamp(), $message->phase, $message->step, $message->status, $msg, $trace, $handler, $message->progress, $message->stepno, $message->status, $message->progress, $trace, $handler, $msg)); } } elseif ($message instanceof Scalr_Messaging_Msg_Win_HostDown) { $status = PlatformFactory::NewPlatform($dbserver->platform)->GetServerRealStatus($dbserver); if ($status->isRunning()) { $event = new RebootBeginEvent($dbserver); } else { $event = new HostDownEvent($dbserver); } } elseif ($message instanceof Scalr_Messaging_Msg_Win_PrepareBundleResult) { try { $bundleTask = BundleTask::LoadById($message->bundleTaskId); } catch (Exception $e) { } if ($bundleTask) { if ($message->status == 'ok') { $metaData = array('szr_version' => $message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION], 'os' => $message->os, 'software' => $message->software); $bundleTask->setMetaData($metaData); $bundleTask->Save(); PlatformFactory::NewPlatform($bundleTask->platform)->CreateServerSnapshot($bundleTask); } else { $bundleTask->SnapshotCreationFailed("PrepareBundle procedure failed: {$message->lastError}"); } } } elseif ($message instanceof Scalr_Messaging_Msg_DeployResult) { try { $deploymentTask = Scalr_Model::init(Scalr_Model::DM_DEPLOYMENT_TASK)->loadById($message->deployTaskId); } catch (Exception $e) { } if ($deploymentTask) { if ($message->status == 'error') { $deploymentTask->status = Scalr_Dm_DeploymentTask::STATUS_FAILED; $deploymentTask->lastError = $message->lastError; } else { $deploymentTask->status = Scalr_Dm_DeploymentTask::STATUS_DEPLOYED; $deploymentTask->dtDeployed = date("Y-m-d H:i:s"); } $deploymentTask->save(); } } elseif ($message instanceof Scalr_Messaging_Msg_Hello) { $event = $this->onHello($message, $dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_MongoDb) { try { $dbFarmRole = $dbserver->GetFarmRoleObject(); } catch (Exception $e) { } if ($dbFarmRole instanceof DBFarmRole) { foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->handleMessage($message, $dbserver); } } } elseif ($message instanceof Scalr_Messaging_Msg_DbMsr) { try { $dbFarmRole = $dbserver->GetFarmRoleObject(); } catch (Exception $e) { } if ($dbFarmRole instanceof DBFarmRole) { foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->handleMessage($message, $dbserver); } } } elseif ($message instanceof Scalr_Messaging_Msg_HostInit) { $event = $this->onHostInit($message, $dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_HostUp) { $event = $this->onHostUp($message, $dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_HostDown) { $isMoving = false; if ($dbserver->platform == SERVER_PLATFORMS::RACKSPACE) { $p = PlatformFactory::NewPlatform($dbserver->platform); $status = $p->GetServerRealStatus($dbserver)->getName(); if (stristr($status, 'MOVE') || stristr($status, 'REBOOT')) { $this->logger->error(new FarmLogMessage($dbserver->farmId, "Rackspace server is in MOVING state. Ignoring HostDown message.")); $isMoving = true; } } if (!$isMoving) { $event = new HostDownEvent($dbserver); } } elseif ($message instanceof Scalr_Messaging_Msg_RebootStart) { $event = new RebootBeginEvent($dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_RebootFinish) { $event = new RebootCompleteEvent($dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_BeforeHostUp) { $event = new BeforeHostUpEvent($dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_BlockDeviceAttached) { if ($dbserver->platform == SERVER_PLATFORMS::EC2) { $ec2Client = Scalr_Service_Cloud_Aws::newEc2($dbserver->GetProperty(EC2_SERVER_PROPERTIES::REGION), $dbserver->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $dbserver->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); $instanceId = $dbserver->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID); $volumes = $ec2Client->DescribeVolumes()->volumeSet->item; if (!is_array($volumes)) { $volumes = array($volumes); } foreach ($volumes as $volume) { if ($volume->status == AMAZON_EBS_STATE::IN_USE && $volume->attachmentSet->item->instanceId == $instanceId && $volume->attachmentSet->item->device == $message->deviceName) { $message->volumeId = $volume->volumeId; } } } $event = new EBSVolumeAttachedEvent($dbserver, $message->deviceName, $message->volumeId); } elseif ($message instanceof Scalr_Messaging_Msg_BlockDeviceMounted) { // Single volume $ebsinfo = $this->db->GetRow("SELECT * FROM ec2_ebs WHERE volume_id=?", array($message->volumeId)); if ($ebsinfo) { $this->db->Execute("UPDATE ec2_ebs SET mount_status=?, isfsexist='1' WHERE id=?", array(EC2_EBS_MOUNT_STATUS::MOUNTED, $ebsinfo['id'])); } $event = new EBSVolumeMountedEvent($dbserver, $message->mountpoint, $message->volumeId, $message->deviceName); } elseif ($message instanceof Scalr_Messaging_Msg_RebundleResult) { if ($message->status == Scalr_Messaging_Msg_RebundleResult::STATUS_OK) { $metaData = array('szr_version' => $message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION], 'dist' => $message->dist, 'os' => $message->os, 'software' => $message->software); if ($dbserver->platform == SERVER_PLATFORMS::EC2) { if ($message->aws) { if ($message->aws->root - device - type == 'ebs') { $tags[] = ROLE_TAGS::EC2_EBS; } if ($message->aws->virtualization - type == 'hvm') { $tags[] = ROLE_TAGS::EC2_HVM; } } else { $ec2Client = Scalr_Service_Cloud_Aws::newEc2($dbserver->GetProperty(EC2_SERVER_PROPERTIES::REGION), $dbserver->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $dbserver->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); try { $DescribeImagesType = new DescribeImagesType(null, array(), null); $DescribeImagesType->imagesSet = new stdClass(); $DescribeImagesType->imagesSet->item = array(); $DescribeImagesType->imagesSet->item[] = array('imageId' => $dbserver->GetProperty(EC2_SERVER_PROPERTIES::AMIID)); $info = $ec2Client->DescribeImages($DescribeImagesType); if ($info->imagesSet->item->rootDeviceType == 'ebs') { $tags[] = ROLE_TAGS::EC2_EBS; } else { try { $bundleTask = BundleTask::LoadById($message->bundleTaskId); if ($bundleTask->bundleType == SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS) { $tags[] = ROLE_TAGS::EC2_EBS; } } catch (Exception $e) { } } if ($info->imagesSet->item->virtualizationType == 'hvm') { $tags[] = ROLE_TAGS::EC2_HVM; } } catch (Exception $e) { $metaData['tagsError'] = $e->getMessage(); } } } elseif ($dbserver->platform == SERVER_PLATFORMS::NIMBULA) { $metaData['init_root_user'] = $message->sshUser; $metaData['init_root_pass'] = $message->sshPassword; } $metaData['tags'] = $tags; $event = new RebundleCompleteEvent($dbserver, $message->snapshotId, $message->bundleTaskId, $metaData); } else { if ($message->status == Scalr_Messaging_Msg_RebundleResult::STATUS_FAILED) { $event = new RebundleFailedEvent($dbserver, $message->bundleTaskId, $message->lastError); } } } elseif ($message instanceof Scalr_Messaging_Msg_Mysql_CreateDataBundleResult) { if ($message->status == "ok") { $event = new MysqlBackupCompleteEvent($dbserver, MYSQL_BACKUP_TYPE::BUNDLE, array('snapshotConfig' => $message->snapshotConfig, 'logFile' => $message->logFile, 'logPos' => $message->logPos, 'dataBundleSize' => $message->dataBundleSize, 'snapshotId' => $message->snapshotId)); } else { $event = new MysqlBackupFailEvent($dbserver, MYSQL_BACKUP_TYPE::BUNDLE); $event->lastError = $message->lastError; } } elseif ($message instanceof Scalr_Messaging_Msg_Mysql_CreateBackupResult) { if ($message->status == "ok") { $event = new MysqlBackupCompleteEvent($dbserver, MYSQL_BACKUP_TYPE::DUMP); } else { $event = new MysqlBackupFailEvent($dbserver, MYSQL_BACKUP_TYPE::DUMP); $event->lastError = $message->lastError; } } elseif ($message instanceof Scalr_Messaging_Msg_Mysql_PromoteToMasterResult) { $event = $this->onMysql_PromoteToMasterResult($message, $dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_Mysql_CreatePmaUserResult) { $farmRole = DBFarmRole::LoadByID($message->farmRoleId); if ($message->status == "ok") { $farmRole->SetSetting(DbFarmRole::SETTING_MYSQL_PMA_USER, $message->pmaUser); $farmRole->SetSetting(DbFarmRole::SETTING_MYSQL_PMA_PASS, $message->pmaPassword); } else { $farmRole->SetSetting(DBFarmRole::SETTING_MYSQL_PMA_REQUEST_TIME, ""); $farmRole->SetSetting(DBFarmRole::SETTING_MYSQL_PMA_REQUEST_ERROR, $message->lastError); } } elseif ($message instanceof Scalr_Messaging_Msg_RabbitMq_SetupControlPanelResult) { $farmRole = $dbserver->GetFarmRoleObject(); if ($message->status == "ok") { $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_SERVER_ID, $dbserver->serverId); $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_URL, $message->cpanelUrl); $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_REQUEST_TIME, ""); } else { $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_SERVER_ID, ""); $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_REQUEST_TIME, ""); $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_ERROR_MSG, $message->lastError); } } elseif ($message instanceof Scalr_Messaging_Msg_AmiScriptsMigrationResult) { try { //Open security group: if ($dbserver->platform == SERVER_PLATFORMS::EC2) { $info = PlatformFactory::NewPlatform($dbserver->platform)->GetServerExtendedInformation($dbserver); $sg = explode(", ", $info['Security groups']); foreach ($sg as $sgroup) { if ($sgroup != 'default') { $ipPermissionSet = new IpPermissionSetType(); $group_rules = array(array('rule' => 'tcp:8013:8013:0.0.0.0/0'), array('rule' => 'udp:8014:8014:0.0.0.0/0')); foreach ($group_rules as $rule) { $group_rule = explode(":", $rule["rule"]); $ipPermissionSet->AddItem($group_rule[0], $group_rule[1], $group_rule[2], null, array($group_rule[3])); } $ec2Client = Scalr_Service_Cloud_Aws::newEc2($dbserver->GetProperty(EC2_SERVER_PROPERTIES::REGION), $dbserver->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $dbserver->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); // Create security group $ec2Client->AuthorizeSecurityGroupIngress($dbserver->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCOUNT_ID), $sgroup, $ipPermissionSet); break; } } } } catch (Exception $e) { $this->logger->fatal($e->getMessage()); } $dbserver->SetProperty(SERVER_PROPERTIES::SZR_SNMP_PORT, 8014); $dbserver->SetProperty(SERVER_PROPERTIES::SZR_VESION, "0.7.217"); if ($message->mysql) { $event = $this->onHostUp($message, $dbserver, true); } } $handle_status = MESSAGE_STATUS::HANDLED; } catch (Exception $e) { $handle_status = MESSAGE_STATUS::FAILED; $this->logger->error(sprintf("Cannot handle message '%s' (message_id: %s) " . "from server '%s' (server_id: %s). %s", $message->getName(), $message->messageId, $dbserver->remoteIp ? $dbserver->remoteIp : '*no-ip*', $dbserver->serverId, $e->getMessage() . "({$e->getFile()}:{$e->getLine()})")); } $this->db->Execute("UPDATE messages SET status = ? WHERE messageid = ?", array($handle_status, $message->messageId)); if ($event) { Scalr::FireEvent($dbserver->farmId, $event); } } catch (Exception $e) { $this->logger->error($e->getMessage(), $e); } } }
public function getRdsClient(Scalr_Environment $environment, $region) { return Scalr_Service_Cloud_Aws::newRds($environment->getPlatformConfigValue(self::ACCESS_KEY), $environment->getPlatformConfigValue(self::SECRET_KEY), $region); }
public function xListVolumesAction() { $this->request->defineParams(array('sort' => array('type' => 'json', 'default' => array('property' => 'volumeId', 'direction' => 'DESC')), 'volumeId')); $amazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); // Rows $aws_response = $amazonEC2Client->DescribeVolumes(); $rowz = $aws_response->volumeSet->item; if ($rowz instanceof stdClass) { $rowz = array($rowz); } $vols = array(); foreach ($rowz as $pk => $pv) { if ($pv->attachmentSet && $pv->attachmentSet->item) { $pv->attachmentSet = $pv->attachmentSet->item; } if ($this->getParam('volumeId') && $this->getParam('volumeId') != $pv->volumeId) { continue; } $item = array('volumeId' => $pv->volumeId, 'size' => $pv->size, 'snapshotId' => $pv->snapshotId, 'availZone' => $pv->availabilityZone, 'status' => $pv->status, 'attachmentStatus' => $pv->attachmentSet->status, 'device' => $pv->attachmentSet->device, 'instanceId' => $pv->attachmentSet->instanceId); $item['autoSnaps'] = $this->db->GetOne("SELECT id FROM autosnap_settings WHERE objectid=? AND object_type=?", array($pv->volumeId, AUTOSNAPSHOT_TYPE::EBSSnap)) ? true : false; $DBEBSVolume = false; try { $DBEBSVolume = DBEBSVolume::loadByVolumeId($pv->volumeId); //$sort_key = "{$DBEBSVolume->farmId}_{$DBEBSVolume->farmRoleId}_{$pv->volumeId}"; $item['farmId'] = $DBEBSVolume->farmId; $item['farmRoleId'] = $DBEBSVolume->farmRoleId; $item['serverIndex'] = $DBEBSVolume->serverIndex; $item['serverId'] = $DBEBSVolume->serverId; $item['mountStatus'] = $DBEBSVolume->mountStatus; $item['farmName'] = DBFarm::LoadByID($DBEBSVolume->farmId)->Name; $item['roleName'] = DBFarmRole::LoadByID($DBEBSVolume->farmRoleId)->GetRoleObject()->name; $item['autoAttach'] = true; } catch (Exception $e) { } if (!$DBEBSVolume && $item['instanceId']) { try { $dbServer = DBServer::LoadByPropertyValue(EC2_SERVER_PROPERTIES::INSTANCE_ID, $item['instanceId']); $item['farmId'] = $dbServer->farmId; $item['farmRoleId'] = $dbServer->farmRoleId; $item['serverIndex'] = $dbServer->index; $item['serverId'] = $dbServer->serverId; $item['farmName'] = $dbServer->GetFarmObject()->Name; $item['mountStatus'] = false; $item['roleName'] = $dbServer->GetFarmRoleObject()->GetRoleObject()->name; } catch (Exception $e) { } } $vols[] = $item; } $response = $this->buildResponseFromData($vols, array('instanceId', 'volumeId', 'snapshotId', 'farmId', 'farmRoleId', 'availZone')); $this->response->data($response); }
public function xRestoreInstanceAction() { $amazonRDSClient = Scalr_Service_Cloud_Aws::newRds($this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY), $this->getParam('cloudLocation')); $amazonRDSClient->RestoreDBInstanceFromDBSnapshot($this->getParam('Snapshot'), $this->getParam('DBInstanceIdentifier'), $this->getParam('DBInstanceClass'), $this->getParam('Port'), $this->getParam('AvailabilityZone'), $this->getParam('MultiAZ')); $this->response->success("DB Instance successfully restore from Snapshot"); }
public function xSaveEc2Action() { $pars = array(); $enabled = false; if ($this->getParam('ec2_is_enabled')) { $enabled = true; $pars[Modules_Platforms_Ec2::ACCOUNT_ID] = $this->checkVar(Modules_Platforms_Ec2::ACCOUNT_ID, 'string', "AWS Account Number required"); if (!is_numeric($pars[Modules_Platforms_Ec2::ACCOUNT_ID]) || strlen($pars[Modules_Platforms_Ec2::ACCOUNT_ID]) != 12) { //$err[Modules_Platforms_Ec2::ACCOUNT_ID] = _("AWS numeric account ID required (See <a href='/faq.html'>FAQ</a> for info on where to get it)."); $this->checkVarError[Modules_Platforms_Ec2::ACCOUNT_ID] = _("AWS Account Number should be numeric"); } else { $pars[Modules_Platforms_Ec2::ACCOUNT_ID] = preg_replace("/[^0-9]+/", "", $pars[Modules_Platforms_Ec2::ACCOUNT_ID]); } $pars[Modules_Platforms_Ec2::ACCESS_KEY] = $this->checkVar(Modules_Platforms_Ec2::ACCESS_KEY, 'string', "AWS Access Key required"); $pars[Modules_Platforms_Ec2::SECRET_KEY] = $this->checkVar(Modules_Platforms_Ec2::SECRET_KEY, 'password', "AWS Access Key required"); $pars[Modules_Platforms_Ec2::PRIVATE_KEY] = trim($this->checkVar(Modules_Platforms_Ec2::PRIVATE_KEY, 'file', "AWS x.509 Private Key required")); $pars[Modules_Platforms_Ec2::CERTIFICATE] = trim($this->checkVar(Modules_Platforms_Ec2::CERTIFICATE, 'file', "AWS x.509 Certificate required")); // the same as EC2 $pars[Modules_Platforms_Rds::ACCOUNT_ID] = $pars[Modules_Platforms_Ec2::ACCOUNT_ID]; $pars[Modules_Platforms_Rds::ACCESS_KEY] = $pars[Modules_Platforms_Ec2::ACCESS_KEY]; $pars[Modules_Platforms_Rds::SECRET_KEY] = $pars[Modules_Platforms_Ec2::SECRET_KEY]; $pars[Modules_Platforms_Rds::PRIVATE_KEY] = $pars[Modules_Platforms_Ec2::PRIVATE_KEY]; $pars[Modules_Platforms_Rds::CERTIFICATE] = $pars[Modules_Platforms_Ec2::CERTIFICATE]; if (!count($this->checkVarError)) { if ($pars[Modules_Platforms_Ec2::ACCOUNT_ID] != $this->env->getPlatformConfigValue(Modules_Platforms_Ec2::ACCOUNT_ID) or $pars[Modules_Platforms_Ec2::ACCESS_KEY] != $this->env->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY) or $pars[Modules_Platforms_Ec2::SECRET_KEY] != $this->env->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY) or $pars[Modules_Platforms_Ec2::PRIVATE_KEY] != $this->env->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY) or $pars[Modules_Platforms_Ec2::CERTIFICATE] != $this->env->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)) { try { $AmazonEC2Client = Scalr_Service_Cloud_Aws::newEc2('us-east-1', $pars[Modules_Platforms_Ec2::PRIVATE_KEY], $pars[Modules_Platforms_Ec2::CERTIFICATE]); $AmazonEC2Client->describeInstances(); } catch (Exception $e) { throw new Exception(_("Incorrect format of X.509 certificate or private key. Make sure that you are using files downloaded from AWS profile. ({$e->getMessage()})")); } try { $AmazonS3 = new AmazonS3($pars[Modules_Platforms_Ec2::ACCESS_KEY], $pars[Modules_Platforms_Ec2::SECRET_KEY]); $buckets = $AmazonS3->ListBuckets(); } catch (Exception $e) { throw new Exception(sprintf(_("Failed to verify your EC2 access key and secret key: %s"), $e->getMessage())); } } } else { $this->response->failure(); $this->response->data(array('errors' => $this->checkVarError)); return; } } $this->db->BeginTrans(); try { $this->env->enablePlatform(SERVER_PLATFORMS::EC2, $enabled); $this->env->enablePlatform(SERVER_PLATFORMS::RDS, $enabled); if ($enabled) { $this->env->setPlatformConfig($pars); } if (!$this->user->getAccount()->getSetting(Scalr_Account::SETTING_DATE_ENV_CONFIGURED)) { $this->user->getAccount()->setSetting(Scalr_Account::SETTING_DATE_ENV_CONFIGURED, time()); } if ($this->user->getAccount()->getSetting(Scalr_Account::SETTING_IS_TRIAL) == 1) { if ($this->db->GetOne("SELECT COUNT(*) FROM farms WHERE clientid = ?", array($this->user->getAccountId())) == 0) { //Create demo farm try { $dbFarm = DBFarm::LoadByID(9670); // LAMP-PROTOTYPE $dbFarm->cloneFarm('My First LAMP Farm'); $demoFarm = true; } catch (Exception $e) { throw new Exception("Demo farm creation failed: {$e->getMessage()}"); } } } $this->response->success('Environment saved'); $this->response->data(array('enabled' => $enabled, 'demoFarm' => $demoFarm)); } catch (Exception $e) { $this->db->RollbackTrans(); throw new Exception(_("Failed to save AWS settings: {$e->getMessage()}")); } $this->db->CommitTrans(); }
public function StartThread($volume) { $db = Core::GetDBInstance(null, true); $DBEBSVolume = DBEBSVolume::loadById($volume['id']); $EC2Client = Scalr_Service_Cloud_Aws::newEc2($DBEBSVolume->ec2Region, $DBEBSVolume->getEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $DBEBSVolume->getEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); if ($DBEBSVolume->volumeId) { try { $result = $EC2Client->DescribeVolumes($DBEBSVolume->volumeId); $volumeinfo = $result->volumeSet->item; } catch (Exception $e) { if (stristr($e->getMessage(), "does not exist")) { $DBEBSVolume->delete(); exit; } else { $this->logger->error("Cannot get EBS volume information: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); } } } switch ($DBEBSVolume->attachmentStatus) { case EC2_EBS_ATTACH_STATUS::DELETING: if ($DBEBSVolume->volumeId) { try { $EC2Client->DeleteVolume($DBEBSVolume->volumeId); $removeFromDb = true; } catch (Exception $e) { if (stristr($e->getMessage(), "does not exist")) { $removeFromDb = true; } else { $this->logger->error("Cannot remove volume: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); } } } else { $removeFromDb = true; } if ($removeFromDb) { $DBEBSVolume->delete(); } break; case EC2_EBS_ATTACH_STATUS::ATTACHING: switch ($volumeinfo->status) { case AMAZON_EBS_STATE::IN_USE: $volumeInstanceId = $volumeinfo->attachmentSet->item->instanceId; $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); if ($volumeInstanceId == $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID)) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHED; } else { $this->logger->warn(sprintf(_("Volume #%s should be attached to server %s (%s), but it already attached to instance %s. Re-attaching..."), $DBEBSVolume->volumeId, $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $DBServer->serverId, $volumeInstanceId)); try { $DetachVolumeType = new DetachVolumeType($DBEBSVolume->volumeId, $volumeInstanceId, $DBEBSVolume->deviceName, true); $EC2Client->DetachVolume($DetachVolumeType); } catch (Exception $e) { } } $DBEBSVolume->save(); break; case AMAZON_EBS_STATE::AVAILABLE: $attach_volume = true; break; case AMAZON_EBS_STATE::ATTACHING: // NOTHING TO DO; break; default: $this->logger->error("Cannot attach volume to server {$DBServer->serverId}. Volume status: {$volumeinfo->status}. Volume Database ID: {$DBEBSVolume->id}. Volume ID: {$DBEBSVolume->volumeId} (" . serialize($volumeinfo) . ")"); break; } break; case EC2_EBS_ATTACH_STATUS::CREATING: if (!$DBEBSVolume->volumeId) { if ($DBEBSVolume->ec2AvailZone == 'x-scalr-diff' || stristr($DBEBSVolume->ec2AvailZone, "x-scalr-custom")) { if ($DBEBSVolume->serverId) { $DBEBSVolume->ec2AvailZone = DBServer::LoadByID($DBEBSVolume->serverId)->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE); } else { $DBEBSVolume->delete(); } } $CreateVolumeType = new CreateVolumeType($DBEBSVolume->size, $DBEBSVolume->snapId ? $DBEBSVolume->snapId : "", $DBEBSVolume->ec2AvailZone); try { $result = $EC2Client->CreateVolume($CreateVolumeType); if ($result->volumeId) { $DBEBSVolume->volumeId = $result->volumeId; $DBEBSVolume->save(); $this->logger->info("Created new volume: {$DBEBSVolume->volumeId}. Database ID: {$DBEBSVolume->id}"); } else { $this->logger->error("Cannot create volume. Database ID: {$DBEBSVolume->id}"); exit; } } catch (Exception $e) { if (stristr($e->getMessage(), "must be at least snapshot size")) { @preg_match_all("/(([0-9]+)GiB)/sim", $e->getMessage(), $matches); if ($matches[2][1] > 1) { $DBEBSVolume->size = $matches[2][1]; $DBEBSVolume->save(); } } $this->logger->error("Cannot create volume: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); exit; } } else { if ($volumeinfo && $DBEBSVolume->volumeId) { if ($volumeinfo->status == AMAZON_EBS_STATE::AVAILABLE) { if (!$DBEBSVolume->serverId) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::AVAILABLE; $DBEBSVolume->save(); } else { $attach_volume = true; } } } } break; } switch ($DBEBSVolume->mountStatus) { case EC2_EBS_MOUNT_STATUS::AWAITING_ATTACHMENT: if ($DBEBSVolume->attachmentStatus == EC2_EBS_ATTACH_STATUS::ATTACHED) { $DBEBSVolume->mountStatus = EC2_EBS_MOUNT_STATUS::MOUNTING; $DBEBSVolume->save(); $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); $DBServer->SendMessage(new Scalr_Messaging_Msg_MountPointsReconfigure()); } break; case EC2_EBS_MOUNT_STATUS::MOUNTING: //NOTHING TO DO break; } if ($attach_volume) { try { $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); if ($DBServer->status != SERVER_STATUS::RUNNING && $DBServer->IsSupported("0.7.36")) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHING; $DBEBSVolume->save(); $this->logger->fatal("Szr verison > 0.7.36. Status: {$DBServer->status}. VolumeID: {$DBEBSVolume->volumeId}"); return; } } catch (ServerNotFoundException $e) { if ($DBEBSVolume->volumeId) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::AVAILABLE; $DBEBSVolume->mountStatus = EC2_EBS_MOUNT_STATUS::NOT_MOUNTED; $DBEBSVolume->save(); } } if ($DBServer) { //NOT supported if ($DBServer->GetOsFamily() == 'windows') { return; } try { $attachVolumeType = new AttachVolumeType($DBEBSVolume->volumeId, $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $DBServer->GetFreeDeviceName()); $result = $EC2Client->AttachVolume($attachVolumeType); } catch (Exception $e) { if (!stristr($e->getMessage(), "is not in the same availability zone as instance") && !stristr($e->getMessage(), "Cannot get a list of used disk devices")) { $this->logger->fatal("Cannot attach volume: {$e->getMessage()}"); } else { $this->logger->info("Cannot attach volume: {$e->getMessage()}"); } } if ($result->status == AMAZON_EBS_STATE::IN_USE || $result->status == AMAZON_EBS_STATE::ATTACHING) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHING; $DBEBSVolume->deviceName = $attachVolumeType->device; $DBEBSVolume->save(); } else { $this->logger->warn("Cannot attach volume: volume status: {$result->status} ({$volumeinfo->status}). Database ID: {$DBEBSVolume->id}. Volume ID: {$DBEBSVolume->volumeId}"); } } } }
private function getPlatformClient() { if (!$this->getParam('platform')) { throw new Exception('Platform should be specified'); } switch ($this->getParam('platform')) { case SERVER_PLATFORMS::EC2: return Scalr_Service_Cloud_Aws::newEc2($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); break; default: throw new Exception("Platfrom not suppored"); break; } }
public function xResetAction() { $amazonRDSClient = Scalr_Service_Cloud_Aws::newRds($this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY), $this->getParam('cloudLocation')); $response = $amazonRDSClient->DescribeDBParameters($this->getParam('name')); $result = json_decode(json_encode($response->DescribeDBParametersResult->Parameters), true); $params = $result['Parameter']; $modifiedParameters = new ParametersList(); foreach ($params as $param) { if ($param['ParameterValue'] && !empty($param['ParameterValue'])) { if ($param['ApplyType'] == 'static') { $modifiedParameters->AddParameters($param['ParameterName'], $param['ParameterValue'], "pending-reboot"); } else { $modifiedParameters->AddParameters($param['ParameterName'], $param['ParameterValue'], "immediate"); } } } $amazonRDSClient->ResetDBParameterGroup($this->getParam('name'), $modifiedParameters); $this->response->success("DB parameter group successfully reset to default"); }
public function xListElasticLoadBalancersAction() { $amazonELBClient = Scalr_Service_Cloud_Aws::newElb($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY)); // Rows $aws_response = $amazonELBClient->DescribeLoadBalancers(); $lb = (array) $aws_response->DescribeLoadBalancersResult->LoadBalancerDescriptions; $rowz = $lb['member']; if (!is_array($rowz)) { $rowz = array($rowz); } $rowz1 = array(); foreach ($rowz as $pk => $pv) { if (!(string) $pv->DNSName) { continue; } $roleid = $this->db->GetOne("SELECT farm_roleid FROM farm_role_settings WHERE name=? AND value=?", array(DBFarmRole::SETTING_BALANCING_HOSTNAME, (string) $pv->DNSName)); $farmId = false; $farmRoleId = false; $farmName = false; $roleName = false; if ($roleid) { try { $DBFarmRole = DBFarmRole::LoadByID($roleid); $farmId = $DBFarmRole->FarmID; $farmRoleId = $roleid; $farmName = $DBFarmRole->GetFarmObject()->Name; $roleName = $DBFarmRole->GetRoleObject()->name; } catch (Exception $e) { } } $rowz1[] = array("name" => (string) $pv->LoadBalancerName, "dtcreated" => (string) $pv->CreatedTime, "dnsName" => (string) $pv->DNSName, "farmId" => $farmId, "farmRoleId" => $farmRoleId, "farmName" => $farmName, "roleName" => $roleName); } $response = $this->buildResponseFromData($rowz1, array('name', 'dnsname', 'farmName', 'roleName')); foreach ($response['data'] as &$row) { $row['dtcreated'] = Scalr_Util_DateTime::convertTz($row['dtcreated']); } $this->response->data($response); }
/** * Return new instance of AmazonEC2 object * * @return AmazonEC2 */ private function GetAmazonEC2ClientObject(Scalr_Environment $environment, $region) { // Return new instance of AmazonEC2 object $AmazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($region, $environment->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $environment->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); return $AmazonEC2Client; }
public function LaunchServer(DBServer $DBServer, Scalr_Server_LaunchOptions $launchOptions = null) { $RunInstancesType = new RunInstancesType(); $RunInstancesType->ConfigureRootPartition(); if (!$launchOptions) { $launchOptions = new Scalr_Server_LaunchOptions(); $DBRole = DBRole::loadById($DBServer->roleId); // Set Cloudwatch monitoring $RunInstancesType->SetCloudWatchMonitoring($DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_AWS_ENABLE_CW_MONITORING)); $launchOptions->architecture = $DBRole->architecture; $launchOptions->imageId = $DBRole->getImageId(SERVER_PLATFORMS::EC2, $DBServer->GetFarmRoleObject()->CloudLocation); $launchOptions->cloudLocation = $DBServer->GetFarmRoleObject()->CloudLocation; $akiId = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::AKIID); if (!$akiId) { $akiId = $DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_AWS_AKI_ID); } if ($akiId) { $RunInstancesType->kernelId = $akiId; } $ariId = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::ARIID); if (!$ariId) { $ariId = $DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_AWS_ARI_ID); } if ($ariId) { $RunInstancesType->ramdiskId = $ariId; } $i_type = $DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_AWS_INSTANCE_TYPE); if (!$i_type) { $DBRole = DBRole::loadById($DBServer->roleId); $i_type = $DBRole->getProperty(EC2_SERVER_PROPERTIES::INSTANCE_TYPE); } $launchOptions->serverType = $i_type; foreach ($DBServer->GetCloudUserData() as $k => $v) { $u_data .= "{$k}={$v};"; } $RunInstancesType->SetUserData(trim($u_data, ";")); $vpcPrivateIp = $DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_AWS_VPC_PRIVATE_IP); $vpcSubnetId = $DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_AWS_VPC_SUBNET_ID); if ($vpcSubnetId) { $RunInstancesType->subnetId = $vpcSubnetId; if ($vpcPrivateIp) { $RunInstancesType->privateIpAddress = $vpcPrivateIp; } } } else { $RunInstancesType->SetUserData(trim($launchOptions->userData)); } $DBServer->SetProperty(SERVER_PROPERTIES::ARCHITECTURE, $launchOptions->architecture); $EC2Client = Scalr_Service_Cloud_Aws::newEc2($launchOptions->cloudLocation, $DBServer->GetEnvironmentObject()->getPlatformConfigValue(self::PRIVATE_KEY), $DBServer->GetEnvironmentObject()->getPlatformConfigValue(self::CERTIFICATE)); // Set AMI, AKI and ARI ids $RunInstancesType->imageId = $launchOptions->imageId; if (!$RunInstancesType->subnetId) { // Set Security groups foreach ($this->GetServerSecurityGroupsList($DBServer, $EC2Client) as $sgroup) { $RunInstancesType->AddSecurityGroup($sgroup); } } $RunInstancesType->minCount = 1; $RunInstancesType->maxCount = 1; // Set availability zone if (!$launchOptions->availZone) { $avail_zone = $this->GetServerAvailZone($DBServer, $EC2Client, $launchOptions); if ($avail_zone) { $RunInstancesType->SetAvailabilityZone($avail_zone); } } else { $RunInstancesType->SetAvailabilityZone($launchOptions->availZone); } // Set instance type $RunInstancesType->instanceType = $launchOptions->serverType; if (in_array($RunInstancesType->instanceType, array('cc1.4xlarge', 'cg1.4xlarge', 'cc2.8xlarge'))) { $placementGroup = $DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_AWS_CLUSTER_PG); if (!$placementGroup) { $placementGroup = "scalr-role-{$DBServer->farmRoleId}"; if (!$EC2Client->CreatePlacementGroup($placementGroup)) { throw new Exception(sprintf(_("Cannot launch new instance. Unable to create placement group: %s"), $result->faultstring)); } $DBServer->GetFarmRoleObject()->SetSetting(DBFarmRole::SETTING_AWS_CLUSTER_PG, $placementGroup); } $RunInstancesType->SetPlacementGroup($placementGroup); } // Set additional info $RunInstancesType->additionalInfo = ""; ///// if ($DBServer->status == SERVER_STATUS::TEMPORARY) { $keyName = "SCALR-ROLESBUILDER"; $sshKey = Scalr_Model::init(Scalr_Model::SSH_KEY); if (!$sshKey->loadGlobalByName($keyName, $launchOptions->cloudLocation, $DBServer->envId)) { $result = $EC2Client->CreateKeyPair($keyName); if ($result->keyMaterial) { $sshKey->farmId = 0; $sshKey->clientId = $DBServer->clientId; $sshKey->envId = $DBServer->envId; $sshKey->type = Scalr_SshKey::TYPE_GLOBAL; $sshKey->cloudLocation = $launchOptions->cloudLocation; $sshKey->cloudKeyName = $keyName; $sshKey->platform = SERVER_PLATFORMS::EC2; $sshKey->setPrivate($result->keyMaterial); $sshKey->setPublic($sshKey->generatePublicKey()); $sshKey->save(); } } } else { $sshKey = Scalr_Model::init(Scalr_Model::SSH_KEY)->loadGlobalByFarmId($DBServer->farmId, $DBServer->GetProperty(EC2_SERVER_PROPERTIES::REGION)); $keyName = $sshKey->cloudKeyName; } ///// $RunInstancesType->keyName = $keyName; try { $result = $EC2Client->RunInstances($RunInstancesType); } catch (Exception $e) { if (stristr($e->getMessage(), "key pair") && stristr($e->getMessage(), "does not exist")) { $result = $EC2Client->CreateKeyPair($keyName); if ($result->keyMaterial) { $sshKey->setPrivate($result->keyMaterial); $sshKey->setPublic($sshKey->generatePublicKey()); $sshKey->save(); } //Your requested instance type (m2.2xlarge) is not supported in your requested Availability Zone (us-east-1a). Please retry your request by not specifying an Availability Zone or choosing us-east-1c, us-east-1b, us-east-1 } else { if (stristr($e->getMessage(), "The requested Availability Zone is no longer supported") || stristr($e->getMessage(), "is not supported in your requested Availability Zone")) { $availZone = $RunInstancesType->placement->availabilityZone; $DBServer->GetEnvironmentObject()->setPlatformConfig(array("aws.{$launchOptions->cloudLocation}.{$availZone}.unavailable" => time()), false); throw $e; } else { throw $e; } } } if ($result->instancesSet) { $DBServer->SetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE, (string) $result->instancesSet->item->placement->availabilityZone); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID, (string) $result->instancesSet->item->instanceId); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::INSTANCE_TYPE, $RunInstancesType->instanceType); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::AMIID, $RunInstancesType->imageId); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::REGION, $launchOptions->cloudLocation); try { if ($DBServer->farmId != 0) { $CreateTagsType = new CreateTagsType(array((string) $result->instancesSet->item->instanceId), array("scalr-farm-id" => $DBServer->farmId, "scalr-farm-name" => $DBServer->GetFarmObject()->Name, "scalr-farm-role-id" => $DBServer->farmRoleId, "scalr-role-name" => $DBServer->GetFarmRoleObject()->GetRoleObject()->name, "scalr-server-id" => $DBServer->serverId)); $EC2Client->CreateTags($CreateTagsType); } } catch (Exception $e) { Logger::getLogger('EC2')->warn("Cannot add tags to server: {$e->getMessage()}"); } return $DBServer; } else { throw new Exception(sprintf(_("Cannot launch new instance. %s"), serialize($result))); } }
public static function farmUpdateRoleSettings(DBFarmRole $DBFarmRole, $oldSettings, $newSettings) { try { $DBFarm = $DBFarmRole->GetFarmObject(); $Client = Client::Load($DBFarm->ClientID); $AmazonELB = Scalr_Service_Cloud_Aws::newElb($DBFarmRole->CloudLocation, $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY)); // Load balancer settings if ($newSettings[DBFarmRole::SETTING_BALANCING_USE_ELB] == 1) { // Listeners $DBFarmRole->ClearSettings("lb.role.listener"); $ELBListenersList = new ELBListenersList(); $li = 0; foreach ($newSettings as $sk => $sv) { if (stristr($sk, "lb.role.listener")) { $li++; $listener_chunks = explode("#", $sv); $ELBListenersList->AddListener($listener_chunks[0], $listener_chunks[1], $listener_chunks[2], $listener_chunks[3]); $DBFarmRole->SetSetting("lb.role.listener.{$li}", $sv); } } $avail_zones = array(); $avail_zones_setting_hash = ""; foreach ($newSettings as $skey => $sval) { if (preg_match("/^lb.avail_zone.(.*)?\$/", $skey, $macthes)) { if ($macthes[1] != 'hash' && $macthes[1] != '.hash') { if ($sval == 1) { array_push($avail_zones, $macthes[1]); } $avail_zones_setting_hash .= "[{$macthes[1]}:{$sval}]"; } } } if (!$DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME)) { $elb_name = sprintf("scalr-%s-%s", $DBFarm->Hash, rand(100, 999)); //CREATE NEW ELB $elb_dns_name = $AmazonELB->CreateLoadBalancer($elb_name, $avail_zones, $ELBListenersList); if ($elb_dns_name) { $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME, $elb_dns_name); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_NAME, $elb_name); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH, $avail_zones_setting_hash); $register_servers = true; } } if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME)) { $ELBHealthCheckType = new ELBHealthCheckType($newSettings[DBFarmRole::SETTING_BALANCING_HC_TARGET], $newSettings[DBFarmRole::SETTING_BALANCING_HC_HTH], $newSettings[DBFarmRole::SETTING_BALANCING_HC_INTERVAL], $newSettings[DBFarmRole::SETTING_BALANCING_HC_TIMEOUT], $newSettings[DBFarmRole::SETTING_BALANCING_HC_UTH]); $hash = md5(serialize($ELBHealthCheckType)); if ($elb_name || $hash != $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH)) { //UPDATE CURRENT ELB $AmazonELB->ConfigureHealthCheck($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $ELBHealthCheckType); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH, $hash); } // Configure AVAIL zones for the LB if (!$elb_name && $avail_zones_setting_hash != $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH)) { $info = $AmazonELB->DescribeLoadBalancers(array($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME))); $elb = $info->DescribeLoadBalancersResult->LoadBalancerDescriptions->member; $c = (array) $elb->AvailabilityZones; if (!is_array($c['member'])) { $c_zones = array($c['member']); } else { $c_zones = $c['member']; } $add_avail_zones = array(); $rem_avail_zones = array(); foreach ($newSettings as $skey => $sval) { if (preg_match("/^lb.avail_zone.(.*)?\$/", $skey, $m)) { if ($sval == 1 && !in_array($m[1], $c_zones)) { array_push($add_avail_zones, $m[1]); } if ($sval == 0 && in_array($m[1], $c_zones)) { array_push($rem_avail_zones, $m[1]); } } } if (count($add_avail_zones) > 0) { $AmazonELB->EnableAvailabilityZonesForLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $add_avail_zones); } if (count($rem_avail_zones) > 0) { $AmazonELB->DisableAvailabilityZonesForLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $rem_avail_zones); } $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH, $avail_zones_setting_hash); } } if ($register_servers) { $servers = $DBFarmRole->GetServersByFilter(array('status' => SERVER_STATUS::RUNNING)); $instances = array(); foreach ($servers as $DBServer) { $instances[] = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID); } if (count($instances) > 0) { $AmazonELB->RegisterInstancesWithLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $instances); } } } else { if ($oldSettings[DBFarmRole::SETTING_BALANCING_HOSTNAME]) { try { $AmazonELB->DeleteLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME)); } catch (Exception $e) { } $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_NAME, ""); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME, ""); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_USE_ELB, "0"); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH, ""); $DBFarmRole->ClearSettings("lb.avail_zone"); $DBFarmRole->ClearSettings("lb.healthcheck"); $DBFarmRole->ClearSettings("lb.role.listener"); } } } catch (Exception $e) { throw new Exception("Error with ELB on Role '{$DBFarmRole->GetRoleObject()->name}': {$e->getMessage()}"); } }
function handleWork($farmId) { $DBFarm = DBFarm::LoadByID($farmId); $GLOBALS["SUB_TRANSACTIONID"] = abs(crc32(posix_getpid() . $farmId)); $GLOBALS["LOGGER_FARMID"] = $farmId; if ($DBFarm->Status != FARM_STATUS::RUNNING) { $this->logger->warn("[FarmID: {$DBFarm->ID}] Farm terminated. There is no need to scale it."); return; } foreach ($DBFarm->GetFarmRoles() as $DBFarmRole) { for ($i = 0; $i < 10; $i++) { if ($DBFarmRole->NewRoleID != '') { $this->logger->warn("[FarmID: {$DBFarm->ID}] Role '{$DBFarmRole->GetRoleObject()->name}' being synchronized. This role will not be scalled."); continue 2; } if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_ENABLED) == '0' && !$DBFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MONGODB)) { $this->logger->info("[FarmID: {$DBFarm->ID}] Scaling disabled for role '{$DBFarmRole->GetRoleObject()->name}'. Skipping..."); continue 2; } // Get polling interval in seconds $polling_interval = $DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_POLLING_INTERVAL) * 60; $dt_last_polling = $DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_LAST_POLLING_TIME); if ($dt_last_polling && $dt_last_polling + $polling_interval > time() && $i == 0) { $this->logger->info("Polling interval: every {$polling_interval} seconds"); //continue; } // Set Last polling time $DBFarmRole->SetSetting(DBFarmRole::SETTING_SCALING_LAST_POLLING_TIME, time()); // Get current count of running and pending instances. $this->logger->info(sprintf("Processing role '%s'", $DBFarmRole->GetRoleObject()->name)); $scalingManager = new Scalr_Scaling_Manager($DBFarmRole); $scalingDecision = $scalingManager->makeScalingDecition(); if ($scalingDecision == Scalr_Scaling_Decision::STOP_SCALING) { return; } if ($scalingDecision == Scalr_Scaling_Decision::NOOP) { continue 2; } elseif ($scalingDecision == Scalr_Scaling_Decision::DOWNSCALE) { /* Timeout instance's count decrease. Decreases instance�s count after scaling resolution the spare instances are running�g for selected timeout interval from scaling EditOptions */ // We have to check timeout limits before new scaling (downscaling) process will be initiated if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_DOWNSCALE_TIMEOUT_ENABLED)) { // if the farm timeout is exceeded // checking timeout interval. $last_down_scale_data_time = $DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_DOWNSCALE_DATETIME); $timeout_interval = $DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_DOWNSCALE_TIMEOUT); // check the time interval to continue scaling or cancel it... if (time() - $last_down_scale_data_time < $timeout_interval * 60) { // if the launch time is too small to terminate smth in this role -> go to the next role in foreach() Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($DBFarm->ID, sprintf("Waiting for downscaling timeout on farm %s, role %s", $DBFarm->Name, $DBFarmRole->GetRoleObject()->name))); continue 2; } } // end Timeout instance's count decrease $sort = $DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_KEEP_OLDEST) == 1 ? 'DESC' : 'ASC'; $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status = ? AND farm_roleid=? ORDER BY dtadded {$sort}", array(SERVER_STATUS::RUNNING, $DBFarmRole->ID)); $got_valid_instance = false; // Select instance that will be terminated // // * Instances ordered by uptime (oldest wil be choosen) // * Instance cannot be mysql master // * Choose the one that was rebundled recently while (!$got_valid_instance && count($servers) > 0) { $item = array_shift($servers); $DBServer = DBServer::LoadByID($item['server_id']); if ($DBServer->GetFarmRoleObject()->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::RABBITMQ)) { $serversCount = count($DBServer->GetFarmRoleObject()->GetServersByFilter(array(), array('status' => SERVER_STATUS::TERMINATED))); if ($DBServer->index == 1 && $serversCount > 1) { continue; } } // Exclude db master if ($DBServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) != 1 && $DBServer->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER) != 1) { /* * We do not want to delete the most recently synced instance. Because of LA fluctuation. * I.e. LA may skyrocket during sync and drop dramatically after sync. */ if ($DBServer->dateLastSync != 0) { $chk_sync_time = $this->db->GetOne("SELECT server_id FROM servers \n\t \t\tWHERE dtlastsync > {$DBServer->dateLastSync} \n\t\t \tAND farm_roleid='{$DBServer->farmRoleId}' AND status != '" . SERVER_STATUS::TERMINATED . "'"); if ($chk_sync_time) { $got_valid_instance = true; } } else { $got_valid_instance = true; } } } if ($DBServer && $got_valid_instance) { $this->logger->info(sprintf("Server '%s' selected for termination...", $DBServer->serverId)); $allow_terminate = false; if ($DBServer->platform == SERVER_PLATFORMS::EC2) { $AmazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($DBServer->GetProperty(EC2_SERVER_PROPERTIES::REGION), $DBServer->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $DBServer->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); // Shutdown an instance just before a full hour running $response = $AmazonEC2Client->DescribeInstances($DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID)); if ($response && $response->reservationSet->item) { $launch_time = strtotime($response->reservationSet->item->instancesSet->item->launchTime); $time = 3600 - (time() - $launch_time) % 3600; // Terminate instance in < 10 minutes for full hour. if ($time <= 600) { $allow_terminate = true; } else { $timeout = round(($time - 600) / 60, 1); Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($DBFarm->ID, sprintf("Farm %s, role %s scaling down. Server '%s' will be terminated in %s minutes. Launch time: %s", $DBFarm->Name, $DBServer->GetFarmRoleObject()->GetRoleObject()->name, $DBServer->serverId, $timeout, $response->reservationSet->item->instancesSet->item->launchTime))); } } // } else { $allow_terminate = true; } if ($allow_terminate) { //Check safe shutdown if ($DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_SCALING_SAFE_SHUTDOWN) == 1) { $snmpClient = new Scalr_Net_Snmp_Client(); $port = $DBServer->GetProperty(SERVER_PROPERTIES::SZR_SNMP_PORT); $snmpClient->connect($DBServer->remoteIp, $port ? $port : 161, $DBFarm->Hash, null, null, false); $res = $snmpClient->get('1.3.6.1.4.1.36632.6.1'); if ($res != '1') { Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($DBFarm->ID, sprintf("Safe shutdown enabled. Server '%s'. Script return '%s', server won't be terminated while return value not '1'", $DBServer->serverId, $res))); } } try { Scalr::FireEvent($DBFarm->ID, new BeforeHostTerminateEvent($DBServer, false)); $DBFarmRole->SetSetting(DBFarmRole::SETTING_SCALING_DOWNSCALE_DATETIME, time()); Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($DBFarm->ID, sprintf("Farm %s, role %s scaling down. Server '%s' marked as 'Pending terminate' and will be fully terminated in 3 minutes.", $DBFarm->Name, $DBServer->GetFarmRoleObject()->GetRoleObject()->name, $DBServer->serverId))); } catch (Exception $e) { $this->logger->fatal(sprintf("Cannot terminate %s: %s", $DBFarm->ID, $DBServer->serverId, $e->getMessage())); } } } else { $this->logger->warn(sprintf("[FarmID: {$DBFarm->ID}] Scalr unable to determine what instance it should terminate (FarmRoleID: {$DBFarmRole->ID}). Skipping...")); } break; } elseif ($scalingDecision == Scalr_Scaling_Decision::UPSCALE) { /* Timeout instance's count increase. Increases instance's count after scaling resolution �need more instances� for selected timeout interval from scaling EditOptions */ if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_UPSCALE_TIMEOUT_ENABLED)) { // if the farm timeout is exceeded // checking timeout interval. $last_up_scale_data_time = $DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_UPSCALE_DATETIME); $timeout_interval = $DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_UPSCALE_TIMEOUT); // check the time interval to continue scaling or cancel it... if (time() - $last_up_scale_data_time < $timeout_interval * 60) { // if the launch time is too small to terminate smth in this role -> go to the next role in foreach() Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($DBFarm->ID, sprintf("Waiting for upscaling timeout on farm %s, role %s", $DBFarm->Name, $DBFarmRole->GetRoleObject()->name))); continue 2; } } // end Timeout instance's count increase if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_ONE_BY_ONE) == 1) { $pendingInstances = $DBFarmRole->GetPendingInstancesCount(); if ($pendingInstances > 0) { Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($DBFarm->ID, sprintf("There are %s pending intances of %s role on % farm. Waiting...", $pendingInstances, $DBFarmRole->GetRoleObject()->name, $DBFarm->Name))); continue 2; } } $fstatus = $this->db->GetOne("SELECT status FROM farms WHERE id=?", array($DBFarm->ID)); if ($fstatus != FARM_STATUS::RUNNING) { $this->logger->warn("[FarmID: {$DBFarm->ID}] Farm terminated. There is no need to scale it."); return; } $ServerCreateInfo = new ServerCreateInfo($DBFarmRole->Platform, $DBFarmRole); try { $DBServer = Scalr::LaunchServer($ServerCreateInfo); $DBFarmRole->SetSetting(DBFarmRole::SETTING_SCALING_UPSCALE_DATETIME, time()); Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($DBFarm->ID, sprintf("Farm %s, role %s scaling up. Starting new instance. ServerID = %s.", $DBFarm->Name, $DBServer->GetFarmRoleObject()->GetRoleObject()->name, $DBServer->serverId))); } catch (Exception $e) { Logger::getLogger(LOG_CATEGORY::SCALING)->error($e->getMessage()); } } } } }
public static function farmSave(DBFarm $DBFarm, array $roles) { $buckets = array(); foreach ($roles as $DBFarmRole) { if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_S3_BUCKET)) { $buckets[$DBFarmRole->CloudLocation] = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_S3_BUCKET); } } foreach ($roles as $DBFarmRole) { if ($DBFarmRole->Platform != SERVER_PLATFORMS::EC2) { continue; } $location = $DBFarmRole->CloudLocation; $sshKey = Scalr_Model::init(Scalr_Model::SSH_KEY); if (!$sshKey->loadGlobalByFarmId($DBFarm->ID, $location)) { $key_name = "FARM-{$DBFarm->ID}"; $AmazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($location, $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); $result = $AmazonEC2Client->CreateKeyPair($key_name); if ($result->keyMaterial) { $sshKey->farmId = $DBFarm->ID; $sshKey->clientId = $DBFarm->ClientID; $sshKey->envId = $DBFarm->EnvID; $sshKey->type = Scalr_SshKey::TYPE_GLOBAL; $sshKey->cloudLocation = $location; $sshKey->cloudKeyName = $key_name; $sshKey->platform = SERVER_PLATFORMS::EC2; $sshKey->setPrivate($result->keyMaterial); $sshKey->save(); } } try { if (!$DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_S3_BUCKET)) { if (!$buckets[$location]) { $aws_account_id = $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCOUNT_ID); $bucket_name = "farm-{$DBFarm->Hash}-{$aws_account_id}-{$location}"; // // Create S3 Bucket (For MySQL, BackUs, etc.) // $AmazonS3 = new AmazonS3($DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY)); $buckets = $AmazonS3->ListBuckets(); $create_bucket = true; foreach ($buckets as $bucket) { if ($bucket->Name == $bucket_name) { $create_bucket = false; $buckets[$location] = $bucket_name; break; } } if ($create_bucket) { if ($AmazonS3->CreateBucket($bucket_name, $location)) { $buckets[$location] = $bucket_name; } } } $DBFarmRole->SetSetting(DBFarmRole::SETTING_AWS_S3_BUCKET, $buckets[$location]); } } catch (Exception $e) { throw new Exception("Amazon S3: {$e->getMessage()}"); } } }