def _extract_service_catalog(self, url, resp, body, extract_token=True): """See what the auth service told us and process the response. We may get redirected to another site, fail or actually get back a service catalog with a token and our endpoints. """ # content must always present if resp.status_code == 200 or resp.status_code == 201: try: self.auth_url = url self.service_catalog = \ service_catalog.ServiceCatalog(body) if extract_token: self.auth_token = self.service_catalog.get_token() self.tenant_id = self.service_catalog.get_tenant_id() self.management_url = self.get_service_url(self.service_type) return None 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_code == 305: return resp.headers['location'] else: raise exceptions.from_response(resp, body, url)
def authenticate(self): if not self.auth_url: msg = _("Authentication requires 'auth_url', which should be " "specified in '%s'") % self.__class__.__name__ raise exceptions.AuthorizationFailure(msg) magic_tuple = netutils.urlsplit(self.auth_url) scheme, netloc, path, query, frag = magic_tuple port = magic_tuple.port if port is None: port = 80 path_parts = path.split('/') for part in path_parts: if len(part) > 0 and part[0] == 'v': self.version = part break if self.auth_token and self.management_url: self._save_keys() return # TODO(sandy): Assume admin endpoint is 35357 for now. # Ideally this is going to have to be provided by the service catalog. new_netloc = netloc.replace(':%d' % port, ':%d' % (35357, )) admin_url = parse.urlunsplit((scheme, new_netloc, path, query, frag)) auth_url = self.auth_url if self.version == "v2.0": # FIXME(chris): This should be better. while auth_url: auth_url = self._v2_auth(auth_url) # Are we acting on behalf of another user via an # existing token? If so, our actual endpoints may # be different than that of the admin token. if self.proxy_token: if self.bypass_url: self.set_management_url(self.bypass_url) else: self._fetch_endpoints_from_auth(admin_url) # Since keystone no longer returns the user token # with the endpoints any more, we need to replace # our service account token with the user token. self.auth_token = self.proxy_token else: try: while auth_url: auth_url = self._v1_auth(auth_url) # In some configurations nova makes redirection to # v2.0 keystone endpoint. Also, new location does not contain # real endpoint, only hostname and port. except exceptions.AuthorizationFailure: if auth_url.find('v2.0') < 0: auth_url = auth_url + '/v2.0' self._v2_auth(auth_url) if self.bypass_url: self.set_management_url(self.bypass_url) elif not self.management_url: raise exceptions.Unauthorized('Nova Client') self._save_keys()
def _check_keystone_versions(url): try: httpclient = client.HTTPClient(user=None, password=None, projectid=None, auth_url=None) resp, body = httpclient.request(url, "GET", headers={'Accept': 'application/json'}) if resp.status in (200, 204): # in some cases we get No Content try: print "Keystone found at %s" % url if 'version' in body: version = body['version'] # Stable/diablo incorrect format _display_version_info(version, url) return True if 'versions' in body: # Correct format for version in body['versions']['values']: _display_version_info(version, url) return True print "Unrecognized response from %s" % url except KeyError: raise exceptions.AuthorizationFailure() elif resp.status == 305: return _check_keystone_versions(resp['location']) else: raise exceptions.from_response(resp, body) except: return False
def _extract_service_catalog(self, url, resp, body, extract_token=True): """See what the auth service told us and process the response. We may get redirected to another site, fail or actually get back a service catalog with a token and our endpoints.""" if resp.status == 200: # content must always present try: self.auth_url = url self.service_catalog = \ service_catalog.ServiceCatalog(body) if extract_token: self.auth_token = self.service_catalog.get_token() self.management_url = self.service_catalog.url_for( attr='region', filter_value=self.region_name, endpoint_type=self.endpoint_name) return None 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 _extract_service_catalog(self, url, resp, body, extract_token=True): """See what the auth service told us and process the response. We may get redirected to another site, fail or actually get back a service catalog with a token and our endpoints.""" if resp.status == 200: # content must always present try: self.auth_url = url self.service_catalog = \ service_catalog.ServiceCatalog(body) if extract_token: self.auth_token = self.service_catalog.get_token() self.management_url = self.service_catalog.url_for( attr='region', filter_value=self.region_name, endpoint_type=self.endpoint_type, service_name=self.service_name) return None except exceptions.AmbiguousEndpoints, exc: print "Found more than one valid endpoint. Use a more " \ "restrictive filter" raise except KeyError: raise exceptions.AuthorizationFailure()
def basic_auth(self): """Authenticate against a v2.0 auth service.""" auth_url = self.auth_url body = {"credentials": {"username": self.user, "key": self.password}} resp, resp_body = self._authenticate_without_tokens(auth_url, body) try: 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()
def _v1_auth(self, url): if self.proxy_token: raise exceptions.NoTokenLookupException() headers = {'X-Auth-User': self.user, 'X-Auth-Key': self.password} if self.projectid: headers['X-Auth-Project-Id'] = self.projectid resp, body = self.request(url, 'GET', headers=headers) if resp.status in (200, 204): # in some cases we get No Content try: self.management_url = resp['x-server-management-url'] self.auth_token = resp['x-auth-token'] self.auth_url = url except KeyError: raise exceptions.AuthorizationFailure() elif resp.status == 305: return resp['location'] else: raise exceptions.from_response(resp, body)
def _v1_auth(self, url): if self.proxy_token: raise exceptions.NoTokenLookupException() headers = {'X-Auth-User': self.user, 'X-Auth-Key': self._get_password()} if self.projectid: headers['X-Auth-Project-Id'] = self.projectid resp, body = self._time_request(url, 'GET', headers=headers) if resp.status_code in (200, 204): # in some cases we get No Content try: mgmt_header = 'x-server-management-url' self.management_url = resp.headers[mgmt_header].rstrip('/') self.auth_token = resp.headers['x-auth-token'] self.auth_url = url except (KeyError, TypeError): raise exceptions.AuthorizationFailure() elif resp.status_code == 305: return resp.headers['location'] else: raise exceptions.from_response(resp, body, url)