Skip to content

Commit

Permalink
Switching from service levels to plans (pantheon-systems#1901)
Browse files Browse the repository at this point in the history
  • Loading branch information
TeslaDethray authored Nov 14, 2018
1 parent 498d3c8 commit 7773fc7
Show file tree
Hide file tree
Showing 29 changed files with 1,346 additions and 38 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org)

## MASTER
### Added
- New `plan:list` command lists the plans available to a site. (#1901)
- New `plan:set` command sets a site's plan. (#1901)
- New `Plans` collection interacts with plans available to a Site. (#1901)
- New `Plan` model represents a plan available to a Site or set on a site. (#1901)
- New `Site::getPlan()` function to retrieve a model representing the Site's present plan. (#1901)
- New `Site::getPlans()` function to retrieve a collection representing all available plans for the Site. (#1901)

### Changed
- `org:site:list` now displays a `Plan`/`plan_name` field to replace `Service Level`/`service_level`. (#1901)
- `site:info` now displays a `Plan`/`plan_name` field to replace `Service Level`/`service_level`. (#1901)
- `site:list` now displays a `Plan`/`plan_name` field to replace `Service Level`/`service_level`. (#1901)

### Deprecated
- `service-level:set` is now deprecated. Please use `plan:set`. (#1901)
- `Site::updateServiceLevel()` is now deprecated. Please use `Plans::set()`. (#1901)

## 1.9.0 - 2018-09-11
### Added
Expand Down
5 changes: 3 additions & 2 deletions config/constants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ TERMINUS_DASHBOARD_HOST: 'dashboard.pantheon.io'
TERMINUS_DASHBOARD_PROTOCOL: 'https'

# Localization
TERMINUS_DATE_FORMAT: 'Y-m-d H:i:s'
TERMINUS_TIME_ZONE: 'UTC'
TERMINUS_DATE_FORMAT: 'Y-m-d H:i:s'
TERMINUS_MONETARY_FORMAT: '$%01.2f'
TERMINUS_TIME_ZONE: 'UTC'

# File Storage
TERMINUS_CACHE_DIR: '[[ TERMINUS_USER_HOME ]]/.terminus/cache'
Expand Down
36 changes: 36 additions & 0 deletions src/Collections/Plans.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Pantheon\Terminus\Collections;

use Pantheon\Terminus\Models\Plan;

/**
* Class Plans
* @package Pantheon\Terminus\Collections
*/
class Plans extends SiteOwnedCollection
{
public static $pretty_name = 'plans';
/**
* @var string
*/
protected $collected_class = Plan::class;
/**
* @var string
*/
protected $url = 'sites/{site_id}/plans';

/**
* Sets the site's plan to the plan indicated.
*
* @param Plan $plan Plan to be set.
* @return Workflow
*/
public function set(Plan $plan)
{
return $this->getSite()->getWorkflows()->create(
'change_site_service_level',
['params' => ['sku' => $plan->getSku(),],]
);
}
}
2 changes: 1 addition & 1 deletion src/Commands/Org/Site/ListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class ListCommand extends TerminusCommand implements SiteAwareInterface
* @field-labels
* name: Name
* id: ID
* service_level: Service Level
* plan_name: Plan
* framework: Framework
* owner: Owner
* created: Created
Expand Down
47 changes: 47 additions & 0 deletions src/Commands/Plan/InfoCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Pantheon\Terminus\Commands\Plan;

use Consolidation\OutputFormatters\StructuredData\PropertyList;
use Pantheon\Terminus\Commands\Site\SiteCommand;

/**
* Class InfoCommand
* @package Pantheon\Terminus\Commands\Plan
*/
class InfoCommand extends SiteCommand
{
/**
* Displays information about a site's plan.
*
* @authorize
*
* @command plan:info
*
* @field-labels
* id: ID
* sku: SKU
* name: Name
* billing_cycle: Billing Cycle
* price: Price
* monthly_price: Monthly Price
* automated_backups: Automated Backups
* cache_server: Cache Server
* custom_upstreams: Custom Upstreams
* multidev: Multidev Environments
* new_relic: New Relic
* rackspace_ssl: Rackspace SSL
* secure_runtime_access: Secure Runtime Access
* storage: Storage (GB)
* support_plan: Support Plan
* @return PropertyList
*
* @param string $site The name or UUID of a site to retrieve current plan information on
*
* @usage <site> Displays <site>'s current plan information.
*/
public function info($site)
{
return new PropertyList($this->sites->get($site)->getPlan()->fetch()->serialize());
}
}
38 changes: 38 additions & 0 deletions src/Commands/Plan/ListCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Pantheon\Terminus\Commands\Plan;

use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
use Pantheon\Terminus\Commands\Site\SiteCommand;

/**
* Class ListCommand
* @package Pantheon\Terminus\Commands\Plan
*/
class ListCommand extends SiteCommand
{
/**
* Displays the list of available site plans.
*
* @authorize
*
* @command plan:list
* @aliases plans
*
* @field-labels
* sku: SKU
* name: Name
* billing_cycle: Billing Cycle
* price: Price
* monthly_price: Monthly Price
* @return RowsOfFields
*
* @param string $site_id The name or UUID of a site to view the available plans for
*
* @usage <site_id> Displays a list of plans available to <site>.
*/
public function listPlans($site_id)
{
return new RowsOfFields($this->getSite($site_id)->getPlans()->serialize());
}
}
40 changes: 40 additions & 0 deletions src/Commands/Plan/SetCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Pantheon\Terminus\Commands\Plan;

use Pantheon\Terminus\Commands\TerminusCommand;
use Pantheon\Terminus\Site\SiteAwareInterface;
use Pantheon\Terminus\Site\SiteAwareTrait;

/**
* Class SetCommand
* @package Pantheon\Terminus\Commands\Plan
*/
class SetCommand extends TerminusCommand implements SiteAwareInterface
{
use SiteAwareTrait;

/**
* Changes a site's plan.
*
* @authorize
*
* @command plan:set
*
* @param string $site_id Site name
* @param string $plan_id The SKU or UUID of the plan to set
*
* @usage <site> <plan> Updates <site>'s plan to <plan>.
*/
public function set($site_id, $plan_id)
{
$site = $this->getSite($site_id);
$plans = $site->getPlans();
$workflow = $plans->set($plans->get($plan_id));
$this->log()->notice('Setting plan of "{site_id}" to "{plan_id}".', compact('site_id', 'plan_id'));
while (!$workflow->checkProgress()) {
// @TODO: Add Symfony progress bar to indicate that something is happening.
}
$this->log()->notice($workflow->getMessage());
}
}
2 changes: 2 additions & 0 deletions src/Commands/ServiceLevel/SetCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class SetCommand extends TerminusCommand implements SiteAwareInterface
/**
* Upgrades or downgrades a site's service level.
*
* @deprecated 2.0.0 This will be removed in the future. Please use plan:set and plan:list instead.
*
* @authorize
*
* @command service-level:set
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/Site/InfoCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class InfoCommand extends SiteCommand
* created: Created
* framework: Framework
* organization: Organization
* service_level: Service Level
* plan_name: Plan
* max_num_cdes: Max Multidevs
* upstream: Upstream
* php_version: PHP Version
Expand Down
4 changes: 2 additions & 2 deletions src/Commands/Site/ListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ class ListCommand extends SiteCommand
* @field-labels
* name: Name
* id: ID
* service_level: Service Level
* plan_name: Plan
* framework: Framework
* owner: Owner
* created: Created
* memberships: Memberships
* frozen: Is Frozen?
* last_frozen_at: Date frozen
* @default-fields name,id,service_level,framework,owner,created,memberships,frozen
* @default-fields name,id,plan_name,framework,owner,created,memberships,frozen
* @return RowsOfFields
*
* @option name Name filter
Expand Down
126 changes: 126 additions & 0 deletions src/Models/Plan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

namespace Pantheon\Terminus\Models;

use Pantheon\Terminus\Friends\SiteInterface;
use Pantheon\Terminus\Friends\SiteTrait;
use Robo\Common\ConfigAwareTrait;
use Robo\Contract\ConfigAwareInterface;

/**
* Class Plan
* @package Pantheon\Terminus\Models
*/
class Plan extends TerminusModel implements ConfigAwareInterface, SiteInterface
{
use ConfigAwareTrait;
use SiteTrait;

public static $pretty_name = 'plan';
/**
* @var string
*/
protected $url = 'sites/{site_id}/plan';

/**
* @inheritdoc
*/
public function __construct($attributes = null, array $options = [])
{
if (property_exists($attributes, 'attributes')) {
$attributes = (object)$attributes->attributes;
}
parent::__construct($attributes, $options);
}

/**
* @return float|int
*/
public function getMonthlyPrice()
{
$price = (integer)$this->get('price');
if ($this->isAnnual()) {
return $price/12;
}
return $price;
}

/**
* @return string
*/
public function getName()
{
$name = $this->get('name');
return !is_null($name) ? $name : $this->get('plan_name');
}

/**
* @return string[]
*/
public function getReferences()
{
return [$this->id, $this->getSku(),];
}

/**
* @return string
*/
public function getSku()
{
$sku = $this->get('sku');
return !is_null($sku) ? $sku : $this->get('plan_sku');
}

/**
* @return boolean
*/
public function isAnnual()
{
return $this->get('billing_cycle') === 'annual';
}

/**
* @return boolean
*/
public function isFree()
{
return strpos($this->getSku(), 'plan-free') === 0;
}

/**
* @return boolean
*/
public function isMonthly()
{
return $this->get('billing_cycle') === 'monthly';
}

/**
* @return null|string
*/
public function formatPrice($price)
{
if (!$this->isFree() && ($price === 0)) {
return null;
}
return sprintf($this->getConfig()->get('monetary_format'), ($price / 100));
}


/**
* Formats plan object into an associative array for output
*
* @return array Associative array of data for output
*/
public function serialize()
{
return [
'billing_cycle' => $this->get('billing_cycle'),
'id' => $this->id,
'monthly_price' => $this->formatPrice($this->getMonthlyPrice()),
'name' => $this->getName(),
'price' => $this->formatPrice($this->get('price')),
'sku' => $this->getSku(),
];
}
}
Loading

0 comments on commit 7773fc7

Please sign in to comment.