Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RackSpace OpenStack #316

Open
ap-coder opened this issue Oct 27, 2020 · 11 comments
Open

RackSpace OpenStack #316

ap-coder opened this issue Oct 27, 2020 · 11 comments

Comments

@ap-coder
Copy link

Any chance someone is working on this?

It would be really helpful in getting it integrated with my app so i was just wondering.

@haphan
Copy link
Collaborator

haphan commented Oct 27, 2020

@ap-coder This SDK should work with RackSpace Openstack for the most part. What is the issue you are having?

@braisdesousa
Copy link

Hi @haphan ! I'm at the same point than @ap-coder . I'm moving my old ObjectStore from https://github.com/rackspace/php-opencloud to this new OpenStack code ( the old rackspace still requiring deprected code)

Trying to follow with https://php-openstack-sdk.readthedocs.io/en/latest/services/object-store/v1/account.html docs, I create a very simple PHP Code as follows

$openstack = new OpenStack([ 'authUrl' => 'https://identity.api.rackspacecloud.com/v2.0/', 'region' => 'LON', 'user' => [ 'id' => 'myUserName', 'password' => 'myApiKey' ], 'scope' => ['project' => ['id' => 'object-store']] ]);
But, the output I got while trying to execute this code is
` HTTP Error

The remote server returned a "404 Not Found" error for the following transaction:                                                                                                                                                                
                                                                                                                                                                                                                                                 
Request                                                                                                                                                                                                                                          
~~~~~~~                                                                                                                                                                                                                                          
POST /v2.0/auth/tokens HTTP/1.1                                                                                                                                                                                                                  
User-Agent: GuzzleHttp/7                                                                                                                                                                                                                         
Content-Type: application/json                                                                                                                                                                                                                   
Host: identity.api.rackspacecloud.com                                                                                                                                                                                                            
                                                                                                                                                                                                                                                 
{"auth":{"identity":{"password":{"user":{"id":"myUser","password":"myApiKey"}},"methods":["password"]},"scope":{"project":{"id":"object-store"}}}}                                                                        
                                                                                                                                                                                                                                                 
Response                                                                                                                                                                                                                                         
~~~~~~~~                                                                                                                                                                                                                                         
HTTP/1.1 404 Not Found                                                                                                                                                                                                                           
Date: Wed, 04 Nov 2020 07:15:53 GMT, Wed, 04 Nov 2020 07:15:53 GMT                                                                                                                                                                               
Content-Type: application/xml                                                                                                                                                                                                                    
Vary: Accept, Accept-Encoding, X-Auth-Token, Accept-Encoding                                                                                                                                                                                     
X-NewRelic-App-Data: PxQCWVFVDwQTVVRTBAQAUlATGhE1AwE2QgNWEVlbQFtcC2VOYgRBFAhTQz1JKV1BQwEYQmRBRQ8KVhZkBwRDI0ASVAtbWUBbXAsbTQFPA05XGAJVVVMAdh1QTU8GHRVRB1JUBwMFU1MDU1oHXgAAEB8DWA1CBG4=                                                            
X-Trans-Id: eyJyZXF1ZXN0SWQiOiJlNzRhMjM0My00NzlhLTQzMzAtODcwZi00Mzk5ODFjYTk3MjgiLCJvcmlnaW4iOm51bGx9                                                                                                                                             
Content-Length: 1139                                                                                                                                                                                                                             
Server: Jetty(9.4.z-SNAPSHOT)                                                                                                                                                                                                                    
Strict-Transport-Security: max-age=15552000; includeSubDomains                                                                                                                                                                                   
X-XSS-Protection: 1; mode=block                                                                                                                                                                                                                  
X-Content-Type-Options: nosniff                                                                                                                                                                                                                  
X-Frame-Options: DENY                                                                                                                                                                                                                            
Content-Security-Policy: default-src 'self'                                                                                                                                                                                                      
                                                                                                                                                                                                                                                 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns17:itemNotFound xmlns:ns2="http://docs.openstack.org/common/api/v1.0" xmlns:ns3="http://docs.openstack.org/compute/api/v1.1" xmlns:ns4="http://www.w3.org/2005/Atom" xmlns:ns5="http://
tity/api/ext/RAX-AUTH/v1.0" xmlns:ns7="http://docs.rackspace.com/identity/api/ext/RAX-KSKEY/v1.0" xmlns:ns8="http://docs.rackspace.com/identity/api/ext/RAX-KSQA/v1.0" xmlns:ns9="http://docs.openstack.org/identity/api/ext/OS-KSEC2/v1.0" xmlns
ttp://docs.openstack.org/identity/api/ext/OS-KSADM/v1.0" xmlns:ns12="http://docs.openstack.org/identity/api/ext/OS-KSCATALOG/v1.0" xmlns:ns13="http://docs.rackspace.com/core/event" xmlns:ns14="http://schemas.dmtf.org/cloud/audit/1.0/event" x
16="http://docs.rackspacecloud.com/auth/api/v1.1" xmlns:ns17="http://fault.common.api.rackspace.com/v1.0"><code>404</code><message>Resource Not Found</message></ns17:itemNotFound>                                                              
                                                                                                                                                                                                                                                 
Further information                                                                                                                                                                                                                              

Please ensure that the resource you're trying to access actually exists. Visit http://docs.php-opencloud.com/en/latest/http-codes for more information about debugging HTTP status codes, or file a support issue on https://github.com/php-openc
`

