From d35a5edcab21db4a9cbd9c4b00349d38920a5146 Mon Sep 17 00:00:00 2001 From: Morgan Fainberg Date: Tue, 17 Jul 2018 13:33:07 -0700 Subject: [PATCH] Allow for 'extension' rel in json home Allow providing an alternative REL function (e.g. for extensions) in JSON Home in flask. The alternative functions are expected to be functools.partial. The extension-mode should only ever be used in the case of a keystone API that was an extension (legacy style) and has not been converted over to a new URI path; typically extensions start with an OS- prefix in the URL. All new APIs should not be using the 'extension' style. Change-Id: I3970aef12f3b7c8e84fa80dfea8fc6eda63fe77d Partial-Bug: #1776504 --- keystone/server/flask/common.py | 39 ++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/keystone/server/flask/common.py b/keystone/server/flask/common.py index 8e7d292e65..304935f111 100644 --- a/keystone/server/flask/common.py +++ b/keystone/server/flask/common.py @@ -124,7 +124,7 @@ def construct_resource_map(resource, url, resource_kwargs, alternate_urls=None, def construct_json_home_data(rel, status=json_home.Status.STABLE, path_vars=None, resource_relation_func=_v3_resource_relation): - rel = resource_relation_func(rel) + rel = resource_relation_func(resource_name=rel) return JsonHomeData(rel=rel, status=status, path_vars=(path_vars or {})) @@ -305,28 +305,44 @@ class APIBase(object): 'm_key': m_key}) continue + # NOTE(morgan): The Prefix is automatically added by the API, so + # we do not add it to the paths here. collection_path = '/%s' % c_key - entity_path = '/%(collection_key)s/' % { - 'collection_key': c_key, 'member_key': m_key} + entity_path = '/%(collection)s/' % { + 'collection': c_key, 'member': m_key} # NOTE(morgan): The json-home form of the entity path is different # from the flask-url routing form. jh_e_path = _URL_SUBST.sub('{\\1}', entity_path) LOG.debug( 'Adding standard routes to API %(name)s for `%(resource)s` ' - '[%(collection_path)s, %(entity_path)s]', { + '(API Prefix: %(prefix)s) [%(collection_path)s, ' + '%(entity_path)s]', { 'name': self._name, 'resource': r.__class__.__name__, 'collection_path': collection_path, - 'entity_path': entity_path}) + 'entity_path': entity_path, + 'prefix': self._api_url_prefix}) self.api.add_resource(r, collection_path, entity_path) # Add JSON Home data - collection_rel = json_home.build_v3_resource_relation(c_key) - rel_data = {'href': collection_path} + resource_rel_func = getattr( + r, 'json_home_resource_rel_func', + json_home.build_v3_resource_relation) + collection_rel = resource_rel_func(resource_name=c_key) + # NOTE(morgan): Add the prefix explicitly for JSON Home documents + # to the collection path. + rel_data = {'href': '%(pfx)s%(collection_path)s' % { + 'pfx': self._api_url_prefix, + 'collection_path': collection_path} + } - entity_rel = json_home.build_v3_resource_relation(m_key) + entity_rel = resource_rel_func(resource_name=m_key) id_str = '%s_id' % m_key - id_param_rel = json_home.build_v3_parameter_relation(id_str) + + parameter_rel_func = getattr( + r, 'json_home_parameter_rel_func', + json_home.build_v3_parameter_relation) + id_param_rel = parameter_rel_func(parameter_name=id_str) entity_rel_data = {'href-template': jh_e_path, 'href-vars': {id_str: id_param_rel}} @@ -358,7 +374,10 @@ class APIBase(object): resource_data = {} # NOTE(morgan): JSON Home form of the URL is different # from FLASK, do the conversion here. - conv_url = _URL_SUBST.sub('{\\1}', r.url) + conv_url = '%(pfx)s/%(url)s' % { + 'url': _URL_SUBST.sub('{\\1}', r.url).lstrip('/'), + 'pfx': self._api_url_prefix} + if r.json_home_data.path_vars: resource_data['href-template'] = conv_url resource_data['href-vars'] = r.json_home_data.path_vars