Since: 5.0 (08.05.2014)
Author: Igor Vodiasov (invar@scalr.com)
Inheritance: extends Scalr\Model\AbstractEntity, implements Scalr\DataType\ScopeInterface, implements Scalr\DataType\AccessPermissionsInterface
 protected function run1($stage)
 {
     $table = 'event_definitions';
     $sql = [];
     if (!$this->hasTableColumn($table, 'created')) {
         $bCreated = true;
         $this->console->out("Adding scalr.event_definitions.created column...");
         $sql[] = "ADD COLUMN `created` DATETIME NOT NULL COMMENT 'Created at timestamp' AFTER `description`";
     }
     if (!$this->hasTableIndex($table, 'idx_created')) {
         $this->console->out('Adding index by `created` to `event_definitions`');
         $sql[] = 'ADD INDEX `idx_created` (created ASC)';
     }
     if (!empty($sql)) {
         $this->applyChanges($table, $sql);
     }
     if (!empty($bCreated)) {
         $date = new DateTime();
         $date->modify('-1 hour');
         $list = EventDefinition::find([['$or' => [['created' => null], ['created' => new \DateTime('0000-00-00 00:00:00')]]]]);
         foreach ($list as $event) {
             /* @var $event EventDefinition */
             $event->created = $date;
             $event->save();
             $date->modify('+1 second');
         }
     }
 }
Beispiel #2
0
 /**
  * {@inheritdoc}
  * @see \Scalr\Api\DataType\ApiEntityAdapter::validateEntity()
  */
 public function validateEntity($entity)
 {
     if (!$entity instanceof Entity\EventDefinition) {
         throw new \InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\EventDefinition class"));
     }
     if ($entity->id !== null) {
         //Checks if the event does exist
         if (!Entity\EventDefinition::findPk($entity->id)) {
             throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the Event with ID: %d", $entity->name));
         }
     }
     if (!preg_match('/^' . Entity\EventDefinition::NAME_REGEXP . '$/', $entity->name)) {
         throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid id of the Event");
     }
     $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 Account or Environment Scope Events
     if ($entity->getScope() !== $this->controller->getScope()) {
         throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, sprintf("Invalid scope"));
     }
 }
Beispiel #3
0
 public function postEvent(array $eventData, $environment = false)
 {
     $uri = self::getUserApiUrl('/events', $environment);
     $response = $this->request($uri, Request::METHOD_POST, [], $eventData);
     $body = $response->getBody();
     if ($response->status == 201 && isset($body->data->id)) {
         $criteria = $this->getCriteria($environment === null);
         $criteria[] = ['name' => $body->data->id];
         $this->eventToDelete(EventDefinition::findOne($criteria)->id);
     }
     return $response;
 }
 public function FireCustomEvent($ServerID, $EventName, array $Params = array())
 {
     $this->restrictAccess(Acl::RESOURCE_GENERAL_CUSTOM_EVENTS);
     $dbServer = DBServer::LoadByID($ServerID);
     if ($dbServer->envId != $this->Environment->id) {
         throw new Exception(sprintf("Server ID #%s not found", $ServerID));
     }
     if (\Scalr\Model\Entity\EventDefinition::isExist($EventName, $this->user->getAccountId(), $this->Environment->id)) {
         $event = new CustomEvent($dbServer, $EventName, (array) $Params);
     } else {
         throw new Exception(sprintf("Event %s is not defined", $EventName));
     }
     Scalr::FireEvent($dbServer->farmId, $event);
     $response = $this->CreateInitialResponse();
     $response->EventID = $event->GetEventID();
     return $response;
 }
Beispiel #5
0
 public function scriptingAction()
 {
     $this->request->restrictAccess(Acl::RESOURCE_LOGS_SCRIPTING_LOGS);
     $farms = self::loadController('Farms')->getList();
     array_unshift($farms, ['id' => '0', 'name' => 'All farms']);
     //todo: use Script::getScriptingData
     $scripts = array_map(function ($s) {
         return ['id' => $s['id'], 'name' => $s['name']];
     }, Script::getList($this->user->getAccountId(), $this->getEnvironmentId()));
     array_unshift($scripts, ['id' => 0, 'name' => '']);
     $glEvents = array_keys(EVENT_TYPE::getScriptingEvents());
     sort($glEvents);
     array_unshift($glEvents, '');
     $events = array_merge($glEvents, array_keys(\Scalr\Model\Entity\EventDefinition::getList($this->user->getAccountId(), $this->getEnvironmentId())));
     $tasks = $this->db->GetAll('SELECT id, name FROM scheduler WHERE env_id = ? ORDER BY name ASC', [$this->getEnvironmentId()]);
     array_unshift($tasks, ['id' => 0, 'name' => '']);
     $this->response->page('ui/logs/scripting.js', ['farms' => $farms, 'scripts' => $scripts, 'events' => $events, 'tasks' => $tasks]);
 }
