summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSai Krishna <saikrishna1511@gmail.com>2011-05-12 17:20:41 +0530
committerSai Krishna <saikrishna1511@gmail.com>2011-05-12 17:20:41 +0530
commite4f2a0a89f17d79c9e4577a0feac2fe507fd9f83 (patch)
tree35d9af44efc2156abe2c17cbef4f0b0f85a4848b
parent11e6bf86962c98540e0c6a19832e6544c55f8ffe (diff)
parentd5ce3e52fa784c7e1f2b1a6998e38546b3727e8b (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--README36
-rw-r--r--README.md113
-rwxr-xr-xecho/bin/echod26
-rw-r--r--echo/echo/__init__.py18
-rw-r--r--echo/echo/server.py (renamed from echo/echo/echo.py)5
-rw-r--r--keystone/logic/service.py18
-rw-r--r--test/unit/test_exthandler.py49
7 files changed, 214 insertions, 51 deletions
diff --git a/README b/README
index 35b27cc1..2dd74d01 100644
--- a/README
+++ b/README
@@ -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()