      1: <?php
      2: /**
      3:  * Copyright 2012-2014 Rackspace US, Inc.
      4:  *
      5:  * Licensed under the Apache License, Version 2.0 (the "License");
      6:  * you may not use this file except in compliance with the License.
      7:  * You may obtain a copy of the License at
      8:  *
      9:  * http://www.apache.org/licenses/LICENSE-2.0
     10:  *
     11:  * Unless required by applicable law or agreed to in writing, software
     12:  * distributed under the License is distributed on an "AS IS" BASIS,
     13:  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14:  * See the License for the specific language governing permissions and
     15:  * limitations under the License.
     16:  */
     17:
     18: namespace OpenCloud\Autoscale\Resource;
     19:
     20: use OpenCloud\Common\Exceptions;
     21: use OpenCloud\Common\Http\Message\Formatter;
     22:
     23: /**
     24:  * An autoscaling group is monitored by Rackspace CloudMonitoring. When
     25:  * Monitoring triggers an alarm for high utilization within the autoscaling
     26:  * group, a webhook is triggered. The webhook stimulates the autoscale service
     27:  * which consults a policy in accordance with the webhook. The policy determines
     28:  * how many additional cloud servers should be added or removed in accordance
     29:  * with the alarm.
     30:  *
     31:  * There are three components to Autoscale:
     32:  *
     33:  * - The Scaling Group Configuration ($this->groupConfiguration)
     34:  * - The Scaling Group's Launch Configuration ($this->launchConfiguration)
     35:  * - The Scaling Group's Policies ($this->scalingPolicies)
     36:  *
     37:  * @link https://github.com/rackerlabs/otter/blob/master/doc/getting_started.rst
     38:  * @link http://docs.autoscale.apiary.io/
     39:  */
     40: class Group extends AbstractResource
     41: {
     42:     private $id;
     43:     private $links;
     44:     private $groupConfiguration;
     45:     private $launchConfiguration;
     46:     private $scalingPolicies;
     47:     private $name;
     48:     protected $metadata;
     49:
     50:     private $active;
     51:     private $activeCapacity;
     52:     private $pendingCapacity;
     53:     private $desiredCapacity;
     54:     private $paused;
     55:
     56:     protected static $json_name = 'group';
     57:     protected static $url_resource = 'groups';
     58:     protected static $json_collection_name = 'groups';
     59:
     60:     /**
     61:      * {@inheritDoc}
     62:      */
     63:     public $createKeys = array(
     64:         'groupConfiguration',
     65:         'launchConfiguration',
     66:         'scalingPolicies'
     67:     );
     68:
     69:     /**
     70:      * {@inheritDoc}
     71:      */
     72:     public $associatedResources = array(
     73:         'groupConfiguration'  => 'GroupConfiguration',
     74:         'launchConfiguration' => 'LaunchConfiguration',
     75:
     76:     );
     77:
     78:     /**
     79:      * {@inheritDoc}
     80:      */
     81:     public $associatedCollections = array(
     82:         'scalingPolicies' => 'ScalingPolicy'
     83:     );
     84:
     85:     /**
     86:      * {@inheritDoc}
     87:      */
     88:     public function update($params = array())
     89:     {
     90:         return $this->noUpdate();
     91:     }
     92:
     93:     /**
     94:      * Get the current state of the scaling group, including the current set of
     95:      * active entities, the number of pending entities, and the desired number
     96:      * of entities.
     97:      *
     98:      * @return object|boolean
     99:      * @throws Exceptions\HttpError
    100:      * @throws Exceptions\ServerActionError
    101:      */
    102:     public function getState()
    103:     {
    104:         $response = $this->getService()
    105:             ->getClient()
    106:             ->get($this->url('state'))
    107:             ->send();
    108:
    109:         $body = Formatter::decode($response);
    110:
    111:         return (!empty($body->group)) ? $body->group : false;
    112:     }
    113:
    114:     /**
    115:      * Get the group configuration for this autoscale group.
    116:      *
    117:      * @return GroupConfiguration
    118:      */
    119:     public function getGroupConfig()
    120:     {
    121:         if (($config = $this->getProperty('groupConfiguration')) instanceof GroupConfiguration) {
    122:             return $config;
    123:         }
    124:
    125:         $config = $this->getService()->resource('GroupConfiguration');
    126:         $config->setParent($this);
    127:         if ($this->getId()) {
    128:             $config->refresh(null, $config->url());
    129:         }
    130:
    131:         return $config;
    132:     }
    133:
    134:     /**
    135:      * Get the launch configuration for this autoscale group.
    136:      *
    137:      * @return LaunchConfiguration
    138:      */
    139:     public function getLaunchConfig()
    140:     {
    141:         if (($config = $this->getProperty('launchConfiguration')) instanceof LaunchConfiguration) {
    142:             return $config;
    143:         }
    144:
    145:         $config = $this->getService()->resource('LaunchConfiguration');
    146:         $config->setParent($this);
    147:         if ($this->getId()) {
    148:             $config->refresh(null, $config->url());
    149:         }
    150:
    151:         return $config;
    152:     }
    153:
    154:     /**
    155:      * NB: NOT SUPPORTED YET.
    156:      *
    157:      * @codeCoverageIgnore
    158:      */
    159:     public function pause()
    160:     {
    161:         return $this->getService()->getClient()->post($this->url('pause'))->send();
    162:     }
    163:
    164:     /**
    165:      * NB: NOT SUPPORTED YET.
    166:      *
    167:      * @codeCoverageIgnore
    168:      */
    169:     public function resume()
    170:     {
    171:         return $this->getService()->getClient()->post($this->url('resume'))->send();
    172:     }
    173:
    174:     /**
    175:      * Get the scaling policies associated with this autoscale group.
    176:      *
    177:      * @return Collection
    178:      */
    179:     public function getScalingPolicies($override = false)
    180:     {
    181:         if (null === $this->scalingPolicies || $override === true) {
    182:             $this->scalingPolicies = $this->getService()->resourceList('ScalingPolicy', null, $this);
    183:         }
    184:
    185:         return $this->scalingPolicies;
    186:     }
    187:
    188:     /**
    189:      * Get a particular scaling policy for this autoscale group.
    190:      *
    191:      * @param  object|int $id
    192:      * @return ScalingPolicy
    193:      */
    194:     public function getScalingPolicy($id = null)
    195:     {
    196:         $config = $this->getService()->resource('ScalingPolicy');
    197:         $config->setParent($this);
    198:         if ($id) {
    199:             $config->populate($id);
    200:         }
    201:
    202:         return $config;
    203:     }
    204:
    205:     public function createScalingPolicies(array $policies)
    206:     {
    207:         $url = clone $this->getUrl();
    208:         $url->addPath('policies');
    209:
    210:         $body = json_encode($policies);
    211:         $this->checkJsonError();
    212:
    213:         return $this->getService()
    214:             ->getClient()
    215:             ->post($url, self::getJsonHeader(), $body)
    216:             ->send();
    217:     }
    218: }
    219: