Example #1
0
 /**
  * @test
  * @functional
  */
 public function testGetVersions()
 {
     $list = Script::find(null, null, null, 10);
     $this->assertInternalType('array', $list->getArrayCopy());
     $this->assertInternalType('integer', count($list));
     $this->assertInternalType('integer', $list->count());
     try {
         /* @var $script Script */
         $script = Script::findOne([]);
     } catch (\Exception $e) {
         $this->markTestSkipped($e->getMessage());
     }
     if (!$script) {
         $this->markTestSkipped("There are no scripts so it can not proceed");
     }
     $versions = $script->getVersions()->getArrayCopy();
     $this->assertInternalType('array', $versions);
 }
Example #2
0
 /**
  * @test
  *
  * @throws \Scalr\Exception\ModelException
  */
 public function testComplex()
 {
     $user = $this->getUser();
     $environment = $this->getEnvironment();
     $fictionController = new ApiController();
     //test script post
     $data = ['name' => 'test-post', 'description' => 'test-post', 'timeoutDefault' => 1000, 'blockingDefault' => true, 'osType' => 'linux'];
     $response = $this->postScript($data);
     $this->assertEquals(201, $response->status, $this->printResponseError($response));
     $scriptId = $response->getBody()->data->id;
     /* @var $script Script */
     $script = Script::findPk($scriptId);
     $this->assertNotEmpty($script);
     $this->scriptToDelete($scriptId);
     $this->assertObjectEqualsEntity($data, $script);
     //post environment-scoped script
     $data['scope'] = ScopeInterface::SCOPE_ENVIRONMENT;
     $response = $this->postScript($data);
     $this->assertEquals(201, $response->status, $this->printResponseError($response));
     $scriptId = $response->getBody()->data->id;
     $script = Script::findPk($scriptId);
     $this->assertNotEmpty($script);
     $this->scriptToDelete($scriptId);
     $this->assertObjectEqualsEntity($data, $script);
     //post script already existing
     $data = ['id' => $script->id, 'name' => 'test-post-existing', 'description' => 'test-post-existing', 'osType' => 'linux', 'scope' => ScopeInterface::SCOPE_ENVIRONMENT];
     $response = $this->postScript($data);
     $this->assertEquals(201, $response->status, $this->printResponseError($response));
     $scriptId = $response->getBody()->data->id;
     $this->scriptToDelete($scriptId);
     $this->assertNotEquals($data['id'], $scriptId);
     unset($data['id']);
     $scriptData = $data;
     $scriptData['accountId'] = $user->getAccountId();
     $scriptData['envId'] = $environment->id;
     $scriptData['os'] = $data['osType'];
     unset($scriptData['osType'], $scriptData['scope']);
     $envScript = $this->createEntity(new Script(), $scriptData);
     //post script with name already exists in current (environment) scope
     $data['name'] = 'test-post-existing';
     $response = $this->postScript($data);
     $this->assertErrorMessageContains($response, 409, ErrorMessage::ERR_UNICITY_VIOLATION);
     $envScript->delete();
     //post script with properties that not existing
     $data = ['name' => 'test-post-not-existing-field', 'description' => 'test-post-not-existing-field', 'foo' => 'bar', 'osType' => 'linux'];
     $response = $this->postScript($data);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     //post script without required fields
     $data = ['name' => 'foobar', 'description' => 'test-post-no-scope'];
     $response = $this->postScript($data);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     //test script fetch
     $response = $this->getScript($script->id);
     $this->assertEquals(200, $response->status, $this->printResponseError($response));
     $this->assertObjectEqualsEntity($response->getBody()->data, $script);
     //test fetch script that doe not exists
     $response = $this->getScript(Script::findOne([], null, ['id' => false])->id + 1);
     $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
     //test script modify
     $data = ['name' => 'test-modify', 'description' => 'test-modify', 'timeoutDefault' => 0, 'blockingDefault' => false];
     $response = $this->modifyScript($script->id, $data);
     $this->assertEquals(200, $response->status, $this->printResponseError($response));
     $this->assertObjectEqualsEntity($response->getBody()->data, Script::findPk($script->id));
     //modify property that does not exists
     $data = ['foo' => 'bar'];
     $response = $this->modifyScript($script->id, $data);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     //modify properties that not alterable
     $scriptAdapter = new ScriptAdapter($fictionController);
     $adapterRules = $scriptAdapter->getRules();
     $publicProperties = $adapterRules[BaseAdapter::RULE_TYPE_TO_DATA];
     $alterableProperties = $adapterRules[ApiEntityAdapter::RULE_TYPE_ALTERABLE];
     $nonAlterableProperties = array_diff(array_values($publicProperties), $alterableProperties);
     foreach ($nonAlterableProperties as $property) {
         $data = [$property => 'foo'];
         $response = $this->modifyScript($script->id, $data);
         $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     }
     //modify script that does not exists
     $data = ['name' => 'test-modify-not-found'];
     $response = $this->modifyScript(Script::findOne([], null, ['id' => false])->id + 1, $data);
     $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
     //modify Scalr-scoped script
     /* @var $script Script */
     $script = static::createEntity(new Script(), ['name' => "{$this->uuid}-script", 'description' => "{$this->uuid}-description", 'createdById' => $user->getId()]);
     //modify Scalr-scoped script
     $data = ['name' => 'test-modify-scalr-scoped'];
     $response = $this->modifyScript($script->id, $data);
     $this->assertErrorMessageContains($response, 403, ErrorMessage::ERR_PERMISSION_VIOLATION, 'Insufficient permissions');
     /* @var $script Script */
     $script = static::createEntity(new Script(), ['name' => "{$this->uuid}-script", 'description' => "{$this->uuid}-description", 'accountId' => $user->getAccountId(), 'createdById' => $user->getId()]);
     //test have access to all listed scripts
     $scripts = $this->listScripts();
     foreach ($scripts as $script) {
         $this->assertTrue(Script::findPk($script->id)->hasAccessPermissions($user), "Script id: {$script->id}");
     }
     //test convertible data filters
     $mergedLists = array_merge($this->listScripts(['scope' => ScopeInterface::SCOPE_SCALR]), $this->listScripts(['scope' => ScopeInterface::SCOPE_ENVIRONMENT]), $this->listScripts(['scope' => ScopeInterface::SCOPE_ACCOUNT]));
     foreach ($mergedLists as $script) {
         $this->assertTrue(Script::findPk($script->id)->hasAccessPermissions($user), "Script id: {$script->id}");
     }
     //test list scripts filters
     $filterable = $scriptAdapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE];
     /* @var $script Script */
     foreach ($scripts as $script) {
         foreach ($filterable as $property) {
             $filterValue = $script->{$property};
             $listResult = $this->listScripts([$property => $filterValue]);
             if (!static::isRecursivelyEmpty($filterValue)) {
                 foreach ($listResult as $filtered) {
                     $this->assertEquals($filterValue, $filtered->{$property}, "Property '{$property}' mismatch");
                 }
             }
         }
         $response = $this->getScript($script->id);
         $this->assertEquals(200, $response->status, $this->printResponseError($response));
         $dbScript = Script::findPk($script->id);
         $this->assertObjectEqualsEntity($response->getBody()->data, $dbScript, $scriptAdapter);
     }
     //test have write access to environments and account scoped scripts
     foreach (array_merge($this->listScripts(['scope' => ScopeInterface::SCOPE_ENVIRONMENT]), $this->listScripts(['scope' => ScopeInterface::SCOPE_ACCOUNT])) as $script) {
         $this->assertTrue(Script::findPk($script->id)->hasAccessPermissions($user, null, true));
     }
     $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 $script Script */
     $script = static::createEntity(new Script(), ['name' => "{$this->uuid}-script", 'description' => "{$this->uuid}-description", 'envId' => $environment->id, 'createdById' => $user->getId()]);
     $response = $this->deleteScript($script->id);
     $this->assertEquals(200, $response->status, $this->printResponseError($response));
     //delete scalr-scoped script
     $scripts = $this->listScripts(['scope' => ScopeInterface::SCOPE_SCALR]);
     $script = array_shift($scripts);
     $response = $this->deleteScript($script->id);
     $this->assertErrorMessageContains($response, 403, ErrorMessage::ERR_PERMISSION_VIOLATION);
     //delete script that does not exists
     $response = $this->deleteScript(Script::findOne([], null, ['id' => false])->id + 1);
     $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
 }
