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'); } } }
/** * {@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")); } }
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; }
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]); }
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; }
public static function getScriptingData($accountId, $envId) { return ['events' => array_merge(\EVENT_TYPE::getScriptingEventsWithScope(), EventDefinition::getList($accountId, $envId)), 'scripts' => static::getList($accountId, $envId)]; }
/** * 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)); }
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(); }
/** * {@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"); } }
/** * @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))); }
/** * @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); }
/** * 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"); } }