def base_url(self, filters, auth_data=None): """Base URL from catalog :param filters: Used to filter results Filters can be: - service: service type name such as compute, image, etc. - region: service region name - name: service name, only if service exists - endpoint_type: type of endpoint such as adminURL, publicURL, internalURL - api_version: the version of api used to replace catalog version - skip_path: skips the suffix path of the url and uses base URL :rtype: string :return: url with filters applied """ if auth_data is None: auth_data = self.get_auth() token, _auth_data = auth_data service = filters.get('service') region = filters.get('region') name = filters.get('name') endpoint_type = filters.get('endpoint_type', 'publicURL') if service is None: raise exceptions.EndpointNotFound("No service provided") _base_url = None for ep in _auth_data['serviceCatalog']: if ep["type"] == service: if name is not None and ep["name"] != name: continue for _ep in ep['endpoints']: if region is not None and _ep['region'] == region: _base_url = _ep.get(endpoint_type) if not _base_url: # No region or name matching, use the first _base_url = ep['endpoints'][0].get(endpoint_type) break if _base_url is None: raise exceptions.EndpointNotFound( "service: %s, region: %s, endpoint_type: %s, name: %s" % (service, region, endpoint_type, name)) return apply_url_filters(_base_url, filters)
def base_url(self, filters, auth_data=None): """Base URL from catalog If scope is not 'project', it may be that there is not catalog in the auth_data. In such case, as long as the requested service is 'identity', we can use the original auth URL to build the base_url. :param filters: Used to filter results Filters can be: - service: service type name such as compute, image, etc. - region: service region name - name: service name, only if service exists - endpoint_type: type of endpoint such as adminURL, publicURL, internalURL - api_version: the version of api used to replace catalog version - skip_path: skips the suffix path of the url and uses base URL :rtype: string :return: url with filters applied """ if auth_data is None: auth_data = self.get_auth() token, _auth_data = auth_data service = filters.get('service') region = filters.get('region') name = filters.get('name') endpoint_type = filters.get('endpoint_type', 'public') if service is None: raise exceptions.EndpointNotFound("No service provided") if 'URL' in endpoint_type: endpoint_type = endpoint_type.replace('URL', '') _base_url = None catalog = _auth_data.get('catalog', []) # Select entries with matching service type service_catalog = [ep for ep in catalog if ep['type'] == service] if service_catalog: if name is not None: service_catalog = ( [ep for ep in service_catalog if ep['name'] == name]) if service_catalog: service_catalog = service_catalog[0]['endpoints'] else: raise exceptions.EndpointNotFound(name) else: service_catalog = service_catalog[0]['endpoints'] else: if not catalog and service == 'identity': # NOTE(andreaf) If there's no catalog at all and the service # is identity, it's a valid use case. Having a non-empty # catalog with no identity in it is not valid instead. msg = ('Got an empty catalog. Scope: %s. ' 'Falling back to configured URL for %s: %s') LOG.debug(msg, self.scope, service, self.auth_url) return apply_url_filters(self.auth_url, filters) else: # No matching service msg = ('No matching service found in the catalog.\n' 'Scope: %s, Credentials: %s\n' 'Auth data: %s\n' 'Service: %s, Region: %s, endpoint_type: %s\n' 'Catalog: %s') raise exceptions.EndpointNotFound(msg % ( self.scope, self.credentials, _auth_data, service, region, endpoint_type, catalog)) # Filter by endpoint type (interface) filtered_catalog = [ep for ep in service_catalog if ep['interface'] == endpoint_type] if not filtered_catalog: # No matching type, keep all and try matching by region at least filtered_catalog = service_catalog # Filter by region filtered_catalog = [ep for ep in filtered_catalog if ep['region'] == region] if not filtered_catalog: # No matching region (or name), take the first endpoint filtered_catalog = [service_catalog[0]] # There should be only one match. If not take the first. _base_url = filtered_catalog[0].get('url', None) if _base_url is None: raise exceptions.EndpointNotFound(service) return apply_url_filters(_base_url, filters)
def base_url(self, filters, auth_data=None): """Base URL from catalog Filters can be: - service: compute, image, etc - region: the service region - endpoint_type: adminURL, publicURL, internalURL - api_version: replace catalog version with this - skip_path: take just the base URL """ if auth_data is None: auth_data = self.auth_data token, _auth_data = auth_data service = filters.get('service') region = filters.get('region') endpoint_type = filters.get('endpoint_type', 'public') if service is None: raise exceptions.EndpointNotFound("No service provided") if 'URL' in endpoint_type: endpoint_type = endpoint_type.replace('URL', '') _base_url = None catalog = _auth_data['catalog'] # Select entries with matching service type service_catalog = [ep for ep in catalog if ep['type'] == service] if len(service_catalog) > 0: service_catalog = service_catalog[0]['endpoints'] else: # No matching service raise exceptions.EndpointNotFound(service) # Filter by endpoint type (interface) filtered_catalog = [ ep for ep in service_catalog if ep['interface'] == endpoint_type ] if len(filtered_catalog) == 0: # No matching type, keep all and try matching by region at least filtered_catalog = service_catalog # Filter by region filtered_catalog = [ ep for ep in filtered_catalog if ep['region'] == region ] if len(filtered_catalog) == 0: # No matching region, take the first endpoint filtered_catalog = [service_catalog[0]] # There should be only one match. If not take the first. _base_url = filtered_catalog[0].get('url', None) if _base_url is None: raise exceptions.EndpointNotFound(service) parts = urlparse.urlparse(_base_url) if filters.get('api_version', None) is not None: version_path = '/%s' % filters['api_version'] path = re.sub(r'(^|/)+v\d+(?:\.\d+)?', version_path, parts.path, count=1) _base_url = urlparse.urlunparse( (parts.scheme, parts.netloc, path or version_path, parts.params, parts.query, parts.fragment)) if filters.get('skip_path', None) is not None: _base_url = urlparse.urlunparse( (parts.scheme, parts.netloc, '/', parts.params, parts.query, parts.fragment)) return _base_url