Example #3
0
 /**
  * @test
  */
 public function testComplex()
 {
     /* @var Script $script */
     $script = static::generateScripts([['os' => 'linux']])[0];
     /* @var ScriptVersion $version */
     $version = static::generateVersions($script, [['content' => '#!/bin/sh']])[0];
     $adapter = $this->getAdapter('OrchestrationRules\\FarmRoleScript');
     /* @var User $user */
     $user = $this->getUser();
     $environment = $this->getEnvironment();
     /* @var $farm Farm */
     $farm = static::createEntity(new Farm(), ['changedById' => $user->getId(), 'name' => "{$this->uuid}-farm", 'description' => "{$this->uuid}-description", 'envId' => $environment->id, 'accountId' => $user->getAccountId(), 'createdById' => $user->getId()]);
     $farmRole = $this->createTestFarmRole($farm);
     static::createEntity(new FarmRoleScript(), ['farmRoleId' => $farmRole->id, 'scriptId' => $script->id, 'farmId' => $farm->id]);
     //test get endpoint
     $filterable = $adapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE];
     $rules = $this->listRules($farmRole->id);
     foreach ($rules as $rule) {
         foreach ($filterable as $property) {
             $filterValue = $rule->{$property};
             $listResult = $this->listRules($farmRole->id, [$property => $filterValue]);
             if (!static::isRecursivelyEmpty($filterValue)) {
                 foreach ($listResult as $filtered) {
                     $this->assertEquals($filterValue, $filtered->{$property}, "Property '{$property}' mismatch");
                 }
             }
         }
         $response = $this->getRule($farmRole->id, $rule->id);
         $this->assertEquals(200, $response->status, $this->printResponseError($response));
         $dbRule = FarmRoleScript::findPk($rule->id);
         $this->assertObjectEqualsEntity($response->getBody()->data, $dbRule, $adapter);
     }
     $scalrFRScriptData = ['trigger' => ['triggerType' => FarmRoleScriptAdapter::TRIGGER_SINGLE_EVENT, 'event' => ['id' => 'HostInit']], 'target' => ['targetType' => FarmRoleScriptAdapter::TARGET_NAME_TRIGGERING_SERVER], 'action' => ['actionType' => FarmRoleScriptAdapter::ACTION_SCRIPT, 'scriptVersion' => ['script' => ['id' => $script->id], 'version' => $version->version]]];
     $localFRScriptData = ['trigger' => ['triggerType' => FarmRoleScriptAdapter::TRIGGER_ALL_EVENTS], 'target' => ['targetType' => FarmRoleScriptAdapter::TARGET_NAME_NULL], 'action' => ['actionType' => FarmRoleScriptAdapter::ACTION_URI, 'path' => 'https://example.com']];
     //post scalr rule
     $response = $this->postRule($farmRole->id, $scalrFRScriptData);
     $this->assertEquals(201, $response->status, $this->printResponseError($response));
     $ruleId = $response->getBody()->data->id;
     /* @var $rule FarmRoleScript */
     $rule = FarmRoleScript::findPk($ruleId);
     $this->assertNotEmpty($rule);
     $this->ruleToDelete($ruleId);
     $this->assertObjectEqualsEntity($scalrFRScriptData, $rule, $adapter);
     //post local rule
     $response = $this->postRule($farmRole->id, $localFRScriptData);
     $this->assertEquals(201, $response->status, $this->printResponseError($response));
     $ruleId = $response->getBody()->data->id;
     /* @var $rule FarmRoleScript */
     $rule = FarmRoleScript::findPk($ruleId);
     $this->assertNotEmpty($rule);
     $this->ruleToDelete($ruleId);
     $this->assertObjectEqualsEntity($localFRScriptData, $rule, $adapter);
     //post rule already existing
     $data = $scalrFRScriptData;
     $data['id'] = $ruleId;
     $response = $this->postRule($farmRole->id, $data);
     $this->assertEquals(201, $response->status, $this->printResponseError($response));
     $ruleId = $response->getBody()->data->id;
     $this->ruleToDelete($ruleId);
     $this->assertNotEquals($data['id'], $ruleId);
     //post rule with script that does not exists
     $data = $scalrFRScriptData;
     $data['action']['scriptVersion']['script']['id'] = Script::findOne([], null, ['id' => true])->id + 1;
     $response = $this->postRule($farmRole->id, $data);
     $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
     //post rule with version that does not exists
     $data = $scalrFRScriptData;
     $data['action']['scriptVersion']['version'] = Script::findPk($data['action']['scriptVersion']['script']['id'])->getLatestVersion()->version + 1;
     $response = $this->postRule($farmRole->id, $data);
     $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
     //post rule with properties that not existing
     $data = $scalrFRScriptData;
     $data['foo'] = 'bar';
     $response = $this->postRule($farmRole->id, $data);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     //post rule without required fields
     $data = $localFRScriptData;
     unset($data['action']);
     $response = $this->postRule($farmRole->id, $data);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     //post rule with invalid field
     $data = $localFRScriptData;
     $data['action'] = '';
     $response = $this->postRule($farmRole->id, $data);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     //modify rule
     //TODO::ape add modify rule
     //fetch rule
     $response = $this->getRule($farmRole->id, $rule->id);
     $this->assertEquals(200, $response->status, $this->printResponseError($response));
     $this->assertObjectEqualsEntity($response->getBody()->data, $rule, $adapter);
     //fetch rule that doe not exists
     $response = $this->getRule($farmRole->id, FarmRoleScript::findOne([], null, ['id' => false])->id + 1);
     $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
     //fetch rule with missmatch farm role id
     $response = $this->getRule(FarmRole::findOne([], null, ['id' => false])->id + 1, $rule->id);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_VALUE);
     //test have access to all listed rules
     $rules = $this->listRules($farmRole->id);
     foreach ($rules as $rule) {
         $this->assertTrue(FarmRoleScript::findPk($rule->id)->hasAccessPermissions($user));
     }
     //test invalid filters
     $url = self::getUserApiUrl("/farm-roles/{$farmRole->id}/orchestration-rules/");
     $response = $this->request($url, Request::METHOD_GET, ['foo' => 'bar']);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     $response = $this->request($url, Request::METHOD_GET, ['scope' => 'foobar']);
     $this->assertErrorMessageContains($response, 400, ErrorMessage::ERR_INVALID_STRUCTURE);
     //delete script
     /* @var $rule FarmRoleScript */
     $rule = static::createEntity(new FarmRoleScript(), ['farmRoleId' => $farmRole->id, 'scriptId' => $script->id, 'farmId' => $farm->id]);
     $response = $this->deleteRule($farmRole->id, $rule->id);
     $this->assertEquals(200, $response->status, $this->printResponseError($response));
     //delete script that does not exists
     $response = $this->deleteRule($farmRole->id, FarmRoleScript::findOne([], null, ['id' => false])->id + 1);
     $this->assertErrorMessageContains($response, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND);
 }