I have also opened a ticket with Rackspace, but I thing here I could get a better solution.

@haphan
Copy link
Collaborator

haphan commented Nov 4, 2020 via email

@braisdesousa
Copy link

This may be the problem @haphan, there is not identityV3 on rackspace. All documentation is based on https://developer.rackspace.com/docs/cloud-identity/quickstart/

And just refers to https://lon.identity.api.rackspacecloud.com/v2.0/ to identificate. Using CURL I'm able to retrive the catalog list of services, also my TOKEN to use with X-Auth-Token. And the public URL endpoints of this catalog services,

But I cannot make it work with OpenStack.

@haphan
Copy link
Collaborator

haphan commented Nov 4, 2020

@braisdesousa I recall this issue with auth v2.0 now. Pardon me because not many platforms are still using v2.

For v2 identity you'd need to override the config for IdentityService, it is documented here

Can you give it a try and report back? Thanks

@braisdesousa
Copy link

braisdesousa commented Nov 5, 2020

Test Done, following that documentation I'm able to create the same Guzzle Post, thant I was doing with CURL. And, this part "works", using it as identityService, is till giving the same response.

$httpClient = new Client([
            'base_uri' => TransportUtils::normalizeUrl('https://lon.identity.api.rackspacecloud.com/v2.0/'),
            'handler'  => HandlerStack::create(),
            'json'=>["auth"=>['RAX-KSKEY:apiKeyCredentials'=>["username"=>"username","apiKey"=>'apikey']]],
            'defaults'=>['headers'  => ['content-type' => 'application/json', 'Accept' => 'application/json']],
            ]
        );
        #I've used this piece just to check getting the same result as with the CURL client identifiing to Rackspace.
        #$response=$httpClient->post("tokens");
        #$body=json_decode($response->getBody()->getContents(),true);

        $options = [
            'authUrl'         => 'https://lon.identity.api.rackspacecloud.com/v2.0/',
            'region'          => 'LON',
            'username'        => 'username',
            'password'        => 'apikey',
            'identityService' => Service::factory($httpClient),
        ];

        /** @var OpenStack $openstack */
        $openstack = new OpenStack($options);

        $containers = $openstack->objectStoreV1()->listContainers();

