diff options
| author | Jamie Lennox <jamielennox@redhat.com> | 2014-04-22 12:17:42 +1000 |
|---|---|---|
| committer | Jamie Lennox <jamielennox@redhat.com> | 2014-05-05 08:06:16 +1000 |
| commit | c1c5669d0c95ca43788abcb3eda07fd3bccec73f (patch) | |
| tree | 88af3cb5fd8cd2ad50ad01238f7c11d98c3f4eea /keystoneclient/middleware | |
| parent | 570a9dc22dad6c246372f273bd6db23342752c3a (diff) | |
| download | python-keystoneclient-c1c5669d0c95ca43788abcb3eda07fd3bccec73f.tar.gz | |
Make auth_token return a V2 Catalog
As there is no way to distinguish a v2 or v3 catalog from the headers
provided to an application we will for the meantime always return a v2
catalog. This should not cause any issues as the full token data is not
provided to the service so there is no-one that will get caught out by a
v2/v3 mix, and anyone that is already supporting the v3 catalog format
will have to support the v2 catalog format as well so it will continue
to work.
Change-Id: Ic9b38e0ba4682b47ae295bd3f89bac59ef7437cf
Closes-Bug: #1302970
Diffstat (limited to 'keystoneclient/middleware')
| -rw-r--r-- | keystoneclient/middleware/auth_token.py | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/keystoneclient/middleware/auth_token.py b/keystoneclient/middleware/auth_token.py index 637b3b2..25544dd 100644 --- a/keystoneclient/middleware/auth_token.py +++ b/keystoneclient/middleware/auth_token.py @@ -108,6 +108,8 @@ HTTP_X_ROLES HTTP_X_SERVICE_CATALOG json encoded keystone service catalog (optional). + For compatibility reasons this catalog will always be in the V2 catalog + format even if it is a v3 token. HTTP_X_TENANT_ID *Deprecated* in favor of HTTP_X_PROJECT_ID @@ -371,6 +373,42 @@ def confirm_token_not_expired(data): return timeutils.isotime(at=expires, subsecond=True) +def _v3_to_v2_catalog(catalog): + """Convert a catalog to v2 format. + + X_SERVICE_CATALOG must be specified in v2 format. If you get a token + that is in v3 convert it. + """ + v2_services = [] + for v3_service in catalog: + # first copy over the entries we allow for the service + v2_service = {'type': v3_service['type']} + try: + v2_service['name'] = v3_service['name'] + except KeyError: + pass + + # now convert the endpoints. Because in v3 we specify region per + # URL not per group we have to collect all the entries of the same + # region together before adding it to the new service. + regions = {} + for v3_endpoint in v3_service.get('endpoints', []): + region_name = v3_endpoint.get('region') + try: + region = regions[region_name] + except KeyError: + region = {'region': region_name} if region_name else {} + regions[region_name] = region + + interface_name = v3_endpoint['interface'].lower() + 'URL' + region[interface_name] = v3_endpoint['url'] + + v2_service['endpoints'] = list(regions.values()) + v2_services.append(v2_service) + + return v2_services + + def safe_quote(s): """URL-encode strings that are not already URL-encoded.""" return urllib.parse.quote(s) if s == urllib.parse.unquote(s) else s @@ -939,6 +977,8 @@ class AuthProtocol(object): if self.include_service_catalog and auth_ref.has_service_catalog(): catalog = auth_ref.service_catalog.get_data() + if _token_is_v3(token_info): + catalog = _v3_to_v2_catalog(catalog) rval['X-Service-Catalog'] = jsonutils.dumps(catalog) return rval |