Example #4
0
 /**
  * @param int $scriptId
  * @param string $name
  * @throws Scalr_Exception_Core
  * @throws Scalr_UI_Exception_NotFound
  */
 public function xForkAction($scriptId, $name)
 {
     $this->request->restrictAccess('SCRIPTS', 'FORK');
     if (!$name) {
         throw new Scalr_Exception_Core('Name cannot be null');
     }
     /* @var $script Script */
     $script = Script::findPk($scriptId);
     if (!$script) {
         throw new Scalr_UI_Exception_NotFound();
     }
     $script->checkPermission($this->user, $this->getEnvironmentId(true));
     $criteria = [];
     $criteria[] = ['name' => $name];
     switch ($this->request->getScope()) {
         case Script::SCOPE_ENVIRONMENT:
             $criteria[] = ['envId' => $this->getEnvironmentId(true)];
             $criteria[] = ['accountId' => $this->user->getAccountId()];
             break;
         case Script::SCOPE_ACCOUNT:
             $criteria[] = ['envId' => null];
             $criteria[] = ['accountId' => $this->user->getAccountId()];
             break;
         case Script::SCOPE_SCALR:
             $criteria[] = ['envId' => null];
             $criteria[] = ['accountId' => null];
             break;
     }
     if (Script::findOne($criteria)) {
         throw new Scalr_Exception_Core('Script name must be unique within current scope');
     }
     $forkedScript = $script->fork($name, $this->user, $this->getEnvironmentId(true));
     $this->response->success('Script successfully forked');
     $this->response->data(['script' => array_merge($this->getScript($forkedScript), $this->getScriptInfo($forkedScript))]);
 }
