Since: 5.0 (11.02.2014)
Author: Vitaliy Demidov (vitaliy@scalr.com)
Inheritance: extends Scalr\Model\AbstractEntity, implements Scalr\DataType\AccessPermissionsInterface
Example #1
0
 public function _billingCode($from, $to, $action)
 {
     switch ($action) {
         case static::ACT_CONVERT_TO_OBJECT:
             /* @var $from ProjectEntity */
             $to->billingCode = $from->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE);
             break;
         case static::ACT_CONVERT_TO_ENTITY:
             /* @var $to ProjectEntity */
             break;
         case static::ACT_GET_FILTER_CRITERIA:
             $project = new ProjectEntity();
             $property = new ProjectPropertyEntity();
             return [AbstractEntity::STMT_FROM => $project->table() . " LEFT JOIN " . $property->table() . " ON {$property->columnProjectId} = {$project->columnProjectId}", AbstractEntity::STMT_WHERE => "{$property->columnName} = '" . ProjectPropertyEntity::NAME_BILLING_CODE . "' AND {$property->columnValue} = " . $property->qstr('value', $from->billingCode)];
     }
 }
Example #2
0
 public function defaultAction()
 {
     $ccs = array();
     $projects = array();
     foreach (CostCentreEntity::find([['archived' => 0]]) as $cc) {
         $ccs[$cc->ccId] = $cc->name;
     }
     foreach (ProjectEntity::find([['archived' => 0]]) as $project) {
         $projects[$project->projectId] = $project->name;
     }
     $this->response->page('ui/admin/analytics/notifications/view.js', array('notifications.ccs' => NotificationEntity::findBySubjectType(NotificationEntity::SUBJECT_TYPE_CC)->getArrayCopy(), 'notifications.projects' => NotificationEntity::findBySubjectType(NotificationEntity::SUBJECT_TYPE_PROJECT)->getArrayCopy(), 'reports' => ReportEntity::all()->getArrayCopy(), 'ccs' => $ccs, 'projects' => $projects), array(), array('ui/admin/analytics/notifications/view.css'));
 }
Example #3
0
 public function defaultAction()
 {
     $ccs = array();
     $projects = array();
     foreach (CostCentreEntity::find([['archived' => 0]]) as $cc) {
         $ccs[$cc->ccId] = $cc->name;
     }
     foreach (ProjectEntity::find([['archived' => 0]]) as $project) {
         $projects[$project->projectId] = $project->name;
     }
     $this->response->page('ui/analytics/notifications/view.js', array('notifications.ccs' => array('enabled' => SettingEntity::getValue(SettingEntity::ID_NOTIFICATIONS_CCS_ENABLED), 'items' => NotificationEntity::findBySubjectType(NotificationEntity::SUBJECT_TYPE_CC)), 'notifications.projects' => array('enabled' => SettingEntity::getValue(SettingEntity::ID_NOTIFICATIONS_PROJECTS_ENABLED), 'items' => NotificationEntity::findBySubjectType(NotificationEntity::SUBJECT_TYPE_PROJECT)), 'reports' => array('enabled' => SettingEntity::getValue(SettingEntity::ID_REPORTS_ENABLED), 'items' => ReportEntity::all()), 'ccs' => $ccs, 'projects' => $projects), array(), array());
 }
Example #4
0
 /**
  * Gets specified Script taking into account both scope and authentication token
  *
  * @param   string  $projectId  Unique identifier of the project
  *
  * @return ProjectEntity Returns the Project Entity on success
  * @throws ApiErrorException
  */
 public function getProject($projectId)
 {
     /* @var $project ProjectEntity */
     $project = ProjectEntity::findPk($projectId);
     if (!$project) {
         throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Requested Project either does not exist or is not owned by your environment.");
     }
     if (!$this->hasPermissions($project)) {
         //Checks entity level write access permissions
         throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions");
     }
     return $project;
 }
Example #5
0
 /**
  * Constructor
  *
  * @param   \DBFarm    $farm          The DBFarm instance
  * @param   string     $projectId     The uuid of the project
  */
 public function __construct(DBFarm $farm, $projectId)
 {
     parent::__construct();
     $projectEntity = ProjectEntity::findPk($projectId);
     $this->projects[] = $projectId;
     if ($projectEntity) {
         $this->ccs[] = $projectEntity->ccId;
         $projectName = $projectEntity->name;
     } else {
         $projectName = AccountTagEntity::fetchName($projectId, TagEntity::TAG_ID_PROJECT);
     }
     $this->message = sprintf("User %s assigned a new farm '%s' id:%d to the project '%s'", strip_tags($this->getUserEmail()), strip_tags($farm->Name), $farm->ID, strip_tags($projectName));
     $this->messageToHash = sprintf('%s|%s|%s|%s', $this->timelineEvent->dtime->format('Y-m-d'), $this->getUserEmail(), $farm->ID, $projectId);
 }
Example #6
0
 public function defaultAction()
 {
     $ccs = [];
     $projects = [];
     foreach (CostCentreEntity::find([['archived' => 0]]) as $cc) {
         /* @var $cc CostCentreEntity */
         $ccs[$cc->ccId] = $cc->name;
     }
     foreach (ProjectEntity::find([['archived' => 0]]) as $project) {
         /* @var $project ProjectEntity */
         $projects[$project->projectId] = $project->name;
     }
     $this->response->page('ui/admin/analytics/notifications/view.js', ['notifications.ccs' => NotificationEntity::findBySubjectType(NotificationEntity::SUBJECT_TYPE_CC)->getArrayCopy(), 'notifications.projects' => NotificationEntity::find([['subjectType' => NotificationEntity::SUBJECT_TYPE_PROJECT], ['accountId' => null]])->getArrayCopy(), 'reports' => ReportEntity::find([['accountId' => null]])->getArrayCopy(), 'ccs' => $ccs, 'projects' => $projects], [], ['ui/admin/analytics/notifications/view.css']);
 }
Example #7
0
 /**
  * Constructor
  *
  * @param   \DBFarm    $farm              The DBFarm instance
  * @param   string     $projectId         The identifier of the project to assign
  * @param   string     $oldProjectId      The identifier of the old project which is replaced
  */
 public function __construct(DBFarm $farm, $projectId, $oldProjectId)
 {
     parent::__construct();
     array_push($this->projects, $projectId, $oldProjectId);
     $projectEntity = ProjectEntity::findPk($projectId);
     if ($projectEntity) {
         $this->ccs[$projectEntity->ccId] = $projectEntity->ccId;
         $projectName = $projectEntity->name;
     } else {
         $projectName = AccountTagEntity::fetchName($projectId, TagEntity::TAG_ID_PROJECT);
     }
     $oldProjectEntity = ProjectEntity::findPk($oldProjectId);
     if ($oldProjectEntity) {
         $this->ccs[$oldProjectEntity->ccId] = $oldProjectEntity->ccId;
         $oldProjectName = $oldProjectEntity->name;
     } else {
         $oldProjectName = AccountTagEntity::fetchName($oldProjectId, TagEntity::TAG_ID_PROJECT);
     }
     $this->message = sprintf("User %s replaced project '%s' with project '%s' in the farm '%s' id:%d", strip_tags($this->getUserEmail()), strip_tags($oldProjectName), strip_tags($projectName), strip_tags($farm->Name), $farm->ID);
     $this->messageToHash = sprintf('%s|%s|%s|%s|%s', $this->timelineEvent->dtime->format('Y-m-d'), $this->getUserEmail(), $oldProjectId, $projectId, $farm->ID);
 }
