Overview

Namespaces

  • OpenCloud
    • Autoscale
      • Resource
    • CloudMonitoring
      • Exception
      • Resource
    • Common
      • Collection
      • Constants
      • Exceptions
      • Http
        • Message
      • Identity
      • Log
      • Service
    • Compute
      • Constants
      • Exception
      • Resource
    • Database
      • Resource
    • DNS
      • Resource
    • LoadBalancer
      • Resource
    • ObjectStore
      • Constants
      • Exception
      • Resource
      • Upload
    • Orchestration
    • Queues
      • Exception
      • Resource
    • Volume
      • Resource
  • PHP

Classes

  • OpenStack
  • Rackspace
  • Overview
  • Namespace
  • Class
  • Tree
  • Download
  1: <?php
  2: /**
  3:  * PHP OpenCloud library.
  4:  * 
  5:  * @copyright 2013 Rackspace Hosting, Inc. See LICENSE for information.
  6:  * @license   https://www.apache.org/licenses/LICENSE-2.0
  7:  * @author    Jamie Hannaford <jamie.hannaford@rackspace.com>
  8:  * @author    Glen Campbell <glen.campbell@rackspace.com>
  9:  */
 10: 
 11: namespace OpenCloud;
 12: 
 13: use OpenCloud\Common\Constants\Header;
 14: use OpenCloud\Common\Constants\Mime;
 15: use OpenCloud\Common\Http\Client;
 16: use OpenCloud\Common\Http\Message\RequestSubscriber;
 17: use OpenCloud\Common\Lang;
 18: use OpenCloud\Common\Exceptions;
 19: use OpenCloud\Common\Service\ServiceBuilder;
 20: use OpenCloud\Common\Service\Catalog;
 21: use OpenCloud\Common\Http\Message\Formatter;
 22: use Guzzle\Http\Url;
 23: 
 24: define('RACKSPACE_US', 'https://identity.api.rackspacecloud.com/v2.0/');
 25: define('RACKSPACE_UK', 'https://lon.identity.api.rackspacecloud.com/v2.0/');
 26: 
 27: /**
 28:  * The main client of the library. This object is the central point of negotiation between your application and the
 29:  * API because it handles all of the HTTP transactions required to perform operations. It also manages the services
 30:  * for your application through convenient factory methods.
 31:  */
 32: class OpenStack extends Client
 33: {
 34:     /**
 35:      * @var array Credentials passed in by the user
 36:      */
 37:     private $secret = array();
 38: 
 39:     /**
 40:      * @var string The token produced by the API
 41:      */
 42:     private $token;
 43: 
 44:     /**
 45:      * @var int The expiration date (in Unix time) for the current token
 46:      */
 47:     private $expiration;
 48: 
 49:     /**
 50:      * @var string The unique identifier for who's accessing the API
 51:      */
 52:     private $tenant;
 53: 
 54:     /**
 55:      * @var \OpenCloud\Common\Service\Catalog The catalog of services which are provided by the API
 56:      */
 57:     private $catalog;
 58: 
 59:     /**
 60:      * @var \OpenCloud\Common\Log\LoggerInterface The object responsible for logging output
 61:      */
 62:     private $logger;
 63: 
 64:     /**
 65:      * @var string The endpoint URL used for authentication
 66:      */
 67:     private $authUrl;
 68: 
 69:     public function __construct($url, array $secret, array $options = array())
 70:     {
 71:         $this->getLogger()->info(Lang::translate('Initializing OpenStack client'));
 72: 
 73:         $this->setSecret($secret);
 74:         $this->setAuthUrl($url);
 75: 
 76:         parent::__construct($url, $options);
 77:         
 78:         $this->addSubscriber(RequestSubscriber::getInstance());
 79:         $this->setDefaultOption('headers/Accept', 'application/json');
 80:     }
 81:         
 82:     /**
 83:      * Set the credentials for the client
 84:      *
 85:      * @param array $secret
 86:      * @return $this
 87:      */
 88:     public function setSecret(array $secret = array())
 89:     {
 90:         $this->secret = $secret;
 91:         
 92:         return $this;
 93:     }
 94:     
 95:     /**
 96:      * Get the secret.
 97:      * 
 98:      * @return array
 99:      */
100:     public function getSecret()
101:     {
102:         return $this->secret;
103:     }
104:     
105:     /**
106:      * Set the token for this client.
107:      * 
108:      * @param  string $token
109:      * @return $this
110:      */
111:     public function setToken($token)
112:     {
113:         $this->token = $token;
114:         
115:         return $this;
116:     }
117:     
118:     /**
119:      * Get the token for this client.
120:      * 
121:      * @return string
122:      */
123:     public function getToken()
124:     {
125:         return $this->token;
126:     }
127:     
128:     /**
129:      * Set the expiration for this token.
130:      * 
131:      * @param  int $expiration
132:      * @return $this
133:      */
134:     public function setExpiration($expiration)
135:     {
136:         $this->expiration = $expiration;
137:         
138:         return $this;
139:     }
140:     
141:     /**
142:      * Get the expiration time.
143:      * 
144:      * @return int
145:      */
146:     public function getExpiration()
147:     {
148:         return $this->expiration;
149:     }
150:     
151:     /**
152:      * Set the tenant for this client.
153:      * 
154:      * @param  string $tenant
155:      * @return $this
156:      */
157:     public function setTenant($tenant)
158:     {
159:         $this->tenant = $tenant;
160:        
161:         return $this;
162:     }
163:     
164:     /**
165:      * Get the tenant for this client.
166:      * 
167:      * @return string
168:      */
169:     public function getTenant()
170:     {
171:         return $this->tenant;
172:     }
173:     
174:     /**
175:      * Set the service catalog.
176:      * 
177:      * @param  mixed $catalog
178:      * @return $this
179:      */
180:     public function setCatalog($catalog)
181:     {
182:         $this->catalog = Catalog::factory($catalog);
183: 
184:         return $this;
185:     }
186:     
187:     /**
188:      * Get the service catalog.
189:      * 
190:      * @return array
191:      */
192:     public function getCatalog()
193:     {
194:         return $this->catalog;
195:     }
196: 
197:     /**
198:      * @param Common\Log\LoggerInterface $logger
199:      * @return $this
200:      */
201:     public function setLogger(Common\Log\LoggerInterface $logger)
202:     {
203:         $this->logger = $logger;
204:         return $this;
205:     }
206: 
207:     /**
208:      * @return Common\Log\LoggerInterface
209:      */
210:     public function getLogger()
211:     {
212:         if (null === $this->logger) {
213:             $this->setLogger(new Common\Log\Logger);
214:         }
215:         return $this->logger;
216:     }
217:     
218:     /**
219:      * Checks whether token has expired
220:      * 
221:      * @return bool
222:      */
223:     public function hasExpired()
224:     {
225:         return !$this->expiration || (time() > $this->expiration);
226:     }
227: 
228:     /**
229:      * Formats the credentials array (as a string) for authentication
230:      *
231:      * @return string
232:      * @throws Common\Exceptions\CredentialError
233:      */
234:     public function getCredentials()
235:     {
236:         if (!empty($this->secret['username']) && !empty($this->secret['password'])) {
237: 
238:             $credentials = array('auth' => array(
239:                 'passwordCredentials' => array(
240:                     'username' => $this->secret['username'],
241:                     'password' => $this->secret['password']
242:                 )
243:             ));
244: 
245:             if (!empty($this->secret['tenantName'])) {
246:                 $credentials['auth']['tenantName'] = $this->secret['tenantName'];
247:             } elseif (!empty($this->secret['tenantId'])) {
248:                 $credentials['auth']['tenantId'] = $this->secret['tenantId'];
249:             }
250: 
251:             return json_encode($credentials);
252: 
253:         } else {
254:             throw new Exceptions\CredentialError(
255:                Lang::translate('Unrecognized credential secret')
256:             );
257:         }
258:     }
259: 
260:     /**
261:      * @param $url
262:      * @return $this
263:      */
264:     public function setAuthUrl($url)
265:     {
266:         $this->authUrl = $url;
267:         return $this;
268:     }
269: 
270:     /**
271:      * @return Url
272:      */
273:     public function getAuthUrl()
274:     {
275:         return Url::factory($this->authUrl)->addPath('tokens');
276:     }
277: 
278:     /**
279:      * Authenticate the tenant using the supplied credentials
280:      *
281:      * @return void
282:      * @throws AuthenticationError
283:      */
284:     public function authenticate()
285:     {
286:         $headers = array(Header::CONTENT_TYPE => Mime::JSON);
287:         $response = $this->post($this->getAuthUrl('tokens'), $headers, $this->getCredentials())->send();
288:         $body = Formatter::decode($response);
289: 
290:         // Save the token information as well as the ServiceCatalog
291:         $this->setToken($body->access->token->id);
292:         $this->setExpiration(strtotime($body->access->token->expires));
293:         $this->setCatalog($body->access->serviceCatalog);
294:         
295:         // Add to default headers for future reference
296:         $this->setDefaultOption('headers/X-Auth-Token', (string) $this->getToken());
297: 
298:         /**
299:          * In some cases, the tenant name/id is not returned
300:          * as part of the auth token, so we check for it before
301:          * we set it. This occurs with pure Keystone, but not
302:          * with the Rackspace auth.
303:          */
304:         if (isset($body->access->token->tenant)) {
305:             $this->setTenant($body->access->token->tenant->id);
306:         }
307:     }
308: 
309:     /**
310:      * @deprecated
311:      */
312:     public function getUrl()
313:     {
314:         return $this->getBaseUrl();
315:     }
316: 
317:     /**
318:      * Convenience method for exporting current credentials. Useful for local caching.
319:      * @return array
320:      */
321:     public function exportCredentials()
322:     {
323:         if ($this->hasExpired()) {
324:             $this->authenticate();
325:         }
326:         return array(
327:             'token'      => $this->getToken(),
328:             'expiration' => $this->getExpiration(),
329:             'tenant'     => $this->getTenant(),
330:             'catalog'    => $this->getCatalog()
331:         );
332:     }
333: 
334:     /**
335:      * Convenience method for importing credentials. Useful for local caching because it reduces HTTP traffic.
336:      *
337:      * @param array $values
338:      */
339:     public function importCredentials(array $values)
340:     {
341:         if (!empty($values['token'])) {
342:             $this->setToken($values['token']);
343:         }
344:         if (!empty($values['expiration'])) {
345:             $this->setExpiration($values['expiration']);
346:         }
347:         if (!empty($values['tenant'])) {
348:             $this->setTenant($values['tenant']);
349:         }
350:         if (!empty($values['catalog'])) {
351:             $this->setCatalog($values['catalog']);
352:         }
353:     }
354: 
355:     /**
356:      * Creates a new ObjectStore object (Swift/Cloud Files)
357:      *
358:      * @param string $name    The name of the service as it appears in the Catalog
359:      * @param string $region  The region (DFW, IAD, ORD, LON, SYD)
360:      * @param string $urltype The URL type ("publicURL" or "internalURL")
361:      * @return \OpenCloud\ObjectStore\Service
362:      */
363:     public function objectStoreService($name = null, $region = null, $urltype = null)
364:     {
365:         return ServiceBuilder::factory($this, 'OpenCloud\ObjectStore\Service', array(
366:             'name'    => $name, 
367:             'region'  => $region, 
368:             'urlType' => $urltype
369:         ));
370:     }
371: 
372:     /**
373:      * Creates a new Compute object (Nova/Cloud Servers)
374:      *
375:      * @param string $name    The name of the service as it appears in the Catalog
376:      * @param string $region  The region (DFW, IAD, ORD, LON, SYD)
377:      * @param string $urltype The URL type ("publicURL" or "internalURL")
378:      * @return \OpenCloud\Compute\Service
379:      */
380:     public function computeService($name = null, $region = null, $urltype = null)
381:     {
382:         return ServiceBuilder::factory($this, 'OpenCloud\Compute\Service', array(
383:             'name'    => $name, 
384:             'region'  => $region, 
385:             'urlType' => $urltype
386:         ));
387:     }
388: 
389:     /**
390:      * Creates a new Orchestration (Heat) service object
391:      *
392:      * @param string $name    The name of the service as it appears in the Catalog
393:      * @param string $region  The region (DFW, IAD, ORD, LON, SYD)
394:      * @param string $urltype The URL type ("publicURL" or "internalURL")
395:      * @return \OpenCloud\Orchestration\Service
396:      * @codeCoverageIgnore
397:      */
398:     public function orchestrationService($name = null, $region = null, $urltype = null)
399:     {
400:         return ServiceBuilder::factory($this, 'OpenCloud\Orchestration\Service', array(
401:             'name'    => $name, 
402:             'region'  => $region, 
403:             'urlType' => $urltype
404:         ));
405:     }
406: 
407:     /**
408:      * Creates a new Volume (Cinder) service object
409:      *
410:      * @param string $name    The name of the service as it appears in the Catalog
411:      * @param string $region  The region (DFW, IAD, ORD, LON, SYD)
412:      * @param string $urltype The URL type ("publicURL" or "internalURL")
413:      * @return \OpenCloud\Volume\Service
414:      */
415:     public function volumeService($name = null, $region = null, $urltype = null)
416:     {
417:         return ServiceBuilder::factory($this, 'OpenCloud\Volume\Service', array(
418:             'name'    => $name, 
419:             'region'  => $region, 
420:             'urlType' => $urltype
421:         ));
422:     }
423: 
424: }
425: 
PHP OpenCloud API API documentation generated by ApiGen 2.8.0