diff options
Diffstat (limited to 'reddwarfclient/auth.py')
| -rw-r--r-- | reddwarfclient/auth.py | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/reddwarfclient/auth.py b/reddwarfclient/auth.py deleted file mode 100644 index 4494447..0000000 --- a/reddwarfclient/auth.py +++ /dev/null @@ -1,269 +0,0 @@ -# Copyright 2012 OpenStack LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from reddwarfclient import exceptions - - -def get_authenticator_cls(cls_or_name): - """Factory method to retrieve Authenticator class.""" - if isinstance(cls_or_name, type): - return cls_or_name - elif isinstance(cls_or_name, basestring): - if cls_or_name == "keystone": - return KeyStoneV2Authenticator - elif cls_or_name == "rax": - return RaxAuthenticator - elif cls_or_name == "auth1.1": - return Auth1_1 - elif cls_or_name == "fake": - return FakeAuth - - raise ValueError("Could not determine authenticator class from the given " - "value %r." % cls_or_name) - - -class Authenticator(object): - """ - Helper class to perform Keystone or other miscellaneous authentication. - - The "authenticate" method returns a ServiceCatalog, which can be used - to obtain a token. - - """ - - URL_REQUIRED = True - - def __init__(self, client, type, url, username, password, tenant, - region=None, service_type=None, service_name=None, - service_url=None): - self.client = client - self.type = type - self.url = url - self.username = username - self.password = password - self.tenant = tenant - self.region = region - self.service_type = service_type - self.service_name = service_name - self.service_url = service_url - - def _authenticate(self, url, body, root_key='access'): - """Authenticate and extract the service catalog.""" - # Make sure we follow redirects when trying to reach Keystone - tmp_follow_all_redirects = self.client.follow_all_redirects - self.client.follow_all_redirects = True - - try: - resp, body = self.client._time_request(url, "POST", body=body) - finally: - self.client.follow_all_redirects = tmp_follow_all_redirects - - if resp.status == 200: # content must always present - try: - return ServiceCatalog(body, region=self.region, - service_type=self.service_type, - service_name=self.service_name, - service_url=self.service_url, - root_key=root_key) - except exceptions.AmbiguousEndpoints: - print "Found more than one valid endpoint. Use a more "\ - "restrictive filter" - raise - except KeyError: - raise exceptions.AuthorizationFailure() - except exceptions.EndpointNotFound: - print "Could not find any suitable endpoint. Correct region?" - raise - - elif resp.status == 305: - return resp['location'] - else: - raise exceptions.from_response(resp, body) - - def authenticate(self): - raise NotImplementedError("Missing authenticate method.") - - -class KeyStoneV2Authenticator(Authenticator): - - def authenticate(self): - if self.url is None: - raise exceptions.AuthUrlNotGiven() - return self._v2_auth(self.url) - - def _v2_auth(self, url): - """Authenticate against a v2.0 auth service.""" - body = {"auth": { - "passwordCredentials": { - "username": self.username, - "password": self.password} - } - } - - if self.tenant: - body['auth']['tenantName'] = self.tenant - - return self._authenticate(url, body) - - -class Auth1_1(Authenticator): - - def authenticate(self): - """Authenticate against a v2.0 auth service.""" - if self.url is None: - raise exceptions.AuthUrlNotGiven() - auth_url = self.url - body = {"credentials": {"username": self.username, - "key": self.password}} - return self._authenticate(auth_url, body, root_key='auth') - - try: - print(resp_body) - self.auth_token = resp_body['auth']['token']['id'] - except KeyError: - raise nova_exceptions.AuthorizationFailure() - - catalog = resp_body['auth']['serviceCatalog'] - if 'cloudDatabases' not in catalog: - raise nova_exceptions.EndpointNotFound() - endpoints = catalog['cloudDatabases'] - for endpoint in endpoints: - if self.region_name is None or \ - endpoint['region'] == self.region_name: - self.management_url = endpoint['publicURL'] - return - raise nova_exceptions.EndpointNotFound() - - -class RaxAuthenticator(Authenticator): - - def authenticate(self): - if self.url is None: - raise exceptions.AuthUrlNotGiven() - return self._rax_auth(self.url) - - def _rax_auth(self, url): - """Authenticate against the Rackspace auth service.""" - body = {'auth': { - 'RAX-KSKEY:apiKeyCredentials': { - 'username': self.username, - 'apiKey': self.password, - 'tenantName': self.tenant} - } - } - - return self._authenticate(self.url, body) - - -class FakeAuth(Authenticator): - """Useful for faking auth.""" - - def authenticate(self): - class FakeCatalog(object): - def __init__(self, auth): - self.auth = auth - - def get_public_url(self): - return "%s/%s" % ('http://localhost:8779/v1.0', - self.auth.tenant) - - def get_token(self): - return self.auth.tenant - - return FakeCatalog(self) - - -class ServiceCatalog(object): - """Represents a Keystone Service Catalog which describes a service. - - This class has methods to obtain a valid token as well as a public service - url and a management url. - - """ - - def __init__(self, resource_dict, region=None, service_type=None, - service_name=None, service_url=None, root_key='access'): - self.catalog = resource_dict - self.region = region - self.service_type = service_type - self.service_name = service_name - self.service_url = service_url - self.management_url = None - self.public_url = None - self.root_key = root_key - self._load() - - def _load(self): - if not self.service_url: - self.public_url = self._url_for(attr='region', - filter_value=self.region, - endpoint_type="publicURL") - self.management_url = self._url_for(attr='region', - filter_value=self.region, - endpoint_type="adminURL") - else: - self.public_url = self.service_url - self.management_url = self.service_url - - def get_token(self): - return self.catalog[self.root_key]['token']['id'] - - def get_management_url(self): - return self.management_url - - def get_public_url(self): - return self.public_url - - def _url_for(self, attr=None, filter_value=None, - endpoint_type='publicURL'): - """ - Fetch the public URL from the Reddwarf service for a particular - endpoint attribute. If none given, return the first. - """ - matching_endpoints = [] - if 'endpoints' in self.catalog: - # We have a bastardized service catalog. Treat it special. :/ - for endpoint in self.catalog['endpoints']: - if not filter_value or endpoint[attr] == filter_value: - matching_endpoints.append(endpoint) - if not matching_endpoints: - raise exceptions.EndpointNotFound() - - # We don't always get a service catalog back ... - if not 'serviceCatalog' in self.catalog[self.root_key]: - raise exceptions.EndpointNotFound() - - # Full catalog ... - catalog = self.catalog[self.root_key]['serviceCatalog'] - - for service in catalog: - if service.get("type") != self.service_type: - continue - - if (self.service_name and self.service_type == 'database' and - service.get('name') != self.service_name): - continue - - endpoints = service['endpoints'] - for endpoint in endpoints: - if not filter_value or endpoint.get(attr) == filter_value: - endpoint["serviceName"] = service.get("name") - matching_endpoints.append(endpoint) - - if not matching_endpoints: - raise exceptions.EndpointNotFound() - elif len(matching_endpoints) > 1: - raise exceptions.AmbiguousEndpoints(endpoints=matching_endpoints) - else: - return matching_endpoints[0].get(endpoint_type, None) |