Example #8
0
 /**
  * @test
  */
 public function testComplex()
 {
     //create archived project
     $projectArch = $this->createTestProject(['name' => $this->getTestName(), 'archived' => ProjectEntity::ARCHIVED]);
     $projects = $this->listProjects([], 1);
     $adapter = $this->getAdapter('project');
     $filterable = $adapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE];
     foreach ($projects as $project) {
         foreach ($filterable as $property) {
             $filterValue = $project->{$property};
             $listResult = $this->listProjects([$property => $filterValue], 1);
             if (!empty($filterValue)) {
                 foreach ($listResult as $filtered) {
                     $this->assertEquals($filterValue, $filtered->{$property}, "Property '{$property}' mismatch");
                 }
             }
         }
         $response = $this->getProject($project->id);
         $this->assertEquals(200, $response->status, $this->printResponseError($response));
         $dbProject = ProjectEntity::findPk($project->id);
         $this->assertFalse((bool) $dbProject->archived);
         $this->assertObjectEqualsEntity($response->getBody()->data, $dbProject, $adapter);
     }
     $filterByName = $this->listProjects(['name' => $projectArch->name], 1);
     $this->assertNotEmpty($filterByName);
     foreach ($filterByName as $project) {
         $this->assertObjectEqualsEntity($project, $projectArch, $adapter);
         $this->assertNotContains($project, $projects, "List of project shouldn't  have an archived project", false, false);
     }
     $filterByBillingCode = $this->listProjects(['billingCode' => $projectArch->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE)], 1);
     $this->assertNotEmpty($filterByBillingCode);
     foreach ($filterByBillingCode as $project) {
         $this->assertObjectEqualsEntity($project, $projectArch, $adapter);
         $this->assertNotContains($project, $projects, "List of project shouldn't  have an archived project", false, false);
     }
     $ccId = Scalr_Environment::init()->loadById($this->getEnvironment()->id)->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID);
     $cc = \Scalr::getContainer()->analytics->ccs->get($ccId);
     //test create project
     $projectData = ['name' => 'test', 'costCenter' => ['id' => $ccId], 'billingCode' => $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE), 'leadEmail' => '*****@*****.**', 'description' => 'test'];
     $response = $this->postProject($projectData);
     $this->assertEquals(201, $response->status, $this->printResponseError($response));
     $projectId = $response->getBody()->data->id;
     $dbProject = ProjectEntity::findPk($projectId);
     $this->assertNotEmpty($dbProject);
     $this->projectToDelete($projectId);
     $this->assertObjectEqualsEntity($projectData, $dbProject, $adapter);
     //test empty project name
     $projectData = ['name' => "\t\r\n\v<a href=\"#\">\t\r\n\v</a>\t\r\n\v", 'costCenter' => ['id' => $ccId], 'billingCode' => $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE), 'leadEmail' => '*****@*****.**', 'description' => 'test-empty-name'];
     $response = $this->postProject($projectData);
     $this->assertEquals(400, $response->status, $this->printResponseError($response));
     //test wrong ccId
     $projectData = ['name' => "test-wrong-cc-id", 'costCenter' => ['id' => "\t\r\n\v<a href=\"#\">\t\r\n\v</a>\t\r\n\v"], 'billingCode' => $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE), 'leadEmail' => '*****@*****.**', 'description' => 'test-empty-name'];
     $response = $this->postProject($projectData);
     $this->assertEquals(404, $response->status, $this->printResponseError($response));
     //test wrong leadEmail
     $projectData = ['name' => "test-wrong-cc-id", 'costCenter' => ['id' => $ccId], 'billingCode' => $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE), 'leadEmail' => "\t\r\n\v<a href=\"#\">\t\r\n\v</a>\t\r\n\v", 'description' => 'test-empty-lead-email'];
     $response = $this->postProject($projectData);
     $this->assertEquals(400, $response->status, $this->printResponseError($response));
 }
Example #9
0
 /**
  * Launches server
  *
  * @param   \ServerCreateInfo       $ServerCreateInfo optional The server create info
  * @param   \DBServer               $DBServer         optional The DBServer object
  * @param   bool                    $delayed          optional
  * @param   integer|array            $reason           optional
  * @param   \Scalr_Account_User|int $user             optional The Scalr_Account_User object or its unique identifier
  * @return  DBServer|null           Returns the DBServer object on cussess or null otherwise
  */
 public static function LaunchServer(ServerCreateInfo $ServerCreateInfo = null, DBServer $DBServer = null, $delayed = false, $reason = 0, $user = null)
 {
     $db = self::getDb();
     $farm = null;
     //Ensures handling identifier of the user instead of the object
     if ($user !== null && !$user instanceof \Scalr_Account_User) {
         try {
             $user = Scalr_Account_User::init()->loadById(intval($user));
         } catch (\Exception $e) {
         }
     }
     if (!$DBServer && $ServerCreateInfo) {
         $ServerCreateInfo->SetProperties(array(SERVER_PROPERTIES::SZR_KEY => Scalr::GenerateRandomKey(40), SERVER_PROPERTIES::SZR_KEY_TYPE => SZR_KEY_TYPE::ONE_TIME));
         $DBServer = DBServer::Create($ServerCreateInfo, false, true);
     } elseif (!$DBServer && !$ServerCreateInfo) {
         // incorrect arguments
         Logger::getLogger(LOG_CATEGORY::FARM)->error(sprintf("Cannot create server"));
         return null;
     }
     $propsToSet = array();
     if ($user instanceof \Scalr_Account_User) {
         $propsToSet[SERVER_PROPERTIES::LAUNCHED_BY_ID] = $user->id;
         $propsToSet[SERVER_PROPERTIES::LAUNCHED_BY_EMAIL] = $user->getEmail();
     }
     //We should keep role_id and farm_role_id in server properties to use in cost analytics
     if (!empty($DBServer->farmRoleId)) {
         $propsToSet[SERVER_PROPERTIES::FARM_ROLE_ID] = $DBServer->farmRoleId;
         $propsToSet[SERVER_PROPERTIES::ROLE_ID] = $DBServer->farmRoleId ? $DBServer->GetFarmRoleObject()->RoleID : 0;
     }
     try {
         // Ensures the farm object will be fetched as correctly as possible
         $farm = $DBServer->farmId ? $DBServer->GetFarmObject() : null;
         $farmRole = $DBServer->farmRoleId ? $DBServer->GetFarmRoleObject() : null;
         if (!$farmRole instanceof DBFarmRole) {
             $farmRole = null;
         } else {
             if (!$farm instanceof DBFarm) {
                 // Gets farm through FarmRole object in this case
                 $farm = $farmRole->GetFarmObject();
             }
         }
         if ($farm instanceof DBFarm) {
             $propsToSet[SERVER_PROPERTIES::FARM_CREATED_BY_ID] = $farm->createdByUserId;
             $propsToSet[SERVER_PROPERTIES::FARM_CREATED_BY_EMAIL] = $farm->createdByUserEmail;
             $projectId = $farm->GetSetting(DBFarm::SETTING_PROJECT_ID);
             if (!empty($projectId)) {
                 try {
                     $projectEntity = ProjectEntity::findPk($projectId);
                     if ($projectEntity instanceof ProjectEntity) {
                         /* @var $projectEntity ProjectEntity */
                         $ccId = $projectEntity->ccId;
                     } else {
                         $projectId = null;
                     }
                 } catch (Exception $e) {
                     $projectId = null;
                 }
             }
             $propsToSet[SERVER_PROPERTIES::FARM_PROJECT_ID] = $projectId;
         }
         if ($farmRole instanceof DBFarmRole) {
             $propsToSet[SERVER_PROPERTIES::INFO_INSTANCE_TYPE_NAME] = $farmRole->GetSetting(DBFarmRole::SETTING_INFO_INSTANCE_TYPE_NAME);
         }
         if (!empty($ccId)) {
             $propsToSet[SERVER_PROPERTIES::ENV_CC_ID] = $ccId;
         } elseif ($DBServer->envId && ($environment = $DBServer->GetEnvironmentObject()) instanceof Scalr_Environment) {
             $propsToSet[SERVER_PROPERTIES::ENV_CC_ID] = $environment->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID);
         }
     } catch (Exception $e) {
         Logger::getLogger(LOG_CATEGORY::FARM)->error(sprintf("Could not load related object for recently created server %s. It says: %s", $DBServer->serverId, $e->getMessage()));
     }
     if (!empty($propsToSet)) {
         $DBServer->SetProperties($propsToSet);
     }
     $fnGetReason = function ($reasonId) {
         $args = func_get_args();
         $args[0] = DBServer::getLaunchReason($reasonId);
         return [call_user_func_array('sprintf', $args), $reasonId];
     };
     if ($delayed) {
         $DBServer->status = SERVER_STATUS::PENDING_LAUNCH;
         list($reasonMsg, $reasonId) = is_array($reason) ? call_user_func_array($fnGetReason, $reason) : $fnGetReason($reason);
         $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_REASON => $reasonMsg, SERVER_PROPERTIES::LAUNCH_REASON_ID => $reasonId]);
         $DBServer->Save();
         return $DBServer;
     }
     if ($ServerCreateInfo && $ServerCreateInfo->roleId) {
         $dbRole = DBRole::loadById($ServerCreateInfo->roleId);
         if ($dbRole->generation == 1) {
             $DBServer->status = SERVER_STATUS::PENDING_LAUNCH;
             $DBServer->Save();
             $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ERROR => "ami-scripts servers no longer supported", SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
             return $DBServer;
         }
     }
     // Limit amount of pending servers
     if ($DBServer->isOpenstack()) {
         $config = \Scalr::getContainer()->config;
         if ($config->defined("scalr.{$DBServer->platform}.pending_servers_limit")) {
             $pendingServersLimit = $config->get("scalr.{$DBServer->platform}.pending_servers_limit");
             $pendingServers = $db->GetOne("SELECT COUNT(*) FROM servers WHERE platform=? AND status=? AND server_id != ?", array($DBServer->platform, SERVER_STATUS::PENDING, $DBServer->serverId));
             if ($pendingServers >= $pendingServersLimit) {
                 Logger::getLogger("SERVER_LAUNCH")->warn("{$pendingServers} servers in PENDING state on {$DBServer->platform}. Limit is: {$pendingServersLimit}. Waiting.");
                 $DBServer->status = SERVER_STATUS::PENDING_LAUNCH;
                 $DBServer->Save();
                 $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
                 return $DBServer;
             } else {
                 Logger::getLogger("SERVER_LAUNCH")->warn("{$pendingServers} servers in PENDING state on {$DBServer->platform}. Limit is: {$pendingServersLimit}. Launching server.");
             }
         }
     }
     try {
         $account = Scalr_Account::init()->loadById($DBServer->clientId);
         $account->validateLimit(Scalr_Limits::ACCOUNT_SERVERS, 1);
         PlatformFactory::NewPlatform($DBServer->platform)->LaunchServer($DBServer);
         $DBServer->status = SERVER_STATUS::PENDING;
         $DBServer->Save();
         try {
             if ($reason) {
                 list($reasonMsg, $reasonId) = is_array($reason) ? call_user_func_array($fnGetReason, $reason) : $fnGetReason($reason);
             } else {
                 $reasonMsg = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_REASON);
                 $reasonId = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_REASON_ID);
             }
             $DBServer->getServerHistory()->markAsLaunched($reasonMsg, $reasonId);
             $DBServer->updateTimelog('ts_launched');
             if ($DBServer->imageId) {
                 //Update Image last used date
                 $image = Image::findOne([['id' => $DBServer->imageId], ['envId' => $DBServer->envId], ['platform' => $DBServer->platform], ['cloudLocation' => $DBServer->cloudLocation]]);
                 if (!$image) {
                     $image = Image::findOne([['id' => $DBServer->imageId], ['envId' => NULL], ['platform' => $DBServer->platform], ['cloudLocation' => $DBServer->cloudLocation]]);
                 }
                 if ($image) {
                     $image->dtLastUsed = new DateTime();
                     $image->save();
                 }
                 //Update Role last used date
                 if ($DBServer->farmRoleId) {
                     $dbRole = $DBServer->GetFarmRoleObject()->GetRoleObject();
                     $dbRole->dtLastUsed = date("Y-m-d H:i:s");
                     $dbRole->save();
                 }
             }
         } catch (Exception $e) {
             Logger::getLogger('SERVER_HISTORY')->error(sprintf("Cannot update servers history: {$e->getMessage()}"));
         }
     } catch (Exception $e) {
         Logger::getLogger(LOG_CATEGORY::FARM)->error(new FarmLogMessage($DBServer->farmId, sprintf("Cannot launch server on '%s' platform: %s", $DBServer->platform, $e->getMessage()), $DBServer->serverId));
         $existingLaunchError = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ERROR);
         $DBServer->status = SERVER_STATUS::PENDING_LAUNCH;
         $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ERROR => $e->getMessage(), SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
         $DBServer->Save();
         if ($DBServer->farmId && !$existingLaunchError) {
             Scalr::FireEvent($DBServer->farmId, new InstanceLaunchFailedEvent($DBServer, $e->getMessage()));
         }
     }
     if ($DBServer->status == SERVER_STATUS::PENDING) {
         Scalr::FireEvent($DBServer->farmId, new BeforeInstanceLaunchEvent($DBServer));
         $DBServer->SetProperty(SERVER_PROPERTIES::LAUNCH_ERROR, "");
     }
     return $DBServer;
 }
