This method ensures that aws instance is always from the
current environment scope.
public aws ( string | DBServer | DBFarmRole | DBEBSVolume $awsRegion = null, string $awsAccessKeyId = null, string $awsSecretAccessKey = null, string $certificate = null, string $privateKey = null ) : |
||
$awsRegion | string | DBServer | DBFarmRole | DBEBSVolume | optional The region or object which has both Scalr_Environment instance and cloud location itself |
$awsAccessKeyId | string | optional The AccessKeyId |
$awsSecretAccessKey | string | optional The SecretAccessKey |
$certificate | string | optional Contains x.509 certificate |
$privateKey | string | optional The private key for the certificate |
리턴 | Returns Aws instance |
private function saveEc2() { $pars = []; $enabled = false; $envAutoEnabled = false; $bNew = !$this->env->isPlatformEnabled(SERVER_PLATFORMS::EC2); $currentCloudCredentials = $this->env->keychain(SERVER_PLATFORMS::EC2); $ccProps = $currentCloudCredentials->properties; if ($this->getParam('ec2_is_enabled')) { $enabled = true; $pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_TYPE] = trim($this->checkVar(Entity\CloudCredentialsProperty::AWS_ACCOUNT_TYPE, 'string', "AWS Account Type required", SERVER_PLATFORMS::EC2)); $pars[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY] = trim($this->checkVar(Entity\CloudCredentialsProperty::AWS_ACCESS_KEY, 'string', "AWS Access Key required", SERVER_PLATFORMS::EC2)); $pars[Entity\CloudCredentialsProperty::AWS_SECRET_KEY] = trim($this->checkVar(Entity\CloudCredentialsProperty::AWS_SECRET_KEY, 'password', "AWS Access Key required", SERVER_PLATFORMS::EC2)); $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] = $this->checkVar(Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY, 'file', '', SERVER_PLATFORMS::EC2); $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] = $this->checkVar(Entity\CloudCredentialsProperty::AWS_CERTIFICATE, 'file', '', SERVER_PLATFORMS::EC2); if ($this->getContainer()->analytics->enabled) { $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_ENABLED] = $this->checkVar2(Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_ENABLED, 'bool', '', SERVER_PLATFORMS::EC2); if (!empty($pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_ENABLED])) { $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET] = $this->checkVar(Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET, 'string', "Detailed billing bucket name is required", SERVER_PLATFORMS::EC2); $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT] = $this->checkVar2(Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT, 'string', '', SERVER_PLATFORMS::EC2); $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_REGION] = $this->checkVar(Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_REGION, 'string', "Aws region is required", SERVER_PLATFORMS::EC2); } else { $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET] = false; $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT] = false; $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_REGION] = false; } } // user can mull certificate and private key, check it if (strpos($pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY], 'BEGIN CERTIFICATE') !== FALSE && strpos($pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE], 'BEGIN PRIVATE KEY') !== FALSE) { // swap it $key = $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY]; $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] = $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE]; $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] = $key; } if ($pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_TYPE] == Entity\CloudCredentialsProperty::AWS_ACCOUNT_TYPE_GOV_CLOUD) { $region = \Scalr\Service\Aws::REGION_US_GOV_WEST_1; } else { if ($pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_TYPE] == Entity\CloudCredentialsProperty::AWS_ACCOUNT_TYPE_CN_CLOUD) { $region = \Scalr\Service\Aws::REGION_CN_NORTH_1; } else { $region = \Scalr\Service\Aws::REGION_US_EAST_1; } } if (!count($this->checkVarError)) { if ($pars[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY] != $ccProps[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY] or $pars[Entity\CloudCredentialsProperty::AWS_SECRET_KEY] != $ccProps[Entity\CloudCredentialsProperty::AWS_SECRET_KEY] or $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] != $ccProps[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] or $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] != $ccProps[Entity\CloudCredentialsProperty::AWS_CERTIFICATE]) { $aws = $this->env->aws($region, $pars[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY], $pars[Entity\CloudCredentialsProperty::AWS_SECRET_KEY], !empty($pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE]) ? $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] : null, !empty($pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY]) ? $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] : null); //Validates private key and certificate if they are provided if (!empty($pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE]) || !empty($pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY])) { try { //SOAP is not supported anymore //$aws->validateCertificateAndPrivateKey(); } 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()})")); } } //Validates both access and secret keys try { $buckets = $aws->s3->bucket->getList(); } catch (Exception $e) { throw new Exception(sprintf(_("Failed to verify your EC2 access key and secret key: %s"), $e->getMessage())); } //Extract AWS Account ID $pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID] = $aws->getAccountNumber(); try { if ($ccProps[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID] != $pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID]) { $this->db->Execute("DELETE FROM client_environment_properties WHERE name LIKE 'ec2.vpc.default%' AND env_id = ?", [$this->env->id]); } } catch (Exception $e) { } } else { $pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID] = $ccProps[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID]; } } else { $this->response->failure(); $this->response->data(['errors' => $this->checkVarError]); return; } } if ($enabled && $this->getContainer()->analytics->enabled && !empty($pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET])) { try { $region = $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_REGION]; $aws = $this->env->aws($region, $pars[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY], $pars[Entity\CloudCredentialsProperty::AWS_SECRET_KEY]); if (!empty($pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT]) && $aws->getAccountNumber() != $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT]) { $payerCredentials = $this->getUser()->getAccount()->cloudCredentialsList([SERVER_PLATFORMS::EC2], [], [Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID => [['value' => $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT]]]]); if (count($payerCredentials) == 0) { throw new Exception("Payer account not found!"); } $payerCredentials = $payerCredentials->current(); $aws = $this->env->aws($region, $payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY], $payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_SECRET_KEY], !empty($payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_CERTIFICATE]) ? $payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] : null, !empty($payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY]) ? $payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] : null); } try { $bucketObjects = $aws->s3->bucket->listObjects($pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET]); } catch (ClientException $e) { if ($e->getErrorData() && $e->getErrorData()->getCode() == ErrorData::ERR_AUTHORIZATION_HEADER_MALFORMED && preg_match("/expecting\\s+'(.+?)'/", $e->getMessage(), $matches) && in_array($matches[1], Aws::getCloudLocations())) { $expectingRegion = $matches[1]; if (isset($payerCredentials)) { $aws = $this->env->aws($expectingRegion, $payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY], $payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_SECRET_KEY], !empty($payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_CERTIFICATE]) ? $payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] : null, !empty($payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY]) ? $payerCredentials->properties[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] : null); } else { $aws = $this->env->aws($expectingRegion, $pars[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY], $pars[Entity\CloudCredentialsProperty::AWS_SECRET_KEY]); } $bucketObjects = $aws->s3->bucket->listObjects($pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET]); $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_REGION] = $expectingRegion; } else { throw $e; } } $objectName = (empty($pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT]) ? '' : "{$pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT]}-") . 'aws-billing-detailed-line-items-with-resources-and-tags'; $objectExists = false; $bucketObjectName = null; foreach ($bucketObjects as $bucketObject) { /* @var $bucketObject Scalr\Service\Aws\S3\DataType\ObjectData */ if (strpos($bucketObject->objectName, $objectName) !== false) { $bucketObjectName = $bucketObject->objectName; $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_ENABLED] = 1; $objectExists = true; break; } } if (!$objectExists) { $this->response->failure(); $this->response->data(['errors' => [Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_PAYER_ACCOUNT => "Object with name '{$objectName}' does not exist."]]); return; } $aws->s3->object->getMetadata($pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET], $bucketObjectName); } catch (Exception $e) { $this->response->failure(); $this->response->data(['errors' => [Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET => sprintf("Cannot access billing bucket with name %s. Error: %s", $pars[Entity\CloudCredentialsProperty::AWS_DETAILED_BILLING_BUCKET], $e->getMessage())]]); return; } } $this->db->BeginTrans(); try { $this->env->enablePlatform(SERVER_PLATFORMS::EC2, $enabled); if ($enabled) { $this->makeCloudCredentials(SERVER_PLATFORMS::EC2, $pars); if ($this->getContainer()->analytics->enabled && $bNew) { $this->getContainer()->analytics->notifications->onCloudAdd('ec2', $this->env, $this->user); } } if (!$this->user->getAccount()->getSetting(Scalr_Account::SETTING_DATE_ENV_CONFIGURED)) { $this->user->getAccount()->setSetting(Scalr_Account::SETTING_DATE_ENV_CONFIGURED, time()); } //TODO: cloud suspension info must work with cloud credentials if ($enabled && $this->env->status == Scalr_Environment::STATUS_INACTIVE && $this->env->getPlatformConfigValue('system.auto-disable-reason')) { // env was inactive due invalid keys for amazon, activate it $this->env->status = Scalr_Environment::STATUS_ACTIVE; $this->env->save(); $this->env->setPlatformConfig(['system.auto-disable-reason' => NULL]); $envAutoEnabled = true; } $this->db->CommitTrans(); } catch (Exception $e) { $this->db->RollbackTrans(); throw new Exception(_("Failed to save AWS settings: {$e->getMessage()}")); } $this->response->success('Cloud credentials have been ' . ($enabled ? 'saved' : 'removed from Scalr')); $this->response->data(['enabled' => $enabled, 'demoFarm' => $demoFarm, 'envAutoEnabled' => $envAutoEnabled]); }
public function xSaveEc2Action() { $pars = array(); $enabled = false; $ccProps = $this->env->cloudCredentials(SERVER_PLATFORMS::EC2)->properties; if ($this->getParam('ec2_is_enabled')) { $enabled = true; $pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID] = $this->checkVar(Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID, 'string', "AWS Account Number required", SERVER_PLATFORMS::EC2); if (!is_numeric($pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID]) || strlen($pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID]) != 12) { //$err[Ec2PlatformModule::ACCOUNT_ID] = _("AWS numeric account ID required (See <a href='/faq.html'>FAQ</a> for info on where to get it)."); $this->checkVarError[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID] = _("AWS Account Number should be numeric"); } else { $pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID] = preg_replace("/[^0-9]+/", "", $pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID]); } $pars[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY] = $this->checkVar(Entity\CloudCredentialsProperty::AWS_ACCESS_KEY, 'string', "AWS Access Key required", SERVER_PLATFORMS::EC2); $pars[Entity\CloudCredentialsProperty::AWS_SECRET_KEY] = $this->checkVar(Entity\CloudCredentialsProperty::AWS_SECRET_KEY, 'password', "AWS Access Key required", SERVER_PLATFORMS::EC2); $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] = trim($this->checkVar(Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY, 'file', "AWS x.509 Private Key required", SERVER_PLATFORMS::EC2)); $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] = trim($this->checkVar(Entity\CloudCredentialsProperty::AWS_CERTIFICATE, 'file', "AWS x.509 Certificate required", SERVER_PLATFORMS::EC2)); // user can mull certificate and private key, check it if (strpos($pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY], 'BEGIN CERTIFICATE') !== FALSE && strpos($pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE], 'BEGIN PRIVATE KEY') !== FALSE) { // swap it $key = $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY]; $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] = $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE]; $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] = $key; } if (!count($this->checkVarError)) { if ($pars[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID] != $ccProps[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID] or $pars[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY] != $ccProps[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY] or $pars[Entity\CloudCredentialsProperty::AWS_SECRET_KEY] != $ccProps[Entity\CloudCredentialsProperty::AWS_SECRET_KEY] or $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] != $ccProps[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY] or $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE] != $ccProps[Entity\CloudCredentialsProperty::AWS_CERTIFICATE]) { try { $aws = $this->env->aws(\Scalr\Service\Aws::REGION_US_EAST_1, $pars[Entity\CloudCredentialsProperty::AWS_ACCESS_KEY], $pars[Entity\CloudCredentialsProperty::AWS_SECRET_KEY], $pars[Entity\CloudCredentialsProperty::AWS_CERTIFICATE], $pars[Entity\CloudCredentialsProperty::AWS_PRIVATE_KEY]); $aws->validateCertificateAndPrivateKey(); } 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 { $buckets = $aws->s3->bucket->getList(); } 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); if ($enabled) { $this->makeCloudCredentials(SERVER_PLATFORMS::EC2, $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->env->status == Scalr_Environment::STATUS_INACTIVE) { $this->env->status = Scalr_Environment::STATUS_ACTIVE; $this->env->save(); } $this->db->CommitTrans(); } catch (Exception $e) { $this->db->RollbackTrans(); throw new Exception(_("Failed to save AWS settings: {$e->getMessage()}")); } $demoFarm = false; $this->response->success('Environment saved'); $this->response->data(array('enabled' => $enabled, 'demoFarm' => $demoFarm)); }
/** * {@inheritdoc} * @see PlatformModuleInterface::getImageInfo() */ public function getImageInfo(\Scalr_Environment $environment, $cloudLocation, $imageId) { $info = []; $snap = $environment->aws($cloudLocation)->ec2->image->describe($imageId); if ($snap->count() > 0) { $sn = $snap->get(0); if ($sn->imageState == ImageData::STATE_AVAILABLE) { $info["name"] = $sn->name; $info["architecture"] = $sn->architecture; if ($sn->description) { $info["description"] = $sn->description; } if ($sn->platform) { // platform could be windows or empty string $info["osFamily"] = $sn->platform; } if ($sn->rootDeviceType == "ebs" || $sn->rootDeviceType == "instance-store") { $info["type"] = $sn->rootDeviceType; if ($sn->virtualizationType == "hvm") { $info["type"] .= "-hvm"; } } foreach ($sn->blockDeviceMapping as $b) { if ($b->deviceName == $sn->rootDeviceName && $b->ebs) { $info["size"] = $b->ebs->volumeSize; $info["ec2VolumeType"] = $b->ebs->volumeType; $info["ec2VolumeIops"] = $b->ebs->iops; } } } } return $info; }
public function getDefaultVpc(\Scalr_Environment $environment, $cloudLocation) { $vpcId = $environment->getPlatformConfigValue(self::DEFAULT_VPC_ID . ".{$cloudLocation}"); if ($vpcId === null || $vpcId === false) { $vpcId = ""; $aws = $environment->aws($cloudLocation); $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 . ".{$cloudLocation}" => $vpcId)); } return $vpcId; }
/** * Gets unused image id from the cloud * * @param \Scalr_Environment $env Scalr environment * @param string $cloudLocation Region * @return null|string */ protected function getNewImageId(\Scalr_Environment $env, $cloudLocation) { $aws = $env->aws($cloudLocation); $cloudImageId = null; $existedImages = []; foreach (Image::find([['platform' => \SERVER_PLATFORMS::EC2], ['cloudLocation' => $cloudLocation], ['envId' => static::$testEnvId]]) as $img) { /* @var $img Image */ $existedImages[$img->id] = $img; } foreach ($aws->ec2->image->describe(null, 'self') as $awsImage) { /* @var $awsImage \Scalr\Service\Aws\Ec2\DataType\ImageData */ if (!isset($existedImages[$awsImage->imageId])) { $cloudImageId = $awsImage->imageId; break; } } return $cloudImageId; }
/** * Gets the list of the EC2 instances * for the specified environment and AWS location * * @param Scalr_Environment $environment Environment Object * @param string $region EC2 location name * @param bool $skipCache Whether it should skip the cache. * @return array Returns array looks like array(InstanceId => stateName) */ public function GetServersList(Scalr_Environment $environment, $region, $skipCache = false) { if (!$region) { return array(); } if (empty($this->instancesListCache[$environment->id][$region]) || $skipCache) { try { $results = $environment->aws($region)->ec2->instance->describe(); } catch (Exception $e) { throw new Exception(sprintf("Cannot get list of servers for platfrom ec2: %s", $e->getMessage())); } if (count($results)) { foreach ($results as $reservation) { /* @var $reservation Scalr\Service\Aws\Ec2\DataType\ReservationData */ foreach ($reservation->instancesSet as $instance) { /* @var $instance Scalr\Service\Aws\Ec2\DataType\InstanceData */ $this->instancesListCache[$environment->id][$region][$instance->instanceId] = $instance->instanceState->name; } } } } return !empty($this->instancesListCache[$environment->id][$region]) ? $this->instancesListCache[$environment->id][$region] : array(); }
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')); $pars[Modules_Platforms_Ec2::CERTIFICATE] = trim($this->checkVar(Modules_Platforms_Ec2::CERTIFICATE, 'file')); // user can mull certificate and private key, check it if (strpos($pars[Modules_Platforms_Ec2::PRIVATE_KEY], 'BEGIN CERTIFICATE') !== FALSE && strpos($pars[Modules_Platforms_Ec2::CERTIFICATE], 'BEGIN PRIVATE KEY') !== FALSE) { // swap it $key = $pars[Modules_Platforms_Ec2::PRIVATE_KEY]; $pars[Modules_Platforms_Ec2::PRIVATE_KEY] = $pars[Modules_Platforms_Ec2::CERTIFICATE]; $pars[Modules_Platforms_Ec2::CERTIFICATE] = $key; } 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)) { $aws = $this->env->aws(\Scalr\Service\Aws::REGION_US_EAST_1, $pars[Modules_Platforms_Ec2::ACCESS_KEY], $pars[Modules_Platforms_Ec2::SECRET_KEY], !empty($pars[Modules_Platforms_Ec2::CERTIFICATE]) ? $pars[Modules_Platforms_Ec2::CERTIFICATE] : null, !empty($pars[Modules_Platforms_Ec2::PRIVATE_KEY]) ? $pars[Modules_Platforms_Ec2::PRIVATE_KEY] : null); if (!empty($pars[Modules_Platforms_Ec2::CERTIFICATE]) || !empty($pars[Modules_Platforms_Ec2::PRIVATE_KEY])) { try { $aws->validateCertificateAndPrivateKey(); } 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 { $buckets = $aws->s3->bucket->getList(); } 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); 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()); } $this->db->CommitTrans(); } catch (Exception $e) { $this->db->RollbackTrans(); throw new Exception(_("Failed to save AWS settings: {$e->getMessage()}")); } try { 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', $this->user, $this->getEnvironmentId()); $demoFarm = true; } catch (Exception $e) { throw new Exception("Demo farm creation failed: {$e->getMessage()}"); } } } } catch (Exception $e) { } $this->response->success('Environment saved'); $this->response->data(array('enabled' => $enabled, 'demoFarm' => $demoFarm)); }
/** * Gets the list of the EC2 instances * for the specified environment and AWS location * * @param \Scalr_Environment $environment Environment Object * @param string $region EC2 location name * @param bool $skipCache Whether it should skip the cache. * @return array Returns array looks like array(InstanceId => stateName) */ public function GetServersList(\Scalr_Environment $environment, $region, $skipCache = false) { if (!$region) { return array(); } $aws = $environment->aws($region); $cacheKey = sprintf('%s:%s', $environment->id, $region); if (!isset($this->instancesListCache[$cacheKey]) || $skipCache) { $cacheValue = array(); $nextToken = null; $results = null; do { try { if (isset($results)) { $nextToken = $results->getNextToken(); } $results = $aws->ec2->instance->describe(null, null, $nextToken); } catch (Exception $e) { throw new Exception(sprintf("Cannot get list of servers for platfrom ec2: %s", $e->getMessage())); } if (count($results)) { foreach ($results as $reservation) { /* @var $reservation Scalr\Service\Aws\Ec2\DataType\ReservationData */ foreach ($reservation->instancesSet as $instance) { /* @var $instance Scalr\Service\Aws\Ec2\DataType\InstanceData */ $cacheValue[sprintf('%s:%s', $environment->id, $region)][$instance->instanceId] = $instance->instanceState->name; } } } } while ($results->getNextToken()); foreach ($cacheValue as $offset => $value) { $this->instancesListCache[$offset] = $value; } } return isset($this->instancesListCache[$cacheKey]) ? $this->instancesListCache[$cacheKey] : array(); }
private function saveEc2() { $pars = array(); $enabled = false; $envAutoEnabled = false; $bNew = !$this->env->isPlatformEnabled(SERVER_PLATFORMS::EC2); if ($this->getParam('ec2_is_enabled')) { $enabled = true; $pars[Ec2PlatformModule::ACCOUNT_TYPE] = trim($this->checkVar(Ec2PlatformModule::ACCOUNT_TYPE, 'string', "AWS Account Type required")); $pars[Ec2PlatformModule::ACCESS_KEY] = trim($this->checkVar(Ec2PlatformModule::ACCESS_KEY, 'string', "AWS Access Key required")); $pars[Ec2PlatformModule::SECRET_KEY] = trim($this->checkVar(Ec2PlatformModule::SECRET_KEY, 'password', "AWS Access Key required")); $pars[Ec2PlatformModule::PRIVATE_KEY] = trim($this->checkVar(Ec2PlatformModule::PRIVATE_KEY, 'file')); $pars[Ec2PlatformModule::CERTIFICATE] = trim($this->checkVar(Ec2PlatformModule::CERTIFICATE, 'file')); if ($this->getContainer()->analytics->enabled) { $pars[Ec2PlatformModule::DETAILED_BILLING_BUCKET] = $this->getParam(Ec2PlatformModule::DETAILED_BILLING_BUCKET) ?: null; $pars[Ec2PlatformModule::DETAILED_BILLING_ENABLED] = 0; } // user can mull certificate and private key, check it if (strpos($pars[Ec2PlatformModule::PRIVATE_KEY], 'BEGIN CERTIFICATE') !== FALSE && strpos($pars[Ec2PlatformModule::CERTIFICATE], 'BEGIN PRIVATE KEY') !== FALSE) { // swap it $key = $pars[Ec2PlatformModule::PRIVATE_KEY]; $pars[Ec2PlatformModule::PRIVATE_KEY] = $pars[Ec2PlatformModule::CERTIFICATE]; $pars[Ec2PlatformModule::CERTIFICATE] = $key; } if ($pars[Ec2PlatformModule::ACCOUNT_TYPE] == Ec2PlatformModule::ACCOUNT_TYPE_GOV_CLOUD) { $region = \Scalr\Service\Aws::REGION_US_GOV_WEST_1; } else { if ($pars[Ec2PlatformModule::ACCOUNT_TYPE] == Ec2PlatformModule::ACCOUNT_TYPE_CN_CLOUD) { $region = \Scalr\Service\Aws::REGION_CN_NORTH_1; } else { $region = \Scalr\Service\Aws::REGION_US_EAST_1; } } if (!count($this->checkVarError)) { if ($pars[Ec2PlatformModule::ACCESS_KEY] != $this->env->getPlatformConfigValue(Ec2PlatformModule::ACCESS_KEY) or $pars[Ec2PlatformModule::SECRET_KEY] != $this->env->getPlatformConfigValue(Ec2PlatformModule::SECRET_KEY) or $pars[Ec2PlatformModule::PRIVATE_KEY] != $this->env->getPlatformConfigValue(Ec2PlatformModule::PRIVATE_KEY) or $pars[Ec2PlatformModule::CERTIFICATE] != $this->env->getPlatformConfigValue(Ec2PlatformModule::CERTIFICATE)) { $aws = $this->env->aws($region, $pars[Ec2PlatformModule::ACCESS_KEY], $pars[Ec2PlatformModule::SECRET_KEY], !empty($pars[Ec2PlatformModule::CERTIFICATE]) ? $pars[Ec2PlatformModule::CERTIFICATE] : null, !empty($pars[Ec2PlatformModule::PRIVATE_KEY]) ? $pars[Ec2PlatformModule::PRIVATE_KEY] : null); //Validates private key and certificate if they are provided if (!empty($pars[Ec2PlatformModule::CERTIFICATE]) || !empty($pars[Ec2PlatformModule::PRIVATE_KEY])) { try { //SOAP is not supported anymore //$aws->validateCertificateAndPrivateKey(); } 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()})")); } } //Validates both access and secret keys try { $buckets = $aws->s3->bucket->getList(); } catch (Exception $e) { throw new Exception(sprintf(_("Failed to verify your EC2 access key and secret key: %s"), $e->getMessage())); } //Extract AWS Account ID $pars[Ec2PlatformModule::ACCOUNT_ID] = $aws->getAccountNumber(); try { if ($this->env->getPlatformConfigValue(Ec2PlatformModule::ACCOUNT_ID) != $pars[Ec2PlatformModule::ACCOUNT_ID]) { $this->db->Execute("DELETE FROM client_environment_properties WHERE name LIKE 'ec2.vpc.default%' AND env_id = ?", array($this->env->id)); } } catch (Exception $e) { } } } else { $this->response->failure(); $this->response->data(array('errors' => $this->checkVarError)); return; } } if ($enabled && $this->getContainer()->analytics->enabled && !empty($pars[Ec2PlatformModule::DETAILED_BILLING_BUCKET])) { try { $aws = $this->env->aws($region, $pars[Ec2PlatformModule::ACCESS_KEY], $pars[Ec2PlatformModule::SECRET_KEY]); $bucketObjects = $aws->s3->bucket->listObjects($pars[Ec2PlatformModule::DETAILED_BILLING_BUCKET]); $objectName = 'aws-billing-detailed-line-items-with-resources-and-tags'; $objectExists = false; foreach ($bucketObjects as $bucketObject) { /* @var $bucketObject Scalr\Service\Aws\S3\DataType\ObjectData */ if (strpos($bucketObject->objectName, $objectName) !== false) { $pars[Ec2PlatformModule::DETAILED_BILLING_ENABLED] = 1; $objectExists = true; break; } } if (!$objectExists) { $this->response->failure(); $this->response->data(['errors' => [Ec2PlatformModule::DETAILED_BILLING_BUCKET => "Object with name 'aws-billing-detailed-line-items-with-resources-and-tags' does not exist."]]); return; } } catch (Exception $e) { $this->response->failure(); $this->response->data(['errors' => [Ec2PlatformModule::DETAILED_BILLING_BUCKET => sprintf("Cannot access billing bucket with name %s.", $pars[Ec2PlatformModule::DETAILED_BILLING_BUCKET])]]); return; } } $this->db->BeginTrans(); try { $this->env->enablePlatform(SERVER_PLATFORMS::EC2, $enabled); if ($enabled) { $this->env->setPlatformConfig($pars); if ($this->getContainer()->analytics->enabled && $bNew) { $this->getContainer()->analytics->notifications->onCloudAdd('ec2', $this->env, $this->user); } } if (!$this->user->getAccount()->getSetting(Scalr_Account::SETTING_DATE_ENV_CONFIGURED)) { $this->user->getAccount()->setSetting(Scalr_Account::SETTING_DATE_ENV_CONFIGURED, time()); } if ($enabled && $this->env->status == Scalr_Environment::STATUS_INACTIVE && $this->env->getPlatformConfigValue('system.auto-disable-reason')) { // env was inactive due invalid keys for amazon, activate it $this->env->status = Scalr_Environment::STATUS_ACTIVE; $this->env->save(); $this->env->setPlatformConfig(['system.auto-disable-reason' => NULL]); $envAutoEnabled = true; } $this->db->CommitTrans(); } catch (Exception $e) { $this->db->RollbackTrans(); throw new Exception(_("Failed to save AWS settings: {$e->getMessage()}")); } $this->response->success('Cloud credentials have been ' . ($enabled ? 'saved' : 'removed from Scalr')); $this->response->data(array('enabled' => $enabled, 'demoFarm' => $demoFarm, 'envAutoEnabled' => $envAutoEnabled)); }