Beispiel #6
0
 private function getEventsList()
 {
     $events = EVENT_TYPE::getScriptingEventsWithScope();
     $envId = null;
     if ($this->request->getScope() == WebhookConfig::SCOPE_ENVIRONMENT) {
         $envId = (int) $this->getEnvironmentId(true);
     }
     //Temporary added new events like this, workign on events refactoring
     $events['HostInitFailed'] = ['name' => 'HostInitFailed', 'description' => 'Instance was unable to initialize', 'scope' => 'scalr'];
     $events['InstanceLaunchFailed'] = ['name' => 'InstanceLaunchFailed', 'description' => 'Scalr failed to launch instance due to cloud error', 'scope' => 'scalr'];
     $events = array_merge($events, \Scalr\Model\Entity\EventDefinition::getList($this->user->getAccountId(), $envId));
     return $events;
 }
Beispiel #7
0
 public static function getScriptingData($accountId, $envId)
 {
     return ['events' => array_merge(\EVENT_TYPE::getScriptingEventsWithScope(), EventDefinition::getList($accountId, $envId)), 'scripts' => static::getList($accountId, $envId)];
 }
Beispiel #8
0
 /**
  * Creates new event in current scope
  *
  * @return \Scalr\Api\DataType\ResultEnvelope
  * @throws ApiErrorException
  * @throws \Scalr\Exception\ModelException
  */
 public function createAction()
 {
     $this->checkPermissions(Acl::RESOURCE_GENERAL_CUSTOM_EVENTS, Acl::PERM_GENERAL_CUSTOM_EVENTS_MANAGE);
     $object = $this->request->getJsonBody();
     $eventAdapter = $this->adapter('event');
     //Pre validates the request object
     $eventAdapter->validateObject($object, Request::METHOD_POST);
     if (empty($object->id)) {
         throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Required field 'id' is missing.");
     }
     $object->scope = $this->getScope();
     $criteria = [['name' => $object->id]];
     switch ($this->getScope()) {
         case ScopeInterface::SCOPE_ACCOUNT:
             $criteria[] = ['$or' => [['$and' => [['envId' => null], ['accountId' => null]]], ['accountId' => $this->getUser()->getAccountId()]]];
             break;
         case ScopeInterface::SCOPE_ENVIRONMENT:
             $criteria[] = ['$and' => [['envId' => $this->getEnvironment()->id], ['accountId' => $this->getUser()->getAccountId()]]];
             break;
         default:
             throw new ApiErrorException(500, ErrorMessage::ERR_NOT_IMPLEMENTED, sprintf("The Scope '%s' has not been implemented yet", $this->getScope()));
     }
     /* @var $oldEvent Entity\EventDefinition */
     $oldEvent = Entity\EventDefinition::findOne($criteria);
     if (!empty($oldEvent)) {
         if ($this->getScope() == ScopeInterface::SCOPE_ACCOUNT && $this->request->get('replace', false)) {
             $replacements = Entity\EventDefinition::find([['name' => $object->id], ['accountId' => $this->getUser()->getAccountId()], ['envId' => ['$ne' => null]]]);
             if ($replacements->count()) {
                 foreach ($replacements as $lowerEvent) {
                     $lowerEvent->delete();
                 }
             } else {
                 throw new ApiErrorException(409, ErrorMessage::ERR_UNICITY_VIOLATION, sprintf('Event with id %s already exists', $object->id));
             }
         } else {
             throw new ApiErrorException(409, ErrorMessage::ERR_UNICITY_VIOLATION, sprintf('Event with id %s already exists', $object->id));
         }
     }
     /* @var $event Entity\EventDefinition */
     //Converts object into EventDefinition entity
     $event = $eventAdapter->toEntity($object);
     $event->id = null;
     $eventAdapter->validateEntity($event);
     //Saves entity
     $event->save();
     //Responds with 201 Created status
     $this->response->setStatus(201);
     return $this->result($eventAdapter->toData($event));
 }
