/** * @deprecated Use method FarmRole::getImage * * @return Image|NULL * @throws \Exception */ public function getImage() { /* @var $role Role */ $role = Role::findPk($this->roleId); $criteria = [['id' => $this->imageId], ['platform' => $this->platform], ['cloudLocation' => $this->cloudLocation], ['$or' => [['accountId' => null], ['$and' => [['accountId' => $role->accountId], ['$or' => [['envId' => null], ['envId' => $role->envId]]]]]]]]; return Image::findOne($criteria); }
/** * @param string $platform * @param string $cloudLocation * @param string $cloudServerId * @param string $name * @param bool $createImage * @throws Exception */ public function xInitiateImportAction($platform, $cloudLocation, $cloudServerId, $name, $createImage = false) { if (!Role::validateName($name)) { throw new Exception(_("Name is incorrect")); } if (!$createImage && $this->db->GetOne("SELECT id FROM roles WHERE name=? AND (env_id IS NULL OR env_id = ?) LIMIT 1", array($name, $this->getEnvironmentId()))) { throw new Exception('Selected role name is already used. Please select another one.'); } $cryptoKey = Scalr::GenerateRandomKey(40); $creInfo = new ServerCreateInfo($platform, null, 0, 0); $creInfo->clientId = $this->user->getAccountId(); $creInfo->envId = $this->getEnvironmentId(); $creInfo->farmId = 0; $creInfo->SetProperties(array(SERVER_PROPERTIES::SZR_IMPORTING_ROLE_NAME => $name, SERVER_PROPERTIES::SZR_IMPORTING_OBJECT => $createImage ? BundleTask::BUNDLETASK_OBJECT_IMAGE : BundleTask::BUNDLETASK_OBJECT_ROLE, SERVER_PROPERTIES::SZR_KEY => $cryptoKey, SERVER_PROPERTIES::SZR_KEY_TYPE => SZR_KEY_TYPE::PERMANENT, SERVER_PROPERTIES::SZR_VESION => "0.14.0", SERVER_PROPERTIES::SZR_IMPORTING_VERSION => 2, SERVER_PROPERTIES::SZR_IMPORTING_STEP => 1, SERVER_PROPERTIES::LAUNCHED_BY_ID => $this->user->id, SERVER_PROPERTIES::LAUNCHED_BY_EMAIL => $this->user->getEmail())); $platformObj = PlatformFactory::NewPlatform($platform); if ($platform == SERVER_PLATFORMS::EC2) { $client = $this->environment->aws($cloudLocation)->ec2; $r = $client->instance->describe($cloudServerId); $instance = $r->get(0)->instancesSet->get(0); $creInfo->SetProperties(array(EC2_SERVER_PROPERTIES::REGION => $cloudLocation, EC2_SERVER_PROPERTIES::INSTANCE_ID => $cloudServerId, EC2_SERVER_PROPERTIES::AMIID => $instance->imageId, EC2_SERVER_PROPERTIES::AVAIL_ZONE => $instance->placement->availabilityZone)); } else { if ($platform == SERVER_PLATFORMS::EUCALYPTUS) { $client = $this->environment->eucalyptus($cloudLocation)->ec2; $r = $client->instance->describe($cloudServerId); $instance = $r->get(0)->instancesSet->get(0); $creInfo->SetProperties(array(EUCA_SERVER_PROPERTIES::REGION => $cloudLocation, EUCA_SERVER_PROPERTIES::INSTANCE_ID => $cloudServerId, EUCA_SERVER_PROPERTIES::EMIID => $instance->imageId, EUCA_SERVER_PROPERTIES::AVAIL_ZONE => $instance->placement->availabilityZone)); } else { if ($platform == SERVER_PLATFORMS::GCE) { $gce = $platformObj->getClient($this->environment, $cloudLocation); $result = $gce->instances->get($this->environment->getPlatformConfigValue(GoogleCEPlatformModule::PROJECT_ID), $cloudLocation, $cloudServerId); $creInfo->SetProperties(array(GCE_SERVER_PROPERTIES::SERVER_NAME => $cloudServerId, GCE_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation)); } else { if (PlatformFactory::isOpenstack($platform)) { $creInfo->SetProperties(array(OPENSTACK_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation, OPENSTACK_SERVER_PROPERTIES::SERVER_ID => $cloudServerId)); } else { if (PlatformFactory::isCloudstack($platform)) { $creInfo->SetProperties(array(CLOUDSTACK_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation, CLOUDSTACK_SERVER_PROPERTIES::SERVER_ID => $cloudServerId)); } } } } } $dbServer = DBServer::Create($creInfo, true); $ips = $platformObj->GetServerIPAddresses($dbServer); $dbServer->localIp = $ips['localIp']; $dbServer->remoteIp = $ips['remoteIp']; $dbServer->Save(); $this->response->data(array('command' => $this->getSzrCmd($dbServer), 'serverId' => $dbServer->serverId)); }
/** * @param string $platform * @param string $architecture * @param JsonData $behaviors * @param string $name * @param bool $createImage * @param string $imageId * @param string $cloudLocation * @param string $osId * @param integer $hvm * @param JsonData $advanced * @param JsonData $chef * @throws Exception */ public function xBuildAction($platform, $architecture, JsonData $behaviors, $name = '', $createImage = false, $imageId, $cloudLocation, $osId, $hvm = 0, JsonData $advanced, JsonData $chef) { $this->request->restrictAccess(Acl::RESOURCE_FARMS_ROLES, Acl::PERM_FARMS_ROLES_CREATE); if (!\Scalr\Model\Entity\Role::validateName($name)) { throw new Exception(_("Name is incorrect")); } if (!$createImage && $this->db->GetOne("SELECT id FROM roles WHERE name=? AND (env_id IS NULL OR env_id = ?) LIMIT 1", array($name, $this->getEnvironmentId()))) { throw new Exception('Selected role name is already used. Please select another one.'); } $behaviours = implode(",", array_values($behaviors->getArrayCopy())); $os = Os::findPk($osId); if (!$os) { throw new Exception('Operating system not found.'); } // Create server $creInfo = new ServerCreateInfo($platform, null, 0, 0); $creInfo->clientId = $this->user->getAccountId(); $creInfo->envId = $this->getEnvironmentId(); $creInfo->farmId = 0; $creInfo->SetProperties(array(SERVER_PROPERTIES::SZR_IMPORTING_BEHAVIOR => $behaviours, SERVER_PROPERTIES::SZR_IMPORTING_IMAGE_ID => $imageId, SERVER_PROPERTIES::SZR_KEY => Scalr::GenerateRandomKey(40), SERVER_PROPERTIES::SZR_KEY_TYPE => SZR_KEY_TYPE::PERMANENT, SERVER_PROPERTIES::SZR_VESION => "0.13.0", SERVER_PROPERTIES::SZR_IMPORTING_MYSQL_SERVER_TYPE => "mysql", SERVER_PROPERTIES::SZR_DEV_SCALARIZR_BRANCH => $advanced['scalrbranch'], SERVER_PROPERTIES::ARCHITECTURE => $architecture, SERVER_PROPERTIES::SZR_IMPORTING_LEAVE_ON_FAIL => $advanced['dontterminatefailed'] == 'on' ? 1 : 0, SERVER_PROPERTIES::SZR_IMPORTING_CHEF_SERVER_ID => $chef['chef.server'], SERVER_PROPERTIES::SZR_IMPORTING_CHEF_ENVIRONMENT => $chef['chef.environment'], SERVER_PROPERTIES::SZR_IMPORTING_CHEF_ROLE_NAME => $chef['chef.role'])); $dbServer = DBServer::Create($creInfo, true); $dbServer->status = SERVER_STATUS::TEMPORARY; $dbServer->imageId = $imageId; $dbServer->save(); //Launch server $launchOptions = new Scalr_Server_LaunchOptions(); $launchOptions->imageId = $imageId; $launchOptions->cloudLocation = $cloudLocation; $launchOptions->architecture = $architecture; $platformObj = PlatformFactory::NewPlatform($platform); switch ($platform) { case SERVER_PLATFORMS::ECS: $launchOptions->serverType = 10; if ($cloudLocation == 'all') { $locations = array_keys($platformObj->getLocations($this->environment)); $launchOptions->cloudLocation = $locations[0]; } //Network here: $osClient = $platformObj->getOsClient($this->environment, $launchOptions->cloudLocation); $networks = $osClient->network->listNetworks(); $tenantId = $osClient->getConfig()->getAuthToken()->getTenantId(); foreach ($networks as $network) { if ($network->status == 'ACTIVE') { if ($network->{"router:external"} != true) { if ($tenantId == $network->tenant_id) { $launchOptions->networks = array($network->id); break; } } } } break; case SERVER_PLATFORMS::IDCF: $launchOptions->serverType = 24; break; case SERVER_PLATFORMS::RACKSPACE: if ($os->family == 'ubuntu') { $launchOptions->serverType = 1; } else { $launchOptions->serverType = 3; } break; case SERVER_PLATFORMS::RACKSPACENG_US: $launchOptions->serverType = 3; break; case SERVER_PLATFORMS::RACKSPACENG_UK: $launchOptions->serverType = 3; break; case SERVER_PLATFORMS::EC2: if ($hvm == 1) { $launchOptions->serverType = 'm3.xlarge'; $bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } else { if ($os->family == 'oel') { $launchOptions->serverType = 'm3.large'; $bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } elseif ($os->family == 'rhel') { $launchOptions->serverType = 'm3.large'; $bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } elseif ($os->family == 'scientific') { $launchOptions->serverType = 'm3.large'; $bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } elseif ($os->family == 'debian' && $os->generation == '8') { $launchOptions->serverType = 'm3.large'; $bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } elseif ($os->family == 'centos' && $os->generation == '7') { $launchOptions->serverType = 'm3.large'; $bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } else { $launchOptions->serverType = 'm3.large'; } } $launchOptions->userData = "#cloud-config\ndisable_root: false"; break; case SERVER_PLATFORMS::GCE: $launchOptions->serverType = 'n1-standard-1'; $location = null; $locations = array_keys($platformObj->getLocations($this->environment)); while (count($locations) != 0) { $location = array_shift($locations); if (strstr($location, "us-")) { break; } } $launchOptions->cloudLocation = $locations[0]; $bundleType = SERVER_SNAPSHOT_CREATION_TYPE::GCE_STORAGE; break; } if ($advanced['servertype']) { $launchOptions->serverType = $advanced['servertype']; } if ($advanced['availzone']) { $launchOptions->availZone = $advanced['availzone']; } if ($advanced['region']) { $launchOptions->cloudLocation = $advanced['region']; } //Add Bundle task $creInfo = new ServerSnapshotCreateInfo($dbServer, $name, SERVER_REPLACEMENT_TYPE::NO_REPLACE); $bundleTask = BundleTask::Create($creInfo, true); if ($bundleType) { $bundleTask->bundleType = $bundleType; } $bundleTask->createdById = $this->user->id; $bundleTask->createdByEmail = $this->user->getEmail(); $bundleTask->osFamily = $os->family; $bundleTask->object = $createImage ? BundleTask::BUNDLETASK_OBJECT_IMAGE : BundleTask::BUNDLETASK_OBJECT_ROLE; $bundleTask->cloudLocation = $launchOptions->cloudLocation; $bundleTask->save(); $bundleTask->Log(sprintf("Launching temporary server (%s)", serialize($launchOptions))); $dbServer->SetProperty(SERVER_PROPERTIES::SZR_IMPORTING_BUNDLE_TASK_ID, $bundleTask->id); try { $platformObj->LaunchServer($dbServer, $launchOptions); $bundleTask->Log(_("Temporary server launched. Waiting for running state...")); } catch (Exception $e) { $bundleTask->SnapshotCreationFailed(sprintf(_("Unable to launch temporary server: %s"), $e->getMessage())); } $this->response->data(array('serverId' => $dbServer->serverId, 'bundleTaskId' => $bundleTask->id)); }
/** * Check if given name is used on scalr, account or environment scopes * * @param string $name Role's name to check * @param int $accountId Identifier of account * @param int $envId Identifier of environment * @param int $ignoreRoleId Role id to ignore * @return bool Returns TRUE if a such name has been already used on scalr or account (or environment) scopes */ public static function isNameUsed($name, $accountId, $envId, $ignoreRoleId = null) { $criteria = [['accountId' => null]]; if ($accountId) { if ($envId) { $criteria[] = ['$and' => [['accountId' => $accountId], ['envId' => null]]]; $criteria[] = ['envId' => $envId]; } else { $criteria[] = ['accountId' => $accountId]; } } $criteria = [['name' => $name], ['$or' => $criteria]]; if ($ignoreRoleId) { $criteria[] = ['id' => ['$ne' => $ignoreRoleId]]; } return !!Role::findOne($criteria); }
public function createTestFarmRole($farm) { /* @var $role Role */ $roles = Role::findByName('base-ubuntu1404'); if (empty($roles) || !count($roles)) { $this->markTestSkipped("Not found suitable role, required role - 'base-ubuntu1404'"); } else { $role = $roles->current(); } /* @var $farmRole FarmRole */ $farmRole = static::createEntity(new FarmRole(), ['farmId' => $farm->id, 'roleId' => $role->id, 'alias' => 'test-launch-farm-role', 'platform' => SERVER_PLATFORMS::EC2, 'cloudLocation' => static::TEST_REGION]); /* @var $settings SettingsCollection */ $settings = $farmRole->settings; $settings->saveSettings([FarmRoleSetting::AWS_INSTANCE_TYPE => 't1.micro', FarmRoleSetting::AWS_AVAIL_ZONE => '', FarmRoleSetting::SCALING_ENABLED => true, FarmRoleSetting::SCALING_MIN_INSTANCES => 1, FarmRoleSetting::SCALING_MAX_INSTANCES => 2]); $farmRole->save(); return $farmRole; }
/** * Creates new farm for testing purposes * * @param string $name Farm name * @param string[] $rolesNames Roles names * * @return Farm */ public function createTestFarm($name, array $rolesNames) { $user = $this->getUser(); /* @var $farm Farm */ $farm = static::createEntity(new Farm(), ['changedById' => $user->getId(), 'name' => "{$this->uuid}-{$name}-farm", 'comments' => "{$this->uuid}-description", 'envId' => $this->getEnvironment()->id, 'accountId' => $user->getAccountId(), 'ownerId' => $user->getId()]); foreach ($rolesNames as $roleName) { /* @var $role Role */ $role = Role::findOneByName($roleName); if (empty($role)) { $this->markTestSkipped("Not found suitable role, required role - 'base-ubuntu1404'"); } /* @var $farmRole FarmRole */ $farmRole = static::createEntity(new FarmRole(), ['farmId' => $farm->id, 'roleId' => $role->id, 'alias' => 'test-launch-farm-role', 'platform' => SERVER_PLATFORMS::EC2, 'cloudLocation' => static::TEST_REGION]); /* @var $settings SettingsCollection */ $settings = $farmRole->settings; $settings->saveSettings([FarmRoleSetting::INSTANCE_TYPE => 't1.micro', FarmRoleSetting::AWS_AVAIL_ZONE => '', FarmRoleSetting::SCALING_ENABLED => true, FarmRoleSetting::SCALING_MIN_INSTANCES => 1, FarmRoleSetting::SCALING_MAX_INSTANCES => 2]); } return $farm; }
/** * Gets role from database using User's Environment * * @param int $roleId The identifier of the Role * @param bool $restrictToCurrentScope optional Whether it should additionally check that role corresponds to current scope * * @throws ApiErrorException * @return \Scalr\Model\Entity\Role|null Returns Role entity on success or NULL otherwise */ public function getRole($roleId, $restrictToCurrentScope = false) { $criteria = $this->getDefaultCriteria(); $criteria[] = ['id' => $roleId]; $role = Entity\Role::findOne($criteria); /* @var $role Entity\Role */ if (!$role) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "The Role either does not exist or isn't in scope for the current Environment."); } //To be over-suspicious check READ access to Role object $this->checkPermissions($role); if ($restrictToCurrentScope && $role->getScope() !== $this->getScope()) { throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, "The Role is not either from the {$this->getScope()} scope or owned by your {$this->getScope()}."); } return $role; }
/** * @test */ public function testComplex() { $user = $this->getUser(); $environment = $this->getEnvironment(); $fictionController = new ApiController(); //foreach iterates through values in order of ads //we need to remove rules first, then - scripts //we initialize data set for removal with non-existing rule $this->ruleToDelete(-1); /* @var $roles Role[] */ $roles = $this->getTestRoles(); /* @var $role Role */ $role = array_shift($roles); /* @var $scalrRole Role */ $scalrRole = Role::findOne([['envId' => null, 'accountId' => null]]); /* @var $script Script */ $script = static::createEntity(new Script(), ['name' => 'test-role-scripts', 'description' => 'test-role-scripts', '']); $isWindows = $role->getOs()->family == 'windows'; /* @var $version ScriptVersion */ $version = static::createEntity(new ScriptVersion(), ['scriptId' => $script->id, 'version' => $script->getLatestVersion()->version + 1, 'content' => $isWindows ? '#!cmd' : '#!/bin/sh']); $script->os = $isWindows ? 'windows' : 'linux'; $script->save(); $scalrRoleScriptData = ['trigger' => ['type' => RoleScriptAdapter::TRIGGER_SINGLE_EVENT, 'event' => ['id' => 'HostInit']], 'target' => ['type' => RoleScriptAdapter::TARGET_TRIGGERING_FARM_ROLE], 'action' => ['actionType' => RoleScriptAdapter::ACTION_SCRIPT, 'scriptVersion' => ['script' => ['id' => $script->id], 'version' => $version->version]]]; $localRoleScriptData = ['trigger' => ['type' => RoleScriptAdapter::TRIGGER_ALL_EVENTS], 'target' => ['type' => RoleScriptAdapter::TARGET_NULL], 'action' => ['actionType' => RoleScriptAdapter::ACTION_URI, 'uri' => 'https://example.com']]; //post scalr rule $response = $this->postRule($role->id, $scalrRoleScriptData); $this->assertEquals(201, $response->status, $this->printResponseError($response)); $ruleId = $response->getBody()->data->id; /* @var $rule RoleScript */ $rule = RoleScript::findPk($ruleId); $this->assertNotEmpty($rule); $this->ruleToDelete($ruleId); $this->assertObjectEqualsEntity($scalrRoleScriptData, $rule); //post local rule $response = $this->postRule($role->id, $localRoleScriptData); $this->assertEquals(201, $response->status, $this->printResponseError($response)); $ruleId = $response->getBody()->data->id; /* @var $rule RoleScript */ $rule = RoleScript::findPk($ruleId); $this->assertNotEmpty($rule); $this->ruleToDelete($ruleId); $this->assertObjectEqualsEntity($localRoleScriptData, $rule); //post rule to environment-scoped role $response = $this->postRule($scalrRole->id, $scalrRoleScriptData); $this->assertErrorMessageContains($response, 403, ErrorMessage::ERR_PERMISSION_VIOLATION); //post rule already existing $data = $scalrRoleScriptData; $data['id'] = $ruleId; $response = $this->postRule($role->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 = $scalrRoleScriptData; $data['action']['scriptVersion']['script']['id'] = Script::findOne([], ['id' => true])->id + 1; $response = $this->postRule($role->id, $data); $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); //post rule with version that does not exists $data = $scalrRoleScriptData; $data['action']['scriptVersion']['version'] = Script::findPk($data['action']['scriptVersion']['script']['id'])->getLatestVersion()->version + 1; $response = $this->postRule($role->id, $data); $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); //post rule with properties that not existing $data = $scalrRoleScriptData; $data['foo'] = 'bar'; $response = $this->postRule($role->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //post rule without required fields $data = $localRoleScriptData; unset($data['action']); $response = $this->postRule($role->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //post rule with invalid field $data = $localRoleScriptData; $data['action'] = ''; $response = $this->postRule($role->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //fetch rule $response = $this->getRule($role->id, $rule->id); $this->assertEquals(200, $response->status, $this->printResponseError($response)); $this->assertObjectEqualsEntity($response->getBody()->data, $rule); //fetch rule that doe not exists $response = $this->getRule($role->id, RoleScript::findOne([], ['id' => ''])->id + 1); $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); //fetch rule with missmatch role id $response = $this->getRule(Role::findOne([], ['id' => ''])->id + 1, $rule->id); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE); //test have access to all listed rules $rules = $this->listRules($role->id); foreach ($rules as $rule) { $this->assertTrue(RoleScript::findPk($rule->id)->hasAccessPermissions($user)); } $listUri = static::getUserApiUrl("/scripts"); //test invalid filters $response = $this->request($listUri, Request::METHOD_GET, ['foo' => 'bar']); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //test invalid filters values $response = $this->request($listUri, Request::METHOD_GET, ['scope' => 'foobar']); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE); //delete script /* @var $rule RoleScript */ $rule = static::createEntity(new RoleScript(), ['roleId' => $role->id, 'scriptId' => $script->id]); $response = $this->deleteRule($role->id, $rule->id); $this->assertEquals(200, $response->status, $this->printResponseError($response)); //delete scalr-scoped script /* @var $rule RoleScript */ $rule = static::createEntity(new RoleScript(), ['roleId' => $scalrRole->id, 'scriptId' => $script->id, 'version' => -1]); $response = $this->deleteRule($scalrRole->id, $rule->id); $this->assertErrorMessageContains($response, 403, ErrorMessage::ERR_PERMISSION_VIOLATION); //delete script that does not exists $response = $this->deleteRule($role->id, RoleScript::findOne([], ['id' => ''])->id + 1); $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); }
/** * {@inheritdoc} * @see \Scalr\Api\DataType\ApiEntityAdapter::validateEntity() */ public function validateEntity($entity) { if (!$entity instanceof Entity\Image) { throw new \InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\Image class")); } if ($entity->hash !== null) { //Checks if the image does exist if (!Entity\Image::findPk($entity->hash)) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the Image with ID: %d", $entity->hash)); } } else { $image = Entity\Image::findOne([['id' => $entity->id], ['platform' => $entity->platform], ['cloudLocation' => (string) $entity->cloudLocation], ['$or' => [['accountId' => null], ['$and' => [['accountId' => $entity->accountId], ['$or' => [['envId' => null], ['envId' => $entity->envId]]]]]]]]); if ($image) { throw new ApiErrorException(409, ErrorMessage::ERR_UNICITY_VIOLATION, "This Image has already been registered in Scalr"); } } //Is this a new Image if (!$entity->hash) { $entity->createdByEmail = $this->controller->getUser()->email; $entity->createdById = $this->controller->getUser()->id; } if (!Entity\Role::isValidName($entity->name)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid name of the Image"); } if (empty($entity->architecture)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property 'architecture'"); } if (!$this->controller->hasPermissions($entity, true)) { //Checks entity level write access permissions throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions"); } //We only allow to either create or modify Environment Scope Roles if ($entity->getScope() !== $this->controller->getScope()) { throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, sprintf("Invalid scope")); } if (empty($entity->osId)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property 'os.id'"); } //Tries to find out the specified OS if (empty(Entity\Os::findPk($entity->osId))) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "OS with id '{$entity->osId}' not found."); } if (empty($entity->platform)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property platform"); } if (!isset(SERVER_PLATFORMS::GetList()[$entity->platform])) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Unexpected platform value"); } }
/** * @test */ public function testRolesFunctional() { $db = \Scalr::getDb(); $testName = str_replace('-', '', static::getTestName()); $roles = null; $uri = self::getUserApiUrl('/roles'); // test describe pagination $describe = $this->request(static::getUserApiUrl('/roles', 'invalidEnv'), Request::METHOD_GET); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_VALUE, 'Environment has not been provided with the request'); do { $query = []; if (isset($roles->pagination->next)) { $parts = parse_url($roles->pagination->next); parse_str($parts['query'], $query); } $describe = $this->request($uri, Request::METHOD_GET, $query); $this->assertDescribeResponseNotEmpty($describe); $this->assertNotEmpty($describe->getBody()); $roles = $describe->getBody(); foreach ($roles->data as $role) { $this->assertRolesObjectNotEmpty($role); if ($role->name == $testName) { $delete = $this->request($uri . '/' . $role->id, Request::METHOD_DELETE); $this->assertEquals(200, $delete->status); } } } while (!empty($roles->pagination->next)); // test create action $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => 'invalid']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid scope'); $create = $this->request($uri, Request::METHOD_POST); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Invalid body'); $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, [], ['id' => 'value']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid name'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => 'invalidName^$&&']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid name of the Role'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName, 'description' => 'invalidDesc<br/>']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid description'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Role category should be provided'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName, 'category' => ['id' => 'not int']]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid identifier of the category'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName, 'category' => ['id' => -1]]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'The Role category does not exist'); $rolesCat = RoleCategory::findOne(); /* @var $rolesCat RoleCategory */ $this->assertNotEmpty($rolesCat); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName, 'category' => ['id' => $rolesCat->id]]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'OS must be provided'); $os = Os::findOne([['status' => Os::STATUS_ACTIVE], ['family' => 'ubuntu'], ['generation' => '12.04']]); /* @var $os Os */ $this->assertNotEmpty($os); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName, 'category' => ['id' => $rolesCat->id], 'os' => ['id' => -1]]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid identifier of the OS'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName, 'category' => ['id' => $rolesCat->id], 'os' => ['id' => 'invalid']]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Specified OS does not exist'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName, 'description' => $testName, 'category' => $rolesCat->id, 'os' => $os->id]); $body = $create->getBody(); $this->assertEquals(201, $create->response->getStatus()); $this->assertFetchResponseNotEmpty($create); $this->assertRolesObjectNotEmpty($body->data); $this->assertNotEmpty($body->data->id); $this->assertEquals($testName, $body->data->name); $this->assertEquals($testName, $body->data->description); $this->assertEquals(ScopeInterface::SCOPE_ENVIRONMENT, $body->data->scope); $this->assertEquals($rolesCat->id, $body->data->category->id); $this->assertEquals($os->id, $body->data->os->id); // test images actions $roleId = $body->data->id; $imagesUri = $uri . '/' . $roleId . '/images'; $images = null; do { $query = []; if (isset($images->pagination->next)) { $parts = parse_url($images->pagination->next); parse_str($parts['query'], $query); } $describeImages = $this->request($imagesUri, Request::METHOD_GET, $query); $this->assertDescribeResponseNotEmpty($describeImages); $images = $describeImages->getBody(); foreach ($images->data as $imageRole) { $this->assertRoleImageObjectNotEmpty($imageRole); $this->assertEquals($roleId, $imageRole->role->id); $image = Image::findPk($imageRole->image->id); /* @var $image Image */ if ($image->name == $testName) { $delete = $this->request($imagesUri . '/' . $imageRole->image->id, Request::METHOD_DELETE); $this->assertEquals(200, $delete->status); } } } while (!empty($images->pagination->next)); $env = \Scalr_Environment::init()->loadById(static::$testEnvId); $platform = \SERVER_PLATFORMS::EC2; if (!$env->isPlatformEnabled($platform)) { $env->setPlatformConfig([$platform . '.is_enabled' => 1]); } $region = null; $cloudImageId = null; foreach (Aws::getCloudLocations() as $cloudLocation) { $cloudImageId = $this->getNewImageId($env, $cloudLocation); if (!empty($cloudImageId)) { $region = $cloudLocation; break; } } $this->assertNotNull($cloudImageId); $this->assertNotNull($cloudLocation); $createImage = $this->request(static::getUserApiUrl('/images'), Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT, 'name' => $testName, 'os' => ['id' => $os->id], 'cloudPlatform' => $platform, 'cloudLocation' => $region, 'cloudImageId' => $cloudImageId]); $createImageBody = $createImage->getBody(); $this->assertEquals(201, $createImage->response->getStatus()); $this->assertFetchResponseNotEmpty($createImage); $this->assertImageObjectNotEmpty($createImageBody->data); $this->assertNotEmpty($createImageBody->data->id); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId + 10], 'image' => ['id' => $createImageBody->data->id]]); $this->assertErrorMessageStatusEquals(400, $createRoleImage); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_INVALID_VALUE, $createRoleImage); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId]]); $this->assertErrorMessageStatusEquals(400, $createRoleImage); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_INVALID_STRUCTURE, $createRoleImage); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId], 'image' => ['id' => '11111111-1111-1111-1111-111111111111']]); $this->assertErrorMessageStatusEquals(404, $createRoleImage); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_INVALID_VALUE, $createRoleImage); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId], 'image' => ['id' => $createImageBody->data->id]]); $createRoleImageBody = $createRoleImage->getBody(); $this->assertEquals(201, $createRoleImage->response->getStatus()); $this->assertFetchResponseNotEmpty($createRoleImage); $this->assertRoleImageObjectNotEmpty($createRoleImageBody->data); $createRoleImageError = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId], 'image' => ['id' => $createImageBody->data->id]]); $this->assertErrorMessageStatusEquals(400, $createRoleImageError); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_BAD_REQUEST, $createRoleImageError); $fetchImage = $this->request($imagesUri . '/' . $createRoleImageBody->data->image->id, Request::METHOD_GET); $fetchImageBody = $fetchImage->getBody(); $this->assertEquals(200, $fetchImage->response->getStatus()); $this->assertFetchResponseNotEmpty($fetchImage); $this->assertImageObjectNotEmpty($fetchImageBody->data); $this->assertEquals($cloudImageId, $fetchImageBody->data->cloudImageId); $this->assertEquals($testName, $fetchImageBody->data->name); // test role images filtering $describeRoleImages = $this->request($imagesUri, Request::METHOD_GET, ['role' => $roleId]); $this->assertDescribeResponseNotEmpty($describeRoleImages); foreach ($describeRoleImages->getBody()->data as $data) { $this->assertRoleImageObjectNotEmpty($data); $this->assertEquals($roleId, $data->role->id); } $describeRoleImages = $this->request($imagesUri, Request::METHOD_GET, ['image' => $createImageBody->data->id]); $this->assertDescribeResponseNotEmpty($describeRoleImages); foreach ($describeRoleImages->getBody()->data as $data) { $this->assertRoleImageObjectNotEmpty($data); $this->assertEquals($createImageBody->data->id, $data->image->id); } $describeRoleImages = $this->request($imagesUri, Request::METHOD_GET, ['invalid' => 'value']); $this->assertErrorMessageContains($describeRoleImages, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Unsupported filter'); $currentRole = Role::findPk($roleId); /* @var $currentRole Role */ $this->assertNotEmpty($currentRole); $adminImages = Image::find([['envId' => null], ['status' => Image::STATUS_ACTIVE], ['cloudLocation' => $region]]); $this->assertNotEmpty($adminImages); $adminImage = null; foreach ($adminImages as $aImage) { /* @var $aImage Image */ $imageOs = $aImage->getOs(); if (!empty($imageOs) && $imageOs->generation == $currentRole->getOs()->generation && $imageOs->family == $currentRole->getOs()->family) { $adminImage = $aImage; break; } } /* @var $adminImage Image */ $this->assertNotEmpty($adminImage); $this->assertNotEquals($createRoleImageBody->data->image->id, $adminImage->hash); $replaceImage = $this->request($imagesUri . '/' . $createRoleImageBody->data->image->id . '/actions/replace', Request::METHOD_POST, [], ['role' => $roleId, 'image' => $adminImage->hash]); $replaceImageBody = $replaceImage->getBody(); $this->assertEquals(200, $replaceImage->response->getStatus()); $this->assertFetchResponseNotEmpty($replaceImage); $this->assertRoleImageObjectNotEmpty($replaceImageBody->data); $this->assertEquals($adminImage->hash, $replaceImageBody->data->image->id); $deleteImage = $this->request($imagesUri . '/' . $replaceImageBody->data->image->id, Request::METHOD_DELETE); $this->assertEquals(200, $deleteImage->response->getStatus()); $delete = $this->request(static::getUserApiUrl("images/{$createImageBody->data->id}"), Request::METHOD_DELETE); $this->assertEquals(200, $delete->response->getStatus()); // test get action $notFoundRoleId = 10 + $db->GetOne("SELECT MAX(r.id) FROM roles r"); $get = $this->request($uri . '/' . $notFoundRoleId, Request::METHOD_GET); $this->assertErrorMessageContains($get, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "The Role either does not exist or isn't in scope for the current Environment"); $get = $this->request($uri . '/' . $body->data->id, Request::METHOD_GET); $getBody = $get->getBody(); $this->assertEquals(200, $get->response->getStatus()); $this->assertFetchResponseNotEmpty($get); $this->assertRolesObjectNotEmpty($getBody->data); $this->assertEquals($body->data->id, $getBody->data->id); $this->assertEquals($testName, $getBody->data->name); $this->assertEquals($testName, $getBody->data->description); $this->assertEquals(ScopeInterface::SCOPE_ENVIRONMENT, $getBody->data->scope); $this->assertEquals($rolesCat->id, $getBody->data->category->id); $this->assertEquals($os->id, $getBody->data->os->id); // test filters $describe = $this->request($uri, Request::METHOD_GET, ['description' => $testName]); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Unsupported filter'); $describe = $this->request($uri, Request::METHOD_GET, ['scope' => 'wrong<br>']); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_VALUE, 'Unexpected scope value'); $describe = $this->request($uri, Request::METHOD_GET, ['scope' => ScopeInterface::SCOPE_SCALR]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); } $describe = $this->request($uri, Request::METHOD_GET, ['scope' => ScopeInterface::SCOPE_ENVIRONMENT]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals(ScopeInterface::SCOPE_ENVIRONMENT, $data->scope); } $describe = $this->request($uri, Request::METHOD_GET, ['name' => $testName]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals($testName, $data->name); } $describe = $this->request($uri, Request::METHOD_GET, ['id' => $roleId]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals($roleId, $data->id); } $describe = $this->request($uri, Request::METHOD_GET, ['os' => $os->id]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals($os->id, $data->os->id); } $describe = $this->request($uri, Request::METHOD_GET, ['os' => 'invalid*&^^%']); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_VALUE, "Invalid identifier of the OS"); $describe = $this->request($uri, Request::METHOD_GET, ['category' => $rolesCat->id]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals($rolesCat->id, $data->category->id); } $describe = $this->request($uri, Request::METHOD_GET, ['category' => '']); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_VALUE, "Invalid identifier of the category"); // test modify action $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Invalid body'); $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH, [], ['id' => 'some id']); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Identifier of the Role does not match identifier'); $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH, [], ['invalid' => 'err']); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'You are trying to set'); $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH, [], ['scope' => 'environment']); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'You are trying to set'); $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH, [], ['description' => '']); $modifyBody = $modify->getBody(); $this->assertEquals(200, $modify->response->getStatus()); $this->assertFetchResponseNotEmpty($modify); $this->assertRolesObjectNotEmpty($modifyBody->data); $this->assertEquals($body->data->id, $modifyBody->data->id); $this->assertEquals($testName, $modifyBody->data->name); $this->assertEquals('', $modifyBody->data->description); $this->assertEquals(ScopeInterface::SCOPE_ENVIRONMENT, $modifyBody->data->scope); $this->assertEquals($rolesCat->id, $modifyBody->data->category->id); $this->assertEquals($os->id, $modifyBody->data->os->id); // test delete action $delete = $this->request(static::getUserApiUrl("/roles/{$body->data->id}", 0), Request::METHOD_DELETE); $this->assertErrorMessageContains($delete, 400, ErrorMessage::ERR_INVALID_VALUE, 'Environment has not been provided'); $delete = $this->request(static::getUserApiUrl("/roles/{$body->data->id}", static::$testEnvId + 1), Request::METHOD_DELETE); $this->assertErrorMessageContains($delete, 403, ErrorMessage::ERR_OBJECT_NOT_FOUND, 'Invalid environment'); $delete = $this->request(static::getUserApiUrl("/roles/{$notFoundRoleId}"), Request::METHOD_DELETE); $this->assertErrorMessageContains($delete, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "The Role either does not exist or isn't in scope for the current Environment"); $delete = $this->request($uri . '/' . $body->data->id, Request::METHOD_DELETE); $this->assertEquals(200, $delete->status); $db->Execute("INSERT INTO roles SET\n name = ?,\n dtadded = NOW(),\n env_id\t = NULL,\n client_id = NULL\n ", [$testName]); $insertedId = $db->_insertid(); $delete = $this->request($uri . '/' . $insertedId, Request::METHOD_DELETE); $db->Execute("DELETE FROM roles WHERE name = ? AND id = ?", [$testName, $insertedId]); $this->assertErrorMessageContains($delete, 403, ErrorMessage::ERR_SCOPE_VIOLATION, 'is not either from the Environment scope or owned'); }
/** * Move role to account scope * * @param int $id ID of Role * @throws Exception */ public function xPromoteAction($id) { throw new \Scalr\Exception\NotYetImplementedException('Not implemented yet'); $this->request->restrictAccess(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE); $this->request->restrictAccess(Acl::RESOURCE_ROLES_ACCOUNT, Acl::PERM_ROLES_ACCOUNT_MANAGE); /* @var $role Role */ if (!$id || !($role = Role::findPk($id))) { throw new Exception('Role not found'); } $role->envId = null; $role->save(); // Invar: move all images to account scope $this->response->data(['role' => $this->getInfo($role->id, true)]); }
/** * @param int $roleId * @param string $name * @param string $description * @param string $osId * @param int $catId * @param bool $isQuickStart * @param bool $isDeprecated * @param JsonData $behaviors * @param JsonData $images * @param JsonData $scripts * @param JsonData $variables * @param JsonData $chef * @param JsonData $environments * @throws Exception * @throws Scalr_Exception_Core * @throws Scalr_Exception_InsufficientPermissions */ public function xSaveAction($roleId = 0, $name, $description, $osId, $catId, $isQuickStart = false, $isDeprecated = false, JsonData $behaviors, JsonData $images, JsonData $scripts, JsonData $variables, JsonData $chef, JsonData $environments) { $this->restrictAccess('ROLES', 'MANAGE'); if ($roleId == 0) { $accountId = $this->user->getAccountId() ?: NULL; if (!Role::isValidName($name)) { throw new Exception(_("Role name is incorrect")); } if (Role::isNameUsed($name, $accountId, $this->getEnvironmentId(true))) { throw new Exception('Selected role name is already used. Please select another one.'); } if (!Os::findPk($osId)) { throw new Exception(sprintf('%s is not valid osId', $osId)); } $role = new Role(); $role->generation = 2; $role->origin = $this->user->isScalrAdmin() ? ROLE_TYPE::SHARED : ROLE_TYPE::CUSTOM; $role->accountId = $accountId; $role->envId = $this->getEnvironmentId(true); $role->name = $name; $role->catId = $catId; $role->osId = $osId; $role->addedByUserId = $this->user->getId(); $role->addedByEmail = $this->user->getEmail(); $role->setBehaviors((array) $behaviors); $role->save(); } else { $role = Role::findPk($roleId); if (!$role) { throw new Scalr_Exception_Core(sprintf(_("Role ID#%s not found in database"), $roleId)); } $this->checkPermissions($role, true); } $globalVariables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(true), ScopeInterface::SCOPE_ROLE); $globalVariables->setValues($variables, $role->id); foreach (RoleProperty::find([['roleId' => $role->id], ['name' => ['$like' => ['chef.%']]]]) as $prop) { $prop->delete(); } foreach ($chef as $name => $value) { $prop = new RoleProperty(); $prop->roleId = $role->id; $prop->name = $name; $prop->value = $value; $prop->save(); } $role->description = $description; $role->isQuickStart = $isQuickStart; $role->isDeprecated = $isDeprecated; foreach ($images as $i) { if (isset($i['platform']) && isset($i['cloudLocation']) && isset($i['imageId'])) { $role->setImage($i['platform'], $i['cloudLocation'], $i['imageId'], $this->user->getId(), $this->user->getEmail()); } } $role->setScripts((array) $scripts); $role->save(); if ($this->request->getScope() == ScopeInterface::SCOPE_ACCOUNT) { foreach (RoleEnvironment::find([['roleId' => $roleId]]) as $re) { $re->delete(); } $accountEnvironments = []; $allowedEnvironments = []; foreach (Environment::find([['accountId' => $this->user->getAccountId()]]) as $env) { $accountEnvironments[] = $env->id; } foreach ($environments as $e) { if ($e['enabled'] == 1 && in_array($e['id'], $accountEnvironments)) { $allowedEnvironments[] = $e['id']; } } if (count($allowedEnvironments) < count($accountEnvironments)) { foreach ($allowedEnvironments as $id) { $re = new RoleEnvironment(); $re->roleId = $role->id; $re->envId = $id; $re->save(); } } } $this->response->data(['role' => $this->getInfo($role->id, true)]); $this->response->success('Role saved'); }
/** * {@inheritdoc} * @see \Scalr\Api\DataType\ApiEntityAdapter::validateEntity() */ public function validateEntity($entity) { if (!$entity instanceof Entity\Image) { throw new \InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\Image class")); } if ($entity->hash !== null) { //Checks if the image does exist if (!Entity\Image::findPk($entity->hash)) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the Image with ID: %d", $entity->hash)); } } else { $image = Entity\Image::findOne([['id' => $entity->id], ['$or' => [['envId' => $entity->envId], ['envId' => null]]], ['platform' => $entity->platform], ['cloudLocation' => $entity->cloudLocation]]); if ($image) { throw new ApiErrorException(409, ErrorMessage::ERR_UNICITY_VIOLATION, "This Image has already been registered in Scalr"); } } //Is this a new Image if (!$entity->hash) { $entity->createdByEmail = $this->controller->getUser()->email; $entity->createdById = $this->controller->getUser()->id; } if (!Entity\Role::validateName($entity->name)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid name of the Image"); } $entity->architecture = $entity->architecture ?: 'x86_64'; if (!in_array($entity->architecture, ['i386', 'x86_64'])) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid architecture of the Image."); } if (!$this->controller->hasPermissions($entity, true)) { //Checks entity level write access permissions throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions"); } //We only allow to either create or modify Environment Scope Roles if ($entity->getScope() !== ScopeInterface::SCOPE_ENVIRONMENT) { throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, sprintf("Only %s scope is allowed.", ScopeInterface::SCOPE_ENVIRONMENT)); } //Validates OS if (!empty($entity->osId)) { //Tries to find out the specified OS $os = Entity\Os::findPk($entity->osId); if (!$os instanceof Entity\Os) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Specified OS does not exist"); } } else { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "OS must be provided with the request."); } }
/** * @param int $roleId */ public function xGetRoleChefSettingsAction($roleId) { /* @var $role Role */ $role = Role::findPk($roleId); if (!$role) { $this->response->failure('Role not found'); return; } $this->checkPermissions($role); $properties = []; foreach (RoleProperty::find([['roleId' => $role->id], ['name' => ['$like' => 'chef.%']]]) as $prop) { /* @var $prop RoleProperty */ $properties[$prop->name] = $prop->value; } $this->response->data(['chef' => $properties]); }
/** * @param $id * @param $platform * @param $cloudLocation * @param $name */ public function xUpdateNameAction($id, $platform, $cloudLocation, $name) { $this->request->restrictAccess(Acl::RESOURCE_FARMS_IMAGES, Acl::PERM_FARMS_IMAGES_MANAGE); if (!\Scalr\Model\Entity\Role::validateName($name)) { $this->response->failure('Invalid name for image'); return; } /* @var $image Image */ $image = Image::findOne([['id' => $id], ['envId' => $this->getEnvironmentId(true)], ['platform' => $platform], ['cloudLocation' => $cloudLocation]]); if (!$image) { $this->response->failure('Image not found'); return; } $image->name = $name; $image->save(); $this->response->data(['name' => $name]); $this->response->success('Image\'s name was updated'); }
protected function run8($stage) { $knownOses = []; //Retrieves the list of all known OSes foreach (Entity\Os::all() as $os) { /* @var $os Entity\Os */ $knownOses[$os->id] = $os; } $role = new Entity\Role(); //Trying to clarify the operating system of the Roles using Images which are associated with them. //If all Images have the same operating system it will be considered as acceptable for the Role at latter will be updated. $rs = $this->db->Execute("\n SELECT " . $role->fields('r', true) . ", GROUP_CONCAT(t.os_id) `osids`\n FROM roles r JOIN (\n SELECT DISTINCT ri.role_id, i.os_id\n FROM images i\n JOIN role_images ri ON i.id = ri.image_id\n AND i.platform = ri.platform\n AND i.cloud_location = ri.cloud_location\n ) t ON t.role_id = r.id\n WHERE r.os_id = ?\n GROUP BY r.id\n HAVING osids != r.os_id\n ", ['unknown-os']); if ($rs->RecordCount()) { $this->console->out("Found %d Roles the OS value of which can be filled from the Images. Updating...", $rs->RecordCount()); } while ($row = $rs->FetchRow()) { $role = new Entity\Role(); $role->load($row, 'r'); if (!empty($row['osids'])) { if (isset($knownOses[$row['osids']])) { //Updating OS value of the Role $role->osId = $row['osids']; $role->save(); } else { $this->console->warning("Role %s (%d) is associated with the Images with either different or unknown OS: %s", $role->name, $role->id, $row['osids']); } } } $image = new Entity\Image(); //Trying to clarify the operating sytem of the Images using Roles which are associated with them. $rs = $this->db->Execute("\n SELECT " . $image->fields('i', true) . ", GROUP_CONCAT(t.os_id) `osids`\n FROM images i JOIN (\n SELECT DISTINCT ri.image_id, ri.platform, ri.cloud_location, r.os_id\n FROM roles r\n JOIN role_images ri ON ri.role_id = r.id\n ) t ON t.image_id = i.id AND t.platform = i.platform AND t.cloud_location = i.cloud_location\n WHERE i.os_id = ?\n GROUP BY i.hash\n HAVING osids != i.os_id\n ", ['unknown-os']); if ($rs->RecordCount()) { $this->console->out("Found %d Images the OS value of which can be filled from the Roles. Updating...", $rs->RecordCount()); } while ($row = $rs->FetchRow()) { $image = new Entity\Image(); $image->load($row, 'i'); if (!empty($row['osids'])) { if (isset($knownOses[$row['osids']])) { //Updating OS value of the Image $image->osId = $row['osids']; $image->save(); } else { $this->console->warning("Image (%s) imageId: %s, platform: %s, cloudLocation: %s is associated with the Roles with either different or unknown OS: %s", $image->hash, $image->id, $image->platform, $image->cloudLocation, $row['osids']); } } } }
/** * @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; }
/** * @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; }
public function ServerImageCreate($ServerID, $RoleName) { $this->restrictAccess(Acl::RESOURCE_IMAGES_ENVIRONMENT, Acl::PERM_IMAGES_ENVIRONMENT_MANAGE); $this->restrictAccess(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE); $DBServer = DBServer::LoadByID($ServerID); // Validate client and server if ($DBServer->envId != $this->Environment->id) { throw new Exception(sprintf("Server ID #%s not found", $ServerID)); } $this->user->getPermissions()->validate($DBServer); //Check for already running bundle on selected instance $chk = $this->DB->GetOne("SELECT id FROM bundle_tasks WHERE server_id=? AND status NOT IN ('success', 'failed') LIMIT 1", array($ServerID)); if ($chk) { throw new Exception(sprintf(_("Server '%s' is already synchonizing."), $ServerID)); } if (!Role::isValidName($RoleName)) { throw new Exception(_("Role name is incorrect")); } if (Role::isNameUsed($RoleName, $this->user->getAccountId(), $this->Environment->id)) { throw new Exception("Specified role name is already used by another role"); } if ($btId = BundleTask::getActiveTaskIdByName($RoleName, $this->user->getAccountId(), $this->Environment->id)) { throw new Exception(sprintf("Specified role name is already reserved for BundleTask with ID: %d.", $btId)); } $ServerSnapshotCreateInfo = new ServerSnapshotCreateInfo($DBServer, $RoleName, SERVER_REPLACEMENT_TYPE::NO_REPLACE, BundleTask::BUNDLETASK_OBJECT_ROLE, 'Bundled via API'); $BundleTask = BundleTask::Create($ServerSnapshotCreateInfo); $BundleTask->createdById = $this->user->id; $BundleTask->createdByEmail = $this->user->getEmail(); $BundleTask->save(); $response = $this->CreateInitialResponse(); $response->BundleTaskID = $BundleTask->id; return $response; }
/** * @param string $serverId * @param string $name * @param string $description * @param bool $createRole * @param string $scope * @param string $replaceRole * @param bool $replaceImage * @param int $rootVolumeSize * @param string $rootVolumeType * @param int $rootVolumeIops * @throws Exception */ public function xServerCreateSnapshotAction($serverId, $name = '', $description = '', $createRole = false, $scope = '', $replaceRole = '', $replaceImage = false, $rootVolumeSize = 0, $rootVolumeType = '', $rootVolumeIops = 0) { $this->request->restrictAccess(Acl::RESOURCE_IMAGES_ENVIRONMENT, Acl::PERM_IMAGES_ENVIRONMENT_MANAGE); $server = $this->getServerEntity($serverId); $this->request->checkPermissions($server, true); $farm = $server->getFarm(); $role = $server->getFarmRole()->getRole(); //Check for already running bundle on selected instance if ($this->db->GetOne("SELECT id FROM bundle_tasks WHERE server_id=? AND status NOT IN ('success', 'failed') LIMIT 1", array($server->serverId))) { throw new Exception(sprintf(_("Server '%s' is already synchonizing."), $server->serverId)); } $validator = new Validator(); $validator->addErrorIf(!Entity\Role::isValidName($name), 'name', "Role name is incorrect"); $validator->addErrorIf(!in_array($replaceRole, ['farm', 'all', '']), 'replaceRole', 'Invalid value'); $object = $createRole ? BundleTask::BUNDLETASK_OBJECT_ROLE : BundleTask::BUNDLETASK_OBJECT_IMAGE; $replaceType = SERVER_REPLACEMENT_TYPE::NO_REPLACE; $createScope = ScopeInterface::SCOPE_ENVIRONMENT; if ($createRole) { $this->request->restrictAccess(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE); if ($replaceRole == 'farm') { if ($farm->hasAccessPermissions($this->getUser(), $this->getEnvironment(), Acl::PERM_FARMS_UPDATE)) { $replaceType = SERVER_REPLACEMENT_TYPE::REPLACE_FARM; } else { $validator->addError('replaceRole', "You don't have permissions to update farm"); } } else { if ($replaceRole == 'all') { if ($this->request->isAllowed([Acl::RESOURCE_FARMS, Acl::RESOURCE_TEAM_FARMS, Acl::RESOURCE_OWN_FARMS], Acl::PERM_FARMS_UPDATE)) { $replaceType = SERVER_REPLACEMENT_TYPE::REPLACE_ALL; } else { $validator->addError('replaceRole', "You don't have permissions to update farms"); } } } /* @var $existRole Entity\Role */ $existRole = Entity\Role::findOne([['name' => $name], ['$or' => [['accountId' => null], ['$and' => [['accountId' => $this->getUser()->accountId], ['$or' => [['envId' => null], ['envId' => $this->getEnvironment()->id]]]]]]]]); if ($existRole) { if (empty($existRole->accountId)) { $validator->addError('name', _("Selected role name is reserved and cannot be used for custom role")); } else { if ($replaceType != SERVER_REPLACEMENT_TYPE::REPLACE_ALL) { $validator->addError('name', _("Specified role name is already used by another role. You can use this role name only if you will replace old one on ALL your farms.")); } else { if ($replaceType == SERVER_REPLACEMENT_TYPE::REPLACE_ALL && $existRole->id != $role->id) { $validator->addError('name', _("Specified role name is already in use. You cannot replace a Role different from the one you are currently snapshotting.")); } } } } if ($btId = BundleTask::getActiveTaskIdByName($name, $this->getUser()->accountId, $this->getEnvironment()->id)) { $validator->addError('name', sprintf("Specified role name is already reserved for BundleTask with ID: %d.", $btId)); } if ($replaceType != SERVER_REPLACEMENT_TYPE::NO_REPLACE) { $chk = BundleTask::getActiveTaskIdByRoleId($role->id, $this->getEnvironment()->id, BundleTask::BUNDLETASK_OBJECT_ROLE); $validator->addErrorIf($chk, 'replaceRole', sprintf("Role is already synchronizing in BundleTask: %d.", $chk)); } } else { $sc = $role->getScope(); if ($replaceImage) { if ($sc == ScopeInterface::SCOPE_ENVIRONMENT && $this->request->isAllowed(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE) || $sc == ScopeInterface::SCOPE_ACCOUNT && $this->request->isAllowed(Acl::RESOURCE_ROLES_ACCOUNT, Acl::PERM_ROLES_ACCOUNT_MANAGE)) { $replaceType = SERVER_REPLACEMENT_TYPE::REPLACE_ALL; $chk = BundleTask::getActiveTaskIdByRoleId($role->id, $this->getEnvironment()->id, BundleTask::BUNDLETASK_OBJECT_IMAGE); $validator->addErrorIf($chk, 'replaceImage', sprintf("Role is already synchronizing in BundleTask: %d.", $chk)); } else { $validator->addError('replaceImage', "You don't have permissions to replace image in role"); } } } if ($scope && ($createRole || $scope != $createScope)) { if ($createRole) { $c = $scope == ScopeInterface::SCOPE_ENVIRONMENT && $this->request->isAllowed(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE) || $scope == ScopeInterface::SCOPE_ACCOUNT && $this->request->isAllowed(Acl::RESOURCE_ROLES_ACCOUNT, Acl::PERM_ROLES_ACCOUNT_MANAGE); $validator->addErrorIf(!$c, 'scope', sprintf("You don't have permissions to create role in scope %s", $scope)); } $c = $scope == ScopeInterface::SCOPE_ENVIRONMENT && $this->request->isAllowed(Acl::RESOURCE_IMAGES_ENVIRONMENT, Acl::PERM_IMAGES_ENVIRONMENT_MANAGE) || $scope == ScopeInterface::SCOPE_ACCOUNT && $this->request->isAllowed(Acl::RESOURCE_IMAGES_ACCOUNT, Acl::PERM_IMAGES_ACCOUNT_MANAGE); $validator->addErrorIf(!$c, 'scope', sprintf("You don't have permissions to create image in scope %s", $scope)); $createScope = $scope; } $image = $role->getImage($server->platform, $server->cloudLocation)->getImage(); $rootBlockDevice = []; if ($server->platform == SERVER_PLATFORMS::EC2 && ($server->isVersionSupported('0.7') && $server->os == 'linux' || $image->isEc2HvmImage())) { if ($rootVolumeSize > 0) { $rootBlockDevice['size'] = $rootVolumeSize; } if (in_array($rootVolumeType, [CreateVolumeRequestData::VOLUME_TYPE_STANDARD, CreateVolumeRequestData::VOLUME_TYPE_GP2, CreateVolumeRequestData::VOLUME_TYPE_IO1, CreateVolumeRequestData::VOLUME_TYPE_SC1, CreateVolumeRequestData::VOLUME_TYPE_ST1])) { $rootBlockDevice['volume_type'] = $rootVolumeType; if ($rootVolumeType == CreateVolumeRequestData::VOLUME_TYPE_IO1 && $rootVolumeIops > 0) { $rootBlockDevice['iops'] = $rootVolumeIops; } } } if (!$validator->isValid($this->response)) { return; } $ServerSnapshotCreateInfo = new ServerSnapshotCreateInfo(DBServer::LoadByID($server->serverId), $name, $replaceType, $object, $description, $rootBlockDevice); $BundleTask = BundleTask::Create($ServerSnapshotCreateInfo); $BundleTask->createdById = $this->user->id; $BundleTask->createdByEmail = $this->user->getEmail(); $BundleTask->osId = $role->osId; $BundleTask->objectScope = $createScope; if ($role->getOs()->family == 'windows') { $BundleTask->osFamily = $role->getOs()->family; $BundleTask->osVersion = $role->getOs()->generation; $BundleTask->osName = ''; } else { $BundleTask->osFamily = $role->getOs()->family; $BundleTask->osVersion = $role->getOs()->version; $BundleTask->osName = $role->getOs()->name; } if (in_array($role->getOs()->family, array('redhat', 'oel', 'scientific')) && $server->platform == SERVER_PLATFORMS::EC2) { $BundleTask->bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } $BundleTask->save(); $this->response->data(['bundleTaskId' => $BundleTask->id]); $this->response->success("Bundle task successfully created."); }
/** * @return \Scalr\Model\Entity\Role * @throws Exception */ public function __getNewRoleObject() { if (!$this->__newRoleObject) { if ($this->id) { $this->__newRoleObject = Role::findPk($this->id); } if (!$this->__newRoleObject) { throw new Exception('Role object is not found'); } } return $this->__newRoleObject; }
/** * @test * @functional */ public function testRoleGlobalVariables() { $db = \Scalr::getDb(); $testName = str_replace('-', '', $this->getTestName()); $role = Role::findOne([['envId' => static::$testEnvId]]); /* @var $role Role */ $roleId = $role->id; $uri = static::getUserApiUrl("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_ROLE) { $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(r.id) FROM roles r"); $describe = $this->request(static::getUserApiUrl("/roles/{$notFoundRoleId}/global-variables"), Request::METHOD_GET); $this->assertErrorMessageContains($describe, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "The Role either does not exist or isn't in scope for the current Environment"); $adminRole = Role::findOne([['envId' => null]]); /* @var $adminRole Role */ $this->assertInstanceOf("Scalr\\Model\\Entity\\Role", $adminRole); $notAccessibleId = $adminRole->id; $this->assertNotEmpty($notAccessibleId); $describe = $this->request(self::getUserApiUrl("/roles/{$notAccessibleId}/global-variables"), Request::METHOD_GET); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_SCOPE_VIOLATION, $describe); $this->assertErrorMessageStatusEquals(403, $describe); $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'); $create = $this->request($uri, Request::METHOD_POST, [], ['name' => 'scalr_test']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'prefix is reserved and cannot be used'); //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 ScopeInterface::getScope() */ public function getScope() { /* @var $role Role */ $role = Role::findPk($this->roleId); return $role->getScope(); }
/** * Get Role entity * * @return Role|null */ public function getRole() { if (!empty($this->roleId)) { if (empty($this->_role) || $this->_role->id != $this->roleId) { $this->_role = Role::findPk($this->roleId); } } return $this->_role; }
/** * @param string $platform * @param string $cloudLocation * @param string $cloudServerId * @param string $name * @param bool $createImage * @throws Exception */ public function xInitiateImportAction($platform, $cloudLocation, $cloudServerId, $name, $createImage = false) { if (!Role::isValidName($name)) { throw new Exception(_("Name is incorrect")); } if (!$createImage) { $this->request->restrictAccess(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE); } if (!$createImage && Role::isNameUsed($name, $this->user->getAccountId(), $this->getEnvironmentId())) { throw new Exception('Selected role name is already used. Please select another one.'); } $cryptoKey = Scalr::GenerateRandomKey(40); $creInfo = new ServerCreateInfo($platform, null, 0, 0); $creInfo->clientId = $this->user->getAccountId(); $creInfo->envId = $this->getEnvironmentId(); $creInfo->farmId = 0; $creInfo->SetProperties(array(SERVER_PROPERTIES::SZR_IMPORTING_ROLE_NAME => $name, SERVER_PROPERTIES::SZR_IMPORTING_OBJECT => $createImage ? BundleTask::BUNDLETASK_OBJECT_IMAGE : BundleTask::BUNDLETASK_OBJECT_ROLE, SERVER_PROPERTIES::SZR_KEY => $cryptoKey, SERVER_PROPERTIES::SZR_KEY_TYPE => SZR_KEY_TYPE::PERMANENT, SERVER_PROPERTIES::SZR_VESION => "0.14.0", SERVER_PROPERTIES::SZR_IMPORTING_VERSION => 2, SERVER_PROPERTIES::SZR_IMPORTING_STEP => 1, SERVER_PROPERTIES::LAUNCHED_BY_ID => $this->user->id, SERVER_PROPERTIES::LAUNCHED_BY_EMAIL => $this->user->getEmail())); $platformObj = PlatformFactory::NewPlatform($platform); $availZone = null; $osType = ''; if ($platform == SERVER_PLATFORMS::EC2) { $client = $this->environment->aws($cloudLocation)->ec2; $r = $client->instance->describe($cloudServerId); $instance = $r->get(0)->instancesSet->get(0); $availZone = $instance->placement->availabilityZone; $osType = $instance->platform == 'windows' ? 'windows' : 'linux'; $creInfo->SetProperties(array(EC2_SERVER_PROPERTIES::REGION => $cloudLocation, EC2_SERVER_PROPERTIES::INSTANCE_ID => $cloudServerId, EC2_SERVER_PROPERTIES::AMIID => $instance->imageId, EC2_SERVER_PROPERTIES::AVAIL_ZONE => $instance->placement->availabilityZone)); } else { if ($platform == SERVER_PLATFORMS::GCE) { $gce = $platformObj->getClient($this->environment); $result = $gce->instances->get($this->environment->keychain(SERVER_PLATFORMS::GCE)->properties[CloudCredentialsProperty::GCE_PROJECT_ID], $cloudLocation, $cloudServerId); $creInfo->SetProperties(array(GCE_SERVER_PROPERTIES::SERVER_NAME => $cloudServerId, GCE_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation)); } else { if ($platform == SERVER_PLATFORMS::AZURE) { //$this->getEnvironment()->azure()->compute->virtualMachine->getInstanceViewInfo() // $r->properties->osProfile->linuxConfiguration != NULL } else { if (PlatformFactory::isOpenstack($platform)) { $creInfo->SetProperties(array(OPENSTACK_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation, OPENSTACK_SERVER_PROPERTIES::SERVER_ID => $cloudServerId)); } else { if (PlatformFactory::isCloudstack($platform)) { $creInfo->SetProperties(array(CLOUDSTACK_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation, CLOUDSTACK_SERVER_PROPERTIES::SERVER_ID => $cloudServerId)); } } } } } $dbServer = DBServer::Create($creInfo, true); $dbServer->osType = $osType; $ips = $platformObj->GetServerIPAddresses($dbServer); $dbServer->localIp = $ips['localIp']; $dbServer->remoteIp = $ips['remoteIp']; $dbServer->cloudLocation = $cloudLocation; if ($platform == SERVER_PLATFORMS::GCE) { $dbServer->cloudLocationZone = $cloudLocation; } else { $dbServer->cloudLocationZone = $availZone; } $dbServer->Save(); $this->response->data(array('command' => $this->getSzrCmd($dbServer), 'installCommand' => $this->getInstallCmd($dbServer), 'osType' => $dbServer->osType, 'serverId' => $dbServer->serverId)); }
public function __get($name) { switch ($name) { case 'settings': if (empty($this->_settings)) { $this->_settings = new SettingsCollection('Scalr\\Model\\Entity\\FarmRoleSetting', [['farmRoleId' => &$this->id]], ['farmRoleId' => &$this->id]); } return $this->_settings; case 'farm': if (empty($this->_farm) && !empty($this->farmId)) { $this->_farm = Farm::findPk($this->farmId); } return $this->_farm; case 'role': if (empty($this->_role) && !empty($this->roleId)) { $this->_role = Role::findPk($this->roleId); } return $this->_role; default: return parent::__get($name); } }
/** * {@inheritdoc} * @see \Scalr\Api\DataType\ApiEntityAdapter::validateEntity() */ public function validateEntity($entity) { if (!$entity instanceof Entity\Role) { throw new \InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\Role class")); } if ($entity->id !== null) { if (!is_integer($entity->id)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid value of the identifier"); } //Checks if the role does exist if (!Entity\Role::findPk($entity->id)) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the Role with ID: %d", $entity->id)); } } //Is this a new Role if (!$entity->id) { $entity->addedByEmail = $this->controller->getUser()->email; $entity->addedByUserId = $this->controller->getUser()->id; } if (!$entity::isValidName($entity->name)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid name of the Role"); } $entity->description = $entity->description ?: ''; $this->validateString($entity->description, 'Invalid description'); if (!$this->controller->hasPermissions($entity, true)) { //Checks entity level write access permissions throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions"); } //We only allow to either create or modify Environment Scope Roles if ($entity->getScope() !== $this->controller->getScope()) { throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, sprintf("Invalid scope")); } //Checks the Role Category if (!empty($entity->catId)) { //Tries to find out the specified Role category $category = Entity\RoleCategory::findPk($entity->catId); if ($category instanceof Entity\RoleCategory) { //Checks if the specified RoleCategory either shared or belongs to User's scope. if ($category->getScope() !== ScopeInterface::SCOPE_SCALR && $category->envId !== $this->controller->getEnvironment()->id) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "The specified category isn't owned by your environment."); } } else { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "The Role category does not exist"); } } else { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Role category should be provided with the request."); } if (empty($entity->osId)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property 'os.id'"); } //Tries to find out the specified OS if (empty(Entity\Os::findPk($entity->osId))) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "OS with id '{$entity->osId}' not found."); } }
/** * @param string $hash * @param string $name */ public function xUpdateNameAction($hash, $name) { $this->restrictAccess('IMAGES', 'MANAGE'); if (!\Scalr\Model\Entity\Role::isValidName($name)) { $this->response->failure('Invalid name for image'); return; } /* @var $image Image */ $image = Image::findPk($hash); if (!$image) { $this->response->failure('Image not found'); return; } $this->checkPermissions($image, true); $image->name = $name; $image->save(); $this->response->data(['name' => $name]); $this->response->success('Image\'s name was updated'); }
/** * @test * @functional */ public function testComplex() { $user = $this->getUser(); $environment = $this->getEnvironment(); $fictionController = new ApiController(); /* @var $farm Farm */ $farm = static::createEntity(new Farm(), ['changedById' => $user->getId(), 'name' => "{$this->uuid}-farm", 'comments' => "{$this->uuid}-description", 'envId' => $environment->id, 'accountId' => $user->getAccountId(), 'ownerId' => $user->getId()]); /* @var $roles EntityIterator */ /* @var $role Role */ $roles = Role::findByName('base-ubuntu1404'); if (empty($roles) || !count($roles)) { $this->markTestSkipped("Not found suitable role, required role - 'base-ubuntu1404'"); } else { $role = $roles->current(); } //test Governance $this->getGovernance(); /* @var $vpcList VpcList */ $vpcList = \Scalr::getContainer()->aws(self::TEST_REGION, $this->getEnvironment())->ec2->vpc->describe(self::TEST_VPC_ID); /* @var $vpc VpcData */ $vpc = $vpcList->current(); /* @var $subnetList SubnetList */ $subnetList = \Scalr::getContainer()->aws(self::TEST_REGION, $this->getEnvironment())->ec2->subnet->describe(null, [['name' => SubnetFilterNameType::vpcId(), 'value' => $vpc->vpcId]]); /* @var $subnet SubnetData */ $subnet = $subnetList->current(); //setup test governance $vpcId = $vpc->vpcId; $subnetId = $subnet->subnetId; $governanceConfiguration = [SERVER_PLATFORMS::EC2 => [Scalr_Governance::INSTANCE_TYPE => ['enabled' => true, 'limits' => ['value' => ['t1.micro', 't2.small', 't2.medium', 't2.large'], 'default' => ['t2.small']]], Scalr_Governance::AWS_VPC => ['enabled' => true, 'limits' => ['regions' => [self::TEST_REGION => ['default' => true, 'ids' => [$vpcId]]], 'ids' => [$vpcId => [$subnetId]]]]]]; $this->setupGovernanceConfiguration($governanceConfiguration); //farm role data $data = ['role' => ['id' => $role->id], 'alias' => 't-ps', 'platform' => SERVER_PLATFORMS::EC2, 'placement' => ['placementConfigurationType' => FarmRoles::AWS_CLASSIC_PLACEMENT_CONFIGURATION, 'region' => static::TEST_REGION], 'scaling' => ['enabled' => true, 'minInstances' => 2, 'maxInstances' => 3], 'instance' => ['instanceConfigurationType' => FarmRoles::AWS_INSTANCE_CONFIGURATION, 'instanceType' => ['id' => 't1.micro']]]; //create farmRole with wrong instance type $data['instance']['instanceType']['id'] = 'm1.small'; $response = $this->postFarmRole($farm->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE); //Add AWS VPC settings $farm->settings[FarmSetting::EC2_VPC_ID] = $vpc->vpcId; $farm->settings[FarmSetting::EC2_VPC_REGION] = self::TEST_REGION; $farm->save(); //create farm role with AwsClassicPlacementConfiguration $data['instance']['instanceType']['id'] = 't2.small'; $response = $this->postFarmRole($farm->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE); //create farm role with incorrect subnet $subnetList->next(); /* @var $incorrectSubnet SubnetData */ $incorrectSubnet = $subnetList->current(); $data['placement'] = ['region' => self::TEST_REGION, 'placementConfigurationType' => 'AwsVpcPlacementConfiguration', 'subnets' => [['id' => $incorrectSubnet->subnetId]]]; $response = $this->postFarmRole($farm->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE); //create farm role with incorrect region $data['placement'] = ['region' => Aws::REGION_US_WEST_1, 'placementConfigurationType' => 'AwsVpcPlacementConfiguration', 'subnets' => [['id' => $subnetId]]]; $response = $this->postFarmRole($farm->id, $data); $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE); //post farm role correct data $data['placement']['region'] = self::TEST_REGION; $data['alias'] = 't-ps-1'; $response = $this->postFarmRole($farm->id, $data); $this->assertEquals(201, $response->status, $this->printResponseError($response)); $farmRoleId = $response->getBody()->data->id; /* @var $farmRole FarmRole */ $farmRole = FarmRole::findPk($farmRoleId); $this->assertNotEmpty($farmRole); $this->farmRoleToDelete($farmRoleId); $data['scaling']['rules'] = []; $this->assertObjectEqualsEntity($data, $farmRole); //Reset AWS VPC settings $farm->settings[FarmSetting::EC2_VPC_ID] = null; $farm->settings[FarmSetting::EC2_VPC_REGION] = null; $farm->save(); //set default governance settings $this->restoreGovernanceConfiguration(); //test farm roles post $data = ['role' => ['id' => $role->id], 'alias' => 't-ps-2', 'platform' => SERVER_PLATFORMS::EC2, 'placement' => ['placementConfigurationType' => FarmRoles::AWS_CLASSIC_PLACEMENT_CONFIGURATION, 'region' => static::TEST_REGION], 'scaling' => ['enabled' => true, 'minInstances' => 2, 'maxInstances' => 3], 'instance' => ['instanceConfigurationType' => FarmRoles::AWS_INSTANCE_CONFIGURATION, 'instanceType' => ['id' => 't1.micro']]]; $response = $this->postFarmRole($farm->id, $data); $this->assertEquals(201, $response->status, $this->printResponseError($response)); $farmRoleId = $response->getBody()->data->id; /* @var $farmRole FarmRole */ $farmRole = FarmRole::findPk($farmRoleId); $this->assertNotEmpty($farmRole); $this->farmRoleToDelete($farmRoleId); $data['placement']['availabilityZones'] = ''; $data['scaling']['rules'] = []; $this->assertObjectEqualsEntity($data, $farmRole); //test farm role modify scaling $data = ['scaling' => ['enabled' => false]]; $response = $this->modifyFarmRole($farmRole->id, $data); $this->assertEquals(200, $response->status, $this->printResponseError($response)); $farmRoleData = $response->getBody()->data; $this->assertObjectHasAttribute('scaling', $farmRoleData); $scalingConfiguration = $farmRoleData->scaling; $this->assertObjectNotHasAttribute('enabled', $scalingConfiguration); //test modify instance $data = ['instance' => ['instanceConfigurationType' => FarmRoles::AWS_INSTANCE_CONFIGURATION, 'instanceType' => 'm3.medium']]; $response = $this->modifyFarmRole($farmRole->id, $data); $this->assertEquals(200, $response->status, $this->printResponseError($response)); $farmRoleData = $response->getBody()->data; $this->assertObjectHasAttribute('instance', $farmRoleData); $instanceConfiguration = $farmRoleData->instance; $this->assertObjectHasAttribute('instanceType', $instanceConfiguration); $instanceType = $instanceConfiguration->instanceType; $this->assertObjectHasAttribute('id', $instanceType); $this->assertEquals('m3.medium', $instanceType->id); //test list farm roles filters $farmRoles = $this->listFarmRoles($farm->id); $farmRoleAdapter = $this->getAdapter('farmRole'); $filterable = $farmRoleAdapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE]; /* @var $farmRole FarmRole */ foreach ($farmRoles as $farmRole) { foreach ($filterable as $property) { $filterValue = $farmRole->{$property}; $listResult = $this->listFarmRoles($farm->id, [$property => $filterValue]); if (!static::isRecursivelyEmpty($filterValue)) { foreach ($listResult as $filtered) { $this->assertEquals($filterValue, $filtered->{$property}, "Property '{$property}' mismatch"); } } } $response = $this->getFarmRole($farmRole->id); $this->assertEquals(200, $response->status, $this->printResponseError($response)); $dbFarmRole = FarmRole::findPk($farmRole->id); $this->assertObjectEqualsEntity($response->getBody()->data, $dbFarmRole, $farmRoleAdapter); } }
/** * @return Image|NULL * @throws \Exception */ public function getImage() { /* @var $role Role */ $role = Role::findPk($this->roleId); return Image::findOne([['id' => $this->imageId], ['$or' => [['envId' => $role->envId == 0 ? null : $role->envId], ['envId' => null]]], ['platform' => $this->platform], ['cloudLocation' => $this->cloudLocation]]); }