The response stills
Client error:POST https://lon.identity.api.rackspacecloud.com/v2.0/tokens` resulted in a 401 Unauthorized response:
{"unauthorized":{"code":401,"message":"Error code: 'AUTH-004'; Unable to authenticate user with credentials provided."}}
`

@kynx
Copy link

kynx commented Nov 5, 2020

@braisdesousa We use this with Rackspace.

I can't remember doing it, but it looks like Rackspace expects 'apiKey', not 'password' and that we're overriding the default OpenStack\Identity\v2\Api to accomplish that. It's mixed in with stuff like caching the auth token and guzzle retry middleware. But from a quick look the relevant bits are:

use OpenStack\Identity\v2\Api as OpenStackApi;

class Api extends OpenStackApi
{
    protected $params;

    public function __construct()
    {
        $this->params = new Params();
    }

    public function postToken(): array 
    {
        return [
            'method' => 'POST',
            'path'   => 'tokens',
            'params' => [
                'username' => $this->params->username(),
                'apiKey'   => $this->params->apiKey(),
            ],
        ];
    }
}

and

use OpenStack\Common\Api\AbstractParams;

class Params extends AbstractParams
{
    public function username()
    {
        return [
            'type'     => self::STRING_TYPE,
            'location' => self::JSON,
            'path'     => 'auth.RAX-KSKEY:apiKeyCredentials',
            'required' => true,
        ];
    }

    public function apiKey()
    {
        return [
            'type'     => self::STRING_TYPE,
            'location' => self::JSON,
            'path'     => 'auth.RAX-KSKEY:apiKeyCredentials',
            'required' => true,
        ];
    }
}

Then the config looks something like:

$options = [
    'authUrl'         => $config['auth_url'],
    'region'          => $config['region'],
    'username'        => $config['username'],
    'apiKey'          => $config['api_key'],
];

You'd need to construct an instance of the Identity service passing the api as the second param, and somehow tell the rest of openstack to use that. As I said, our requirements are complex and there may be a much easier way of doing it.

Sure would have been nice if Rackspace hadn't fired all their developers 4 years ago ;)

@braisdesousa
Copy link

Thank you @kynx ! I will give it a Try ASAP and reply if it works.

@braisdesousa
Copy link

It Works as expected, the only required extra change is having to EDIT OpenStack Builder, to make a replacement of the API and the Service class, to match the ones we have created.
Somthing as UGLY as this

 if($apiClass==='OpenStack\Identity\v2\Api'){
            $serviceClass=Service::class;
            $apiClass=Api::class;
        }

I'm not so happy with this solution. Looks like a horrible patch. But it works, which is what my company need right now. I'll try to write Rackspace Support for looking for a better solution than this one. But, anyway thanks @kynx @haphan for your incredible help. Couldn't make it without you.

@gkilwein
Copy link

I struggled with getting OpenStack working with Rackspace Cloud Files for days so I wrote my own very simple PHP client for the basic functionality that my app needs for Cloud Files here: https://github.com/gkilwein/Rackspace-Cloud-Files Hopefully this helps someone.

@colethorsen
Copy link

Late to this issue, but since it still doesn't seem to have a solution:

This uses php-opencloud/openstack v3.10.0

$authUrl = 'https://identity.api.rackspacecloud.com/v2.0/';

$httpClient = new \GuzzleHttp\Client([
	'base_uri' => \OpenStack\Common\Transport\Utils::normalizeUrl($authUrl),
	'handler'  => \GuzzleHttp\HandlerStack::create(),
]);

$openstack = new \OpenStack\OpenStack([
	'authUrl'         => $authUrl,
	'identityService' => RackspaceIdentityService::factory($httpClient),
	'region'          => '{{ ADD RACKSPACE REGION }}',
	'user'            => [
		'username' => '{{ ADD RACKSPACE USERNAME HERE }}',
		'apiKey'   => '{{ ADD RACKSPACE API KEY HERE }}',
	],
]);

$container = $openstack->objectStoreV1([
	'catalogName' => 'cloudFiles',
])
	->getContainer('{{ ADD CONTAINER NAME HERE }}');

You also need to create the identity service referenced in the code:

use OpenStack\Common\Auth\IdentityService;
use OpenStack\Identity\v2\Models\Catalog;
use OpenStack\Identity\v2\Models\Token;
use OpenStack\Identity\v2\Service as V2Service;

class RackspaceIdentityService extends V2Service implements IdentityService
{
	public function authenticate(array $options = []): array
	{
		$response = $this->execute([
			'method'   => 'POST',
			'path'     => 'tokens',
			'skipAuth' => true,
			'params'   => [
				'username'   => [
					'type'     => 'string',
					'required' => true,
					'path'     => 'auth.RAX-KSKEY:apiKeyCredentials',
				],
				'apiKey'   => [
					'type'     => 'string',
					'required' => true,
					'path'     => 'auth.RAX-KSKEY:apiKeyCredentials',
				],
			],
		], $options['user']);

		$token = $this->model(Token::class, $response);

		$serviceUrl = $this->model(Catalog::class, $response)->getServiceUrl(
			$options['catalogName'],
			$options['catalogType'],
			$options['region'],
			$options['urlType']
		);

		return [$token, $serviceUrl];
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants