Got the new Openstack SDK working with Rackspace, and added my own support for the Rackspace-specific extensions for API key and CDN. #144
This commit is contained in:
parent
61c51fcd37
commit
7b2ea74a19
@ -132,21 +132,23 @@ class OpenStackSource extends AlbumSourceBase implements IAlbumSource
|
||||
|
||||
protected function getClient()
|
||||
{
|
||||
$openstackOptions = [
|
||||
'authUrl' => $this->configuration->auth_url,
|
||||
$authURL = $this->configuration->auth_url;
|
||||
|
||||
$options = [
|
||||
'authUrl' => $authURL,
|
||||
'username' => $this->configuration->username,
|
||||
'password' => decrypt($this->configuration->password),
|
||||
'tenantName' => $this->configuration->tenant_name,
|
||||
'region' => $this->configuration->service_region,
|
||||
'identityService' => IdentityV2Service::factory(
|
||||
new Client([
|
||||
'base_uri' => TransportUtils::normalizeUrl( $this->configuration->auth_url),
|
||||
'base_uri' => TransportUtils::normalizeUrl($authURL),
|
||||
'handler' => HandlerStack::create(),
|
||||
])
|
||||
)
|
||||
];
|
||||
|
||||
return new OpenStack($openstackOptions);
|
||||
return new OpenStack($options);
|
||||
}
|
||||
|
||||
protected function getContainer()
|
||||
@ -157,10 +159,15 @@ class OpenStackSource extends AlbumSourceBase implements IAlbumSource
|
||||
protected function getStorageService()
|
||||
{
|
||||
return $this->getClient()->objectStoreV1([
|
||||
'catalogName' => $this->configuration->service_name
|
||||
'catalogName' => $this->getStorageServiceCatalogName()
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getStorageServiceCatalogName()
|
||||
{
|
||||
return $this->configuration->service_name;
|
||||
}
|
||||
|
||||
protected function getOriginalsFolder()
|
||||
{
|
||||
return '_originals';
|
||||
|
@ -3,24 +3,15 @@
|
||||
namespace App\AlbumSources;
|
||||
|
||||
use App\Photo;
|
||||
use App\Services\Rackspace\Identity\v2\Service as RackspaceIdentityV2Service;
|
||||
use App\Services\Rackspace\ObjectStoreCdn\v1\Models\Container;
|
||||
use App\Services\Rackspace\Rackspace;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use OpenStack\Common\Transport\Utils as TransportUtils;
|
||||
|
||||
class RackspaceSource extends OpenStackSource
|
||||
{
|
||||
protected function getClient()
|
||||
{
|
||||
$endpoint = Rackspace::US_IDENTITY_ENDPOINT;
|
||||
|
||||
if ($this->configuration->service_region == 'LON')
|
||||
{
|
||||
$endpoint = Rackspace::UK_IDENTITY_ENDPOINT;
|
||||
}
|
||||
|
||||
return new Rackspace($endpoint, [
|
||||
'username' => $this->configuration->username,
|
||||
'apiKey' => decrypt($this->configuration->password)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this album source.
|
||||
* @return string
|
||||
@ -39,12 +30,14 @@ class RackspaceSource extends OpenStackSource
|
||||
public function getUrlToPhoto(Photo $photo, $thumbnail = null)
|
||||
{
|
||||
$isCdnEnabled = false;
|
||||
$cdnService = $this->getStorageService()->getCdnService();
|
||||
$cdnService = $this->getCdnService();
|
||||
|
||||
$thisCdnContainer = null;
|
||||
|
||||
/** @var Container $cdnContainer */
|
||||
foreach ($cdnService->listContainers() as $cdnContainer)
|
||||
{
|
||||
if ($cdnContainer->name == $this->configuration->container_name)
|
||||
if ($cdnContainer->cdn_enabled && strtolower($cdnContainer->name) == strtolower($this->configuration->container_name))
|
||||
{
|
||||
$isCdnEnabled = true;
|
||||
$thisCdnContainer = $cdnContainer;
|
||||
@ -53,9 +46,47 @@ class RackspaceSource extends OpenStackSource
|
||||
|
||||
if ($isCdnEnabled)
|
||||
{
|
||||
return sprintf('%s/%s', $thisCdnContainer->getCdnSslUri(), $this->getPathToPhoto($photo, $thumbnail));
|
||||
return sprintf('%s/%s', $thisCdnContainer->cdn_ssl_uri, $this->getPathToPhoto($photo, $thumbnail));
|
||||
}
|
||||
|
||||
return parent::getPathToPhoto($photo, $thumbnail);
|
||||
}
|
||||
|
||||
protected function getCdnService()
|
||||
{
|
||||
return $this->getClient()->objectStoreCdnV1();
|
||||
}
|
||||
|
||||
protected function getClient()
|
||||
{
|
||||
$authURL = config('services.rackspace.authentication_url');
|
||||
|
||||
// Uncomment the commented out lines below and in the $options array to get a 'storage/logs/openstack.log' file
|
||||
// with passed HTTP traffic
|
||||
//$logger = new Logger('MyLog');
|
||||
//$logger->pushHandler(new StreamHandler(__DIR__ . '/../../storage/logs/openstack.log'), Logger::DEBUG);
|
||||
|
||||
$options = [
|
||||
'authUrl' => $authURL,
|
||||
'username' => $this->configuration->username,
|
||||
'apiKey' => decrypt($this->configuration->password),
|
||||
'region' => $this->configuration->service_region,
|
||||
'identityService' => RackspaceIdentityV2Service::factory(
|
||||
new Client([
|
||||
'base_uri' => TransportUtils::normalizeUrl($authURL),
|
||||
'handler' => HandlerStack::create(),
|
||||
])
|
||||
),
|
||||
//'debugLog' => true,
|
||||
//'logger' => $logger,
|
||||
//'messageFormatter' => new MessageFormatter('{req_body} - {res_body}')
|
||||
];
|
||||
|
||||
return new Rackspace($options);
|
||||
}
|
||||
|
||||
protected function getStorageServiceCatalogName()
|
||||
{
|
||||
return 'cloudFiles';
|
||||
}
|
||||
}
|
36
app/Services/Rackspace/Identity/v2/Api.php
Normal file
36
app/Services/Rackspace/Identity/v2/Api.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Rackspace\Identity\v2;
|
||||
|
||||
use OpenStack\Common\Api\ApiInterface;
|
||||
|
||||
class Api implements ApiInterface
|
||||
{
|
||||
public function postTokenWithApiKey(): array
|
||||
{
|
||||
return [
|
||||
'method' => 'POST',
|
||||
'path' => 'tokens',
|
||||
'params' => [
|
||||
'username' => [
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
'path' => 'auth.RAX-KSKEY:apiKeyCredentials',
|
||||
],
|
||||
'apiKey' => [
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
'path' => 'auth.RAX-KSKEY:apiKeyCredentials',
|
||||
],
|
||||
'tenantId' => [
|
||||
'type' => 'string',
|
||||
'path' => 'auth',
|
||||
],
|
||||
'tenantName' => [
|
||||
'type' => 'string',
|
||||
'path' => 'auth',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
54
app/Services/Rackspace/Identity/v2/Service.php
Normal file
54
app/Services/Rackspace/Identity/v2/Service.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Rackspace\Identity\v2;
|
||||
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use OpenStack\Common\Auth\IdentityService;
|
||||
use OpenStack\Common\Service\AbstractService;
|
||||
use OpenStack\Identity\v2\Models\Catalog;
|
||||
use OpenStack\Identity\v2\Models\Token;
|
||||
|
||||
/**
|
||||
* Represents the Rackspace Identity v2 service.
|
||||
*
|
||||
* @property Api $api
|
||||
*/
|
||||
class Service extends AbstractService implements IdentityService
|
||||
{
|
||||
public static function factory(ClientInterface $client): self
|
||||
{
|
||||
return new static($client, new Api());
|
||||
}
|
||||
|
||||
public function authenticate(array $options = []): array
|
||||
{
|
||||
$definition = $this->api->postTokenWithApiKey();
|
||||
|
||||
$response = $this->execute($definition, array_intersect_key($options, $definition['params']));
|
||||
|
||||
$token = $this->model(Token::class, $response);
|
||||
|
||||
$serviceUrl = $this->model(Catalog::class, $response)->getServiceUrl(
|
||||
$options['catalogName'],
|
||||
$options['catalogType'],
|
||||
$options['region'],
|
||||
$options['urlType']
|
||||
);
|
||||
|
||||
return [$token, $serviceUrl];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new authentication token.
|
||||
*
|
||||
* @param array $options {@see \OpenStack\Identity\v2\Api::postToken}
|
||||
*
|
||||
* @return Token
|
||||
*/
|
||||
public function generateToken(array $options = []): Token
|
||||
{
|
||||
$response = $this->execute($this->api->postTokenWithApiKey(), $options);
|
||||
|
||||
return $this->model(Token::class, $response);
|
||||
}
|
||||
}
|
24
app/Services/Rackspace/ObjectStoreCdn/v1/Api.php
Normal file
24
app/Services/Rackspace/ObjectStoreCdn/v1/Api.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Rackspace\ObjectStoreCdn\v1;
|
||||
|
||||
use OpenStack\Common\Api\AbstractApi;
|
||||
|
||||
class Api extends AbstractApi
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->params = new Params();
|
||||
}
|
||||
|
||||
public function getAccount(): array
|
||||
{
|
||||
return [
|
||||
'method' => 'GET',
|
||||
'path' => '',
|
||||
'params' => [
|
||||
'format' => $this->params->format()
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Rackspace\ObjectStoreCdn\v1\Models;
|
||||
|
||||
use OpenStack\Common\Resource\OperatorResource;
|
||||
|
||||
class Container extends OperatorResource
|
||||
{
|
||||
/** @var bool */
|
||||
public $cdn_enabled;
|
||||
|
||||
/** @var string */
|
||||
public $cdn_ssl_uri;
|
||||
|
||||
/** @var string */
|
||||
public $name;
|
||||
}
|
17
app/Services/Rackspace/ObjectStoreCdn/v1/Params.php
Normal file
17
app/Services/Rackspace/ObjectStoreCdn/v1/Params.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Rackspace\ObjectStoreCdn\v1;
|
||||
|
||||
use OpenStack\Common\Api\AbstractParams;
|
||||
|
||||
class Params extends AbstractParams
|
||||
{
|
||||
public function format(): array
|
||||
{
|
||||
return [
|
||||
'location' => self::QUERY,
|
||||
'type' => self::STRING_TYPE,
|
||||
'description' => 'Defines the format of the collection. Will always default to `json`.',
|
||||
];
|
||||
}
|
||||
}
|
27
app/Services/Rackspace/ObjectStoreCdn/v1/Service.php
Normal file
27
app/Services/Rackspace/ObjectStoreCdn/v1/Service.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Rackspace\ObjectStoreCdn\v1;
|
||||
|
||||
use App\Services\Rackspace\ObjectStoreCdn\v1\Models\Container;
|
||||
use OpenStack\Common\Service\AbstractService;
|
||||
|
||||
/**
|
||||
* Represents the Rackspace Cloud Files CDN v1 service.
|
||||
*
|
||||
* @property Api $api
|
||||
*/
|
||||
class Service extends AbstractService
|
||||
{
|
||||
/**
|
||||
* Retrieves a collection of CDN-enabled container resources in a generator format.
|
||||
*
|
||||
* @param array $options {@see Api::getAccount()}
|
||||
* @param callable|null $mapFn allows a function to be mapped over each element in the collection
|
||||
*/
|
||||
public function listContainers(array $options = [], callable $mapFn = null): \Generator
|
||||
{
|
||||
$options = array_merge($options, ['format' => 'json']);
|
||||
|
||||
return $this->model(Container::class)->enumerate($this->api->getAccount(), $options, $mapFn);
|
||||
}
|
||||
}
|
32
app/Services/Rackspace/Rackspace.php
Normal file
32
app/Services/Rackspace/Rackspace.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Rackspace;
|
||||
|
||||
use App\Services\Rackspace\ObjectStoreCdn\v1\Service as ObjectStoreCdnService;
|
||||
use OpenStack\Common\Service\Builder;
|
||||
use OpenStack\OpenStack;
|
||||
|
||||
class Rackspace extends OpenStack
|
||||
{
|
||||
/** @var Builder */
|
||||
private $rsBuilder;
|
||||
|
||||
public function __construct(array $options = [], Builder $builder = null)
|
||||
{
|
||||
parent::__construct($options, $builder);
|
||||
|
||||
$this->rsBuilder = $builder ?: new Builder($options, 'App\Services\Rackspace');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Object Store (Rackspace CDN) v1 service.
|
||||
*
|
||||
* @param array $options options that will be used in configuring the service
|
||||
*/
|
||||
public function objectStoreCdnV1(array $options = []): ObjectStoreCdnService
|
||||
{
|
||||
$defaults = ['catalogName' => 'cloudFilesCDN', 'catalogType' => 'rax:object-cdn'];
|
||||
|
||||
return $this->rsBuilder->createService('ObjectStoreCdn\\v1', array_merge($defaults, $options));
|
||||
}
|
||||
}
|
@ -35,6 +35,10 @@ return [
|
||||
'repo_owner' => 'aheathershaw'
|
||||
],
|
||||
|
||||
'rackspace' => [
|
||||
'authentication_url' => 'https://identity.api.rackspacecloud.com/v2.0'
|
||||
],
|
||||
|
||||
'recaptcha' => [
|
||||
'verify_url' => 'https://www.google.com/recaptcha/api/siteverify'
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user