Beispiel #9
0
 public function xSaveAction()
 {
     $this->request->restrictAccess(Acl::RESOURCE_GENERAL_SCHEDULERTASKS, Acl::PERM_GENERAL_SCHEDULERTASKS_MANAGE);
     $this->request->defineParams(array('id' => array('type' => 'integer'), 'name' => array('type' => 'string', 'validator' => array(Scalr_Validator::REQUIRED => true, Scalr_Validator::NOHTML => true)), 'type' => array('type' => 'string', 'validator' => array(Scalr_Validator::RANGE => array(Scalr_SchedulerTask::SCRIPT_EXEC, Scalr_SchedulerTask::LAUNCH_FARM, Scalr_SchedulerTask::TERMINATE_FARM, Scalr_SchedulerTask::FIRE_EVENT), Scalr_Validator::REQUIRED => true)), 'startTime', 'startTimeDate', 'restartEvery', 'timezone' => array('type' => 'string', 'validator' => array(Scalr_Validator::REQUIRED => true)), 'farmId' => array('type' => 'integer'), 'farmRoleId' => array('type' => 'integer'), 'serverId' => array('type' => 'string'), 'scriptOptions' => array('type' => 'array'), 'eventParams' => array('type' => 'array'), 'eventName' => array('type' => 'string')));
     $task = Scalr_SchedulerTask::init();
     if ($this->getParam('id')) {
         $task->loadById($this->getParam('id'));
         $this->user->getPermissions()->validate($task);
     } else {
         $task->accountId = $this->user->getAccountId();
         $task->envId = $this->getEnvironmentId();
         $task->status = Scalr_SchedulerTask::STATUS_ACTIVE;
     }
     $this->request->validate();
     $params = array();
     $timezone = new DateTimeZone($this->getParam('timezone'));
     $startTm = $this->getParam('startTime') ? new DateTime($this->getParam('startTimeDate') . " " . $this->getParam('startTime'), $timezone) : NULL;
     if ($startTm) {
         Scalr_Util_DateTime::convertTimeZone($startTm, NULL);
     }
     $curTm = new DateTime();
     if ($startTm && $startTm < $curTm && !$task->id) {
         $this->request->addValidationErrors('startTimeDate', array('Start time must be greater then current time'));
     }
     switch ($this->getParam('type')) {
         case Scalr_SchedulerTask::FIRE_EVENT:
         case Scalr_SchedulerTask::SCRIPT_EXEC:
             if ($this->getParam('serverId')) {
                 $dbServer = DBServer::LoadByID($this->getParam('serverId'));
                 $this->user->getPermissions()->validate($dbServer);
                 $task->targetId = $dbServer->GetFarmRoleObject()->ID;
                 $task->targetServerIndex = $dbServer->index;
                 $task->targetType = Scalr_SchedulerTask::TARGET_INSTANCE;
             } else {
                 if ($this->getParam('farmRoleId')) {
                     $dbFarmRole = DBFarmRole::LoadByID($this->getParam('farmRoleId'));
                     $this->user->getPermissions()->validate($dbFarmRole);
                     $task->targetId = $dbFarmRole->ID;
                     $task->targetType = Scalr_SchedulerTask::TARGET_ROLE;
                 } else {
                     if ($this->getParam('farmId')) {
                         $dbFarm = DBFarm::LoadByID($this->getParam('farmId'));
                         $this->user->getPermissions()->validate($dbFarm);
                         $task->targetId = $dbFarm->ID;
                         $task->targetType = Scalr_SchedulerTask::TARGET_FARM;
                     } else {
                         $this->request->addValidationErrors('farmId', array('Farm ID is required'));
                     }
                 }
             }
             if ($this->getParam('type') == Scalr_SchedulerTask::SCRIPT_EXEC) {
                 /* @var $script Script */
                 $script = Script::findPk($this->getParam('scriptId'));
                 try {
                     if ($script) {
                         $script->checkPermission($this->user, $this->getEnvironmentId());
                         $task->scriptId = $this->getParam('scriptId');
                         $params['scriptId'] = $this->getParam('scriptId');
                         $params['scriptIsSync'] = $this->getParam('scriptIsSync');
                         $params['scriptTimeout'] = $this->getParam('scriptTimeout');
                         $params['scriptVersion'] = $this->getParam('scriptVersion');
                         $params['scriptOptions'] = $this->getParam('scriptOptions');
                     } else {
                         throw new Exception();
                     }
                 } catch (Exception $e) {
                     $this->request->addValidationErrors('scriptId', array('Script ID is required'));
                 }
             } elseif ($this->getParam('type') == Scalr_SchedulerTask::FIRE_EVENT) {
                 if (!EventDefinition::findOne([['name' => $this->getParam('eventName')], ['$or' => [['accountId' => null], ['accountId' => $this->user->getAccountId()]]], ['$or' => [['envId' => null], ['envId' => $this->getEnvironmentId()]]]])) {
                     throw new Exception("Event definition not found");
                 }
                 $params['eventName'] = $this->getParam('eventName');
                 $params['eventParams'] = $this->getParam('eventParams');
             }
             break;
         case Scalr_SchedulerTask::LAUNCH_FARM:
             if ($this->getParam('farmId')) {
                 $dbFarm = DBFarm::LoadByID($this->getParam('farmId'));
                 $this->user->getPermissions()->validate($dbFarm);
                 $task->targetId = $dbFarm->ID;
                 $task->targetType = Scalr_SchedulerTask::TARGET_FARM;
             } else {
                 $this->request->addValidationErrors('farmId', array('Farm ID is required'));
             }
             break;
         case Scalr_SchedulerTask::TERMINATE_FARM:
             if ($this->getParam('farmId')) {
                 $dbFarm = DBFarm::LoadByID($this->getParam('farmId'));
                 $this->user->getPermissions()->validate($dbFarm);
                 $task->targetId = $dbFarm->ID;
                 $task->targetType = Scalr_SchedulerTask::TARGET_FARM;
             } else {
                 $this->request->addValidationErrors('farmId', array('Farm ID is required'));
             }
             $params['deleteDNSZones'] = $this->getParam('deleteDNSZones');
             $params['deleteCloudObjects'] = $this->getParam('deleteCloudObjects');
             break;
     }
     if (!$this->request->isValid()) {
         $this->response->failure();
         $this->response->data($this->request->getValidationErrors());
         return;
     }
     $task->name = $this->getParam('name');
     $task->type = $this->getParam('type');
     $task->comments = $this->getParam('comments');
     $task->timezone = $this->getParam('timezone');
     $task->startTime = $startTm ? $startTm->format('Y-m-d H:i:s') : NULL;
     //$task->endTime = $endTm ? $endTm->format('Y-m-d H:i:s') : NULL;
     $task->restartEvery = $this->getParam('restartEvery');
     $task->config = $params;
     $task->save();
     $this->response->success();
 }