Example #5
0
 /**
  * {@inheritdoc}
  * @see \Scalr\Api\DataType\ApiEntityAdapter::validateEntity()
  */
 public function validateEntity($entity)
 {
     if (!$entity instanceof Script) {
         throw new InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\Script class"));
     }
     if ($entity->id !== null) {
         if (!Script::findPk($entity->id)) {
             throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the Script with ID: %d", $entity->id));
         }
     }
     if (empty($entity->name)) {
         throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Property name cannot be empty");
     } else {
         switch ($entity->getScope()) {
             case ScopeInterface::SCOPE_ACCOUNT:
                 $existed = Script::findOne([['name' => $entity->name], ['accountId' => $this->controller->getUser()->accountId], ['envId' => null]]);
                 break;
             case ScopeInterface::SCOPE_ENVIRONMENT:
                 $existed = Script::findOne([['name' => $entity->name], ['accountId' => $this->controller->getUser()->accountId], ['envId' => $this->controller->getEnvironment()->id]]);
                 break;
             case ScopeInterface::SCOPE_SCALR:
                 $existed = Script::findOne([['name' => $entity->name], ['accountId' => null], ['envId' => null]]);
                 break;
         }
         /* @var $existed Script */
         if (!empty($existed) && $entity->id !== $existed->id) {
             throw new ApiErrorException(409, ErrorMessage::ERR_UNICITY_VIOLATION, "Script '{$entity->name}' already exists on scope {$existed->getScope()}");
         }
     }
     if (empty($entity->os)) {
         throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property osType");
     } else {
         if (!in_array($entity->os, [Script::OS_LINUX, Script::OS_WINDOWS])) {
             throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid osType");
         }
     }
     //NOTE: scalr-scope currently restricted in APIv2
     switch ($entity->getScope()) {
         case ScopeInterface::SCOPE_ENVIRONMENT:
             if (!$this->controller->getEnvironment()) {
                 throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, "Invalid scope");
             }
             break;
         case ScopeInterface::SCOPE_ACCOUNT:
             if ($this->controller->getEnvironment()) {
                 throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, "Invalid scope");
             }
             break;
         case ScopeInterface::SCOPE_SCALR:
         case ScopeInterface::SCOPE_FARM:
         case ScopeInterface::SCOPE_FARMROLE:
         case ScopeInterface::SCOPE_ROLE:
         case ScopeInterface::SCOPE_SERVER:
             throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, "Invalid scope");
         default:
             throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid scope");
     }
     if (!$this->controller->hasPermissions($entity, true)) {
         //Checks entity level write access permissions
         throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions");
     }
 }
Example #6
0
 /**
  * @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);
 }
Example #7
0
 /**
  * @param int $id
  * @param string $name
  * @param string $description
  * @param int $isSync
  * @param bool $allowScriptParameters
  * @param int $envId optional
  * @param int $timeout optional
  * @param int $version
  * @param RawData $content
  * @param string $tags
  * @param string $uploadType optional
  * @param string $uploadUrl optional
  * @param FileUploadData $uploadFile optional
  * @param bool $checkScriptParameters optional
  * @throws Scalr_UI_Exception_NotFound
  * @throws Scalr_Exception_InsufficientPermissions
  * @throws Exception
  */
 public function xSaveAction($id, $name, $description, $isSync = 0, $allowScriptParameters = false, $envId = NULL, $timeout = NULL, $version, RawData $content, $tags, $uploadType = NULL, $uploadUrl = NULL, FileUploadData $uploadFile = NULL, $checkScriptParameters = false)
 {
     $this->request->restrictAccess(Acl::RESOURCE_ADMINISTRATION_SCRIPTS, Acl::PERM_ADMINISTRATION_SCRIPTS_MANAGE);
     $validator = new Validator();
     $validator->validate($name, 'name', Validator::NOEMPTY);
     if ($uploadType && $uploadType == 'URL') {
         $validator->validate($uploadUrl, 'uploadUrl', Validator::URL);
         if (!$validator->isValid($this->response)) {
             return;
         }
     }
     if ($uploadType) {
         $content = false;
         if ($uploadType == 'URL') {
             $content = @file_get_contents($uploadUrl);
             $validator->validate($content, 'uploadUrl', Validator::NOEMPTY, [], 'Invalid source');
         } else {
             if ($uploadType == 'File') {
                 $content = $uploadFile;
                 $validator->validate($content, 'uploadFile', Validator::NOEMPTY, [], 'Invalid source');
             } else {
                 $validator->addError('uploadType', 'Invalid source for script');
             }
         }
     }
     $envId = $envId ? $this->user->getDefaultEnvironment($envId)->id : NULL;
     $content = str_replace("\r\n", "\n", $content);
     $tagsResult = [];
     foreach (explode(',', $tags) as $t) {
         $t = trim($t);
         if ($t) {
             if (!preg_match('/^[a-zA-Z0-9-]{3,10}$/', $t)) {
                 $validator->addError('tags', sprintf('Invalid name for tag: %s', $t));
             }
             $tagsResult[] = $t;
         }
     }
     $tags = $tagsResult;
     $criteria = [];
     $criteria[] = ['name' => $name];
     if ($id) {
         $criteria[] = ['id' => ['$ne' => $id]];
     }
     switch ($this->request->getScope()) {
         case Script::SCOPE_ENVIRONMENT:
             $criteria[] = ['envId' => $envId];
             $criteria[] = ['accountId' => $this->user->getAccountId()];
             break;
         case Script::SCOPE_ACCOUNT:
             $criteria[] = ['envId' => null];
             $criteria[] = ['accountId' => $this->user->getAccountId()];
             break;
         case Script::SCOPE_SCALR:
             $criteria[] = ['envId' => null];
             $criteria[] = ['accountId' => null];
             break;
     }
     if (Script::findOne($criteria)) {
         $validator->addError('name', 'Script name must be unique within current scope');
     }
     if (!$validator->isValid($this->response)) {
         return;
     }
     /* @var $script Script */
     if ($id) {
         $script = Script::findPk($id);
         if (!$script) {
             throw new Scalr_UI_Exception_NotFound();
         }
         $script->checkPermission($this->user, $envId);
         if (!$script->accountId && $this->user->getType() != Scalr_Account_User::TYPE_SCALR_ADMIN) {
             throw new Scalr_Exception_InsufficientPermissions();
         }
     } else {
         $script = new Script();
         $script->accountId = $this->user->getAccountId() ? $this->user->getAccountId() : NULL;
         $script->createdById = $this->user->getId();
         $script->createdByEmail = $this->user->getEmail();
         $script->envId = $envId;
         $version = 1;
     }
     //check variables in script content
     if (!$id && $checkScriptParameters && !$allowScriptParameters) {
         $scriptHasParameters = Script::hasVariables($content);
         if (!$scriptHasParameters) {
             /* @var $scriptVersion ScriptVersion */
             foreach ($script->getVersions() as $scriptVersion) {
                 if ($scriptVersion->version != $version) {
                     $scriptHasParameters = Script::hasVariables($scriptVersion->content);
                     if ($scriptHasParameters) {
                         break;
                     }
                 }
             }
         }
         if ($scriptHasParameters) {
             $this->response->data(['showScriptParametersConfirmation' => true]);
             $this->response->failure();
             return;
         }
     }
     $script->name = $name;
     $script->description = $description;
     $script->timeout = $timeout ? $timeout : NULL;
     $script->isSync = $isSync == 1 ? 1 : 0;
     $script->allowScriptParameters = $allowScriptParameters ? 1 : 0;
     $script->os = !strncmp($content, '#!cmd', strlen('#!cmd')) || !strncmp($content, '#!powershell', strlen('#!powershell')) ? Script::OS_WINDOWS : Script::OS_LINUX;
     $script->save();
     $scriptVersion = NULL;
     if ($version) {
         $scriptVersion = $script->getVersion($version);
     }
     if (!$scriptVersion && $script->getLatestVersion()->content !== $content) {
         $scriptVersion = new ScriptVersion();
         $scriptVersion->scriptId = $script->id;
         $scriptVersion->version = $script->getLatestVersion()->version + 1;
     }
     if ($scriptVersion) {
         $scriptVersion->changedById = $this->user->getId();
         $scriptVersion->changedByEmail = $this->user->getEmail();
         $scriptVersion->content = $content;
         $scriptVersion->save();
     }
     if ($this->user->getAccountId()) {
         Tag::setTags($tags, $this->user->getAccountId(), Tag::RESOURCE_SCRIPT, $script->id);
     }
     $this->response->success('Script successfully saved');
     $this->response->data(['script' => array_merge($this->getScript($script), $this->getScriptInfo($script))]);
 }