示例#1
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;
 }
示例#2
0
文件: Budgets.php 项目: scalr/scalr
 /**
  * Gets the list of the cost centres
  *
  * @return   array Returns the list of the cost centres
  */
 private function getNodesList($period, $ccId = null, $query = null)
 {
     $nodes = [];
     $projectItems = $this->getContainer()->analytics->projects->findByKey($query, ['accountId' => $this->user->getAccountId()], true);
     foreach ($projectItems as $item) {
         /* @var $item ProjectEntity */
         if (!isset($nodes[$item->ccId])) {
             $nodes[$item->ccId] = $this->getCostCenterData($this->getContainer()->analytics->ccs->get($item->ccId), $period);
             $nodes[$item->ccId]['nodes'] = [];
         }
         $nodes[$item->ccId]['nodes'][] = $this->getProjectData($item, $period);
     }
     $ccsItems = $this->getContainer()->analytics->ccs->findByKey($query, ['accountId' => $this->user->getAccountId()], true);
     foreach ($ccsItems as $item) {
         /* @var $item CostCentreEntity */
         if (!isset($nodes[$item->ccId])) {
             $nodes[$item->ccId] = $this->getCostCenterData($item, $period);
             $nodes[$item->ccId]['nodes'] = [];
             foreach (ProjectEntity::findByCcId($item->ccId) as $projectItem) {
                 /* @var $projectItem ProjectEntity */
                 if ($projectItem->shared != ProjectEntity::SHARED_WITHIN_ACCOUNT || $projectItem->accountId != $this->user->getAccountId()) {
                     continue;
                 }
                 $nodes[$item->ccId]['nodes'][] = $this->getProjectData($projectItem, $period);
             }
         }
     }
     return array_values($nodes);
 }
示例#3
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;
 }
示例#4
0
 /**
  * Gets the list of the cost centres
  *
  * @return   array Returns the list of the cost centres
  */
 private function getNodesList($period, $ccId = null, $query = null)
 {
     $nodes = array();
     if (!$ccId) {
         $criteria = null;
         if ($query) {
             $criteria = array('name' => array('$like' => array('%' . $query . '%')));
             foreach (ProjectEntity::find($criteria) as $item) {
                 /* @var $item ProjectEntity */
                 if (!isset($nodes[$item->ccId])) {
                     $nodes[$item->ccId] = $this->getCostCenterData($this->getContainer()->analytics->ccs->get($item->ccId), $period);
                     $nodes[$item->ccId]['nodes'] = array();
                 }
                 $nodes[$item->ccId]['nodes'][] = $this->getProjectData($item, $period);
             }
             foreach (CostCentreEntity::find($criteria) as $item) {
                 /* @var $item CostCentreEntity */
                 if (!isset($nodes[$item->ccId])) {
                     $nodes[$item->ccId] = $this->getCostCenterData($item, $period);
                     $nodes[$item->ccId]['nodes'] = array();
                 }
                 $projectItems = ProjectEntity::findByCcId($item->ccId);
                 foreach ($projectItems as $projectItem) {
                     $nodes[$item->ccId]['nodes'][] = $this->getProjectData($projectItem, $period);
                 }
             }
         } else {
             foreach (CostCentreEntity::all() as $item) {
                 /* @var $item CostCentreEntity */
                 $nodes[$item->ccId] = $this->getCostCenterData($item, $period);
             }
         }
     } else {
         foreach ($this->getContainer()->analytics->ccs->get($ccId)->getProjects() as $item) {
             $nodes[$item->projectId] = $this->getProjectData($item, $period);
         }
     }
     return array_values($nodes);
 }
