diff options
| author | Sai Krishna <saikrishna1511@gmail.com> | 2011-05-12 17:20:41 +0530 |
|---|---|---|
| committer | Sai Krishna <saikrishna1511@gmail.com> | 2011-05-12 17:20:41 +0530 |
| commit | e4f2a0a89f17d79c9e4577a0feac2fe507fd9f83 (patch) | |
| tree | 35d9af44efc2156abe2c17cbef4f0b0f85a4848b | |
| parent | 11e6bf86962c98540e0c6a19832e6544c55f8ffe (diff) | |
| parent | d5ce3e52fa784c7e1f2b1a6998e38546b3727e8b (diff) | |
Merge remote branch 'github/master'
Merged conflicts but added README.md, need to verify if this is needed
Conflicts:
README.md
keystone/logic/service.py
| -rw-r--r-- | README | 36 | ||||
| -rw-r--r-- | README.md | 113 | ||||
| -rwxr-xr-x | echo/bin/echod | 26 | ||||
| -rw-r--r-- | echo/echo/__init__.py | 18 | ||||
| -rw-r--r-- | echo/echo/server.py (renamed from echo/echo/echo.py) | 5 | ||||
| -rw-r--r-- | keystone/logic/service.py | 18 | ||||
| -rw-r--r-- | test/unit/test_exthandler.py | 49 |
7 files changed, 214 insertions, 51 deletions
@@ -61,40 +61,7 @@ Or using pip: RUNNING KEYSTONE: ----------------- -<<<<<<< HEAD From the topdir -======= -During development, you can simply run - - $ bin/keystone-auth - -It dumps stdout and stderr onto the terminal. - - -RUNNING KEYSOTNE IN AS ROOT IN PRODUCTION ---------------------------------------------- -In production, stdout and stderr need to be closed and all theoutput needs tobe redirected to a log file. -Once the package is installed through setup tools, RPM, deb, or ebuild keystone-control is installed -as /usr/sbin/keystone-control. Typically, it will be started a script in /etc/init.d/keystoned - -keystone-control can invoke keystone-auth and start the keystone daemon with - - $ /usr/sbin/keystone-control auth start - -It writes the process id of the daemon into /var/run/keystone/keystine-auth.pid. he daemon can be stopped with - - $ /usr/sbin/keystone-control auth stop - -keystone-control has the infrastructure to start and stop multiple servers keystone-xxx - - -DEVELOPMENT OF keystone-control -------------------------------- - -During the development of keystone-control can be started as a user instead of root - -From the topdir ->>>>>>> a0c43a05126d9cca83b58b788fbc8e24f004fb66 $ bin/keystone-control --pid-file pidfile auth <start|stop|restart> @@ -207,6 +174,3 @@ DATABASE SCHEMA - - - diff --git a/README.md b/README.md new file mode 100644 index 00000000..0fb7c64e --- /dev/null +++ b/README.md @@ -0,0 +1,113 @@ +Keystone: Identity Service +========================== + +Keystone is a proposed independent authentication service for [OpenStack](http://www.openstack.org). + +This initial proof of concept aims to address the current use cases in Swift and Nova which are: + +* REST-based, token auth for Swift +* many-to-many relationship between identity and tenant for Nova. + + +SERVICES: +--------- + +* Keystone - authentication service +* Auth_Token - WSGI middleware that can be used to handle token auth protocol (WSGI or remote proxy) +* Echo - A sample service that responds by returning call details + +Also included: + +* Auth_Basic - Stub for WSGI middleware that will be used to handle basic auth +* Auth_OpenID - Stub for WSGI middleware that will be used to handle openid auth protocol +* RemoteAuth - WSGI middleware that can be used in services (like Swift, Nova, and Glance) when Auth middleware is running remotely + + +ENVIRONMENT & DEPENDENCIES: +--------------------------- +see pip-requires for dependency list +Setup: +Install http://pypi.python.org/pypi/setuptools + sudo easy_install pip + sudo pip install -r pip-requires + + +RUNNING KEYSTONE: +----------------- + + $ cd bin + $ ./keystoned + + +RUNNING TEST SERVICE: +--------------------- + + Standalone stack (with Auth_Token) + $ cd echo/bin + $ ./echod + + Distributed stack (with RemoteAuth local and Auth_Token remote) + $ cd echo/bon + $ ./echod --remote + + in separate session + $ cd keystone/auth_protocols + $ python auth_token.py --remote + + +DEMO CLIENT: +--------------------- + $ cd echo/echo + $ python echo_client.py + Note: this requires tests data. See section TESTING for initializing data + + +TESTING +------- + +After starting keystone a keystone.db sqlite database should be created in the keystone folder. + +Add test data to the database: + + $ sqlite3 keystone/keystone.db < test/test_setup.sql + +To clean the test database + + $ sqlite3 keystone/keystone.db < test/kill.sql + +To run unit tests: + + $ python test/unit/test_identity.py + +To run client demo (with all auth middleware running locally on sample service): + + $ ./echo/bin/echod + $ python echo/echo/echo_client.py + + +To perform contract validation and load testing, use SoapUI (for now). + +Using SOAPUI: + +Download [SOAPUI](http://sourceforge.net/projects/soapui/files/): + +To Test Keystone Service: + +* File->Import Project +* Select tests/IdentitySOAPUI.xml +* Double click on "Keystone Tests" and press the green play (>) button + + +Unit Test on Identity Services +------------------------------ +In order to run the unit test on identity services: +* start the keystone server +* cat test_setup.sql |sqlite ../../keystone/keystone.db +* go to unit test/unit directory +* python test_identity.py + +For more on unit testing please refer + + python test_identity --help + + diff --git a/echo/bin/echod b/echo/bin/echod new file mode 100755 index 00000000..d20a1b5e --- /dev/null +++ b/echo/bin/echod @@ -0,0 +1,26 @@ +#!/bin/sh +# Copyright (C) 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. + +# If ../echo/__init__.py exists, add ../ to the Python search path so +# that it will override whatever may be installed in the default Python +# search path. +script_dir=`dirname $0` +if [ -f "$script_dir/../echo/__init__.py" ] +then + PYTHONPATH="$script_dir/..:$PYTHONPATH" + export PYTHONPATH +fi + +/usr/bin/env python -m echo.server $* diff --git a/echo/echo/__init__.py b/echo/echo/__init__.py index 52bcde04..3c39fdbc 100644 --- a/echo/echo/__init__.py +++ b/echo/echo/__init__.py @@ -1 +1,17 @@ -from echo import app_factory +# 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. + +from server import app_factory diff --git a/echo/echo/echo.py b/echo/echo/server.py index e7fa38d3..8c24aa8f 100644 --- a/echo/echo/echo.py +++ b/echo/echo/server.py @@ -159,5 +159,6 @@ if __name__ == "__main__": app = loadapp("config:" + \ os.path.join(os.path.abspath(os.path.dirname(__file__)), ini), global_conf={"log_name": "echo.log"}) - - wsgi.server(eventlet.listen(('', port)), app) + listener = eventlet.listen(('', port)) + pool = eventlet.GreenPool(1000) + wsgi.server(listener, app, custom_pool=pool) diff --git a/keystone/logic/service.py b/keystone/logic/service.py index 44d0b173..efe2f930 100644 --- a/keystone/logic/service.py +++ b/keystone/logic/service.py @@ -59,13 +59,13 @@ class IDMService(object): dtoken = db_models.Token() dtoken.token_id = str(uuid.uuid4()) dtoken.user_id = duser.id - + if not duser.tenants: raise fault.IDMFault("Strange: user %s is not associated " "with a tenant!" % duser.id) if not credentials.tenant_id and db_api.user_get_by_tenant(duser.id, credentials.tenant_id): raise fault.IDMFault("Error: user %s is not associated " - "with a tenant! %s" % (duser.id, + "with a tenant! %s" % (duser.id, credentials.tenant_id)) dtoken.tenant_id = credentials.tenant_id else: @@ -90,6 +90,7 @@ class IDMService(object): % user.id) return self.__get_auth_data(token, user) + def revoke_token(self, admin_token, token_id): self.__validate_token(admin_token) @@ -125,6 +126,7 @@ class IDMService(object): return tenant + ## ## GET Tenants with Pagination ## @@ -145,8 +147,6 @@ class IDMService(object): if next: links.append(atom.Link('next', "%s?'marker=%s&limit=%s'" \ % (url, next, limit))) - - return tenants.Tenants(ts, links) def get_tenant(self, admin_token, tenant_id): @@ -155,7 +155,6 @@ class IDMService(object): dtenant = db_api.tenant_get(tenant_id) if not dtenant: raise fault.ItemNotFoundFault("The tenant could not be found") - return tenants.Tenant(dtenant.id, dtenant.desc, dtenant.enabled) def update_tenant(self, admin_token, tenant_id, tenant): @@ -168,11 +167,8 @@ class IDMService(object): dtenant = db_api.tenant_get(tenant_id) if dtenant == None: raise fault.ItemNotFoundFault("The tenant cloud not be found") - values = {'desc': tenant.description, 'enabled': tenant.enabled} - db_api.tenant_update(tenant_id, values) - return tenants.Tenant(dtenant.id, tenant.description, tenant.enabled) def delete_tenant(self, admin_token, tenant_id): @@ -218,9 +214,7 @@ class IDMService(object): dtenant.id = group.group_id dtenant.desc = group.description dtenant.tenant_id = tenant - db_api.tenant_group_create(dtenant) - return tenants.Group(dtenant.id, dtenant.desc, dtenant.tenant_id) def get_tenant_groups(self, admin_token, tenantId, marker, limit, url): @@ -861,9 +855,9 @@ class IDMService(object): if not dtoken.tenant_id and \ db_api.user_get_by_tenant(duser.id, dtoken.tenant_id): raise fault.IDMFault("Error: user %s is not associated " - "with a tenant! %s" % (duser.id, + "with a tenant! %s" % (duser.id, dtoken.tenant_id)) - + user = auth.User(duser.id, dtoken.tenant_id, groups) return auth.AuthData(token, user) diff --git a/test/unit/test_exthandler.py b/test/unit/test_exthandler.py new file mode 100644 index 00000000..003923ff --- /dev/null +++ b/test/unit/test_exthandler.py @@ -0,0 +1,49 @@ +import os +import sys +# Need to access identity module +sys.path.append(os.path.abspath(os.path.join( + os.getcwd(), '..', '..', 'keystone')) +) +from queryext.exthandler import UrlExtensionFilter +import unittest + + +class MockWsgiApp(object): + + def __init__(self): + pass + + def __call__(self, env, start_response): + pass + + +def _start_response(): + pass + + +class UrlExtensionFilterTest(unittest.TestCase): + + def setUp(self): + self.filter = UrlExtensionFilter(MockWsgiApp(), {}) + + def test_xml_extension(self): + env = {'PATH_INFO': '/v1.0/someresource.xml'} + self.filter(env, _start_response) + self.assertEqual('/v1.0/someresource', env['PATH_INFO']) + self.assertEqual('application/xml', env['HTTP_ACCEPT']) + + def test_json_extension(self): + env = {'PATH_INFO': '/v1.0/someresource.json'} + self.filter(env, _start_response) + self.assertEqual('/v1.0/someresource', env['PATH_INFO']) + self.assertEqual('application/json', env['HTTP_ACCEPT']) + + def test_extension_overrides_header(self): + env = {'PATH_INFO': '/v1.0/someresource.json', 'HTTP_ACCEPT': 'application/xml'} + self.filter(env, _start_response) + self.assertEqual('/v1.0/someresource', env['PATH_INFO']) + self.assertEqual('application/json', env['HTTP_ACCEPT']) + + +if __name__ == '__main__': + unittest.main() |
