From dd70a5548ef4a110841474d264a82bba4a5cb76a Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Sat, 2 Aug 2014 16:15:21 -0500 Subject: [PATCH] Class for V3 router packages The V3 routes were being added by the append_v3_routers function in each controller package, so the only way state could be stored is in a global variable which makes unit testing difficult. With this change, the append_v3_routers functions are put into a class in each package. This will eventually be used to store JSON Home data. bp json-home Change-Id: I744a4c82dc84bb1a8d29d0314e3c51cc43c077a2 --- keystone/assignment/routers.py | 207 +++++++++++++++++---------------- keystone/auth/routers.py | 55 ++++----- keystone/catalog/routers.py | 41 ++++--- keystone/common/wsgi.py | 10 ++ keystone/credential/routers.py | 11 +- keystone/identity/routers.py | 68 +++++------ keystone/policy/routers.py | 9 +- keystone/service.py | 9 +- keystone/trust/routers.py | 55 ++++----- 9 files changed, 253 insertions(+), 212 deletions(-) diff --git a/keystone/assignment/routers.py b/keystone/assignment/routers.py index 74d3baed59..98c54e3426 100644 --- a/keystone/assignment/routers.py +++ b/keystone/assignment/routers.py @@ -55,128 +55,139 @@ class Admin(wsgi.ComposableRouter): conditions=dict(method=['GET'])) -def append_v3_routers(mapper, routers): - routers.append( - router.Router(controllers.DomainV3(), - 'domains', 'domain')) +class Routers(wsgi.RoutersBase): - project_controller = controllers.ProjectV3() - routers.append( - router.Router(project_controller, - 'projects', 'project')) - mapper.connect('/users/{user_id}/projects', - controller=project_controller, - action='list_user_projects', - conditions=dict(method=['GET'])) + def append_v3_routers(self, mapper, routers): + routers.append( + router.Router(controllers.DomainV3(), + 'domains', 'domain')) - role_controller = controllers.RoleV3() - routers.append(router.Router(role_controller, 'roles', 'role')) - mapper.connect('/projects/{project_id}/users/{user_id}/roles/{role_id}', - controller=role_controller, - action='create_grant', - conditions=dict(method=['PUT'])) - mapper.connect('/projects/{project_id}/groups/{group_id}/roles/{role_id}', - controller=role_controller, - action='create_grant', - conditions=dict(method=['PUT'])) - mapper.connect('/projects/{project_id}/users/{user_id}/roles/{role_id}', - controller=role_controller, - action='check_grant', - conditions=dict(method=['GET', 'HEAD'])) - mapper.connect('/projects/{project_id}/groups/{group_id}/roles/{role_id}', - controller=role_controller, - action='check_grant', - conditions=dict(method=['GET', 'HEAD'])) - mapper.connect('/projects/{project_id}/users/{user_id}/roles', - controller=role_controller, - action='list_grants', - conditions=dict(method=['GET'])) - mapper.connect('/projects/{project_id}/groups/{group_id}/roles', - controller=role_controller, - action='list_grants', - conditions=dict(method=['GET'])) - mapper.connect('/projects/{project_id}/users/{user_id}/roles/{role_id}', - controller=role_controller, - action='revoke_grant', - conditions=dict(method=['DELETE'])) - mapper.connect('/projects/{project_id}/groups/{group_id}/roles/{role_id}', - controller=role_controller, - action='revoke_grant', - conditions=dict(method=['DELETE'])) - mapper.connect('/domains/{domain_id}/users/{user_id}/roles/{role_id}', - controller=role_controller, - action='create_grant', - conditions=dict(method=['PUT'])) - mapper.connect('/domains/{domain_id}/groups/{group_id}/roles/{role_id}', - controller=role_controller, - action='create_grant', - conditions=dict(method=['PUT'])) - mapper.connect('/domains/{domain_id}/users/{user_id}/roles/{role_id}', - controller=role_controller, - action='check_grant', - conditions=dict(method=['GET', 'HEAD'])) - mapper.connect('/domains/{domain_id}/groups/{group_id}/roles/{role_id}', - controller=role_controller, - action='check_grant', - conditions=dict(method=['GET', 'HEAD'])) - mapper.connect('/domains/{domain_id}/users/{user_id}/roles', - controller=role_controller, - action='list_grants', - conditions=dict(method=['GET'])) - mapper.connect('/domains/{domain_id}/groups/{group_id}/roles', - controller=role_controller, - action='list_grants', - conditions=dict(method=['GET'])) - mapper.connect('/domains/{domain_id}/users/{user_id}/roles/{role_id}', - controller=role_controller, - action='revoke_grant', - conditions=dict(method=['DELETE'])) - mapper.connect('/domains/{domain_id}/groups/{group_id}/roles/{role_id}', - controller=role_controller, - action='revoke_grant', - conditions=dict(method=['DELETE'])) + project_controller = controllers.ProjectV3() + routers.append( + router.Router(project_controller, + 'projects', 'project')) + mapper.connect('/users/{user_id}/projects', + controller=project_controller, + action='list_user_projects', + conditions=dict(method=['GET'])) - if config.CONF.os_inherit.enabled: - mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' - '/roles/{role_id}/inherited_to_projects'), + role_controller = controllers.RoleV3() + routers.append(router.Router(role_controller, 'roles', 'role')) + mapper.connect('/projects/{project_id}/users/{user_id}/roles/' + '{role_id}', controller=role_controller, action='create_grant', conditions=dict(method=['PUT'])) - mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' - '/roles/{role_id}/inherited_to_projects'), + mapper.connect('/projects/{project_id}/groups/{group_id}/roles/' + '{role_id}', controller=role_controller, action='create_grant', conditions=dict(method=['PUT'])) - mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' - '/roles/{role_id}/inherited_to_projects'), + mapper.connect('/projects/{project_id}/users/{user_id}/roles/' + '{role_id}', controller=role_controller, action='check_grant', conditions=dict(method=['GET', 'HEAD'])) - mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' - '/roles/{role_id}/inherited_to_projects'), + mapper.connect('/projects/{project_id}/groups/{group_id}/roles/' + '{role_id}', controller=role_controller, action='check_grant', conditions=dict(method=['GET', 'HEAD'])) - mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' - '/roles/inherited_to_projects'), + mapper.connect('/projects/{project_id}/users/{user_id}/roles', controller=role_controller, action='list_grants', conditions=dict(method=['GET'])) - mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' - '/roles/inherited_to_projects'), + mapper.connect('/projects/{project_id}/groups/{group_id}/roles', controller=role_controller, action='list_grants', conditions=dict(method=['GET'])) - mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' - '/roles/{role_id}/inherited_to_projects'), + mapper.connect('/projects/{project_id}/users/{user_id}/roles/' + '{role_id}', controller=role_controller, action='revoke_grant', conditions=dict(method=['DELETE'])) - mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' - '/roles/{role_id}/inherited_to_projects'), + mapper.connect('/projects/{project_id}/groups/{group_id}/roles/' + '{role_id}', controller=role_controller, action='revoke_grant', conditions=dict(method=['DELETE'])) - routers.append( - router.Router(controllers.RoleAssignmentV3(), - 'role_assignments', 'role_assignment')) + mapper.connect('/domains/{domain_id}/users/{user_id}/roles/{role_id}', + controller=role_controller, + action='create_grant', + conditions=dict(method=['PUT'])) + mapper.connect('/domains/{domain_id}/groups/{group_id}/roles/' + '{role_id}', + controller=role_controller, + action='create_grant', + conditions=dict(method=['PUT'])) + mapper.connect('/domains/{domain_id}/users/{user_id}/roles/{role_id}', + controller=role_controller, + action='check_grant', + conditions=dict(method=['GET', 'HEAD'])) + mapper.connect('/domains/{domain_id}/groups/{group_id}/roles/' + '{role_id}', + controller=role_controller, + action='check_grant', + conditions=dict(method=['GET', 'HEAD'])) + mapper.connect('/domains/{domain_id}/users/{user_id}/roles', + controller=role_controller, + action='list_grants', + conditions=dict(method=['GET'])) + mapper.connect('/domains/{domain_id}/groups/{group_id}/roles', + controller=role_controller, + action='list_grants', + conditions=dict(method=['GET'])) + mapper.connect('/domains/{domain_id}/users/{user_id}/roles/{role_id}', + controller=role_controller, + action='revoke_grant', + conditions=dict(method=['DELETE'])) + mapper.connect('/domains/{domain_id}/groups/{group_id}/roles/' + '{role_id}', + controller=role_controller, + action='revoke_grant', + conditions=dict(method=['DELETE'])) + + if config.CONF.os_inherit.enabled: + mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='create_grant', + conditions=dict(method=['PUT'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='create_grant', + conditions=dict(method=['PUT'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='check_grant', + conditions=dict(method=['GET', 'HEAD'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='check_grant', + conditions=dict(method=['GET', 'HEAD'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' + '/roles/inherited_to_projects'), + controller=role_controller, + action='list_grants', + conditions=dict(method=['GET'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' + '/roles/inherited_to_projects'), + controller=role_controller, + action='list_grants', + conditions=dict(method=['GET'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/users/{user_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='revoke_grant', + conditions=dict(method=['DELETE'])) + mapper.connect(('/OS-INHERIT/domains/{domain_id}/groups/{group_id}' + '/roles/{role_id}/inherited_to_projects'), + controller=role_controller, + action='revoke_grant', + conditions=dict(method=['DELETE'])) + routers.append( + router.Router(controllers.RoleAssignmentV3(), + 'role_assignments', 'role_assignment')) diff --git a/keystone/auth/routers.py b/keystone/auth/routers.py index 9ec2227848..052baa7b62 100644 --- a/keystone/auth/routers.py +++ b/keystone/auth/routers.py @@ -13,32 +13,35 @@ # under the License. from keystone.auth import controllers +from keystone.common import wsgi -def append_v3_routers(mapper, routers): - auth_controller = controllers.Auth() +class Routers(wsgi.RoutersBase): - mapper.connect('/auth/tokens', - controller=auth_controller, - action='authenticate_for_token', - conditions=dict(method=['POST'])) - # NOTE(morganfainberg): For policy enforcement reasons, the - # ``validate_token_head`` method is still used for HEAD requests. - # The controller method makes the same call as the validate_token - # call and lets wsgi.render_response remove the body data. - mapper.connect('/auth/tokens', - controller=auth_controller, - action='check_token', - conditions=dict(method=['HEAD'])) - mapper.connect('/auth/tokens', - controller=auth_controller, - action='revoke_token', - conditions=dict(method=['DELETE'])) - mapper.connect('/auth/tokens', - controller=auth_controller, - action='validate_token', - conditions=dict(method=['GET'])) - mapper.connect('/auth/tokens/OS-PKI/revoked', - controller=auth_controller, - action='revocation_list', - conditions=dict(method=['GET'])) + def append_v3_routers(self, mapper, routers): + auth_controller = controllers.Auth() + + mapper.connect('/auth/tokens', + controller=auth_controller, + action='authenticate_for_token', + conditions=dict(method=['POST'])) + # NOTE(morganfainberg): For policy enforcement reasons, the + # ``validate_token_head`` method is still used for HEAD requests. + # The controller method makes the same call as the validate_token + # call and lets wsgi.render_response remove the body data. + mapper.connect('/auth/tokens', + controller=auth_controller, + action='check_token', + conditions=dict(method=['HEAD'])) + mapper.connect('/auth/tokens', + controller=auth_controller, + action='revoke_token', + conditions=dict(method=['DELETE'])) + mapper.connect('/auth/tokens', + controller=auth_controller, + action='validate_token', + conditions=dict(method=['GET'])) + mapper.connect('/auth/tokens/OS-PKI/revoked', + controller=auth_controller, + action='revocation_list', + conditions=dict(method=['GET'])) diff --git a/keystone/catalog/routers.py b/keystone/catalog/routers.py index 69b5d6b291..cd7b7c7833 100644 --- a/keystone/catalog/routers.py +++ b/keystone/catalog/routers.py @@ -14,27 +14,30 @@ from keystone.catalog import controllers from keystone.common import router +from keystone.common import wsgi -def append_v3_routers(mapper, routers): - regions_controller = controllers.RegionV3() - routers.append(router.Router(regions_controller, - 'regions', 'region')) +class Routers(wsgi.RoutersBase): - # Need to add an additional route to support PUT /regions/{region_id} - mapper.connect( - '/regions/{region_id}', - controller=regions_controller, - action='create_region_with_id', - conditions=dict(method=['PUT'])) + def append_v3_routers(self, mapper, routers): + regions_controller = controllers.RegionV3() + routers.append(router.Router(regions_controller, + 'regions', 'region')) - routers.append(router.Router(controllers.ServiceV3(), - 'services', 'service')) - routers.append(router.Router(controllers.EndpointV3(), - 'endpoints', 'endpoint')) + # Need to add an additional route to support PUT /regions/{region_id} + mapper.connect( + '/regions/{region_id}', + controller=regions_controller, + action='create_region_with_id', + conditions=dict(method=['PUT'])) - mapper.connect( - '/catalog', - controller=controllers.CatalogV3(), - action='get_catalog', - conditions=dict(method=['GET'])) + routers.append(router.Router(controllers.ServiceV3(), + 'services', 'service')) + routers.append(router.Router(controllers.EndpointV3(), + 'endpoints', 'endpoint')) + + mapper.connect( + '/catalog', + controller=controllers.CatalogV3(), + action='get_catalog', + conditions=dict(method=['GET'])) diff --git a/keystone/common/wsgi.py b/keystone/common/wsgi.py index 32980ad247..412e500c90 100644 --- a/keystone/common/wsgi.py +++ b/keystone/common/wsgi.py @@ -604,6 +604,16 @@ class ExtensionRouter(Router): return _factory +class RoutersBase(object): + """Base class for Routers.""" + + def append_v3_routers(self, mapper, routers): + """Append v3 routers. + + Subclasses should override this method to map its routes. + """ + + def render_response(body=None, status=None, headers=None, method=None): """Forms a WSGI response.""" if headers is None: diff --git a/keystone/credential/routers.py b/keystone/credential/routers.py index 75cd334316..36febbf6ee 100644 --- a/keystone/credential/routers.py +++ b/keystone/credential/routers.py @@ -15,10 +15,13 @@ """WSGI Routers for the Credentials service.""" from keystone.common import router +from keystone.common import wsgi from keystone.credential import controllers -def append_v3_routers(mapper, routers): - routers.append( - router.Router(controllers.CredentialV3(), - 'credentials', 'credential')) +class Routers(wsgi.RoutersBase): + + def append_v3_routers(self, mapper, routers): + routers.append( + router.Router(controllers.CredentialV3(), + 'credentials', 'credential')) diff --git a/keystone/identity/routers.py b/keystone/identity/routers.py index a892b0c45c..a8b2ea754c 100644 --- a/keystone/identity/routers.py +++ b/keystone/identity/routers.py @@ -27,41 +27,43 @@ class Admin(wsgi.ComposableRouter): conditions=dict(method=['GET'])) -def append_v3_routers(mapper, routers): - user_controller = controllers.UserV3() - routers.append( - router.Router(user_controller, - 'users', 'user')) - mapper.connect('/users/{user_id}/password', - controller=user_controller, - action='change_password', - conditions=dict(method=['POST'])) +class Routers(wsgi.RoutersBase): - mapper.connect('/groups/{group_id}/users', - controller=user_controller, - action='list_users_in_group', - conditions=dict(method=['GET'])) + def append_v3_routers(self, mapper, routers): + user_controller = controllers.UserV3() + routers.append( + router.Router(user_controller, + 'users', 'user')) + mapper.connect('/users/{user_id}/password', + controller=user_controller, + action='change_password', + conditions=dict(method=['POST'])) - mapper.connect('/groups/{group_id}/users/{user_id}', - controller=user_controller, - action='add_user_to_group', - conditions=dict(method=['PUT'])) + mapper.connect('/groups/{group_id}/users', + controller=user_controller, + action='list_users_in_group', + conditions=dict(method=['GET'])) - mapper.connect('/groups/{group_id}/users/{user_id}', - controller=user_controller, - action='check_user_in_group', - conditions=dict(method=['GET', 'HEAD'])) + mapper.connect('/groups/{group_id}/users/{user_id}', + controller=user_controller, + action='add_user_to_group', + conditions=dict(method=['PUT'])) - mapper.connect('/groups/{group_id}/users/{user_id}', - controller=user_controller, - action='remove_user_from_group', - conditions=dict(method=['DELETE'])) + mapper.connect('/groups/{group_id}/users/{user_id}', + controller=user_controller, + action='check_user_in_group', + conditions=dict(method=['GET', 'HEAD'])) - group_controller = controllers.GroupV3() - routers.append( - router.Router(group_controller, - 'groups', 'group')) - mapper.connect('/users/{user_id}/groups', - controller=group_controller, - action='list_groups_for_user', - conditions=dict(method=['GET'])) + mapper.connect('/groups/{group_id}/users/{user_id}', + controller=user_controller, + action='remove_user_from_group', + conditions=dict(method=['DELETE'])) + + group_controller = controllers.GroupV3() + routers.append( + router.Router(group_controller, + 'groups', 'group')) + mapper.connect('/users/{user_id}/groups', + controller=group_controller, + action='list_groups_for_user', + conditions=dict(method=['GET'])) diff --git a/keystone/policy/routers.py b/keystone/policy/routers.py index 96a524bd79..d55ca26ab2 100644 --- a/keystone/policy/routers.py +++ b/keystone/policy/routers.py @@ -12,9 +12,12 @@ # License for the specific language governing permissions and limitations # under the License. from keystone.common import router +from keystone.common import wsgi from keystone.policy import controllers -def append_v3_routers(mapper, routers): - policy_controller = controllers.PolicyV3() - routers.append(router.Router(policy_controller, 'policies', 'policy')) +class Routers(wsgi.RoutersBase): + + def append_v3_routers(self, mapper, routers): + policy_controller = controllers.PolicyV3() + routers.append(router.Router(policy_controller, 'policies', 'policy')) diff --git a/keystone/service.py b/keystone/service.py index f5514c0e89..48f8872bf9 100644 --- a/keystone/service.py +++ b/keystone/service.py @@ -89,11 +89,14 @@ def v3_app_factory(global_conf, **local_conf): controllers.register_version('v3') mapper = routes.Mapper() v3routers = [] - for module in [assignment, auth, catalog, credential, identity, policy]: - module.routers.append_v3_routers(mapper, v3routers) + router_modules = [assignment, auth, catalog, credential, identity, policy] if CONF.trust.enabled: - trust.routers.append_v3_routers(mapper, v3routers) + router_modules.append(trust) + + for module in router_modules: + routers_instance = module.routers.Routers() + routers_instance.append_v3_routers(mapper, v3routers) # Add in the v3 version api v3routers.append(routers.VersionV3('admin')) diff --git a/keystone/trust/routers.py b/keystone/trust/routers.py index 5f3c66f4b4..493bc5d433 100644 --- a/keystone/trust/routers.py +++ b/keystone/trust/routers.py @@ -13,38 +13,41 @@ # under the License. """WSGI Routers for the Identity service.""" +from keystone.common import wsgi from keystone.trust import controllers -def append_v3_routers(mapper, routers): - trust_controller = controllers.TrustV3() +class Routers(wsgi.RoutersBase): - mapper.connect('/OS-TRUST/trusts', - controller=trust_controller, - action='create_trust', - conditions=dict(method=['POST'])) + def append_v3_routers(self, mapper, routers): + trust_controller = controllers.TrustV3() - mapper.connect('/OS-TRUST/trusts', - controller=trust_controller, - action='list_trusts', - conditions=dict(method=['GET'])) + mapper.connect('/OS-TRUST/trusts', + controller=trust_controller, + action='create_trust', + conditions=dict(method=['POST'])) - mapper.connect('/OS-TRUST/trusts/{trust_id}', - controller=trust_controller, - action='delete_trust', - conditions=dict(method=['DELETE'])) + mapper.connect('/OS-TRUST/trusts', + controller=trust_controller, + action='list_trusts', + conditions=dict(method=['GET'])) - mapper.connect('/OS-TRUST/trusts/{trust_id}', - controller=trust_controller, - action='get_trust', - conditions=dict(method=['GET'])) + mapper.connect('/OS-TRUST/trusts/{trust_id}', + controller=trust_controller, + action='delete_trust', + conditions=dict(method=['DELETE'])) - mapper.connect('/OS-TRUST/trusts/{trust_id}/roles', - controller=trust_controller, - action='list_roles_for_trust', - conditions=dict(method=['GET'])) + mapper.connect('/OS-TRUST/trusts/{trust_id}', + controller=trust_controller, + action='get_trust', + conditions=dict(method=['GET'])) - mapper.connect('/OS-TRUST/trusts/{trust_id}/roles/{role_id}', - controller=trust_controller, - action='get_role_for_trust', - conditions=dict(method=['GET', 'HEAD'])) + mapper.connect('/OS-TRUST/trusts/{trust_id}/roles', + controller=trust_controller, + action='list_roles_for_trust', + conditions=dict(method=['GET'])) + + mapper.connect('/OS-TRUST/trusts/{trust_id}/roles/{role_id}', + controller=trust_controller, + action='get_role_for_trust', + conditions=dict(method=['GET', 'HEAD']))