Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

module refactoring

Distributes the functionality of service.py into the modules.
Moves ComposableRouters into the modules.
The routers and controllers now have short names.
The controllers get their APIs via the base class.

Change-Id:  I87404b80ea9800d6792f97a7a3a64fe839065c1c
  • Loading branch information...
commit fb963a560939e6be8c98d74e5555de7283173e32 1 parent 44e3c3e
Adam Young authored
View
1  keystone/catalog/__init__.py
@@ -16,3 +16,4 @@
from keystone.catalog.core import *
from keystone.catalog import controllers
+from keystone.catalog import routers
View
20 keystone/catalog/controllers.py
@@ -20,18 +20,9 @@
from keystone.catalog import core
from keystone.common import controller
from keystone.common import wsgi
-from keystone import identity
-from keystone import policy
-from keystone import token
-class Service(wsgi.Application):
- def __init__(self):
- self.catalog_api = core.Manager()
- self.identity_api = identity.Manager()
- self.policy_api = policy.Manager()
- self.token_api = token.Manager()
- super(Service, self).__init__()
+class Service(controller.V2Controller):
def get_services(self, context):
self.assert_admin(context)
@@ -57,14 +48,7 @@ def create_service(self, context, OS_KSADM_service):
return {'OS-KSADM:service': new_service_ref}
-class Endpoint(wsgi.Application):
- def __init__(self):
- self.catalog_api = core.Manager()
- self.identity_api = identity.Manager()
- self.policy_api = policy.Manager()
- self.token_api = token.Manager()
- super(Endpoint, self).__init__()
-
+class Endpoint(controller.V2Controller):
def get_endpoints(self, context):
self.assert_admin(context)
endpoint_list = self.catalog_api.list_endpoints(context)
View
25 keystone/catalog/routers.py
@@ -0,0 +1,25 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# 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.catalog import controllers
+from keystone.common import router
+from keystone.common import wsgi
+
+
+def append_v3_routers(mapper, routers, apis):
+ routers.append(router.Router(controllers.ServiceV3(**apis),
+ 'services', 'service'))
+ routers.append(router.Router(controllers.EndpointV3(**apis),
+ 'endpoints', 'endpoint'))
View
57 keystone/common/router.py
@@ -0,0 +1,57 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# 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 wsgi
+from keystone import config
+
+
+class Router(wsgi.ComposableRouter):
+ def __init__(self, controller, collection_key, key):
+ self.controller = controller
+ self.key = key
+ self.collection_key = collection_key
+
+ def add_routes(self, mapper):
+ collection_path = '/%(collection_key)s' % {
+ 'collection_key': self.collection_key}
+ entity_path = '/%(collection_key)s/{%(key)s_id}' % {
+ 'collection_key': self.collection_key,
+ 'key': self.key}
+
+ mapper.connect(
+ collection_path,
+ controller=self.controller,
+ action='create_%s' % self.key,
+ conditions=dict(method=['POST']))
+ mapper.connect(
+ collection_path,
+ controller=self.controller,
+ action='list_%s' % self.collection_key,
+ conditions=dict(method=['GET']))
+ mapper.connect(
+ entity_path,
+ controller=self.controller,
+ action='get_%s' % self.key,
+ conditions=dict(method=['GET']))
+ mapper.connect(
+ entity_path,
+ controller=self.controller,
+ action='update_%s' % self.key,
+ conditions=dict(method=['PATCH']))
+ mapper.connect(
+ entity_path,
+ controller=self.controller,
+ action='delete_%s' % self.key,
+ conditions=dict(method=['DELETE']))
View
18 keystone/contrib/admin_crud/core.py
@@ -13,10 +13,11 @@
# 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 import catalog
from keystone.common import wsgi
from keystone import identity
+from keystone import policy
+from keystone import token
class CrudExtension(wsgi.ExtensionRouter):
@@ -27,11 +28,16 @@ class CrudExtension(wsgi.ExtensionRouter):
"""
def add_routes(self, mapper):
- tenant_controller = identity.controllers.Tenant()
- user_controller = identity.controllers.User()
- role_controller = identity.controllers.Role()
- service_controller = catalog.controllers.Service()
- endpoint_controller = catalog.controllers.Endpoint()
+ apis = dict(catalog_api=catalog.Manager(),
+ identity_api=identity.Manager(),
+ policy_api=policy.Manager(),
+ token_api=token.Manager())
+
+ tenant_controller = identity.controllers.Tenant(**apis)
+ user_controller = identity.controllers.User(**apis)
+ role_controller = identity.controllers.Role(**apis)
+ service_controller = catalog.controllers.Service(**apis)
+ endpoint_controller = catalog.controllers.Endpoint(**apis)
# Tenant Operations
mapper.connect(
View
23 keystone/contrib/user_crud/core.py
@@ -18,21 +18,19 @@
import uuid
from keystone import exception
+from keystone.common import controller
from keystone.common import logging
from keystone.common import wsgi
+from keystone import catalog
from keystone import identity
+from keystone import policy
from keystone import token
LOG = logging.getLogger(__name__)
-class UserController(wsgi.Application):
- def __init__(self):
- self.identity_api = identity.Manager()
- self.token_api = token.Manager()
- self.user_controller = identity.controllers.User()
-
+class UserController(identity.controllers.User):
def set_user_password(self, context, user_id, user):
token_id = context.get('token_id')
original_password = user.get('original_password')
@@ -62,9 +60,9 @@ def set_user_password(self, context, user_id, user):
admin_context = copy.copy(context)
admin_context['is_admin'] = True
- self.user_controller.set_user_password(admin_context,
- user_id,
- update_dict)
+ super(UserController, self).set_user_password(admin_context,
+ user_id,
+ update_dict)
token_id = uuid.uuid4().hex
new_token_ref = copy.copy(token_ref)
@@ -83,7 +81,12 @@ class CrudExtension(wsgi.ExtensionRouter):
"""
def add_routes(self, mapper):
- user_controller = UserController()
+ apis = dict(catalog_api=catalog.Manager(),
+ identity_api=identity.Manager(),
+ policy_api=policy.Manager(),
+ token_api=token.Manager())
+
+ user_controller = UserController(**apis)
mapper.connect('/OS-KSCRUD/users/{user_id}',
controller=user_controller,
View
144 keystone/controllers.py
@@ -0,0 +1,144 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# 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 wsgi
+from keystone import catalog
+from keystone import exception
+
+
+class Extensions(wsgi.Application):
+ """Base extensions controller to be extended by public and admin API's."""
+
+ def __init__(self, extensions=None):
+ super(Extensions, self).__init__()
+
+ self.extensions = extensions or {}
+
+ def get_extensions_info(self, context):
+ return {'extensions': {'values': self.extensions.values()}}
+
+ def get_extension_info(self, context, extension_alias):
+ try:
+ return {'extension': self.extensions[extension_alias]}
+ except KeyError:
+ raise exception.NotFound(target=extension_alias)
+
+
+class AdminExtensions(Extensions):
+ def __init__(self, *args, **kwargs):
+ super(AdminExtensions, self).__init__(*args, **kwargs)
+
+ # TODO(dolph): Extensions should obviously provide this information
+ # themselves, but hardcoding it here allows us to match
+ # the API spec in the short term with minimal complexity.
+ self.extensions['OS-KSADM'] = {
+ 'name': 'Openstack Keystone Admin',
+ 'namespace': 'http://docs.openstack.org/identity/api/ext/'
+ 'OS-KSADM/v1.0',
+ 'alias': 'OS-KSADM',
+ 'updated': '2011-08-19T13:25:27-06:00',
+ 'description': 'Openstack extensions to Keystone v2.0 API '
+ 'enabling Admin Operations.',
+ 'links': [
+ {
+ 'rel': 'describedby',
+ # TODO(dolph): link needs to be revised after
+ # bug 928059 merges
+ 'type': 'text/html',
+ 'href': 'https://github.com/openstack/identity-api',
+ }
+ ]
+ }
+
+
+class PublicExtensions(Extensions):
+ pass
+
+
+class Version(wsgi.Application):
+ def __init__(self, version_type):
+ self.catalog_api = catalog.Manager()
+ self.url_key = '%sURL' % version_type
+
+ super(Version, self).__init__()
+
+ def _get_identity_url(self, context):
+ catalog_ref = self.catalog_api.get_catalog(context=context,
+ user_id=None,
+ tenant_id=None)
+ for region, region_ref in catalog_ref.iteritems():
+ for service, service_ref in region_ref.iteritems():
+ if service == 'identity':
+ return service_ref[self.url_key]
+
+ raise exception.NotImplemented()
+
+ def _get_versions_list(self, context):
+ """The list of versions is dependent on the context."""
+ identity_url = self._get_identity_url(context)
+ if not identity_url.endswith('/'):
+ identity_url = identity_url + '/'
+
+ versions = {}
+ versions['v2.0'] = {
+ 'id': 'v2.0',
+ 'status': 'beta',
+ 'updated': '2011-11-19T00:00:00Z',
+ 'links': [
+ {
+ 'rel': 'self',
+ 'href': identity_url,
+ }, {
+ 'rel': 'describedby',
+ 'type': 'text/html',
+ 'href': 'http://docs.openstack.org/api/openstack-'
+ 'identity-service/2.0/content/'
+ }, {
+ 'rel': 'describedby',
+ 'type': 'application/pdf',
+ 'href': 'http://docs.openstack.org/api/openstack-'
+ 'identity-service/2.0/identity-dev-guide-'
+ '2.0.pdf'
+ }
+ ],
+ 'media-types': [
+ {
+ 'base': 'application/json',
+ 'type': 'application/vnd.openstack.identity-v2.0'
+ '+json'
+ }, {
+ 'base': 'application/xml',
+ 'type': 'application/vnd.openstack.identity-v2.0'
+ '+xml'
+ }
+ ]
+ }
+
+ return versions
+
+ def get_versions(self, context):
+ versions = self._get_versions_list(context)
+ return wsgi.render_response(status=(300, 'Multiple Choices'), body={
+ 'versions': {
+ 'values': versions.values()
+ }
+ })
+
+ def get_version(self, context):
+ versions = self._get_versions_list(context)
+ return wsgi.render_response(body={
+ 'version': versions['v2.0']
+ })
View
24 keystone/identity/controllers.py
@@ -32,13 +32,7 @@
LOG = logging.getLogger(__name__)
-class Tenant(wsgi.Application):
- def __init__(self):
- self.identity_api = core.Manager()
- self.policy_api = policy.Manager()
- self.token_api = token.Manager()
- super(Tenant, self).__init__()
-
+class Tenant(controller.V2Controller):
def get_all_tenants(self, context, **kw):
"""Gets a list of all tenants for an admin user."""
if 'name' in context['query_string']:
@@ -157,13 +151,7 @@ def _format_tenant_list(self, tenant_refs, **kwargs):
return o
-class User(wsgi.Application):
- def __init__(self):
- self.identity_api = core.Manager()
- self.policy_api = policy.Manager()
- self.token_api = token.Manager()
- super(User, self).__init__()
-
+class User(controller.V2Controller):
def get_user(self, context, user_id):
self.assert_admin(context)
return {'user': self.identity_api.get_user(context, user_id)}
@@ -240,13 +228,7 @@ def update_user_tenant(self, context, user_id, user):
return self.update_user(context, user_id, user)
-class Role(wsgi.Application):
- def __init__(self):
- self.identity_api = core.Manager()
- self.token_api = token.Manager()
- self.policy_api = policy.Manager()
- super(Role, self).__init__()
-
+class Role(controller.V2Controller):
# COMPAT(essex-3)
def get_user_roles(self, context, user_id, tenant_id=None):
"""Get the roles for a user and tenant pair.
View
73 keystone/identity/routers.py
@@ -13,16 +13,19 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
-
"""WSGI Routers for the Identity service."""
-
from keystone.common import wsgi
from keystone.identity import controllers
+from keystone.common import router
class Public(wsgi.ComposableRouter):
+ def __init__(self, apis):
+ self.apis = apis
+ super(Public, self).__init__()
+
def add_routes(self, mapper):
- tenant_controller = controllers.Tenant()
+ tenant_controller = controllers.Tenant(**self.apis)
mapper.connect('/tenants',
controller=tenant_controller,
action='get_tenants_for_token',
@@ -30,9 +33,13 @@ def add_routes(self, mapper):
class Admin(wsgi.ComposableRouter):
+ def __init__(self, apis):
+ self.apis = apis
+ super(Admin, self).__init__()
+
def add_routes(self, mapper):
# Tenant Operations
- tenant_controller = controllers.Tenant()
+ tenant_controller = controllers.Tenant(**self.apis)
mapper.connect('/tenants',
controller=tenant_controller,
action='get_all_tenants',
@@ -43,14 +50,14 @@ def add_routes(self, mapper):
conditions=dict(method=['GET']))
# User Operations
- user_controller = controllers.User()
+ user_controller = controllers.User(**self.apis)
mapper.connect('/users/{user_id}',
controller=user_controller,
action='get_user',
conditions=dict(method=['GET']))
# Role Operations
- roles_controller = controllers.Role()
+ roles_controller = controllers.Role(**self.apis)
mapper.connect('/tenants/{tenant_id}/users/{user_id}/roles',
controller=roles_controller,
action='get_user_roles',
@@ -59,3 +66,57 @@ def add_routes(self, mapper):
controller=roles_controller,
action='get_user_roles',
conditions=dict(method=['GET']))
+
+
+def append_v3_routers(mapper, routers, apis):
+ routers.append(
+ router.Router(controllers.DomainV3(**apis),
+ 'domains', 'domain'))
+ project_controller = controllers.ProjectV3(**apis)
+ 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']))
+ routers.append(
+ router.Router(controllers.UserV3(**apis),
+ 'users', 'user'))
+ routers.append(
+ router.Router(controllers.CredentialV3(**apis),
+ 'credentials', 'credential'))
+ role_controller = controllers.RoleV3(**apis)
+ 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}/users/{user_id}/roles/{role_id}',
+ controller=role_controller,
+ action='check_grant',
+ conditions=dict(method=['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}/users/{user_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}/users/{user_id}/roles/{role_id}',
+ controller=role_controller,
+ action='check_grant',
+ conditions=dict(method=['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}/users/{user_id}/roles/{role_id}',
+ controller=role_controller,
+ action='revoke_grant',
+ conditions=dict(method=['DELETE']))
View
1  keystone/policy/__init__.py
@@ -16,3 +16,4 @@
from keystone.policy.core import *
from keystone.policy import controllers
+from keystone.policy import routers
View
22 keystone/policy/routers.py
@@ -0,0 +1,22 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# 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.policy import controllers
+from keystone.common import router
+
+
+def append_v3_routers(mapper, routers, apis):
+ policy_controller = controllers.PolicyV3(**apis)
+ routers.append(router.Router(policy_controller, 'policies', 'policy'))
View
68 keystone/routers.py
@@ -0,0 +1,68 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+"""
+The only types of routers in this file should be ComposingRouters.
+The routers for the submodules should be in the module specific router files
+for example, the Composable Router for identity belongs in
+keystone/identity/routers.py
+"""
+
+
+from keystone.common import wsgi
+from keystone import catalog
+from keystone import controllers
+from keystone import exception
+
+
+class Extension(wsgi.ComposableRouter):
+ def __init__(self, is_admin=True):
+ if is_admin:
+ self.controller = controllers.AdminExtensions()
+ else:
+ self.controller = controllers.PublicExtensions()
+
+ def add_routes(self, mapper):
+ extensions_controller = self.controller
+ mapper.connect('/extensions',
+ controller=extensions_controller,
+ action='get_extensions_info',
+ conditions=dict(method=['GET']))
+ mapper.connect('/extensions/{extension_alias}',
+ controller=extensions_controller,
+ action='get_extension_info',
+ conditions=dict(method=['GET']))
+
+
+class Version(wsgi.ComposableRouter):
+ def __init__(self, description):
+ self.description = description
+
+ def add_routes(self, mapper):
+ version_controller = controllers.Version(self.description)
+ mapper.connect('/',
+ controller=version_controller,
+ action='get_version')
+
+
+class Versions(wsgi.ComposableRouter):
+ def __init__(self, description):
+ self.description = description
+
+ def add_routes(self, mapper):
+ version_controller = controllers.Version(self.description)
+ mapper.connect('/',
+ controller=version_controller,
+ action='get_versions')
View
472 keystone/service.py
@@ -22,484 +22,64 @@
from keystone import exception
from keystone import identity
from keystone import policy
+from keystone import routers
from keystone import token
-
LOG = logging.getLogger(__name__)
-class V3Router(wsgi.ComposingRouter):
- def crud_routes(self, mapper, controller, collection_key, key):
- collection_path = '/%(collection_key)s' % {
- 'collection_key': collection_key}
- entity_path = '/%(collection_key)s/{%(key)s_id}' % {
- 'collection_key': collection_key,
- 'key': key}
-
- mapper.connect(
- collection_path,
- controller=controller,
- action='create_%s' % key,
- conditions=dict(method=['POST']))
- mapper.connect(
- collection_path,
- controller=controller,
- action='list_%s' % collection_key,
- conditions=dict(method=['GET']))
- mapper.connect(
- entity_path,
- controller=controller,
- action='get_%s' % key,
- conditions=dict(method=['GET']))
- mapper.connect(
- entity_path,
- controller=controller,
- action='update_%s' % key,
- conditions=dict(method=['PATCH']))
- mapper.connect(
- entity_path,
- controller=controller,
- action='delete_%s' % key,
- conditions=dict(method=['DELETE']))
-
- def __init__(self):
- mapper = routes.Mapper()
-
- apis = dict(
- catalog_api=catalog.Manager(),
- identity_api=identity.Manager(),
- policy_api=policy.Manager(),
- token_api=token.Manager())
-
- # Catalog
-
- self.crud_routes(
- mapper,
- catalog.controllers.ServiceV3(**apis),
- 'services',
- 'service')
-
- self.crud_routes(
- mapper,
- catalog.controllers.EndpointV3(**apis),
- 'endpoints',
- 'endpoint')
-
- # Identity
-
- self.crud_routes(
- mapper,
- identity.controllers.DomainV3(**apis),
- 'domains',
- 'domain')
-
- project_controller = identity.controllers.ProjectV3(**apis)
- self.crud_routes(
- mapper,
- project_controller,
- 'projects',
- 'project')
- mapper.connect(
- '/users/{user_id}/projects',
- controller=project_controller,
- action='list_user_projects',
- conditions=dict(method=['GET']))
-
- self.crud_routes(
- mapper,
- identity.controllers.UserV3(**apis),
- 'users',
- 'user')
-
- self.crud_routes(
- mapper,
- identity.controllers.CredentialV3(**apis),
- 'credentials',
- 'credential')
-
- role_controller = identity.controllers.RoleV3(**apis)
- self.crud_routes(
- mapper,
- 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}/users/{user_id}/roles/{role_id}',
- controller=role_controller,
- action='check_grant',
- conditions=dict(method=['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}/users/{user_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}/users/{user_id}/roles/{role_id}',
- controller=role_controller,
- action='check_grant',
- conditions=dict(method=['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}/users/{user_id}/roles/{role_id}',
- controller=role_controller,
- action='revoke_grant',
- conditions=dict(method=['DELETE']))
-
- # Policy
-
- policy_controller = policy.controllers.PolicyV3(**apis)
- self.crud_routes(
- mapper,
- policy_controller,
- 'policies',
- 'policy')
-
- # Token
-
- """
- # v2.0 LEGACY
- mapper.connect('/tokens/{token_id}',
- controller=auth_controller,
- action='validate_token',
- conditions=dict(method=['GET']))
- mapper.connect('/tokens/{token_id}',
- controller=auth_controller,
- action='validate_token_head',
- conditions=dict(method=['HEAD']))
- mapper.connect('/tokens/{token_id}',
- controller=auth_controller,
- action='delete_token',
- conditions=dict(method=['DELETE']))
- mapper.connect('/tokens/{token_id}/endpoints',
- controller=auth_controller,
- action='endpoints',
- conditions=dict(method=['GET']))
- """
-
- super(V3Router, self).__init__(mapper, [])
-
-
-class AdminRouter(wsgi.ComposingRouter):
- def __init__(self):
- mapper = routes.Mapper()
-
- apis = dict(
- catalog_api=catalog.Manager(),
- identity_api=identity.Manager(),
- policy_api=policy.Manager(),
- token_api=token.Manager())
-
- version_controller = VersionController('admin')
- mapper.connect('/',
- controller=version_controller,
- action='get_version')
-
- # Token Operations
- auth_controller = token.controllers.Auth(**apis)
- mapper.connect('/tokens',
- controller=auth_controller,
- action='authenticate',
- conditions=dict(method=['POST']))
- mapper.connect('/tokens/revoked',
- controller=auth_controller,
- action='revocation_list',
- conditions=dict(method=['GET']))
- mapper.connect('/tokens/{token_id}',
- controller=auth_controller,
- action='validate_token',
- conditions=dict(method=['GET']))
- mapper.connect('/tokens/{token_id}',
- controller=auth_controller,
- action='validate_token_head',
- conditions=dict(method=['HEAD']))
- mapper.connect('/tokens/{token_id}',
- controller=auth_controller,
- action='delete_token',
- conditions=dict(method=['DELETE']))
- mapper.connect('/tokens/{token_id}/endpoints',
- controller=auth_controller,
- action='endpoints',
- conditions=dict(method=['GET']))
-
- # Certificates used to verify auth tokens
- mapper.connect('/certificates/ca',
- controller=auth_controller,
- action='ca_cert',
- conditions=dict(method=['GET']))
-
- mapper.connect('/certificates/signing',
- controller=auth_controller,
- action='signing_cert',
- conditions=dict(method=['GET']))
-
- # Miscellaneous Operations
- extensions_controller = AdminExtensionsController()
- mapper.connect('/extensions',
- controller=extensions_controller,
- action='get_extensions_info',
- conditions=dict(method=['GET']))
- mapper.connect('/extensions/{extension_alias}',
- controller=extensions_controller,
- action='get_extension_info',
- conditions=dict(method=['GET']))
- identity_router = identity.routers.Admin()
- routers = [identity_router]
- super(AdminRouter, self).__init__(mapper, routers)
-
-
-class PublicRouter(wsgi.ComposingRouter):
- def __init__(self):
- mapper = routes.Mapper()
-
- apis = dict(
- catalog_api=catalog.Manager(),
- identity_api=identity.Manager(),
- policy_api=policy.Manager(),
- token_api=token.Manager())
-
- version_controller = VersionController('public')
- mapper.connect('/',
- controller=version_controller,
- action='get_version')
-
- # Token Operations
- auth_controller = token.controllers.Auth(**apis)
- mapper.connect('/tokens',
- controller=auth_controller,
- action='authenticate',
- conditions=dict(method=['POST']))
-
- mapper.connect('/certificates/ca',
- controller=auth_controller,
- action='ca_cert',
- conditions=dict(method=['GET']))
-
- mapper.connect('/certificates/signing',
- controller=auth_controller,
- action='signing_cert',
- conditions=dict(method=['GET']))
-
- # Miscellaneous
- extensions_controller = PublicExtensionsController()
- mapper.connect('/extensions',
- controller=extensions_controller,
- action='get_extensions_info',
- conditions=dict(method=['GET']))
- mapper.connect('/extensions/{extension_alias}',
- controller=extensions_controller,
- action='get_extension_info',
- conditions=dict(method=['GET']))
-
- identity_router = identity.routers.Public()
- routers = [identity_router]
-
- super(PublicRouter, self).__init__(mapper, routers)
-
-
-class PublicVersionRouter(wsgi.ComposingRouter):
- def __init__(self):
- mapper = routes.Mapper()
- version_controller = VersionController('public')
- mapper.connect('/',
- controller=version_controller,
- action='get_versions')
- routers = []
- super(PublicVersionRouter, self).__init__(mapper, routers)
-
-
-class AdminVersionRouter(wsgi.ComposingRouter):
- def __init__(self):
- mapper = routes.Mapper()
- version_controller = VersionController('admin')
- mapper.connect('/',
- controller=version_controller,
- action='get_versions')
- routers = []
- super(AdminVersionRouter, self).__init__(mapper, routers)
-
-
-class VersionController(wsgi.Application):
- def __init__(self, version_type):
- self.catalog_api = catalog.Manager()
- self.url_key = '%sURL' % version_type
-
- super(VersionController, self).__init__()
-
- def _get_identity_url(self, context):
- catalog_ref = self.catalog_api.get_catalog(context=context,
- user_id=None,
- tenant_id=None)
- for region, region_ref in catalog_ref.iteritems():
- for service, service_ref in region_ref.iteritems():
- if service == 'identity':
- return service_ref[self.url_key]
-
- raise exception.NotImplemented()
-
- def _get_versions_list(self, context):
- """The list of versions is dependent on the context."""
- identity_url = self._get_identity_url(context)
- if not identity_url.endswith('/'):
- identity_url = identity_url + '/'
-
- versions = {}
- versions['v2.0'] = {
- 'id': 'v2.0',
- 'status': 'beta',
- 'updated': '2011-11-19T00:00:00Z',
- 'links': [
- {
- 'rel': 'self',
- 'href': identity_url,
- }, {
- 'rel': 'describedby',
- 'type': 'text/html',
- 'href': 'http://docs.openstack.org/api/openstack-'
- 'identity-service/2.0/content/'
- }, {
- 'rel': 'describedby',
- 'type': 'application/pdf',
- 'href': 'http://docs.openstack.org/api/openstack-'
- 'identity-service/2.0/identity-dev-guide-'
- '2.0.pdf'
- }
- ],
- 'media-types': [
- {
- 'base': 'application/json',
- 'type': 'application/vnd.openstack.identity-v2.0'
- '+json'
- }, {
- 'base': 'application/xml',
- 'type': 'application/vnd.openstack.identity-v2.0'
- '+xml'
- }
- ]
- }
-
- return versions
-
- def get_versions(self, context):
- versions = self._get_versions_list(context)
- return wsgi.render_response(status=(300, 'Multiple Choices'), body={
- 'versions': {
- 'values': versions.values()
- }
- })
-
- def get_version(self, context):
- versions = self._get_versions_list(context)
- return wsgi.render_response(body={
- 'version': versions['v2.0']
- })
-
-
-class NoopController(wsgi.Application):
- def __init__(self):
- super(NoopController, self).__init__()
-
- def noop(self, context):
- return {}
-
-
-class ExtensionsController(wsgi.Application):
- """Base extensions controller to be extended by public and admin API's."""
-
- def __init__(self, extensions=None):
- super(ExtensionsController, self).__init__()
-
- self.extensions = extensions or {}
-
- def get_extensions_info(self, context):
- return {'extensions': {'values': self.extensions.values()}}
-
- def get_extension_info(self, context, extension_alias):
- try:
- return {'extension': self.extensions[extension_alias]}
- except KeyError:
- raise exception.NotFound(target=extension_alias)
-
-
-class PublicExtensionsController(ExtensionsController):
- pass
-
-
-class AdminExtensionsController(ExtensionsController):
- def __init__(self, *args, **kwargs):
- super(AdminExtensionsController, self).__init__(*args, **kwargs)
-
- # TODO(dolph): Extensions should obviously provide this information
- # themselves, but hardcoding it here allows us to match
- # the API spec in the short term with minimal complexity.
- self.extensions['OS-KSADM'] = {
- 'name': 'Openstack Keystone Admin',
- 'namespace': 'http://docs.openstack.org/identity/api/ext/'
- 'OS-KSADM/v1.0',
- 'alias': 'OS-KSADM',
- 'updated': '2011-08-19T13:25:27-06:00',
- 'description': 'Openstack extensions to Keystone v2.0 API '
- 'enabling Admin Operations.',
- 'links': [
- {
- 'rel': 'describedby',
- # TODO(dolph): link needs to be revised after
- # bug 928059 merges
- 'type': 'text/html',
- 'href': 'https://github.com/openstack/identity-api',
- }
- ]
- }
+def _apis():
+ return dict(catalog_api=catalog.Manager(),
+ identity_api=identity.Manager(),
+ policy_api=policy.Manager(),
+ token_api=token.Manager())
@logging.fail_gracefully
def public_app_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)
- return PublicRouter()
+ return wsgi.ComposingRouter(routes.Mapper(),
+ [identity.routers.Public(_apis()),
+ token.routers.Router(_apis()),
+ routers.Version('public'),
+ routers.Extension(False)])
@logging.fail_gracefully
def admin_app_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)
- return AdminRouter()
+ return wsgi.ComposingRouter(routes.Mapper(),
+ [identity.routers.Admin(_apis()),
+ token.routers.Router(_apis()),
+ routers.Version('admin'),
+ routers.Extension()])
@logging.fail_gracefully
def public_version_app_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)
- return PublicVersionRouter()
+ return wsgi.ComposingRouter(routes.Mapper(),
+ [routers.Versions('public')])
@logging.fail_gracefully
def admin_version_app_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)
- return AdminVersionRouter()
+ return wsgi.ComposingRouter(routes.Mapper(),
+ [routers.Versions('admin')])
@logging.fail_gracefully
def v3_app_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)
- return V3Router()
+ mapper = routes.Mapper()
+ v3routers = []
+ for module in [catalog, identity, policy]:
+ module.routers.append_v3_routers(mapper, v3routers, _apis())
+ #TODO put token routes here
+ return wsgi.ComposingRouter(mapper, v3routers)
View
1  keystone/token/__init__.py
@@ -16,3 +16,4 @@
from keystone.token.core import *
from keystone.token import controllers
+from keystone.token import routers
View
61 keystone/token/routers.py
@@ -0,0 +1,61 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# 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 wsgi
+from keystone.token import controllers
+
+
+class Router(wsgi.ComposableRouter):
+ def __init__(self, apis):
+ self.apis = apis
+ super(Router, self).__init__()
+
+ def add_routes(self, mapper):
+ token_controller = controllers.Auth(**self.apis)
+ mapper.connect('/tokens',
+ controller=token_controller,
+ action='authenticate',
+ conditions=dict(method=['POST']))
+ mapper.connect('/tokens/revoked',
+ controller=token_controller,
+ action='revocation_list',
+ conditions=dict(method=['GET']))
+ mapper.connect('/tokens/{token_id}',
+ controller=token_controller,
+ action='validate_token',
+ conditions=dict(method=['GET']))
+ mapper.connect('/tokens/{token_id}',
+ controller=token_controller,
+ action='validate_token_head',
+ conditions=dict(method=['HEAD']))
+ mapper.connect('/tokens/{token_id}',
+ controller=token_controller,
+ action='delete_token',
+ conditions=dict(method=['DELETE']))
+ mapper.connect('/tokens/{token_id}/endpoints',
+ controller=token_controller,
+ action='endpoints',
+ conditions=dict(method=['GET']))
+
+ # Certificates used to verify auth tokens
+ mapper.connect('/certificates/ca',
+ controller=token_controller,
+ action='ca_cert',
+ conditions=dict(method=['GET']))
+
+ mapper.connect('/certificates/signing',
+ controller=token_controller,
+ action='signing_cert',
+ conditions=dict(method=['GET']))
Please sign in to comment.
Something went wrong with that request. Please try again.