1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
17:
18: namespace OpenCloud;
19:
20: use Guzzle\Http\Url;
21: use OpenCloud\Common\Exceptions;
22: use OpenCloud\Common\Http\Client;
23: use OpenCloud\Common\Http\Message\Formatter;
24: use OpenCloud\Common\Http\Message\RequestSubscriber;
25: use OpenCloud\Common\Lang;
26: use OpenCloud\Common\Log\Logger;
27: use OpenCloud\Common\Service\Catalog;
28: use OpenCloud\Common\Service\ServiceBuilder;
29: use OpenCloud\Identity\Resource\Tenant;
30: use OpenCloud\Identity\Resource\Token;
31: use OpenCloud\Identity\Resource\User;
32: use OpenCloud\Identity\Service as IdentityService;
33: use Psr\Log\LoggerInterface;
34:
35: define('RACKSPACE_US', 'https://identity.api.rackspacecloud.com/v2.0/');
36: define('RACKSPACE_UK', 'https://lon.identity.api.rackspacecloud.com/v2.0/');
37:
38: 39: 40: 41: 42:
43: class OpenStack extends Client
44: {
45: 46: 47:
48: private $secret = array();
49:
50: 51: 52:
53: private $token;
54:
55: 56: 57:
58: private $tenant;
59:
60: 61: 62:
63: private $catalog;
64:
65: 66: 67:
68: private $logger;
69:
70: 71: 72:
73: private $authUrl;
74:
75: 76: 77:
78: private $user;
79:
80: public function __construct($url, array $secret, array $options = array())
81: {
82: if (isset($options['logger']) && $options['logger'] instanceof LoggerInterface) {
83: $this->setLogger($options['logger']);
84: }
85:
86: $this->setSecret($secret);
87: $this->setAuthUrl($url);
88:
89: parent::__construct($url, $options);
90:
91: $this->addSubscriber(RequestSubscriber::getInstance());
92: $this->setDefaultOption('headers/Accept', 'application/json');
93: }
94:
95: 96: 97: 98: 99: 100:
101: public function setSecret(array $secret = array())
102: {
103: $this->secret = $secret;
104:
105: return $this;
106: }
107:
108: 109: 110: 111: 112:
113: public function getSecret()
114: {
115: return $this->secret;
116: }
117:
118: 119: 120: 121: 122: 123: 124: 125:
126: public function setToken($token)
127: {
128: $identity = IdentityService::factory($this);
129:
130: if (is_string($token)) {
131: if (!$this->token) {
132: $this->setTokenObject($identity->resource('Token'));
133: }
134: $this->token->setId($token);
135: } else {
136: $this->setTokenObject($identity->resource('Token', $token));
137: }
138:
139: return $this;
140: }
141:
142: 143: 144: 145: 146:
147: public function getToken()
148: {
149: return ($this->getTokenObject()) ? $this->getTokenObject()->getId() : null;
150: }
151:
152: 153: 154:
155: public function setTokenObject(Token $token)
156: {
157: $this->token = $token;
158: }
159:
160: 161: 162:
163: public function getTokenObject()
164: {
165: return $this->token;
166: }
167:
168: 169: 170:
171: public function setExpiration($expiration)
172: {
173: $this->getLogger()->warning(Logger::deprecated(__METHOD__, '::getTokenObject()->setExpires()'));
174: if ($this->getTokenObject()) {
175: $this->getTokenObject()->setExpires($expiration);
176: }
177:
178: return $this;
179: }
180:
181: 182: 183:
184: public function getExpiration()
185: {
186: $this->getLogger()->warning(Logger::deprecated(__METHOD__, '::getTokenObject()->getExpires()'));
187: if ($this->getTokenObject()) {
188: return $this->getTokenObject()->getExpires();
189: }
190: }
191:
192: 193: 194: 195: 196: 197: 198: 199:
200: public function setTenant($tenant)
201: {
202: $identity = IdentityService::factory($this);
203:
204: if (is_numeric($tenant) || is_string($tenant)) {
205: if (!$this->tenant) {
206: $this->setTenantObject($identity->resource('Tenant'));
207: }
208: $this->tenant->setId($tenant);
209: } else {
210: $this->setTenantObject($identity->resource('Tenant', $tenant));
211: }
212:
213: return $this;
214: }
215:
216: 217: 218: 219: 220:
221: public function getTenant()
222: {
223: return ($this->getTenantObject()) ? $this->getTenantObject()->getId() : null;
224: }
225:
226: 227: 228: 229: 230:
231: public function setTenantObject(Tenant $tenant)
232: {
233: $this->tenant = $tenant;
234: }
235:
236: 237: 238: 239: 240:
241: public function getTenantObject()
242: {
243: return $this->tenant;
244: }
245:
246: 247: 248: 249: 250: 251:
252: public function setCatalog($catalog)
253: {
254: $this->catalog = Catalog::factory($catalog);
255:
256: return $this;
257: }
258:
259: 260: 261: 262: 263:
264: public function getCatalog()
265: {
266: return $this->catalog;
267: }
268:
269: 270: 271: 272: 273:
274: public function setLogger(LoggerInterface $logger)
275: {
276: $this->logger = $logger;
277:
278: return $this;
279: }
280:
281: 282: 283:
284: public function getLogger()
285: {
286: if (null === $this->logger) {
287: $this->setLogger(new Common\Log\Logger);
288: }
289:
290: return $this->logger;
291: }
292:
293: 294: 295:
296: public function hasLogger()
297: {
298: return (null !== $this->logger);
299: }
300:
301: 302: 303:
304: public function hasExpired()
305: {
306: $this->getLogger()->warning(Logger::deprecated(__METHOD__, 'getTokenObject()->hasExpired()'));
307:
308: return $this->getTokenObject() && $this->getTokenObject()->hasExpired();
309: }
310:
311: 312: 313: 314: 315: 316:
317: public function getCredentials()
318: {
319: if (!empty($this->secret['username']) && !empty($this->secret['password'])) {
320: $credentials = array('auth' => array(
321: 'passwordCredentials' => array(
322: 'username' => $this->secret['username'],
323: 'password' => $this->secret['password']
324: )
325: ));
326:
327: if (!empty($this->secret['tenantName'])) {
328: $credentials['auth']['tenantName'] = $this->secret['tenantName'];
329: } elseif (!empty($this->secret['tenantId'])) {
330: $credentials['auth']['tenantId'] = $this->secret['tenantId'];
331: }
332:
333: return json_encode($credentials);
334: } else {
335: throw new Exceptions\CredentialError(
336: Lang::translate('Unrecognized credential secret')
337: );
338: }
339: }
340:
341: 342: 343: 344:
345: public function setAuthUrl($url)
346: {
347: $this->authUrl = Url::factory($url);
348:
349: return $this;
350: }
351:
352: 353: 354:
355: public function getAuthUrl()
356: {
357: return $this->authUrl;
358: }
359:
360: 361: 362: 363: 364:
365: public function setUser(User $user)
366: {
367: $this->user = $user;
368: }
369:
370: 371: 372:
373: public function getUser()
374: {
375: return $this->user;
376: }
377:
378: 379: 380: 381: 382: 383:
384: public function authenticate()
385: {
386:
387:
388: $this->updateTokenHeader('');
389:
390: $identity = IdentityService::factory($this);
391: $response = $identity->generateToken($this->getCredentials());
392:
393: $body = Formatter::decode($response);
394:
395: $this->setCatalog($body->access->serviceCatalog);
396: $this->setTokenObject($identity->resource('Token', $body->access->token));
397: $this->setUser($identity->resource('User', $body->access->user));
398:
399: if (isset($body->access->token->tenant)) {
400: $this->setTenantObject($identity->resource('Tenant', $body->access->token->tenant));
401: }
402:
403:
404: $this->updateTokenHeader($this->getToken());
405: }
406:
407: 408: 409:
410: public function getUrl()
411: {
412: return $this->getBaseUrl();
413: }
414:
415: 416: 417: 418:
419: public function exportCredentials()
420: {
421: if ($this->hasExpired()) {
422: $this->authenticate();
423: }
424:
425: return array(
426: 'token' => $this->getToken(),
427: 'expiration' => $this->getExpiration(),
428: 'tenant' => $this->getTenant(),
429: 'catalog' => $this->getCatalog()
430: );
431: }
432:
433: 434: 435: 436: 437:
438: public function importCredentials(array $values)
439: {
440: if (!empty($values['token'])) {
441: $this->setToken($values['token']);
442: $this->updateTokenHeader($this->getToken());
443: }
444: if (!empty($values['expiration'])) {
445: $this->setExpiration($values['expiration']);
446: }
447: if (!empty($values['tenant'])) {
448: $this->setTenant($values['tenant']);
449: }
450: if (!empty($values['catalog'])) {
451: $this->setCatalog($values['catalog']);
452: }
453: }
454:
455: 456: 457: 458: 459: 460:
461: private function ($token)
462: {
463: $this->setDefaultOption('headers/X-Auth-Token', (string) $token);
464: }
465:
466: 467: 468: 469: 470: 471: 472: 473:
474: public function objectStoreService($name = null, $region = null, $urltype = null)
475: {
476: return ServiceBuilder::factory($this, 'OpenCloud\ObjectStore\Service', array(
477: 'name' => $name,
478: 'region' => $region,
479: 'urlType' => $urltype
480: ));
481: }
482:
483: 484: 485: 486: 487: 488: 489: 490:
491: public function computeService($name = null, $region = null, $urltype = null)
492: {
493: return ServiceBuilder::factory($this, 'OpenCloud\Compute\Service', array(
494: 'name' => $name,
495: 'region' => $region,
496: 'urlType' => $urltype
497: ));
498: }
499:
500: 501: 502: 503: 504: 505: 506: 507: 508:
509: public function orchestrationService($name = null, $region = null, $urltype = null)
510: {
511: return ServiceBuilder::factory($this, 'OpenCloud\Orchestration\Service', array(
512: 'name' => $name,
513: 'region' => $region,
514: 'urlType' => $urltype
515: ));
516: }
517:
518: 519: 520: 521: 522: 523: 524: 525:
526: public function volumeService($name = null, $region = null, $urltype = null)
527: {
528: return ServiceBuilder::factory($this, 'OpenCloud\Volume\Service', array(
529: 'name' => $name,
530: 'region' => $region,
531: 'urlType' => $urltype
532: ));
533: }
534:
535: 536: 537: 538: 539:
540: public function identityService()
541: {
542: $service = IdentityService::factory($this);
543: $this->authenticate();
544:
545: return $service;
546: }
547:
548: 549: 550: 551: 552: 553: 554: 555:
556: public function imageService($name = null, $region = null, $urltype = null)
557: {
558: return ServiceBuilder::factory($this, 'OpenCloud\Image\Service', array(
559: 'name' => $name,
560: 'region' => $region,
561: 'urlType' => $urltype
562: ));
563: }
564:
565: 566: 567: 568: 569: 570: 571: 572: 573:
574: public function networkingService($name = null, $region = null, $urltype = null)
575: {
576: return ServiceBuilder::factory($this, 'OpenCloud\Networking\Service', array(
577: 'name' => $name,
578: 'region' => $region,
579: 'urlType' => $urltype
580: ));
581: }
582:
583: 584: 585: 586: 587: 588: 589: 590: 591:
592: public function cdnService($name = null, $region = null, $urltype = null)
593: {
594: return ServiceBuilder::factory($this, 'OpenCloud\CDN\Service', array(
595: 'name' => $name,
596: 'region' => $region,
597: 'urlType' => $urltype
598: ));
599: }
600: }
601: