diff --git a/keystone/assignment/routers.py b/keystone/assignment/routers.py index f88d822d9..66293879f 100644 --- a/keystone/assignment/routers.py +++ b/keystone/assignment/routers.py @@ -61,12 +61,14 @@ class Routers(wsgi.RoutersBase): def append_v3_routers(self, mapper, routers): routers.append( router.Router(controllers.DomainV3(), - 'domains', 'domain')) + 'domains', 'domain', + resource_descriptions=self.v3_resources)) project_controller = controllers.ProjectV3() routers.append( router.Router(project_controller, - 'projects', 'project')) + 'projects', 'project', + resource_descriptions=self.v3_resources)) self._add_resource( mapper, project_controller, @@ -79,7 +81,8 @@ class Routers(wsgi.RoutersBase): role_controller = controllers.RoleV3() routers.append( - router.Router(role_controller, 'roles', 'role')) + router.Router(role_controller, 'roles', 'role', + resource_descriptions=self.v3_resources)) self._add_resource( mapper, role_controller, @@ -168,7 +171,9 @@ class Routers(wsgi.RoutersBase): routers.append( router.Router(controllers.RoleAssignmentV3(), - 'role_assignments', 'role_assignment')) + 'role_assignments', 'role_assignment', + resource_descriptions=self.v3_resources, + is_entity_implemented=False)) if config.CONF.os_inherit.enabled: self._add_resource( diff --git a/keystone/catalog/routers.py b/keystone/catalog/routers.py index fd485609a..f3bd988bf 100644 --- a/keystone/catalog/routers.py +++ b/keystone/catalog/routers.py @@ -22,7 +22,8 @@ class Routers(wsgi.RoutersBase): def append_v3_routers(self, mapper, routers): regions_controller = controllers.RegionV3() routers.append(router.Router(regions_controller, - 'regions', 'region')) + 'regions', 'region', + resource_descriptions=self.v3_resources)) # Need to add an additional route to support PUT /regions/{region_id} mapper.connect( @@ -32,6 +33,8 @@ class Routers(wsgi.RoutersBase): conditions=dict(method=['PUT'])) routers.append(router.Router(controllers.ServiceV3(), - 'services', 'service')) + 'services', 'service', + resource_descriptions=self.v3_resources)) routers.append(router.Router(controllers.EndpointV3(), - 'endpoints', 'endpoint')) + 'endpoints', 'endpoint', + resource_descriptions=self.v3_resources)) diff --git a/keystone/common/router.py b/keystone/common/router.py index 48a377c12..11a2a901d 100644 --- a/keystone/common/router.py +++ b/keystone/common/router.py @@ -11,14 +11,20 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + +from keystone.common import json_home from keystone.common import wsgi class Router(wsgi.ComposableRouter): - def __init__(self, controller, collection_key, key): + def __init__(self, controller, collection_key, key, + resource_descriptions=None, + is_entity_implemented=True): self.controller = controller self.key = key self.collection_key = collection_key + self._resource_descriptions = resource_descriptions + self._is_entity_implemented = is_entity_implemented def add_routes(self, mapper): collection_path = '/%(collection_key)s' % { @@ -52,3 +58,30 @@ class Router(wsgi.ComposableRouter): controller=self.controller, action='delete_%s' % self.key, conditions=dict(method=['DELETE'])) + + if self._resource_descriptions is not None: + # Add the collection resource and entity resource to the resource + # descriptions. + + collection_rel = json_home.build_v3_resource_relation( + self.collection_key) + self._resource_descriptions.append( + (collection_rel, + { + 'href': collection_path, + } + )) + + if self._is_entity_implemented: + entity_rel = json_home.build_v3_resource_relation(self.key) + id_str = '%s_id' % self.key + id_param_rel = json_home.build_v3_parameter_relation(id_str) + self._resource_descriptions.append( + (entity_rel, + { + 'href-template': entity_path, + 'href-vars': { + id_str: id_param_rel, + }, + } + )) diff --git a/keystone/credential/routers.py b/keystone/credential/routers.py index 36febbf6e..db3651f4b 100644 --- a/keystone/credential/routers.py +++ b/keystone/credential/routers.py @@ -24,4 +24,5 @@ class Routers(wsgi.RoutersBase): def append_v3_routers(self, mapper, routers): routers.append( router.Router(controllers.CredentialV3(), - 'credentials', 'credential')) + 'credentials', 'credential', + resource_descriptions=self.v3_resources)) diff --git a/keystone/identity/routers.py b/keystone/identity/routers.py index 222e87cf2..e274d6f44 100644 --- a/keystone/identity/routers.py +++ b/keystone/identity/routers.py @@ -35,7 +35,8 @@ class Routers(wsgi.RoutersBase): user_controller = controllers.UserV3() routers.append( router.Router(user_controller, - 'users', 'user')) + 'users', 'user', + resource_descriptions=self.v3_resources)) self._add_resource( mapper, user_controller, @@ -70,7 +71,8 @@ class Routers(wsgi.RoutersBase): group_controller = controllers.GroupV3() routers.append( router.Router(group_controller, - 'groups', 'group')) + 'groups', 'group', + resource_descriptions=self.v3_resources)) self._add_resource( mapper, group_controller, diff --git a/keystone/policy/routers.py b/keystone/policy/routers.py index d55ca26ab..5daadc815 100644 --- a/keystone/policy/routers.py +++ b/keystone/policy/routers.py @@ -20,4 +20,5 @@ class Routers(wsgi.RoutersBase): def append_v3_routers(self, mapper, routers): policy_controller = controllers.PolicyV3() - routers.append(router.Router(policy_controller, 'policies', 'policy')) + routers.append(router.Router(policy_controller, 'policies', 'policy', + resource_descriptions=self.v3_resources)) diff --git a/keystone/tests/test_versions.py b/keystone/tests/test_versions.py index 23fb0c26e..a4ef6e0d3 100644 --- a/keystone/tests/test_versions.py +++ b/keystone/tests/test_versions.py @@ -104,6 +104,9 @@ VERSIONS_RESPONSE = { } } +REVOCATIONS_RELATION = json_home.build_v3_extension_resource_relation( + 'OS-PKI', '1.0', 'revocations') + _build_trust_relation = functools.partial( json_home.build_v3_extension_resource_relation, extension_name='OS-TRUST', extension_version='1.0') @@ -120,6 +123,16 @@ V3_JSON_HOME_RESOURCES = { 'href': '/auth/projects'}, json_home.build_v3_resource_relation('auth_domains'): { 'href': '/auth/domains'}, + json_home.build_v3_resource_relation('credential'): { + 'href-template': '/credentials/{credential_id}', + 'href-vars': { + 'credential_id': + json_home.build_v3_parameter_relation('credential_id')}}, + json_home.build_v3_resource_relation('credentials'): { + 'href': '/credentials'}, + json_home.build_v3_resource_relation('domain'): { + 'href-template': '/domains/{domain_id}', + 'href-vars': {'domain_id': json_home.Parameters.DOMAIN_ID, }}, json_home.build_v3_resource_relation('domain_group_role'): { 'href-template': '/domains/{domain_id}/groups/{group_id}/roles/{role_id}', @@ -144,8 +157,15 @@ V3_JSON_HOME_RESOURCES = { 'href-vars': { 'domain_id': json_home.Parameters.DOMAIN_ID, 'user_id': json_home.Parameters.USER_ID, }}, - json_home.build_v3_extension_resource_relation('OS-PKI', '1.0', - 'revocations'): { + json_home.build_v3_resource_relation('domains'): {'href': '/domains'}, + json_home.build_v3_resource_relation('endpoint'): { + 'href-template': '/endpoints/{endpoint_id}', + 'href-vars': { + 'endpoint_id': + json_home.build_v3_parameter_relation('endpoint_id'), }}, + json_home.build_v3_resource_relation('endpoints'): { + 'href': '/endpoints'}, + REVOCATIONS_RELATION: { 'href': '/auth/tokens/OS-PKI/revoked'}, _build_trust_relation(resource_name='trust'): { @@ -161,6 +181,10 @@ V3_JSON_HOME_RESOURCES = { 'href-vars': {'trust_id': TRUST_ID_PARAMETER_RELATION, }}, _build_trust_relation(resource_name='trusts'): { 'href': '/OS-TRUST/trusts'}, + json_home.build_v3_resource_relation('group'): { + 'href-template': '/groups/{group_id}', + 'href-vars': { + 'group_id': json_home.Parameters.GROUP_ID, }}, json_home.build_v3_resource_relation('group_user'): { 'href-template': '/groups/{group_id}/users/{user_id}', 'href-vars': { @@ -169,6 +193,18 @@ V3_JSON_HOME_RESOURCES = { json_home.build_v3_resource_relation('group_users'): { 'href-template': '/groups/{group_id}/users', 'href-vars': {'group_id': json_home.Parameters.GROUP_ID, }}, + json_home.build_v3_resource_relation('groups'): {'href': '/groups'}, + json_home.build_v3_resource_relation('policies'): { + 'href': '/policies'}, + json_home.build_v3_resource_relation('policy'): { + 'href-template': '/policies/{policy_id}', + 'href-vars': { + 'policy_id': + json_home.build_v3_parameter_relation('policy_id'), }}, + json_home.build_v3_resource_relation('project'): { + 'href-template': '/projects/{project_id}', + 'href-vars': { + 'project_id': json_home.Parameters.PROJECT_ID, }}, json_home.build_v3_resource_relation('project_group_role'): { 'href-template': '/projects/{project_id}/groups/{group_id}/roles/{role_id}', @@ -193,6 +229,32 @@ V3_JSON_HOME_RESOURCES = { 'href-vars': { 'project_id': json_home.Parameters.PROJECT_ID, 'user_id': json_home.Parameters.USER_ID, }}, + json_home.build_v3_resource_relation('projects'): { + 'href': '/projects'}, + json_home.build_v3_resource_relation('region'): { + 'href-template': '/regions/{region_id}', + 'href-vars': { + 'region_id': + json_home.build_v3_parameter_relation('region_id'), }}, + json_home.build_v3_resource_relation('regions'): {'href': '/regions'}, + json_home.build_v3_resource_relation('role'): { + 'href-template': '/roles/{role_id}', + 'href-vars': { + 'role_id': json_home.Parameters.ROLE_ID, }}, + json_home.build_v3_resource_relation('role_assignments'): { + 'href': '/role_assignments'}, + json_home.build_v3_resource_relation('roles'): {'href': '/roles'}, + json_home.build_v3_resource_relation('service'): { + 'href-template': '/services/{service_id}', + 'href-vars': { + 'service_id': + json_home.build_v3_parameter_relation('service_id')}}, + json_home.build_v3_resource_relation('services'): { + 'href': '/services'}, + json_home.build_v3_resource_relation('user'): { + 'href-template': '/users/{user_id}', + 'href-vars': { + 'user_id': json_home.Parameters.USER_ID, }}, json_home.build_v3_resource_relation('user_change_password'): { 'href-template': '/users/{user_id}/password', 'href-vars': {'user_id': json_home.Parameters.USER_ID, }}, @@ -202,6 +264,7 @@ V3_JSON_HOME_RESOURCES = { json_home.build_v3_resource_relation('user_projects'): { 'href-template': '/users/{user_id}/projects', 'href-vars': {'user_id': json_home.Parameters.USER_ID, }}, + json_home.build_v3_resource_relation('users'): {'href': '/users'}, }