Example #10
0
 /**
  * Gets relation dependent budget
  *
  * Another words it will return total budgeted amount for all projects
  * which have relations to the cost center.
  *
  * If we use this method for the project it will return 0
  *
  * @return  float  Returns relation dependent budget amount according to current state in the database
  */
 public function getRelationDependentBudget()
 {
     if (empty($this->subjectId)) {
         throw new InvalidArgumentException(sprintf("Identifier of the subject has not been provided for the %s", get_class($this)));
     }
     //Projects have no descendants
     if ($this->subjectType == self::SUBJECT_TYPE_PROJECT) {
         return 0;
     }
     $params = [$this->year, self::SUBJECT_TYPE_PROJECT];
     $stmt = '';
     foreach (ProjectEntity::findByCcId($this->subjectId) as $project) {
         $stmt .= ", " . $this->qstr('subjectId', $project->projectId);
     }
     if ($stmt != '') {
         $ret = $this->db()->GetOne("\n                SELECT SUM(q.`budget`) AS `budget`\n                FROM " . $this->table('q') . "\n                WHERE q.`year` = ?\n                AND q.`subject_type` = ?\n                " . (is_numeric($this->quarter) ? " AND q.`quarter` =" . intval($this->quarter) : "") . "\n                AND q.`subject_id` IN (" . ltrim($stmt, ',') . ")\n            ", $params);
     } else {
         $ret = 0.0;
     }
     return $ret;
 }
Example #11
0
 /**
  * Gets project properties and parameters
  *
  * @param   ProjectEntity    $projectEntity          Project entity
  * @param   string           $calculate   optional Whether response should be adjusted with cost usage data
  * @return  array Returns cost centre properties and parameters
  */
 private function getProjectData(ProjectEntity $projectEntity, $calculate = false)
 {
     $ret = array('ccId' => $projectEntity->ccId, 'ccName' => $projectEntity->getCostCenter() !== null ? $projectEntity->getCostCenter()->name : null, 'projectId' => $projectEntity->projectId, 'name' => $projectEntity->name, 'billingCode' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE), 'description' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_DESCRIPTION), 'leadEmail' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL), 'created' => $projectEntity->created->format('Y-m-d'), 'createdByEmail' => $projectEntity->createdByEmail, 'archived' => $projectEntity->archived, 'farmsCount' => count($projectEntity->getFarmsList()));
     if ($calculate) {
         $iterator = new ChartPeriodIterator('month', gmdate('Y-m-01'), null, 'UTC');
         $usage = $this->getContainer()->analytics->usage->get(['projectId' => $ret['projectId']], $iterator->getStart(), $iterator->getEnd());
         //It calculates usage for previous period same days
         $prevusage = $this->getContainer()->analytics->usage->get(['projectId' => $ret['projectId']], $iterator->getPreviousStart(), $iterator->getPreviousEnd());
         //Calclulates usage for previous whole period
         if ($iterator->getPreviousEnd() != $iterator->getWholePreviousPeriodEnd()) {
             $prevWholePeriodUsage = $this->getContainer()->analytics->usage->get(['projectId' => $ret['projectId']], $iterator->getPreviousStart(), $iterator->getWholePreviousPeriodEnd());
         } else {
             $prevWholePeriodUsage = $prevusage;
         }
         $ret = $this->getWrappedUsageData(['ccId' => $ret['ccId'], 'projectId' => $ret['projectId'], 'iterator' => $iterator, 'usage' => $usage['cost'], 'prevusage' => $prevusage['cost'], 'prevusagewhole' => $prevWholePeriodUsage['cost']]) + $ret;
     }
     return $ret;
 }
Example #12
0
 /**
  * Gets all projects associated with the cost centre
  *
  * @return  ArrayCollection  Returns collection of the ProjectEntity objects
  */
 public function getProjects()
 {
     return ProjectEntity::result(self::RESULT_ENTITY_COLLECTION)->findByCcId($this->ccId);
 }
