/** * Download private key * * @param int $sshKeyId * @param int $farmId * @param string $platform * @param string $cloudLocation * @param bool $formatPpk * @throws Scalr_Exception_InsufficientPermissions * @throws Scalr_UI_Exception_NotFound * @throws Exception */ public function downloadPrivateAction($sshKeyId = null, $farmId = null, $platform = null, $cloudLocation = null, $formatPpk = false) { /* @var $sshKey SshKey */ if ($sshKeyId) { $sshKey = SshKey::findPk($sshKeyId); } else { $sshKey = (new SshKey())->loadGlobalByFarmId($this->getEnvironmentId(), $platform, $cloudLocation, $farmId); if (!$sshKey && $platform == SERVER_PLATFORMS::EC2) { $governance = new \Scalr_Governance($this->getEnvironmentId()); $keyName = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_KEYPAIR); if ($keyName) { throw new Exception("The SSH Key was not found. Note that SSH Key Governance is active, so Scalr does not automatically create SSH Keys for your Amazon EC2 Servers."); } } } if (!$sshKey) { throw new Exception('SSH key not found in database'); } $this->checkPermissions($sshKey); $extension = $formatPpk ? 'ppk' : 'pem'; $fileName = $sshKey->cloudLocation ? "{$sshKey->cloudKeyName}.{$sshKey->cloudLocation}.{$extension}" : "{$sshKey->cloudKeyName}.{$extension}"; $key = $formatPpk ? $sshKey->getPuttyPrivateKey() : $sshKey->privateKey; $this->response->setHeader('Pragma', 'private'); $this->response->setHeader('Cache-control', 'private, must-revalidate'); $this->response->setHeader('Content-type', 'plain/text'); $this->response->setHeader('Content-Disposition', 'attachment; filename="' . $fileName . '"'); $this->response->setHeader('Content-Length', strlen($key)); $this->response->setResponse($key); }
function handleWork($farmId) { try { $dbFarm = DBFarm::LoadByID($farmId); $governance = new Scalr_Governance($dbFarm->EnvID); $settings = $governance->getValue(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_LEASE, 'notifications'); $curDate = new DateTime(); $td = new DateTime($dbFarm->GetSetting(DBFarm::SETTING_LEASE_TERMINATE_DATE)); if ($td > $curDate) { // only inform user $days = $td->diff($curDate)->days; $notifications = json_decode($dbFarm->GetSetting(DBFarm::SETTING_LEASE_NOTIFICATION_SEND), true); if (is_array($settings)) { foreach ($settings as $n) { if (!$notifications[$n['key']] && $n['period'] >= $days) { $mailer = Scalr::getContainer()->mailer; $tdHuman = Scalr_Util_DateTime::convertDateTime($td, $dbFarm->GetSetting(DBFarm::SETTING_TIMEZONE), 'M j, Y'); if ($n['to'] == 'owner') { $user = new Scalr_Account_User(); $user->loadById($dbFarm->createdByUserId); if (Scalr::config('scalr.auth_mode') == 'ldap') { $email = $user->getSetting(Scalr_Account_User::SETTING_LDAP_EMAIL); if (!$email) { $email = $user->getEmail(); } } else { $email = $user->getEmail(); } $mailer->addTo($email); } else { foreach (explode(',', $n['emails']) as $email) { $mailer->addTo(trim($email)); } } $mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/farm_lease_terminate.eml', array('{{terminate_date}}' => $tdHuman, '{{farm}}' => $dbFarm->Name, '{{envName}}' => $dbFarm->GetEnvironmentObject()->name, '{{envId}}' => $dbFarm->GetEnvironmentObject()->id)); $notifications[$n['key']] = 1; $dbFarm->SetSetting(DBFarm::SETTING_LEASE_NOTIFICATION_SEND, json_encode($notifications)); $this->logger->info("Notification was sent by key: " . $n['key'] . " about farm: " . $dbFarm->Name . " by lease manager"); } } } } else { // terminate farm $event = new FarmTerminatedEvent(0, 1, false, 1); Scalr::FireEvent($farmId, $event); $this->logger->info("Farm: " . $dbFarm->Name . " was terminated by lease manager"); } } catch (Exception $e) { var_dump($e->getMessage()); } }
public function xListServersAction() { if (!$this->user->isAdmin()) { $governance = new Scalr_Governance($this->getEnvironmentId()); $limits = $governance->getValue(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_CHEF, null); } $list = []; foreach ($this->getList() as $server) { if (!$limits || isset($limits['servers'][(string) $server['id']])) { $list[] = ['id' => (string) $server['id'], 'url' => $server['url'], 'username' => $server['username'], 'scope' => $server['scope']]; } } $this->response->data(['data' => $list]); }
public function xCreateAction() { $this->request->defineParams(array('listeners' => array('type' => 'json'), 'healthcheck' => array('type' => 'json'), 'zones' => array('type' => 'array'), 'subnets' => array('type' => 'array'), 'scheme' => array('type' => 'string'))); $healthCheck = $this->getParam('healthcheck'); $elb = $this->environment->aws($this->getParam('cloudLocation'))->elb; //prepare listeners $listenersList = new ListenerList(); $li = 0; foreach ($this->getParam('listeners') as $listener) { $listener_chunks = explode("#", $listener); $listenersList->append(new ListenerData(trim($listener_chunks[1]), trim($listener_chunks[2]), trim($listener_chunks[0]), null, trim($listener_chunks[3]))); } $availZones = $this->getParam('zones'); $subnets = $this->getParam('subnets'); $scheme = $this->getParam('scheme'); $elb_name = sprintf("scalr-%s-%s", CryptoTool::sault(10), rand(100, 999)); $healthCheckType = new HealthCheckData(); $healthCheckType->target = $healthCheck['target']; $healthCheckType->healthyThreshold = $healthCheck['healthyThreshold']; $healthCheckType->interval = $healthCheck['interval']; $healthCheckType->timeout = $healthCheck['timeout']; $healthCheckType->unhealthyThreshold = $healthCheck['unhealthyThreshold']; //Creates a new ELB $dnsName = $elb->loadBalancer->create($elb_name, $listenersList, !empty($availZones) ? $availZones : null, !empty($subnets) ? $subnets : null, null, !empty($scheme) ? $scheme : null); $tags = [['key' => \Scalr_Governance::SCALR_META_TAG_NAME, 'value' => $this->environment->applyGlobalVarsToValue(\Scalr_Governance::SCALR_META_TAG_VALUE)]]; //Tags governance $governance = new \Scalr_Governance($this->environment->id); $gTags = (array) $governance->getValue('ec2', \Scalr_Governance::AWS_TAGS); if (count($gTags) > 0) { foreach ($gTags as $tKey => $tValue) { $tags[] = array('key' => $tKey, 'value' => $this->environment->applyGlobalVarsToValue($tValue)); } } $elb->loadBalancer->addTags($elb_name, $tags); try { $elb->loadBalancer->configureHealthCheck($elb_name, $healthCheckType); } catch (Exception $e) { $elb->loadBalancer->delete($elb_name); throw $e; } // return all as in xListElb $this->response->data(array('elb' => array('name' => $elb_name, 'dnsName' => $dnsName))); }
public function getBaseConfiguration(DBServer $dbServer, $isHostInit = false) { $configuration = new stdClass(); $dbFarmRole = $dbServer->GetFarmRoleObject(); //Storage try { if ($dbFarmRole) { $storage = new FarmRoleStorage($dbFarmRole); $volumes = $storage->getVolumesConfigs($dbServer->index, $isHostInit); if (!empty($volumes)) { $configuration->volumes = $volumes; } } } catch (Exception $e) { $this->logger->error(new FarmLogMessage($dbServer->farmId, "Cannot init storage: {$e->getMessage()}")); } // Base try { if ($dbFarmRole) { $scriptingLogTimeout = $dbFarmRole->GetSetting(self::ROLE_BASE_KEEP_SCRIPTING_LOGS_TIME); if (!$scriptingLogTimeout) { $scriptingLogTimeout = 3600; } $configuration->base = new stdClass(); $configuration->base->keepScriptingLogsTime = $scriptingLogTimeout; $configuration->base->resumeStrategy = PlatformFactory::NewPlatform($dbFarmRole->Platform)->getResumeStrategy(); $governance = new Scalr_Governance($dbFarmRole->GetFarmObject()->EnvID); if ($governance->isEnabled(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_HOSTNAME_FORMAT)) { $hostNameFormat = $governance->getValue(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_HOSTNAME_FORMAT); } else { $hostNameFormat = $dbFarmRole->GetSetting(self::ROLE_BASE_HOSTNAME_FORMAT); } $configuration->base->hostname = !empty($hostNameFormat) ? $dbServer->applyGlobalVarsToValue($hostNameFormat) : ''; $apiPort = $dbFarmRole->GetSetting(self::ROLE_BASE_API_PORT); $messagingPort = $dbFarmRole->GetSetting(self::ROLE_BASE_MESSAGING_PORT); $configuration->base->apiPort = $apiPort ? $apiPort : 8010; $configuration->base->messagingPort = $messagingPort ? $messagingPort : 8013; } //Update settings $updateSettings = $dbServer->getScalarizrRepository(); $configuration->base->update = new stdClass(); foreach ($updateSettings as $k => $v) { $configuration->base->update->{$k} = $v; } } catch (Exception $e) { } return $configuration; }
/** * Gets default vpc security group list * * @param SecurityGroupList $sgList * @param string $vpcId * @param string $serviceName Service name (rds, elb ...) * @return array */ private function getDefaultSgRow($sgList, $vpcId, $serviceName = null) { $governance = new Scalr_Governance($this->getEnvironmentId()); $governanceSecurityGroups = $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::getEc2SecurityGroupPolicyNameForService($serviceName), null); $vpcSgList = []; $sgDefaultNames = []; $wildCardSgDefaultNames = []; $defaultSecurityGroups = []; foreach ($sgList as $sg) { if ($sg->vpcId == $vpcId) { $vpcSgList[$sg->groupName] = $sg->groupId; } } if (!empty($governanceSecurityGroups['value'])) { $sgs = explode(',', $governanceSecurityGroups['value']); foreach ($sgs as $sg) { if ($sg != '') { array_push($sgDefaultNames, trim($sg)); if (strpos($sg, '*') !== false) { array_push($wildCardSgDefaultNames, trim($sg)); } } } unset($sgs); } if (!empty($sgDefaultNames)) { $foundVpcSgNames = []; foreach ($sgDefaultNames as $groupName) { if (!isset($vpcSgList[$groupName])) { if (in_array($groupName, $wildCardSgDefaultNames)) { $wildCardMatchedSgs = []; $groupNamePattern = \Scalr_Governance::convertAsteriskPatternToRegexp($groupName); foreach ($vpcSgList as $sgGroupName => $sgGroupId) { if (preg_match($groupNamePattern, $sgGroupName) === 1) { array_push($wildCardMatchedSgs, $sgGroupName); } } if (count($wildCardMatchedSgs) == 1) { $defaultSecurityGroups[] = ['securityGroupId' => $vpcSgList[$wildCardMatchedSgs[0]], 'securityGroupName' => $wildCardMatchedSgs[0]]; } else { $defaultSecurityGroups[] = ['securityGroupId' => null, 'securityGroupName' => $groupName]; } $foundVpcSgNames[] = $groupName; } } else { $defaultSecurityGroups[] = ['securityGroupId' => $vpcSgList[$groupName], 'securityGroupName' => $groupName]; $foundVpcSgNames[] = $groupName; } } $missingSgs = array_diff($sgDefaultNames, $foundVpcSgNames); foreach ($missingSgs as $missingSg) { $defaultSecurityGroups[] = ['securityGroupId' => null, 'securityGroupName' => $missingSg]; } } elseif (isset($vpcSgList['default']) && empty($governanceSecurityGroups)) { $defaultSecurityGroups[] = ['securityGroupId' => $vpcSgList['default'], 'securityGroupName' => 'default']; } return $defaultSecurityGroups; }
/** * Gets the list of the security groups for the specified db server. * * If server does not have required security groups this method will create them. * * @param DBServer $DBServer The DB Server instance * @param \Scalr\Service\Aws\Ec2 $ec2 Ec2 Client instance * @param string $vpcId optional The ID of VPC * @return array Returns array looks like array(groupid-1, groupid-2, ..., groupid-N) */ private function GetServerSecurityGroupsList(DBServer $DBServer, \Scalr\Service\Aws\Ec2 $ec2, $vpcId = "", \Scalr_Governance $governance = null) { $retval = array(); $checkGroups = array(); $sgGovernance = true; $allowAdditionalSgs = true; $vpcId = null; if ($governance) { $sgs = $governance->getValue(\SERVER_PLATFORMS::EUCALYPTUS, \Scalr_Governance::EUCALYPTUS_SECURITY_GROUPS); if ($sgs !== null) { $governanceSecurityGroups = @explode(",", $sgs); if (!empty($governanceSecurityGroups)) { foreach ($governanceSecurityGroups as $sg) { if ($sg != '') { array_push($checkGroups, trim($sg)); } } } $sgGovernance = false; $allowAdditionalSgs = $governance->getValue(\SERVER_PLATFORMS::EUCALYPTUS, \Scalr_Governance::EUCALYPTUS_SECURITY_GROUPS, 'allow_additional_sec_groups'); } } if (!$sgGovernance || $allowAdditionalSgs) { if ($DBServer->farmRoleId != 0) { $dbFarmRole = $DBServer->GetFarmRoleObject(); if ($dbFarmRole->GetSetting(DBFarmRole::SETTING_EUCA_SECURITY_GROUPS_LIST) !== null) { // New SG management $sgs = @json_decode($dbFarmRole->GetSetting(DBFarmRole::SETTING_EUCA_SECURITY_GROUPS_LIST)); if (!empty($sgs)) { foreach ($sgs as $sg) { if (stripos($sg, 'sg-') === 0) { array_push($retval, $sg); } else { array_push($checkGroups, $sg); } } } } } else { array_push($checkGroups, 'scalr-rb-system'); } } // No name based security groups, return only SG ids. if (empty($checkGroups)) { return $retval; } // Filter groups $filter = array(array('name' => SecurityGroupFilterNameType::groupName(), 'value' => $checkGroups)); // Get filtered list of SG required by scalr; try { $list = $ec2->securityGroup->describe(null, null, $filter); $sgList = array(); foreach ($list as $sg) { /* @var $sg \Scalr\Service\Aws\Ec2\DataType\SecurityGroupData */ if ($vpcId == '' && !$sg->vpcId || $vpcId && $sg->vpcId == $vpcId) { $sgList[$sg->groupName] = $sg->groupId; } } unset($list); } catch (\Exception $e) { throw new \Exception("Cannot get list of security groups (1): {$e->getMessage()}"); } foreach ($checkGroups as $groupName) { // Check default SG if ($groupName == 'default') { array_push($retval, $sgList[$groupName]); // Check Roles builder SG } elseif ($groupName == 'scalr-rb-system') { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create('scalr-rb-system', "Security group for Roles Builder", $vpcId); $ipRangeList = new IpRangeList(); foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) { $ipRangeList->append(new IpRangeData($ip)); } sleep(2); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 22, 22, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList)), $securityGroupId); $sgList['scalr-rb-system'] = $securityGroupId; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot create security group '%s': %s"), 'scalr-rb-system', $e->getMessage())); } } array_push($retval, $sgList[$groupName]); //Check scalr-farm.* security group } elseif (stripos($groupName, 'scalr-farm.') === 0) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmID N%s", $DBServer->farmId), $vpcId); sleep(2); $userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->getPlatformConfigValue(self::ACCOUNT_ID), null, $groupName)); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)), $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); //Check scalr-role.* security group } elseif (stripos($groupName, 'scalr-role.') === 0) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmRoleID N%s on FarmID N%s", $DBServer->GetFarmRoleObject()->ID, $DBServer->farmId), $vpcId); sleep(2); // DB rules $dbRules = $DBServer->GetFarmRoleObject()->GetRoleObject()->getSecurityRules(); $groupRules = array(); foreach ($dbRules as $rule) { $groupRules[\Scalr_Util_CryptoTool::hash($rule['rule'])] = $rule; } // Behavior rules foreach (\Scalr_Role_Behavior::getListForFarmRole($DBServer->GetFarmRoleObject()) as $bObj) { $bRules = $bObj->getSecurityRules(); foreach ($bRules as $r) { if ($r) { $groupRules[\Scalr_Util_CryptoTool::hash($r)] = array('rule' => $r); } } } // Default rules $userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->getPlatformConfigValue(self::ACCOUNT_ID), null, $groupName)); $rules = array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)); foreach ($groupRules as $rule) { $group_rule = explode(":", $rule["rule"]); $rules[] = new IpPermissionData($group_rule[0], $group_rule[1], $group_rule[2], new IpRangeData($group_rule[3])); } $ec2->securityGroup->authorizeIngress($rules, $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); } elseif ($groupName == \Scalr::config('scalr.aws.security_group_name')) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, "Security rules needed by Scalr", $vpcId); $ipRangeList = new IpRangeList(); foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) { $ipRangeList->append(new IpRangeData($ip)); } // TODO: Open only FOR VPC ranges $ipRangeList->append(new IpRangeData('10.0.0.0/8')); sleep(2); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 3306, 3306, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList), new IpPermissionData('udp', 8014, 8014, $ipRangeList)), $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); } else { if (!isset($sgList[$groupName])) { throw new \Exception(sprintf(_("Security group '%s' is not found"), $groupName)); } else { array_push($retval, $sgList[$groupName]); } } } return $retval; }
public function getBaseConfiguration(DBServer $dbServer, $isHostInit = false, $onlyBase = false) { $configuration = new stdClass(); $dbFarmRole = $dbServer->GetFarmRoleObject(); //Storage if (!$onlyBase) { try { if ($dbFarmRole) { $storage = new FarmRoleStorage($dbFarmRole); $volumes = $storage->getVolumesConfigs($dbServer, $isHostInit); if (!empty($volumes)) { $configuration->volumes = $volumes; } } } catch (Exception $e) { $this->logger->error(new FarmLogMessage($dbServer->farmId, "Cannot init storage: {$e->getMessage()}")); } } // Base try { if ($dbFarmRole) { $scriptingLogTimeout = $dbFarmRole->GetSetting(self::ROLE_BASE_KEEP_SCRIPTING_LOGS_TIME); if (!$scriptingLogTimeout) { $scriptingLogTimeout = 3600; } $configuration->base = new stdClass(); $configuration->base->keepScriptingLogsTime = $scriptingLogTimeout; $configuration->base->abortInitOnScriptFail = (int) $dbFarmRole->GetSetting(self::ROLE_BASE_ABORT_INIT_ON_SCRIPT_FAIL); $configuration->base->disableFirewallManagement = (int) $dbFarmRole->GetSetting(self::ROLE_BASE_DISABLE_FIREWALL_MANAGEMENT); $configuration->base->rebootAfterHostinitPhase = (int) $dbFarmRole->GetSetting(self::ROLE_BASE_REBOOT_AFTER_HOSTINIT_PHASE); $configuration->base->resumeStrategy = PlatformFactory::NewPlatform($dbFarmRole->Platform)->getResumeStrategy(); //Dev falgs for our if (Scalr::isHostedScalr() && $dbServer->envId == 3414) { $configuration->base->unionScriptExecutor = 1; } $governance = new Scalr_Governance($dbFarmRole->GetFarmObject()->EnvID); if ($governance->isEnabled(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_HOSTNAME_FORMAT)) { $hostNameFormat = $governance->getValue(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_HOSTNAME_FORMAT); } else { $hostNameFormat = $dbFarmRole->GetSetting(self::ROLE_BASE_HOSTNAME_FORMAT); } $configuration->base->hostname = !empty($hostNameFormat) ? $dbServer->applyGlobalVarsToValue($hostNameFormat) : ''; if ($configuration->base->hostname != '') { $dbServer->SetProperty(self::SERVER_BASE_HOSTNAME, $configuration->base->hostname); } $apiPort = null; $messagingPort = null; if (!PlatformFactory::isCloudstack($dbFarmRole->Platform)) { $apiPort = $dbFarmRole->GetSetting(self::ROLE_BASE_API_PORT); $messagingPort = $dbFarmRole->GetSetting(self::ROLE_BASE_MESSAGING_PORT); } $configuration->base->apiPort = $apiPort ? $apiPort : 8010; $configuration->base->messagingPort = $messagingPort ? $messagingPort : 8013; } //Update settings $updateSettings = $dbServer->getScalarizrRepository(); $configuration->base->update = new stdClass(); foreach ($updateSettings as $k => $v) { $configuration->base->update->{$k} = $v; } } catch (Exception $e) { } return $configuration; }
private function GetServerSecurityGroupsList(DBServer $DBServer, \Scalr\Service\OpenStack\OpenStack $osClient, \Scalr_Governance $governance = null) { $retval = array(); $checkGroups = array(); $sgGovernance = true; $allowAdditionalSgs = true; if ($governance) { $sgs = $governance->getValue($DBServer->platform, \Scalr_Governance::OPENSTACK_SECURITY_GROUPS); if ($sgs !== null) { $governanceSecurityGroups = @explode(",", $sgs); if (!empty($governanceSecurityGroups)) { foreach ($governanceSecurityGroups as $sg) { if ($sg != '') { array_push($checkGroups, trim($sg)); } } } $sgGovernance = false; $allowAdditionalSgs = $governance->getValue($DBServer->platform, \Scalr_Governance::OPENSTACK_SECURITY_GROUPS, 'allow_additional_sec_groups'); } } if (!$sgGovernance || $allowAdditionalSgs) { if ($DBServer->farmRoleId != 0) { $dbFarmRole = $DBServer->GetFarmRoleObject(); if ($dbFarmRole->GetSetting(\DBFarmRole::SETTING_OPENSTACK_SECURITY_GROUPS_LIST) !== null) { // New SG management $sgs = @json_decode($dbFarmRole->GetSetting(\DBFarmRole::SETTING_OPENSTACK_SECURITY_GROUPS_LIST)); if (!empty($sgs)) { foreach ($sgs as $sg) { array_push($checkGroups, $sg); } } } else { // Old SG management array_push($checkGroups, 'default'); array_push($checkGroups, \Scalr::config('scalr.aws.security_group_name')); } } else { array_push($checkGroups, 'scalr-rb-system'); } } try { if ($this->hasOpenStackNetworkSecurityGroupExtension($osClient)) { $list = $osClient->network->securityGroups->list(); } else { $list = $osClient->servers->securityGroups->list(); } do { foreach ($list as $sg) { $sgroups[strtolower($sg->name)] = $sg; $sgroupIds[strtolower($sg->id)] = $sg; } if ($list instanceof PaginationInterface) { $list = $list->getNextPage(); } else { $list = false; } } while ($list !== false); unset($list); } catch (\Exception $e) { throw new \Exception("GetServerSecurityGroupsList failed: {$e->getMessage()}"); } foreach ($checkGroups as $groupName) { if (preg_match('/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/si', $groupName) || !in_array($groupName, array('scalr-rb-system', 'default', \Scalr::config('scalr.aws.security_group_name')))) { if (isset($sgroupIds[$groupName])) { $groupName = $sgroupIds[$groupName]->name; } else { throw new \Exception(sprintf(_("Security group '%s' is not found"), $groupName)); } } // Check default SG if ($groupName == 'default') { array_push($retval, $groupName); // Check Roles builder SG } elseif ($groupName == 'scalr-rb-system' || $groupName == \Scalr::config('scalr.aws.security_group_name')) { if (!isset($sgroups[$groupName])) { if ($this->hasOpenStackNetworkSecurityGroupExtension($osClient)) { try { $group = $osClient->network->securityGroups->create($groupName, _("Scalr system security group")); $groupId = $group->id; } catch (\Exception $e) { throw new \Exception("GetServerSecurityGroupsList failed on scalr.ip-pool: {$e->getMessage()}"); } //Temporary solution because of API requests rate limit $rule = new \stdClass(); $rule->protocol = "tcp"; $rule->port_range_min = 1; $rule->port_range_max = 65535; $rule->remote_ip_prefix = "0.0.0.0/0"; $rule->security_group_id = $groupId; $res = $osClient->servers->securityGroups->addRule($rule); $rule = new \stdClass(); $rule->protocol = "udp"; $rule->port_range_min = 1; $rule->port_range_max = 65535; $rule->remote_ip_prefix = "0.0.0.0/0"; $rule->security_group_id = $groupId; $res = $osClient->servers->securityGroups->addRule($rule); } else { try { $group = $osClient->servers->securityGroups->create($groupName, _("Scalr system security group")); $groupId = $group->id; } catch (\Exception $e) { throw new \Exception("GetServerSecurityGroupsList failed on scalr.ip-pool: {$e->getMessage()}"); } //Temporary solution because of API requests rate limit $rule = new \stdClass(); $rule->ip_protocol = "tcp"; $rule->from_port = 1; $rule->to_port = 65535; $rule->cidr = "0.0.0.0/0"; $rule->parent_group_id = $groupId; $res = $osClient->servers->securityGroups->addRule($rule); $rule = new \stdClass(); $rule->ip_protocol = "udp"; $rule->from_port = 1; $rule->to_port = 65535; $rule->cidr = "0.0.0.0/0"; $rule->parent_group_id = $groupId; $res = $osClient->servers->securityGroups->addRule($rule); } } array_push($retval, $groupName); } else { if (!isset($sgroups[$groupName])) { throw new \Exception(sprintf(_("Security group '%s' is not found"), $groupName)); } else { array_push($retval, $groupName); } } } return $retval; }
/** * @param JsonData $VpcSecurityGroups * @param JsonData $DBSecurityGroups * @param JsonData $SubnetIds */ public function xLaunchInstanceAction(JsonData $VpcSecurityGroups = null, JsonData $DBSecurityGroups = null, JsonData $SubnetIds = null) { $cloudLocation = $this->getParam('cloudLocation'); $aws = $this->getEnvironment()->aws($cloudLocation); $engine = $this->getParam('Engine'); if ($engine == 'mysql') { $engine = 'MySQL'; } $request = new CreateDBInstanceRequestData($this->getParam('DBInstanceIdentifier'), $this->getParam('AllocatedStorage'), $this->getParam('DBInstanceClass'), $engine, $this->getParam('MasterUsername'), $this->getParam('MasterUserPassword')); $request->port = $this->getParam('Port') ?: null; $request->dBName = $this->getParam('DBName') ?: null; $request->characterSetName = $this->getParam('CharacterSetName') ?: null; $paramName = $this->getParam('DBParameterGroup'); if (!empty($paramName)) { $paramGroups = $aws->rds->dbParameterGroup->describe(); foreach ($paramGroups as $param) { /* @var $param DBParameterGroupData */ if ($param->dBParameterGroupName == $paramName) { $paramGroup = $param; break; } } } if (!empty($paramGroup)) { $request->dBParameterGroupName = $paramGroup->dBParameterGroupName; } $optionList = $aws->rds->optionGroup->describe($engine); foreach ($optionList as $option) { /* @var $option OptionGroupData */ if ($option->optionGroupName == $this->getParam('OptionGroupName')) { $optionGroup = $option; break; } } if (!empty($optionGroup)) { $request->optionGroupName = $optionGroup->optionGroupName; } $dbSgIds = null; foreach ($DBSecurityGroups as $DBSecurityGroup) { $dbSgIds[] = $DBSecurityGroup; } $request->dBSecurityGroups = $dbSgIds; $request->autoMinorVersionUpgrade = $this->getParam('AutoMinorVersionUpgrade') == 'false' ? false : true; $request->availabilityZone = $this->getParam('AvailabilityZone') ?: null; $request->backupRetentionPeriod = $this->getParam('BackupRetentionPeriod') ?: null; $request->preferredBackupWindow = $this->getParam('PreferredBackupWindow') ?: null; $request->preferredMaintenanceWindow = $this->getParam('PreferredMaintenanceWindow') ?: null; $multiAz = $this->getParam('MultiAZ'); if (!empty($multiAz)) { $request->multiAZ = $this->getParam('MultiAZ') == 'false' ? false : true; } $request->storageType = $this->getParam('StorageType'); $request->dBSubnetGroupName = $this->getParam('DBSubnetGroupName') ?: null; $request->licenseModel = $this->getParam('LicenseModel'); $vpcSgIds = null; foreach ($VpcSecurityGroups as $VpcSecurityGroup) { $vpcSgIds[] = $VpcSecurityGroup['id']; } $request->vpcSecurityGroupIds = $vpcSgIds; $request->engineVersion = $this->getParam('EngineVersion') ?: null; $request->iops = $this->getParam('Iops') ?: null; $vpcId = $this->getParam('VpcId'); $tagsObject = $this->getParam('farmId') ? DBFarm::LoadByID($this->getParam('farmId')) : $this->environment; $tags = [['key' => \Scalr_Governance::SCALR_META_TAG_NAME, 'value' => $tagsObject->applyGlobalVarsToValue(\Scalr_Governance::SCALR_META_TAG_VALUE)]]; $governance = new \Scalr_Governance($this->environment->id); $gTags = (array) $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_TAGS); if (count($gTags) > 0) { foreach ($gTags as $tKey => $tValue) { $tags[] = array('key' => $tKey, 'value' => $tagsObject->applyGlobalVarsToValue($tValue)); } } $request->tags = new TagsList($tags); $errorMessage = $this->checkPolicy($VpcSecurityGroups, $vpcId, $SubnetIds, $cloudLocation); if (empty($errorMessage)) { $aws->rds->dbInstance->create($request); if ($this->getParam('farmId')) { $cloudResource = new CloudResource(); $cloudResource->id = $request->dBInstanceIdentifier; $cloudResource->type = CloudResource::TYPE_AWS_RDS; $cloudResource->platform = \SERVER_PLATFORMS::EC2; $cloudResource->cloudLocation = $cloudLocation; $cloudResource->envId = $this->getEnvironmentId(); $cloudResource->farmId = $this->getParam('farmId'); $cloudResource->save(); } $this->response->success("DB Instance successfully created"); } else { $this->response->failure($errorMessage); } }
/** * {@inheritdoc} * @see \Scalr\Modules\PlatformModuleInterface::LaunchServer() */ public function LaunchServer(DBServer $DBServer, \Scalr_Server_LaunchOptions $launchOptions = null) { $config = \Scalr::getContainer()->config; $environment = $DBServer->GetEnvironmentObject(); $governance = new \Scalr_Governance($environment->id); if (!$launchOptions) { $launchOptions = new \Scalr_Server_LaunchOptions(); $DBRole = $DBServer->GetFarmRoleObject()->GetRoleObject(); $launchOptions->imageId = $DBRole->__getNewRoleObject()->getImage($this->platform, $DBServer->GetCloudLocation())->imageId; $launchOptions->serverType = $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::INSTANCE_TYPE); $launchOptions->cloudLocation = $DBServer->GetFarmRoleObject()->CloudLocation; $launchOptions->userData = $DBServer->GetCloudUserData(); $launchOptions->userData['region'] = $launchOptions->cloudLocation; $launchOptions->userData['vzc.adminpassword'] = \Scalr::GenerateRandomKey(20); $launchOptions->userData['platform'] = \SERVER_PLATFORMS::VERIZON; // Apply tags $launchOptions->userData = array_merge($DBServer->getOpenstackTags(), $launchOptions->userData); $launchOptions->networks = @json_decode($DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::OPENSTACK_NETWORKS)); $gevernanceNetworks = $governance->getValue($this->platform, 'openstack.networks'); if (count($launchOptions->networks) == 0 && $gevernanceNetworks) { $launchOptions->networks = $gevernanceNetworks[$launchOptions->cloudLocation]; } foreach ($launchOptions->userData as $k => $v) { if (!$v) { unset($launchOptions->userData[$k]); } } $launchOptions->architecture = 'x86_64'; $isWindows = $DBServer->osType == 'windows' || $DBRole->getOs()->family == 'windows'; $customUserData = $DBServer->GetFarmRoleObject()->GetSetting('base.custom_user_data'); $serverNameFormat = $governance->getValue($DBServer->platform, \Scalr_Governance::OPENSTACK_INSTANCE_NAME_FORMAT); if (!$serverNameFormat) { $serverNameFormat = $DBServer->GetFarmRoleObject()->GetSetting(\Scalr_Role_Behavior::ROLE_INSTANCE_NAME_FORMAT); } } else { $launchOptions->userData = array(); $customUserData = false; if (!$launchOptions->networks) { $launchOptions->networks = array(); } $isWindows = $DBServer->osType == 'windows'; } $client = $this->getOsClient($environment, $launchOptions->cloudLocation); // Prepare user data $u_data = ""; foreach ($launchOptions->userData as $k => $v) { $u_data .= "{$k}={$v};"; } $u_data = trim($u_data, ";"); if ($customUserData) { $repos = $DBServer->getScalarizrRepository(); $extProperties["user_data"] = base64_encode(str_replace(array('{SCALR_USER_DATA}', '{RPM_REPO_URL}', '{DEB_REPO_URL}'), array($u_data, $repos['rpm_repo_url'], $repos['deb_repo_url']), $customUserData)); } $personality = new PersonalityList(); if ($isWindows) { $personality->append(new Personality('C:\\Program Files\\Scalarizr\\etc\\private.d\\.user-data', base64_encode($u_data))); } else { $personality->append(new Personality('/etc/scalr/private.d/.user-data', base64_encode($u_data))); } //TODO: newtorks $networks = new NetworkList(); foreach ((array) $launchOptions->networks as $network) { if ($network) { $networks->append(new Network($network)); } } //$osUserData = null; $osPersonality = null; $userDataMethod = 'meta-data'; $osPersonality = null; $userDataMethod = $config->defined("scalr.{$this->platform}.user_data_method") ? $config("scalr.{$this->platform}.user_data_method") : null; if (!$userDataMethod || $userDataMethod == 'both' || $userDataMethod == 'personality') { $osPersonality = $personality; } if (!$userDataMethod || $userDataMethod == 'both' || $userDataMethod == 'meta-data' || $isWindows) { $osUserData = $launchOptions->userData; } $serverName = $serverNameFormat ? $DBServer->applyGlobalVarsToValue($serverNameFormat) : $DBServer->serverId; try { $result = $client->servers->createServer($serverName, $launchOptions->serverType, $launchOptions->imageId, null, $osUserData, $osPersonality, $networks, $extProperties); $instanceTypeInfo = $this->getInstanceType($launchOptions->serverType, $environment, $launchOptions->cloudLocation); /* @var $instanceTypeInfo CloudInstanceType */ $DBServer->SetProperties([\OPENSTACK_SERVER_PROPERTIES::SERVER_ID => $result->id, \OPENSTACK_SERVER_PROPERTIES::IMAGE_ID => $launchOptions->imageId, \OPENSTACK_SERVER_PROPERTIES::ADMIN_PASS => $launchOptions->userData['vzc.adminpassword'] ? $launchOptions->userData['vzc.adminpassword'] : $result->adminPass, \OPENSTACK_SERVER_PROPERTIES::NAME => $DBServer->serverId, \SERVER_PROPERTIES::ARCHITECTURE => $launchOptions->architecture, \OPENSTACK_SERVER_PROPERTIES::CLOUD_LOCATION => $launchOptions->cloudLocation, \SERVER_PROPERTIES::SYSTEM_USER_DATA_METHOD => $userDataMethod, \SERVER_PROPERTIES::INFO_INSTANCE_VCPUS => $instanceTypeInfo ? $instanceTypeInfo->vcpus : null]); if ($DBServer->farmRoleId) { $ipPool = $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::OPENSTACK_IP_POOL); if ($ipPool) { $DBServer->SetProperty(\SERVER_PROPERTIES::SYSTEM_IGNORE_INBOUND_MESSAGES, 1); } } $params = ['type' => $launchOptions->serverType]; if ($instanceTypeInfo) { $params['instanceTypeName'] = $instanceTypeInfo->name; } $DBServer->setOsType($isWindows ? 'windows' : 'linux'); $DBServer->cloudLocation = $launchOptions->cloudLocation; $DBServer->cloudLocationZone = ""; // Not supported by openstack $DBServer->imageId = $launchOptions->imageId; $DBServer->update($params); // we set server history here $DBServer->getServerHistory()->update(['cloudServerId' => $result->id]); return $DBServer; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot launch new instance. %s"), $e->getMessage())); } }
private function listGroupsEc2($platform, $cloudLocation, $filters) { $sgFilter = null; $result = []; if (!is_array($filters)) { $filters = []; } if (!empty($filters['sgIds'])) { $sgFilter = is_null($sgFilter) ? array() : $sgFilter; $sgFilter[] = array('name' => SecurityGroupFilterNameType::groupId(), 'value' => $filters['sgIds']); } if (empty($filters['vpcId']) && array_key_exists('vpcId', $filters)) { $p = PlatformFactory::NewPlatform(SERVER_PLATFORMS::EC2); $defaultVpc = $p->getDefaultVpc($this->environment, $cloudLocation); if ($defaultVpc) { $filters['vpcId'] = $defaultVpc; } } if (!empty($filters['vpcId'])) { $sgFilter = is_null($sgFilter) ? array() : $sgFilter; $sgFilter[] = array('name' => SecurityGroupFilterNameType::vpcId(), 'value' => $filters['vpcId']); } $sgList = $this->getPlatformService($platform, $cloudLocation)->describe(null, null, $sgFilter); /* @var $sg SecurityGroupData */ foreach ($sgList as $sg) { if (is_array($filters) && array_key_exists('vpcId', $filters) && $filters['vpcId'] == null && $sg->vpcId) { //we don't want to see VPC Security groups when $filters['vpcId'] == null continue; } $result[] = ['id' => $sg->groupId, 'name' => $sg->groupName, 'description' => $sg->groupDescription, 'vpcId' => $sg->vpcId, 'owner' => $sg->ownerId]; } if ($filters['considerGovernance']) { $filteredSg = []; $allowedSgNames = []; $governance = new Scalr_Governance($this->getEnvironmentId()); $governanceSecurityGroups = $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::getEc2SecurityGroupPolicyNameForService($filters['serviceName']), ''); if ($governanceSecurityGroups) { $sgRequiredPatterns = \Scalr_Governance::prepareSecurityGroupsPatterns($filters['osFamily'] == 'windows' && $governanceSecurityGroups['windows'] ? $governanceSecurityGroups['windows'] : $governanceSecurityGroups['value']); $sgOptionalPatterns = $governanceSecurityGroups['allow_additional_sec_groups'] ? \Scalr_Governance::prepareSecurityGroupsPatterns($governanceSecurityGroups['additional_sec_groups_list']) : []; foreach ($result as $sg) { $sgNameLowerCase = strtolower($sg['name']); $sgAllowed = false; if ($governanceSecurityGroups['allow_additional_sec_groups']) { if (!empty($sgOptionalPatterns)) { if (isset($sgOptionalPatterns[$sgNameLowerCase])) { $sgAllowed = true; } else { foreach ($sgOptionalPatterns as &$sgOptionalPattern) { if (isset($sgOptionalPattern['regexp']) && preg_match($sgOptionalPattern['regexp'], $sg['name']) === 1) { $sgAllowed = true; break; } } } } else { $sgAllowed = true; } } if (isset($sgRequiredPatterns[$sgNameLowerCase])) { $sgAllowed = true; $sg['addedByGovernance'] = true; $sgRequiredPatterns[$sgNameLowerCase]['found'] = true; } else { foreach ($sgRequiredPatterns as &$sgRequiredPattern) { if (isset($sgRequiredPattern['regexp']) && preg_match($sgRequiredPattern['regexp'], $sg['name']) === 1) { $sgRequiredPattern['matches'][] = $sg; break; } } } if ($sgAllowed) { $allowedSgNames[] = $sgNameLowerCase; $filteredSg[$sg['id']] = $sg; } } foreach ($sgRequiredPatterns as &$sgRequiredPattern) { if (isset($sgRequiredPattern['matches']) && count($sgRequiredPattern['matches']) == 1) { $sg = $sgRequiredPattern['matches'][0]; if (!isset($filteredSg[$sg['id']])) { $filteredSg[$sg['id']] = $sg; } $filteredSg[$sg['id']]['addedByGovernance'] = true; $sgRequiredPattern['found'] = true; } } $result = $filteredSg; if (!$filters['existingGroupsOnly']) { foreach ($sgRequiredPatterns as $sgRequiredPattern) { if (!$sgRequiredPattern['found']) { $result[] = ['id' => null, 'name' => $sgRequiredPattern['value'], 'description' => null, 'vpcId' => null, 'owner' => null, 'addedByGovernance' => true]; } } } } } return $result; }
/** * Farm launched * * @param FarmLaunchedEvent $event */ public function OnFarmLaunched(FarmLaunchedEvent $event) { $DBFarm = DBFarm::LoadByID($this->FarmID); // TODO: Refactoting -> Move to DBFarm class $this->DB->Execute("UPDATE farms SET status=?, dtlaunched=NOW() WHERE id=?", array(FARM_STATUS::RUNNING, $this->FarmID)); $governance = new Scalr_Governance($DBFarm->EnvID); if ($governance->isEnabled(Scalr_Governance::GENERAL_LEASE) && $DBFarm->GetSetting(DBFarm::SETTING_LEASE_STATUS)) { $dt = new DateTime(); $dt->add(new DateInterval('P' . intval($governance->getValue(Scalr_Governance::GENERAL_LEASE, 'defaultLifePeriod')) . 'D')); $DBFarm->SetSetting(DBFarm::SETTING_LEASE_EXTEND_CNT, 0); $DBFarm->SetSetting(DBFarm::SETTING_LEASE_TERMINATE_DATE, $dt->format('Y-m-d H:i:s')); $DBFarm->SetSetting(DBFarm::SETTING_LEASE_NOTIFICATION_SEND, ''); } $roles = $DBFarm->GetFarmRoles(); foreach ($roles as $dbFarmRole) { if ($dbFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_ENABLED) && !$DBFarm->GetSetting(DBFarm::SETTING_EC2_VPC_ID)) { $scalingManager = new Scalr_Scaling_Manager($dbFarmRole); $scalingDecision = $scalingManager->makeScalingDecition(); if ($scalingDecision == Scalr_Scaling_Decision::UPSCALE) { $ServerCreateInfo = new ServerCreateInfo($dbFarmRole->Platform, $dbFarmRole); try { $DBServer = Scalr::LaunchServer($ServerCreateInfo, null, true, "Farm launched", isset($event->userId) ? $event->userId : null); $dbFarmRole->SetSetting(DBFarmRole::SETTING_SCALING_UPSCALE_DATETIME, time(), DBFarmRole::TYPE_LCL); Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($DBFarm->ID, sprintf("Farm %s, role %s scaling up. Starting new instance. ServerID = %s.", $DBFarm->Name, $dbFarmRole->GetRoleObject()->name, $DBServer->serverId))); } catch (Exception $e) { Logger::getLogger(LOG_CATEGORY::SCALING)->error($e->getMessage()); } } } } }
/** * * @param array $farmSettings * @param array $roles * @return bool */ private function isFarmConfigurationValid($farmId, $farmSettings, array $roles = array()) { $this->errors = array('error_count' => 0); $farmVariables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), ScopeInterface::SCOPE_FARM); $farmRoleVariables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), ScopeInterface::SCOPE_FARMROLE); $name = $this->request->stripValue($farmSettings['name']); if (empty($name)) { $this->setBuildError('name', 'Farm name is invalid'); } if ($farmSettings['variables']) { $result = $farmVariables->validateValues(is_array($farmSettings['variables']) ? $farmSettings['variables'] : [], 0, $farmId); if ($result !== TRUE) { $this->setBuildError('variables', $result); } } if (is_numeric($farmSettings['owner'])) { try { $u = (new Scalr_Account_User())->loadById($farmSettings['owner']); if ($u->getAccountId() != $this->user->getAccountId()) { throw new Exception('User not found'); } } catch (Exception $e) { $this->setBuildError('owner', $e->getMessage()); } } if (is_numeric($farmSettings['teamOwner']) && $farmSettings['teamOwner'] > 0) { if ($this->user->canManageAcl()) { $teams = $this->db->getAll('SELECT id, name FROM account_teams WHERE account_id = ?', array($this->user->getAccountId())); } else { $teams = $this->user->getTeams(); } if (!in_array($farmSettings['teamOwner'], array_map(function ($t) { return $t['id']; }, $teams))) { if ($this->db->GetOne('SELECT team_id FROM farms WHERE id = ?', [$farmId]) != $farmSettings['teamOwner']) { $this->setBuildError('teamOwner', 'Team not found'); } } } if (!empty($roles)) { $hasVpcRouter = false; $vpcRouterRequired = false; $governance = new Scalr_Governance($this->getEnvironmentId()); foreach ($roles as $role) { $dbRole = DBRole::loadById($role['role_id']); if (!$this->hasPermissions($dbRole->__getNewRoleObject())) { $this->setBuildError($dbRole->name, 'You don\'t have access to this role'); } try { $dbRole->__getNewRoleObject()->getImage($role['platform'], $role['cloud_location']); } catch (Exception $e) { $this->setBuildError($dbRole->name, sprintf("Role '%s' is not available in %s on %s", $dbRole->name, $role['platform'], $role['cloud_location'])); } if ($role['alias']) { if (!preg_match("/^[[:alnum:]](?:-*[[:alnum:]])*\$/", $role['alias'])) { $this->setBuildError('alias', 'Alias should start and end with letter or number and contain only letters, numbers and dashes.', $role['farm_role_id']); } } // Validate deployments if (isset($role[Scalr_Role_Behavior::ROLE_DM_APPLICATION_ID])) { $application = Scalr_Dm_Application::init()->loadById($role[Scalr_Role_Behavior::ROLE_DM_APPLICATION_ID]); $this->user->getPermissions()->validate($application); if (!$role[Scalr_Role_Behavior::ROLE_DM_REMOTE_PATH]) { $this->setBuildError(Scalr_Role_Behavior::ROLE_DM_REMOTE_PATH, 'Remote path is required for deployment', $role['farm_role_id']); } } if ($dbRole->hasBehavior(ROLE_BEHAVIORS::VPC_ROUTER)) { $hasVpcRouter = true; } if ($dbRole->hasBehavior(ROLE_BEHAVIORS::RABBITMQ)) { $role['settings'][Entity\FarmRoleSetting::SCALING_MAX_INSTANCES] = $role['settings'][Entity\FarmRoleSetting::SCALING_MIN_INSTANCES]; $role['settings'][Scalr_Role_Behavior_RabbitMQ::ROLE_NODES_RATIO] = (int) $role['settings'][Scalr_Role_Behavior_RabbitMQ::ROLE_NODES_RATIO]; if ($role['settings'][Scalr_Role_Behavior_RabbitMQ::ROLE_NODES_RATIO] < 1 || $role['settings'][Scalr_Role_Behavior_RabbitMQ::ROLE_NODES_RATIO] > 100) { $this->setBuildError(Scalr_Role_Behavior_RabbitMQ::ROLE_NODES_RATIO, 'Nodes ratio should be an integer between 1 and 100', $role['farm_role_id']); } else { $this->checkInteger($role['farm_role_id'], Scalr_Role_Behavior_RabbitMQ::ROLE_DATA_STORAGE_EBS_SIZE, $role['settings'][Scalr_Role_Behavior_RabbitMQ::ROLE_DATA_STORAGE_EBS_SIZE], 'Storage size', 1, 1000); } } if ($dbRole->hasBehavior(ROLE_BEHAVIORS::MONGODB)) { if ($role['settings'][Scalr_Role_Behavior_MongoDB::ROLE_DATA_STORAGE_ENGINE] == 'ebs') { if ($role['settings'][Scalr_Role_Behavior_MongoDB::ROLE_DATA_STORAGE_EBS_SIZE] < 10 || $role['settings'][Scalr_Role_Behavior_MongoDB::ROLE_DATA_STORAGE_EBS_SIZE] > 1000) { $this->setBuildError(Scalr_Role_Behavior_MongoDB::ROLE_DATA_STORAGE_EBS_SIZE, sprintf("EBS size for mongoDB role should be between 10 and 1000 GB", $dbRole->name), $role['farm_role_id']); } } } if ($dbRole->hasBehavior(ROLE_BEHAVIORS::NGINX)) { $proxies = (array) @json_decode($role['settings'][Scalr_Role_Behavior_Nginx::ROLE_PROXIES], true); foreach ($proxies as $proxyIndex => $proxy) { if ($proxy['ssl'] == 1) { if (empty($proxy['ssl_certificate_id'])) { $this->setBuildError(Scalr_Role_Behavior_Nginx::ROLE_PROXIES, ['message' => 'SSL certificate is required', 'invalidIndex' => $proxyIndex], $role['farm_role_id']); break; } if ($proxy['port'] == $proxy['ssl_port']) { $this->setBuildError(Scalr_Role_Behavior_Nginx::ROLE_PROXIES, ['message' => 'HTTP and HTTPS ports cannot be the same', 'invalidIndex' => $proxyIndex], $role['farm_role_id']); } } if (count($proxy['backends']) > 0) { foreach ($proxy['backends'] as $backend) { if (empty($backend['farm_role_id']) && empty($backend['farm_role_alias']) && empty($backend['host'])) { $this->setBuildError(Scalr_Role_Behavior_Nginx::ROLE_PROXIES, ['message' => 'Destination is required', 'invalidIndex' => $proxyIndex], $role['farm_role_id']); break; } } } } } /* Validate scaling */ if (!$dbRole->hasBehavior(ROLE_BEHAVIORS::VPC_ROUTER) && !$dbRole->hasBehavior(ROLE_BEHAVIORS::MONGODB)) { $minCount = $this->checkInteger($role['farm_role_id'], Entity\FarmRoleSetting::SCALING_MIN_INSTANCES, $role['settings'][Entity\FarmRoleSetting::SCALING_MIN_INSTANCES], 'Min instances', 0, 400); $maxCount = $this->checkInteger($role['farm_role_id'], Entity\FarmRoleSetting::SCALING_MAX_INSTANCES, $role['settings'][Entity\FarmRoleSetting::SCALING_MAX_INSTANCES], 'Max instances', 1, 400); if ($minCount !== false && $maxCount !== false && $maxCount < $minCount) { $this->setBuildError(Entity\FarmRoleSetting::SCALING_MAX_INSTANCES, 'Max instances should be greater than or equal to Min instances', $role['farm_role_id']); } $this->checkInteger($role['farm_role_id'], Entity\FarmRoleSetting::SCALING_POLLING_INTERVAL, $role['settings'][Entity\FarmRoleSetting::SCALING_POLLING_INTERVAL], 'Polling interval', 1, 50); if (array_key_exists(Entity\FarmRoleSetting::SCALING_UPSCALE_TIMEOUT_ENABLED, $role["settings"]) && $role['settings'][Entity\FarmRoleSetting::SCALING_UPSCALE_TIMEOUT_ENABLED] == 1) { $this->checkInteger($role['farm_role_id'], Entity\FarmRoleSetting::SCALING_UPSCALE_TIMEOUT, $role['settings'][Entity\FarmRoleSetting::SCALING_UPSCALE_TIMEOUT], 'Upscale timeout', 1); } if (array_key_exists(Entity\FarmRoleSetting::SCALING_DOWNSCALE_TIMEOUT_ENABLED, $role["settings"]) && $role['settings'][Entity\FarmRoleSetting::SCALING_DOWNSCALE_TIMEOUT_ENABLED] == 1) { $this->checkInteger($role['farm_role_id'], Entity\FarmRoleSetting::SCALING_DOWNSCALE_TIMEOUT, $role['settings'][Entity\FarmRoleSetting::SCALING_DOWNSCALE_TIMEOUT], 'Downscale timeout', 1); } if (is_array($role['scaling'])) { foreach ($role['scaling'] as $metricId => $metricSettings) { $hasError = false; if ($metricId == Entity\ScalingMetric::METRIC_URL_RESPONSE_TIME_ID) { $hasError = Validator::validateUrl($metricSettings['url']) !== true || Validator::validateInteger($metricSettings['min']) !== true || Validator::validateInteger($metricSettings['max']) !== true; } elseif ($metricId == Entity\ScalingMetric::METRIC_SQS_QUEUE_SIZE_ID) { $hasError = Validator::validateNotEmpty($metricSettings['queue_name']) !== true || Validator::validateInteger($metricSettings['min']) !== true || Validator::validateInteger($metricSettings['max']) !== true; } elseif (in_array($metricId, [Entity\ScalingMetric::METRIC_LOAD_AVERAGES_ID, Entity\ScalingMetric::METRIC_FREE_RAM_ID, Entity\ScalingMetric::METRIC_BANDWIDTH_ID])) { $hasError = Validator::validateFloat($metricSettings['min']) !== true || Validator::validateFloat($metricSettings['max']) !== true; } if ($hasError) { $this->setBuildError('scaling', ['message' => 'Scaling metric settings are invalid', 'invalidIndex' => $metricId], $role['farm_role_id']); break; } } } } /* Validate advanced settings */ if (!$dbRole->hasBehavior(ROLE_BEHAVIORS::VPC_ROUTER)) { if (isset($role['settings'][Scalr_Role_Behavior::ROLE_BASE_API_PORT])) { $this->checkInteger($role['farm_role_id'], Scalr_Role_Behavior::ROLE_BASE_API_PORT, $role['settings'][Scalr_Role_Behavior::ROLE_BASE_API_PORT], 'Scalarizr API port', 1, 65535); } if (isset($role['settings'][Scalr_Role_Behavior::ROLE_BASE_MESSAGING_PORT])) { $this->checkInteger($role['farm_role_id'], Scalr_Role_Behavior::ROLE_BASE_MESSAGING_PORT, $role['settings'][Scalr_Role_Behavior::ROLE_BASE_MESSAGING_PORT], 'Scalarizr control port', 1, 65535); } if (isset($role['settings'][Entity\FarmRoleSetting::SYSTEM_REBOOT_TIMEOUT])) { $this->checkInteger($role['farm_role_id'], Entity\FarmRoleSetting::SYSTEM_REBOOT_TIMEOUT, $role['settings'][Entity\FarmRoleSetting::SYSTEM_REBOOT_TIMEOUT], 'Reboot timeout', 1); } if (isset($role['settings'][Entity\FarmRoleSetting::SYSTEM_LAUNCH_TIMEOUT])) { $this->checkInteger($role['farm_role_id'], Entity\FarmRoleSetting::SYSTEM_LAUNCH_TIMEOUT, $role['settings'][Entity\FarmRoleSetting::SYSTEM_LAUNCH_TIMEOUT], 'Launch timeout', 1); } } /* Validate chef settings */ if ($dbRole->hasBehavior(ROLE_BEHAVIORS::CHEF)) { if ($role['settings'][Scalr_Role_Behavior_Chef::ROLE_CHEF_BOOTSTRAP] == 1) { if (empty($role['settings'][Scalr_Role_Behavior_Chef::ROLE_CHEF_COOKBOOK_URL]) && empty($role['settings'][Scalr_Role_Behavior_Chef::ROLE_CHEF_SERVER_ID])) { $this->setBuildError(Scalr_Role_Behavior_Chef::ROLE_CHEF_SERVER_ID, 'Chef Server or Chef Solo must be setup if using Chef to bootstrap Role', $role['farm_role_id']); } elseif ($role['settings'][Scalr_Role_Behavior_Chef::ROLE_CHEF_COOKBOOK_URL_TYPE] == 'http' && !empty($role['settings'][Scalr_Role_Behavior_Chef::ROLE_CHEF_COOKBOOK_URL]) && Validator::validateUrl($role['settings'][Scalr_Role_Behavior_Chef::ROLE_CHEF_COOKBOOK_URL]) !== true) { $this->setBuildError(Scalr_Role_Behavior_Chef::ROLE_CHEF_COOKBOOK_URL, 'Cookbook URL is invalid.', $role['farm_role_id']); } } elseif ($dbRole->getProperty(Scalr_Role_Behavior_Chef::ROLE_CHEF_BOOTSTRAP) == 1 && $dbRole->getProperty(Scalr_Role_Behavior_Chef::ROLE_CHEF_SERVER_ID)) { if (strpos($role['farm_role_id'], "virtual_") !== false) { $chefGovernance = $governance->getValue(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_CHEF, 'servers'); if ($chefGovernance !== null && !isset($chefGovernance[$dbRole->getProperty(Scalr_Role_Behavior_Chef::ROLE_CHEF_SERVER_ID)])) { $this->setBuildError(Scalr_Role_Behavior_Chef::ROLE_CHEF_SERVER_ID, 'Chef server is not allowed by Governance.', $role['farm_role_id']); } } if (empty($dbRole->getProperty(Scalr_Role_Behavior_Chef::ROLE_CHEF_ENVIRONMENT)) && empty($role['settings'][Scalr_Role_Behavior_Chef::ROLE_CHEF_ENVIRONMENT])) { $this->setBuildError(Scalr_Role_Behavior_Chef::ROLE_CHEF_ENVIRONMENT, 'Chef Environment is required', $role['farm_role_id']); } } } /** Validate platform specified settings **/ switch ($role['platform']) { case SERVER_PLATFORMS::EC2: if (!empty($role['settings'][Entity\FarmRoleSetting::AWS_TAGS_LIST])) { $reservedBaseCustomTags = ['scalr-meta', 'Name']; $baseCustomTags = @explode("\n", $role['settings'][Entity\FarmRoleSetting::AWS_TAGS_LIST]); foreach ((array) $baseCustomTags as $tag) { $tag = trim($tag); $tagChunks = explode("=", $tag); if (in_array(trim($tagChunks[0]), $reservedBaseCustomTags)) { $this->setBuildError(Entity\FarmRoleSetting::AWS_TAGS_LIST, "Avoid using Scalr-reserved tag names.", $role['farm_role_id']); } } } if ($dbRole->hasBehavior(ROLE_BEHAVIORS::MYSQL)) { if ($role['settings'][Entity\FarmRoleSetting::MYSQL_DATA_STORAGE_ENGINE] == MYSQL_STORAGE_ENGINE::EBS) { if ($dbRole->generation != 2 && isset($role['settings'][Entity\FarmRoleSetting::AWS_AVAIL_ZONE])) { if ($role['settings'][Entity\FarmRoleSetting::AWS_AVAIL_ZONE] == "" || $role['settings'][Entity\FarmRoleSetting::AWS_AVAIL_ZONE] == "x-scalr-diff" || stristr($role['settings'][Entity\FarmRoleSetting::AWS_AVAIL_ZONE], 'x-scalr-custom')) { $this->setBuildError(Entity\FarmRoleSetting::AWS_AVAIL_ZONE, 'Requirement for EBS MySQL data storage is specific \'Placement\' parameter', $role['farm_role_id']); } } } } if ($dbRole->getDbMsrBehavior()) { if ($role['settings'][Scalr_Db_Msr::DATA_STORAGE_ENGINE] == MYSQL_STORAGE_ENGINE::EPH) { if (!$role['settings'][Scalr_Db_Msr::DATA_STORAGE_EPH_DISK] && !$role['settings'][Scalr_Db_Msr::DATA_STORAGE_EPH_DISKS]) { $this->setBuildError(Scalr_Db_Msr::DATA_STORAGE_EPH_DISK, 'Ephemeral disk settings is required', $role['farm_role_id']); } } elseif ($role['settings'][Scalr_Db_Msr::DATA_STORAGE_ENGINE] == MYSQL_STORAGE_ENGINE::EBS) { if (array_key_exists(Scalr_Db_Msr::DATA_STORAGE_EBS_TYPE, $role["settings"])) { if ($role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_TYPE] == CreateVolumeRequestData::VOLUME_TYPE_STANDARD) { $this->checkInteger($role['farm_role_id'], Scalr_Db_Msr::DATA_STORAGE_EBS_SIZE, $role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_SIZE], 'Storage size', 1, 1024); } elseif ($role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_TYPE] == CreateVolumeRequestData::VOLUME_TYPE_GP2) { $this->checkInteger($role['farm_role_id'], Scalr_Db_Msr::DATA_STORAGE_EBS_SIZE, $role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_SIZE], 'Storage size', 1, 16384); } elseif ($role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_TYPE] == CreateVolumeRequestData::VOLUME_TYPE_IO1) { $this->checkInteger($role['farm_role_id'], Scalr_Db_Msr::DATA_STORAGE_EBS_SIZE, $role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_SIZE], 'Storage size', 4, 16384); $this->checkInteger($role['farm_role_id'], Scalr_Db_Msr::DATA_STORAGE_EBS_IOPS, $role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_IOPS], 'IOPS', 100, 20000); } } } if (array_key_exists(Scalr_Db_Msr::DATA_STORAGE_EBS_ENABLE_ROTATION, $role["settings"]) && $role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_ENABLE_ROTATION] == 1) { $this->checkInteger($role['farm_role_id'], Scalr_Db_Msr::DATA_STORAGE_EBS_ROTATE, $role['settings'][Scalr_Db_Msr::DATA_STORAGE_EBS_ROTATE], 'Snapshot rotation limit', 1); } if ($role['settings'][Scalr_Db_Msr::DATA_STORAGE_ENGINE] == MYSQL_STORAGE_ENGINE::LVM) { if (!$role['settings'][Scalr_Role_DbMsrBehavior::ROLE_DATA_STORAGE_LVM_VOLUMES]) { $this->setBuildError(Scalr_Role_DbMsrBehavior::ROLE_DATA_STORAGE_LVM_VOLUMES, 'LVM storage settings is required', $role['farm_role_id']); } } } if ($role['settings'][Entity\FarmRoleSetting::AWS_AVAIL_ZONE] == 'x-scalr-custom=') { $this->setBuildError(Entity\FarmRoleSetting::AWS_AVAIL_ZONE, 'Availability zone should be selected', $role['farm_role_id']); } if (!empty($farmSettings['vpc_id'])) { $sgs = @json_decode($role['settings'][Entity\FarmRoleSetting::AWS_SECURITY_GROUPS_LIST]); if (!$governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_SECURITY_GROUPS) && !$dbRole->hasBehavior(ROLE_BEHAVIORS::VPC_ROUTER) && empty($sgs) && empty($role['settings'][Entity\FarmRoleSetting::AWS_SG_LIST])) { $this->setBuildError(Entity\FarmRoleSetting::AWS_SECURITY_GROUPS_LIST, 'Security group(s) should be selected', $role['farm_role_id']); } $subnets = @json_decode($role['settings'][Entity\FarmRoleSetting::AWS_VPC_SUBNET_ID]); if (empty($subnets)) { $this->setBuildError(Entity\FarmRoleSetting::AWS_VPC_SUBNET_ID, 'VPC Subnet(s) should be selected', $role['farm_role_id']); } if (\Scalr::config('scalr.instances_connection_policy') != 'local' && empty($role['settings'][Scalr_Role_Behavior_Router::ROLE_VPC_SCALR_ROUTER_ID])) { try { if (!empty($subnets[0])) { $platform = PlatformFactory::NewPlatform(SERVER_PLATFORMS::EC2); $info = $platform->listSubnets($this->getEnvironment(), $role['cloud_location'], $farmSettings['vpc_id'], true, $subnets[0]); if (!empty($info["type"]) && $info['type'] == 'private') { $vpcRouterRequired = $role['farm_role_id']; } } } catch (Exception $e) { } } } break; case SERVER_PLATFORMS::CLOUDSTACK: if (!$role['settings'][Entity\FarmRoleSetting::CLOUDSTACK_SERVICE_OFFERING_ID]) { $this->setBuildError(Entity\FarmRoleSetting::CLOUDSTACK_SERVICE_OFFERING_ID, 'Service offering should be selected', $role['farm_role_id']); } break; case SERVER_PLATFORMS::RACKSPACE: if (!$role['settings'][Entity\FarmRoleSetting::RS_FLAVOR_ID]) { $this->setBuildError(Entity\FarmRoleSetting::CLOUDSTACK_SERVICE_OFFERING_ID, 'Flavor should be selected', $role['farm_role_id']); } break; case SERVER_PLATFORMS::GCE: if ($dbRole->getDbMsrBehavior()) { if ($role['settings'][Scalr_Db_Msr::DATA_STORAGE_ENGINE] == MYSQL_STORAGE_ENGINE::GCE_PERSISTENT) { $this->checkInteger($role['farm_role_id'], Scalr_Db_Msr::DATA_STORAGE_GCED_SIZE, $role['settings'][Scalr_Db_Msr::DATA_STORAGE_GCED_SIZE], 'Storage size', 1); } } break; } if ($dbRole->getDbMsrBehavior()) { if (array_key_exists(Scalr_Db_Msr::DATA_BUNDLE_ENABLED, $role["settings"]) && $role['settings'][Scalr_Db_Msr::DATA_BUNDLE_ENABLED] == 1) { $this->checkInteger($role['farm_role_id'], Scalr_Db_Msr::DATA_BUNDLE_EVERY, $role['settings'][Scalr_Db_Msr::DATA_BUNDLE_EVERY], 'Bundle period', 1); $this->checkString($role['farm_role_id'], Scalr_Db_Msr::DATA_BUNDLE_TIMEFRAME_START_HH, $role['settings'][Scalr_Db_Msr::DATA_BUNDLE_TIMEFRAME_START_HH], 'Preferred bundle window start HH is invalid', '/^([0-1][0-9])|(2[0-4])$/'); $this->checkString($role['farm_role_id'], Scalr_Db_Msr::DATA_BUNDLE_TIMEFRAME_START_MM, $role['settings'][Scalr_Db_Msr::DATA_BUNDLE_TIMEFRAME_START_MM], 'Preferred bundle window start MM is invalid', '/^[0-5][0-9]$/'); $this->checkString($role['farm_role_id'], Scalr_Db_Msr::DATA_BUNDLE_TIMEFRAME_END_HH, $role['settings'][Scalr_Db_Msr::DATA_BUNDLE_TIMEFRAME_END_HH], 'Preferred bundle window end HH is invalid', '/^([0-1][0-9])|(2[0-4])$/'); $this->checkString($role['farm_role_id'], Scalr_Db_Msr::DATA_BUNDLE_TIMEFRAME_END_MM, $role['settings'][Scalr_Db_Msr::DATA_BUNDLE_TIMEFRAME_END_MM], 'Preferred bundle window end MM is invalid', '/^[0-5][0-9]$/'); } if (array_key_exists(Scalr_Db_Msr::DATA_BACKUP_ENABLED, $role["settings"]) && $role['settings'][Scalr_Db_Msr::DATA_BACKUP_ENABLED] == 1) { $this->checkInteger($role['farm_role_id'], Scalr_Db_Msr::DATA_BACKUP_EVERY, $role['settings'][Scalr_Db_Msr::DATA_BACKUP_EVERY], 'Backup period', 1); $this->checkString($role['farm_role_id'], Scalr_Db_Msr::DATA_BACKUP_TIMEFRAME_START_HH, $role['settings'][Scalr_Db_Msr::DATA_BACKUP_TIMEFRAME_START_HH], 'Preferred backup window start HH is invalid', '/^([0-1][0-9])|(2[0-4])$/'); $this->checkString($role['farm_role_id'], Scalr_Db_Msr::DATA_BACKUP_TIMEFRAME_START_MM, $role['settings'][Scalr_Db_Msr::DATA_BACKUP_TIMEFRAME_START_MM], 'Preferred backup window start MM is invalid', '/^[0-5][0-9]$/'); $this->checkString($role['farm_role_id'], Scalr_Db_Msr::DATA_BACKUP_TIMEFRAME_END_HH, $role['settings'][Scalr_Db_Msr::DATA_BACKUP_TIMEFRAME_END_HH], 'Preferred backup window end HH is invalid', '/^([0-1][0-9])|(2[0-4])$/'); $this->checkString($role['farm_role_id'], Scalr_Db_Msr::DATA_BACKUP_TIMEFRAME_END_MM, $role['settings'][Scalr_Db_Msr::DATA_BACKUP_TIMEFRAME_END_MM], 'Preferred backup window end MM is invalid', '/^[0-5][0-9]$/'); } } if (!empty($role['settings'][Scalr_Role_Behavior::ROLE_BASE_CUSTOM_TAGS]) && PlatformFactory::isOpenstack($role['platform'])) { $reservedBaseCustomTags = ['scalr-meta', 'farmid', 'role', 'httpproto', 'region', 'hash', 'realrolename', 'szr_key', 'serverid', 'p2p_producer_endpoint', 'queryenv_url', 'behaviors', 'farm_roleid', 'roleid', 'env_id', 'platform', 'server_index', 'cloud_server_id', 'cloud_location_zone', 'owner_email']; $baseCustomTags = @explode("\n", $role['settings'][Scalr_Role_Behavior::ROLE_BASE_CUSTOM_TAGS]); foreach ((array) $baseCustomTags as $tag) { $tag = trim($tag); $tagChunks = explode("=", $tag); if (in_array(trim($tagChunks[0]), $reservedBaseCustomTags)) { $this->setBuildError(Scalr_Role_Behavior::ROLE_BASE_CUSTOM_TAGS, "Avoid using Scalr-reserved metadata names.", $role['farm_role_id']); } } } if (!empty($role['settings'][Scalr_Role_Behavior::ROLE_BASE_HOSTNAME_FORMAT])) { if (!preg_match('/^[\\w\\{\\}\\.-]+$/', $role['settings'][Scalr_Role_Behavior::ROLE_BASE_HOSTNAME_FORMAT])) { $this->setBuildError(Scalr_Role_Behavior::ROLE_BASE_HOSTNAME_FORMAT, "server hostname format for role'{$dbRole->name}' should contain only [a-z0-9-] chars. First char should not be hypen.", $role['farm_role_id']); } } if (!empty($role['settings'][Entity\FarmRoleSetting::DNS_CREATE_RECORDS])) { if ($role['settings'][Entity\FarmRoleSetting::DNS_EXT_RECORD_ALIAS]) { if (!preg_match('/^[\\w\\{\\}\\.-]+$/', $role['settings'][Entity\FarmRoleSetting::DNS_EXT_RECORD_ALIAS])) { $this->setBuildError(Entity\FarmRoleSetting::DNS_EXT_RECORD_ALIAS, "ext- record alias for role '{$dbRole->name}' should contain only [A-Za-z0-9-] chars. First and last char should not be hypen.", $role['farm_role_id']); } } if ($role['settings'][Entity\FarmRoleSetting::DNS_INT_RECORD_ALIAS]) { if (!preg_match('/^[\\w\\{\\}\\.-]+$/', $role['settings'][Entity\FarmRoleSetting::DNS_INT_RECORD_ALIAS])) { $this->setBuildError(Entity\FarmRoleSetting::DNS_INT_RECORD_ALIAS, "int- record alias for role '{$dbRole->name}' should contain only [A-Za-z0-9-] chars. First and last char should not by hypen.", $role['farm_role_id']); } } } // Validate Global variables if (!strstr($role['farm_role_id'], 'virtual_')) { $farmRole = DBFarmRole::LoadByID($role['farm_role_id']); } else { $farmRole = null; if ($dbRole->isDeprecated == 1) { $this->setBuildError('roleId', 'This role has been deprecated and cannot be added', $role['farm_role_id']); } if (!empty($envs = $dbRole->__getNewRoleObject()->getAllowedEnvironments())) { if (!in_array($this->getEnvironmentId(), $envs)) { $this->setBuildError('roleId', "You don't have access to this role", $role['farm_role_id']); } } } if (isset($role['storages']['configs'])) { // TODO: refactor, get rid of using DBFarmRole in constructor $fr = $farmRole ? $farmRole : new DBFarmRole(0); foreach ($fr->getStorage()->validateConfigs($role['storages']['configs']) as $index => $message) { $this->setBuildError('storages', ['message' => $message, 'invalidIndex' => $index], $role['farm_role_id']); break; } } $result = $farmRoleVariables->validateValues(is_array($role['variables']) ? $role['variables'] : [], $dbRole->id, $farmId, $farmRole ? $farmRole->ID : 0); if ($result !== TRUE) { $this->setBuildError('variables', $result, $role['farm_role_id']); } } } if ($farmSettings['vpc_id']) { if (!$hasVpcRouter && $vpcRouterRequired) { $this->setBuildError(Entity\FarmRoleSetting::AWS_VPC_SUBNET_ID, 'You must select a VPC Router for Farm Roles launched in a Private VPC Subnet', $vpcRouterRequired); } } if ($this->getContainer()->analytics->enabled) { if ($farmSettings['projectId']) { $project = $this->getContainer()->analytics->projects->get($farmSettings['projectId']); if (!$project) { $this->setBuildError('projectId', 'Project not found', null); } else { if ($project->ccId != $this->getEnvironment()->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID)) { $this->setBuildError('projectId', 'Invalid project identifier. Project should correspond to the Environment\'s cost center.', null); } } } else { $this->setBuildError('projectId', 'Project field is required', null); } } return $this->errors['error_count'] == 0 ? true : false; }
/** * Applies governance to security groups list * * @param string $list SG list * @param string $platform Platform * @param string $cloudLocation Cloud location * @param array $options options * @return array */ private function applyGovernanceToSgList($list, $platform, $cloudLocation, $options) { if (isset($options['considerGovernance']) && $options['considerGovernance']) { $filteredSg = []; $allowedSgNames = []; $governance = new Scalr_Governance($this->getEnvironmentId()); if ($platform == SERVER_PLATFORMS::EC2) { $governanceSecurityGroups = $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::getEc2SecurityGroupPolicyNameForService($options['serviceName']), null); } elseif (PlatformFactory::isOpenstack($platform)) { $governanceSecurityGroups = $governance->getValue($platform, Scalr_Governance::OPENSTACK_SECURITY_GROUPS, null); } elseif (PlatformFactory::isCloudstack($platform)) { $governanceSecurityGroups = $governance->getValue($platform, Scalr_Governance::CLOUDSTACK_SECURITY_GROUPS, null); } if ($governanceSecurityGroups) { $sgRequiredPatterns = \Scalr_Governance::prepareSecurityGroupsPatterns($options['osFamily'] == 'windows' && $governanceSecurityGroups['windows'] ? $governanceSecurityGroups['windows'] : $governanceSecurityGroups['value']); $sgOptionalPatterns = $governanceSecurityGroups['allow_additional_sec_groups'] ? \Scalr_Governance::prepareSecurityGroupsPatterns($governanceSecurityGroups['additional_sec_groups_list']) : []; foreach ($list as $sg) { $sgNameLowerCase = strtolower($sg['name']); $sgAllowed = false; if ($governanceSecurityGroups['allow_additional_sec_groups']) { if (!empty($sgOptionalPatterns)) { if (isset($sgOptionalPatterns[$sgNameLowerCase])) { $sgAllowed = true; } else { foreach ($sgOptionalPatterns as &$sgOptionalPattern) { if (isset($sgOptionalPattern['regexp']) && preg_match($sgOptionalPattern['regexp'], $sg['name']) === 1) { $sgAllowed = true; break; } } } } else { $sgAllowed = true; } } if (isset($sgRequiredPatterns[$sgNameLowerCase])) { $sgAllowed = true; $sg['addedByGovernance'] = true; $sg['ignoreOnSave'] = true; $sgRequiredPatterns[$sgNameLowerCase]['found'] = true; } else { foreach ($sgRequiredPatterns as &$sgRequiredPattern) { if (isset($sgRequiredPattern['regexp']) && preg_match($sgRequiredPattern['regexp'], $sg['name']) === 1) { $sgRequiredPattern['matches'][] = $sg; break; } } } if ($sgAllowed) { $allowedSgNames[] = $sgNameLowerCase; $filteredSg[$sg['id']] = $sg; } } foreach ($sgRequiredPatterns as &$sgRequiredPattern) { if (isset($sgRequiredPattern['matches']) && count($sgRequiredPattern['matches']) == 1) { $sg = $sgRequiredPattern['matches'][0]; if (!isset($filteredSg[$sg['id']])) { $filteredSg[$sg['id']] = $sg; } $filteredSg[$sg['id']]['addedByGovernance'] = true; $filteredSg[$sg['id']]['ignoreOnSave'] = true; $sgRequiredPattern['found'] = true; } } $list = $filteredSg; if (!$options['existingGroupsOnly']) { foreach ($sgRequiredPatterns as $sgRequiredPattern) { if (!$sgRequiredPattern['found']) { $list[] = ['id' => null, 'name' => $sgRequiredPattern['value'], 'description' => null, 'vpcId' => null, 'owner' => null, 'addedByGovernance' => true, 'ignoreOnSave' => true]; } } } } } return $list; }
public function createAction() { $governance = new Scalr_Governance($this->getEnvironmentId()); $this->response->page('ui/security/groups/edit.js', array('platform' => $this->getParam('platform'), 'cloudLocation' => $this->getParam('cloudLocation'), 'cloudLocationName' => $this->getCloudLocationName($this->getParam('platform'), $this->getParam('cloudLocation')), 'accountId' => $this->environment->getPlatformConfigValue(Ec2PlatformModule::ACCOUNT_ID), 'vpcLimits' => $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, null), 'remoteAddress' => $this->request->getRemoteAddr()), array('ui/security/groups/sgeditor.js')); }
public function FarmCreate($Name, $Description = "", $ProjectID = "", array $Configuration = array()) { $this->restrictFarmAccess(null, Acl::PERM_FARMS_MANAGE); $governance = new Scalr_Governance($this->Environment->id); $ProjectID = strtolower($ProjectID); $response = $this->CreateInitialResponse(); $Name = $this->stripValue($Name); $Description = $this->stripValue($Description); if (!$Name || strlen($Name) < 5) { throw new Exception('Name should be at least 5 characters'); } if ($Configuration['vpc_region'] && !$Configuration['vpc_id']) { throw new Exception("VPC ID is required if VPC region was specified"); } if (!$Configuration['vpc_region'] && $Configuration['vpc_id']) { throw new Exception("VPC Region is required if VPC ID was specified"); } // VPC Governance validation $vpcGovernance = $governance->getValue('ec2', 'aws.vpc'); if ($vpcGovernance) { $vpcGovernanceRegions = $governance->getValue('ec2', 'aws.vpc', 'regions'); if (!$Configuration['vpc_region']) { throw new Exception("VPC configuration is required according to governance settings"); } if (!in_array($Configuration['vpc_region'], array_keys($vpcGovernanceRegions))) { throw new Exception(sprintf("Only %s region(s) allowed according to governance settings", implode(', ', array_keys($vpcGovernanceRegions)))); } if (!in_array($Configuration['vpc_id'], $vpcGovernanceRegions[$Configuration['vpc_region']]['ids'])) { throw new Exception(sprintf("Only %s VPC(s) allowed according to governance settings", implode(', ', $vpcGovernanceRegions[$Configuration['vpc_region']]['ids']))); } } $dbFarm = new DBFarm(); $dbFarm->ClientID = $this->user->getAccountId(); $dbFarm->EnvID = $this->Environment->id; $dbFarm->Status = FARM_STATUS::TERMINATED; $dbFarm->createdByUserId = $this->user->getId(); $dbFarm->createdByUserEmail = $this->user->getEmail(); $dbFarm->changedByUserId = $this->user->getId(); $dbFarm->changedTime = microtime(); $dbFarm->Name = $Name; $dbFarm->RolesLaunchOrder = 0; $dbFarm->Comments = $Description; $dbFarm->save(); //Associates cost analytics project with the farm. $dbFarm->setProject(!empty($ProjectID) ? $ProjectID : null); if ($governance->isEnabled(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_LEASE)) { $dbFarm->SetSetting(DBFarm::SETTING_LEASE_STATUS, 'Active'); // for created farm } if (!$Configuration['timezone']) { $Configuration['timezone'] = date_default_timezone_get(); } $dbFarm->SetSetting(DBFarm::SETTING_TIMEZONE, $Configuration['timezone']); if ($Configuration['vpc_region']) { $dbFarm->SetSetting(DBFarm::SETTING_EC2_VPC_ID, $Configuration['vpc_id']); $dbFarm->SetSetting(DBFarm::SETTING_EC2_VPC_REGION, $Configuration['vpc_region']); } $response->FarmID = $dbFarm->ID; return $response; }
/** * Gets the list of the security groups for the specified db server. * * If server does not have required security groups this method will create them. * * @param DBServer $DBServer The DB Server instance * @param \Scalr\Service\Aws\Ec2 $ec2 Ec2 Client instance * @param string $vpcId optional The ID of VPC * @param \Scalr_Governance $governance Governance * @param string $osFamily optional OS family of the instance * @return array Returns array looks like array(groupid-1, groupid-2, ..., groupid-N) */ private function GetServerSecurityGroupsList(DBServer $DBServer, \Scalr\Service\Aws\Ec2 $ec2, $vpcId = "", \Scalr_Governance $governance = null, $osFamily = null) { $retval = array(); $checkGroups = array(); $wildCardSgs = []; $sgGovernance = false; $allowAdditionalSgs = true; $roleBuilderSgName = \Scalr::config('scalr.aws.security_group_name') . "-rb"; if ($governance && $DBServer->farmRoleId) { $sgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS); if ($osFamily == 'windows' && $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'windows')) { $sgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'windows'); } if ($sgs !== null) { $governanceSecurityGroups = @explode(",", $sgs); if (!empty($governanceSecurityGroups)) { foreach ($governanceSecurityGroups as $sg) { if ($sg != '') { array_push($checkGroups, trim($sg)); if (strpos($sg, '*') !== false) { array_push($wildCardSgs, trim($sg)); } } } } if (!empty($checkGroups)) { $sgGovernance = true; } $allowAdditionalSgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'allow_additional_sec_groups'); } } if (!$sgGovernance || $allowAdditionalSgs) { if ($DBServer->farmRoleId != 0) { $dbFarmRole = $DBServer->GetFarmRoleObject(); if ($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SECURITY_GROUPS_LIST) !== null) { // New SG management $sgs = @json_decode($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SECURITY_GROUPS_LIST)); if (!empty($sgs)) { foreach ($sgs as $sg) { if (stripos($sg, 'sg-') === 0) { array_push($retval, $sg); } else { array_push($checkGroups, $sg); } } } } else { // Old SG management array_push($checkGroups, 'default'); array_push($checkGroups, \Scalr::config('scalr.aws.security_group_name')); if (!$vpcId) { array_push($checkGroups, "scalr-farm.{$DBServer->farmId}"); array_push($checkGroups, "scalr-role.{$DBServer->farmRoleId}"); } $additionalSgs = trim($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SG_LIST)); if ($additionalSgs) { $sgs = explode(",", $additionalSgs); if (!empty($sgs)) { foreach ($sgs as $sg) { $sg = trim($sg); if (stripos($sg, 'sg-') === 0) { array_push($retval, $sg); } else { array_push($checkGroups, $sg); } } } } } } else { array_push($checkGroups, $roleBuilderSgName); } } // No name based security groups, return only SG ids. if (empty($checkGroups)) { return $retval; } // Filter groups $filter = array(array('name' => SecurityGroupFilterNameType::groupName(), 'value' => $checkGroups)); // If instance run in VPC, add VPC filter if ($vpcId != '') { $filter[] = array('name' => SecurityGroupFilterNameType::vpcId(), 'value' => $vpcId); } // Get filtered list of SG required by scalr; try { $list = $ec2->securityGroup->describe(null, null, $filter); $sgList = array(); foreach ($list as $sg) { /* @var $sg \Scalr\Service\Aws\Ec2\DataType\SecurityGroupData */ if ($vpcId == '' && !$sg->vpcId || $vpcId && $sg->vpcId == $vpcId) { $sgList[$sg->groupName] = $sg->groupId; } } unset($list); } catch (Exception $e) { throw new Exception("Cannot get list of security groups (1): {$e->getMessage()}"); } foreach ($checkGroups as $groupName) { // Check default SG if ($groupName == 'default') { array_push($retval, $sgList[$groupName]); // Check Roles builder SG } elseif ($groupName == $roleBuilderSgName) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($roleBuilderSgName, "Security group for Roles Builder", $vpcId); $ipRangeList = new IpRangeList(); foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) { $ipRangeList->append(new IpRangeData($ip)); } sleep(2); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 22, 22, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList)), $securityGroupId); $sgList[$roleBuilderSgName] = $securityGroupId; } catch (Exception $e) { throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $roleBuilderSgName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); //Check scalr-farm.* security group } elseif (stripos($groupName, 'scalr-farm.') === 0) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmID N%s", $DBServer->farmId), $vpcId); sleep(2); $userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->keychain(SERVER_PLATFORMS::EC2)->properties[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID], null, $groupName)); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)), $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (Exception $e) { throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); //Check scalr-role.* security group } elseif (stripos($groupName, 'scalr-role.') === 0) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmRoleID N%s on FarmID N%s", $DBServer->GetFarmRoleObject()->ID, $DBServer->farmId), $vpcId); sleep(2); // DB rules $dbRules = $DBServer->GetFarmRoleObject()->GetRoleObject()->getSecurityRules(); $groupRules = array(); foreach ($dbRules as $rule) { $groupRules[CryptoTool::hash($rule['rule'])] = $rule; } // Behavior rules foreach (\Scalr_Role_Behavior::getListForFarmRole($DBServer->GetFarmRoleObject()) as $bObj) { $bRules = $bObj->getSecurityRules(); foreach ($bRules as $r) { if ($r) { $groupRules[CryptoTool::hash($r)] = array('rule' => $r); } } } // Default rules $userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->keychain(SERVER_PLATFORMS::EC2)->properties[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID], null, $groupName)); $rules = array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)); foreach ($groupRules as $rule) { $group_rule = explode(":", $rule["rule"]); $rules[] = new IpPermissionData($group_rule[0], $group_rule[1], $group_rule[2], new IpRangeData($group_rule[3])); } $ec2->securityGroup->authorizeIngress($rules, $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (Exception $e) { throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); } elseif ($groupName == \Scalr::config('scalr.aws.security_group_name')) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, "Security rules needed by Scalr", $vpcId); $ipRangeList = new IpRangeList(); foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) { $ipRangeList->append(new IpRangeData($ip)); } // TODO: Open only FOR VPC ranges $ipRangeList->append(new IpRangeData('10.0.0.0/8')); sleep(2); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 3306, 3306, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList), new IpPermissionData('udp', 8014, 8014, $ipRangeList)), $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (Exception $e) { throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); } else { if (!isset($sgList[$groupName])) { if (!in_array($groupName, $wildCardSgs)) { throw new Exception(sprintf(_("Security group '%s' is not found"), $groupName)); } else { $wildCardMatchedSgs = []; $groupNamePattern = \Scalr_Governance::convertAsteriskPatternToRegexp($groupName); foreach ($sgList as $sgGroupName => $sgGroupId) { if (preg_match($groupNamePattern, $sgGroupName) === 1) { array_push($wildCardMatchedSgs, $sgGroupId); } } if (empty($wildCardMatchedSgs)) { throw new Exception(sprintf(_("Security group matched to pattern '%s' is not found."), $groupName)); } else { if (count($wildCardMatchedSgs) > 1) { throw new Exception(sprintf(_("There are more than one Security group matched to pattern '%s' found."), $groupName)); } else { array_push($retval, $wildCardMatchedSgs[0]); } } } } else { array_push($retval, $sgList[$groupName]); } } } return $retval; }
private function GetServerSecurityGroupsList(DBServer $DBServer, \Scalr\Service\CloudStack\CloudStack $csClient, \Scalr_Governance $governance = null) { $retval = array(); $checkGroups = array(); $sgGovernance = true; $allowAdditionalSgs = true; if ($governance) { $sgs = $governance->getValue($DBServer->platform, \Scalr_Governance::CLOUDSTACK_SECURITY_GROUPS); if ($sgs !== null) { $governanceSecurityGroups = @explode(",", $sgs); if (!empty($governanceSecurityGroups)) { foreach ($governanceSecurityGroups as $sg) { if ($sg != '') { array_push($checkGroups, trim($sg)); } } } $sgGovernance = false; $allowAdditionalSgs = $governance->getValue($DBServer->platform, \Scalr_Governance::CLOUDSTACK_SECURITY_GROUPS, 'allow_additional_sec_groups'); } } if (!$sgGovernance || $allowAdditionalSgs) { if ($DBServer->farmRoleId != 0) { $dbFarmRole = $DBServer->GetFarmRoleObject(); if ($dbFarmRole->GetSetting(\DBFarmRole::SETTING_CLOUDSTACK_SECURITY_GROUPS_LIST) !== null) { // New SG management $sgs = @json_decode($dbFarmRole->GetSetting(\DBFarmRole::SETTING_CLOUDSTACK_SECURITY_GROUPS_LIST)); if (!empty($sgs)) { foreach ($sgs as $sg) { array_push($checkGroups, $sg); } } } } else { array_push($checkGroups, 'scalr-rb-system'); } } try { $sgroups = array(); $sgroupIds = array(); $list = $csClient->securityGroup->describe(); foreach ($list as $sg) { /* @var $sg SecurityGroupData */ $sgroups[strtolower($sg->name)] = $sg; $sgroupIds[strtolower($sg->id)] = $sg; } } catch (\Exception $e) { throw new \Exception("GetServerSecurityGroupsList failed: {$e->getMessage()}"); } foreach ($checkGroups as $groupName) { // || !in_array($groupName, array('scalr-rb-system', 'default', \Scalr::config('scalr.aws.security_group_name'))) if (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/si', $groupName)) { if (isset($sgroupIds[strtolower($groupName)])) { $groupName = $sgroupIds[$groupName]->name; } else { throw new \Exception(sprintf(_("Security group '%s' is not found (1)"), $groupName)); } } // Check default SG if ($groupName == 'default') { array_push($retval, $sgroups[$groupName]->id); // Check Roles builder SG } elseif ($groupName == 'scalr-rb-system' || $groupName == \Scalr::config('scalr.aws.security_group_name')) { if (!isset($sgroups[strtolower($groupName)])) { $request = new CreateSecurityGroupData($groupName); $request->description = _("Scalr system security group"); $sg = $csClient->securityGroup->create($request); $sgroups[strtolower($groupName)] = $sg; $sgroupIds[strtolower($sg->id)] = $sg; } array_push($retval, $sgroups[$groupName]->id); } else { if (!isset($sgroups[strtolower($groupName)])) { throw new \Exception(sprintf(_("Security group '%s' is not found (2)"), $groupName)); } else { array_push($retval, $sgroups[strtolower($groupName)]->id); } } } return $retval; }
/** * {@inheritdoc} * @see \Scalr\Modules\PlatformModuleInterface::LaunchServer() */ public function LaunchServer(DBServer $DBServer, Scalr_Server_LaunchOptions $launchOptions = null) { $environment = $DBServer->GetEnvironmentObject(); $governance = new \Scalr_Governance($DBServer->envId); $azure = $environment->azure(); $subscriptionId = $environment->keychain(SERVER_PLATFORMS::AZURE)->properties[CloudCredentialsProperty::AZURE_SUBSCRIPTION_ID]; if (!$launchOptions) { $dbFarmRole = $DBServer->GetFarmRoleObject(); $DBRole = $dbFarmRole->GetRoleObject(); $launchOptions = new \Scalr_Server_LaunchOptions(); $launchOptions->cloudLocation = $dbFarmRole->CloudLocation; $launchOptions->serverType = $dbFarmRole->GetSetting(FarmRoleSetting::INSTANCE_TYPE); $launchOptions->availZone = $dbFarmRole->GetSetting(FarmRoleSetting::SETTING_AZURE_AVAIL_SET); $launchOptions->imageId = $DBRole->__getNewRoleObject()->getImage(\SERVER_PLATFORMS::AZURE, "")->imageId; $isWindows = $DBRole->getOs()->family == 'windows'; // Set User Data $u_data = ""; foreach ($DBServer->GetCloudUserData() as $k => $v) { $u_data .= "{$k}={$v};"; } $launchOptions->userData = trim($u_data, ";"); $launchOptions->azureResourceGroup = $dbFarmRole->GetSetting(FarmRoleSetting::SETTING_AZURE_RESOURCE_GROUP); $launchOptions->azureStorageAccount = $dbFarmRole->GetSetting(FarmRoleSetting::SETTING_AZURE_STORAGE_ACCOUNT); //Create NIC try { $ipConfigProperties = new IpConfigurationProperties(["id" => sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s", $subscriptionId, $launchOptions->azureResourceGroup, $dbFarmRole->GetSetting(FarmRoleSetting::SETTING_AZURE_VIRTUAL_NETWORK), $dbFarmRole->GetSetting(FarmRoleSetting::SETTING_AZURE_SUBNET))], "Dynamic"); $publicIpName = null; if ($governance->isEnabled(\SERVER_PLATFORMS::AZURE, \Scalr_Governance::AZURE_NETWORK)) { $usePublicIp = $governance->getValue(\SERVER_PLATFORMS::AZURE, \Scalr_Governance::AZURE_NETWORK, 'use_public_ips'); } if (!isset($usePublicIp)) { $usePublicIp = $dbFarmRole->GetSetting(FarmRoleSetting::SETTING_AZURE_USE_PUBLIC_IPS); } if ($usePublicIp) { //Create Public IP object $publicIpName = "scalr-{$DBServer->serverId}"; $createPublicIpAddressRequest = new CreatePublicIpAddress($launchOptions->cloudLocation, new PublicIpAddressProperties('Dynamic')); $ipCreateResult = $azure->network->publicIPAddress->create($subscriptionId, $launchOptions->azureResourceGroup, $publicIpName, $createPublicIpAddressRequest); } if ($publicIpName) { $ipConfigProperties->publicIPAddress = ["id" => sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/publicIPAddresses/%s", $subscriptionId, $launchOptions->azureResourceGroup, $publicIpName)]; } $nicProperties = new InterfaceProperties([new InterfaceIpConfigurationsData('public1', $ipConfigProperties)]); //Security group $sg = $dbFarmRole->GetSetting(FarmRoleSetting::SETTING_AZURE_SECURITY_GROUPS_LIST); if ($sg) { $sgName = json_decode($sg); if ($sgName) { $sgroup = new SecurityGroupData(); $sgroup->id = sprintf('/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s', $subscriptionId, $launchOptions->azureResourceGroup, $sgName[0]); $nicProperties->setNetworkSecurityGroup($sgroup); } } $createNicData = new CreateInterface($launchOptions->cloudLocation, $nicProperties); $nicResponse = $azure->network->interface->create($subscriptionId, $launchOptions->azureResourceGroup, "scalr-{$DBServer->serverId}", $createNicData); } catch (\Exception $e) { throw new \Exception("Scalr is unable to create NetworkInterface: {$e->getMessage()}"); } $launchOptions->azureNicName = "scalr-{$DBServer->serverId}"; $launchOptions->azurePublicIpName = $publicIpName; } // Configure OS Profile // Make sure that password always have 1 special character. $adminPassword = \Scalr::GenerateSecurePassword(16, ['D' => '.']); $osProfile = new OsProfile('scalr', $adminPassword); $osProfile->computerName = \Scalr::GenerateUID(true); $osProfile->customData = base64_encode(trim($launchOptions->userData)); // Configure Network Profile $networkProfile = ["networkInterfaces" => [["id" => sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/networkInterfaces/%s", $subscriptionId, $launchOptions->azureResourceGroup, $launchOptions->azureNicName)]]]; // Configure Storage Profile $osDiskName = "scalr-{$DBServer->serverId}"; $vhd = ['uri' => sprintf("https://%s.blob.core.windows.net/vhds/%s.vhd", $launchOptions->azureStorageAccount, $osDiskName)]; $storageProfile = new StorageProfile(new OsDisk($osDiskName, $vhd, 'FromImage')); if (preg_match("/^([^\\/]+)\\/([^\\/]+)\\/([^\\/]+)\\/([^\\/]+)(\\/(1))?\$/", rtrim($launchOptions->imageId, '/'), $imageChunks)) { $publisher = $imageChunks[1]; $offer = $imageChunks[2]; $sku = $imageChunks[3]; $version = $imageChunks[4]; $isMarketPlaceImage = isset($imageChunks[5]) ? true : false; if ($isMarketPlaceImage) { $plan = new PlanProperties($sku, $publisher, $offer); } $storageProfile->setImageReference(['publisher' => $publisher, 'offer' => $offer, 'sku' => $sku, 'version' => $version]); } else { throw new \Exception("Image definition '{$launchOptions->imageId}' is not supported"); } $vmProps = new VirtualMachineProperties(["vmSize" => $launchOptions->serverType], $networkProfile, $storageProfile, $osProfile); // Set availability set if configured. if ($launchOptions->availZone) { $vmProps->availabilitySet = ['id' => sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/availabilitySets/%s", $subscriptionId, $launchOptions->azureResourceGroup, $launchOptions->availZone)]; } $vmData = new CreateVirtualMachine($DBServer->serverId, $launchOptions->cloudLocation, $vmProps); $vmData->tags = $DBServer->getAzureTags(); if (isset($plan)) { $vmData->setPlan($plan); } $azure->compute->virtualMachine->create($subscriptionId, $launchOptions->azureResourceGroup, $vmData); $DBServer->setOsType($isWindows ? 'windows' : 'linux'); $instanceTypeInfo = $this->getInstanceType($launchOptions->serverType, $environment, $launchOptions->cloudLocation); /* @var $instanceTypeInfo CloudInstanceType */ $DBServer->SetProperties([\AZURE_SERVER_PROPERTIES::SERVER_NAME => $DBServer->serverId, \AZURE_SERVER_PROPERTIES::ADMIN_PASSWORD => $adminPassword, \AZURE_SERVER_PROPERTIES::RESOURCE_GROUP => $launchOptions->azureResourceGroup, \AZURE_SERVER_PROPERTIES::CLOUD_LOCATION => $launchOptions->cloudLocation, \AZURE_SERVER_PROPERTIES::AVAIL_SET => $launchOptions->availZone, \AZURE_SERVER_PROPERTIES::NETWORK_INTERFACE => $launchOptions->azureNicName, \AZURE_SERVER_PROPERTIES::PUBLIC_IP_NAME => $launchOptions->azurePublicIpName, \SERVER_PROPERTIES::INFO_INSTANCE_VCPUS => $instanceTypeInfo ? $instanceTypeInfo->vcpus : null]); $params = ['type' => $launchOptions->serverType]; if ($instanceTypeInfo) { $params['instanceTypeName'] = $instanceTypeInfo->name; } $DBServer->imageId = $launchOptions->imageId; $DBServer->update($params); $DBServer->cloudLocation = $launchOptions->cloudLocation; $DBServer->cloudLocationZone = $launchOptions->availZone; // we set server history here $DBServer->getServerHistory()->update(['cloudServerId' => $DBServer->serverId]); return $DBServer; }
public function LaunchServer(DBServer $DBServer, \Scalr_Server_LaunchOptions $launchOptions = null) { $environment = $DBServer->GetEnvironmentObject(); $ccProps = $environment->keychain(SERVER_PLATFORMS::GCE)->properties; $governance = new \Scalr_Governance($environment->id); $rootDeviceSettings = null; $ssdDisks = array(); $scopes = ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/compute", "https://www.googleapis.com/auth/devstorage.full_control"]; if (!$launchOptions) { $launchOptions = new \Scalr_Server_LaunchOptions(); $DBRole = $DBServer->GetFarmRoleObject()->GetRoleObject(); $launchOptions->imageId = $DBRole->__getNewRoleObject()->getImage(\SERVER_PLATFORMS::GCE, $DBServer->GetProperty(\GCE_SERVER_PROPERTIES::CLOUD_LOCATION))->imageId; $launchOptions->serverType = $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::INSTANCE_TYPE); $launchOptions->cloudLocation = $DBServer->GetFarmRoleObject()->CloudLocation; $userData = $DBServer->GetCloudUserData(); $launchOptions->architecture = 'x86_64'; $networkName = $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::GCE_NETWORK); $subnet = $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::GCE_SUBNET); $onHostMaintenance = $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::GCE_ON_HOST_MAINTENANCE); $osType = $DBRole->getOs()->family == 'windows' ? 'windows' : 'linux'; $rootDevice = json_decode($DBServer->GetFarmRoleObject()->GetSetting(\Scalr_Role_Behavior::ROLE_BASE_ROOT_DEVICE_CONFIG), true); if ($rootDevice && $rootDevice['settings']) { $rootDeviceSettings = $rootDevice['settings']; } $storage = new FarmRoleStorage($DBServer->GetFarmRoleObject()); $volumes = $storage->getVolumesConfigs($DBServer); if (!empty($volumes)) { foreach ($volumes as $volume) { if ($volume->type == FarmRoleStorageConfig::TYPE_GCE_EPHEMERAL) { array_push($ssdDisks, $volume); } } } if ($governance->isEnabled(\Scalr_Governance::CATEGORY_GENERAL, \Scalr_Governance::GENERAL_HOSTNAME_FORMAT)) { $hostNameFormat = $governance->getValue(\Scalr_Governance::CATEGORY_GENERAL, \Scalr_Governance::GENERAL_HOSTNAME_FORMAT); } else { $hostNameFormat = $DBServer->GetFarmRoleObject()->GetSetting(\Scalr_Role_Behavior::ROLE_BASE_HOSTNAME_FORMAT); } $hostname = !empty($hostNameFormat) ? $DBServer->applyGlobalVarsToValue($hostNameFormat) : ''; if ($hostname != '') { $DBServer->SetProperty(\Scalr_Role_Behavior::SERVER_BASE_HOSTNAME, $hostname); } $userScopes = json_decode($DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::GCE_INSTANCE_PERMISSIONS)); if (!empty($userScopes) && is_array($userScopes)) { $scopes = array_merge($scopes, $userScopes); } } else { $userData = array(); $networkName = 'default'; $osType = 'linux'; $hostname = ''; } if (!$onHostMaintenance) { $onHostMaintenance = 'MIGRATE'; } if ($DBServer->status == \SERVER_STATUS::TEMPORARY) { $keyName = "SCALR-ROLESBUILDER-" . SCALR_ID; } else { $keyName = "FARM-{$DBServer->farmId}-" . SCALR_ID; } $sshKey = (new SshKey())->loadGlobalByName($DBServer->envId, \SERVER_PLATFORMS::GCE, "", $keyName); if (!$sshKey) { $sshKey = new SshKey(); $keys = $sshKey->generateKeypair(); if ($keys['public']) { $sshKey->farmId = $DBServer->farmId; $sshKey->envId = $DBServer->envId; $sshKey->type = SshKey::TYPE_GLOBAL; $sshKey->platform = \SERVER_PLATFORMS::GCE; $sshKey->cloudLocation = ""; $sshKey->cloudKeyName = $keyName; $sshKey->save(); $publicKey = $keys['public']; } else { throw new Exception("Scalr unable to generate ssh keypair"); } } else { $publicKey = $sshKey->publicKey; } $gce = $this->getClient($environment); $projectId = $ccProps[Entity\CloudCredentialsProperty::GCE_PROJECT_ID]; // Check firewall $firewalls = $gce->firewalls->listFirewalls($projectId); $firewallFound = false; foreach ($firewalls->getItems() as $f) { if ($f->getName() == 'scalr-system') { $firewallFound = true; break; } } // Create scalr firewall if (!$firewallFound) { $firewall = new \Google_Service_Compute_Firewall(); $firewall->setName('scalr-system'); $firewall->setNetwork($this->getObjectUrl($networkName, 'networks', $projectId)); //Get scalr IP-pool IP list and set source ranges $firewall->setSourceRanges(\Scalr::config('scalr.aws.ip_pool')); // Set ports $tcp = new \Google_Service_Compute_FirewallAllowed(); $tcp->setIPProtocol('tcp'); $tcp->setPorts(array('1-65535')); $udp = new \Google_Service_Compute_FirewallAllowed(); $udp->setIPProtocol('udp'); $udp->setPorts(array('1-65535')); $firewall->setAllowed(array($tcp, $udp)); // Set target tags $firewall->setTargetTags(array('scalr')); $gce->firewalls->insert($projectId, $firewall); } $instance = new \Google_Service_Compute_Instance(); $instance->setKind("compute#instance"); // Set scheduling $scheduling = new \Google_Service_Compute_Scheduling(); $scheduling->setAutomaticRestart(true); $scheduling->setOnHostMaintenance($onHostMaintenance); $instance->setScheduling($scheduling); $accessConfig = new \Google_Service_Compute_AccessConfig(); $accessConfig->setName("External NAT"); $accessConfig->setType("ONE_TO_ONE_NAT"); $network = new \Google_Service_Compute_NetworkInterface(); $network->setNetwork($this->getObjectUrl($networkName, 'networks', $projectId)); if (!empty($subnet)) { $network->setSubnetwork($this->getObjectUrl($subnet, 'subnetworks', $projectId, $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::GCE_REGION))); } $network->setAccessConfigs(array($accessConfig)); $instance->setNetworkInterfaces(array($network)); $serviceAccount = new \Google_Service_Compute_ServiceAccount(); $serviceAccount->setEmail("default"); $serviceAccount->setScopes($scopes); $instance->setServiceAccounts(array($serviceAccount)); if ($launchOptions->cloudLocation != 'x-scalr-custom') { $availZone = $launchOptions->cloudLocation; } else { $location = $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::GCE_CLOUD_LOCATION); $availZones = array(); if (stristr($location, "x-scalr-custom")) { $zones = explode("=", $location); foreach (explode(":", $zones[1]) as $zone) { if ($zone != "") { array_push($availZones, $zone); } } } sort($availZones); $availZones = array_reverse($availZones); $servers = $DBServer->GetFarmRoleObject()->GetServersByFilter(array("status" => array(\SERVER_STATUS::RUNNING, \SERVER_STATUS::INIT, \SERVER_STATUS::PENDING))); $availZoneDistribution = array(); foreach ($servers as $cDbServer) { if ($cDbServer->serverId != $DBServer->serverId) { $availZoneDistribution[$cDbServer->GetProperty(\GCE_SERVER_PROPERTIES::CLOUD_LOCATION)]++; } } $sCount = 1000000; foreach ($availZones as $zone) { if ((int) $availZoneDistribution[$zone] <= $sCount) { $sCount = (int) $availZoneDistribution[$zone]; $availZone = $zone; } } $aZones = implode(",", $availZones); // Available zones $dZones = ""; // Zones distribution foreach ($availZoneDistribution as $zone => $num) { $dZones .= "({$zone}:{$num})"; } } $instance->setZone($this->getObjectUrl($availZone, 'zones', $projectId)); $instance->setMachineType($this->getObjectUrl($launchOptions->serverType, 'machineTypes', $projectId, $availZone)); //Create root disk $image = $this->getObjectUrl($launchOptions->imageId, 'images', $projectId); $disks = array(); $diskName = "root-{$DBServer->serverId}"; $initializeParams = new \Google_Service_Compute_AttachedDiskInitializeParams(); $initializeParams->sourceImage = $image; $initializeParams->diskName = $diskName; if ($rootDeviceSettings) { $initializeParams->diskType = $this->getObjectUrl($rootDeviceSettings[FarmRoleStorageConfig::SETTING_GCE_PD_TYPE] ? $rootDeviceSettings[FarmRoleStorageConfig::SETTING_GCE_PD_TYPE] : 'pd-standard', 'diskTypes', $projectId, $availZone); $initializeParams->diskSizeGb = $rootDeviceSettings[FarmRoleStorageConfig::SETTING_GCE_PD_SIZE]; } $attachedDisk = new \Google_Service_Compute_AttachedDisk(); $attachedDisk->setKind("compute#attachedDisk"); $attachedDisk->setBoot(true); $attachedDisk->setMode("READ_WRITE"); $attachedDisk->setType("PERSISTENT"); $attachedDisk->setDeviceName("root"); $attachedDisk->setAutoDelete(true); $attachedDisk->setInitializeParams($initializeParams); array_push($disks, $attachedDisk); if (count($ssdDisks) > 0) { foreach ($ssdDisks as $disk) { $attachedDisk = new \Google_Service_Compute_AttachedDisk(); $attachedDisk->setKind("compute#attachedDisk"); $attachedDisk->setBoot(false); $attachedDisk->setMode("READ_WRITE"); $attachedDisk->setType("SCRATCH"); $attachedDisk->setDeviceName(str_replace("google-", "", $disk->name)); $attachedDisk->setInterface('SCSI'); $attachedDisk->setAutoDelete(true); $initializeParams = new \Google_Service_Compute_AttachedDiskInitializeParams(); $initializeParams->diskType = $this->getObjectUrl('local-ssd', 'diskTypes', $projectId, $availZone); $attachedDisk->setInitializeParams($initializeParams); array_push($disks, $attachedDisk); } } $instance->setDisks($disks); $instance->setName($DBServer->serverId); $tags = array('scalr', "env-{$DBServer->envId}"); if ($DBServer->farmId) { $tags[] = "farm-{$DBServer->farmId}"; } if ($DBServer->farmRoleId) { $tags[] = "farmrole-{$DBServer->farmRoleId}"; } $gTags = new \Google_Service_Compute_Tags(); $gTags->setItems($tags); $instance->setTags($gTags); $metadata = new \Google_Service_Compute_Metadata(); $items = array(); // Set user data $uData = ''; foreach ($userData as $k => $v) { $uData .= "{$k}={$v};"; } $uData = trim($uData, ";"); if ($uData) { $item = new \Google_Service_Compute_MetadataItems(); $item->setKey('scalr'); $item->setValue($uData); $items[] = $item; } if ($osType == 'windows') { // Add Windows credentials $item = new \Google_Service_Compute_MetadataItems(); $item->setKey("gce-initial-windows-user"); $item->setValue("scalr"); $items[] = $item; $item = new \Google_Service_Compute_MetadataItems(); $item->setKey("gce-initial-windows-password"); $item->setValue(\Scalr::GenerateRandomKey(16) . rand(0, 9)); $items[] = $item; } else { // Add SSH Key $item = new \Google_Service_Compute_MetadataItems(); $item->setKey("sshKeys"); $item->setValue("scalr:{$publicKey}"); $items[] = $item; } //Set hostname if ($hostname != '') { $item = new \Google_Service_Compute_MetadataItems(); $item->setKey("hostname"); $item->setValue($hostname); $items[] = $item; } $metadata->setItems($items); $instance->setMetadata($metadata); try { $result = $gce->instances->insert($projectId, $availZone, $instance); } catch (Exception $e) { $json = json_decode($e->getMessage()); if (!empty($json->error->message)) { $message = $json->error->message; } else { $message = $e->getMessage(); } throw new Exception(sprintf(_("Cannot launch new instance. %s (%s, %s)"), $message, $image, $launchOptions->serverType)); } if ($result->id) { $instanceTypeInfo = $this->getInstanceType($launchOptions->serverType, $environment, $availZone); /* @var $instanceTypeInfo CloudInstanceType */ $DBServer->SetProperties([\GCE_SERVER_PROPERTIES::PROVISIONING_OP_ID => $result->name, \GCE_SERVER_PROPERTIES::SERVER_NAME => $DBServer->serverId, \GCE_SERVER_PROPERTIES::CLOUD_LOCATION => $availZone, \GCE_SERVER_PROPERTIES::CLOUD_LOCATION_ZONE => $availZone, \SERVER_PROPERTIES::ARCHITECTURE => $launchOptions->architecture, 'debug.region' => $result->region, 'debug.zone' => $result->zone, \SERVER_PROPERTIES::INFO_INSTANCE_VCPUS => $instanceTypeInfo ? $instanceTypeInfo->vcpus : null]); $DBServer->setOsType($osType); $DBServer->cloudLocation = $availZone; $DBServer->cloudLocationZone = $availZone; $DBServer->imageId = $launchOptions->imageId; $DBServer->update(['type' => $launchOptions->serverType, 'instanceTypeName' => $launchOptions->serverType]); // we set server history here $DBServer->getServerHistory()->update(['cloudServerId' => $DBServer->serverId]); return $DBServer; } else { throw new Exception(sprintf(_("Cannot launch new instance. %s (%s, %s)"), serialize($result), $launchOptions->imageId, $launchOptions->serverType)); } }
public function createAction() { $governance = new Scalr_Governance($this->getEnvironmentId()); $this->response->page('ui/tools/aws/ec2/elb/create.js', array('vpcLimits' => $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, null), 'zones' => self::loadController('Ec2', 'Scalr_UI_Controller_Platforms')->getAvailZones($this->getParam('cloudLocation'))), array('ux-boxselect.js')); }
public function xLeaseExtendAction() { $this->request->restrictAccess(Acl::RESOURCE_FARMS); if (!$this->getParam('farmId')) { throw new Exception(_('Server not found')); } $dbFarm = DBFarm::LoadByID($this->getParam('farmId')); $this->user->getPermissions()->validate($dbFarm); $governance = new Scalr_Governance($this->getEnvironmentId()); if (!($governance->isEnabled(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_LEASE) && $dbFarm->GetSetting(DBFarm::SETTING_LEASE_STATUS) && $dbFarm->Status == FARM_STATUS::RUNNING)) { throw new Scalr_Exception_Core('You can\'t manage lease for this farm'); } $config = $governance->getValue(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_LEASE, null); $terminateDate = new DateTime($dbFarm->GetSetting(DBFarm::SETTING_LEASE_TERMINATE_DATE)); if ($config['leaseExtension'] != 'allow') { throw new Scalr_Exception_Core('You can\'t extend lease for this farm'); } if ($this->getParam('extend') == 'standard') { $standardExtend = $terminateDate->diff(new DateTime())->days < $config['defaultLifePeriod'] && $dbFarm->GetSetting(DBFarm::SETTING_LEASE_EXTEND_CNT) < $config['leaseExtensionStandardNumber']; if ($standardExtend) { $terminateDate->add(new DateInterval('P' . intval($config['defaultLifePeriod']) . 'D')); $dbFarm->SetSetting(DBFarm::SETTING_LEASE_EXTEND_CNT, $dbFarm->GetSetting(DBFarm::SETTING_LEASE_EXTEND_CNT) + 1); $dbFarm->SetSetting(DBFarm::SETTING_LEASE_TERMINATE_DATE, $terminateDate->format('Y-m-d H:i:s')); $dbFarm->SetSetting(DBFarm::SETTING_LEASE_NOTIFICATION_SEND, null); $this->response->success('Farm expiration date was changed'); } else { $this->response->failure('Limit of changes was reached'); } } else { if ($this->getParam('extend') == 'non-standard') { $lease = new FarmLease($dbFarm); $comment = $this->getParam('comment'); $last = $lease->getLastRequest(); if ($last && $last['status'] == FarmLease::STATUS_PENDING) { $this->response->failure('You\'ve already made expiration request. Before make another one, wait for answer.'); } else { if ($this->getParam('by') == 'days' && intval($this->getParam('byDays')) > 0) { $lease->addRequest(intval($this->getParam('byDays')), $comment, $this->user->getId()); } else { if ($this->getParam('by') == 'date' && strtotime($this->getParam('byDate'))) { $dt = new DateTime($this->getParam('byDate')); $lease->addRequest($terminateDate->diff($dt)->days, $comment, $this->user->getId()); } else { if ($this->getParam('by') == 'forever') { $lease->addRequest(0, $comment, $this->user->getId()); } else { throw new Scalr_Exception_Core('Invalid period format'); } } } $mailer = Scalr::getContainer()->mailer; if ($this->getContainer()->config('scalr.auth_mode') == 'ldap') { $owner = $this->user->getAccount()->getOwner(); if ($owner->getSetting(Scalr_Account_User::SETTING_LDAP_EMAIL)) { $mailer->addTo($owner->getSetting(Scalr_Account_User::SETTING_LDAP_EMAIL)); } else { $mailer->addTo($owner->getEmail()); } } else { $mailer->addTo($this->user->getAccount()->getOwner()->getEmail()); } if ($config['leaseExtensionNonStandardNotifyEmails']) { $emails = explode(',', $config['leaseExtensionNonStandardNotifyEmails']); foreach ($emails as $email) { $email = trim($email); if (filter_var($email, FILTER_VALIDATE_EMAIL)) { $mailer->addTo($email); } } } $mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/farm_lease_non_standard_request.eml', array('{{farm_name}}' => $dbFarm->Name, '{{user_name}}' => $this->user->getEmail(), '{{comment}}' => $comment, '{{envName}}' => $dbFarm->GetEnvironmentObject()->name, '{{envId}}' => $dbFarm->GetEnvironmentObject()->id)); $this->response->success('Farm expiration request was sent'); } } else { if ($this->getParam('extend') == 'cancel') { $lease = new FarmLease($dbFarm); if ($lease->cancelLastRequest()) { $this->response->success('Non-standard extend was cancelled'); } else { $this->response->failure('Last request wasn\'t found'); } } else { $this->response->failure('Invalid extend type'); } } } }
public function createAction($cloudLocation) { $this->request->restrictAccess(Acl::RESOURCE_AWS_ELB, Acl::PERM_AWS_ELB_MANAGE); $governance = new Scalr_Governance($this->getEnvironmentId()); $this->response->page('ui/tools/aws/ec2/elb/create.js', array('vpcLimits' => $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, null), 'zones' => self::loadController('Ec2', 'Scalr_UI_Controller_Platforms')->getAvailZones($cloudLocation))); }
/** * Return list of tags that should be applied on EC2 resources * @param string $addNameTag * @return array */ public function getAwsTags($addNameTag = false) { $tags = []; $governance = new \Scalr_Governance($this->envId); if ($addNameTag) { $nameFormat = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_INSTANCE_NAME_FORMAT); if (!$nameFormat) { $nameFormat = $this->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::AWS_INSTANCE_NAME_FORMAT); if (!$nameFormat) { $nameFormat = "{SCALR_FARM_NAME} -> {SCALR_FARM_ROLE_ALIAS} #{SCALR_INSTANCE_INDEX}"; } } $instanceName = $this->applyGlobalVarsToValue($nameFormat); $tags['Name'] = $instanceName; } $tags[\Scalr_Governance::SCALR_META_TAG_NAME] = $this->applyGlobalVarsToValue(\Scalr_Governance::SCALR_META_TAG_VALUE); $gTags = (array) $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_TAGS); $gAllowAdditionalTags = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_TAGS, 'allow_additional_tags'); if (count($gTags) > 0) { foreach ($gTags as $tKey => $tValue) { if ($tKey && count($tags) < 10 && !isset($tags[$tKey])) { $tags[$tKey] = $this->applyGlobalVarsToValue($tValue); } } } if (count($gTags) == 0 || $gAllowAdditionalTags) { //Custom tags $cTags = $this->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::AWS_TAGS_LIST); $tagsList = @explode("\n", $cTags); foreach ((array) $tagsList as $tag) { $tag = trim($tag); if ($tag && count($tags) < 10) { $tagChunks = explode("=", $tag); if (!isset($tags[trim($tagChunks[0])])) { $tags[trim($tagChunks[0])] = $this->applyGlobalVarsToValue(trim($tagChunks[1])); } } } } return $tags; }
/** * @param string $platform Name of platform * @param string $cloudLocation Name of location * @param array $ids The list of the identifiers of the cloud instances * @param int $roleId optional Identifier of Role * @return array * @throws Exception */ public function checkStatus($platform, $cloudLocation, $ids, $roleId = null) { if (!in_array($platform, $this->allowedPlatforms)) { throw new Exception(sprintf("Platform '%s' is not supported", $platform)); } if (!$this->environment->isPlatformEnabled($platform)) { throw new Exception(sprintf("Platform '%s' is not enabled", $platform)); } if (empty($ids) || empty($ids[0])) { throw new Exception("You should provide at least one instanceId"); } $instances = PlatformFactory::NewPlatform($platform)->getOrphanedServers($this->getEnvironmentEntity(), $cloudLocation, $ids); $status = ['instances' => $instances]; $imageIds = array_unique(array_map(function ($item) { return $item->imageId; }, $instances)); if (count($imageIds) != 1) { $status['compatibility'] = ['success' => false]; return $status; } /* @var $instance OrphanedServer */ $instance = $instances[0]; $status['compatibility'] = ['success' => true]; // Check vpc compatibility if ($instance->vpcId && $instance->subnetId) { $gov = new Scalr_Governance($this->getEnvironmentId()); $vpcGovernanceRegions = $gov->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, 'regions'); if (isset($vpcGovernanceRegions)) { if (!array_key_exists($cloudLocation, $vpcGovernanceRegions)) { $status['compatibility']['success'] = false; $status['compatibility']['message'] = sprintf('Region <b>%s</b> is not allowed by the Governance.', $cloudLocation); } else { $vpcGovernanceIds = $vpcGovernanceRegions[$cloudLocation]['ids']; if (!empty($vpcGovernanceIds) && !in_array($instance->vpcId, $vpcGovernanceIds)) { $status['compatibility']['success'] = false; $status['compatibility']['message'] = sprintf('VPC <b>%s</b> is not allowed by the Governance.', $instance->vpcId); } else { $vpcGovernanceIds = $gov->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, 'ids'); /* @var $platformObject Ec2PlatformModule */ $platformObject = PlatformFactory::NewPlatform(SERVER_PLATFORMS::EC2); $subnet = $platformObject->listSubnets($this->getEnvironment(), $cloudLocation, $instance->vpcId, true, $instance->subnetId); if (isset($vpcGovernanceIds[$instance->vpcId])) { if (!empty($vpcGovernanceIds[$instance->vpcId]) && is_array($vpcGovernanceIds[$instance->vpcId]) && !in_array($instance->subnetId, $vpcGovernanceIds[$instance->vpcId])) { $status['compatibility']['success'] = false; $status['compatibility']['message'] = sprintf('Subnet <b>%s</b> is prohibited by the Governance.', $instance->subnetId); } else { if ($vpcGovernanceIds[$instance->vpcId] == "outbound-only" && $subnet['type'] != 'private') { $status['compatibility']['success'] = false; $status['compatibility']['message'] = 'Only private subnets are allowed by the Governance.'; } else { if ($vpcGovernanceIds[$instance->vpcId] == "full" && $subnet['type'] != 'public') { $status['compatibility']['success'] = false; $status['compatibility']['message'] = 'Only public subnets are allowed by the Governance.'; } } } } } } } } if (!$status['compatibility']['success']) { return $status; } $scopeCriteria = ['$or' => [['accountId' => null], ['$and' => [['accountId' => $this->getUser()->accountId], ['$or' => [['envId' => null], ['envId' => $this->getEnvironment()->id]]]]]]]; /* @var $image Entity\Image */ $image = Entity\Image::findOne([['platform' => $platform], ['cloudLocation' => $cloudLocation], ['id' => $instance->imageId], $scopeCriteria]); $status['image'] = ['success' => !!$image, 'data' => ['id' => $instance->imageId]]; if ($image) { if ($image->isScalarized) { $status['image']['success'] = false; $status['image']['isScalarized'] = true; return $status; } $status['image']['data'] = ['hash' => $image->hash, 'name' => $image->name, 'id' => $image->id, 'scope' => $image->getScope()]; $criteria = [['platform' => $platform], ['imageId' => $image->id]]; if (!($platform == SERVER_PLATFORMS::GCE || $platform == SERVER_PLATFORMS::AZURE)) { $criteria[] = ['cloudLocation' => $cloudLocation]; } $roleIds = []; foreach (Entity\RoleImage::find($criteria) as $ri) { $roleIds[] = $ri->roleId; } if (count($roleIds)) { $roles = Entity\Role::find([['id' => ['$in' => $roleIds]], ['isScalarized' => false], $scopeCriteria]); $status['role'] = ['availableRoles' => [], 'image' => Scalr_UI_Controller_Images::controller()->convertEntityToArray($image)]; $selectedRole = null; if (count($roles) == 1) { $selectedRole = $roles->current(); } else { if ($roleId && in_array($roleId, $roleIds)) { foreach ($roles as $role) { /* @var $role Entity\Role */ if ($role->id == $roleId) { $selectedRole = $role; break; } } } } foreach ($roles as $role) { /* @var $role Entity\Role */ $status['role']['availableRoles'][] = ['id' => $role->id, 'name' => $role->name, 'scope' => $role->getScope()]; } if ($selectedRole) { $status['role']['success'] = true; $status['role']['data'] = ['id' => $selectedRole->id, 'name' => $selectedRole->name, 'scope' => $selectedRole->getScope()]; $farms = []; $status['farmrole'] = ['instance' => ['instanceType' => $instance->instanceType, 'vpcId' => $instance->vpcId, 'subnetId' => $instance->subnetId, 'roleName' => $selectedRole->name]]; foreach (Entity\Farm::find([['envId' => $this->getEnvironment()->id], ['status' => FARM_STATUS::RUNNING]]) as $farm) { /* @var $farm Entity\Farm */ if ($this->request->hasPermissions($farm, Acl::PERM_FARMS_UPDATE) && $this->request->hasPermissions($farm, Acl::PERM_FARMS_SERVERS)) { // cloud specific (EC2) if ($farm->settings[Entity\FarmSetting::EC2_VPC_ID] == $instance->vpcId) { $farms[$farm->id] = ['id' => $farm->id, 'name' => $farm->name, 'farmroles' => []]; } } } foreach (Entity\FarmRole::find([['farmId' => ['$in' => array_keys($farms)]], ['roleId' => $selectedRole->id]]) as $farmRole) { /* @var $farmRole Entity\FarmRole */ if (isset($farms[$farmRole->farmId])) { if (!$instance->subnetId || $instance->subnetId && in_array($instance->subnetId, json_decode($farmRole->settings[Entity\FarmRoleSetting::AWS_VPC_SUBNET_ID]))) { $farms[$farmRole->farmId]['farmroles'][] = ['id' => $farmRole->id, 'name' => $farmRole->alias, 'tags' => $farmRole->getCloudTags(true)]; } } } $status['farmrole']['data'] = array_values($farms); $status['farmrole']['success'] = false; } else { if (count($roles) > 1) { $status['role']['success'] = false; } else { $status['role']['success'] = false; } } } else { $status['role']['success'] = false; $status['role']['image'] = Scalr_UI_Controller_Images::controller()->convertEntityToArray($image); } } return $status; }
/** * Gets AWS tags that should be applied to the resource * * @return array Returns list of the AWS tags */ public function getAwsTags() { $tags = [['key' => \Scalr_Governance::SCALR_META_TAG_NAME, 'value' => $this->applyGlobalVarsToValue(\Scalr_Governance::SCALR_META_TAG_VALUE)]]; //Tags governance $governance = new \Scalr_Governance($this->EnvID); $gTags = (array) $governance->getValue('ec2', \Scalr_Governance::AWS_TAGS); if (count($gTags) > 0) { foreach ($gTags as $tKey => $tValue) { $tags[] = ['key' => $tKey, 'value' => $this->applyGlobalVarsToValue($tValue)]; } } return $tags; }
/** * xLaunchInstanceAction * * @param string $cloudLocation * @param string $Engine * @param string $DBInstanceIdentifier * @param string $DBInstanceClass * @param string $MasterUsername * @param RawData $MasterUserPassword * @param string $DBParameterGroup * @param string $LicenseModel optional * @param string $OptionGroupName optional * @param string $AllocatedStorage optional * @param string $StorageType optional * @param int $farmId optional * @param string $DBName optional * @param int $Port optional * @param string $VpcId optional * @param JsonData $VpcSecurityGroups optional * @param JsonData $DBSecurityGroups optional * @param JsonData $SubnetIds optional * @param bool $StorageEncrypted optional * @param string $KmsKeyId optional * @param string $PreferredBackupWindow optional * @param string $CharacterSetName optional * @param bool $MultiAZ optional * @param bool $AutoMinorVersionUpgrade optional * @param string $AvailabilityZone optional * @param int $Iops optional * @param string $BackupRetentionPeriod optional * @param string $PreferredMaintenanceWindow optional * @param string $DBSubnetGroupName optional * @param string $EngineVersion optional * @param bool $PubliclyAccessible optional * @throws Exception * @throws ScalrException */ public function xLaunchInstanceAction($cloudLocation, $Engine, $DBInstanceIdentifier, $DBInstanceClass, $MasterUsername, RawData $MasterUserPassword, $DBParameterGroup, $LicenseModel = null, $OptionGroupName = null, $AllocatedStorage = null, $StorageType = null, $farmId = null, $DBName = null, $Port = null, $VpcId = null, JsonData $VpcSecurityGroups = null, JsonData $DBSecurityGroups = null, JsonData $SubnetIds = null, $StorageEncrypted = false, $KmsKeyId = null, $PreferredBackupWindow = null, $CharacterSetName = null, $MultiAZ = null, $AutoMinorVersionUpgrade = false, $AvailabilityZone = null, $Iops = null, $BackupRetentionPeriod = null, $PreferredMaintenanceWindow = null, $DBSubnetGroupName = null, $EngineVersion = null, $PubliclyAccessible = false) { $this->request->restrictAccess(Acl::RESOURCE_AWS_RDS, Acl::PERM_AWS_RDS_MANAGE); $aws = $this->getAwsClient($cloudLocation); if ($Engine == 'mysql') { $Engine = 'MySQL'; } $request = new CreateDBInstanceRequestData($DBInstanceIdentifier, $DBInstanceClass, $Engine); if ($Engine == 'aurora') { $StorageType = 'aurora'; $request->dBClusterIdentifier = strtolower($DBInstanceIdentifier); } if ($StorageEncrypted) { $request->storageEncrypted = $Engine != 'aurora' ? true : null; if ($KmsKeyId) { $kmsKey = $aws->kms->key->describe($KmsKeyId); if (!$kmsKey->enabled) { throw new Exception("This KMS Key is disabled, please choose another one."); } $allowed = true; $governance = new Scalr_Governance($this->getEnvironmentId()); $allowedKeys = $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_KMS_KEYS, $cloudLocation); if (!empty($allowedKeys)) { $allowed = false; foreach ($allowedKeys['keys'] as $key) { if ($key['id'] == $kmsKey->keyId) { $allowed = true; break; } } } if (!$allowed) { throw new ScalrException("A KMS Policy is active in this Environment, access to '{$kmsKey->keyId}' has been restricted by account owner."); } $request->kmsKeyId = $Engine != 'aurora' ? $KmsKeyId : null; } } if (empty($request->dBClusterIdentifier)) { $request->allocatedStorage = $AllocatedStorage; $request->masterUsername = $MasterUsername; $request->masterUserPassword = (string) $MasterUserPassword; $request->dBName = $DBName ?: null; $request->port = $Port ?: null; $request->preferredBackupWindow = $PreferredBackupWindow ?: null; $vpcSgIds = []; foreach ($VpcSecurityGroups as $VpcSecurityGroup) { $vpcSgIds[] = $VpcSecurityGroup['id']; } $request->vpcSecurityGroupIds = empty($vpcSgIds) ? null : $vpcSgIds; } $request->characterSetName = $CharacterSetName ?: null; if (!empty($DBParameterGroup)) { $paramGroups = $aws->rds->dbParameterGroup->describe(); foreach ($paramGroups as $param) { /* @var $param DBParameterGroupData */ if ($param->dBParameterGroupName == $DBParameterGroup) { $paramGroup = $param; break; } } } if (!empty($paramGroup)) { $request->dBParameterGroupName = $paramGroup->dBParameterGroupName; } $isMirror = $MultiAZ && in_array($Engine, [DBInstanceData::ENGINE_SQL_SERVER_SE, DBInstanceData::ENGINE_SQL_SERVER_EE]); $optionList = $aws->rds->optionGroup->describe($Engine); foreach ($optionList as $option) { /* @var $option OptionGroupData */ if ($option->optionGroupName == $OptionGroupName) { $optionGroup = $option; break; } } if (isset($optionGroup)) { $request->optionGroupName = $optionGroup->optionGroupName; } else { if ($isMirror) { $request->optionGroupName = $OptionGroupName; } } $dbSgIds = []; foreach ($DBSecurityGroups as $DBSecurityGroup) { $dbSgIds[] = $DBSecurityGroup; } $request->dBSecurityGroups = empty($dbSgIds) ? null : $dbSgIds; $request->autoMinorVersionUpgrade = $AutoMinorVersionUpgrade; $request->availabilityZone = $AvailabilityZone ?: null; $request->backupRetentionPeriod = $BackupRetentionPeriod ?: null; $request->preferredMaintenanceWindow = $PreferredMaintenanceWindow ?: null; $request->multiAZ = $isMirror ? false : $MultiAZ; $request->storageType = $StorageType; $request->dBSubnetGroupName = $DBSubnetGroupName ?: null; $request->licenseModel = $LicenseModel; $request->engineVersion = $EngineVersion ?: null; $request->iops = $Iops ?: null; if ($VpcId) { $request->publiclyAccessible = $PubliclyAccessible; } $tagsObject = $farmId ? DBFarm::LoadByID($farmId) : $this->environment; $request->tags = new TagsList($tagsObject->getAwsTags()); $result = self::loadController('Aws', 'Scalr_UI_Controller_Tools')->checkSecurityGroupsPolicy($VpcSecurityGroups, Aws::SERVICE_INTERFACE_RDS); if ($result === true) { $result = self::loadController('Aws', 'Scalr_UI_Controller_Tools')->checkVpcPolicy($VpcId, $SubnetIds, $cloudLocation); } if ($result === true) { if (!empty($request->dBClusterIdentifier)) { try { $checkInstance = $aws->rds->dbInstance->describe($request->dBInstanceIdentifier); } catch (Exception $e) { $checkInstance = []; } if (count($checkInstance) > 0) { throw new Exception(sprintf("AWS Error. DB Instance with identifier %s already exists.", $request->dBInstanceIdentifier)); } self::loadController('Clusters', 'Scalr_UI_Controller_Tools_Aws_Rds')->xSaveAction($cloudLocation, $request->dBClusterIdentifier, $Engine, $MasterUsername, $MasterUserPassword, $VpcId, $Port, $DBName, $request->characterSetName, $request->dBParameterGroupName, $request->optionGroupName, new JsonData([$request->availabilityZone]), $request->backupRetentionPeriod, $PreferredBackupWindow, $request->preferredMaintenanceWindow, $request->dBSubnetGroupName, $request->engineVersion, $farmId, $VpcSecurityGroups, $SubnetIds, $StorageEncrypted, $KmsKeyId); } $instance = $aws->rds->dbInstance->create($request); CloudResource::deletePk($request->dBInstanceIdentifier, CloudResource::TYPE_AWS_RDS, $this->getEnvironmentId(), \SERVER_PLATFORMS::EC2, $cloudLocation); if ($farmId) { $cloudResource = new CloudResource(); $cloudResource->id = $request->dBInstanceIdentifier; $cloudResource->type = CloudResource::TYPE_AWS_RDS; $cloudResource->platform = \SERVER_PLATFORMS::EC2; $cloudResource->cloudLocation = $cloudLocation; $cloudResource->envId = $this->getEnvironmentId(); $cloudResource->farmId = $farmId; $cloudResource->save(); } $vpcSglist = null; if (!empty($VpcId)) { $filter[] = ['name' => SecurityGroupFilterNameType::vpcId(), 'value' => $VpcId]; $vpcSglist = $aws->ec2->securityGroup->describe(null, null, $filter); } $clusters = null; if (!empty($instance->dBClusterIdentifier)) { /* @var $cluster DBClusterData */ $clusters = $aws->rds->dbCluster->describe($instance->dBClusterIdentifier); } $data = $this->getDbInstanceData($aws, $instance, $vpcSglist, $clusters); $data['isReplica'] = false; if ($isMirror) { $data['MultiAZ'] = true; } $this->response->success("DB Instance successfully created"); $this->response->data(['instance' => $data, 'cloudLocation' => $cloudLocation]); } else { $this->response->failure($result); } }
private function GetServerSecurityGroupsList(DBServer $DBServer, OpenStack $osClient, \Scalr_Governance $governance = null) { $retval = $sgroups = $sgroupIds = $checkGroups = []; $sgGovernance = false; $allowAdditionalSgs = true; if ($governance) { $sgs = $governance->getValue($DBServer->platform, \Scalr_Governance::OPENSTACK_SECURITY_GROUPS); if ($sgs !== null) { $governanceSecurityGroups = @explode(",", $sgs); if (!empty($governanceSecurityGroups)) { foreach ($governanceSecurityGroups as $sg) { if ($sg != '') { array_push($checkGroups, trim($sg)); } } } if (!empty($checkGroups)) { $sgGovernance = true; } $allowAdditionalSgs = $governance->getValue($DBServer->platform, \Scalr_Governance::OPENSTACK_SECURITY_GROUPS, 'allow_additional_sec_groups'); } } if (!$sgGovernance || $allowAdditionalSgs) { if ($DBServer->farmRoleId != 0) { $dbFarmRole = $DBServer->GetFarmRoleObject(); if ($dbFarmRole->GetSetting(Entity\FarmRoleSetting::OPENSTACK_SECURITY_GROUPS_LIST) !== null) { // New SG management $sgs = @json_decode($dbFarmRole->GetSetting(Entity\FarmRoleSetting::OPENSTACK_SECURITY_GROUPS_LIST)); if (!empty($sgs)) { foreach ($sgs as $sg) { array_push($checkGroups, $sg); } } } else { // Old SG management array_push($checkGroups, 'default'); array_push($checkGroups, \Scalr::config('scalr.aws.security_group_name')); } } else { array_push($checkGroups, 'scalr-rb-system'); } } try { $list = $osClient->listSecurityGroups(); do { foreach ($list as $sg) { $sgroups[strtolower($sg->name)] = $sg; $sgroupIds[strtolower($sg->id)] = $sg; } if ($list instanceof PaginationInterface) { $list = $list->getNextPage(); } else { $list = false; } } while ($list !== false); unset($list); } catch (\Exception $e) { throw new \Exception("GetServerSecurityGroupsList failed: {$e->getMessage()}"); } foreach ($checkGroups as $groupName) { if (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $groupName)) { if (isset($sgroupIds[strtolower($groupName)])) { $groupName = $sgroupIds[$groupName]->name; } else { throw new \Exception(sprintf(_("Security group '%s' is not found (1)"), $groupName)); } } elseif (preg_match('/^\\d+$/', $groupName)) { // In openstack IceHouse, SG ID is integer and not UUID if (isset($sgroupIds[strtolower($groupName)])) { $groupName = $sgroupIds[$groupName]->name; } else { throw new \Exception(sprintf(_("Security group '%s' is not found (1)"), $groupName)); } } if ($groupName == 'default') { // Check default SG array_push($retval, $groupName); } elseif ($groupName == 'scalr-rb-system' || $groupName == \Scalr::config('scalr.aws.security_group_name')) { // Check Roles builder SG if (!isset($sgroups[strtolower($groupName)])) { try { $group = $osClient->createSecurityGroup($groupName, _("Scalr system security group")); $groupId = $group->id; } catch (\Exception $e) { throw new \Exception("GetServerSecurityGroupsList failed on scalr.ip-pool: {$e->getMessage()}"); } $r = new CreateSecurityGroupRule($groupId); $r->direction = 'ingress'; $r->protocol = 'tcp'; $r->port_range_min = 1; $r->port_range_max = 65535; $r->remote_ip_prefix = "0.0.0.0/0"; $res = $osClient->createSecurityGroupRule($r); $r = new CreateSecurityGroupRule($groupId); $r->direction = 'ingress'; $r->protocol = 'udp'; $r->port_range_min = 1; $r->port_range_max = 65535; $r->remote_ip_prefix = "0.0.0.0/0"; $res = $osClient->createSecurityGroupRule($r); } array_push($retval, $groupName); } else { if (!isset($sgroups[strtolower($groupName)])) { throw new \Exception(sprintf(_("Security group '%s' is not found (2)"), $groupName)); } else { array_push($retval, $groupName); } } } return $retval; }
/** * Checks vpc governance policy * * @param string $vpcId * @param Scalr\UI\Request\JsonData $subnetIds * @param string $cloudLocation * @return bool|string Returns error message if access to some data restricted. True otherwise. * @throws Scalr_Exception_Core */ public function checkVpcPolicy($vpcId, $subnetIds, $cloudLocation) { $governance = new Scalr_Governance($this->getEnvironmentId()); $value = $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, ''); if (!empty($value)) { if (!empty($value['value']) && empty($vpcId)) { return "A Vpc Policy is active in this Environment, all resources should be launched in a VPC."; } if (!empty($vpcId)) { if (!empty($cloudLocation) && !array_key_exists($cloudLocation, (array) $value['regions'])) { return sprintf("A Vpc Policy is active in this Environment, access to %s region has been restricted by account owner.", $cloudLocation); } foreach ($value['regions'] as $region => $policy) { if (!empty($policy['ids']) && !empty($cloudLocation) && $cloudLocation == $region && !in_array($vpcId, (array) $policy['ids'])) { return sprintf("A Vpc Policy is active in this Environment, access to vpc %s has been restricted by account owner.", $vpcId); } } foreach ($value['ids'] as $vpc => $restrictions) { $subnetIds = (array) $subnetIds; $missingSubnets = array_diff($subnetIds, $restrictions); $s = count($missingSubnets) > 1 ? 's' : ''; if (!empty($restrictions) && is_array($restrictions) && $vpc == $vpcId && !empty($missingSubnets)) { return sprintf("A Vpc Policy is active in this Environment, access to subnet%s %s has been restricted by account owner.", $s, implode(', ', $missingSubnets)); } } } } return true; }