示例#5
0
文件: Usage.php 项目: scalr/scalr
 /**
  * Gets analytics data for the cost center
  *
  * @param   string   $ccId      The identifier of the cost center (UUID)
  * @param   string   $mode      Mode (week, month, quarter, year, custom)
  * @param   string   $startDate Start date in UTC (Y-m-d)
  * @param   string   $endDate   End date in UTC (Y-m-d)
  * @return  array    Returns analytics data for the specified cost center
  */
 public function getCostCenterPeriodData($ccId, $mode, $startDate, $endDate)
 {
     $analytics = $this->getContainer()->analytics;
     $utcTz = new DateTimeZone('UTC');
     $iterator = ChartPeriodIterator::create($mode, new DateTime($startDate, $utcTz), new DateTime($endDate, $utcTz), 'UTC');
     $timelineEvents = $analytics->events->count($iterator->getInterval(), $iterator->getStart(), $iterator->getEnd(), ['ccId' => $ccId]);
     //Interval which is used in the database query for grouping
     $queryInterval = preg_replace('/^1 /', '', $iterator->getInterval());
     //Current period data
     $collectionSet = (new AggregationCollectionSet(['byPlatformDetailed' => new AggregationCollection(['period', 'platform', 'projectId'], ['cost' => 'sum']), 'byProjectDetailed' => new AggregationCollection(['period', 'projectId', 'platform'], ['cost' => 'sum']), 'byPlatform' => new AggregationCollection(['platform', 'projectId'], ['cost' => 'sum']), 'byProject' => new AggregationCollection(['projectId', 'platform'], ['cost' => 'sum'])]))->load($this->get(['ccId' => $ccId], $iterator->getStart(), $iterator->getEnd(), [$queryInterval, TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_PROJECT], true))->calculatePercentage();
     //Previous period data
     $collectionSetPrev = (new AggregationCollectionSet(['byPlatformDetailed' => new AggregationCollection(['period', 'platform', 'projectId'], ['cost' => 'sum']), 'byProjectDetailed' => new AggregationCollection(['period', 'projectId', 'platform'], ['cost' => 'sum']), 'byPlatform' => new AggregationCollection(['platform', 'projectId'], ['cost' => 'sum']), 'byProject' => new AggregationCollection(['projectId', 'platform'], ['cost' => 'sum'])]))->load($this->get(['ccId' => $ccId], $iterator->getPreviousStart(), $iterator->getPreviousEnd(), [$queryInterval, TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_PROJECT], true))->calculatePercentage();
     $quarterIterator = $this->getCurrentQuarterIterator();
     $queryQuarterInterval = preg_replace('/^1 /', '', $quarterIterator->getInterval());
     $rawQuarterUsage = $this->get(['ccId' => $ccId], $quarterIterator->getStart(), $quarterIterator->getEnd(), [TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_PROJECT], true);
     $itemsRollingAvg = $this->getRollingAvg(['ccId' => $ccId], $queryQuarterInterval, $quarterIterator->getEnd(), null, $rawQuarterUsage, ['projectId' => 'projects', 'platform' => 'clouds']);
     //Gets the list of the projects which is assigned to cost center at current moment to optimize
     //retrieving its names with one query
     $projects = new ArrayCollection();
     foreach (ProjectEntity::findByCcId($ccId) as $i) {
         $projects[$i->projectId] = $i;
     }
     //Function retrieves the name of the project by specified identifier
     $fnGetProjectName = function ($projectId) use($projects) {
         if (empty($projectId)) {
             $projectName = 'Unassigned resources';
         } else {
             if (!isset($projects[$projectId])) {
                 //Trying to find the name of the project in the tag values history
                 if (null === ($pe = AccountTagEntity::findOne([['tagId' => TagEntity::TAG_ID_PROJECT], ['valueId' => $projectId]]))) {
                     $projectName = $projectId;
                 } else {
                     $projectName = $pe->valueName;
                     unset($pe);
                 }
             } else {
                 $projectName = $projects[$projectId]->name;
             }
         }
         return $projectName;
     };
     $cloudsData = [];
     $projectsData = [];
     $timeline = [];
     $prevPointKey = null;
     foreach ($iterator as $chartPoint) {
         /* @var $chartPoint \Scalr\Stats\CostAnalytics\ChartPointInfo */
         $i = $chartPoint->i;
         $timeline[] = array('datetime' => $chartPoint->dt->format('Y-m-d H:00'), 'label' => $chartPoint->label, 'onchart' => $chartPoint->show, 'cost' => round(isset($collectionSet['byPlatformDetailed']['data'][$chartPoint->key]['cost']) ? $collectionSet['byPlatformDetailed']['data'][$chartPoint->key]['cost'] : 0, 2), 'events' => isset($timelineEvents[$chartPoint->key]) ? $timelineEvents[$chartPoint->key] : null);
         //Period - Platform - Projects subtotals
         if (!isset($collectionSet['byPlatformDetailed']['data'][$chartPoint->key]['data'])) {
             foreach ($cloudsData as $platform => $v) {
                 if (!$iterator->isFuture()) {
                     //Previous period details
                     if (isset($collectionSetPrev['byPlatformDetailed']['data'][$chartPoint->previousPeriodKey]['data'][$platform])) {
                         $pp = $collectionSetPrev['byPlatformDetailed']['data'][$chartPoint->previousPeriodKey]['data'][$platform];
                     } else {
                         $pp = null;
                     }
                     //Previous point details
                     if (isset($collectionSet['byPlatformDetailed']['data'][$prevPointKey]['data'][$platform])) {
                         $ppt = $collectionSet['byPlatformDetailed']['data'][$prevPointKey]['data'][$platform];
                     } else {
                         $ppt = null;
                     }
                     $r = $this->getPointDataArray(null, $pp, $ppt);
                     //Projects data is empty
                     $r['projects'] = [];
                     $cloudsData[$platform]['data'][] = $r;
                 } else {
                     $cloudsData[$platform]['data'][] = null;
                 }
             }
         } else {
             //Initializes with empty values to prevent data shifts on charts.
             if (!isset($collectionSet['byPlatformDetailed']['data'][$chartPoint->key]['data'])) {
                 $collectionSet['byPlatformDetailed']['data'][$chartPoint->key]['data'] = [];
             }
             $combined =& $collectionSet['byPlatformDetailed']['data'][$chartPoint->key]['data'];
             if (!empty($cloudsData)) {
                 foreach ($cloudsData as $platform => $t) {
                     if (!array_key_exists($platform, $combined)) {
                         $combined[$platform] = [];
                     }
                 }
             }
             foreach ($combined as $platform => $v) {
                 //Previous period details
                 if (isset($collectionSetPrev['byPlatformDetailed']['data'][$chartPoint->previousPeriodKey]['data'][$platform])) {
                     $pp = $collectionSetPrev['byPlatformDetailed']['data'][$chartPoint->previousPeriodKey]['data'][$platform];
                 } else {
                     $pp = null;
                 }
                 //Previous point details
                 if (isset($collectionSet['byPlatformDetailed']['data'][$prevPointKey]['data'][$platform])) {
                     $ppt = $collectionSet['byPlatformDetailed']['data'][$prevPointKey]['data'][$platform];
                 } else {
                     $ppt = null;
                 }
                 if (!isset($cloudsData[$platform]) && $i > 0) {
                     $cloudsData[$platform]['name'] = $platform;
                     //initializes platfrorm legend for the not filled period
                     $cloudsData[$platform]['data'] = array_fill(0, $i, null);
                 }
                 if (!$iterator->isFuture()) {
                     $r = $this->getPointDataArray($v, $pp, $ppt);
                     // projects data
                     $cloudProjectData = [];
                     if (!empty($v['data'])) {
                         foreach ($v['data'] as $projectId => $pv) {
                             if (isset($pp['data'][$projectId])) {
                                 $ppp = $pp['data'][$projectId];
                             } else {
                                 $ppp = null;
                             }
                             if (isset($ppt['data'][$projectId])) {
                                 $pppt = $ppt['data'][$projectId];
                             } else {
                                 $pppt = null;
                             }
                             $cloudProjectData[] = $this->getDetailedPointDataArray($projectId, $fnGetProjectName($projectId), $pv, $ppp, $pppt);
                         }
                     }
                     $r['projects'] = $cloudProjectData;
                     $cloudsData[$platform]['name'] = $platform;
                     $cloudsData[$platform]['data'][] = $r;
                 } else {
                     $cloudsData[$platform]['data'][] = null;
                 }
             }
         }
         //Period - Project - Platform subtotal
         if (!isset($collectionSet['byProjectDetailed']['data'][$chartPoint->key]['data'])) {
             foreach ($projectsData as $projectId => $v) {
                 if (!$iterator->isFuture()) {
                     //Previous period details
                     if (isset($collectionSetPrev['byProjectDetailed']['data'][$chartPoint->previousPeriodKey]['data'][$projectId])) {
                         $pp = $collectionSetPrev['byProjectDetailed']['data'][$chartPoint->previousPeriodKey]['data'][$projectId];
                     } else {
                         $pp = null;
                     }
                     //Previous point details
                     if (isset($collectionSet['byProjectDetailed']['data'][$prevPointKey]['data'][$projectId])) {
                         $ppt = $collectionSet['byProjectDetailed']['data'][$prevPointKey]['data'][$projectId];
                     } else {
                         $ppt = null;
                     }
                     $r = $this->getPointDataArray(null, $pp, $ppt);
                     //Projects data is empty
                     $r['clouds'] = [];
                     $projectsData[$projectId]['data'][] = $r;
                 } else {
                     $projectsData[$projectId]['data'][] = null;
                 }
             }
         } else {
             //Initializes with empty values to prevent data shifts on charts.
             if (!isset($collectionSet['byProjectDetailed']['data'][$chartPoint->key]['data'])) {
                 $collectionSet['byProjectDetailed']['data'][$chartPoint->key]['data'] = [];
             }
             $combined =& $collectionSet['byProjectDetailed']['data'][$chartPoint->key]['data'];
             if (!empty($projectsData)) {
                 foreach ($projectsData as $projectId => $t) {
                     if (!array_key_exists($projectId, $combined)) {
                         $combined[$projectId] = [];
                     }
                 }
             }
             foreach ($combined as $projectId => $v) {
                 //Previous period details
                 if (isset($collectionSetPrev['byProjectDetailed']['data'][$chartPoint->previousPeriodKey]['data'][$projectId])) {
                     $pp = $collectionSetPrev['byProjectDetailed']['data'][$chartPoint->previousPeriodKey]['data'][$projectId];
                 } else {
                     $pp = null;
                 }
                 //Previous point details
                 if (isset($collectionSet['byProjectDetailed']['data'][$prevPointKey]['data'][$projectId])) {
                     $ppt = $collectionSet['byProjectDetailed']['data'][$prevPointKey]['data'][$projectId];
                 } else {
                     $ppt = null;
                 }
                 if (!isset($projectsData[$projectId]) && $i > 0) {
                     $projectsData[$projectId]['name'] = $fnGetProjectName($projectId);
                     //initializes project legend for the not filled period
                     $projectsData[$projectId]['data'] = array_fill(0, $i, null);
                 }
                 if (!$iterator->isFuture()) {
                     $r = $this->getPointDataArray($v, $pp, $ppt);
                     // platform data
                     $cloudPlatformData = [];
                     if (!empty($v['data'])) {
                         foreach ($v['data'] as $platform => $pv) {
                             if (isset($pp['data'][$platform])) {
                                 $ppp = $pp['data'][$platform];
                             } else {
                                 $ppp = null;
                             }
                             if (isset($ppt['data'][$platform])) {
                                 $pppt = $ppt['data'][$platform];
                             } else {
                                 $pppt = null;
                             }
                             $cloudPlatformData[] = $this->getDetailedPointDataArray($platform, $platform, $pv, $ppp, $pppt);
                         }
                     }
                     $r['clouds'] = $cloudPlatformData;
                     $projectsData[$projectId]['name'] = $fnGetProjectName($projectId);
                     $projectsData[$projectId]['data'][] = $r;
                 } else {
                     $projectsData[$projectId]['data'][] = null;
                 }
             }
         }
         $prevPointKey = $chartPoint->key;
     }
     //complete arrays for cloud data and project data
     $cntpoints = count($timeline);
     foreach ($cloudsData as $platform => $v) {
         if (($j = count($v['data'])) < $cntpoints) {
             while ($j < $cntpoints) {
                 $cloudsData[$platform]['data'][] = null;
                 $j++;
             }
         }
     }
     foreach ($projectsData as $projectId => $v) {
         if (($j = count($v['data'])) < $cntpoints) {
             while ($j < $cntpoints) {
                 $projectsData[$projectId]['data'][] = null;
                 $j++;
             }
         }
     }
     //Spending trends uses daily usage precalculated data
     $trends = $this->calculateSpendingTrends(['ccId' => $ccId], $timeline, $queryInterval, $iterator->getEnd());
     if ($iterator->getWholePreviousPeriodEnd() != $iterator->getPreviousEnd()) {
         $rawPrevUsageWhole = $this->get(['ccId' => $ccId], $iterator->getPreviousStart(), $iterator->getWholePreviousPeriodEnd(), [TagEntity::TAG_ID_PLATFORM, TagEntity::TAG_ID_PROJECT], true);
         //Previous whole period usage subtotals by platform
         $prevUsageWhole = (new AggregationCollection(['platform'], ['cost' => 'sum']))->load($rawPrevUsageWhole);
         //Previous whole period usage subtotals by project
         $prevUsageWhole2 = (new AggregationCollection(['projectId'], ['cost' => 'sum']))->load($rawPrevUsageWhole);
     } else {
         $prevUsageWhole = $collectionSetPrev['byPlatform'];
         $prevUsageWhole2 = $collectionSetPrev['byProject'];
     }
     //Build cloud platforms total
     $cloudsTotal = [];
     $it = $collectionSet['byPlatform']->getIterator();
     foreach ($it as $platform => $p) {
         $pp = isset($collectionSetPrev['byPlatform']['data'][$platform]) ? $collectionSetPrev['byPlatform']['data'][$platform] : null;
         $pw = isset($prevUsageWhole['data'][$platform]) ? $prevUsageWhole['data'][$platform] : null;
         $cl = $this->getTotalDataArray($platform, $platform, $p, $pp, $pw, $cloudsData, $iterator);
         if ($it->hasChildren()) {
             $clProjects = [];
             foreach ($it->getChildren() as $projectId => $c) {
                 $cp = isset($collectionSetPrev['byPlatform']['data'][$platform]['data'][$projectId]) ? $collectionSetPrev['byPlatform']['data'][$platform]['data'][$projectId] : null;
                 $clProjects[] = $this->getTotalDataArray($projectId, $fnGetProjectName($projectId), $c, $cp, null, $projectsData, $iterator, true);
             }
             $cl['projects'] = $clProjects;
         } else {
             $cl['projects'] = [];
         }
         $cloudsTotal[] = $cl;
     }
     //Build projects total
     $projectsTotal = [];
     $it = $collectionSet['byProject']->getIterator();
     //For each assigned project wich is not archived we should display
     //zero dollar spend even if there are not any spend for
     //the selected period.
     $projectsWithoutSpend = [];
     foreach ($projects as $projectEntity) {
         /* @var $projectEntity \Scalr\Stats\CostAnalytics\Entity\ProjectEntity */
         if ($projectEntity->archived) {
             continue;
         }
         if (!isset($collectionSet['byProject']['data'][$projectEntity->projectId])) {
             $projectsWithoutSpend[$projectEntity->projectId] = ['cost' => 0, 'cost_percentage' => 0, 'id' => $projectEntity->projectId];
         }
     }
     //Passing projects with spend and then assigned projects without spend for the selected period
     foreach ([$it, $projectsWithoutSpend] as $internalIterator) {
         foreach ($internalIterator as $projectId => $p) {
             $pp = isset($collectionSetPrev['byProject']['data'][$projectId]) ? $collectionSetPrev['byProject']['data'][$projectId] : null;
             $pw = isset($prevUsageWhole2['data'][$projectId]) ? $prevUsageWhole2['data'][$projectId] : null;
             $cl = $this->getTotalDataArray($projectId, $fnGetProjectName($projectId), $p, $pp, $pw, $projectsData, $iterator);
             if ($internalIterator instanceof ArrayIterator && $internalIterator->hasChildren()) {
                 $clPlatforms = [];
                 foreach ($internalIterator->getChildren() as $platform => $c) {
                     $cp = isset($collectionSetPrev['byProject']['data'][$projectId]['data'][$platform]) ? $collectionSetPrev['byProject']['data'][$projectId]['data'][$platform] : null;
                     $clPlatforms[] = $this->getTotalDataArray($platform, $platform, $c, $cp, null, $cloudsData, $iterator, true);
                 }
                 $cl['clouds'] = $clPlatforms;
             } else {
                 $cl['clouds'] = [];
             }
             $projectsTotal[] = $cl;
         }
     }
     $data = ['reportVersion' => '0.1.0', 'totals' => ['cost' => round($collectionSet['byPlatform']['cost'], 2), 'prevCost' => round($collectionSetPrev['byPlatform']['cost'], 2), 'growth' => round($collectionSet['byPlatform']['cost'] - $collectionSetPrev['byPlatform']['cost'], 2), 'growthPct' => $collectionSetPrev['byPlatform']['cost'] == 0 ? null : round(abs(($collectionSet['byPlatform']['cost'] - $collectionSetPrev['byPlatform']['cost']) / $collectionSetPrev['byPlatform']['cost'] * 100), 0), 'clouds' => $cloudsTotal, 'projects' => $projectsTotal, 'trends' => $trends, 'forecastCost' => null], 'timeline' => $timeline, 'clouds' => $cloudsData, 'projects' => $projectsData, 'interval' => $queryInterval, 'startDate' => $iterator->getStart()->format('Y-m-d'), 'endDate' => $iterator->getEnd()->format('Y-m-d'), 'previousStartDate' => $iterator->getPreviousStart()->format('Y-m-d'), 'previousEndDate' => $iterator->getPreviousEnd()->format('Y-m-d')];
     if ($iterator->getTodayDate() < $iterator->getEnd()) {
         $data['totals']['forecastCost'] = self::calculateForecast($data['totals']['cost'], $iterator->getStart(), $iterator->getEnd(), $prevUsageWhole['cost'], ($data['totals']['growth'] >= 0 ? 1 : -1) * $data['totals']['growthPct'], isset($itemsRollingAvg['rollingAverageDaily']) ? $itemsRollingAvg['rollingAverageDaily'] : null);
     }
     $budgetRequest = ['ccId' => $ccId, 'usage' => $data['totals']['cost']];
     if ($mode != 'custom') {
         //We need to get budget for the appropriate quarter
         $budgetRequest['period'] = $iterator->getQuarterPeriod();
     }
     $budget = $this->getBudgetUsedPercentage($budgetRequest);
     $this->calculateBudgetEstimateOverspend($budget);
     $data['totals']['budget'] = $budget;
     return $data;
 }
