      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\Database\Resource;
     19:
     20: use OpenCloud\Common\Http\Message\Formatter;
     21: use OpenCloud\Common\Lang;
     22: use OpenCloud\Common\Exceptions;
     23: use OpenCloud\Common\Resource\NovaResource;
     24: use OpenCloud\Compute\Resource\Flavor;
     25: use OpenCloud\Database\Service;
     26:
     27: /**
     28:  * Instance represents an instance of DbService, similar to a Server in a
     29:  * Compute service
     30:  */
     31: class Instance extends NovaResource
     32: {
     33:     public $id;
     34:     public $name;
     35:     public $status;
     36:     public $links;
     37:     public $hostname;
     38:     public $volume;
     39:     public $created;
     40:     public $updated;
     41:     public $flavor;
     42:
     43:     protected static $json_name = 'instance';
     44:     protected static $url_resource = 'instances';
     45:
     46:     private $_databases; // used to Create databases simultaneously
     47:     private $_users; // used to Create users simultaneously
     48:
     49:     /**
     50:      * Creates a new instance object
     51:      *
     52:      * This could use the default constructor, but we want to make sure that
     53:      * the volume attribute is an object.
     54:      *
     55:      * @param \OpenCloud\DbService $service the DbService object associated
     56:      *                                      with this
     57:      * @param mixed                $info    the ID or array of info for the object
     58:      */
     59:     public function __construct(Service $service, $info = null)
     60:     {
     61:         $this->volume = new \stdClass;
     62:
     63:         return parent::__construct($service, $info);
     64:     }
     65:
     66:     /**
     67:      * Updates a database instance (not permitted)
     68:      *
     69:      * Update() is not supported by database instances; thus, this always
     70:      * throws an exception.
     71:      *
     72:      * @throws InstanceUpdateError always
     73:      */
     74:     public function update($params = array())
     75:     {
     76:         return $this->noUpdate();
     77:     }
     78:
     79:     /**
     80:      * Restarts the database instance
     81:      *
     82:      * @api
     83:      * @returns \OpenCloud\HttpResponse
     84:      */
     85:     public function restart()
     86:     {
     87:         return $this->action($this->restartJson());
     88:     }
     89:
     90:     /**
     91:      * Resizes the database instance (sets RAM)
     92:      *
     93:      * @api
     94:      * @param \OpenCloud\Compute\Flavor $flavor a flavor object
     95:      * @returns \OpenCloud\HttpResponse
     96:      */
     97:     public function resize(Flavor $flavor)
     98:     {
     99:         return $this->action($this->resizeJson($flavor->id));
    100:     }
    101:
    102:     /**
    103:      * Resizes the volume associated with the database instance (disk space)
    104:      *
    105:      * @api
    106:      * @param integer $newvolumesize the size of the new volume, in gigabytes
    107:      * @return \OpenCloud\HttpResponse
    108:      */
    109:     public function resizeVolume($newvolumesize)
    110:     {
    111:         return $this->action($this->resizeVolumeJson($newvolumesize));
    112:     }
    113:
    114:     /**
    115:      * Enables the root user for the instance
    116:      *
    117:      * @api
    118:      * @return User the root user, including name and password
    119:      * @throws InstanceError if HTTP response is not Success
    120:      */
    121:     public function enableRootUser()
    122:     {
    123:         $response = $this->getClient()->post($this->getUrl('root'))->send();
    124:         $body = Formatter::decode($response);
    125:
    126:         return (isset($body->user)) ? new User($this, $body->user) : false;
    127:     }
    128:
    129:     /**
    130:      * Returns TRUE if the root user is enabled
    131:      *
    132:      * @api
    133:      * @return boolean TRUE if the root user is enabled; FALSE otherwise
    134:      * @throws InstanceError if HTTP status is not Success
    135:      */
    136:     public function isRootEnabled()
    137:     {
    138:         $response = $this->getClient()->get($this->url('root'))->send();
    139:         $body = Formatter::decode($response);
    140:
    141:         return !empty($body->rootEnabled);
    142:     }
    143:
    144:     /**
    145:      * Returns a new Database object
    146:      *
    147:      * @param string $name the database name
    148:      * @return Database
    149:      */
    150:     public function database($name = '')
    151:     {
    152:         return new Database($this, $name);
    153:     }
    154:
    155:     /**
    156:      * Returns a new User object
    157:      *
    158:      * @param string $name      the user name
    159:      * @param array  $databases a simple array of database names
    160:      * @return User
    161:      */
    162:     public function user($name = '', $databases = array())
    163:     {
    164:         return new User($this, $name, $databases);
    165:     }
    166:
    167:     /**
    168:      * Returns a Collection of all databases in the instance
    169:      *
    170:      * @return OpenCloud\Common\Collection\PaginatedIterator
    171:      */
    172:     public function databaseList()
    173:     {
    174:         return $this->getService()->resourceList('Database', $this->getUrl('databases'), $this);
    175:     }
    176:
    177:     /**
    178:      * Returns a Collection of all users in the instance
    179:      *
    180:      * @return OpenCloud\Common\Collection\PaginatedIterator
    181:      */
    182:     public function userList()
    183:     {
    184:         return $this->getService()->resourceList('User', $this->getUrl('users'), $this);
    185:     }
    186:
    187:     /**
    188:      * Generates the JSON string for Create()
    189:      *
    190:      * @return \stdClass
    191:      */
    192:     protected function createJson()
    193:     {
    194:         if (empty($this->flavor) || !is_object($this->flavor)) {
    195:             throw new Exceptions\InstanceFlavorError(
    196:                 Lang::translate('The `flavor` attribute is required and must be a Flavor object')
    197:             );
    198:         }
    199:
    200:         if (!isset($this->name)) {
    201:             throw new Exceptions\InstanceError(
    202:                 Lang::translate('Instance name is required')
    203:             );
    204:         }
    205:
    206:         return (object) array(
    207:             'instance' => (object) array(
    208:                     'flavorRef' => $this->flavor->links[0]->href,
    209:                     'name'      => $this->name,
    210:                     'volume'    => $this->volume
    211:                 )
    212:         );
    213:     }
    214:
    215:     /**
    216:      * Generates the JSON object for Restart
    217:      */
    218:     private function restartJson()
    219:     {
    220:         return (object) array('restart' => new \stdClass);
    221:     }
    222:
    223:     /**
    224:      * Generates the JSON object for Resize
    225:      */
    226:     private function resizeJson($flavorRef)
    227:     {
    228:         return (object) array(
    229:             'resize' => (object) array('flavorRef' => $flavorRef)
    230:         );
    231:     }
    232:
    233:     /**
    234:      * Generates the JSON object for ResizeVolume
    235:      */
    236:     private function resizeVolumeJson($size)
    237:     {
    238:         return (object) array(
    239:             'resize' => (object) array(
    240:                     'volume' => (object) array('size' => $size)
    241:                 )
    242:         );
    243:     }
    244: }
    245: