def parse_reqtype(self): """Return the authentication body.""" if self.job_args['os_auth_version'] == 'v1.0': return dict() else: setup = {'username': self.job_args.get('os_user')} # Check if any prefix items are set. A prefix should be a # dictionary with keys matching the os_* credential type. prefixes = self.job_args.get('os_prefix') if self.job_args.get('os_token') is not None: auth_body = { 'auth': { 'token': { 'id': self.job_args.get('os_token') } } } if not self.job_args.get('os_tenant'): raise exceptions.AuthenticationProblem( 'To use token auth you must specify the tenant id. Set' ' the tenant ID with [ --os-tenant ]') elif self.job_args.get('os_password') is not None: setup['password'] = self.job_args.get('os_password') if prefixes: prefix = prefixes.get('os_password') if not prefix: raise NotImplementedError( 'the `password` method is not implemented for this' ' auth plugin') else: prefix = 'passwordCredentials' auth_body = {'auth': {prefix: setup}} elif self.job_args.get('os_apikey') is not None: setup['apiKey'] = self.job_args.get('os_apikey') if prefixes: prefix = prefixes.get('os_apikey') if not prefix: raise NotImplementedError( 'the `apikey` method is not implemented for this' ' auth plugin') else: prefix = 'apiKeyCredentials' auth_body = {'auth': {prefix: setup}} else: raise exceptions.AuthenticationProblem( 'No Password, APIKey, or Token Specified') if self.job_args.get('os_tenant'): auth = auth_body['auth'] auth['tenantName'] = self.job_args.get('os_tenant') LOG.debug('AUTH Request body: [ %s ]', auth_body) return auth_body
def authenticate(job_args): """Authentication For Openstack API. Pulls the full Openstack Service Catalog Credentials are the Users API Username and Key/Password. Set a DC Endpoint and Authentication URL for the OpenStack environment """ # Load any authentication plugins as needed job_args = utils.check_auth_plugin(job_args) # Set the auth version auth_version = utils.get_authversion(job_args=job_args) # Define the base headers that are used in all authentications auth_headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' } auth_headers.update(job_args['base_headers']) if auth_version == 'v1.0': auth = utils.V1Authentication(job_args=job_args) auth_headers.update(auth.get_headers()) LOG.debug('Request Headers: [ %s ]', auth_headers) auth_url = job_args['os_auth_url'] LOG.debug('Parsed Auth URL: [ %s ]', auth_url) auth_kwargs = {'url': auth_url, 'headers': auth_headers} else: auth = utils.OSAuthentication(job_args=job_args) auth_url = auth.parse_region() LOG.debug('Parsed Auth URL: [ %s ]', auth_url) auth_json = auth.parse_reqtype() LOG.debug('Request Headers: [ %s ]', auth_headers) auth_body = json.dumps(auth_json) LOG.debug('Request JSON: [ %s ]', auth_body) auth_kwargs = { 'url': auth_url, 'headers': auth_headers, 'body': auth_body } auth_resp = auth.auth_request(**auth_kwargs) if auth_resp.status_code >= 300: raise exceptions.AuthenticationProblem( 'Authentication Failure, Status: [ %s ] Reason: [ %s ]', auth_resp.status_code, auth_resp.reason) else: return auth.parse_auth_response(auth_resp)
def get_headers(self): """Setup headers for authentication request.""" try: return { 'X-Auth-User': self.job_args['os_user'], 'X-Auth-Key': self.job_args['os_apikey'] } except KeyError as exp: raise exceptions.AuthenticationProblem( 'Missing Credentials. Error: %s', exp)
def parse_region(self): """Pull region/auth url information from context.""" try: auth_url = self.job_args['os_auth_url'] if 'tokens' not in auth_url: if not auth_url.endswith('/'): auth_url = '%s/' % auth_url auth_url = urlparse.urljoin(auth_url, 'tokens') return auth_url except KeyError: raise exceptions.AuthenticationProblem( 'You Are required to specify an Auth URL, Region or Plugin')
def get_service_url(region, endpoint_list, lookup): """Lookup a service URL from the *endpoint_list*. :param region: ``str`` :param endpoint_list: ``list`` :param lookup: ``str`` :return: ``object`` """ for endpoint in endpoint_list: region_get = endpoint.get('region', '') if region.lower() == region_get.lower(): return http.parse_url(url=endpoint.get(lookup)) else: raise exceptions.AuthenticationProblem( 'Region "%s" was not found in your Service Catalog.', region)
def get_authversion(job_args): """Get or infer the auth version. Based on the information found in the *AUTH_VERSION_MAP* the authentication version will be set to a correct value as determined by the **os_auth_version** parameter as found in the `job_args`. :param job_args: ``dict`` :returns: ``str`` """ _version = job_args.get('os_auth_version') for version, variants in AUTH_VERSION_MAP.items(): if _version in variants: authversion = job_args['os_auth_version'] = version return authversion else: raise exceptions.AuthenticationProblem( "Auth Version must be one of %s.", list(AUTH_VERSION_MAP.keys()))
def parse_auth_response(auth_response): """Parse the auth response and return the tenant, token, and username. :param auth_response: the full object returned from an auth call :returns: ``dict`` """ auth_dict = dict() LOG.debug('Authentication Headers %s', auth_response.headers) try: auth_dict['os_token'] = auth_response.headers['x-auth-token'] auth_dict['storage_url'] = urlparse.urlparse( auth_response.headers['x-storage-url']) except KeyError as exp: raise exceptions.AuthenticationProblem( 'No token was found in the authentication response. Please' ' check your auth URL, your credentials, and your set auth' ' version. Auth Headers: [ %s ] Error: [ %s ]', auth_response.headers, exp) else: return auth_dict
def parse_auth_response(self, auth_response): """Parse the auth response and return the tenant, token, and username. :param auth_response: the full object returned from an auth call :returns: ``dict`` """ auth_dict = dict() auth_response = auth_response.json() LOG.debug('Authentication Response Body [ %s ]', auth_response) access = auth_response.get('access') access_token = access.get('token') access_tenant = access_token.get('tenant') access_user = access.get('user') auth_dict['os_token'] = access_token.get('id') auth_dict['os_tenant'] = access_tenant.get('name') auth_dict['os_user'] = access_user.get('name') if not auth_dict['os_token']: raise exceptions.AuthenticationProblem( 'When attempting to grab the tenant or user nothing was' ' found. No Token Found to Parse. Here is the DATA: [ %s ]' ' Stack Trace [ %s ]', auth_response, traceback.format_exc()) region = self.job_args.get('os_region') print(region) if not region: raise exceptions.SystemProblem('No Region Set') service_catalog = access.pop('serviceCatalog') # Get the storage URL object_endpoints = self._service_endpoints( service_catalog=service_catalog, types_list=turbolift.__srv_types__) # In the legacy internal flag is set override the os_endpoint_type # TODO(cloudnull) Remove this in future releases if 'internal' in self.job_args and self.job_args['internal']: LOG.warn( 'The use of the ``--internal`` flag has been deprecated and' ' will be removed in future releases. Please use the' ' ``--os-endpoint-type`` flag and set the type name' ' instead. In the case of using snet (service net) this is' ' generally noted as "internalURL". Example setting:' ' ``--os-endpoint-type internalURL``') self.job_args['os_endpoint_type'] = 'internalURL' auth_dict['storage_url'] = get_service_url( region=region, endpoint_list=object_endpoints, lookup=self.job_args['os_endpoint_type']) # Get the CDN URL cdn_endpoints = self._service_endpoints( service_catalog=service_catalog, types_list=turbolift.__cdn_types__) if cdn_endpoints: auth_dict['cdn_storage_url'] = get_service_url( region=region, endpoint_list=cdn_endpoints, lookup=self.job_args['cdn_endpoint_type']) return auth_dict