Example #13
0
 /**
  * xMoveProjectsAction
  *
  * @param JsonData $projects Projects that should be moved
  * @throws AnalyticsException
  * @throws Exception
  * @throws \Scalr\Exception\ModelException
  */
 public function xMoveProjectsAction(JsonData $projects = null)
 {
     $envChange = [];
     $accountChange = [];
     $projectChange = [];
     $ccEntityCache = [];
     $collisions = [];
     foreach ($projects as $project) {
         $projectEntity = ProjectEntity::findPk($project['projectId']);
         /* @var $projectEntity ProjectEntity */
         if (empty($ccEntity)) {
             $ccEntity = $projectEntity->getCostCenter();
         }
         if ($ccEntity->ccId == $project['ccId']) {
             continue;
         }
         if (empty($ccEntityCache[$project['ccId']])) {
             $newCcEntity = CostCentreEntity::findPk($project['ccId']);
             /* @var $newCcEntity CostCentreEntity */
             if (!$newCcEntity) {
                 throw new Exception(sprintf("Cost center with id %s has not been found.", $project['ccId']), 404);
             }
             $ccEntityCache[$project['ccId']] = $newCcEntity->ccId;
         }
         $farms[$projectEntity->projectId] = $projectEntity->getFarmsList();
         foreach ($farms[$projectEntity->projectId] as $farmId => $farmName) {
             $farmEntity = Farm::findPk($farmId);
             /* @var $farmEntity Farm */
             if (empty($accountChange[$farmEntity->accountId])) {
                 $accountCss = AccountCostCenterEntity::findOne([['accountId' => $farmEntity->accountId], ['ccId' => $newCcEntity->ccId]]);
                 if (!$accountCss) {
                     $accountChange[$farmEntity->accountId] = $newCcEntity->ccId;
                 }
             }
             if (empty($envChange[$farmEntity->envId])) {
                 $project['name'] = $projectEntity->name;
                 $envChange[$farmEntity->envId] = $project;
             } else {
                 if ($envChange[$farmEntity->envId]['ccId'] != $project['ccId']) {
                     if (!in_array($projectEntity->name, $collisions)) {
                         $collisions[] = $projectEntity->name;
                     }
                     if (!in_array($envChange[$farmEntity->envId]['name'], $collisions)) {
                         $collisions[] = $envChange[$farmEntity->envId]['name'];
                     }
                     continue;
                 }
             }
         }
         $projectEntity->ccId = $project['ccId'];
         $projectChange[$projectEntity->projectId] = $projectEntity;
     }
     $remainningEnvs = [];
     $projectsCount = count($projectChange);
     if ($projectsCount) {
         if (isset($ccEntity)) {
             $envList = $ccEntity->getEnvironmentsList();
             foreach ($envList as $envId => $name) {
                 if (isset($envChange[$envId])) {
                     $ccProjects = $this->getContainer()->analytics->projects->getUsedInEnvironment($envId);
                     foreach ($ccProjects as $project) {
                         /* @var $project ProjectEntity */
                         if (!isset($farms[$project->projectId])) {
                             $farms[$project->projectId] = $project->getFarmsList();
                         }
                         if (count($farms[$project->projectId]) > 0 && !isset($projectChange[$project->projectId])) {
                             if (!in_array($envId, $remainningEnvs)) {
                                 $remainningEnvs[] = $envId;
                             }
                         }
                     }
                 }
             }
         }
         $this->db->BeginTrans();
         try {
             foreach ($accountChange as $accountId => $ccId) {
                 $accountCss = new AccountCostCenterEntity($accountId, $ccId);
                 $accountCss->save();
             }
             if (empty($remainningEnvs) && empty($collisions)) {
                 foreach ($envChange as $envId => $data) {
                     $envProp = EnvironmentProperty::findOne([['envId' => $envId], ['name' => EnvironmentProperty::SETTING_CC_ID]]);
                     /* @var $envProp EnvironmentProperty */
                     $envProp->value = $data['ccId'];
                     $envProp->save();
                 }
             }
             foreach ($projectChange as $project) {
                 /* @var $project ProjectEntity */
                 $project->save();
             }
             $this->db->CommitTrans();
         } catch (Exception $e) {
             $this->db->RollbackTrans();
             throw $e;
         }
     }
     if (count($collisions) > 0) {
         $this->response->warning(sprintf("%d Project%s %s been moved however collision occurred. Projects '%s' are used in the Farms from the same Environment however they have been moved to different Cost Centers.", $projectsCount, $projectsCount > 1 ? 's' : '', $projectsCount > 1 ? 'have' : 'has', implode("', '", $collisions)));
     } else {
         if (count($remainningEnvs) > 0) {
             $this->response->warning(sprintf("%d Project%s %s been moved however some Projects don't correspond to Cost Centers assigned to Environments '%s'.", $projectsCount, $projectsCount > 1 ? 's' : '', $projectsCount > 1 ? 'have' : 'has', implode("', '", $remainningEnvs)));
         } else {
             $this->response->success(sprintf("%d Project%s %s been moved to other Cost Center.", $projectsCount, $projectsCount > 1 ? 's' : '', $projectsCount > 1 ? 'have' : 'has'));
         }
     }
 }
Example #14
0
 /**
  * Gets farm properties and parameters
  *
  * @param   DBFarm    $dbFarm          DBFarm object
  * @return  array Returns farm properties and parameters
  */
 private function getFarmData(DBFarm $dbFarm)
 {
     $projectId = $dbFarm->GetSetting(\DBFarm::SETTING_PROJECT_ID);
     $ret = array('farmId' => $dbFarm->ID, 'name' => $dbFarm->Name, 'description' => $dbFarm->Comments, 'createdByEmail' => $dbFarm->createdByUserEmail, 'projectId' => $projectId, 'projectName' => !empty($projectId) ? ProjectEntity::findPk($projectId)->name : null);
     return $ret;
 }
Example #15
0
 /**
  *
  * @return array
  */
 public function GetScriptingVars()
 {
     $dbFarmRole = $this->GetFarmRoleObject();
     $roleId = $dbFarmRole->RoleID;
     $dbRole = DBRole::loadById($roleId);
     $isDbMsr = $dbRole->getDbMsrBehavior();
     if ($isDbMsr) {
         $isMaster = $this->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER);
     } else {
         $isMaster = $this->GetProperty(\SERVER_PROPERTIES::DB_MYSQL_MASTER);
     }
     $retval = array('image_id' => $dbRole->__getNewRoleObject()->getImage($this->platform, $dbFarmRole->CloudLocation)->imageId, 'external_ip' => $this->remoteIp, 'internal_ip' => $this->localIp, 'role_name' => $dbRole->name, 'isdbmaster' => $isMaster, 'instance_index' => $this->index, 'instance_farm_index' => $this->farmIndex, 'server_type' => $this->type, 'server_hostname' => $this->GetProperty(Scalr_Role_Behavior::SERVER_BASE_HOSTNAME), 'server_id' => $this->serverId, 'farm_id' => $this->farmId, 'farm_role_id' => $this->farmRoleId, 'farm_role_alias' => $this->GetFarmRoleObject()->Alias, 'farm_name' => $this->GetFarmObject()->Name, 'farm_hash' => $this->GetFarmObject()->Hash, 'farm_owner_email' => $this->GetFarmObject()->createdByUserEmail, 'farm_team' => $this->GetFarmObject()->teamId ? (new Scalr_Account_Team())->loadById($this->GetFarmObject()->teamId)->name : '', 'behaviors' => implode(",", $dbRole->getBehaviors()), 'env_id' => $this->GetEnvironmentObject()->id, 'env_name' => $this->GetEnvironmentObject()->name, 'cloud_location' => $this->GetCloudLocation(), 'cloud_server_id' => $this->GetCloudServerID());
     if ($this->cloudLocationZone) {
         $retval['cloud_location_zone'] = $this->cloudLocationZone;
     }
     if ($this->platform == SERVER_PLATFORMS::EC2) {
         $retval['instance_id'] = $this->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID);
         $retval['ami_id'] = $this->GetProperty(EC2_SERVER_PROPERTIES::AMIID);
         $retval['region'] = $this->GetProperty(EC2_SERVER_PROPERTIES::REGION);
         $retval['avail_zone'] = $this->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE);
         if ($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_ELB_ENABLED)) {
             $elbId = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_ELB_ID);
             $retval['aws_elb_name'] = $elbId;
         }
     }
     if (\Scalr::getContainer()->analytics->enabled) {
         $ccId = $this->GetProperty(\SERVER_PROPERTIES::ENV_CC_ID);
         if ($ccId) {
             $cc = CostCentreEntity::findPk($ccId);
             if ($cc) {
                 /* @var $cc CostCentreEntity */
                 $retval['cost_center_id'] = $ccId;
                 $retval['cost_center_bc'] = $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE);
                 $retval['cost_center_name'] = $cc->name;
             } else {
                 throw new Exception("Cost center {$ccId} not found");
             }
         }
         $projectId = $this->GetProperty(\SERVER_PROPERTIES::FARM_PROJECT_ID);
         if ($projectId) {
             $project = ProjectEntity::findPk($projectId);
             /* @var $project ProjectEntity */
             $retval['project_id'] = $projectId;
             $retval['project_bc'] = $project->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE);
             $retval['project_name'] = $project->name;
         }
     }
     return $retval;
 }
