/** * @param string $cloudLocation */ public function xListAction($cloudLocation) { $aws = $this->getEnvironment()->aws($cloudLocation); $existedImages = []; foreach (Image::find([['platform' => SERVER_PLATFORMS::EC2], ['cloudLocation' => $cloudLocation], ['envId' => $this->getEnvironmentId()]]) as $i) { /* @var $i Image */ $existedImages[$i->id] = $i; } $images = []; foreach ($aws->ec2->image->describe(null, 'self') as $im) { $i = ['id' => $im->imageId, 'imageName' => $im->name, 'imageState' => $im->imageState, 'imageVirt' => $im->virtualizationType, 'imageIsPublic' => $im->isPublic]; if (isset($existedImages[$im->imageId])) { $i['status'] = 'sync'; $i['name'] = $existedImages[$im->imageId]->name; unset($existedImages[$im->imageId]); } else { $i['status'] = 'none'; } $images[] = $i; } foreach ($existedImages as $i) { /* @var $i Image */ $images[] = ['name' => $i->name, 'id' => $i->id, 'status' => 'missed']; } $this->response->data(['data' => $images]); }
/** * @param $osFamily * @param $osVersion */ public function xGetRoleImagesAction($osFamily, $osVersion) { $this->request->restrictAccess(Acl::RESOURCE_FARMS_ROLES, Acl::PERM_FARMS_ROLES_MANAGE); $data = []; foreach (Image::find([['envId' => $this->getEnvironmentId(true)], ['osFamily' => $osFamily], ['osVersion' => $osVersion]]) as $image) { /* @var Image $image */ $data[] = ['platform' => $image->platform, 'cloudLocation' => $image->cloudLocation, 'id' => $image->id, 'architecture' => $image->architecture, 'source' => $image->source, 'createdByEmail' => $image->createdByEmail]; } $this->response->data(['images' => $data]); }
protected function run3() { $this->console->notice('Updating images'); $cnt = 0; $cntError = 0; $images = Image::find([['status' => 'active'], ['size' => null], ['name' => null]]); foreach ($images as $i) { /* @var Image $i */ if ($i->checkImage()) { $cnt++; } else { $cntError++; } $i->save(); } $this->console->notice('Proceed %d images, mark as deleted: %d', $cnt + $cntError, $cntError); }
protected function run1($stage) { $this->console->notice('Updating type'); // type is defined only on EC2 $this->db->Execute('UPDATE images SET type = NULL WHERE platform != ?', [\SERVER_PLATFORMS::EC2]); $this->db->Execute('UPDATE images SET type = NULL WHERE type = ""'); // we could simply translate to new names $this->db->Execute('UPDATE images SET type = ? WHERE type = ?', ['ebs', 'ec2.ebs']); $this->db->Execute('UPDATE images SET type = ? WHERE type = ?', ['ebs-hvm', 'ec2.ebs-hvm']); // check others $this->console->notice('Checking images'); $images = Image::find([['type' => ['$ne' => '']], ['type' => ['$ne' => 'ebs']], ['type' => ['$ne' => 'ebs-hvm']], ['type' => ['$ne' => 'instance-store']], ['type' => ['$ne' => 'instance-store-hvm']]]); foreach ($images as $im) { /* @var Image $im */ $im->checkImage(); $im->save(); } }
/** * {@inheritdoc} * @see \Scalr\System\Zmq\Cron\TaskInterface::enqueue() */ public function enqueue() { foreach (Image::find([['status' => Image::STATUS_DELETE]]) as $image) { try { /* @var $image Image */ $image->deleteCloudImage(); $image->delete(); } catch (Exception $e) { $flag = false; if (strpos($e->getMessage(), 'The resource could not be found') !== false || strpos($e->getMessage(), 'The requested URL / was not found on this server.') !== false || strpos($e->getMessage(), 'Not Found') !== false || strpos($e->getMessage(), 'was not found') !== false || strpos($e->getMessage(), 'OpenStack error. Image not found.') !== false) { $image->delete(); } else { $image->status = Image::STATUS_FAILED; $image->statusError = $e->getMessage(); $image->save(); } } } //Workers do not need to be used return new ArrayObject([]); }
protected function run1($stage) { $cntAll = 0; $cntError = 0; $cntUpdated = 0; foreach (Image::find([['type' => null], ['platform' => SERVER_PLATFORMS::EC2], ['envId' => ['$ne' => null]]]) as $image) { /* @var $image Image */ $type = $image->type; $cntAll++; if ($image->checkImage()) { $image->save(); if ($type != $image->type) { $cntUpdated++; } } else { $cntError++; } } $this->console->out('Processed images: %d', $cntAll); $this->console->out('Updated images: %d', $cntUpdated); $this->console->out('Invalid images: %d', $cntError); }
/** * List orphaned servers * * @param string $platform Cloud platform * @param string $cloudLocation optional Cloud location */ public function xListAction($platform, $cloudLocation = null) { $orphans = $lookup = []; $p = PlatformFactory::NewPlatform($platform); if (!$this->environment->isPlatformEnabled($platform)) { return $this->response->failure(sprintf("Platform '%s' is not enabled", $platform)); } $orphans = $this->buildResponseFromData($p->getOrphanedServers($this->environment, $cloudLocation), ["cloudServerId", "privateIp", "publicIp"]); foreach ($orphans["data"] as $i => &$orphan) { $orphan["launchTime"] = \Scalr_Util_DateTime::convertTz($orphan["launchTime"]); $orphan["imageHash"] = null; $orphan["imageName"] = null; $lookup[$orphan["imageId"]] = $i; } if (!empty($lookup)) { /* @var $image Scalr\Model\Entity\Image */ foreach (Image::find([["status" => Image::STATUS_ACTIVE], ["id" => ['$in' => array_keys($lookup)]]]) as $image) { $orphans["data"][$lookup[$image->id]]["imageHash"] = $image->hash; $orphans["data"][$lookup[$image->id]]["imageName"] = $image->name; } } $this->response->data($orphans); }
/** * If image is used in any environment (servers, farmRoles) or had duplicates in another environments * * @return bool * @throws \Scalr\Exception\ModelException */ public function isUsedGlobal() { $status = !!$this->db()->GetOne('SELECT EXISTS(SELECT 1 FROM role_images WHERE image_id = ? AND platform = ? AND cloud_location = ?)', [$this->id, $this->platform, $this->cloudLocation]); if ($this->platform == \SERVER_PLATFORMS::GCE) { $status = $status || !!$this->db()->GetOne('SELECT EXISTS(SELECT 1 FROM servers WHERE image_id = ? AND platform = ? AND env_id = ?)', [$this->id, $this->platform, $this->envId]); } else { $status = $status || !!$this->db()->GetOne('SELECT EXISTS(SELECT 1 FROM servers WHERE image_id = ? AND platform = ? AND cloud_location = ? AND env_id = ?)', [$this->id, $this->platform, $this->cloudLocation, $this->envId]); } $status = $status || Image::find([['id' => $this->id], ['platform' => $this->platform], ['cloudLocation' => $this->cloudLocation]])->count() > 1; return $status; }
/** * Gets Images which are associated with the Role * * @param array $criteria optional The search criteria on the Image result set. * @param array $group optional The group parameter * @param array $order optional The results order looks like [[property1 => true|false], ...] * @param int $limit optional The records limit * @param int $offset optional The offset * @param bool $countRecords optional True to calculate total number of the records without limit * @return \Scalr\Model\Collections\EntityIterator Returns Images which are associated with the role */ public function getImages(array $criteria = null, array $group = null, array $order = null, $limit = null, $offset = null, $countRecords = null) { $image = new Image(); $roleImage = new RoleImage(); $criteria = $criteria ?: []; $criteria[static::STMT_FROM] = $image->table() . "\n JOIN " . $roleImage->table() . " ON {$roleImage->columnImageId} = {$image->columnId}\n AND {$roleImage->columnPlatform} = {$image->columnPlatform}\n AND {$roleImage->columnCloudLocation} = {$image->columnCloudLocation}"; $criteria[static::STMT_WHERE] = "{$roleImage->columnRoleId} = " . intval($this->id); $criteria[] = ['$or' => [['accountId' => null], ['$and' => [['accountId' => $this->accountId], ['$or' => [['envId' => null], ['envId' => $this->envId]]]]]]]; return $image->find($criteria, $group, $order, $limit, $offset, $countRecords); }
/** * Detach configured cloud configuration from specified environment * * @param int $envId Environment ID * @param string $cloud Cloud platform name * * @return ResultEnvelope * * @throws ApiErrorException * @throws ModelException */ public function detachCredentialsAction($envId, $cloud) { if (!$this->getUser()->canManageAcl()) { $this->checkPermissions(Acl::RESOURCE_ENV_CLOUDS_ENVIRONMENT); } $env = $this->getEnv($envId); $cloudCredentials = $env->keychain($cloud); if (empty($cloudCredentials->id)) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Cloud '{$cloud}' not configured for this environment"); } if (in_array($cloudCredentials->cloud, [SERVER_PLATFORMS::EC2, SERVER_PLATFORMS::GCE]) && (count(Entity\Server::find([['envId' => $envId], ['platform' => $cloudCredentials->cloud]])) || count(Entity\Image::find([['envId' => $envId], ['platform' => $cloudCredentials->cloud]])))) { throw new ApiErrorException(409, ErrorMessage::ERR_OBJECT_IN_USE, "Cloud Credentials are used"); } $cloudCredentials->environments[$envId]->delete(); return $this->result(null); }
/** * @param string $osFamily * @param string $osVersion */ public function xGetRoleImagesAction($osFamily, $osVersion) { $this->restrictAccess('IMAGES', 'MANAGE'); $data = []; $osIds = Os::findIdsBy($osFamily, null, $osVersion); foreach (Image::find([['$or' => [['envId' => $this->getEnvironmentId(true)], ['envId' => NULL]]], ['osId' => ['$in' => $osIds]], ['status' => Image::STATUS_ACTIVE]]) as $image) { /* @var $image Image */ $data[] = ['platform' => $image->platform, 'cloudLocation' => $image->cloudLocation, 'id' => $image->id, 'architecture' => $image->architecture, 'source' => $image->source, 'createdByEmail' => $image->createdByEmail, 'os_family' => $image->getOs()->family, 'os_generation' => $image->getOs()->generation, 'os_version' => $image->getOs()->version, 'os_id' => $image->getOs()->id, 'os' => $image->getOs()->name]; } $this->response->data(['images' => $data]); }
/** * @test */ public function testAccountRolesFunctional() { $db = \Scalr::getDb(); $testName = str_replace('-', '', static::getTestName()); $roles = null; $uri = self::getAccountApiUrl('/roles'); 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_ACCOUNT, '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_ACCOUNT, '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_ACCOUNT, '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_ACCOUNT, '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_ACCOUNT, '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_ACCOUNT, 'name' => $testName, 'category' => ['id' => $rolesCat->id]]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property 'os.id'"); $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_ACCOUNT, '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_ACCOUNT, 'name' => $testName, 'category' => ['id' => $rolesCat->id], 'os' => ['id' => 'invalid']]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, "OS with id 'invalid' not found."); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName, 'description' => $testName, 'category' => $rolesCat->id, 'os' => $os->id, 'quickStart' => true, 'deprecated' => true]); $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_ACCOUNT, $body->data->scope); $this->assertEquals($rolesCat->id, $body->data->category->id); $this->assertEquals($os->id, $body->data->os->id); $this->assertEquals(true, $body->data->quickStart); $this->assertEquals(true, $body->data->deprecated); // 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); $image = $this->createEntity(new Image(), ['accountId' => $this->getUser()->accountId, 'name' => $testName, 'osId' => $os->id, 'platform' => $platform, 'cloudLocation' => $region, 'id' => $cloudImageId, 'architecture' => 'x86_64', 'source' => Image::SOURCE_MANUAL, 'status' => Image::STATUS_ACTIVE]); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId + 10], 'image' => ['id' => $image->hash]]); $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' => $image->hash]]); $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' => $image->hash]]); $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' => $image->hash]); $this->assertDescribeResponseNotEmpty($describeRoleImages); foreach ($describeRoleImages->getBody()->data as $data) { $this->assertRoleImageObjectNotEmpty($data); $this->assertEquals($image->hash, $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::getAccountApiUrl("images/{$image->hash}"), 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_ACCOUNT, $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_ACCOUNT]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $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' => 123]); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE); $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_VALUE); $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_ACCOUNT, $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::getAccountApiUrl("/roles/{$notFoundRoleId}"), Request::METHOD_DELETE); $this->assertErrorMessageContains($delete, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); $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 generation = 2\n ", [$testName]); $insertedId = $db->_insertid(); $db->Execute("INSERT INTO role_images SET\n role_id = ?,\n platform = 'ec2',\n image_id = 'test'\n ", [$insertedId]); $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); }
/** * Gets unused image id from the cloud * * @param \Scalr_Environment $env Scalr environment * @param string $cloudLocation Region * @return null|string */ protected function getNewImageId(\Scalr_Environment $env, $cloudLocation) { $aws = $env->aws($cloudLocation); $cloudImageId = null; $existedImages = []; foreach (Image::find([['platform' => \SERVER_PLATFORMS::EC2], ['cloudLocation' => $cloudLocation], ['envId' => static::$testEnvId]]) as $img) { /* @var $img Image */ $existedImages[$img->id] = $img; } foreach ($aws->ec2->image->describe(null, 'self') as $awsImage) { /* @var $awsImage \Scalr\Service\Aws\Ec2\DataType\ImageData */ if (!isset($existedImages[$awsImage->imageId])) { $cloudImageId = $awsImage->imageId; break; } } return $cloudImageId; }
/** * List orphaned servers * * @param string $platform Cloud platform * @param string $cloudLocation optional Cloud location * @param string $query optional Filter parameter * @param string $imageId optional Filter parameter * @param string $vpcId optional Filter parameter * @param string $subnetId optional Filter paramerer */ public function xListAction($platform, $cloudLocation = null, $query = null, $imageId = null, $vpcId = null, $subnetId = null) { $lookup = []; $p = PlatformFactory::NewPlatform($platform); if (!$this->environment->isPlatformEnabled($platform)) { $this->response->failure(sprintf("Platform '%s' is not enabled", $platform)); return; } $filterFields = []; if ($query) { $filterFields[join(',', ['cloudServerId', 'privateIp', 'publicIp'])] = $query; } if ($imageId) { $filterFields['imageId'] = $imageId; } if ($vpcId) { $filterFields['vpcId'] = $vpcId; } if ($subnetId) { $filterFields['subnetId'] = $subnetId; } $orphans = $this->buildResponseFromData($p->getOrphanedServers($this->getEnvironmentEntity(), $cloudLocation), $filterFields); foreach ($orphans["data"] as $i => &$orphan) { $orphan["launchTime"] = \Scalr_Util_DateTime::convertTz($orphan["launchTime"]); $orphan["imageHash"] = null; $orphan["imageName"] = null; if (!is_array($lookup[$orphan["imageId"]])) { $lookup[$orphan["imageId"]] = []; } $lookup[$orphan["imageId"]][] = $orphan; } if (!empty($lookup)) { /* @var $image Scalr\Model\Entity\Image */ foreach (Image::find([["status" => Image::STATUS_ACTIVE], ["id" => ['$in' => array_keys($lookup)]], ['$or' => [['accountId' => null], ['$and' => [['accountId' => $this->getUser()->accountId], ['$or' => [['envId' => null], ['envId' => $this->getEnvironment()->id]]]]]]]]) as $image) { foreach ($lookup[$image->id] as &$orphan) { $orphan['imageHash'] = $image->hash; $orphan['imageName'] = $image->name; } } } $this->response->data($orphans); }