/** * Fill information about Farm/FarmRole for each object based on cloudServerId. * cloudServerId could be empty or didn't exist in our database. * * @param array[] $data Array of arrays */ private function applyFarmRoleInfo(&$data) { $cloudServerIds = []; foreach ($data as $row) { if ($row['cloudServerId']) { $cloudServerIds[] = $row['cloudServerId']; } } if (empty($cloudServerIds)) { return; } $server = new Entity\Server(); $history = new Entity\Server\History(); $farm = new Entity\Farm(); $farmRole = new Entity\FarmRole(); $cloudServerIds = join(",", array_map(function ($serverId) { return $this->db->qstr($serverId); }, $cloudServerIds)); $sql = "\n SELECT {$farm->columnId} AS farmId, {$farm->columnName} AS farmName, {$farmRole->columnId} AS farmRoleId,\n {$farmRole->columnAlias} AS farmRoleName, {$server->columnServerId} AS serverId, {$server->columnIndex} AS serverIndex,\n {$history->columnCloudServerId} AS cloudServerId FROM {$server->table()}\n JOIN {$history->table()} ON {$server->columnServerId} = {$history->columnServerId}\n JOIN {$farm->table()} ON {$server->columnFarmId} = {$farm->columnId}\n JOIN {$farmRole->table()} ON {$server->columnFarmRoleId} = {$farmRole->columnId}\n WHERE {$server->columnEnvId} = ? AND {$history->columnCloudServerId} IN ({$cloudServerIds})\n "; $result = []; foreach ($this->db->Execute($sql, [$this->getEnvironmentId()]) as $row) { $result[$row['cloudServerId']] = $row; } foreach ($data as &$row) { if (!empty($row['cloudServerId']) && !empty($result[$row['cloudServerId']])) { $row = array_merge($row, $result[$row['cloudServerId']]); } } }
public static function targetToData(OrchestrationRule $entity, $object) { /* @var $entity FarmRoleScript */ parent::targetToData($entity, $object); if ($entity->target == static::TARGET_VALUE_SPECIFIED_FARM_ROLE) { /* @var $entity FarmRoleScript */ $farmRole = new FarmRole(); $targets = new FarmRoleScriptingTarget(); /* @var $target FarmRole */ foreach (FarmRole::find([['farmId' => $entity->farmId], AbstractEntity::STMT_FROM => "{$farmRole->table()} JOIN {$targets->table('t')} ON {$targets->columnTarget('t')} = {$farmRole->columnAlias()}", AbstractEntity::STMT_WHERE => "{$targets->columnFarmRoleScriptId('t')} = {$targets->qstr('farmRoleScriptId', $entity->id)} AND {$targets->columnTargetType('t')} = {$targets->qstr('targetType', OrchestrationRule::TARGET_ROLES)}"]) as $target) { $object->target->roles[] = ['id' => $target->id]; } } }
public static function setUpBeforeClass() { parent::setUpBeforeClass(); if (self::isSkippedFunctionalTest(self::TEST_TYPE_UI)) { return; } $db = \Scalr::getDb(); self::deleteTestVariables(); $envId = \Scalr::config('scalr.phpunit.envid'); if (!$envId) { return; } $env = \Scalr_Environment::init()->loadById($envId); self::$vars[ScopeInterface::SCOPE_SCALR] = new Scalr_Scripting_GlobalVariables(); self::$vars[ScopeInterface::SCOPE_ACCOUNT] = new Scalr_Scripting_GlobalVariables($env->clientId, 0, ScopeInterface::SCOPE_ACCOUNT); self::$vars[ScopeInterface::SCOPE_ENVIRONMENT] = new Scalr_Scripting_GlobalVariables($env->clientId, $env->id, ScopeInterface::SCOPE_ENVIRONMENT); self::$args[ScopeInterface::SCOPE_SCALR] = self::$args[ScopeInterface::SCOPE_ACCOUNT] = self::$args[ScopeInterface::SCOPE_ENVIRONMENT] = [0, 0, 0, '']; /* @var $farm Farm */ $farm = Farm::findOne([['envId' => $env->id]]); if ($farm) { self::$vars[ScopeInterface::SCOPE_FARM] = new Scalr_Scripting_GlobalVariables($env->clientId, $env->id, ScopeInterface::SCOPE_FARM); self::$args[ScopeInterface::SCOPE_FARM] = [0, $farm->id, 0, '']; /* @var $farmRole FarmRole */ $farmRole = FarmRole::findOne([['farmId' => $farm->id]]); if ($farmRole) { self::$vars[ScopeInterface::SCOPE_ROLE] = new Scalr_Scripting_GlobalVariables($env->clientId, $env->id, ScopeInterface::SCOPE_ROLE); self::$args[ScopeInterface::SCOPE_ROLE] = [$farmRole->roleId, 0, 0, '']; self::$vars[ScopeInterface::SCOPE_FARMROLE] = new Scalr_Scripting_GlobalVariables($env->clientId, $env->id, ScopeInterface::SCOPE_FARMROLE); self::$args[ScopeInterface::SCOPE_FARMROLE] = [$farmRole->roleId, $farm->id, $farmRole->id, '']; } } }
public function _vpc($from, $to, $action) { switch ($action) { case static::ACT_CONVERT_TO_OBJECT: /* @var $from Farm */ $vpc = []; if (!empty($from->settings[FarmSetting::EC2_VPC_ID])) { $vpc['id'] = $from->settings[FarmSetting::EC2_VPC_ID]; } if (!empty($from->settings[FarmSetting::EC2_VPC_REGION])) { $vpc['region'] = $from->settings[FarmSetting::EC2_VPC_REGION]; } if (!empty($vpc)) { $to->vpc = (object) $vpc; } break; case static::ACT_CONVERT_TO_ENTITY: /* @var $to Farm */ $vpcId = ApiController::getBareId($from, 'vpc'); if (!is_string($vpcId)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed vpc.id property"); } if ($to->status || FarmRole::find([['farmId' => $to->id], ['platform' => \SERVER_PLATFORMS::EC2]], null, null, null, null, true)->totalNumber) { throw new ApiErrorException(400, ErrorMessage::ERR_OBJECT_IN_USE, "To change VPC settings you must first stop farm and remove all EC2 farm-roles"); } $to->settings[FarmSetting::EC2_VPC_ID] = $vpcId; if (!empty($from->vpc->region)) { $to->settings[FarmSetting::EC2_VPC_REGION] = $from->vpc->region; } break; case static::ACT_GET_FILTER_CRITERIA: $farm = new Farm(); $farmSetting = new FarmSetting(); $vpcId = ApiController::getBareId($from, 'vpc'); return [AbstractEntity::STMT_FROM => $farm->table() . " LEFT JOIN " . $farmSetting->table() . " ON {$farmSetting->columnFarmId} = {$farm->columnId}", AbstractEntity::STMT_WHERE => "({$farmSetting->columnName} = '" . FarmSetting::EC2_VPC_ID . "' AND {$farmSetting->columnValue} = " . $farmSetting->qstr('value', $vpcId) . ")"]; } }
/** * Gets specified Farm Role taking into account both scope and authentication token * * @param string $farmRoleId Numeric identifier of the Farm role * @param int $farmId optional Identifier of the Farm containing Farm role * @param bool $modify optional Flag checking write permissions * * @return FarmRole Returns the Script Entity on success * @throws ApiErrorException */ public function getFarmRole($farmRoleId, $farmId = null, $modify = false) { /* @var $role FarmRole */ $role = FarmRole::findPk($farmRoleId); if (!$role) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Requested Farm Role either does not exist or is not owned by your environment."); } if (isset($farmId)) { if ($role->farmId != $farmId) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid identifier of the farm"); } } else { $farmId = $role->farmId; } $this->getFarm($farmId, $modify); if (!$this->hasPermissions($role, $modify)) { //Checks entity level write access permissions throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions"); } return $role; }
/** * Get FarmRole entity * * @return FarmRole|null */ public function getFarmRole() { if (empty($this->_farmRole) && !empty($this->farmRoleId)) { $this->_farmRole = FarmRole::findPk($this->farmRoleId); } return $this->_farmRole; }
/** * @param string $platform Name of platform * @param string $instanceId The identifier of the cloud instance * @param int $farmRoleId The identifier of farmRole * @param JsonData $tags Additional tags * @throws Exception */ public function xImportAction($platform, $instanceId, $farmRoleId, JsonData $tags) { 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($instanceId)) { throw new Exception('InstanceId cannot be empty'); } /* @var $farmRole Entity\FarmRole */ if (!$farmRoleId || !($farmRole = Entity\FarmRole::findPk($farmRoleId))) { throw new Exception('FarmRole was not found'); } $this->request->checkPermissions($farmRole, true); $this->request->checkPermissions($farmRole->getFarm(), Acl::PERM_FARMS_UPDATE); $this->request->checkPermissions($farmRole->getFarm(), Acl::PERM_FARMS_SERVERS); $farmRole->settings[Entity\FarmRoleSetting::SCALING_ENABLED] = 0; $farmRole->settings->save(); $farmRole->getServerImport($this->getUser())->import($instanceId, (array) $tags); $this->response->success(); }
/** * Setups given scaling configuration to specified farm role * * @param FarmRole $farmRole Configurable farm role * @param object $scaling Scaling configuration * * @throws ApiErrorException */ public static function setupScalingConfiguration(FarmRole $farmRole, $scaling) { $disabledScalingBehaviors = array_intersect(static::$disableScalingBehaviors, $farmRole->getRole()->getBehaviors()); if (!empty($disabledScalingBehaviors)) { throw new ApiErrorException(409, ErrorMessage::ERR_CONFIGURATION_MISMATCH, sprintf('Can not add scaling configuration to the Role with the following built-in automation types: %s.', implode(', ', RoleAdapter::behaviorsToData($disabledScalingBehaviors)))); } if (isset($scaling->enabled)) { $farmRole->settings[FarmRoleSetting::SCALING_ENABLED] = intval($scaling->enabled); } if (isset($scaling->minInstances)) { if ($scaling->minInstances < 0) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Property scaling.minInstances must be greater than or equal to 0"); } $farmRole->settings[FarmRoleSetting::SCALING_MIN_INSTANCES] = intval($scaling->minInstances); } if (isset($scaling->maxInstances)) { if ($scaling->maxInstances > 400) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Property scaling.maxInstances must be less than or equal to 400"); } $farmRole->settings[FarmRoleSetting::SCALING_MAX_INSTANCES] = intval($scaling->maxInstances); } if ($farmRole->settings[FarmRoleSetting::SCALING_MAX_INSTANCES] < $farmRole->settings[FarmRoleSetting::SCALING_MIN_INSTANCES]) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Property scaling.maxInstances must be greater than or equal to scaling.minInstances"); } }
/** * Returns prepared orchestration log data for response * * @param EntityIterator $logs List of Orchestration Log objects * @return array */ private function prepareOrchestrationLogData($logs) { $farmIds = []; $serverIds = []; $taskIds = []; $eventIds = []; $ids = []; foreach ($logs as $row) { /* @var $row OrchestrationLog */ $farmIds[] = $row->farmId; $serverIds[] = $row->serverId; if ($row->eventServerId) { $serverIds[] = $row->eventServerId; } if ($row->taskId) { $taskIds[] = $row->taskId; } if ($row->eventId) { $eventIds[] = $row->eventId; } if ($row->type == OrchestrationLog::TYPE_MANUAL) { $ids[] = $row->id; } } if (!empty($farmIds)) { $farms = Farm::find([['id' => ['$in' => array_unique($farmIds)]]]); foreach ($farms as $farm) { /* @var $farm Farm */ $farmData[$farm->id] = $farm->name; } } if (!empty($serverIds)) { $servers = Server::find([['serverId' => ['$in' => array_unique($serverIds)]]]); $farmRoleIds = []; $serverFarmIds = []; foreach ($servers as $server) { /* @var $server Server */ $serverData[$server->serverId]['serverIndex'] = $server->index; $farmRoleIds[$server->serverId] = $server->farmRoleId; $serverFarmIds[$server->serverId] = $server->farmId; } $farms = Farm::find([['id' => ['$in' => array_unique(array_values($serverFarmIds))]]]); foreach ($farms as $farm) { /* @var $farm Farm */ foreach ($serverFarmIds as $serverId => $farmId) { if ($farmId == $farm->id) { $serverData[$serverId]['farmName'] = $farm->name; $serverData[$serverId]['farmId'] = $farm->id; } } } $farmRoles = FarmRole::find([['id' => ['$in' => array_unique(array_values($farmRoleIds))]]]); foreach ($farmRoles as $farmRole) { /* @var $farmRole FarmRole */ foreach ($farmRoleIds as $serverId => $farmRoleId) { if ($farmRoleId == $farmRole->id) { $serverData[$serverId]['alias'] = $farmRole->alias; $serverData[$serverId]['farmRoleId'] = $farmRole->id; } } } } if (!empty($taskIds)) { $tasks = SchedulerTask::find([['id' => ['$in' => array_unique($taskIds)]]]); foreach ($tasks as $task) { /* @var $task SchedulerTask */ $taskData[$task->id] = $task->name; } } if (!empty($eventIds)) { $events = Event::find([['eventId' => ['$in' => array_unique($eventIds)]]]); foreach ($events as $event) { /* @var $event Event */ $eventData[$event->eventId] = $event->type; } } if (!empty($ids)) { $manualLogs = OrchestrationLogManualScript::find([['orchestrationLogId' => ['$in' => array_unique($ids)]]]); foreach ($manualLogs as $manualLog) { /* @var $manualLog OrchestrationLogManualScript */ $scriptData[$manualLog->orchestrationLogId] = $manualLog->userEmail; } } $data = []; foreach ($logs as $row) { /* @var $row OrchestrationLog */ $dataRow = get_object_vars($row); $dataRow['targetFarmName'] = isset($farmData[$row->farmId]) ? $farmData[$row->farmId] : null; $dataRow['targetFarmId'] = $row->farmId; $dataRow['targetServerId'] = $row->serverId; $dataRow['targetServerIndex'] = isset($serverData[$row->serverId]['serverIndex']) ? $serverData[$row->serverId]['serverIndex'] : null; $dataRow['targetFarmRoleId'] = isset($serverData[$row->serverId]['farmRoleId']) ? $serverData[$row->serverId]['farmRoleId'] : null; $dataRow['targetRoleName'] = isset($serverData[$row->serverId]['alias']) ? $serverData[$row->serverId]['alias'] : null; $dataRow['added'] = Scalr_Util_DateTime::convertTz($row->added); if (\Scalr::config('scalr.system.scripting.logs_storage') == 'scalr') { $dataRow['executionId'] = null; } if ($dataRow['message']) { $dataRow['message'] = nl2br(htmlspecialchars($dataRow['message'])); } if ($row->eventServerId) { $dataRow['eventFarmName'] = isset($serverData[$row->eventServerId]['farmName']) ? $serverData[$row->eventServerId]['farmName'] : null; $dataRow['eventFarmId'] = isset($serverData[$row->eventServerId]['farmId']) ? $serverData[$row->eventServerId]['farmId'] : null; $dataRow['eventFarmRoleId'] = isset($serverData[$row->eventServerId]['farmRoleId']) ? $serverData[$row->eventServerId]['farmRoleId'] : null; $dataRow['eventRoleName'] = isset($serverData[$row->eventServerId]['alias']) ? $serverData[$row->eventServerId]['alias'] : null; $dataRow['eventServerIndex'] = isset($serverData[$row->eventServerId]['serverIndex']) ? $serverData[$row->eventServerId]['serverIndex'] : null; } $dataRow['event'] = null; if ($row->taskId) { $dataRow['event'] = isset($taskData[$row->taskId]) ? $taskData[$row->taskId] : null; } if ($row->eventId) { $dataRow['event'] = isset($eventData[$row->eventId]) ? $eventData[$row->eventId] : null; } if ($row->type == OrchestrationLog::TYPE_MANUAL) { $dataRow['event'] = isset($scriptData[$row->id]) ? $scriptData[$row->id] : null; } $data[] = $dataRow; } return $data; }
/** * Get information about role * * @param int $roleId Identifier of role * @param bool $extended Get extended information about role * @param array $canAddImage Array of platform, cloudLocation to check if role has image in that location * @return array * @throws Exception * @throws Scalr_Exception_Core * @throws Scalr_Exception_InsufficientPermissions */ private function getInfo($roleId, $extended = false, $canAddImage = null) { /* @var $role Role */ $role = Role::findPk($roleId); if (!$role) { throw new Scalr_Exception_Core(sprintf(_("Role ID#%s not found in database"), $roleId)); } $this->request->checkPermissions($role); $usedBy = $role->getFarmsCount($this->user->getAccountId(), $this->getEnvironmentId(true)); $platforms = array_keys($role->fetchImagesArray()); $allPlatforms = array_flip(array_keys(SERVER_PLATFORMS::GetList())); usort($platforms, function ($a, $b) use($allPlatforms) { return $allPlatforms[$a] > $allPlatforms[$b] ? 1 : -1; }); $result = array('name' => $role->name, 'behaviors' => $role->getBehaviors(), 'id' => $role->id, 'accountId' => $role->accountId, 'envId' => $role->envId, 'catId' => $role->catId, 'status' => $usedBy > 0 ? 'In use' : 'Not used', 'scope' => $role->getScope(), 'os' => $role->getOs()->name, 'osId' => $role->osId, 'osFamily' => $role->getOs()->family, 'dtAdded' => $role->added ? Scalr_Util_DateTime::convertTz($role->added) : NULL, 'dtLastUsed' => $role->lastUsed ? Scalr_Util_DateTime::convertTz($role->lastUsed) : NULL, 'isQuickStart' => $role->isQuickStart, 'isDeprecated' => $role->isDeprecated, 'isScalarized' => $role->isScalarized, 'platforms' => $platforms, 'environments' => !empty($envs = $role->getAllowedEnvironments()) ? $this->db->GetCol("SELECT name FROM client_environments WHERE id IN(" . join(',', $envs) . ")") : []); if ($canAddImage) { try { $role->getImage($canAddImage['platform'], $canAddImage['cloudLocation']); $result['canAddImage'] = false; } catch (Exception $e) { $result['canAddImage'] = true; } } if ($extended) { $result['description'] = $role->description; $result['images'] = []; foreach (RoleImage::find([['roleId' => $role->id]]) as $image) { /* @var $image RoleImage */ $im = $image->getImage(); $ext = []; if ($im) { $ext = get_object_vars($im); $ext['software'] = $im->getSoftwareAsString(); } $result['images'][] = ['imageId' => $image->imageId, 'platform' => $image->platform, 'cloudLocation' => $image->cloudLocation, 'extended' => $ext]; } if ($result['status'] == 'In use' && $this->getEnvironmentId(true)) { $farms = []; $f = []; foreach (FarmRole::find([['roleId' => $role->id]]) as $farmRole) { /* @var $farmRole FarmRole */ $f[] = $farmRole->farmId; } $f = array_unique($f); if (count($f)) { foreach (Farm::find([['id' => ['$in' => $f]], ['envId' => $this->getEnvironmentId()]]) as $fm) { /* @var $fm Farm */ $farms[] = ['id' => $fm->id, 'name' => $fm->name]; } } $result['usedBy'] = ['farms' => $farms, 'cnt' => count($farms)]; } } return $result; }
public function FarmRemoveRole($FarmID, $FarmRoleID) { try { $DBFarm = DBFarm::LoadByID($FarmID); if ($DBFarm->EnvID != $this->Environment->id) { throw new Exception("N"); } } catch (Exception $e) { throw new Exception(sprintf("Farm #%s not found", $FarmID)); } $this->user->getPermissions()->validate($DBFarm); $this->restrictFarmAccess($DBFarm, Acl::PERM_FARMS_UPDATE); $DBFarm->isLocked(true); try { $DBFarmRole = DBFarmRole::LoadByID($FarmRoleID); if ($DBFarm->ID != $DBFarmRole->FarmID) { throw new Exception("N"); } } catch (Exception $e) { throw new Exception(sprintf("FarmRole ID #%s not found", $FarmRoleID)); } $this->user->getPermissions()->validate($DBFarm); $farmRole = new Entity\FarmRole(); $farmRole->id = $FarmRoleID; $farmRole->delete(); $response = $this->CreateInitialResponse(); $response->Result = true; return $response; }
/** * {@inheritdoc} * @see ApiEntityAdapter::validateEntity() */ public function validateEntity($entity) { if (!$entity instanceof FarmRole) { throw new InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\FarmRole class")); } if ($entity->id !== null) { if (!FarmRole::findPk($entity->id)) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the Farm with ID: %d", $entity->id)); } } if (empty($entity->farmId)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property farm.id"); } else { $farm = $this->controller->getFarm($entity->farmId, true); } if (empty($entity->roleId)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property role.id"); } if (empty($entity->platform)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property platform"); } switch ($entity->platform) { case SERVER_PLATFORMS::EC2: if (empty($entity->settings[FarmRoleSetting::AWS_INSTANCE_TYPE])) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Missed property instance.type"); } /* @var $platform Ec2PlatformModule */ $platform = PlatformFactory::NewPlatform(SERVER_PLATFORMS::EC2); if (!in_array($entity->settings[FarmRoleSetting::AWS_INSTANCE_TYPE], $platform->getInstanceTypes())) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Wrong instance type"); } $gov = new Scalr_Governance($this->controller->getEnvironment()->id); $allowGovernanceIns = $gov->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_INSTANCE_TYPE); if (isset($allowGovernanceIns) && !in_array($entity->settings[FarmRoleSetting::AWS_INSTANCE_TYPE], $allowGovernanceIns)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, sprintf("Only %s %s allowed according to governance settings", ...count($allowGovernanceIns) > 1 ? [implode(', ', $allowGovernanceIns), 'instances are'] : [array_shift($allowGovernanceIns), 'instance is'])); } if (!in_array($entity->cloudLocation, Aws::getCloudLocations())) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Unknown region"); } $vpcGovernanceRegions = $gov->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, 'regions'); if (isset($vpcGovernanceRegions) && !array_key_exists($entity->cloudLocation, $vpcGovernanceRegions)) { $regions = array_keys($vpcGovernanceRegions); throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, sprintf("Only %s %s allowed according to governance settings", ...count($regions) > 1 ? [implode(', ', $regions), 'regions are'] : [array_shift($regions), 'region is'])); } $env = Scalr_Environment::init()->loadById($this->controller->getEnvironment()->id); $aws = $this->controller->getContainer()->aws($entity->cloudLocation, $env); if (!empty($entity->settings[FarmRoleSetting::AWS_AVAIL_ZONE]) && $entity->settings[FarmRoleSetting::AWS_AVAIL_ZONE] !== 'x-scalr-diff') { $availZones = explode(":", str_replace("x-scalr-custom=", '', $entity->settings[FarmRoleSetting::AWS_AVAIL_ZONE])); $ec2availabilityZones = []; foreach ($aws->ec2->availabilityZone->describe() as $zone) { /* @var $zone AvailabilityZoneData */ if (stristr($zone->zoneState, 'available')) { $ec2availabilityZones[] = $zone->zoneName; } } $diffZones = array_diff($availZones, $ec2availabilityZones); if (!empty($diffZones)) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf('%s %s available. Available zones are %s', ...count($diffZones) > 1 ? [implode(', ', $diffZones), 'zones are not', implode(', ', $ec2availabilityZones)] : [array_shift($diffZones), 'zone is not', implode(', ', $ec2availabilityZones)])); } } if (!empty($entity->settings[FarmRoleSetting::AWS_VPC_SUBNET_ID])) { $vpcId = $farm->settings[FarmSetting::EC2_VPC_ID]; $subnets = $platform->listSubnets($env, $entity->cloudLocation, $vpcId, true); $vpcGovernanceIds = $gov->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, 'ids'); $subnetType = null; foreach (json_decode($entity->settings[FarmRoleSetting::AWS_VPC_SUBNET_ID]) as $subnetId) { $found = false; foreach ($subnets as $subnet) { if ($subnet['id'] == $subnetId) { if ($subnetType == null) { $subnetType = $subnet['type']; } else { if ($subnet['type'] != $subnetType) { throw new ApiErrorException(409, ErrorMessage::ERR_UNICITY_VIOLATION, "All subnets must be a same type"); } } //check governance subnet settings if (isset($vpcGovernanceIds[$vpcId])) { if (!empty($vpcGovernanceIds[$vpcId]) && is_array($vpcGovernanceIds[$vpcId]) && !in_array($subnetId, $vpcGovernanceIds[$vpcId])) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, sprintf("Only %s %s allowed by governance settings", ...count($vpcGovernanceIds[$vpcId]) > 1 ? [implode(', ', $vpcGovernanceIds[$vpcId]), 'subnets are'] : [array_shift($vpcGovernanceIds[$vpcId]), 'subnet is'])); } elseif ($vpcGovernanceIds[$vpcId] == "outbound-only" && $subnetType != 'private') { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Only private subnets allowed by governance settings"); } elseif ($vpcGovernanceIds[$vpcId] == "full" && $subnetType != 'public') { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Only public subnets allowed by governance settings"); } } $found = true; } } if (!$found) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Subnet with id '{$subnetId}' not found"); } } if (!empty($entity->settings[Scalr_Role_Behavior_Router::ROLE_VPC_SCALR_ROUTER_ID])) { $router = $this->controller->getFarmRole($entity->settings[Scalr_Role_Behavior_Router::ROLE_VPC_SCALR_ROUTER_ID]); if (empty($router->settings[Scalr_Role_Behavior_Router::ROLE_VPC_NID])) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Farm-role with id '{$router->id}' is not a valid router"); } } else { if ($subnetType == 'private') { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "You must describe a VPC Router"); } } } else { if ($farm->settings[FarmSetting::EC2_VPC_ID]) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "VPC Subnet(s) should be described"); } } break; default: if (in_array($entity->platform, SERVER_PLATFORMS::GetList())) { throw new ApiErrorException(501, ErrorMessage::ERR_NOT_IMPLEMENTED, "Platform '{$entity->platform}' is not supported yet"); } else { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Unknown platform '{$entity->platform}'"); } } if (!$this->controller->hasPermissions($entity, true)) { //Checks entity level write access permissions throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions"); } }
/** * @param string $query * @throws Scalr_Exception_Core */ public function xSearchResourcesAction($query) { if (trim($query) == '') { $this->response->data(['data' => []]); return; } $environments = $this->request->getScope() == ScopeInterface::SCOPE_ACCOUNT ? array_map(function ($r) { return $r['id']; }, $this->user->getEnvironments()) : [$this->getEnvironmentId()]; $f = new Entity\Farm(); $s = new Entity\Server(); $fr = new Entity\FarmRole(); $e = new Entity\Account\Environment(); $at = new Entity\Account\Team(); $sp = new Entity\Server\Property(); $farmSql = []; $serverSql = []; $queryEnc = "%{$query}%"; foreach ($environments as $envId) { $acl = $this->user->getAclRolesByEnvironment($envId); $isTermporaryServerPerm = $acl->isAllowed(Acl::RESOURCE_IMAGES_ENVIRONMENT, Acl::PERM_IMAGES_ENVIRONMENT_BUILD) || $acl->isAllowed(Acl::RESOURCE_IMAGES_ENVIRONMENT, Acl::PERM_IMAGES_ENVIRONMENT_IMPORT); if ($acl->isAllowed(Acl::RESOURCE_FARMS)) { $farmSql[] = "{$f->columnEnvId} = {$envId}"; if ($isTermporaryServerPerm) { $serverSql[] = "{$s->columnEnvId} = {$envId}"; } else { $serverSql[] = "{$s->columnEnvId} = {$envId} AND {$s->columnFarmId} IS NOT NULL"; } } else { $q = []; if ($acl->isAllowed(Acl::RESOURCE_TEAM_FARMS)) { $t = array_map(function ($t) { return $t['id']; }, $this->user->getTeams()); if (count($t)) { $q[] = "{$f->columnTeamId} IN (" . join(',', $t) . ")"; } } if ($acl->isAllowed(Acl::RESOURCE_OWN_FARMS)) { $q[] = "{$f->columnCreatedById} = {$this->user->getId()}"; } if (count($q)) { $farmSql[] = "{$f->columnEnvId} = {$envId} AND (" . join(" OR ", $q) . ")"; } if ($isTermporaryServerPerm) { $q[] = "{$s->columnStatus} IN ('" . Entity\Server::STATUS_IMPORTING . "', '" . Entity\Server::STATUS_TEMPORARY . "') AND {$s->columnFarmId} IS NULL"; } if (count($q)) { $serverSql[] = "{$s->columnEnvId} = {$envId} AND (" . join(" OR ", $q) . ")"; } } } $farms = []; if (count($farmSql)) { $farmStmt = $this->db->Execute("\n SELECT {$f->columnId} AS id, {$f->columnName} AS name, {$f->columnEnvId} AS envId, {$f->columnStatus} AS status,\n {$f->columnAdded} AS added, {$f->columnCreatedByEmail} AS createdByEmail, {$at->columnName} AS teamName, {$e->columnName} AS `envName`\n FROM {$f->table()}\n LEFT JOIN {$at->table()} ON {$at->columnId} = {$f->columnTeamId}\n LEFT JOIN {$e->table()} ON {$f->columnEnvId} = {$e->columnId}\n WHERE ({$f->columnName} LIKE ?) AND (" . join(" OR ", $farmSql) . ")", [$queryEnc]); while ($farm = $farmStmt->FetchRow()) { $farm['status'] = Entity\Farm::getStatusName($farm['status']); $farm['added'] = Scalr_Util_DateTime::convertTz($farm['added'], 'M j, Y H:i'); $farms[] = ['entityName' => 'farm', 'envId' => $farm['envId'], 'envName' => $farm['envName'], 'matchField' => 'Name', 'matchValue' => $farm['name'], 'data' => $farm]; } } $servers = []; if (count($serverSql)) { $serverStmt = $this->db->Execute("\n SELECT {$s->columnServerId} AS serverId, {$s->columnFarmId} AS farmId, {$s->columnFarmRoleId} AS farmRoleId,\n {$s->columnEnvId} AS envId, {$s->columnPlatform} AS platform, {$s->columnInstanceTypeName} AS instanceTypeName,\n {$s->columnStatus} AS status, {$s->columnCloudLocation} AS cloudLocation, {$s->columnRemoteIp} AS publicIp,\n {$s->columnLocalIp} AS privateIp, {$s->columnAdded} AS added, {$f->columnName} AS farmName,\n {$fr->columnAlias} AS farmRoleName, {$e->columnName} AS `envName`, {$fr->columnRoleId} AS roleId,\n {$sp->columnValue('sp1', 'hostname')}\n FROM {$s->table()}\n LEFT JOIN {$f->table()} ON {$f->columnId} = {$s->columnFarmId}\n LEFT JOIN {$fr->table()} ON {$fr->columnId} = {$s->columnFarmRoleId}\n LEFT JOIN {$e->table()} ON {$e->columnId} = {$s->columnEnvId}\n LEFT JOIN {$sp->table('sp1')} ON {$sp->columnServerId('sp1')} = {$s->columnServerId} AND {$sp->columnName('sp1')} = ?\n WHERE ({$s->columnRemoteIp} LIKE ? OR {$s->columnLocalIp} LIKE ? OR {$sp->columnValue('sp1')} LIKE ?) AND (" . join(" OR ", $serverSql) . ")\n GROUP BY {$s->columnServerId}", [Scalr_Role_Behavior::SERVER_BASE_HOSTNAME, $queryEnc, $queryEnc, $queryEnc]); $names = ['publicIp' => 'Public IP', 'privateIp' => 'Private IP', 'hostname' => 'Hostname']; while ($server = $serverStmt->FetchRow()) { $server['added'] = Scalr_Util_DateTime::convertTz($server['added'], 'M j, Y H:i'); if (strstr($server['publicIp'], $query)) { $m = 'publicIp'; } else { if (strstr($server['privateIp'], $query)) { $m = 'privateIp'; } else { $m = 'hostname'; } } $servers[] = ['entityName' => 'server', 'envId' => $server['envId'], 'envName' => $server['envName'], 'matchField' => $names[$m], 'matchValue' => $server[$m], 'data' => $server]; } } $this->response->data(['data' => array_merge($farms, $servers)]); }
/** * {@inheritdoc} * @see ServerImportInterface::import() */ public function import($instanceId, $tags = []) { $instances = PlatformFactory::NewPlatform($this->farmRole->platform)->getOrphanedServers($this->farmRole->getFarm()->getEnvironment(), $this->farmRole->cloudLocation, [$instanceId]); if (count($instances) != 1) { throw new ValidationErrorException("Instance was not found"); } $this->orphaned = $instances[0]; $this->tags = $tags; $this->validate(); $farm = $this->farmRole->getFarm(); $server = $this->server = new Entity\Server(); try { $server->serverId = \Scalr::GenerateUID(false); // DBServer::Create, startWithLetter $server->platform = $this->farmRole->platform; $server->cloudLocation = $this->farmRole->cloudLocation; $server->accountId = $farm->accountId; $server->envId = $farm->envId; $server->farmId = $farm->id; $server->farmRoleId = $this->farmRole->id; $server->imageId = $this->orphaned->imageId; $server->status = Entity\Server::STATUS_RUNNING; $server->type = $this->orphaned->instanceType; $server->remoteIp = $this->orphaned->publicIp; $server->localIp = $this->orphaned->privateIp; $server->added = new DateTime(); $server->initialized = new DateTime(); // initialized is used in billing, so we set current time as start point $server->scalarized = 0; $server->setFreeFarmIndex(); $server->setFreeFarmRoleIndex(); $server->properties[Entity\Server::SZR_KEY] = \Scalr::GenerateRandomKey(40); $server->properties[Entity\Server::SZR_KEY_TYPE] = SZR_KEY_TYPE::ONE_TIME; $server->properties[Entity\Server::SZR_VESION] = ''; $server->properties[Entity\Server::LAUNCHED_BY_ID] = $this->user->id; $server->properties[Entity\Server::LAUNCHED_BY_EMAIL] = $this->user->email; $server->properties[Entity\Server::LAUNCH_REASON_ID] = DBServer::LAUNCH_REASON_IMPORT; $server->properties[Entity\Server::LAUNCH_REASON] = DBServer::getLaunchReason(DBServer::LAUNCH_REASON_IMPORT); $server->properties[Entity\Server::FARM_ROLE_ID] = $this->farmRole->id; $server->properties[Entity\Server::ROLE_ID] = $this->farmRole->roleId; $server->properties[Entity\Server::FARM_CREATED_BY_ID] = $farm->ownerId ?: $farm->settings[Entity\FarmSetting::CREATED_BY_ID]; $server->properties[Entity\Server::FARM_CREATED_BY_EMAIL] = $farm->ownerId ? Entity\Account\User::findPk($farm->ownerId)->email : $farm->settings[Entity\FarmSetting::CREATED_BY_EMAIL]; // projectId, ccId $projectId = $farm->settings[Entity\FarmSetting::PROJECT_ID]; $ccId = null; if (!empty($projectId)) { try { $projectEntity = ProjectEntity::findPk($projectId); if ($projectEntity instanceof ProjectEntity) { /* @var $projectEntity ProjectEntity */ $ccId = $projectEntity->ccId; } else { $projectId = null; } } catch (Exception $e) { $projectId = null; } } $server->properties[Entity\Server::FARM_PROJECT_ID] = $projectId; if (empty($ccId)) { $ccId = Entity\Account\Environment::findPk($farm->envId)->getProperty(Entity\Account\EnvironmentProperty::SETTING_CC_ID); } $server->properties[Entity\Server::ENV_CC_ID] = $ccId; if (!empty($server->getImage())) { $server->getImage()->update(['dtLastUsed' => new DateTime()]); } if (!empty($this->farmRole->getRole())) { $this->farmRole->getRole()->update(['lastUsed' => new DateTime()]); } $this->importServer(); $server->save(); $server->setTimeLog('ts_created'); $server->setTimeLog('ts_launched', time()); $history = $server->getHistory(); $history->markAsLaunched($server->properties[Entity\Server::LAUNCH_REASON], $server->properties[Entity\Server::LAUNCH_REASON_ID]); $history->update(['cloudServerId' => $this->orphaned->cloudServerId, 'scuCollecting' => 1]); $this->applyTags(); return $server; } catch (Exception $e) { if (!empty($server->serverId)) { // cleanup $server->deleteBy([['serverId' => $server->serverId]]); Entity\ServerProperty::deleteBy([['serverId' => $server->serverId]]); Entity\Server\History::deletePk($server->serverId); $this->db->Execute("DELETE FROM `servers_launch_timelog` WHERE server_id = ?", [$server->serverId]); } throw new ServerImportException(sprintf("Server create was failed with error: %s", $e->getMessage()), $e->getCode(), $e); } }
public function xBuildAction() { $this->request->defineParams(array('farmId' => array('type' => 'int'), 'roles' => array('type' => 'json'), 'farm' => array('type' => 'json'), 'roleUpdate' => array('type' => 'int'), 'launch' => array('type' => 'bool'))); if (!$this->isFarmConfigurationValid($this->getParam('farmId'), $this->getParam('farm'), (array) $this->getParam('roles'))) { if ($this->errors['error_count'] != 0) { $this->response->failure(); $this->response->data(array('errors' => $this->errors)); return; } } $farm = $this->getParam('farm'); $client = Client::Load($this->user->getAccountId()); if ($this->getParam('farmId')) { $dbFarm = DBFarm::LoadByID($this->getParam('farmId')); $this->user->getPermissions()->validate($dbFarm); $this->request->restrictFarmAccess($dbFarm, Acl::PERM_FARMS_MANAGE); $dbFarm->isLocked(); if ($this->getParam('changed') && $dbFarm->changedTime && $this->getParam('changed') != $dbFarm->changedTime) { $userName = '******'; $changed = explode(' ', $this->getParam('changed')); $changedTime = intval($changed[1]); try { $user = new Scalr_Account_User(); $user->loadById($dbFarm->changedByUserId); $userName = $user->getEmail(); } catch (Exception $e) { } $this->response->failure(); $this->response->data(array('changedFailure' => sprintf('%s changed this farm at %s', $userName, Scalr_Util_DateTime::convertTz($changedTime)))); return; } $dbFarm->changedByUserId = $this->user->getId(); $dbFarm->changedTime = microtime(); $bNew = false; } else { $this->request->restrictFarmAccess(null, Acl::PERM_FARMS_MANAGE); $this->user->getAccount()->validateLimit(Scalr_Limits::ACCOUNT_FARMS, 1); $dbFarm = new DBFarm(); $dbFarm->ClientID = $this->user->getAccountId(); $dbFarm->EnvID = $this->getEnvironmentId(); $dbFarm->Status = FARM_STATUS::TERMINATED; $dbFarm->createdByUserId = $this->user->getId(); $dbFarm->createdByUserEmail = $this->user->getEmail(); $dbFarm->changedByUserId = $this->user->getId(); $dbFarm->changedTime = microtime(); $bNew = true; } if ($this->getParam('farm')) { $dbFarm->Name = $this->request->stripValue($farm['name']); $dbFarm->RolesLaunchOrder = $farm['rolesLaunchOrder']; $dbFarm->Comments = $this->request->stripValue($farm['description']); } if (empty($dbFarm->Name)) { throw new Exception(_("Farm name required")); } if ($bNew) { $dbFarm->teamId = is_numeric($farm['teamOwner']) && $farm['teamOwner'] > 0 ? $farm['teamOwner'] : NULL; } else { if ($dbFarm->createdByUserId == $this->user->getId() || $this->user->isAccountOwner() || $this->request->isFarmAllowed($dbFarm, Acl::PERM_FARMS_CHANGE_OWNERSHIP)) { if (is_numeric($farm['owner']) && $farm['owner'] != $dbFarm->createdByUserId) { $user = (new Scalr_Account_User())->loadById($farm['owner']); $dbFarm->createdByUserId = $user->getId(); $dbFarm->createdByUserEmail = $user->getEmail(); // TODO: move to subclass \Farm\Setting\OwnerHistory $history = unserialize($dbFarm->GetSetting(Entity\FarmSetting::OWNER_HISTORY)); if (!is_array($history)) { $history = []; } $history[] = ['newId' => $user->getId(), 'newEmail' => $user->getEmail(), 'changedById' => $this->user->getId(), 'changedByEmail' => $this->user->getEmail(), 'dt' => date('Y-m-d H:i:s')]; $dbFarm->SetSetting(Entity\FarmSetting::OWNER_HISTORY, serialize($history)); } $dbFarm->teamId = is_numeric($farm['teamOwner']) && $farm['teamOwner'] > 0 ? $farm['teamOwner'] : NULL; } } $dbFarm->save(); $governance = new Scalr_Governance($this->getEnvironmentId()); if (!$this->getParam('farmId') && $governance->isEnabled(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_LEASE)) { $dbFarm->SetSetting(Entity\FarmSetting::LEASE_STATUS, 'Active'); // for created farm } if (isset($farm['variables'])) { $variables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), ScopeInterface::SCOPE_FARM); $variables->setValues(is_array($farm['variables']) ? $farm['variables'] : [], 0, $dbFarm->ID, 0, '', false, true); } if (!$farm['timezone']) { $farm['timezone'] = date_default_timezone_get(); } $dbFarm->SetSetting(Entity\FarmSetting::TIMEZONE, $farm['timezone']); $dbFarm->SetSetting(Entity\FarmSetting::EC2_VPC_ID, isset($farm["vpc_id"]) ? $farm['vpc_id'] : null); $dbFarm->SetSetting(Entity\FarmSetting::EC2_VPC_REGION, isset($farm["vpc_id"]) ? $farm['vpc_region'] : null); $dbFarm->SetSetting(Entity\FarmSetting::SZR_UPD_REPOSITORY, $farm[Entity\FarmSetting::SZR_UPD_REPOSITORY]); $dbFarm->SetSetting(Entity\FarmSetting::SZR_UPD_SCHEDULE, $farm[Entity\FarmSetting::SZR_UPD_SCHEDULE]); if (!$dbFarm->GetSetting(Entity\FarmSetting::CRYPTO_KEY)) { $dbFarm->SetSetting(Entity\FarmSetting::CRYPTO_KEY, Scalr::GenerateRandomKey(40)); } if ($this->getContainer()->analytics->enabled) { //Cost analytics project must be set for the Farm object $dbFarm->setProject(!empty($farm['projectId']) ? $farm['projectId'] : null); } $virtualFarmRoles = array(); $roles = $this->getParam('roles'); if (!empty($roles)) { foreach ($roles as $role) { if (strpos($role['farm_role_id'], "virtual_") !== false) { $dbRole = DBRole::loadById($role['role_id']); $dbFarmRole = $dbFarm->AddRole($dbRole, $role['platform'], $role['cloud_location'], (int) $role['launch_index'], $role['alias']); $virtualFarmRoles[$role['farm_role_id']] = $dbFarmRole->ID; } } } $usedPlatforms = array(); $dbFarmRolesList = array(); $newFarmRolesList = array(); $farmRoleVariables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), ScopeInterface::SCOPE_FARMROLE); if (!empty($roles)) { foreach ($roles as $role) { if ($role['farm_role_id']) { if (isset($virtualFarmRoles[$role['farm_role_id']])) { $role['farm_role_id'] = $virtualFarmRoles[$role['farm_role_id']]; } $update = true; $dbFarmRole = DBFarmRole::LoadByID($role['farm_role_id']); $dbRole = DBRole::loadById($dbFarmRole->RoleID); $role['role_id'] = $dbFarmRole->RoleID; if ($dbFarmRole->Platform == SERVER_PLATFORMS::GCE) { $dbFarmRole->CloudLocation = $role['cloud_location']; } } else { /** TODO: Remove because will be handled with virtual_ **/ $update = false; $dbRole = DBRole::loadById($role['role_id']); $dbFarmRole = $dbFarm->AddRole($dbRole, $role['platform'], $role['cloud_location'], (int) $role['launch_index']); } if ($dbRole->hasBehavior(ROLE_BEHAVIORS::RABBITMQ)) { $role['settings'][Entity\FarmRoleSetting::SCALING_MAX_INSTANCES] = $role['settings'][Entity\FarmRoleSetting::SCALING_MIN_INSTANCES]; } if ($update) { $dbFarmRole->LaunchIndex = (int) $role['launch_index']; $dbFarmRole->Alias = $role['alias']; $dbFarmRole->Save(); } $usedPlatforms[$role['platform']] = 1; $oldRoleSettings = $dbFarmRole->GetAllSettings(); // Update virtual farm_role_id with actual value $scripts = (array) $role['scripting']; if (!empty($virtualFarmRoles)) { array_walk_recursive($scripts, function (&$v, $k) use($virtualFarmRoles) { if (is_string($v)) { $v = str_replace(array_keys($virtualFarmRoles), array_values($virtualFarmRoles), $v); } }); array_walk_recursive($role['settings'], function (&$v, $k) use($virtualFarmRoles) { if (is_string($v)) { $v = str_replace(array_keys($virtualFarmRoles), array_values($virtualFarmRoles), $v); } }); } $dbFarmRole->ClearSettings("chef."); if (!empty($role['scaling_settings']) && is_array($role['scaling_settings'])) { foreach ($role['scaling_settings'] as $k => $v) { $dbFarmRole->SetSetting($k, $v, Entity\FarmRoleSetting::TYPE_CFG); } } foreach ($role['settings'] as $k => $v) { $dbFarmRole->SetSetting($k, $v, Entity\FarmRoleSetting::TYPE_CFG); } /****** Scaling settings ******/ $scalingManager = new Scalr_Scaling_Manager($dbFarmRole); $scalingManager->setFarmRoleMetrics(is_array($role['scaling']) ? $role['scaling'] : array()); //TODO: optimize this code... $this->db->Execute("DELETE FROM farm_role_scaling_times WHERE farm_roleid=?", array($dbFarmRole->ID)); // 5 = Time based scaling -> move to constants if (!empty($role['scaling'][Entity\ScalingMetric::METRIC_DATE_AND_TIME_ID])) { foreach ($role['scaling'][Entity\ScalingMetric::METRIC_DATE_AND_TIME_ID] as $scal_period) { $chunks = explode(":", $scal_period['id']); $this->db->Execute("INSERT INTO farm_role_scaling_times SET\n farm_roleid\t\t= ?,\n start_time\t\t= ?,\n end_time\t\t= ?,\n days_of_week\t= ?,\n instances_count\t= ?\n ", array($dbFarmRole->ID, $chunks[0], $chunks[1], $chunks[2], $chunks[3])); } } /*****************/ /* Add script options to databse */ $dbFarmRole->SetScripts($scripts, (array) $role['scripting_params']); /* End of scripting section */ /* Add services configuration */ $dbFarmRole->SetServiceConfigPresets((array) $role['config_presets']); /* End of scripting section */ /* Add storage configuration */ if (isset($role['storages']['configs'])) { $dbFarmRole->getStorage()->setConfigs($role['storages']['configs'], false); } $farmRoleVariables->setValues(is_array($role['variables']) ? $role['variables'] : [], $dbFarmRole->GetRoleID(), $dbFarm->ID, $dbFarmRole->ID, '', false, true); foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->onFarmSave($dbFarm, $dbFarmRole); } /** * Platform specified updates */ if ($dbFarmRole->Platform == SERVER_PLATFORMS::EC2) { \Scalr\Modules\Platforms\Ec2\Helpers\EbsHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); \Scalr\Modules\Platforms\Ec2\Helpers\EipHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); \Scalr\Modules\Platforms\Ec2\Helpers\ElbHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); } if (in_array($dbFarmRole->Platform, array(SERVER_PLATFORMS::IDCF, SERVER_PLATFORMS::CLOUDSTACK))) { Scalr\Modules\Platforms\Cloudstack\Helpers\CloudstackHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); } $dbFarmRolesList[] = $dbFarmRole; $newFarmRolesList[] = $dbFarmRole->ID; } } if (!$this->getParam('roleUpdate')) { /* @var $farmRole Entity\FarmRole */ foreach (Entity\FarmRole::findByFarmId($dbFarm->ID) as $farmRole) { if (!in_array($farmRole->id, $newFarmRolesList)) { $farmRole->delete(); } } } $dbFarm->save(); if (!$client->GetSettingValue(CLIENT_SETTINGS::DATE_FARM_CREATED)) { $client->SetSettingValue(CLIENT_SETTINGS::DATE_FARM_CREATED, time()); } if ($this->request->isFarmAllowed($dbFarm, Acl::PERM_FARMS_LAUNCH_TERMINATE) && $this->getParam('launch')) { $this->user->getPermissions()->validate($dbFarm); $dbFarm->isLocked(); Scalr::FireEvent($dbFarm->ID, new FarmLaunchedEvent(true, $this->user->id)); $this->response->success('Farm successfully saved and launched'); } else { $this->response->success('Farm successfully saved'); } $this->response->data(array('farmId' => $dbFarm->ID, 'isNewFarm' => $bNew)); }
/** * @test */ public function testComplex() { /* @var Script $script */ $script = static::generateScripts([['os' => 'linux']])[0]; /* @var ScriptVersion $version */ $version = static::generateVersions($script, [['content' => '#!/bin/sh']])[0]; $adapter = $this->getAdapter('OrchestrationRules\\FarmRoleScript'); /* @var User $user */ $user = $this->getUser(); $environment = $this->getEnvironment(); /* @var $farm Farm */ $farm = static::createEntity(new Farm(), ['changedById' => $user->getId(), 'name' => "{$this->uuid}-farm", 'description' => "{$this->uuid}-description", 'envId' => $environment->id, 'accountId' => $user->getAccountId(), 'createdById' => $user->getId()]); $farmRole = $this->createTestFarmRole($farm); static::createEntity(new FarmRoleScript(), ['farmRoleId' => $farmRole->id, 'scriptId' => $script->id, 'farmId' => $farm->id]); //test get endpoint $filterable = $adapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE]; $rules = $this->listRules($farmRole->id); foreach ($rules as $rule) { foreach ($filterable as $property) { $filterValue = $rule->{$property}; $listResult = $this->listRules($farmRole->id, [$property => $filterValue]); if (!static::isRecursivelyEmpty($filterValue)) { foreach ($listResult as $filtered) { $this->assertEquals($filterValue, $filtered->{$property}, "Property '{$property}' mismatch"); } } } $response = $this->getRule($farmRole->id, $rule->id); $this->assertEquals(200, $response->status, $this->printResponseError($response)); $dbRule = FarmRoleScript::findPk($rule->id); $this->assertObjectEqualsEntity($response->getBody()->data, $dbRule, $adapter); } $scalrFRScriptData = ['trigger' => ['triggerType' => FarmRoleScriptAdapter::TRIGGER_SINGLE_EVENT, 'event' => ['id' => 'HostInit']], 'target' => ['targetType' => FarmRoleScriptAdapter::TARGET_NAME_TRIGGERING_SERVER], 'action' => ['actionType' => FarmRoleScriptAdapter::ACTION_SCRIPT, 'scriptVersion' => ['script' => ['id' => $script->id], 'version' => $version->version]]]; $localFRScriptData = ['trigger' => ['triggerType' => FarmRoleScriptAdapter::TRIGGER_ALL_EVENTS], 'target' => ['targetType' => FarmRoleScriptAdapter::TARGET_NAME_NULL], 'action' => ['actionType' => FarmRoleScriptAdapter::ACTION_URI, 'path' => 'https://example.com']]; //post scalr rule $response = $this->postRule($farmRole->id, $scalrFRScriptData); $this->assertEquals(201, $response->status, $this->printResponseError($response)); $ruleId = $response->getBody()->data->id; /* @var $rule FarmRoleScript */ $rule = FarmRoleScript::findPk($ruleId); $this->assertNotEmpty($rule); $this->ruleToDelete($ruleId); $this->assertObjectEqualsEntity($scalrFRScriptData, $rule, $adapter); //post local rule $response = $this->postRule($farmRole->id, $localFRScriptData); $this->assertEquals(201, $response->status, $this->printResponseError($response)); $ruleId = $response->getBody()->data->id; /* @var $rule FarmRoleScript */ $rule = FarmRoleScript::findPk($ruleId); $this->assertNotEmpty($rule); $this->ruleToDelete($ruleId); $this->assertObjectEqualsEntity($localFRScriptData, $rule, $adapter); //post rule already existing $data = $scalrFRScriptData; $data['id'] = $ruleId; $response = $this->postRule($farmRole->id, $data); $this->assertEquals(201, $response->status, $this->printResponseError($response)); $ruleId = $response->getBody()->data->id; $this->ruleToDelete($ruleId); $this->assertNotEquals($data['id'], $ruleId); //post rule with script that does not exists $data = $scalrFRScriptData; $data['action']['scriptVersion']['script']['id'] = Script::findOne([], null, ['id' => true])->id + 1; $response = $this->postRule($farmRole->id, $data); $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); //post rule with version that does not exists $data = $scalrFRScriptData; $data['action']['scriptVersion']['version'] = Script::findPk($data['action']['scriptVersion']['script']['id'])->getLatestVersion()->version + 1; $response = $this->postRule($farmRole->id, $data); $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); //post rule with properties that not existing $data = $scalrFRScriptData; $data['foo'] = 'bar'; $response = $this->postRule($farmRole->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //post rule without required fields $data = $localFRScriptData; unset($data['action']); $response = $this->postRule($farmRole->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //post rule with invalid field $data = $localFRScriptData; $data['action'] = ''; $response = $this->postRule($farmRole->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //modify rule //TODO::ape add modify rule //fetch rule $response = $this->getRule($farmRole->id, $rule->id); $this->assertEquals(200, $response->status, $this->printResponseError($response)); $this->assertObjectEqualsEntity($response->getBody()->data, $rule, $adapter); //fetch rule that doe not exists $response = $this->getRule($farmRole->id, FarmRoleScript::findOne([], null, ['id' => false])->id + 1); $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); //fetch rule with missmatch farm role id $response = $this->getRule(FarmRole::findOne([], null, ['id' => false])->id + 1, $rule->id); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE); //test have access to all listed rules $rules = $this->listRules($farmRole->id); foreach ($rules as $rule) { $this->assertTrue(FarmRoleScript::findPk($rule->id)->hasAccessPermissions($user)); } //test invalid filters $url = self::getUserApiUrl("/farm-roles/{$farmRole->id}/orchestration-rules/"); $response = $this->request($url, Request::METHOD_GET, ['foo' => 'bar']); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); $response = $this->request($url, Request::METHOD_GET, ['scope' => 'foobar']); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //delete script /* @var $rule FarmRoleScript */ $rule = static::createEntity(new FarmRoleScript(), ['farmRoleId' => $farmRole->id, 'scriptId' => $script->id, 'farmId' => $farm->id]); $response = $this->deleteRule($farmRole->id, $rule->id); $this->assertEquals(200, $response->status, $this->printResponseError($response)); //delete script that does not exists $response = $this->deleteRule($farmRole->id, FarmRoleScript::findOne([], null, ['id' => false])->id + 1); $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); }
/** * @return Image */ public function createImageEntity() { $snapshot = $this->getSnapshotDetails(); $envId = $this->envId; /* @var Entity\Server $server */ $server = Entity\Server::findOneByServerId($this->serverId); if (!empty($server->farmRoleId)) { /* @var Entity\FarmRole $farmRole */ $farmRole = Entity\FarmRole::findPk($server->farmRoleId); if (!empty($farmRole->roleId)) { /* @var Entity\Role $role */ $role = Entity\Role::findPk($farmRole->roleId); $envId = $role->getScope() == ScopeInterface::SCOPE_ACCOUNT ? NULL : $envId; } } $image = new Image(); $image->id = $this->snapshotId; $image->accountId = $this->clientId; $image->envId = $envId; $image->bundleTaskId = $this->id; $image->platform = $this->platform; $image->cloudLocation = $this->cloudLocation; $image->createdById = $this->createdById; $image->createdByEmail = $this->createdByEmail; $image->architecture = is_null($snapshot['os']->arch) ? 'x86_64' : $snapshot['os']->arch; $image->source = Image::SOURCE_BUNDLE_TASK; $image->status = Image::STATUS_ACTIVE; $image->agentVersion = $snapshot['szr_version']; $image->checkImage(); if (!$image->name) { $image->name = $this->roleName . '-' . date('YmdHi'); } $image->osId = $this->osId; $image->save(); if ($snapshot['software']) { $software = []; foreach ((array) $snapshot['software'] as $soft) { $software[$soft->name] = $soft->version; } $image->setSoftware($software); } return $image; }
/** * Get GV * * @param string $criteria search criteria * @param array $params query params * * @return array */ public function getGlobalVariable($criteria, $params) { $roleId = 0; $farmId = 0; $farmRoleId = 0; $serverId = 0; $scope = ScopeInterface::SCOPE_ENVIRONMENT; if (isset($params['farmId'])) { $scope = ScopeInterface::SCOPE_FARM; $farmId = $params['farmId']; } else { if (isset($params['farmRoleId'])) { /* @var $farmRole FarmRole */ $farmRole = FarmRole::findOne([['id' => $params['farmRoleId']]]); $farmRoleId = $farmRole->id; $roleId = $farmRole->roleId; $farmId = $farmRole->farmId; $scope = ScopeInterface::SCOPE_FARMROLE; } else { if (isset($params['roleId'])) { $roleId = $params['roleId']; $scope = ScopeInterface::SCOPE_ROLE; } } } $variableScopeIdentity = [$roleId, $farmId, $farmRoleId, $serverId]; $varName = $criteria; $gv = new Scalr_Scripting_GlobalVariables($this->getUser()->getAccountId(), $this->getEnvironment()->id, $scope); $variable = []; $list = $gv->getValues(...$variableScopeIdentity); foreach ($list as $var) { if (!empty($var['current']['name']) && $var['current']['name'] == $varName || !empty($var['default']['name']) && $var['default']['name'] == $varName) { $variable = $var; break; } } return $variable; }
/** * Magic getter * * @param string $name Name of property that is accessed * * @return mixed Returns property value */ public function __get($name) { switch ($name) { case 'settings': if (empty($this->_settings)) { $this->_settings = new SettingsCollection('Scalr\\Model\\Entity\\FarmSetting', [['farmId' => &$this->id]], ['farmId' => &$this->id]); } return $this->_settings; case 'farmRoles': if (empty($this->_farmRoles)) { $this->_farmRoles = FarmRole::findByFarmId($this->id); } return $this->_farmRoles; case 'servers': if (empty($this->_servers)) { $this->_servers = Server::findByFarmId($this->id); } return $this->_servers; default: return parent::__get($name); } }
/** * @test * @functional */ public function testFarmRoleGlobalVariables() { $db = \Scalr::getDb(); $testName = str_replace('-', '', $this->getTestName()); $farm = Farm::findOne([['envId' => static::$testEnvId]]); /* @var $farm Farm */ $farmRole = FarmRole::findOne([['farmId' => $farm->id]]); /* @var $farmRole FarmRole */ $roleId = $farmRole->id; $uri = static::getUserApiUrl("farm-roles/{$roleId}/global-variables"); $variables = null; $declaredNotInRole = null; do { $query = []; if (isset($variables->pagination->next)) { $parts = parse_url($variables->pagination->next); parse_str($parts['query'], $query); } $query[ApiController::QUERY_PARAM_MAX_RESULTS] = 2; $describe = $this->request($uri, Request::METHOD_GET, $query); $this->assertDescribeResponseNotEmpty($describe); $this->assertNotEmpty($describe->getBody()); $variables = $describe->getBody(); $this->assertLessThanOrEqual(2, count($variables->data)); foreach ($variables->data as $variable) { $this->assertVariableObjectNotEmpty($variable); if (empty($declaredNotInRole) && $variable->declaredIn !== ScopeInterface::SCOPE_FARMROLE && !$variable->hidden) { $declaredNotInRole = $variable->name; } if (strpos($variable->name, $testName) !== false) { $delete = $this->request($uri . '/' . $variable->name, Request::METHOD_DELETE); $this->assertEquals(200, $delete->response->getStatus()); } } } while (!empty($variables->pagination->next)); $this->assertNotNull($declaredNotInRole); $notFoundRoleId = 10 + $db->GetOne("SELECT MAX(f.id) FROM farm_roles f"); $describe = $this->request(static::getUserApiUrl("/farm-roles/{$notFoundRoleId}/global-variables"), Request::METHOD_GET); $this->assertErrorMessageContains($describe, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); $create = $this->request($uri, Request::METHOD_POST, [], ['invalid' => 'value']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'You are trying to set'); $create = $this->request($uri, Request::METHOD_POST, [], ['name' => 'invalid val--ue']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Name should contain only letters, numbers and underscores, start with letter and be from 2 to 128 chars long'); //test invalid category name $create = $this->request($uri, Request::METHOD_POST, [], ['name' => 'TestName', 'category' => 'invalid category']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE); $create = $this->request($uri, Request::METHOD_POST); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Invalid body'); $create = $this->request($uri, Request::METHOD_POST, [], ['name' => $testName, 'value' => $testName, 'description' => $testName]); $this->assertEquals(201, $create->response->getStatus()); $this->assertFetchResponseNotEmpty($create); $createBody = $create->getBody(); $this->assertNotEmpty($createBody); $this->assertVariableObjectNotEmpty($createBody->data); $this->assertEquals($testName, $createBody->data->name); $this->assertEquals($testName, $createBody->data->value); $this->assertEquals($testName, $createBody->data->description); $create = $this->request($uri, Request::METHOD_POST, [], ['name' => $testName]); $this->assertErrorMessageContains($create, 409, ErrorMessage::ERR_UNICITY_VIOLATION, 'Variable with name'); $fetch = $this->request($uri . '/' . $testName, Request::METHOD_GET); $this->assertEquals(200, $fetch->response->getStatus()); $this->assertFetchResponseNotEmpty($fetch); $fetchBody = $fetch->getBody(); $this->assertNotEmpty($fetchBody); $this->assertVariableObjectNotEmpty($fetchBody->data); $this->assertEquals($testName, $fetchBody->data->name); $this->assertEquals($testName, $fetchBody->data->value); $modify = $this->request($uri . '/' . $testName, Request::METHOD_PATCH, [], ['value' => '']); $this->assertEquals(200, $modify->response->getStatus()); $this->assertFetchResponseNotEmpty($modify); $modifyBody = $modify->getBody(); $this->assertNotEmpty($modifyBody); $this->assertVariableObjectNotEmpty($modifyBody->data); $this->assertEquals($testName, $modifyBody->data->name); $this->assertEquals('', $modifyBody->data->value); $modify = $this->request($uri . '/' . $testName . 'notFound', Request::METHOD_PATCH, [], ['value' => '']); $this->assertEquals(404, $modify->response->getStatus()); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_OBJECT_NOT_FOUND, $modify); $modify = $this->request($uri . '/' . $testName, Request::METHOD_PATCH, [], ['name' => '']); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'You are trying to set'); $modify = $this->request($uri . '/' . $declaredNotInRole, Request::METHOD_PATCH, [], ['hidden' => 1]); $this->assertEquals(403, $modify->response->getStatus()); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_SCOPE_VIOLATION, $modify); $delete = $this->request($uri . '/' . $declaredNotInRole, Request::METHOD_DELETE); $this->assertEquals(403, $delete->response->getStatus()); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_SCOPE_VIOLATION, $delete); $delete = $this->request($uri . '/' . $testName . 'notfound', Request::METHOD_DELETE); $this->assertEquals(404, $delete->response->getStatus()); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_OBJECT_NOT_FOUND, $delete); $delete = $this->request($uri . '/' . $testName, Request::METHOD_DELETE); $this->assertEquals(200, $delete->response->getStatus()); }
/** * {@inheritdoc} * @see OrchestrationRule::hasAccessPermissions() */ public function hasAccessPermissions($user, $environment = null, $modify = null) { return FarmRole::findPk($this->farmRoleId)->hasAccessPermissions($user, $environment, $modify); }