Example #16
0
 /**
  * @test
  */
 public function textComplex()
 {
     $projects = $this->listProjects();
     $adapter = $this->getAdapter('project');
     foreach ($projects as $project) {
         foreach ($adapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE] as $property) {
             foreach ($this->listProjects([$property => $project->{$property}]) as $filteredProject) {
                 $this->assertEquals($project->{$property}, $filteredProject->{$property});
             }
         }
         $response = $this->getProject($project->id);
         $this->assertEquals(200, $response->status, $this->printResponseError($response));
         $dbProject = ProjectEntity::findPk($project->id);
         $this->assertObjectEqualsEntity($response->getBody()->data, $dbProject, $adapter);
     }
     $ccId = Scalr_Environment::init()->loadById($this->getEnvironment()->id)->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID);
     $cc = \Scalr::getContainer()->analytics->ccs->get($ccId);
     $projectData = ['name' => 'test', 'costCenter' => ['id' => $ccId], 'billingCode' => $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE), 'leadEmail' => '*****@*****.**', 'description' => 'test'];
     $response = $this->postProject($projectData);
     $this->assertEquals(201, $response->status, $this->printResponseError($response));
     $projectId = $response->getBody()->data->id;
     $dbProject = ProjectEntity::findPk($projectId);
     $this->assertNotEmpty($dbProject);
     $this->projectToDelete($projectId);
     $this->assertObjectEqualsEntity($projectData, $dbProject, $adapter);
 }
Example #17
0
 /**
  * xGetPeriodLogAction
  *
  * @param   string    $mode      The mode (week, month, quarter, year)
  * @param   string    $startDate The start date of the period in UTC ('Y-m-d')
  * @param   string    $endDate   The end date of the period in UTC ('Y-m-d')
  * @param   string    $type      Type of the data gathered in log file (farms, clouds, projects)
  * @param   string    $ccId      optional The identifier of the cost center
  * @param   string    $projectId optional The identifier of the project
  */
 public function xGetPeriodCsvAction($mode, $startDate, $endDate, $type, $ccId = null, $projectId = null)
 {
     $name = 'Cloud';
     if (!empty($ccId) && empty($projectId)) {
         $data = $this->getContainer()->analytics->usage->getCostCenterPeriodData($ccId, $mode, $startDate, $endDate);
         $entity = CostCentreEntity::findPk($ccId);
         if ($type !== 'clouds') {
             $name = 'Project';
             $extraFields = 'Cost Center name;Billing code;Lead email address;';
         }
     } else {
         if (!empty($projectId)) {
             $data = $this->getContainer()->analytics->usage->getProjectPeriodData($projectId, $mode, $startDate, $endDate);
             $entity = ProjectEntity::findPk($projectId);
             if ($type !== 'clouds') {
                 $name = 'Farm';
                 $extraFields = 'Project name;Billing code;Lead email address;';
             }
         } else {
             throw new \InvalidArgumentException(sprintf("Method %s requires both ccId or projectId to be specified.", __METHOD__));
         }
     }
     $extraData = [$entity->name, $entity->getProperty('billing.code'), $entity->getProperty('lead.email')];
     $head[] = $name;
     $end[] = "Total spent";
     if (isset($extraFields)) {
         $head = array_merge($head, $extraData);
         $end = array_merge($end, $extraData);
     }
     $totals = 0;
     foreach ($data['timeline'] as $timeline) {
         $totals += $timeline['cost'];
         $head[] = $timeline['label'];
         $end[] = $timeline['cost'];
     }
     $head[] = 'Total';
     $end[] = $totals;
     $temp = tmpfile();
     fputcsv($temp, $head);
     foreach ($data[$type] as $item) {
         $row = [];
         $row[] = $item['name'];
         $dataCost = [];
         foreach ($data['timeline'] as $key => $value) {
             $dataCost[] = isset($item['data'][$key]['cost']) ? $item['data'][$key]['cost'] : 0;
         }
         $itemTotal = array_sum($dataCost);
         if (isset($extraFields)) {
             $row = array_merge($row, $extraData);
         }
         $row = array_merge($row, $dataCost);
         $row[] = $itemTotal;
         fputcsv($temp, $row);
     }
     fputcsv($temp, $end);
     $metadata = stream_get_meta_data($temp);
     $label = Scalr_Util_DateTime::convertTz(time(), 'M_j_Y_H:i:s');
     $fileName = $entity->name . '.' . $entity->getProperty('billing.code') . '.' . $type . '.' . $label;
     $bad = array_merge(array_map('chr', range(0, 31)), ["<", ">", ":", '"', "/", "\\", "|", "?", "*"]);
     $fileName = str_replace($bad, "", $fileName);
     $this->response->setHeader('Content-Encoding', 'utf-8');
     $this->response->setHeader('Content-Type', 'text/csv', true);
     $this->response->setHeader('Expires', 'Mon, 10 Jan 1997 08:00:00 GMT');
     $this->response->setHeader('Pragma', 'no-cache');
     $this->response->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
     $this->response->setHeader('Cache-Control', 'post-check=0, pre-check=0');
     $this->response->setHeader('Content-Disposition', 'attachment; filename=' . $fileName . ".csv");
     $this->response->setResponse(file_get_contents($metadata['uri']));
     fclose($temp);
 }
Example #18
0
 /**
  * Finds projects by key
  * It searches by name or billing number
  *
  * @param   string    $key  optional Search key
  * @return  ArrayCollection Returns collection of the ProjectEntity objects
  */
 public function findByKey($key = null)
 {
     if (is_null($key) || $key === '') {
         return $this->all();
     }
     $collection = new ArrayCollection();
     $projectEntity = new ProjectEntity();
     //Includes archived projects
     $projectPropertyEntity = new ProjectPropertyEntity();
     //Cost center entity
     $ccEntity = new CostCentreEntity();
     $rs = $this->db->Execute("\n            SELECT " . $projectEntity->fields('p') . ", " . $ccEntity->fields('c', true) . "\n            FROM " . $projectEntity->table('p') . "\n            LEFT JOIN " . $ccEntity->table('c') . " ON c.`cc_id` = p.`cc_id`\n            WHERE p.`name` LIKE ?\n            OR EXISTS (\n                SELECT 1 FROM " . $projectPropertyEntity->table('pp') . "\n                WHERE `pp`.project_id = `p`.`project_id`\n                AND `pp`.`name` = ? AND `pp`.`value` LIKE ?\n            )\n        ", ['%' . $key . '%', ProjectPropertyEntity::NAME_BILLING_CODE, '%' . $key . '%']);
     while ($rec = $rs->FetchRow()) {
         $item = new ProjectEntity();
         $item->load($rec);
         if ($rec['c_cc_id']) {
             $cc = new CostCentreEntity();
             $cc->load($rec, 'c');
             $item->setCostCenter($cc);
         }
         $collection->append($item);
     }
     return $collection;
 }
Example #19
0
 protected function isApplied1($stage)
 {
     return CostCentreEntity::findPk(Usage::DEFAULT_CC_ID) !== null && ProjectEntity::findPk(Usage::DEFAULT_PROJECT_ID) !== null;
 }
Example #20
0
 protected function run8($stage)
 {
     if ($this->getCountOfAccountTagValues(TagEntity::TAG_ID_PROJECT) && $this->console->confirm('Would you like to remove old projects from account_tag_values?')) {
         $this->console->out("Removing old projects");
         $this->db->Execute("DELETE FROM account_tag_values WHERE tag_id = ?", array(TagEntity::TAG_ID_PROJECT));
     }
     $this->console->out('Populating projects to the dictionary');
     foreach (ProjectEntity::all() as $projectEntity) {
         /* @var $projectEntity ProjectEntity */
         $this->db->Execute("\n                INSERT IGNORE `account_tag_values` (`account_id`, `tag_id`, `value_id`, `value_name`)\n                VALUES (?, ?, ?, ?)\n            ", [$projectEntity->accountId ?: 0, TagEntity::TAG_ID_PROJECT, $projectEntity->projectId, $projectEntity->name]);
     }
 }