示例#6
0
 /**
  * Gets all projects associated with the cost centre
  *
  * @return  \ArrayObject  Returns collection of the ProjectEntity objects
  */
 public function getProjects()
 {
     return ProjectEntity::findByCcId($this->ccId);
 }
示例#7
0
文件: Builder.php 项目: scalr/scalr
 public function xBuildAction()
 {
     $this->request->defineParams(array('farmId' => array('type' => 'int'), 'roles' => array('type' => 'json'), 'rolesToRemove' => array('type' => 'json'), 'farm' => array('type' => 'json'), 'launch' => array('type' => 'bool')));
     if (!$this->isFarmConfigurationValid($this->getParam('farmId'), $this->getParam('farm'), (array) $this->getParam('roles'))) {
         if ($this->errors['error_count'] != 0) {
             $this->response->failure();
             $this->response->data(array('errors' => $this->errors));
             return;
         }
     }
     $farm = $this->getParam('farm');
     $client = Client::Load($this->user->getAccountId());
     if ($this->getParam('farmId')) {
         $dbFarm = DBFarm::LoadByID($this->getParam('farmId'));
         $this->user->getPermissions()->validate($dbFarm);
         $this->request->checkPermissions($dbFarm->__getNewFarmObject(), Acl::PERM_FARMS_UPDATE);
         $dbFarm->isLocked();
         if ($this->getParam('changed') && $dbFarm->changedTime && $this->getParam('changed') != $dbFarm->changedTime) {
             $userName = '******';
             $changed = explode(' ', $this->getParam('changed'));
             $changedTime = intval($changed[1]);
             try {
                 $user = new Scalr_Account_User();
                 $user->loadById($dbFarm->changedByUserId);
                 $userName = $user->getEmail();
             } catch (Exception $e) {
             }
             $this->response->failure();
             $this->response->data(array('changedFailure' => sprintf('%s changed this farm at %s', $userName, Scalr_Util_DateTime::convertTz($changedTime))));
             return;
         } else {
             if ($this->getParam('changed')) {
                 $this->checkFarmConfigurationIntegrity($this->getParam('farmId'), $this->getParam('farm'), (array) $this->getParam('roles'), (array) $this->getParam('rolesToRemove'));
             }
         }
         $dbFarm->changedByUserId = $this->user->getId();
         $dbFarm->changedTime = microtime();
         if ($this->getContainer()->analytics->enabled) {
             $projectId = $farm['projectId'];
             if (empty($projectId)) {
                 $ccId = $dbFarm->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) {
                         $projectId = $projects->getArrayCopy()[0]->projectId;
                     }
                 }
             }
             if (!empty($projectId) && $dbFarm->GetSetting(Entity\FarmSetting::PROJECT_ID) != $projectId) {
                 $this->request->checkPermissions($dbFarm->__getNewFarmObject(), Acl::PERM_FARMS_PROJECTS);
             }
         }
         $bNew = false;
     } else {
         $this->request->restrictAccess(Acl::RESOURCE_OWN_FARMS, Acl::PERM_FARMS_CREATE);
         $this->user->getAccount()->validateLimit(Scalr_Limits::ACCOUNT_FARMS, 1);
         $dbFarm = new DBFarm();
         $dbFarm->ClientID = $this->user->getAccountId();
         $dbFarm->EnvID = $this->getEnvironmentId();
         $dbFarm->Status = FARM_STATUS::TERMINATED;
         $dbFarm->ownerId = $this->user->getId();
         $dbFarm->changedByUserId = $this->user->getId();
         $dbFarm->changedTime = microtime();
         $bNew = true;
     }
     if ($this->getParam('farm')) {
         $dbFarm->Name = $this->request->stripValue($farm['name']);
         $dbFarm->RolesLaunchOrder = $farm['rolesLaunchOrder'];
         $dbFarm->Comments = $this->request->stripValue($farm['description']);
     }
     if (empty($dbFarm->Name)) {
         throw new Exception(_("Farm name required"));
     }
     $setFarmTeams = false;
     if ($bNew) {
         $setFarmTeams = true;
     } else {
         if ($dbFarm->ownerId == $this->user->getId() || $this->request->hasPermissions($dbFarm->__getNewFarmObject(), Acl::PERM_FARMS_CHANGE_OWNERSHIP)) {
             if (is_numeric($farm['owner']) && $farm['owner'] != $dbFarm->ownerId) {
                 $dbFarm->ownerId = $farm['owner'];
                 $f = Entity\Farm::findPk($dbFarm->ID);
                 Entity\FarmSetting::addOwnerHistory($f, User::findPk($farm['owner']), User::findPk($this->user->getId()));
                 $f->save();
             }
             $setFarmTeams = true;
         }
     }
     $dbFarm->save();
     if ($setFarmTeams && is_array($farm['teamOwner'])) {
         /* @var $f Entity\Farm */
         $f = Entity\Farm::findPk($dbFarm->ID);
         $f->setTeams(empty($farm['teamOwner']) ? [] : Entity\Account\Team::find([['name' => ['$in' => $farm['teamOwner']]], ['accountId' => $this->getUser()->accountId]]));
         $f->save();
     }
     if ($bNew) {
         $dbFarm->SetSetting(Entity\FarmSetting::CREATED_BY_ID, $this->user->getId());
         $dbFarm->SetSetting(Entity\FarmSetting::CREATED_BY_EMAIL, $this->user->getEmail());
     }
     $governance = new Scalr_Governance($this->getEnvironmentId());
     if (!$this->getParam('farmId') && $governance->isEnabled(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_LEASE)) {
         $dbFarm->SetSetting(Entity\FarmSetting::LEASE_STATUS, 'Active');
         // for created farm
     }
     if (isset($farm['variables'])) {
         $variables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), ScopeInterface::SCOPE_FARM);
         $variables->setValues(is_array($farm['variables']) ? $farm['variables'] : [], 0, $dbFarm->ID, 0, '', false, true);
     }
     if (!$farm['timezone']) {
         $farm['timezone'] = date_default_timezone_get();
     }
     $dbFarm->SetSetting(Entity\FarmSetting::TIMEZONE, $farm['timezone']);
     $dbFarm->SetSetting(Entity\FarmSetting::EC2_VPC_ID, isset($farm["vpc_id"]) ? $farm['vpc_id'] : null);
     $dbFarm->SetSetting(Entity\FarmSetting::EC2_VPC_REGION, isset($farm["vpc_id"]) ? $farm['vpc_region'] : null);
     $dbFarm->SetSetting(Entity\FarmSetting::SZR_UPD_REPOSITORY, $farm[Entity\FarmSetting::SZR_UPD_REPOSITORY]);
     $dbFarm->SetSetting(Entity\FarmSetting::SZR_UPD_SCHEDULE, $farm[Entity\FarmSetting::SZR_UPD_SCHEDULE]);
     if (!$dbFarm->GetSetting(Entity\FarmSetting::CRYPTO_KEY)) {
         $dbFarm->SetSetting(Entity\FarmSetting::CRYPTO_KEY, Scalr::GenerateRandomKey(40));
     }
     if ($this->getContainer()->analytics->enabled) {
         //Cost analytics project must be set for the Farm object
         $dbFarm->setProject(!empty($farm['projectId']) ? $farm['projectId'] : null);
     }
     $virtualFarmRoles = array();
     $roles = $this->getParam('roles');
     if (!empty($roles)) {
         foreach ($roles as $role) {
             if (strpos($role['farm_role_id'], "virtual_") !== false) {
                 $dbRole = DBRole::loadById($role['role_id']);
                 $dbFarmRole = $dbFarm->AddRole($dbRole, $role['platform'], $role['cloud_location'], (int) $role['launch_index'], $role['alias']);
                 $virtualFarmRoles[$role['farm_role_id']] = $dbFarmRole->ID;
             }
         }
     }
     $usedPlatforms = array();
     $farmRoleVariables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), ScopeInterface::SCOPE_FARMROLE);
     if (!empty($roles)) {
         foreach ($roles as $role) {
             if ($role['farm_role_id']) {
                 if (isset($virtualFarmRoles[$role['farm_role_id']])) {
                     $role['farm_role_id'] = $virtualFarmRoles[$role['farm_role_id']];
                 }
                 $update = true;
                 $dbFarmRole = DBFarmRole::LoadByID($role['farm_role_id']);
                 $dbRole = DBRole::loadById($dbFarmRole->RoleID);
                 $role['role_id'] = $dbFarmRole->RoleID;
                 if ($dbFarmRole->Platform == SERVER_PLATFORMS::GCE) {
                     $dbFarmRole->CloudLocation = $role['cloud_location'];
                 }
             } else {
                 /** TODO:  Remove because will be handled with virtual_ **/
                 $update = false;
                 $dbRole = DBRole::loadById($role['role_id']);
                 $dbFarmRole = $dbFarm->AddRole($dbRole, $role['platform'], $role['cloud_location'], (int) $role['launch_index']);
             }
             if ($dbRole->hasBehavior(ROLE_BEHAVIORS::RABBITMQ)) {
                 $role['settings'][Entity\FarmRoleSetting::SCALING_MAX_INSTANCES] = $role['settings'][Entity\FarmRoleSetting::SCALING_MIN_INSTANCES];
             }
             if ($update) {
                 $dbFarmRole->LaunchIndex = (int) $role['launch_index'];
                 $dbFarmRole->Alias = $role['alias'];
                 $dbFarmRole->Save();
             }
             $usedPlatforms[$role['platform']] = 1;
             $oldRoleSettings = $dbFarmRole->GetAllSettings();
             // Update virtual farm_role_id with actual value
             $scripts = (array) $role['scripting'];
             if (!empty($virtualFarmRoles)) {
                 array_walk_recursive($scripts, function (&$v, $k) use($virtualFarmRoles) {
                     if (is_string($v)) {
                         $v = str_replace(array_keys($virtualFarmRoles), array_values($virtualFarmRoles), $v);
                     }
                 });
                 array_walk_recursive($role['settings'], function (&$v, $k) use($virtualFarmRoles) {
                     if (is_string($v)) {
                         $v = str_replace(array_keys($virtualFarmRoles), array_values($virtualFarmRoles), $v);
                     }
                 });
             }
             $dbFarmRole->ClearSettings("chef.");
             if (!empty($role['scaling_settings']) && is_array($role['scaling_settings'])) {
                 foreach ($role['scaling_settings'] as $k => $v) {
                     $dbFarmRole->SetSetting($k, $v, Entity\FarmRoleSetting::TYPE_CFG);
                 }
             }
             foreach ($role['settings'] as $k => $v) {
                 $dbFarmRole->SetSetting($k, $v, Entity\FarmRoleSetting::TYPE_CFG);
             }
             /****** Scaling settings ******/
             $scalingManager = new Scalr_Scaling_Manager($dbFarmRole);
             $scalingManager->setFarmRoleMetrics(is_array($role['scaling']) ? $role['scaling'] : array());
             //TODO: optimize this code...
             $this->db->Execute("DELETE FROM farm_role_scaling_times WHERE farm_roleid=?", array($dbFarmRole->ID));
             // 5 = Time based scaling -> move to constants
             if (!empty($role['scaling'][Entity\ScalingMetric::METRIC_DATE_AND_TIME_ID])) {
                 foreach ($role['scaling'][Entity\ScalingMetric::METRIC_DATE_AND_TIME_ID] as $scal_period) {
                     $chunks = explode(":", $scal_period['id']);
                     $this->db->Execute("INSERT INTO farm_role_scaling_times SET\n                            farm_roleid\t\t= ?,\n                            start_time\t\t= ?,\n                            end_time\t\t= ?,\n                            days_of_week\t= ?,\n                            instances_count\t= ?\n                        ", array($dbFarmRole->ID, $chunks[0], $chunks[1], $chunks[2], $chunks[3]));
                 }
             }
             /*****************/
             /* Add script options to databse */
             $dbFarmRole->SetScripts($scripts, (array) $role['scripting_params']);
             /* End of scripting section */
             /* Add storage configuration */
             if (isset($role['storages']['configs'])) {
                 $dbFarmRole->getStorage()->setConfigs($role['storages']['configs'], false);
             }
             $farmRoleVariables->setValues(is_array($role['variables']) ? $role['variables'] : [], $dbFarmRole->GetRoleID(), $dbFarm->ID, $dbFarmRole->ID, '', false, true);
             foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) {
                 $behavior->onFarmSave($dbFarm, $dbFarmRole);
             }
             /**
              * Platform specified updates
              */
             if ($dbFarmRole->Platform == SERVER_PLATFORMS::EC2) {
                 \Scalr\Modules\Platforms\Ec2\Helpers\EbsHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']);
                 \Scalr\Modules\Platforms\Ec2\Helpers\EipHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']);
                 if ($role['settings']['aws.elb.remove']) {
                     $this->request->restrictAccess(Acl::RESOURCE_AWS_ELB, Acl::PERM_AWS_ELB_MANAGE);
                 }
                 \Scalr\Modules\Platforms\Ec2\Helpers\ElbHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']);
             }
             if (in_array($dbFarmRole->Platform, array(SERVER_PLATFORMS::IDCF, SERVER_PLATFORMS::CLOUDSTACK))) {
                 Scalr\Modules\Platforms\Cloudstack\Helpers\CloudstackHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']);
             }
         }
     }
     $rolesToRemove = $this->getParam('rolesToRemove');
     if (!empty($rolesToRemove)) {
         $currentFarmRoles = Entity\FarmRole::find([['farmId' => $dbFarm->ID], ['id' => ['$in' => $rolesToRemove]]]);
         /* @var $farmRole Entity\FarmRole */
         foreach ($currentFarmRoles as $farmRole) {
             $farmRole->delete();
         }
     }
     $dbFarm->save();
     if (!$client->GetSettingValue(CLIENT_SETTINGS::DATE_FARM_CREATED)) {
         $client->SetSettingValue(CLIENT_SETTINGS::DATE_FARM_CREATED, time());
     }
     if ($this->request->hasPermissions($dbFarm->__getNewFarmObject(), Acl::PERM_FARMS_LAUNCH_TERMINATE) && $this->getParam('launch')) {
         $this->user->getPermissions()->validate($dbFarm);
         $dbFarm->isLocked();
         Scalr::FireEvent($dbFarm->ID, new FarmLaunchedEvent(true, $this->user->id));
         $this->response->success('Farm successfully saved and launched');
     } else {
         $this->response->success('Farm successfully saved');
     }
     $this->response->data(array('farmId' => $dbFarm->ID, 'isNewFarm' => $bNew));
 }