Beispiel #10
0
 /**
  * {@inheritdoc}
  * @see \Scalr\Api\DataType\ApiEntityAdapter::validateEntity()
  */
 public function validateEntity($entity)
 {
     if (!$entity instanceof RoleScript) {
         throw new InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\RoleScript class"));
     }
     if ($entity->id !== null) {
         if (!RoleScript::findPk($entity->id)) {
             throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the rule with ID: %d", $entity->id));
         }
     }
     //Getting the role initiates check permissions
     $role = $this->controller->getRole($entity->roleId);
     if (!empty($entity->scriptId)) {
         if ($entity->version == ScriptVersion::LATEST_SCRIPT_VERSION) {
             $found = ScriptVersion::findOne([['scriptId' => $entity->scriptId]], null, ['version' => false]);
         } else {
             $found = ScriptVersion::findPk($entity->scriptId, $entity->version);
         }
         if (empty($found)) {
             throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find version %d of the script with ID: %d", $entity->version, $entity->scriptId));
         }
         if (Script::findPk($entity->scriptId)->os == 'windows' && $role->getOs()->family != 'windows') {
             throw new ApiErrorException(409, ErrorMessage::ERR_OS_MISMATCH, "Script OS family does not match role OS family");
         }
     }
     if (empty($entity->eventName)) {
         $entity->eventName = '*';
     } else {
         if ($entity->eventName !== '*') {
             if (array_key_exists($entity->eventName, array_merge(EVENT_TYPE::getScriptingEventsWithScope(), EventDefinition::getList($this->controller->getUser()->id, $this->controller->getEnvironment()->id))) === false) {
                 throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Could not find out the event '{$entity->eventName}'");
             }
             if ($entity->scriptType == OrchestrationRule::ORCHESTRATION_RULE_TYPE_CHEF && in_array($entity->eventName, EVENT_TYPE::getChefRestrictedEvents())) {
                 throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Chef can't be used with {$entity->eventName}");
             }
         }
     }
     if (!$this->controller->hasPermissions($entity, true)) {
         //Checks entity level write access permissions
         throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions");
     }
 }
