public function getConfiguration(DBServer $dbServer) { $configuration = new stdClass(); $configuration->proxies = json_decode($dbServer->GetFarmRoleObject()->GetSetting(self::ROLE_PROXIES), true); $dbFarm = $dbServer->GetFarmObject(); if (count($configuration->proxies) > 0) { foreach ($configuration->proxies as &$proxy) { if (count($proxy['backends']) > 0) { foreach ($proxy['backends'] as &$backend) { if (isset($backend['farm_role_alias']) && !empty($backend['farm_role_alias'])) { $backend['farm_role_id'] = $dbFarm->GetFarmRoleIdByAlias($backend['farm_role_alias']); } } } } } return $configuration; }
/** * Checks whether specified server can be accessed by the user * * @param \DBServer $dbServer The DBServer object * @return boolean Returns true if specified server can be accessed by the user * @throws \Scalr_Exception_Core */ public function hasAccessServer(\DBServer $dbServer) { $access = $this->hasAccessEnvironment($dbServer->envId); if ($access && !empty($dbServer->farmId) && ($dbFarm = $dbServer->GetFarmObject()) instanceof \DBFarm) { $access = $this->hasAccessFarm($dbFarm); } return $access; }
public static function onPromoteToMasterResult(Scalr_Messaging_Msg_DbMsr_PromoteToMasterResult $message, DBServer $dbServer) { $dbFarm = $dbServer->GetFarmObject(); $dbFarmRole = $dbServer->GetFarmRoleObject(); $dbFarmRole->SetSetting(Scalr_Db_Msr::SLAVE_TO_MASTER, 0); if ($message->status == Scalr_Messaging_Msg_Mysql_PromoteToMasterResult::STATUS_FAILED) { $dbServer->SetProperty(Scalr_Db_Msr::REPLICATION_MASTER, 0); return false; } $dbSettings = $message->{$message->dbType}; //Update volumeCondig if ($dbSettings->volumeConfig) { try { $storageVolume = Scalr_Storage_Volume::init(); try { $storageVolume->loadById($dbSettings->volumeConfig->id); $storageVolume->setConfig($dbSettings->volumeConfig); $storageVolume->save(); } catch (Exception $e) { if (strpos($e->getMessage(), 'not found')) { $storageVolume->loadBy(array('id' => $dbSettings->volumeConfig->id, 'client_id' => $dbServer->clientId, 'env_id' => $dbServer->envId, 'name' => "'{$message->dbType}' data volume", 'type' => $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_ENGINE), 'platform' => $dbServer->platform, 'size' => $dbSettings->volumeConfig->size, 'fstype' => $dbSettings->volumeConfig->fstype, 'purpose' => $message->dbType, 'farm_roleid' => $dbFarmRole->ID, 'server_index' => $dbServer->index)); $storageVolume->setConfig($dbSettings->volumeConfig); $storageVolume->save(true); } else { throw $e; } } } catch (Exception $e) { Logger::getLogger(__CLASS__)->error(new FarmLogMessage($dbServer->farmId, "Cannot save storage volume: {$e->getMessage()}")); } } self::onCreateDataBundleResult($message, $dbServer); return true; }
/** * @param Scalr_Messaging_Msg_Mysql_PromoteToMasterResult $message * @param DBServer $dbserver */ private function onMysql_PromoteToMasterResult($message, DBServer $dbserver) { $dbserver->GetFarmRoleObject()->SetSetting(DBFarmRole::SETTING_MYSQL_SLAVE_TO_MASTER, 0); if ($message->status == Scalr_Messaging_Msg_Mysql_PromoteToMasterResult::STATUS_OK) { $dbFarm = $dbserver->GetFarmObject(); $dbFarmRole = $dbserver->GetFarmRoleObject(); $oldMaster = $dbFarm->GetMySQLInstances(true); if ($dbserver->IsSupported("0.7")) { if ($message->volumeConfig) { try { $storageVolume = Scalr_Storage_Volume::init(); try { $storageVolume->loadById($message->volumeConfig->id); $storageVolume->setConfig($message->volumeConfig); $storageVolume->save(); } catch (Exception $e) { if (strpos($e->getMessage(), 'not found')) { $storageVolume->loadBy(array('id' => $message->volumeConfig->id, 'client_id' => $dbserver->clientId, 'env_id' => $dbserver->envId, 'name' => "MySQL data volume", 'type' => $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_DATA_STORAGE_ENGINE), 'platform' => $dbserver->platform, 'size' => $message->volumeConfig->size, 'fstype' => $message->volumeConfig->fstype, 'purpose' => ROLE_BEHAVIORS::MYSQL, 'farm_roleid' => $dbserver->farmRoleId, 'server_index' => $dbserver->index)); $storageVolume->setConfig($message->volumeConfig); $storageVolume->save(true); } else { throw $e; } } } catch (Exception $e) { $this->logger->error(new FarmLogMessage($dbserver->farmId, "Cannot save storage volume: {$e->getMessage()}")); } } if ($message->snapshotConfig) { try { $snapshot = Scalr_Model::init(Scalr_Model::STORAGE_SNAPSHOT); $snapshot->loadBy(array('id' => $message->snapshotConfig->id, 'client_id' => $dbserver->clientId, 'env_id' => $dbserver->envId, 'name' => "Automatical MySQL data bundle", 'type' => $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_DATA_STORAGE_ENGINE), 'platform' => $dbserver->platform, 'description' => "MySQL data bundle created automatically by Scalr", 'ismysql' => true)); $snapshot->setConfig($message->snapshotConfig); $snapshot->save(true); $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_SCALR_SNAPSHOT_ID, $snapshot->id); $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_LOG_FILE, $message->logFile); $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_LOG_POS, $message->logPos); } catch (Exception $e) { $this->logger->error(new FarmLogMessage($dbserver->farmId, "Cannot save storage snapshot: {$e->getMessage()}")); } } } else { // TODO: delete old slave volume if new one was created $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_MASTER_EBS_VOLUME_ID, $message->volumeId); } return new NewMysqlMasterUpEvent($dbserver, "", $oldMaster[0]); } elseif ($message->status == Scalr_Messaging_Msg_Mysql_PromoteToMasterResult::STATUS_FAILED) { $dbserver->SetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER, 0); $dbserver->SetProperty(Scalr_Db_Msr::REPLICATION_MASTER, 0); // XXX: Need to do smth $this->logger->error(sprintf("Promote to Master failed for server %s. Last error: %s", $dbserver->serverId, $message->lastError)); } }
/** * Checks whether user read only access to specified server * * @param \DBServer $dbServer The DBServer object * @return boolean Returns true if specified server can be accessed by the user * @throws \Scalr_Exception_Core */ public function hasReadOnlyAccessServer(\DBServer $dbServer) { $access = $this->hasAccessEnvironment($dbServer->envId); if ($access) { if (!empty($dbServer->farmId)) { if (($dbFarm = $dbServer->GetFarmObject()) instanceof \DBFarm) { $access = $this->hasAccessFarm($dbFarm); } } else { $access = $this->user->getAclRolesByEnvironment($this->envId)->isAllowed(Acl::RESOURCE_IMAGES_ENVIRONMENT, Acl::PERM_IMAGES_ENVIRONMENT_MANAGE); } } return $access; }
/** * Checks whether specified server can be accessed by the user * * @param \DBServer $dbServer The DBServer object * @return boolean Returns true if specified server can be accessed by the user * @throws \Scalr_Exception_Core */ public function hasAccessServer(\DBServer $dbServer) { $access = $this->hasAccessEnvironment($dbServer->envId); if ($access) { if (!empty($dbServer->farmId)) { if (($dbFarm = $dbServer->GetFarmObject()) instanceof \DBFarm) { $access = $this->hasAccessFarm($dbFarm, Acl::PERM_FARMS_SERVERS); } } else { $access = $this->user->getAclRolesByEnvironment($this->envId)->isAllowed(Acl::RESOURCE_FARMS_ROLES, Acl::PERM_FARMS_ROLES_CREATE); } } return $access; }
/** * {@inheritdoc} * @see IPlatformModule::LaunchServer() */ public function LaunchServer(DBServer $DBServer, Scalr_Server_LaunchOptions $launchOptions = null) { $runInstanceRequest = new RunInstancesRequestData(isset($launchOptions->imageId) ? $launchOptions->imageId : null, 1, 1); $environment = $DBServer->GetEnvironmentObject(); $placementData = null; $noSecurityGroups = false; if (!$launchOptions) { $launchOptions = new Scalr_Server_LaunchOptions(); $DBRole = DBRole::loadById($DBServer->roleId); $dbFarmRole = $DBServer->GetFarmRoleObject(); $runInstanceRequest->setMonitoring($dbFarmRole->GetSetting(DBFarmRole::SETTING_AWS_ENABLE_CW_MONITORING)); $launchOptions->imageId = $DBRole->getImageId(SERVER_PLATFORMS::EC2, $dbFarmRole->CloudLocation); // Need OS Family to get block device mapping for OEL roles $imageInfo = $DBRole->getImageDetails(SERVER_PLATFORMS::EC2, $dbFarmRole->CloudLocation); $launchOptions->osFamily = $imageInfo['os_family']; $launchOptions->cloudLocation = $dbFarmRole->CloudLocation; $akiId = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::AKIID); if (!$akiId) { $akiId = $dbFarmRole->GetSetting(DBFarmRole::SETTING_AWS_AKI_ID); } if ($akiId) { $runInstanceRequest->kernelId = $akiId; } $ariId = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::ARIID); if (!$ariId) { $ariId = $dbFarmRole->GetSetting(DBFarmRole::SETTING_AWS_ARI_ID); } if ($ariId) { $runInstanceRequest->ramdiskId = $ariId; } $i_type = $dbFarmRole->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; if ($dbFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_OPTIMIZED) == 1) { $runInstanceRequest->ebsOptimized = true; } else { $runInstanceRequest->ebsOptimized = false; } foreach ($DBServer->GetCloudUserData() as $k => $v) { $u_data .= "{$k}={$v};"; } $runInstanceRequest->userData = base64_encode(trim($u_data, ";")); $vpcId = $dbFarmRole->GetFarmObject()->GetSetting(DBFarm::SETTING_EC2_VPC_ID); if ($vpcId) { if ($DBRole->hasBehavior(ROLE_BEHAVIORS::VPC_ROUTER)) { $networkInterface = new InstanceNetworkInterfaceSetRequestData(); $networkInterface->networkInterfaceId = $dbFarmRole->GetSetting(Scalr_Role_Behavior_Router::ROLE_VPC_NID); $networkInterface->deviceIndex = 0; $networkInterface->deleteOnTermination = false; $runInstanceRequest->setNetworkInterface($networkInterface); $noSecurityGroups = true; } else { $vpcSubnetId = $dbFarmRole->GetSetting(DBFarmRole::SETTING_AWS_VPC_SUBNET_ID); $vpcInternetAccess = $dbFarmRole->GetSetting(DBFarmRole::SETTING_AWS_VPC_INTERNET_ACCESS); if (!$vpcSubnetId) { $aws = $environment->aws($launchOptions->cloudLocation); $subnet = $this->AllocateNewSubnet($aws->ec2, $vpcId, $dbFarmRole->GetSetting(DBFarmRole::SETTING_AWS_VPC_AVAIL_ZONE), 24); try { $subnet->createTags(array(array('key' => "scalr-id", 'value' => SCALR_ID), array('key' => "scalr-sn-type", 'value' => $vpcInternetAccess), array('key' => "Name", 'value' => 'Scalr System Subnet'))); } catch (Exception $e) { } try { $routeTableId = $dbFarmRole->GetSetting(DBFarmRole::SETTING_AWS_VPC_ROUTING_TABLE_ID); Logger::getLogger('VPC')->warn(new FarmLogMessage($DBServer->farmId, "Internet access: {$vpcInternetAccess}")); if (!$routeTableId) { if ($vpcInternetAccess == Scalr_Role_Behavior_Router::INTERNET_ACCESS_OUTBOUND) { $routerRole = $DBServer->GetFarmObject()->GetFarmRoleByBehavior(ROLE_BEHAVIORS::VPC_ROUTER); if (!$routerRole) { if (\Scalr::config('scalr.instances_connection_policy') != 'local') { throw new Exception("Outbound access require VPC router role in farm"); } } $networkInterfaceId = $routerRole->GetSetting(Scalr_Role_Behavior_Router::ROLE_VPC_NID); Logger::getLogger('EC2')->warn(new FarmLogMessage($DBServer->farmId, "Requesting outbound routing table. NID: {$networkInterfaceId}")); $routeTableId = $this->getRoutingTable($vpcInternetAccess, $aws, $networkInterfaceId, $vpcId); Logger::getLogger('EC2')->warn(new FarmLogMessage($DBServer->farmId, "Routing table ID: {$routeTableId}")); } elseif ($vpcInternetAccess == Scalr_Role_Behavior_Router::INTERNET_ACCESS_FULL) { $routeTableId = $this->getRoutingTable($vpcInternetAccess, $aws, null, $vpcId); } } $aws->ec2->routeTable->associate($routeTableId, $subnet->subnetId); } catch (Exception $e) { Logger::getLogger('EC2')->warn(new FarmLogMessage($DBServer->farmId, "Removing allocated subnet, due to routing table issues")); $aws->ec2->subnet->delete($subnet->subnetId); throw $e; } $vpcSubnetId = $subnet->subnetId; $dbFarmRole->SetSetting(DBFarmRole::SETTING_AWS_VPC_SUBNET_ID, $vpcSubnetId, DBFarmRole::TYPE_LCL); } if ($vpcSubnetId) { $runInstanceRequest->subnetId = $vpcSubnetId; } else { throw new Exception("Unable to define subnetId for role in VPC"); } } } } else { $runInstanceRequest->userData = base64_encode(trim($launchOptions->userData)); } $governance = new Scalr_Governance($DBServer->envId); $aws = $environment->aws($launchOptions->cloudLocation); if (!$vpcId) { $vpcId = $environment->getPlatformConfigValue(self::DEFAULT_VPC_ID . ".{$launchOptions->cloudLocation}"); if ($vpcId === null || $vpcId === false) { $vpcId = ""; $list = $aws->ec2->describeAccountAttributes(array('default-vpc')); foreach ($list as $item) { if ($item->attributeName == 'default-vpc') { $vpcId = $item->attributeValueSet[0]->attributeValue; } } if ($vpcId == 'none') { $vpcId = ''; } $environment->setPlatformConfig(array(self::DEFAULT_VPC_ID . ".{$launchOptions->cloudLocation}" => $vpcId)); } } // Set AMI, AKI and ARI ids $runInstanceRequest->imageId = $launchOptions->imageId; $runInstanceRequest->instanceInitiatedShutdownBehavior = 'terminate'; if (!$noSecurityGroups) { foreach ($this->GetServerSecurityGroupsList($DBServer, $aws->ec2, $vpcId, $governance) as $sgroup) { $runInstanceRequest->appendSecurityGroupId($sgroup); } if (!$runInstanceRequest->subnetId) { // Set availability zone if (!$launchOptions->availZone) { $avail_zone = $this->GetServerAvailZone($DBServer, $aws->ec2, $launchOptions); if ($avail_zone) { $placementData = new PlacementResponseData($avail_zone); } } else { $placementData = new PlacementResponseData($launchOptions->availZone); } } } $runInstanceRequest->minCount = 1; $runInstanceRequest->maxCount = 1; // Set instance type $runInstanceRequest->instanceType = $launchOptions->serverType; if ($launchOptions->serverType == 'hi1.4xlarge' || $launchOptions->serverType == 'cc2.8xlarge' || $launchOptions->osFamily == 'oel') { foreach ($this->GetBlockDeviceMapping($launchOptions->serverType) as $bdm) { $runInstanceRequest->appendBlockDeviceMapping($bdm); } } if (in_array($runInstanceRequest->instanceType, array('cc1.4xlarge', 'cg1.4xlarge', 'cc2.8xlarge', 'hi1.4xlarge'))) { $placementGroup = $DBServer->GetFarmRoleObject()->GetSetting(DBFarmRole::SETTING_AWS_CLUSTER_PG); if (!$placementGroup && $runInstanceRequest->instanceType != 'hi1.4xlarge') { $placementGroup = "scalr-role-{$DBServer->farmRoleId}"; try { $aws->ec2->placementGroup->create($placementGroup); } catch (Exception $e) { if (!stristr($e->getMessage(), "already exists")) { 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, DBFarmRole::TYPE_LCL); } if ($placementGroup) { if ($placementData === null) { $placementData = new PlacementResponseData(null, $placementGroup); } else { $placementData->groupName = $placementGroup; } } } if ($placementData !== null) { $runInstanceRequest->setPlacement($placementData); } $sshKey = Scalr_SshKey::init(); if ($DBServer->status == SERVER_STATUS::TEMPORARY) { $keyName = "SCALR-ROLESBUILDER-" . SCALR_ID; $farmId = 0; } else { $keyName = $governance->getValue(Scalr_Governance::AWS_KEYPAIR); if ($keyName) { $skipKeyValidation = true; } else { $keyName = "FARM-{$DBServer->farmId}-" . SCALR_ID; $farmId = $DBServer->farmId; $oldKeyName = "FARM-{$DBServer->farmId}"; if ($sshKey->loadGlobalByName($oldKeyName, $launchOptions->cloudLocation, $DBServer->envId, SERVER_PLATFORMS::EC2)) { $keyName = $oldKeyName; $skipKeyValidation = true; } } } if (!$skipKeyValidation && !$sshKey->loadGlobalByName($keyName, $launchOptions->cloudLocation, $DBServer->envId, SERVER_PLATFORMS::EC2)) { $result = $aws->ec2->keyPair->create($keyName); if ($result->keyMaterial) { $sshKey->farmId = $farmId; $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(); } } $runInstanceRequest->keyName = $keyName; try { $result = $aws->ec2->instance->run($runInstanceRequest); } catch (Exception $e) { if (stristr($e->getMessage(), "The key pair") && stristr($e->getMessage(), "does not exist")) { $sshKey->delete(); throw $e; } if (stristr($e->getMessage(), "The requested Availability Zone is no longer supported") || stristr($e->getMessage(), "is not supported in your requested Availability Zone") || stristr($e->getMessage(), "is currently constrained and we are no longer accepting new customer requests")) { $availZone = $runInstanceRequest->getPlacement() ? $runInstanceRequest->getPlacement()->availabilityZone : null; if ($availZone) { $DBServer->GetEnvironmentObject()->setPlatformConfig(array("aws.{$launchOptions->cloudLocation}.{$availZone}.unavailable" => time())); } throw $e; } else { throw $e; } } if ($result->instancesSet->get(0)->instanceId) { $DBServer->SetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE, $result->instancesSet->get(0)->placement->availabilityZone); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID, $result->instancesSet->get(0)->instanceId); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::INSTANCE_TYPE, $runInstanceRequest->instanceType); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::AMIID, $runInstanceRequest->imageId); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::REGION, $launchOptions->cloudLocation); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::VPC_ID, $result->instancesSet->get(0)->vpcId); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::SUBNET_ID, $result->instancesSet->get(0)->subnetId); $DBServer->SetProperty(EC2_SERVER_PROPERTIES::ARCHITECTURE, $result->instancesSet->get(0)->architecture); $DBServer->osType = $result->instancesSet->get(0)->platform ? $result->instancesSet->get(0)->platform : 'linux'; return $DBServer; } else { throw new Exception(sprintf(_("Cannot launch new instance. %s"), serialize($result))); } }