Example #21
0
 /**
  * xGetPeriodLogAction
  *
  * @param   string    $mode      The mode (week, month, quarter, year)
  * @param   string    $startDate The start date of the period in UTC ('Y-m-d')
  * @param   string    $endDate   The end date of the period in UTC ('Y-m-d')
  * @param   string    $type      Type of the data gathered in log file
  * @param   string    $projectId optional The identifier of the project
  */
 public function xGetPeriodCsvAction($mode, $startDate, $endDate, $type, $projectId = null, $farmId = null)
 {
     if ($type == 'farms') {
         $name = 'Farm';
     } else {
         if ($type == 'clouds') {
             $name = 'Cloud';
         } else {
             $name = 'Farm Roles';
         }
     }
     if (!empty($projectId)) {
         $filter = ['envId' => $this->environment->id, 'accountId' => $this->environment->clientId];
         $data = $this->getContainer()->analytics->usage->getProjectPeriodData($projectId, $mode, $startDate, $endDate, $filter);
         $entity = ProjectEntity::findPk($projectId);
         if ($type !== 'clouds') {
             $extraFields = 'Project name;Billing code;Lead email address;';
         }
         $fileName = $entity->name . '.' . $entity->getProperty('billing.code');
     } else {
         if (!empty($farmId)) {
             $data = $this->getContainer()->analytics->usage->getFarmPeriodData($farmId, $this->environment, $mode, $startDate, $endDate);
             $farm = \DBFarm::LoadByID($farmId);
             $fileName = $farm->Name . '.' . $farmId;
         } else {
             $data = $this->getContainer()->analytics->usage->getEnvironmentPeriodData($this->environment, $mode, $startDate, $endDate);
             $fileName = 'Environment' . $this->environment->id;
         }
     }
     if (!empty($entity)) {
         $extraData = [$entity->name, $entity->getProperty('billing.code'), $entity->getProperty('lead.email')];
     }
     $head[] = $name;
     $end[] = "Total spent";
     if (isset($extraFields)) {
         $head = array_merge($head, $extraData);
         $end = array_merge($end, $extraData);
     }
     $totals = 0;
     foreach ($data['timeline'] as $timeline) {
         $totals += $timeline['cost'];
         $head[] = $timeline['label'];
         $end[] = $timeline['cost'];
     }
     $head[] = 'Total';
     $end[] = $totals;
     $temp = tmpfile();
     fputcsv($temp, $head);
     foreach ($data[$type] as $item) {
         $row = [];
         $row[] = $item['name'];
         $dataCost = [];
         foreach ($data['timeline'] as $key => $value) {
             $dataCost[] = isset($item['data'][$key]['cost']) ? $item['data'][$key]['cost'] : 0;
         }
         $itemTotal = array_sum($dataCost);
         if (isset($extraFields)) {
             $row = array_merge($row, $extraData);
         }
         $row = array_merge($row, $dataCost);
         $row[] = $itemTotal;
         fputcsv($temp, $row);
     }
     fputcsv($temp, $end);
     $metadata = stream_get_meta_data($temp);
     $fileName = $fileName . '.' . $type . '.' . Scalr_Util_DateTime::convertTz(time(), 'M_j_Y_H:i:s');
     $bad = array_merge(array_map('chr', range(0, 31)), ["<", ">", ":", '"', "/", "\\", "|", "?", "*"]);
     $fileName = str_replace($bad, "", $fileName);
     $this->response->setHeader('Content-Encoding', 'utf-8');
     $this->response->setHeader('Content-Type', 'text/csv', true);
     $this->response->setHeader('Expires', 'Mon, 10 Jan 1997 08:00:00 GMT');
     $this->response->setHeader('Pragma', 'no-cache');
     $this->response->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
     $this->response->setHeader('Cache-Control', 'post-check=0, pre-check=0');
     $this->response->setHeader('Content-Disposition', 'attachment; filename=' . $fileName . ".csv");
     $this->response->setResponse(file_get_contents($metadata['uri']));
     fclose($temp);
 }
Example #22
0
 /**
  * Checks if user has permissions to project in environment or account scope
  *
  * @param string $projectId     Identifier of the project
  * @param array $criteria       ['envId' => '', 'clientid' => '']
  * @return bool|mixed
  */
 public function checkPermission($projectId, array $criteria)
 {
     $and = '';
     foreach ($criteria as $name => $value) {
         $field = 'f.' . \Scalr::decamelize($name);
         $and .= " AND " . $field . "=" . $this->db->escape($value);
     }
     $projectEntity = new ProjectEntity();
     $projectId = $projectEntity->type('projectId')->toDb($projectId);
     $where = " WHERE p.project_id = UNHEX('" . $projectId . "') AND EXISTS (\n                SELECT * FROM farms f\n                LEFT JOIN farm_settings fs ON f.id = fs.farmid\n                WHERE fs.name = '" . Entity\FarmSetting::PROJECT_ID . "'\n                AND REPLACE(fs.value, '-', '') = HEX(p.project_id)\n                {$and})";
     $sql = "SELECT " . $projectEntity->fields('p') . "\n                FROM " . $projectEntity->table('p') . $where;
     return $this->db->GetOne($sql);
 }
Example #23
0
File: User.php Project: scalr/scalr
 /**
  * Checks if user has access to project or cost center
  *
  * @param   string $projectId optional Id of the project
  * @param   string $ccId      optional Id of the cost center
  * @return  boolean           Returns false if user is not lead of the subject
  */
 public function isSubjectLead($projectId = null, $ccId = null)
 {
     if (!empty($projectId)) {
         $project = ProjectEntity::findPk($projectId);
         if (empty($project) || $project->getProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL) !== $this->getEmail()) {
             return false;
         }
     } else {
         if (!empty($ccId)) {
             $ccs = CostCentreEntity::findPk($ccId);
             if (empty($ccs) || $ccs->getProperty(CostCentrePropertyEntity::NAME_LEAD_EMAIL) !== $this->getEmail()) {
                 return false;
             }
         }
     }
     return true;
 }
Example #24
0
 /**
  * {@inheritdoc}
  * @see \Scalr\Model\AbstractEntity::save()
  */
 public function save()
 {
     //Checks data integrity.
     $criteria = [['name' => $this->name], ['ccId' => $this->ccId]];
     if ($this->projectId) {
         $criteria[] = ['projectId' => ['$ne' => $this->projectId]];
     }
     //The name of the project should be unique withing the current cost center
     $item = ProjectEntity::findOne($criteria);
     if ($item) {
         throw new AnalyticsException(sprintf('A Project with this name already exists. Please choose another name.'));
     }
     parent::save();
     if ($this->projectId && \Scalr::getContainer()->analytics->enabled) {
         \Scalr::getContainer()->analytics->tags->syncValue($this->accountId ?: 0, \Scalr\Stats\CostAnalytics\Entity\TagEntity::TAG_ID_PROJECT, $this->projectId, $this->name);
     }
 }
Example #25
0
 /**
  * Gets project properties and parameters
  *
  * @param   ProjectEntity    $projectEntity          Project entity
  * @param   string           $calculate     optional Whether response should be adjusted with cost usage data
  * @return  array Returns cost centre properties and parameters
  */
 private function getProjectData(ProjectEntity $projectEntity, $calculate = false)
 {
     $ret = array('ccId' => $projectEntity->ccId, 'ccName' => $projectEntity->getCostCenter() !== null ? $projectEntity->getCostCenter()->name : null, 'projectId' => $projectEntity->projectId, 'name' => $projectEntity->name, 'billingCode' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE), 'description' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_DESCRIPTION), 'leadEmail' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL), 'created' => $projectEntity->created->format('Y-m-d'), 'createdByEmail' => $projectEntity->createdByEmail, 'archived' => $projectEntity->archived, 'shared' => $projectEntity->shared, 'farmsCount' => count($projectEntity->getFarmsList()));
     if (!empty($projectEntity->accountId) && $projectEntity->shared === ProjectEntity::SHARED_WITHIN_ACCOUNT) {
         $ret['accountId'] = $projectEntity->accountId;
         $ret['accountName'] = Scalr_Account::init()->loadById($projectEntity->accountId)->name;
     } elseif (!empty($projectEntity->envId) && $projectEntity->shared === ProjectEntity::SHARED_WITHIN_ENV) {
         $ret['accountId'] = $projectEntity->accountId;
         $ret['accountName'] = Scalr_Account::init()->loadById($projectEntity->accountId)->name;
         $ret['envId'] = $projectEntity->envId;
         $ret['envName'] = Scalr_Environment::init()->loadById($projectEntity->envId)->name;
     }
     if ($calculate) {
         $iterator = ChartPeriodIterator::create('month', gmdate('Y-m-01'), null, 'UTC');
         $usage = $this->getContainer()->analytics->usage->get(['projectId' => $ret['projectId']], $iterator->getStart(), $iterator->getEnd());
         //It calculates usage for previous period same days
         $prevusage = $this->getContainer()->analytics->usage->get(['projectId' => $ret['projectId']], $iterator->getPreviousStart(), $iterator->getPreviousEnd());
         $ret = $this->getWrappedUsageData(['ccId' => $ret['ccId'], 'projectId' => $ret['projectId'], 'iterator' => $iterator, 'usage' => $usage['cost'], 'prevusage' => $prevusage['cost']]) + $ret;
     }
     return $ret;
 }
