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()
|
protected function getClient()
|
||||||
{
|
{
|
||||||
$openstackOptions = [
|
$authURL = $this->configuration->auth_url;
|
||||||
'authUrl' => $this->configuration->auth_url,
|
|
||||||
|
$options = [
|
||||||
|
'authUrl' => $authURL,
|
||||||
'username' => $this->configuration->username,
|
'username' => $this->configuration->username,
|
||||||
'password' => decrypt($this->configuration->password),
|
'password' => decrypt($this->configuration->password),
|
||||||
'tenantName' => $this->configuration->tenant_name,
|
'tenantName' => $this->configuration->tenant_name,
|
||||||
'region' => $this->configuration->service_region,
|
'region' => $this->configuration->service_region,
|
||||||
'identityService' => IdentityV2Service::factory(
|
'identityService' => IdentityV2Service::factory(
|
||||||
new Client([
|
new Client([
|
||||||
'base_uri' => TransportUtils::normalizeUrl( $this->configuration->auth_url),
|
'base_uri' => TransportUtils::normalizeUrl($authURL),
|
||||||
'handler' => HandlerStack::create(),
|
'handler' => HandlerStack::create(),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
return new OpenStack($openstackOptions);
|
return new OpenStack($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getContainer()
|
protected function getContainer()
|
||||||
@ -157,10 +159,15 @@ class OpenStackSource extends AlbumSourceBase implements IAlbumSource
|
|||||||
protected function getStorageService()
|
protected function getStorageService()
|
||||||
{
|
{
|
||||||
return $this->getClient()->objectStoreV1([
|
return $this->getClient()->objectStoreV1([
|
||||||
'catalogName' => $this->configuration->service_name
|
'catalogName' => $this->getStorageServiceCatalogName()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getStorageServiceCatalogName()
|
||||||
|
{
|
||||||
|
return $this->configuration->service_name;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getOriginalsFolder()
|
protected function getOriginalsFolder()
|
||||||
{
|
{
|
||||||
return '_originals';
|
return '_originals';
|
||||||
|
@ -3,24 +3,15 @@
|
|||||||
namespace App\AlbumSources;
|
namespace App\AlbumSources;
|
||||||
|
|
||||||
use App\Photo;
|
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
|
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.
|
* Gets the name of this album source.
|
||||||
* @return string
|
* @return string
|
||||||
@ -39,12 +30,14 @@ class RackspaceSource extends OpenStackSource
|
|||||||
public function getUrlToPhoto(Photo $photo, $thumbnail = null)
|
public function getUrlToPhoto(Photo $photo, $thumbnail = null)
|
||||||
{
|
{
|
||||||
$isCdnEnabled = false;
|
$isCdnEnabled = false;
|
||||||
$cdnService = $this->getStorageService()->getCdnService();
|
$cdnService = $this->getCdnService();
|
||||||
|
|
||||||
$thisCdnContainer = null;
|
$thisCdnContainer = null;
|
||||||
|
|
||||||
|
/** @var Container $cdnContainer */
|
||||||
foreach ($cdnService->listContainers() as $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;
|
$isCdnEnabled = true;
|
||||||
$thisCdnContainer = $cdnContainer;
|
$thisCdnContainer = $cdnContainer;
|
||||||
@ -53,9 +46,47 @@ class RackspaceSource extends OpenStackSource
|
|||||||
|
|
||||||
if ($isCdnEnabled)
|
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);
|
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'
|
'repo_owner' => 'aheathershaw'
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'rackspace' => [
|
||||||
|
'authentication_url' => 'https://identity.api.rackspacecloud.com/v2.0'
|
||||||
|
],
|
||||||
|
|
||||||
'recaptcha' => [
|
'recaptcha' => [
|
||||||
'verify_url' => 'https://www.google.com/recaptcha/api/siteverify'
|
'verify_url' => 'https://www.google.com/recaptcha/api/siteverify'
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user