Beispiel #11
0
 /**
  * @param   string      $eventName
  * @param   int         $farmId
  * @param   int         $farmRoleId
  * @param   string      $serverId
  * @param   JsonData    $eventParams
  * @throws  Exception
  * @throws  Scalr_Exception_InsufficientPermissions
  */
 public function xFireAction($eventName, $farmId = 0, $farmRoleId = 0, $serverId = '', JsonData $eventParams)
 {
     $this->request->restrictAccess(Acl::RESOURCE_GENERAL_CUSTOM_EVENTS, Acl::PERM_GENERAL_CUSTOM_EVENTS_FIRE);
     if (!EventDefinition::findOne([['name' => $eventName], ['$or' => [['accountId' => null], ['accountId' => $this->user->getAccountId()]]], ['$or' => [['envId' => null], ['envId' => $this->getEnvironmentId()]]]])) {
         throw new Exception("Event definition not found");
     }
     if ($serverId) {
         $dbServer = DBServer::LoadByID($serverId);
         $this->user->getPermissions()->validate($dbServer);
         $servers = array($dbServer);
     } else {
         if ($farmRoleId) {
             $dbFarmRole = DBFarmRole::LoadByID($farmRoleId);
             $this->user->getPermissions()->validate($dbFarmRole);
             $servers = $dbFarmRole->GetServersByFilter(array('status' => SERVER_STATUS::RUNNING));
         } else {
             $dbFarm = DBFarm::LoadByID($farmId);
             $this->user->getPermissions()->validate($dbFarm);
             $servers = $dbFarm->GetServersByFilter(array('status' => SERVER_STATUS::RUNNING));
         }
     }
     if (count($servers) == 0) {
         throw new Exception("No running Servers found. Event was not fired.");
     }
     foreach ($servers as $dbServer) {
         /* @var $dbServer DBServer */
         $event = new CustomEvent($dbServer, $eventName, (array) $eventParams);
         Scalr::FireEvent($dbServer->farmId, $event);
     }
     $this->response->success(sprintf("Event successfully fired on behalf of %s Server(s)", count($servers)));
 }