Example #26
0
 private function getFarmCostData($farmId)
 {
     $result = [];
     $costCenter = $this->getContainer()->analytics->ccs->get($this->getEnvironment()->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID));
     $currentYear = (new \DateTime('now', new \DateTimeZone('UTC')))->format('Y');
     $quarters = new Quarters(SettingEntity::getQuarters());
     $currentQuarter = $quarters->getQuarterForDate(new \DateTime('now', new \DateTimeZone('UTC')));
     $projects = [];
     if ($farmId) {
         $farm = DBFarm::LoadByID($farmId);
         $currentProjectId = $farm->GetSetting(Entity\FarmSetting::PROJECT_ID);
         $currentProject = ProjectEntity::findPk($currentProjectId);
         /* @var $currentProject ProjectEntity */
         if (!empty($currentProject)) {
             $quarterBudget = QuarterlyBudgetEntity::findOne([['year' => $currentYear], ['subjectType' => QuarterlyBudgetEntity::SUBJECT_TYPE_PROJECT], ['subjectId' => $currentProject->projectId], ['quarter' => $currentQuarter]]);
             $projects[] = ['projectId' => $currentProject->projectId, 'name' => "{$currentProject->name} / {$currentProject->getCostCenter()->name}", 'budgetRemain' => !is_null($quarterBudget) && $quarterBudget->budget > 0 ? max(0, round($quarterBudget->budget - $quarterBudget->cumulativespend)) : null];
         }
         $result['projectId'] = $farm->GetSetting(Entity\FarmSetting::PROJECT_ID);
         $result['farmCostMetering'] = $result['projectId'] ? $this->getContainer()->analytics->usage->getFarmCostMetering($this->user->getAccountId(), $farmId) : null;
     }
     if ($costCenter instanceof CostCentreEntity) {
         $projectsIterator = new SharedProjectsFilterIterator($costCenter->getProjects(), $costCenter->ccId, $this->user, $this->getEnvironment());
         foreach ($projectsIterator as $item) {
             /* @var $item Scalr\Stats\CostAnalytics\Entity\ProjectEntity */
             if (!empty($currentProjectId) && $item->projectId == $currentProjectId) {
                 continue;
             }
             $quarterBudget = QuarterlyBudgetEntity::findOne([['year' => $currentYear], ['subjectType' => QuarterlyBudgetEntity::SUBJECT_TYPE_PROJECT], ['subjectId' => $item->projectId], ['quarter' => $currentQuarter]]);
             $projects[] = array('projectId' => $item->projectId, 'name' => "{$item->name} / {$costCenter->name}", 'budgetRemain' => !is_null($quarterBudget) && $quarterBudget->budget > 0 ? max(0, round($quarterBudget->budget - $quarterBudget->cumulativespend)) : null);
         }
         $costCentreName = $costCenter->name;
         $isLocked = $costCenter->getProperty(CostCentrePropertyEntity::NAME_LOCKED);
         $accountCcs = AccountCostCenterEntity::findOne([['accountId' => $this->environment->clientId], ['ccId' => $costCenter->ccId]]);
         if ($isLocked || !$accountCcs instanceof AccountCostCenterEntity) {
             $costCentreLocked = 1;
         } else {
             $costCentreLocked = 0;
         }
     } else {
         $costCentreName = '';
         $costCentreLocked = 0;
     }
     $supportedClouds = $this->getContainer()->analytics->prices->getSupportedClouds();
     $result['analytics'] = array('costCenterName' => $costCentreName, 'costCenterLocked' => $costCentreLocked, 'projects' => $projects, 'unsupportedClouds' => array_values(array_diff($this->environment->getEnabledPlatforms(), $supportedClouds)));
     return $result;
 }
Example #27
0
 /**
  * Associates cost analytics project with the farm
  *
  * It does not perform any actions if cost analytics is disabled
  *
  * @param   ProjectEntity|string  $project         The project entity or its identifier
  * @return  string                Returns identifier of the associated project
  * @throws  InvalidArgumentException
  * @throws  AnalyticsException
  */
 public function setProject($project)
 {
     if (Scalr::getContainer()->analytics->enabled) {
         if ($project instanceof ProjectEntity) {
             $projectId = $project->projectId;
         } else {
             $projectId = $project;
             unset($project);
         }
         $analytics = Scalr::getContainer()->analytics;
         if ($projectId === null) {
             $ccId = $this->GetEnvironmentObject()->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID);
             if (!empty($ccId)) {
                 //Assigns Project automatically only if it is the one withing the Cost Center
                 $projects = ProjectEntity::findByCcId($ccId);
                 if (count($projects) == 1) {
                     $project = $projects->getArrayCopy()[0];
                     $projectId = $project->projectId;
                 }
             }
         } elseif (!empty($projectId)) {
             //Validates specified project's identifier
             if (!preg_match('/^[[:xdigit:]-]{36}$/', $projectId)) {
                 throw new InvalidArgumentException(sprintf("Identifier of the cost analytics Project must have valid UUID format. '%s' given.", strip_tags($projectId)));
             }
             $project = isset($project) ? $project : $analytics->projects->get($projectId);
             if (!$project) {
                 throw new AnalyticsException(sprintf("Could not find Project with specified identifier %s.", strip_tags($projectId)));
             } else {
                 if ($project->ccId !== $this->GetEnvironmentObject()->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID)) {
                     throw new AnalyticsException(sprintf("Invalid project identifier. Parent Cost center of the Project should correspond to the Environment's cost center."));
                 }
             }
         } else {
             $projectId = null;
         }
         //Sets project to the farm object only if it has been provided
         if (isset($projectId)) {
             $project = isset($project) ? $project : $analytics->projects->get($projectId);
             $oldProjectId = $this->GetSetting(Entity\FarmSetting::PROJECT_ID);
             $this->SetSetting(Entity\FarmSetting::PROJECT_ID, $project->projectId);
             //Server property SERVER_PROPERTIES::FARM_PROJECT_ID should be updated
             //for all running servers associated with the farm.
             $this->DB->Execute("\n                    INSERT `server_properties` (`server_id`, `name`, `value`)\n                    SELECT s.`server_id`, ? AS `name`, ? AS `value`\n                    FROM `servers` s\n                    WHERE s.`farm_id` = ?\n                    ON DUPLICATE KEY UPDATE `value` = ?\n                ", [SERVER_PROPERTIES::FARM_PROJECT_ID, $project->projectId, $this->ID, $project->projectId]);
             //Cost centre should correspond to Project's CC
             $this->DB->Execute("\n                    INSERT `server_properties` (`server_id`, `name`, `value`)\n                    SELECT s.`server_id`, ? AS `name`, ? AS `value`\n                    FROM `servers` s\n                    WHERE s.`farm_id` = ?\n                    ON DUPLICATE KEY UPDATE `value` = ?\n                ", [SERVER_PROPERTIES::ENV_CC_ID, $project->ccId, $this->ID, $project->ccId]);
             if (empty($oldProjectId)) {
                 $analytics->events->fireAssignProjectEvent($this, $project->projectId);
             } elseif ($oldProjectId !== $projectId) {
                 $analytics->events->fireReplaceProjectEvent($this, $project->projectId, $oldProjectId);
             }
         }
     }
     return $projectId;
 }
Example #28
0
 /**
  * Gets detailed top 5 usage by farms for specified project on date
  *
  * @param   string|null $projectId    The identifier of the project
  * @param   string      $platform     The cloud platform
  * @param   string      $mode         The mode
  * @param   string      $date         The UTC date within period ('Y-m-d H:00')
  * @param   string      $start        The start date of the period in UTC ('Y-m-d')
  * @param   string      $end          The end date of the period in UTC ('Y-m-d')
  * @param   string      $ccId         optional The identifier of the cost center (It is used only when project is null)
  * @return  array       Returns detailed top 5 usage by farms for specified project on date
  * @throws  AnalyticsException
  * @throws  OutOfBoundsException
  */
 public function getProjectFarmsTopUsageOnDate($projectId, $platform, $mode, $date, $start, $end, $ccId = null)
 {
     $projectId = empty($projectId) ? null : $projectId;
     $iterator = ChartPeriodIterator::create($mode, $start, $end ?: null, 'UTC');
     //Interval which is used in the database query for grouping
     $queryInterval = preg_replace('/^1 /', '', $iterator->getInterval());
     if ($projectId !== null) {
         $project = ProjectEntity::findPk($projectId);
         if ($project === null) {
             if (empty($ccId)) {
                 throw new AnalyticsException(sprintf("Project %s does not exist. Please provide ccId.", $projectId));
             }
         }
     }
     //Requests data for the specified period
     $rawUsage = $this->get(['projectId' => $projectId], $iterator->getStart(), $iterator->getEnd(), [$queryInterval, TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_FARM], true);
     //Requests data for the previous period
     $rawPrevUsage = $this->get(['projectId' => $projectId], $iterator->getPreviousStart(), $iterator->getPreviousEnd(), [$queryInterval, TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_FARM], true);
     //We do not need to calculate the percentage here
     $usg = (new AggregationCollection(['period', 'platform', 'farmId' => ['envId']], ['cost' => 'sum']))->load($rawUsage);
     $prevUsg = (new AggregationCollection(['period', 'platform', 'farmId'], ['cost' => 'sum']))->load($rawPrevUsage)->calculatePercentage();
     //Previous chart point
     $prevcp = null;
     //Finds the key for current label
     foreach ($iterator as $chartPoint) {
         if ($chartPoint->dt->format('Y-m-d H:00') !== $date) {
             $prevcp = $chartPoint;
             continue;
         }
         $cp = $chartPoint;
         break;
     }
     if (!isset($cp)) {
         throw new OutOfRangeException(sprintf('Requested date (%s) is out of the range. Last point date is %s', $date, isset($prevcp->dt) ? $prevcp->dt->format('Y-m-d H:00') : 'undefined'));
     }
     $result = [];
     //Maximum number of the farms without grouping
     $max = 5;
     if (!empty($usg['data'][$cp->key]['data'][$platform]['data'])) {
         $usgFarms = new AggregationCollection(['farmId' => ['envId']], ['cost' => 'sum']);
         $ptr = $usg['data'][$cp->key]['data'][$platform]['data'];
         uasort($ptr, function ($a, $b) {
             if ($a['cost'] == $b['cost']) {
                 return 0;
             }
             return $a['cost'] > $b['cost'] ? -1 : 1;
         });
         //Aggregates farms if its number more then max + 1
         if (count($ptr) > $max + 1) {
             $this->otherFarmsQuantity = count($ptr) - $max;
             $new = [];
             $i = 0;
             foreach ($ptr as $farmId => $v) {
                 $v['cost_percentage'] = round($usg['data'][$cp->key]['data'][$platform]['cost'] == 0 ? 0 : $v['cost'] * 100 / $usg['data'][$cp->key]['data'][$platform]['cost'], 0);
                 if ($i < $max) {
                     $new[$farmId] = $v;
                 } elseif (!isset($new[self::EVERYTHING_ELSE])) {
                     $v['id'] = self::EVERYTHING_ELSE;
                     $new[self::EVERYTHING_ELSE] = $v;
                 } else {
                     $new[self::EVERYTHING_ELSE]['cost'] += $v['cost'];
                 }
                 $i++;
             }
             $new[self::EVERYTHING_ELSE]['cost_percentage'] = round($usg['data'][$cp->key]['data'][$platform]['cost'] == 0 ? 0 : $new[self::EVERYTHING_ELSE]['cost'] * 100 / $usg['data'][$cp->key]['data'][$platform]['cost'], 0);
             $usgFarms->setData(['data' => $new]);
         } else {
             $usgFarms->setData($usg['data'][$cp->key]['data'][$platform])->calculatePercentage();
         }
         //Forms result data array
         foreach ($usgFarms->getIterator() as $farmId => $pv) {
             $record = $this->getDetailedPointDataArray($farmId, $this->fetchFarmName($farmId), $pv, isset($prevUsg['data'][$cp->previousPeriodKey]['data'][$platform]['data'][$farmId]) ? $prevUsg['data'][$cp->previousPeriodKey]['data'][$platform]['data'][$farmId] : null, isset($usg['data'][$cp->key]['data'][$platform]['data'][$farmId]) ? $usg['data'][$cp->key]['data'][$platform]['data'][$farmId] : null);
             if ($farmId && $farmId != self::EVERYTHING_ELSE && !empty($pv['envId'])) {
                 $record['environment'] = ['id' => (int) $pv['envId'], 'name' => AccountTagEntity::fetchName($pv['envId'], TagEntity::TAG_ID_ENVIRONMENT)];
             }
             $result[] = $record;
         }
     }
     return ['data' => $result];
 }
Example #29
0
 public function xSaveAction()
 {
     $this->request->defineParams(array('projectId' => ['type' => 'string'], 'year' => ['type' => 'int'], 'quarters' => ['type' => 'json'], 'selectedQuarter' => ['type' => 'string']));
     $year = $this->getParam('year');
     $selectedQuarter = $this->getParam('selectedQuarter');
     if ($selectedQuarter !== 'year' && ($selectedQuarter < 1 || $selectedQuarter > 4)) {
         throw new OutOfBoundsException(sprintf("Invalid selectedQuarter number."));
     }
     $quarterReq = [];
     foreach ($this->getParam('quarters') as $q) {
         if (!isset($q['quarter'])) {
             throw new InvalidArgumentException(sprintf("Missing quarter property for quarters data set in the request."));
         }
         if ($q['quarter'] < 1 || $q['quarter'] > 4) {
             throw new OutOfRangeException(sprintf("Quarter value should be between 1 and 4."));
         }
         if (!isset($q['budget'])) {
             throw new InvalidArgumentException(sprintf("Missing budget property for quarters data set in the request."));
         }
         $quarterReq[$q['quarter']] = $q;
     }
     if ($this->getParam('projectId')) {
         $subjectType = QuarterlyBudgetEntity::SUBJECT_TYPE_PROJECT;
         $subjectId = $this->getParam('projectId');
         $subjectEntity = ProjectEntity::findPk($subjectId);
         /* @var $subjectEntity ProjectEntity */
         if ($subjectEntity->accountId != $this->user->getAccountId() || $subjectEntity->shared != ProjectEntity::SHARED_WITHIN_ACCOUNT) {
             throw new Scalr_Exception_InsufficientPermissions();
         }
     } else {
         throw new InvalidArgumentException(sprintf('ProjectId must be provided with the request.'));
     }
     if (!preg_match("/^[[:xdigit:]-]{36}\$/", $subjectId)) {
         throw new InvalidArgumentException(sprintf("Invalid UUID has been passed."));
     }
     if (!preg_match('/^\\d{4}$/', $year)) {
         throw new InvalidArgumentException(sprintf("Invalid year has been passed."));
     }
     //Fetches the previous state of the entities from database
     $collection = QuarterlyBudgetEntity::getProjectBudget($year, $subjectId);
     $quarters = new Quarters(SettingEntity::getQuarters(true));
     //Updates|creates entities
     for ($quarter = 1; $quarter <= 4; ++$quarter) {
         if (!isset($quarterReq[$quarter])) {
             continue;
         }
         $period = $quarters->getPeriodForQuarter($quarter, $year);
         //Checks if period has already been closed and forbids update
         if ($period->end->format('Y-m-d') < gmdate('Y-m-d')) {
             continue;
         }
         $entity = current($collection->filterByQuarter($quarter));
         if ($entity instanceof QuarterlyBudgetEntity) {
             //We should update an entity
             $entity->budget = abs((double) $quarterReq[$quarter]['budget']);
         } else {
             //We should create a new one.
             $entity = new QuarterlyBudgetEntity($year, $quarter);
             $entity->subjectType = $subjectType;
             $entity->subjectId = $subjectId;
             $entity->budget = abs((double) $quarterReq[$quarter]['budget']);
         }
         $entity->save();
     }
     if ($selectedQuarter == 'year') {
         $selectedPeriod = $quarters->getPeriodForYear($year);
     } else {
         $selectedPeriod = $quarters->getPeriodForQuarter($selectedQuarter, $year);
     }
     $data = $this->getProjectData(ProjectEntity::findPk($subjectId), $selectedPeriod, true);
     $budgetInfo = $this->getBudgetInfo($year, $data['ccId'], $data['projectId']);
     $this->response->data(['data' => $data, 'budgetInfo' => $budgetInfo]);
     $this->response->success('Budget changes have been saved');
 }
Example #30
0
 /**
  * Gets project properties and parameters
  *
  * @param   ProjectEntity    $projectEntity          Project entity
  * @return  array Returns cost centre properties and parameters
  */
 private function getProjectData(ProjectEntity $projectEntity)
 {
     $ret = array('projectId' => $projectEntity->projectId, 'name' => $projectEntity->name, 'ccId' => $projectEntity->ccId, 'ccName' => $projectEntity->getCostCenter() !== null ? $projectEntity->getCostCenter()->name : null, 'billingCode' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE), 'description' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_DESCRIPTION), 'leadEmail' => $projectEntity->getProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL), 'created' => $projectEntity->created->format('Y-m-d'), 'createdByEmail' => $projectEntity->createdByEmail, 'archived' => $projectEntity->archived, 'shared' => $projectEntity->shared);
     if (!empty($projectEntity->accountId) && $projectEntity->shared === ProjectEntity::SHARED_WITHIN_ACCOUNT) {
         $ret['accountId'] = $projectEntity->accountId;
         $ret['accountName'] = Scalr_Account::init()->loadById($projectEntity->accountId)->name;
     } elseif (!empty($projectEntity->envId) && $projectEntity->shared === ProjectEntity::SHARED_WITHIN_ENV) {
         $ret['accountId'] = $projectEntity->accountId;
         $ret['accountName'] = Scalr_Account::init()->loadById($projectEntity->accountId)->name;
         $ret['envId'] = $projectEntity->envId;
         $ret['envName'] = \Scalr_Environment::init()->loadById($projectEntity->envId)->name;
     }
     return $ret;
 }