Skip to content

Commit

Permalink
module refactoring
Browse files Browse the repository at this point in the history
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
Adam Young committed Dec 17, 2012
1 parent 44e3c3e commit fb963a5
Show file tree
Hide file tree
Showing 15 changed files with 503 additions and 507 deletions.
1 change: 1 addition & 0 deletions keystone/catalog/__init__.py
Expand Up @@ -16,3 +16,4 @@


from keystone.catalog.core import * from keystone.catalog.core import *
from keystone.catalog import controllers from keystone.catalog import controllers
from keystone.catalog import routers
20 changes: 2 additions & 18 deletions keystone/catalog/controllers.py
Expand Up @@ -20,18 +20,9 @@
from keystone.catalog import core from keystone.catalog import core
from keystone.common import controller from keystone.common import controller
from keystone.common import wsgi from keystone.common import wsgi
from keystone import identity
from keystone import policy
from keystone import token




class Service(wsgi.Application): class Service(controller.V2Controller):
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__()


def get_services(self, context): def get_services(self, context):
self.assert_admin(context) self.assert_admin(context)
Expand All @@ -57,14 +48,7 @@ def create_service(self, context, OS_KSADM_service):
return {'OS-KSADM:service': new_service_ref} return {'OS-KSADM:service': new_service_ref}




class Endpoint(wsgi.Application): class Endpoint(controller.V2Controller):
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__()

def get_endpoints(self, context): def get_endpoints(self, context):
self.assert_admin(context) self.assert_admin(context)
endpoint_list = self.catalog_api.list_endpoints(context) endpoint_list = self.catalog_api.list_endpoints(context)
Expand Down
25 changes: 25 additions & 0 deletions 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'))
57 changes: 57 additions & 0 deletions 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']))
18 changes: 12 additions & 6 deletions keystone/contrib/admin_crud/core.py
Expand Up @@ -13,10 +13,11 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.

from keystone import catalog from keystone import catalog
from keystone.common import wsgi from keystone.common import wsgi
from keystone import identity from keystone import identity
from keystone import policy
from keystone import token




class CrudExtension(wsgi.ExtensionRouter): class CrudExtension(wsgi.ExtensionRouter):
Expand All @@ -27,11 +28,16 @@ class CrudExtension(wsgi.ExtensionRouter):
""" """


def add_routes(self, mapper): def add_routes(self, mapper):
tenant_controller = identity.controllers.Tenant() apis = dict(catalog_api=catalog.Manager(),
user_controller = identity.controllers.User() identity_api=identity.Manager(),
role_controller = identity.controllers.Role() policy_api=policy.Manager(),
service_controller = catalog.controllers.Service() token_api=token.Manager())
endpoint_controller = catalog.controllers.Endpoint()
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 # Tenant Operations
mapper.connect( mapper.connect(
Expand Down
23 changes: 13 additions & 10 deletions keystone/contrib/user_crud/core.py
Expand Up @@ -18,21 +18,19 @@
import uuid import uuid


from keystone import exception from keystone import exception
from keystone.common import controller
from keystone.common import logging from keystone.common import logging
from keystone.common import wsgi from keystone.common import wsgi
from keystone import catalog
from keystone import identity from keystone import identity
from keystone import policy
from keystone import token from keystone import token




LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)




class UserController(wsgi.Application): class UserController(identity.controllers.User):
def __init__(self):
self.identity_api = identity.Manager()
self.token_api = token.Manager()
self.user_controller = identity.controllers.User()

def set_user_password(self, context, user_id, user): def set_user_password(self, context, user_id, user):
token_id = context.get('token_id') token_id = context.get('token_id')
original_password = user.get('original_password') original_password = user.get('original_password')
Expand Down Expand Up @@ -62,9 +60,9 @@ def set_user_password(self, context, user_id, user):


admin_context = copy.copy(context) admin_context = copy.copy(context)
admin_context['is_admin'] = True admin_context['is_admin'] = True
self.user_controller.set_user_password(admin_context, super(UserController, self).set_user_password(admin_context,
user_id, user_id,
update_dict) update_dict)


token_id = uuid.uuid4().hex token_id = uuid.uuid4().hex
new_token_ref = copy.copy(token_ref) new_token_ref = copy.copy(token_ref)
Expand All @@ -83,7 +81,12 @@ class CrudExtension(wsgi.ExtensionRouter):
""" """


def add_routes(self, mapper): 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}', mapper.connect('/OS-KSCRUD/users/{user_id}',
controller=user_controller, controller=user_controller,
Expand Down
144 changes: 144 additions & 0 deletions 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']
})

0 comments on commit fb963a5

Please sign in to comment.