Beispiel #12
0
 /**
  * @test
  */
 public function testEventsFunctional()
 {
     $db = \Scalr::getDb();
     $testName = str_replace('-', '', static::getTestName());
     $events = null;
     $uri = self::getAccountApiUrl('/events');
     static::createEntity(new EventDefinition(), ['name' => 'testAccount', 'description' => 'testAccount', 'accountId' => $this->getUser()->getAccountId()]);
     // test describe pagination
     do {
         $query = [];
         if (isset($events->pagination->next)) {
             $parts = parse_url($events->pagination->next);
             parse_str($parts['query'], $query);
         }
         $describe = $this->request($uri, Request::METHOD_GET, $query);
         $this->assertDescribeResponseNotEmpty($describe);
         $this->assertNotEmpty($describe->getBody());
         $events = $describe->getBody();
         foreach ($events->data as $event) {
             $this->assertEventObjectNotEmpty($event);
             if ($event->id == $testName) {
                 $delete = $this->request($uri . '/' . $event->id, Request::METHOD_DELETE);
                 $this->assertEquals(200, $delete->status);
             }
         }
     } while (!empty($events->pagination->next));
     // test create action
     $create = $this->postEvent([]);
     $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Invalid body');
     $create = $this->postEvent(['id' => $testName, 'invalid' => 'value']);
     $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'You are trying to set');
     $create = $this->postEvent(['scope' => ScopeInterface::SCOPE_ACCOUNT]);
     $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Required field');
     $create = $this->postEvent(['id' => 'invalid*^']);
     $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid id of the Event');
     $create = $this->postEvent(['id' => $testName, 'description' => '<br>tags']);
     $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid description');
     $create = $this->postEvent(['id' => $testName, 'description' => $testName, 'scope' => ScopeInterface::SCOPE_ACCOUNT]);
     $body = $create->getBody();
     $this->assertEquals(201, $create->response->getStatus());
     $this->assertFetchResponseNotEmpty($create);
     $this->assertEventObjectNotEmpty($body->data);
     $this->assertNotEmpty($body->data->id);
     $this->assertEquals($testName, $body->data->id);
     $this->assertEquals($testName, $body->data->description);
     $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $body->data->scope);
     $createSame = $this->postEvent(['id' => $testName, 'description' => $testName, 'scope' => ScopeInterface::SCOPE_ACCOUNT]);
     $this->assertErrorMessageContains($createSame, 409, ErrorMessage::ERR_UNICITY_VIOLATION);
     //test event with same id already exists in other scope
     static::createEntity(new EventDefinition(), ['name' => 'testEnvAccount', 'description' => 'testEnvAccount', 'envId' => $this->getEnvironment()->id, 'accountId' => $this->getUser()->getAccountId()]);
     $scopeConflict = $this->postEvent(['id' => 'testEnvAccount', 'description' => 'testEnvAccount-scope-conflict', 'scope' => ScopeInterface::SCOPE_ACCOUNT]);
     $this->assertErrorMessageContains($scopeConflict, 409, ErrorMessage::ERR_UNICITY_VIOLATION);
     //test lower-scope replacement
     $replace = $this->postEvent(['id' => 'testEnvAccount', 'description' => 'testEnvAccount-scope-replace', 'scope' => ScopeInterface::SCOPE_ACCOUNT], false, ['replace' => true]);
     $this->assertEquals(201, $replace->response->getStatus());
     $dbEvents = EventDefinition::find([['name' => 'testEnvAccount'], ['accountId' => $this->getUser()->getAccountId()]]);
     $this->assertEquals(1, count($dbEvents));
     /* @var $dbEvent EventDefinition */
     foreach ($dbEvents as $dbEvent) {
         $this->assertEquals(null, $dbEvent->envId);
     }
     // test filtering
     $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, 'Invalid scope value');
     $describe = $this->request($uri, Request::METHOD_GET, ['scope' => ScopeInterface::SCOPE_ACCOUNT]);
     $this->assertDescribeResponseNotEmpty($describe);
     foreach ($describe->getBody()->data as $data) {
         $this->assertEventObjectNotEmpty($data);
         $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $data->scope);
     }
     $describe = $this->request($uri, Request::METHOD_GET, ['id' => $testName]);
     $this->assertDescribeResponseNotEmpty($describe);
     foreach ($describe->getBody()->data as $data) {
         $this->assertEventObjectNotEmpty($data);
         $this->assertEquals($testName, $data->id);
     }
     // test fetch action
     $eventId = $body->data->id;
     $fetch = $this->request($uri . '/' . $eventId . 'invalid', Request::METHOD_GET);
     $this->assertErrorMessageContains($fetch, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND, 'The Event either does not exist');
     $fetch = $this->request($uri . '/' . $eventId, Request::METHOD_GET);
     $fetchBody = $fetch->getBody();
     $this->assertEquals(200, $fetch->response->getStatus());
     $this->assertFetchResponseNotEmpty($fetch);
     $this->assertEventObjectNotEmpty($fetchBody->data);
     $this->assertEquals($testName, $fetchBody->data->id);
     $this->assertEquals($testName, $fetchBody->data->description);
     $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $fetchBody->data->scope);
     // test modify action
     $modify = $this->request($uri . '/' . $eventId, Request::METHOD_PATCH);
     $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Invalid body');
     $scalrEventId = $db->GetOne("SELECT e.name FROM event_definitions e WHERE e.env_id IS NULL AND e.account_id IS NULL");
     if (!empty($scalrEventId)) {
         $fetch = $this->request($uri . '/' . $scalrEventId, Request::METHOD_PATCH, [], ['description' => '']);
         $this->assertErrorMessageContains($fetch, 403, ErrorMessage::ERR_SCOPE_VIOLATION);
     }
     $modify = $this->request($uri . '/' . $eventId, Request::METHOD_PATCH, [], ['scope' => ScopeInterface::SCOPE_ENVIRONMENT]);
     $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'You are trying to set the property');
     $modify = $this->request($uri . '/' . $eventId, Request::METHOD_PATCH, [], ['description' => '']);
     $modifyBody = $modify->getBody();
     $this->assertEquals(200, $modify->response->getStatus());
     $this->assertFetchResponseNotEmpty($modify);
     $this->assertEventObjectNotEmpty($modifyBody->data);
     $this->assertEquals($testName, $modifyBody->data->id);
     $this->assertEquals('', $modifyBody->data->description);
     $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $modifyBody->data->scope);
     // test delete action
     if (!empty($scalrEventId)) {
         $delete = $this->request($uri . '/' . $scalrEventId, Request::METHOD_DELETE);
         $this->assertErrorMessageContains($delete, 403, ErrorMessage::ERR_SCOPE_VIOLATION);
     }
     $delete = $this->request($uri . '/' . $eventId, Request::METHOD_DELETE);
     $this->assertEquals(200, $delete->status);
 }
