summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdipudi Praveena <padipudi@padipudi.(none)>2011-05-10 20:20:16 +0530
committerAdipudi Praveena <padipudi@padipudi.(none)>2011-05-10 20:20:16 +0530
commitebeda76d08632b3a43d387e8c489dfffb65009ee (patch)
treebdba3a87450a9fcbfbd5b52b613414338634eeac
parentc4cfe98424e6b25ef6fd72d1a62e328a680c4ec9 (diff)
Added the keystone top dir in configuration
-rwxr-xr-xbin/keystone-auth2
-rw-r--r--etc/keystone.conf6
-rwxr-xr-xkeystone/auth_server.py639
-rw-r--r--keystone/common/config.py39
-rwxr-xr-x[-rw-r--r--]keystone/server.py849
-rw-r--r--setup.py18
-rw-r--r--test/unit/test_identity.py2
7 files changed, 583 insertions, 972 deletions
diff --git a/bin/keystone-auth b/bin/keystone-auth
index c1e75daf..eae99ec9 100755
--- a/bin/keystone-auth
+++ b/bin/keystone-auth
@@ -57,7 +57,7 @@ if __name__ == '__main__':
(options, args) = config.parse_options(oparser)
try:
- conf, app = config.load_paste_app('auth_server', options, args)
+ conf, app = config.load_paste_app('server', options, args)
server = wsgi.Server()
server.start(app, int(conf['bind_port']), conf['bind_host'])
server.wait()
diff --git a/etc/keystone.conf b/etc/keystone.conf
index c85fd25a..3b2d4457 100644
--- a/etc/keystone.conf
+++ b/etc/keystone.conf
@@ -5,10 +5,10 @@ verbose = True
# Show debugging output in logs (sets DEBUG log level output)
debug = False
-[app:auth_server]
-paste.app_factory = keystone.auth_server:app_factory
+[app:server]
+paste.app_factory = keystone.server:app_factory
-# Which backend store should Glance use by default is not specified
+# Which backend store should Keystone use by default is not specified
# in a request to add a new image to Glance? Default: 'file'
# Available choices are 'file', 'swift', and 's3'
default_store = file
diff --git a/keystone/auth_server.py b/keystone/auth_server.py
deleted file mode 100755
index 6203dde4..00000000
--- a/keystone/auth_server.py
+++ /dev/null
@@ -1,639 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright (c) 2010-2011 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.
-
-
-"""
-Service that stores identities and issues and manages tokens
-
-HEADERS
--------
-HTTP_ is a standard http header
-HTTP_X is an extended http header
-
-> Coming in from initial call
-HTTP_X_AUTH_TOKEN : the client token being passed in
-HTTP_X_STORAGE_TOKEN: the client token being passed in (legacy Rackspace use)
- to support cloud files
-> Used for communication between components
-www-authenticate : only used if this component is being used remotely
-HTTP_AUTHORIZATION : basic auth password used to validate the connection
-
-> What we add to the request for use by the OpenStack service
-HTTP_X_AUTHORIZATION: the client identity being passed in
-
-"""
-import functools
-import logging
-import os
-import sys
-import httplib
-import json
-
-import routes
-from webob import Response
-from webob import Request
-from webob import descriptors
-from webob.exc import (HTTPNotFound,
- HTTPConflict,
- HTTPBadRequest)
-
-POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
- os.pardir,
- os.pardir))
-if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'keystone', '__init__.py')):
- sys.path.insert(0, POSSIBLE_TOPDIR)
-
-
-from queryext import exthandler
-from keystone.common import wsgi
-import keystone.logic.service as serv
-import keystone.logic.types.tenant as tenants
-import keystone.logic.types.auth as auth
-import keystone.logic.types.fault as fault
-import keystone.logic.types.user as users
-import keystone.common.template as template
-
-
-VERSION_STATUS = "ALPHA"
-VERSION_DATE = "2011-04-23T00:00:00Z"
-
-service = serv.IDMService()
-
-
-def is_xml_response(req):
- if not "Accept" in req.headers:
- return False
- return req.content_type == "application/xml"
-
-
-def get_app_root():
- return os.path.abspath(os.path.dirname(__file__))
-
-
-def get_auth_token(req):
- auth_token = None
- if "X-Auth-Token" in req.headers:
- auth_token = req.headers["X-Auth-Token"]
- return auth_token
-
-
-def wrap_error(func):
- @functools.wraps(func)
- def check_error(*args, **kwargs):
- print '>>>>>>>>>>>>>>>>>>..'
- try:
-
- return func(*args, **kwargs)
-
- except Exception as err:
- if isinstance(err, fault.IDMFault):
- return send_error(err.code, kwargs['req'], err)
- else:
- logging.exception(err)
- return send_error(500, kwargs['req'], fault.IDMFault("Unhandled error", str(err)))
- return check_error
-
-
-def get_normalized_request_content(model, req):
- """initialize a model from json/xml contents of request body"""
-
- if req.content_type == "application/xml":
-
- ret = model.from_xml(req.body)
- elif req.content_type == "application/json":
-
- ret = model.from_json(req.body)
- else:
-
- raise fault.IDMFault("I don't understand the content type ", code=415)
- return ret
-
-def send_error(code, req, result):
- content = None
- resp = Response()
-
- resp.headers['content-type'] = None
- resp.status = code
-
- if result:
-
- if is_xml_response(req):
-
- content = result.to_xml()
- resp.headers['content-type'] = "application/xml"
- else:
-
- content = result.to_json()
- resp.headers['content-type'] = "application/json"
-
- resp.content_type_params={'charset' : 'UTF-8'}
- resp.unicode_body = content.decode('UTF-8')
-
- return resp
-
-
-def send_result(code, req, result):
- content = None
- resp = Response()
- resp.headers['content-type'] = None
- resp.status = code
- if code > 399:
- return resp
-
- if result:
-
- if is_xml_response(req):
- content = result.to_xml()
- resp.headers['content-type'] = "application/xml"
- else:
- content = result.to_json()
- resp.headers['content-type'] = "application/json"
-
- resp.content_type_params={'charset' : 'UTF-8'}
- resp.unicode_body = content.decode('UTF-8')
-
- return resp
-
-class StaticFilesController(wsgi.Controller):
-
- def __init__(self, options):
- self.options = options
-
- @wrap_error
- def get_pdf_contract(self, req):
- resp = Response()
- return template.static_file(resp, req, "content/idmdevguide.pdf",
- root=get_app_root(),
- mimetype="application/pdf")
-
- @wrap_error
- def get_wadl_contract(self, req):
- resp = Response()
- return template.static_file(resp, req, "identity.wadl",
- root=get_app_root(),
- mimetype="application/vnd.sun.wadl+xml")
-
- @wrap_error
- def get_xsd_contract(self, req, xsd):
- resp = Response()
- return template.static_file(resp, req, "/xsd/" + xsd,
- root=get_app_root(),
- mimetype="application/xml")
-
- @wrap_error
- def get_xsd_atom_contract(self, req, xsd):
- resp = Response()
- return template.static_file(resp, req, "/xsd/atom/" + xsd,
- root=get_app_root(),
- mimetype="application/xml")
-
-class MiscController(wsgi.Controller):
-
- def __init__(self, options):
- self.options = options
-
- @wrap_error
- def get_version_info(self, req):
-
- resp = Response()
- resp.charset = 'UTF-8'
- if is_xml_response(req):
- resp_file = os.path.join(POSSIBLE_TOPDIR,
- "keystone/content/version.xml.tpl")
- resp.content_type = "application/xml"
- else:
- resp_file = os.path.join(POSSIBLE_TOPDIR,
- "keystone/content/version.json.tpl")
- resp.content_type = "application/json"
-
- hostname = req.environ.get("SERVER_NAME")
- port = req.environ.get("SERVER_PORT")
-
- resp.unicode_body= template.template(resp_file, HOST=hostname, PORT=port,
- VERSION_STATUS=VERSION_STATUS,
- VERSION_DATE=VERSION_DATE)
- return resp
-
-
-
-class AuthController(wsgi.Controller):
-
- def __init__(self, options):
- self.options = options
- self.request = None
-
- @wrap_error
- def authenticate(self, req):
- self.request = req
-
- creds = get_normalized_request_content(auth.PasswordCredentials, req)
- return send_result(200, req, service.authenticate(creds))
-
- @wrap_error
- def validate_token(self, req, token_id):
-
- belongs_to = None
- if "belongsTo" in req.GET:
- belongs_to = req.GET["belongsTo"]
- rval = service.validate_token(get_auth_token(req), token_id, belongs_to)
-
- return send_result(200, req, rval)
-
- @wrap_error
- def delete_token(self, req, token_id):
- return send_result(204, req, service.revoke_token(get_auth_token(req), token_id))
-
-
-class TenantController(wsgi.Controller):
-
- def __init__(self, options):
- self.options = options
-
- @wrap_error
- def create_tenant(self, req):
- tenant = get_normalized_request_content(tenants.Tenant, req)
- return send_result(201, req,
- service.create_tenant(get_auth_token(req), tenant))
-
- @wrap_error
- def get_tenants(self, req):
- marker = None
- if "marker" in req.GET:
- marker = req.GET["marker"]
-
- if "limit" in req.GET:
- limit = req.GET["limit"]
- else:
- limit = 10
-
- url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
- req.environ.get("SERVER_NAME"),
- req.environ.get("SERVER_PORT"),
- req.environ['PATH_INFO'])
-
- tenants = service.get_tenants(get_auth_token(req), marker, limit, url)
- return send_result(200, req, tenants)
-
-
- @wrap_error
- def get_tenant(self, req, tenant_id):
- tenant = service.get_tenant(get_auth_token(req), tenant_id)
- return send_result(200, req, tenant)
-
- @wrap_error
- def update_tenant(self, req, tenant_id):
- tenant = get_normalized_request_content(tenants.Tenant, req)
- rval = service.update_tenant(get_auth_token(req), tenant_id, tenant)
- return send_result(200, req, rval)
-
- @wrap_error
- def delete_tenant(self, req, tenant_id):
- rval = service.delete_tenant(get_auth_token(req), tenant_id)
- return send_result(204, req, rval)
-
-
-
- # Tenant Group Methods
- @wrap_error
- def create_tenant_group(self, req, tenant_id):
- group = get_normalized_request_content(tenants.Group, req)
- return send_result(201, req,
- service.create_tenant_group(get_auth_token(req), \
- tenant_id, group))
- @wrap_error
- def get_tenant_groups(self, req, tenant_id):
- marker = None
- if "marker" in req.GET:
- marker = req.GET["marker"]
-
- if "limit" in req.GET:
- limit = req.GET["limit"]
- else:
- limit = 10
-
- url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
- req.environ.get("SERVER_NAME"),
- req.environ.get("SERVER_PORT"),
- req.environ['PATH_INFO'])
-
- groups = service.get_tenant_groups(get_auth_token(req),
- tenant_id, marker, limit, url)
- return send_result(200, req, groups)
-
- @wrap_error
- def get_tenant_group(self, req, tenant_id, group_id):
- tenant = service.get_tenant_group(get_auth_token(req), tenant_id,
- group_id)
- return send_result(200, req, tenant)
-
- @wrap_error
- def update_tenant_group(self, req, tenant_id, group_id):
- group = get_normalized_request_content(tenants.Group, req)
- rval = service.update_tenant_group(get_auth_token(req),\
- tenant_id, group_id, group)
- return send_result(200, req, rval)
-
- @wrap_error
- def delete_tenant_group(self, req, tenant_id, group_id):
- rval = service.delete_tenant_group(get_auth_token(req), tenant_id,
- group_id)
- return send_result(204, req, rval)
-
- @wrap_error
- def add_user_tenant_group(self, req, tenant_id, group_id, user_id):
- # TBD
- # IDMDevguide clarification needed on this property
- return None
-
- @wrap_error
- def delete_user_tenant_group(self, req, tenant_id, group_id, user_id):
- # TBD
- # IDMDevguide clarification needed on this property
- return None
-
- @wrap_error
- def get_user_tenant_group(self, req, tenant_id, group_id, user_id):
- # TBD
- # IDMDevguide clarification needed on this property
- return None
-
-class UserController(wsgi.Controller):
-
- def __init__(self, options):
- self.options = options
-
- @wrap_error
- def create_user(self, req, tenant_id):
- user = get_normalized_request_content(users.User, req)
- return send_result(201, req,
- service.create_user(get_auth_token(req), tenant_id, user))
-
- @wrap_error
- def get_tenant_users(self, req, tenant_id):
- marker = None
- if "marker" in req.GET:
- marker = req.GET["marker"]
- if "limit" in req.GET:
- limit = req.GET["limit"]
- else:
- limit = 10
- url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
- req.environ.get("SERVER_NAME"),
- req.environ.get("SERVER_PORT"),
- req.environ['PATH_INFO'])
- users = service.get_tenant_users(get_auth_token(req), tenant_id, marker, limit, url)
- return send_result(200, req, users)
-
- @wrap_error
- def get_user_groups(self, req, tenant_id, user_id):
- marker = None
- if "marker" in req.GET:
- marker = req.GET["marker"]
-
- if "limit" in req.GET:
- limit = req.GET["limit"]
- else:
- limit = 10
- url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
- req.environ.get("SERVER_NAME"),
- req.environ.get("SERVER_PORT"),
- req.environ['PATH_INFO'])
-
- groups = service.get_user_groups(get_auth_token(),
- tenant_id,user_id, marker, limit,url)
- return send_result(200, groups)
-
- @wrap_error
- def get_user(self, req, tenant_id, user_id):
- user = service.get_user(get_auth_token(req), tenant_id, user_id)
- return send_result(200, req, user)
-
- @wrap_error
- def update_user(self, req, user_id, tenant_id):
- user = get_normalized_request_content(users.User_Update, req)
- rval = service.update_user(get_auth_token(req), user_id, user, tenant_id)
- return send_result(200, req, rval)
-
- @wrap_error
- def delete_user(self, req, user_id, tenant_id):
- rval = service.delete_user(get_auth_token(req), user_id, tenant_id)
- return send_result(204, req, rval)
-
- @wrap_error
- def set_user_password(self, req, user_id, tenant_id):
- user = get_normalized_request_content(users.User_Update, req)
- rval = service.set_user_password(get_auth_token(req), user_id, user, tenant_id)
- return send_result(204, req, rval)
-
- # To be checked with Abdul not finished yet
- @wrap_error
- def set_user_enabled(self, req, user_id, tenant_id):
- user = get_normalized_request_content(users.User_Update, req)
- rval = service.enable_disable_user(get_auth_token(req), user_id, user, tenant_id)
- return send_result(204, req, rval)
-
-
-
-class GroupsController(wsgi.Controller):
-
-
- def __init__(self, options):
- self.options = options
-
- @wrap_error
- def create_group(self, req):
- group = get_normalized_request_content(tenants.Group, req)
- return send_result(201, req,
- service.create_global_group(get_auth_token(req),
- group))
- @wrap_error
- def get_groups(self, req):
- marker = None
- if "marker" in req.GET:
- marker = req.GET["marker"]
-
- if "limit" in req.GET:
- limit = req.GET["limit"]
- else:
- limit = 10
-
- url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
- req.environ.get("SERVER_NAME"),
- req.environ.get("SERVER_PORT"),
- req.environ['PATH_INFO'])
- groups = service.get_global_groups(get_auth_token(req),
- marker, limit, url)
- return send_result(200, req, groups)
-
- @wrap_error
- def get_group(self, req, group_id):
- tenant = service.get_global_group(get_auth_token(req), group_id)
- return send_result(200, req, tenant)
-
- @wrap_error
- def update_group(self, req, group_id):
- group = get_normalized_request_content(tenants.Group, req)
- rval = service.update_global_group(get_auth_token(req),
- group_id, group)
- return send_result(200, req, rval)
-
- @wrap_error
- def delete_group(self, req, group_id):
- rval = service.delete_global_group(get_auth_token(req), group_id)
- return send_result(204, req, rval)
-
- @wrap_error
- def get_users_group(self, req, group_id):
- marker = None
- if "marker" in req.GET:
- marker = req.GET["marker"]
-
- if "limit" in req.GET:
- limit = req.GET["limit"]
- else:
- limit = 10
-
- url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
- req.environ.get("SERVER_NAME"),
- req.environ.get("SERVER_PORT"),
- req.environ['PATH_INFO'])
-
- users = service.get_users_global_group(get_auth_token(req),
- group_id, marker, limit, url)
- return send_result(200, req, users)
-
- @wrap_error
- def add_user_group(self, req, group_id, user_id):
- return send_result(201, req,
- service.add_user_global_group(get_auth_token(req),
- group_id, user_id))
- @wrap_error
- def delete_user_group(self, req, group_id, user_id):
- return send_result(204, req,
- service.delete_user_global_group(get_auth_token(req),
- group_id, user_id))
-
-class KeystoneAPI(wsgi.Router):
- """WSGI entry point for all Keystone Auth API requests."""
-
- def __init__(self, options):
- self.options = options
- mapper = routes.Mapper()
-
- # Token Operations
- auth_controller = AuthController(options)
- mapper.connect("/v1.0/token", controller=auth_controller, action="authenticate")
- mapper.connect("/v1.0/token/{token_id}", controller=auth_controller,
- action="validate_token", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/token/{token_id}", controller=auth_controller,
- action="delete_token", conditions=dict(method=["DELETE"]))
-
- # Tenant Operations
- tenant_controller = TenantController(options)
- mapper.connect("/v1.0/tenants", controller=tenant_controller,
- action="create_tenant", conditions=dict(method=["POST"]))
- mapper.connect("/v1.0/tenants", controller=tenant_controller,
- action="get_tenants", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/tenants/{tenant_id}", controller=tenant_controller,
- action="get_tenant", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/tenants/{tenant_id}", controller=tenant_controller,
- action="update_tenant", conditions=dict(method=["PUT"]))
- mapper.connect("/v1.0/tenants/{tenant_id}", controller=tenant_controller,
- action="delete_tenant", conditions=dict(method=["DELETE"]))
-
- # Tenant Group Operations
-
- mapper.connect("/v1.0/tenant/{tenant_id}/groups", controller=tenant_controller,
- action="create_tenant_group", conditions=dict(method=["POST"]))
- mapper.connect("/v1.0/tenant/{tenant_id}/groups", controller=tenant_controller,
- action="get_tenant_groups", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/tenant/{tenant_id}/groups/{group_id}", controller=tenant_controller,
- action="get_tenant_group", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/tenant/{tenant_id}/groups/{group_id}", controller=tenant_controller,
- action="update_tenant_group", conditions=dict(method=["PUT"]))
- mapper.connect("/v1.0/tenant/{tenant_id}/groups/{group_id}", controller=tenant_controller,
- action="delete_tenant_group", conditions=dict(method=["DELETE"]))
-
- # User Operations
- user_controller = UserController(options)
- mapper.connect("/v1.0/tenants/{tenant_id}/users", controller=user_controller,
- action="create_user", conditions=dict(method=["POST"]))
- mapper.connect("/v1.0/tenants/{tenant_id}/users", controller=user_controller,
- action="get_tenant_users", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}", controller=user_controller,
- action="get_user", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}", controller=user_controller,
- action="update_user", conditions=dict(method=["PUT"]))
- mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}", controller=user_controller,
- action="delete_user", conditions=dict(method=["DELETE"]))
- mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}/password", controller=user_controller,
- action="set_user_password", conditions=dict(method=["PUT"]))
-
- # Test this, test failed
- mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}/enabled", controller=user_controller,
- action="set_user_enabled", conditions=dict(method=["PUT"]))
-
- #Global Groups
- groups_controller = GroupsController(options)
- mapper.connect("/v1.0/groups", controller=groups_controller,
- action="create_group", conditions=dict(method=["POST"]))
- mapper.connect("/v1.0/groups", controller=groups_controller,
- action="get_groups", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller,
- action="get_group", conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller,
- action="update_group", conditions=dict(method=["PUT"]))
- mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller,
- action="delete_group", conditions=dict(method=["DELETE"]))
- mapper.connect("/v1.0/groups/{group_id}/users/{user_id}", controller=groups_controller,
- action="add_user_group", conditions=dict(method=["PUT"]))
- mapper.connect("/v1.0/groups/{group_id}/users/{user_id}", controller=groups_controller,
- action="delete_user_group", conditions=dict(method=["DELETE"]))
-
- #Not working yet, somebody who has touched its models, please handle
- mapper.connect("/v1.0/groups/{group_id}/users", controller=groups_controller,
- action="get_users_group", conditions=dict(method=["GET"]))
-
-
-
- # Miscellaneous Operations
- misc_controller = MiscController(options)
- mapper.connect("/v1.0/", controller=misc_controller,
- action="get_version_info",conditions=dict(method=["GET"]))
- mapper.connect("/v1.0", controller=misc_controller,
- action="get_version_info",conditions=dict(method=["GET"]))
-
- # Static Files Controller
- static_files_controller = StaticFilesController(options)
- mapper.connect("/v1.0/idmdevguide.pdf", controller=static_files_controller,
- action="get_pdf_contract",conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/identity.wadl", controller=static_files_controller,
- action="get_identity_wadl",conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/xsd/{xsd}", controller=static_files_controller,
- action="get_pdf_contract",conditions=dict(method=["GET"]))
- mapper.connect("/v1.0/xsd/atom/{xsd}", controller=static_files_controller,
- action="get_pdf_contract",conditions=dict(method=["GET"]))
-
- super(KeystoneAPI, self).__init__(mapper)
-
-def app_factory(global_conf, **local_conf):
- """paste.deploy app factory for creating Glance API server apps"""
- try:
- conf = global_conf.copy()
- conf.update(local_conf)
- except Exception as err:
- print err
- return KeystoneAPI(conf)
diff --git a/keystone/common/config.py b/keystone/common/config.py
index 09baeed5..8e6dc047 100644
--- a/keystone/common/config.py
+++ b/keystone/common/config.py
@@ -68,7 +68,7 @@ def add_common_options(parser):
:param parser: optparse.OptionParser
"""
help_text = "The following configuration options are common to "\
- "all glance programs."
+ "all keystone programs."
group = optparse.OptionGroup(parser, "Common Options", help_text)
group.add_option('-v', '--verbose', default=False, dest="verbose",
@@ -180,16 +180,20 @@ def find_config_file(options, args):
We search for the paste config file in the following order:
* If --config-file option is used, use that
* If args[0] is a file, use that
- * Search for glance.conf in standard directories:
+ * Search for keystone.conf in standard directories:
* .
- * ~.glance/
+ * ~.keystone/
* ~
- * /etc/glance
+ * /etc/keystone
* /etc
+ :if no config file is given get from possible_topdir/etc/keystone.conf
:retval Full path to config file, or None if no config file found
"""
-
+ POSSIBLE_TOPDIR = os.path.normpath(os.path.join(\
+ os.path.abspath(sys.argv[0]),
+ os.pardir,
+ os.pardir))
fix_path = lambda p: os.path.abspath(os.path.expanduser(p))
if options.get('config_file'):
if os.path.exists(options['config_file']):
@@ -198,7 +202,7 @@ def find_config_file(options, args):
if os.path.exists(args[0]):
return fix_path(args[0])
- # Handle standard directory search for glance.conf
+ # Handle standard directory search for keystone.conf
config_file_dirs = [fix_path(os.getcwd()),
fix_path(os.path.join('~', '.keystone')),
fix_path('~'),
@@ -208,8 +212,17 @@ def find_config_file(options, args):
for cfg_dir in config_file_dirs:
cfg_file = os.path.join(cfg_dir, 'keystone.conf')
if os.path.exists(cfg_file):
- print cfg_file
return cfg_file
+ else:
+ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'etc', \
+ 'keystone.conf')):
+ # For debug only
+ config_file = os.path.join(POSSIBLE_TOPDIR, 'etc', \
+ 'keystone.conf')
+
+ print "Running server from %s " % config_file
+ return os.path.join(POSSIBLE_TOPDIR, 'etc', \
+ 'keystone.conf')
def load_paste_config(app_name, options, args):
@@ -220,11 +233,11 @@ def load_paste_config(app_name, options, args):
We search for the paste config file in the following order:
* If --config-file option is used, use that
* If args[0] is a file, use that
- * Search for glance.conf in standard directories:
+ * Search for keystone.conf in standard directories:
* .
- * ~.glance/
+ * ~.keystone/
* ~
- * /etc/glance
+ * /etc/keystone
* /etc
:param app_name: Name of the application to load config for, or None.
@@ -256,11 +269,11 @@ def load_paste_app(app_name, options, args):
We search for the paste config file in the following order:
* If --config-file option is used, use that
* If args[0] is a file, use that
- * Search for glance.conf in standard directories:
+ * Search for keystone.conf in standard directories:
* .
- * ~.glance/
+ * ~.keystone/
* ~
- * /etc/glance
+ * /etc/keystone
* /etc
:param app_name: Name of the application to load
diff --git a/keystone/server.py b/keystone/server.py
index 22ee8887..6203dde4 100644..100755
--- a/keystone/server.py
+++ b/keystone/server.py
@@ -13,7 +13,6 @@
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-# Not yet PEP8
"""
@@ -36,367 +35,605 @@ HTTP_AUTHORIZATION : basic auth password used to validate the connection
HTTP_X_AUTHORIZATION: the client identity being passed in
"""
-
import functools
import logging
import os
import sys
-import eventlet
-from eventlet import wsgi
+import httplib
+import json
-import bottle
-from bottle import request
-from bottle import response
-from queryext import exthandler
+import routes
+from webob import Response
+from webob import Request
+from webob import descriptors
+from webob.exc import (HTTPNotFound,
+ HTTPConflict,
+ HTTPBadRequest)
-# If ../keystone/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'keystone', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
-print POSSIBLE_TOPDIR
+
+from queryext import exthandler
+from keystone.common import wsgi
import keystone.logic.service as serv
-import keystone.logic.types.auth as auth
import keystone.logic.types.tenant as tenants
+import keystone.logic.types.auth as auth
import keystone.logic.types.fault as fault
+import keystone.logic.types.user as users
+import keystone.common.template as template
+
VERSION_STATUS = "ALPHA"
VERSION_DATE = "2011-04-23T00:00:00Z"
-bottle.debug(True)
-
service = serv.IDMService()
-##
-## Override error pages
-##
-
-
-@bottle.error(400)
-@bottle.error(401)
-@bottle.error(403)
-@bottle.error(404)
-@bottle.error(409)
-@bottle.error(415)
-@bottle.error(500)
-@bottle.error(503)
-def error_handler(err):
- return err.output
-
-def is_xml_response():
- if not "Accept" in request.header:
+def is_xml_response(req):
+ if not "Accept" in req.headers:
return False
- return request.header["Accept"] == "application/xml"
+ return req.content_type == "application/xml"
def get_app_root():
return os.path.abspath(os.path.dirname(__file__))
-def send_result(code, result):
- content = None
- response.content_type = None
- if result:
- if is_xml_response():
- content = result.to_xml()
- response.content_type = "application/xml"
- else:
- content = result.to_json()
- response.content_type = "application/json"
- response.status = code
- if code > 399:
- return bottle.abort(code, content)
- return content
-
-
-def get_normalized_request_content(model):
- """initialize a model from json/xml contents of request body"""
-
- ctype = request.environ.get("CONTENT_TYPE")
- if ctype == "application/xml":
- ret = model.from_xml(request.body.read())
- elif ctype == "application/json":
- ret = model.from_json(request.body.read())
- else:
- raise fault.IDMFault("I don't understand the content type ", code=415)
- return ret
-
-
-def get_auth_token():
+def get_auth_token(req):
auth_token = None
- if "X-Auth-Token" in request.header:
- auth_token = request.header["X-Auth-Token"]
+ if "X-Auth-Token" in req.headers:
+ auth_token = req.headers["X-Auth-Token"]
return auth_token
def wrap_error(func):
@functools.wraps(func)
def check_error(*args, **kwargs):
+ print '>>>>>>>>>>>>>>>>>>..'
try:
+
return func(*args, **kwargs)
+
except Exception as err:
if isinstance(err, fault.IDMFault):
- send_result(err.code, err)
+ return send_error(err.code, kwargs['req'], err)
else:
logging.exception(err)
- send_result(500, fault.IDMFault("Unhandled error", str(err)))
+ return send_error(500, kwargs['req'], fault.IDMFault("Unhandled error", str(err)))
return check_error
-@bottle.route('/v1.0', method='GET')
-@bottle.route('/v1.0/', method='GET')
-@wrap_error
-def get_version_info():
- if is_xml_response():
- resp_file = os.path.join(POSSIBLE_TOPDIR,
- "keystone/content/version.xml.tpl")
- response.content_type = "application/xml"
- else:
- resp_file = os.path.join(POSSIBLE_TOPDIR,
- "keystone/content/version.json.tpl")
- response.content_type = "application/json"
- hostname = request.environ.get("SERVER_NAME")
- port = request.environ.get("SERVER_PORT")
- return bottle.template(resp_file, HOST=hostname, PORT=port,
- VERSION_STATUS=VERSION_STATUS,
- VERSION_DATE=VERSION_DATE)
-
-##
-## Version links:
-##
-
-
-@bottle.route('/v1.0/idmdevguide.pdf', method='GET')
-@wrap_error
-def get_pdf_contract():
- return bottle.static_file("content/idmdevguide.pdf",
- root=get_app_root(),
- mimetype="application/pdf")
-
-
-@bottle.route('/v1.0/identity.wadl', method='GET')
-@wrap_error
-def get_wadl_contract():
- return bottle.static_file("identity.wadl",
- root=get_app_root(),
- mimetype="application/vnd.sun.wadl+xml")
-
-
-@bottle.route('/v1.0/xsd/:xsd', method='GET')
-@wrap_error
-def get_xsd_contract(xsd):
- return bottle.static_file("/xsd/" + xsd,
- root=get_app_root(),
- mimetype="application/xml")
-
-
-@bottle.route('/v1.0/xsd/atom/:xsd', method='GET')
-@wrap_error
-def get_xsd_atom_contract(xsd):
- return bottle.static_file("/xsd/atom/" + xsd,
- root=get_app_root(),
- mimetype="application/xml")
-
-##
-## Token Operations
-##
-
-
-@bottle.route('/v1.0/token', method='POST')
-@wrap_error
-def authenticate():
- creds = get_normalized_request_content(auth.PasswordCredentials)
- return send_result(200, service.authenticate(creds))
-
-
-@bottle.route('/v1.0/token/:token_id', method='GET')
-@wrap_error
-def validate_token(token_id):
- belongs_to = None
- if "belongsTo" in request.GET:
- belongs_to = request.GET["belongsTo"]
- rval = service.validate_token(get_auth_token(), token_id, belongs_to)
- return send_result(200, rval)
-
-
-@bottle.route('/v1.0/token/:token_id', method='DELETE')
-@wrap_error
-def delete_token(token_id):
- return send_result(204,
- service.revoke_token(get_auth_token(), token_id))
-
-##
-## Tenant Operations
-##
-
-
-@bottle.route('/v1.0/tenants', method='POST')
-@wrap_error
-def create_tenant():
- tenant = get_normalized_request_content(tenants.Tenant)
- return send_result(201,
- service.create_tenant(get_auth_token(), tenant))
-
-
-#
-# Tenants Pagination Script Added
-@bottle.route('/v1.0/tenants', method='GET')
-@wrap_error
-def get_tenants():
- marker = None
- if "marker" in request.GET:
- marker = request.GET["marker"]
-
- if "limit" in request.GET:
- limit = request.GET["limit"]
- else:
- limit = 10
-
- url = '%s://%s:%s%s' % (request.environ['wsgi.url_scheme'],
- request.environ.get("SERVER_NAME"),
- request.environ.get("SERVER_PORT"),
- request.environ['PATH_INFO'])
-
- tenants = service.get_tenants(get_auth_token(), marker, limit, url)
- return send_result(200, tenants)
-
-
-@bottle.route('/v1.0/tenants/:tenant_id', method='GET')
-@wrap_error
-def get_tenant(tenant_id):
- tenant = service.get_tenant(get_auth_token(), tenant_id)
- return send_result(200, tenant)
-
-
-@bottle.route('/v1.0/tenants/:tenant_id', method='PUT')
-@wrap_error
-def update_tenant(tenant_id):
- tenant = get_normalized_request_content(tenants.Tenant)
- rval = service.update_tenant(get_auth_token(), tenant_id, tenant)
- return send_result(200, rval)
-
-
-@bottle.route('/v1.0/tenants/:tenant_id', method='DELETE')
-@wrap_error
-def delete_tenant(tenant_id):
- rval = service.delete_tenant(get_auth_token(), tenant_id)
- return send_result(204, rval)
-
-
-##
-## Tenant Groups
-##
-
-@bottle.route('/v1.0/tenant/:tenantId/groups', method='POST')
-@wrap_error
-def create_tenant_group(tenantId):
- group = get_normalized_request_content(tenants.Group)
- return send_result(201,
- service.create_tenant_group(get_auth_token(), \
- tenantId, group))
-
-
-@bottle.route('/v1.0/tenant/:tenantId/groups', method='GET')
-@wrap_error
-def get_tenant_groups(tenantId):
- marker = None
- if "marker" in request.GET:
- marker = request.GET["marker"]
-
- if "limit" in request.GET:
- limit = request.GET["limit"]
+def get_normalized_request_content(model, req):
+ """initialize a model from json/xml contents of request body"""
+
+ if req.content_type == "application/xml":
+
+ ret = model.from_xml(req.body)
+ elif req.content_type == "application/json":
+
+ ret = model.from_json(req.body)
else:
- limit = 10
-
- url = '%s://%s:%s%s' % (request.environ['wsgi.url_scheme'],
- request.environ.get("SERVER_NAME"),
- request.environ.get("SERVER_PORT"),
- request.environ['PATH_INFO'])
-
- groups = service.get_tenant_groups(get_auth_token(),
- tenantId, marker, limit, url)
- return send_result(200, groups)
-
-
-@bottle.route('/v1.0/tenant/:tenantId/groups/:groupId', method='GET')
-@wrap_error
-def get_tenant_group(tenantId, groupId):
- tenant = service.get_tenant_group(get_auth_token(), tenantId, groupId)
- return send_result(200, tenant)
-
-
-@bottle.route('/v1.0/tenant/:tenantId/groups/:groupId', method='PUT')
-@wrap_error
-def update_tenant_group(tenantId, groupId):
- group = get_normalized_request_content(tenants.Group)
- rval = service.update_tenant_group(get_auth_token(),\
- tenantId, groupId, group)
- return send_result(200, rval)
-
+
+ raise fault.IDMFault("I don't understand the content type ", code=415)
+ return ret
-@bottle.route('/v1.0/tenant/:tenantId/groups/:groupId', method='DELETE')
-@wrap_error
-def delete_tenant_group(tenantId, groupId):
- rval = service.delete_tenant_group(get_auth_token(), tenantId, groupId)
- return send_result(204, rval)
+def send_error(code, req, result):
+ content = None
+ resp = Response()
+
+ resp.headers['content-type'] = None
+ resp.status = code
+
+ if result:
+
+ if is_xml_response(req):
+
+ content = result.to_xml()
+ resp.headers['content-type'] = "application/xml"
+ else:
+
+ content = result.to_json()
+ resp.headers['content-type'] = "application/json"
+ resp.content_type_params={'charset' : 'UTF-8'}
+ resp.unicode_body = content.decode('UTF-8')
+
+ return resp
-@bottle.route('/v1.0/tenants/:tenantId/groups/:groupId/users', method='GET')
-@wrap_error
-def get_users_tenant_group(tenantId, groupId):
- marker = None
- if "marker" in request.GET:
- marker = request.GET["marker"]
- if "limit" in request.GET:
- limit = request.GET["limit"]
- else:
- limit = 10
+def send_result(code, req, result):
+ content = None
+ resp = Response()
+ resp.headers['content-type'] = None
+ resp.status = code
+ if code > 399:
+ return resp
+
+ if result:
+
+ if is_xml_response(req):
+ content = result.to_xml()
+ resp.headers['content-type'] = "application/xml"
+ else:
+ content = result.to_json()
+ resp.headers['content-type'] = "application/json"
- url = '%s://%s:%s%s' % (request.environ['wsgi.url_scheme'],\
- request.environ.get("SERVER_NAME"),\
- request.environ.get("SERVER_PORT"),\
- request.environ['PATH_INFO'])
+ resp.content_type_params={'charset' : 'UTF-8'}
+ resp.unicode_body = content.decode('UTF-8')
- users = service.get_users_tenant_group(get_auth_token(),\
- tenantId, groupId, marker, limit, url)
- return send_result(200, users)
+ return resp
+class StaticFilesController(wsgi.Controller):
-##
-## Extensions
-##
+ def __init__(self, options):
+ self.options = options
+
+ @wrap_error
+ def get_pdf_contract(self, req):
+ resp = Response()
+ return template.static_file(resp, req, "content/idmdevguide.pdf",
+ root=get_app_root(),
+ mimetype="application/pdf")
-@bottle.route('/v1.0/extensions', method='GET')
-@wrap_error
-def get_extensions():
- if is_xml_response():
- resp_file = "content/extensions.xml"
- mimetype = "application/xml"
- else:
- resp_file = "content/extensions.json"
- mimetype = "application/json"
- return bottle.static_file(resp_file,
+ @wrap_error
+ def get_wadl_contract(self, req):
+ resp = Response()
+ return template.static_file(resp, req, "identity.wadl",
root=get_app_root(),
- mimetype=mimetype)
-
-
-@bottle.route('/v1.0/extensions/:ext_alias', method='GET')
-@wrap_error
-def get_extension(ext_alias):
- #
- # Todo: Define some extensions :-)
- #
- raise fault.ItemNotFoundFault("The extension is not found")
+ mimetype="application/vnd.sun.wadl+xml")
+ @wrap_error
+ def get_xsd_contract(self, req, xsd):
+ resp = Response()
+ return template.static_file(resp, req, "/xsd/" + xsd,
+ root=get_app_root(),
+ mimetype="application/xml")
-def start_server(port=8080):
- app = exthandler.UrlExtensionFilter(bottle.default_app(), None)
- wsgi.server(eventlet.listen(('', port)), app)
+ @wrap_error
+ def get_xsd_atom_contract(self, req, xsd):
+ resp = Response()
+ return template.static_file(resp, req, "/xsd/atom/" + xsd,
+ root=get_app_root(),
+ mimetype="application/xml")
-if __name__ == "__main__":
- start_server()
+class MiscController(wsgi.Controller):
+
+ def __init__(self, options):
+ self.options = options
+
+ @wrap_error
+ def get_version_info(self, req):
+
+ resp = Response()
+ resp.charset = 'UTF-8'
+ if is_xml_response(req):
+ resp_file = os.path.join(POSSIBLE_TOPDIR,
+ "keystone/content/version.xml.tpl")
+ resp.content_type = "application/xml"
+ else:
+ resp_file = os.path.join(POSSIBLE_TOPDIR,
+ "keystone/content/version.json.tpl")
+ resp.content_type = "application/json"
+
+ hostname = req.environ.get("SERVER_NAME")
+ port = req.environ.get("SERVER_PORT")
+
+ resp.unicode_body= template.template(resp_file, HOST=hostname, PORT=port,
+ VERSION_STATUS=VERSION_STATUS,
+ VERSION_DATE=VERSION_DATE)
+ return resp
+
+
+
+class AuthController(wsgi.Controller):
+
+ def __init__(self, options):
+ self.options = options
+ self.request = None
+
+ @wrap_error
+ def authenticate(self, req):
+ self.request = req
+
+ creds = get_normalized_request_content(auth.PasswordCredentials, req)
+ return send_result(200, req, service.authenticate(creds))
+
+ @wrap_error
+ def validate_token(self, req, token_id):
+
+ belongs_to = None
+ if "belongsTo" in req.GET:
+ belongs_to = req.GET["belongsTo"]
+ rval = service.validate_token(get_auth_token(req), token_id, belongs_to)
+
+ return send_result(200, req, rval)
+
+ @wrap_error
+ def delete_token(self, req, token_id):
+ return send_result(204, req, service.revoke_token(get_auth_token(req), token_id))
+
+
+class TenantController(wsgi.Controller):
+
+ def __init__(self, options):
+ self.options = options
+
+ @wrap_error
+ def create_tenant(self, req):
+ tenant = get_normalized_request_content(tenants.Tenant, req)
+ return send_result(201, req,
+ service.create_tenant(get_auth_token(req), tenant))
+
+ @wrap_error
+ def get_tenants(self, req):
+ marker = None
+ if "marker" in req.GET:
+ marker = req.GET["marker"]
+
+ if "limit" in req.GET:
+ limit = req.GET["limit"]
+ else:
+ limit = 10
+
+ url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
+ req.environ.get("SERVER_NAME"),
+ req.environ.get("SERVER_PORT"),
+ req.environ['PATH_INFO'])
+
+ tenants = service.get_tenants(get_auth_token(req), marker, limit, url)
+ return send_result(200, req, tenants)
+
+
+ @wrap_error
+ def get_tenant(self, req, tenant_id):
+ tenant = service.get_tenant(get_auth_token(req), tenant_id)
+ return send_result(200, req, tenant)
+
+ @wrap_error
+ def update_tenant(self, req, tenant_id):
+ tenant = get_normalized_request_content(tenants.Tenant, req)
+ rval = service.update_tenant(get_auth_token(req), tenant_id, tenant)
+ return send_result(200, req, rval)
+
+ @wrap_error
+ def delete_tenant(self, req, tenant_id):
+ rval = service.delete_tenant(get_auth_token(req), tenant_id)
+ return send_result(204, req, rval)
+
+
+
+ # Tenant Group Methods
+ @wrap_error
+ def create_tenant_group(self, req, tenant_id):
+ group = get_normalized_request_content(tenants.Group, req)
+ return send_result(201, req,
+ service.create_tenant_group(get_auth_token(req), \
+ tenant_id, group))
+ @wrap_error
+ def get_tenant_groups(self, req, tenant_id):
+ marker = None
+ if "marker" in req.GET:
+ marker = req.GET["marker"]
+
+ if "limit" in req.GET:
+ limit = req.GET["limit"]
+ else:
+ limit = 10
+
+ url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
+ req.environ.get("SERVER_NAME"),
+ req.environ.get("SERVER_PORT"),
+ req.environ['PATH_INFO'])
+
+ groups = service.get_tenant_groups(get_auth_token(req),
+ tenant_id, marker, limit, url)
+ return send_result(200, req, groups)
+
+ @wrap_error
+ def get_tenant_group(self, req, tenant_id, group_id):
+ tenant = service.get_tenant_group(get_auth_token(req), tenant_id,
+ group_id)
+ return send_result(200, req, tenant)
+
+ @wrap_error
+ def update_tenant_group(self, req, tenant_id, group_id):
+ group = get_normalized_request_content(tenants.Group, req)
+ rval = service.update_tenant_group(get_auth_token(req),\
+ tenant_id, group_id, group)
+ return send_result(200, req, rval)
+
+ @wrap_error
+ def delete_tenant_group(self, req, tenant_id, group_id):
+ rval = service.delete_tenant_group(get_auth_token(req), tenant_id,
+ group_id)
+ return send_result(204, req, rval)
+
+ @wrap_error
+ def add_user_tenant_group(self, req, tenant_id, group_id, user_id):
+ # TBD
+ # IDMDevguide clarification needed on this property
+ return None
+
+ @wrap_error
+ def delete_user_tenant_group(self, req, tenant_id, group_id, user_id):
+ # TBD
+ # IDMDevguide clarification needed on this property
+ return None
+
+ @wrap_error
+ def get_user_tenant_group(self, req, tenant_id, group_id, user_id):
+ # TBD
+ # IDMDevguide clarification needed on this property
+ return None
+
+class UserController(wsgi.Controller):
+
+ def __init__(self, options):
+ self.options = options
+
+ @wrap_error
+ def create_user(self, req, tenant_id):
+ user = get_normalized_request_content(users.User, req)
+ return send_result(201, req,
+ service.create_user(get_auth_token(req), tenant_id, user))
+
+ @wrap_error
+ def get_tenant_users(self, req, tenant_id):
+ marker = None
+ if "marker" in req.GET:
+ marker = req.GET["marker"]
+ if "limit" in req.GET:
+ limit = req.GET["limit"]
+ else:
+ limit = 10
+ url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
+ req.environ.get("SERVER_NAME"),
+ req.environ.get("SERVER_PORT"),
+ req.environ['PATH_INFO'])
+ users = service.get_tenant_users(get_auth_token(req), tenant_id, marker, limit, url)
+ return send_result(200, req, users)
+
+ @wrap_error
+ def get_user_groups(self, req, tenant_id, user_id):
+ marker = None
+ if "marker" in req.GET:
+ marker = req.GET["marker"]
+
+ if "limit" in req.GET:
+ limit = req.GET["limit"]
+ else:
+ limit = 10
+ url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
+ req.environ.get("SERVER_NAME"),
+ req.environ.get("SERVER_PORT"),
+ req.environ['PATH_INFO'])
+
+ groups = service.get_user_groups(get_auth_token(),
+ tenant_id,user_id, marker, limit,url)
+ return send_result(200, groups)
+
+ @wrap_error
+ def get_user(self, req, tenant_id, user_id):
+ user = service.get_user(get_auth_token(req), tenant_id, user_id)
+ return send_result(200, req, user)
+
+ @wrap_error
+ def update_user(self, req, user_id, tenant_id):
+ user = get_normalized_request_content(users.User_Update, req)
+ rval = service.update_user(get_auth_token(req), user_id, user, tenant_id)
+ return send_result(200, req, rval)
+
+ @wrap_error
+ def delete_user(self, req, user_id, tenant_id):
+ rval = service.delete_user(get_auth_token(req), user_id, tenant_id)
+ return send_result(204, req, rval)
+
+ @wrap_error
+ def set_user_password(self, req, user_id, tenant_id):
+ user = get_normalized_request_content(users.User_Update, req)
+ rval = service.set_user_password(get_auth_token(req), user_id, user, tenant_id)
+ return send_result(204, req, rval)
+
+ # To be checked with Abdul not finished yet
+ @wrap_error
+ def set_user_enabled(self, req, user_id, tenant_id):
+ user = get_normalized_request_content(users.User_Update, req)
+ rval = service.enable_disable_user(get_auth_token(req), user_id, user, tenant_id)
+ return send_result(204, req, rval)
+
+
+
+class GroupsController(wsgi.Controller):
+
+
+ def __init__(self, options):
+ self.options = options
+
+ @wrap_error
+ def create_group(self, req):
+ group = get_normalized_request_content(tenants.Group, req)
+ return send_result(201, req,
+ service.create_global_group(get_auth_token(req),
+ group))
+ @wrap_error
+ def get_groups(self, req):
+ marker = None
+ if "marker" in req.GET:
+ marker = req.GET["marker"]
+
+ if "limit" in req.GET:
+ limit = req.GET["limit"]
+ else:
+ limit = 10
+
+ url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
+ req.environ.get("SERVER_NAME"),
+ req.environ.get("SERVER_PORT"),
+ req.environ['PATH_INFO'])
+ groups = service.get_global_groups(get_auth_token(req),
+ marker, limit, url)
+ return send_result(200, req, groups)
+
+ @wrap_error
+ def get_group(self, req, group_id):
+ tenant = service.get_global_group(get_auth_token(req), group_id)
+ return send_result(200, req, tenant)
+
+ @wrap_error
+ def update_group(self, req, group_id):
+ group = get_normalized_request_content(tenants.Group, req)
+ rval = service.update_global_group(get_auth_token(req),
+ group_id, group)
+ return send_result(200, req, rval)
+
+ @wrap_error
+ def delete_group(self, req, group_id):
+ rval = service.delete_global_group(get_auth_token(req), group_id)
+ return send_result(204, req, rval)
+
+ @wrap_error
+ def get_users_group(self, req, group_id):
+ marker = None
+ if "marker" in req.GET:
+ marker = req.GET["marker"]
+
+ if "limit" in req.GET:
+ limit = req.GET["limit"]
+ else:
+ limit = 10
+
+ url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'],
+ req.environ.get("SERVER_NAME"),
+ req.environ.get("SERVER_PORT"),
+ req.environ['PATH_INFO'])
+
+ users = service.get_users_global_group(get_auth_token(req),
+ group_id, marker, limit, url)
+ return send_result(200, req, users)
+
+ @wrap_error
+ def add_user_group(self, req, group_id, user_id):
+ return send_result(201, req,
+ service.add_user_global_group(get_auth_token(req),
+ group_id, user_id))
+ @wrap_error
+ def delete_user_group(self, req, group_id, user_id):
+ return send_result(204, req,
+ service.delete_user_global_group(get_auth_token(req),
+ group_id, user_id))
+
+class KeystoneAPI(wsgi.Router):
+ """WSGI entry point for all Keystone Auth API requests."""
+
+ def __init__(self, options):
+ self.options = options
+ mapper = routes.Mapper()
+
+ # Token Operations
+ auth_controller = AuthController(options)
+ mapper.connect("/v1.0/token", controller=auth_controller, action="authenticate")
+ mapper.connect("/v1.0/token/{token_id}", controller=auth_controller,
+ action="validate_token", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/token/{token_id}", controller=auth_controller,
+ action="delete_token", conditions=dict(method=["DELETE"]))
+
+ # Tenant Operations
+ tenant_controller = TenantController(options)
+ mapper.connect("/v1.0/tenants", controller=tenant_controller,
+ action="create_tenant", conditions=dict(method=["POST"]))
+ mapper.connect("/v1.0/tenants", controller=tenant_controller,
+ action="get_tenants", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/tenants/{tenant_id}", controller=tenant_controller,
+ action="get_tenant", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/tenants/{tenant_id}", controller=tenant_controller,
+ action="update_tenant", conditions=dict(method=["PUT"]))
+ mapper.connect("/v1.0/tenants/{tenant_id}", controller=tenant_controller,
+ action="delete_tenant", conditions=dict(method=["DELETE"]))
+
+ # Tenant Group Operations
+
+ mapper.connect("/v1.0/tenant/{tenant_id}/groups", controller=tenant_controller,
+ action="create_tenant_group", conditions=dict(method=["POST"]))
+ mapper.connect("/v1.0/tenant/{tenant_id}/groups", controller=tenant_controller,
+ action="get_tenant_groups", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/tenant/{tenant_id}/groups/{group_id}", controller=tenant_controller,
+ action="get_tenant_group", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/tenant/{tenant_id}/groups/{group_id}", controller=tenant_controller,
+ action="update_tenant_group", conditions=dict(method=["PUT"]))
+ mapper.connect("/v1.0/tenant/{tenant_id}/groups/{group_id}", controller=tenant_controller,
+ action="delete_tenant_group", conditions=dict(method=["DELETE"]))
+
+ # User Operations
+ user_controller = UserController(options)
+ mapper.connect("/v1.0/tenants/{tenant_id}/users", controller=user_controller,
+ action="create_user", conditions=dict(method=["POST"]))
+ mapper.connect("/v1.0/tenants/{tenant_id}/users", controller=user_controller,
+ action="get_tenant_users", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}", controller=user_controller,
+ action="get_user", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}", controller=user_controller,
+ action="update_user", conditions=dict(method=["PUT"]))
+ mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}", controller=user_controller,
+ action="delete_user", conditions=dict(method=["DELETE"]))
+ mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}/password", controller=user_controller,
+ action="set_user_password", conditions=dict(method=["PUT"]))
+
+ # Test this, test failed
+ mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}/enabled", controller=user_controller,
+ action="set_user_enabled", conditions=dict(method=["PUT"]))
+
+ #Global Groups
+ groups_controller = GroupsController(options)
+ mapper.connect("/v1.0/groups", controller=groups_controller,
+ action="create_group", conditions=dict(method=["POST"]))
+ mapper.connect("/v1.0/groups", controller=groups_controller,
+ action="get_groups", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller,
+ action="get_group", conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller,
+ action="update_group", conditions=dict(method=["PUT"]))
+ mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller,
+ action="delete_group", conditions=dict(method=["DELETE"]))
+ mapper.connect("/v1.0/groups/{group_id}/users/{user_id}", controller=groups_controller,
+ action="add_user_group", conditions=dict(method=["PUT"]))
+ mapper.connect("/v1.0/groups/{group_id}/users/{user_id}", controller=groups_controller,
+ action="delete_user_group", conditions=dict(method=["DELETE"]))
+
+ #Not working yet, somebody who has touched its models, please handle
+ mapper.connect("/v1.0/groups/{group_id}/users", controller=groups_controller,
+ action="get_users_group", conditions=dict(method=["GET"]))
+
+
+
+ # Miscellaneous Operations
+ misc_controller = MiscController(options)
+ mapper.connect("/v1.0/", controller=misc_controller,
+ action="get_version_info",conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0", controller=misc_controller,
+ action="get_version_info",conditions=dict(method=["GET"]))
+
+ # Static Files Controller
+ static_files_controller = StaticFilesController(options)
+ mapper.connect("/v1.0/idmdevguide.pdf", controller=static_files_controller,
+ action="get_pdf_contract",conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/identity.wadl", controller=static_files_controller,
+ action="get_identity_wadl",conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/xsd/{xsd}", controller=static_files_controller,
+ action="get_pdf_contract",conditions=dict(method=["GET"]))
+ mapper.connect("/v1.0/xsd/atom/{xsd}", controller=static_files_controller,
+ action="get_pdf_contract",conditions=dict(method=["GET"]))
+
+ super(KeystoneAPI, self).__init__(mapper)
+
+def app_factory(global_conf, **local_conf):
+ """paste.deploy app factory for creating Glance API server apps"""
+ try:
+ conf = global_conf.copy()
+ conf.update(local_conf)
+ except Exception as err:
+ print err
+ return KeystoneAPI(conf)
diff --git a/setup.py b/setup.py
index f5ab870a..41f326cd 100644
--- a/setup.py
+++ b/setup.py
@@ -31,13 +31,13 @@ setup(
include_package_data=True,
packages=find_packages(exclude=['test', 'bin']),
scripts=['bin/keystone']
- zip_safe=False,
- install_requires=['setuptools'],
- entry_points={
- 'paste.app_factory': ['main=identity:app_factory'],
- 'paste.filter_factory': [
- 'papiauth=keystone:papiauth_factory',
- 'tokenauth=keystone:tokenauth_factory',
- ],
- },
+# zip_safe=False,
+# install_requires=['setuptools'],
+# entry_points={
+# 'paste.app_factory': ['main=identity:app_factory'],
+# 'paste.filter_factory': [
+# 'papiauth=keystone:papiauth_factory',
+# 'tokenauth=keystone:tokenauth_factory',
+# ],
+# },
)
diff --git a/test/unit/test_identity.py b/test/unit/test_identity.py
index e6079366..adbd26db 100644
--- a/test/unit/test_identity.py
+++ b/test/unit/test_identity.py
@@ -3,7 +3,7 @@ import sys
# Need to access identity module
sys.path.append(os.path.abspath(os.path.join(os.path.abspath(__file__),
'..', '..', '..', '..', 'keystone')))
-from keystone import auth_server
+from keystone import server
import unittest
from webtest import TestApp
import httplib2