Beispiel #13
0
 /**
  * Creates new event in current scope
  *
  * @return \Scalr\Api\DataType\ResultEnvelope
  * @throws ApiErrorException
  * @throws \Scalr\Exception\ModelException
  */
 public function createAction()
 {
     $this->checkPermissions(Acl::RESOURCE_GENERAL_CUSTOM_EVENTS);
     $object = $this->request->getJsonBody();
     $eventAdapter = $this->adapter('event');
     //Pre validates the request object
     $eventAdapter->validateObject($object, Request::METHOD_POST);
     if (empty($object->id)) {
         throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Required field 'id' is missing.");
     }
     $object->scope = $this->getScope();
     $criteria = $this->getDefaultCriteria();
     $criteria[] = ['name' => $object->id];
     /* @var $oldEvent Entity\EventDefinition */
     $oldEvent = Entity\EventDefinition::findOne($criteria);
     if (!empty($oldEvent)) {
         throw new ApiErrorException(409, ErrorMessage::ERR_UNICITY_VIOLATION, sprintf('Event with id %s already exists', $object->id));
     }
     /* @var $event Entity\EventDefinition */
     //Converts object into EventDefinition entity
     $event = $eventAdapter->toEntity($object);
     $event->id = null;
     $eventAdapter->validateEntity($event);
     //Saves entity
     $event->save();
     //Responds with 201 Created status
     $this->response->setStatus(201);
     return $this->result($eventAdapter->toData($event));
 }
 /**
  * {@inheritdoc}
  * @see ApiEntityAdapter::validateEntity()
  */
 public function validateEntity($entity)
 {
     /* @var $entity OrchestrationRule */
     $entityClass = $this->entityClass;
     if (!$entity instanceof $entityClass) {
         throw new InvalidArgumentException(sprintf("First argument must be instance of {$entityClass} class"));
     }
     if ($entity->id !== null) {
         if (!$entityClass::findPk($entity->id)) {
             throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the rule with ID: %d", $entity->id));
         }
     }
     if (!empty($entity->scriptId)) {
         if ($entity->version == ScriptVersion::LATEST_SCRIPT_VERSION) {
             $found = ScriptVersion::findOne([['scriptId' => $entity->scriptId]], null, ['version' => false]);
         } else {
             $found = ScriptVersion::findPk($entity->scriptId, $entity->version);
         }
         /* @var $found ScriptVersion */
         if (empty($found) || !$found->hasAccessPermissions($this->controller->getUser(), $this->controller->getEnvironment())) {
             throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find version %d of the script with ID: %d", $entity->version, $entity->scriptId));
         }
     }
     if (empty($entity->eventName)) {
         $entity->eventName = '*';
     } else {
         if ($entity->eventName !== '*') {
             if (array_key_exists($entity->eventName, array_merge(EVENT_TYPE::getScriptingEventsWithScope(), EventDefinition::getList($this->controller->getUser()->id, $this->controller->getScope() === ScopeInterface::SCOPE_ENVIRONMENT ? $this->controller->getEnvironment()->id : null))) === false) {
                 throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Could not find out the event '{$entity->eventName}'");
             }
             if ($entity->scriptType == OrchestrationRule::ORCHESTRATION_RULE_TYPE_CHEF && in_array($entity->eventName, EVENT_TYPE::getChefRestrictedEvents())) {
                 throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Chef can't be used with {$entity->eventName}");
             }
             if ($entity->eventName == EVENT_TYPE::BEFORE_INSTANCE_LAUNCH && $entity->target == Script::TARGET_INSTANCE) {
                 throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Event '{$entity->eventName}' will never be handled by the triggering server");
             }
         }
     }
     if (!$this->controller->hasPermissions($entity, true)) {
         //Checks entity level write access permissions
         throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions");
     }
 }