summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin L. Mitchell <kevin.mitchell@rackspace.com>2011-06-13 13:23:29 -0500
committerKevin L. Mitchell <kevin.mitchell@rackspace.com>2011-06-13 13:23:29 -0500
commitf0567818f3e86357dca815fa2cc0d7a7647d5e4d (patch)
tree6035d1bef00b912de4f73276bb25320efe6ec991
parent59d9bb49649a3c2de6122e0461ad5d9298b1fd85 (diff)
parentef2033be3411ade4e43225de0995fa27baa378fc (diff)
Merge branch 'master' of git://github.com/rackspace/keystone
Conflicts: keystone/test/functional/test_tokens.py
-rw-r--r--README.md95
-rwxr-xr-xbin/keystone21
-rwxr-xr-xbin/keystone-auth28
-rwxr-xr-xbin/keystone-manage77
-rwxr-xr-xbin/sampledata.sh12
-rwxr-xr-x[-rw-r--r--]docs/guide/src/docbkx/identitydevguide.xml287
-rw-r--r--docs/guide/src/docbkx/samples/group.json1
-rw-r--r--docs/guide/src/docbkx/samples/group.xml4
-rw-r--r--docs/guide/src/docbkx/samples/groups.json1
-rw-r--r--docs/guide/src/docbkx/samples/groups.xml5
-rw-r--r--docs/guide/src/docbkx/samples/tenants-request.txt5
-rw-r--r--docs/guide/src/docbkx/samples/tenants.json5
-rw-r--r--docs/guide/src/docbkx/samples/tenants.xml5
-rw-r--r--docs/swift-quick-start.txt121
-rwxr-xr-x[-rw-r--r--]etc/keystone.conf20
-rw-r--r--keystone/auth_protocols/nova_auth_token.py3
-rwxr-xr-x[-rw-r--r--]keystone/common/config.py0
-rw-r--r--keystone/content/identitydevguide.pdfbin285331 -> 302544 bytes
-rwxr-xr-x[-rw-r--r--]keystone/db/sqlalchemy/api.py10
-rw-r--r--keystone/frontends/__init__.py (renamed from test/__init__.py)0
-rw-r--r--keystone/frontends/legacy_token_auth.py129
-rwxr-xr-xkeystone/logic/service.py22
-rwxr-xr-x[-rw-r--r--]keystone/logic/types/auth.py58
-rwxr-xr-x[-rw-r--r--]keystone/server.py63
-rw-r--r--keystone/test/EchoSOAPUI.xml (renamed from test/EchoSOAPUI.xml)0
-rw-r--r--keystone/test/IdentitySOAPUI.xml (renamed from test/IdentitySOAPUI.xml)0
-rw-r--r--keystone/test/__init__.py (renamed from test/unit/__init__.py)0
-rw-r--r--keystone/test/functional/base.py (renamed from test/functional/base.py)0
-rw-r--r--keystone/test/functional/ksapi.py (renamed from test/functional/ksapi.py)0
-rwxr-xr-xkeystone/test/functional/run_tests.py (renamed from test/functional/run_tests.py)4
-rw-r--r--keystone/test/functional/sample_test.py (renamed from test/functional/sample_test.py)0
-rw-r--r--keystone/test/functional/simplerest.py (renamed from test/functional/simplerest.py)0
-rw-r--r--keystone/test/functional/test_tokens.py (renamed from test/functional/test_tokens.py)0
-rw-r--r--keystone/test/unit/__init__.py0
-rw-r--r--keystone/test/unit/base.py (renamed from test/unit/base.py)0
-rw-r--r--keystone/test/unit/decorators.py (renamed from test/unit/decorators.py)0
-rw-r--r--keystone/test/unit/test_BaseURLs.py (renamed from test/unit/test_BaseURLs.py)0
-rw-r--r--keystone/test/unit/test_auth.py (renamed from test/unit/test_auth.py)0
-rwxr-xr-x[-rw-r--r--]keystone/test/unit/test_authentication.py (renamed from test/unit/test_authentication.py)29
-rw-r--r--keystone/test/unit/test_authn_v2.py (renamed from test/unit/test_authn_v2.py)0
-rwxr-xr-x[-rw-r--r--]keystone/test/unit/test_common.py (renamed from test/unit/test_common.py)2
-rw-r--r--keystone/test/unit/test_exthandler.py (renamed from test/unit/test_exthandler.py)0
-rw-r--r--keystone/test/unit/test_groups.py (renamed from test/unit/test_groups.py)0
-rw-r--r--keystone/test/unit/test_keystone.py (renamed from test/unit/test_keystone.py)0
-rw-r--r--keystone/test/unit/test_roles.py (renamed from test/unit/test_roles.py)0
-rw-r--r--keystone/test/unit/test_server.py (renamed from test/unit/test_server.py)0
-rw-r--r--keystone/test/unit/test_tenant_groups.py (renamed from test/unit/test_tenant_groups.py)0
-rw-r--r--keystone/test/unit/test_tenants.py (renamed from test/unit/test_tenants.py)0
-rw-r--r--keystone/test/unit/test_token.py (renamed from test/unit/test_token.py)0
-rw-r--r--keystone/test/unit/test_users.py (renamed from test/unit/test_users.py)0
-rw-r--r--keystone/test/unit/test_version.py (renamed from test/unit/test_version.py)0
-rw-r--r--setup.py2
-rw-r--r--test/kill.sql10
-rwxr-xr-xtools/management/delgroup.py54
-rwxr-xr-xtools/management/getgroup.py52
-rwxr-xr-xtools/management/getgroups.py49
-rwxr-xr-xtools/management/getgroupusers.py51
-rwxr-xr-xtools/management/getuser.py49
-rwxr-xr-xtools/management/getusergroups.py50
-rwxr-xr-xtools/management/groupadd.py52
-rwxr-xr-xtools/management/setuserlock.py61
-rwxr-xr-xtools/management/setuserpswd.py53
-rwxr-xr-xtools/management/updategroup.py54
-rwxr-xr-xtools/management/userdel.py51
-rwxr-xr-xtools/management/userupdate.py53
65 files changed, 722 insertions, 926 deletions
diff --git a/README.md b/README.md
index d9f2ed35..9a54febb 100644
--- a/README.md
+++ b/README.md
@@ -230,9 +230,100 @@ Initial support for using keystone as nova's identity component has been started
Assuming you added the test data using bin/sampledata.sh, you can then use joeuser/secrete
-## SWIFT Integration
+## Swift Integration - Quick Start
+
+1. Install Swift, either from trunk or version 1.4.1 (once it's released) or
+ higher. Do the standard SAIO install with the included TempAuth to be sure
+ you have a working system to start with. This step is beyond the scope of
+ this quick start; see http://swift.openstack.org/development_saio.html for
+ a Swift development set up guide. Once you have a working Swift install, go
+ ahead and shut it down for now (the default Swift install uses the same
+ ports Keystone wants):
+
+ $ swift-init all stop
+
+2. Obtain and install a source copy of Keystone:
+
+ $ git clone https://github.com/rackspace/keystone.git ~/keystone
+ ...
+ $ cd ~/keystone && sudo python setup.py develop
+ ...
+
+3. Start up the Keystone service:
+
+ $ cd ~/keystone/bin && ./keystone
+ Starting the Legacy Authentication component
+ Service API listening on 0.0.0.0:8080
+ Admin API listening on 0.0.0.0:8081
+
+4. In another window, edit the `~/keystone/bin/sampledata.sh` file, find the
+ `public.cloudfiles.com` text and replace it with the URL to your Swift
+ cluster using the following format (note that we're going to change Swift
+ to run on port 8888 later): `http://127.0.0.1:8888/v1/AUTH_%tenant_id%`
+
+5. Create the sample data entries:
+
+ $ cd ~/keystone/bin && ./sampledata.sh
+ ...
+
+6. Reconfigure Swift's proxy server to use Keystone instead of TempAuth.
+ Here's an example `/etc/swift/proxy-server.conf`:
+
+ [DEFAULT]
+ bind_port = 8888
+ user = <user>
+
+ [pipeline:main]
+ pipeline = catch_errors cache keystone proxy-server
+
+ [app:proxy-server]
+ use = egg:swift#proxy
+ account_autocreate = true
+
+ [filter:keystone]
+ use = egg:keystone#tokenauth
+ auth_protocol = http
+ auth_host = 127.0.0.1
+ auth_port = 8081
+ admin_token = 999888777666
+ delay_auth_decision = 0
+ service_protocol = http
+ service_host = 127.0.0.1
+ service_port = 8100
+ service_pass = dTpw
+
+ [filter:cache]
+ use = egg:swift#memcache
+ set log_name = cache
+
+ [filter:catch_errors]
+ use = egg:swift#catch_errors
+
+7. Start Swift back up with the new configuration:
+
+ $ swift-init main start
+ ...
+
+8. Use `st` to check everything works (note: you currently have to create a
+ container or upload something as your first action to have the account
+ created; there's a Swift bug to be fixed soon):
+
+ $ st -A http://127.0.0.1:8080/v1.0 -U joeuser -K secrete post container
+ $ st -A http://127.0.0.1:8080/v1.0 -U joeuser -K secrete stat -v
+ StorageURL: http://127.0.0.1:8888/v1/AUTH_1234
+ Auth Token: 74ce1b05-e839-43b7-bd76-85ef178726c3
+ Account: AUTH_1234
+ Containers: 1
+ Objects: 0
+ Bytes: 0
+ Accept-Ranges: bytes
+ X-Trans-Id: tx25c1a6969d8f4372b63912f411de3c3b
+
+**Note: Keystone currently allows any valid token to do anything with any
+account.**
+
+But, it works as a demo!
-See swift-quick-start.txt in docs folder
## I want OpenStack (all of it)
diff --git a/bin/keystone b/bin/keystone
index 04e1659a..483119f0 100755
--- a/bin/keystone
+++ b/bin/keystone
@@ -33,8 +33,8 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
sys.path.insert(0, possible_topdir)
-
-import tools.tracer #load this first
+#load this first
+import tools.tracer
import keystone
from keystone.common import config
from keystone.common import wsgi
@@ -49,8 +49,8 @@ if __name__ == '__main__':
# Handle a special argument to support starting two endpoints
common_group.add_option('-a', '--admin-port', default=8081,
dest="admin_port", metavar="PORT",
- help = "specifies port for Admin API to listen"
- "on (default is 8080)")
+ help="specifies port for Admin API to listen"
+ "on (default is 8081)")
# Parse arguments and load config
(options, args) = config.parse_options(parser)
@@ -58,7 +58,8 @@ if __name__ == '__main__':
# Start services
try:
# Load Service API server
- conf, app = config.load_paste_app('server', options, args)
+ conf, app = config.load_paste_app(
+ 'keystone-legacy-auth', options, args)
debug = options.get('debug') or conf.get('debug', False)
debug = debug in [True, "True", "1"]
@@ -69,21 +70,21 @@ if __name__ == '__main__':
print "Using config file:", config_file
server = wsgi.Server()
- server.start(app, int(conf['bind_port']), conf['bind_host'])
- print "Service API listening on %s:%s" % (conf['bind_host'],
- conf['bind_port'])
+ server.start(app, int(conf['server_bind_port']),
+ conf['server_bind_host'])
+ print "Service API listening on %s:%s" % (conf['server_bind_host'],
+ conf['server_bind_port'])
# Load Admin API server
admin_conf, admin_app = config.load_paste_app('admin', options, args)
admin_server = wsgi.Server()
admin_bind = options.get('admin_port') or admin_conf.get('bind_port')
- if conf['bind_port'] == admin_bind:
+ if conf['server_bind_port'] == admin_bind:
admin_bind += 1
admin_server.start(admin_app, int(admin_bind),
admin_conf['bind_host'])
print "Admin API listening on %s:%s" % (admin_conf['bind_host'],
admin_bind)
-
# Wait until done
server.wait()
except RuntimeError, e:
diff --git a/bin/keystone-auth b/bin/keystone-auth
index c83af24c..179a0bef 100755
--- a/bin/keystone-auth
+++ b/bin/keystone-auth
@@ -33,8 +33,8 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
sys.path.insert(0, possible_topdir)
-
-import tools.tracer #load this first
+#load this first
+import tools.tracer
import keystone
from keystone.common import config
from keystone.common import wsgi
@@ -49,22 +49,24 @@ if __name__ == '__main__':
# Parse arguments and load config
(options, args) = config.parse_options(parser)
- debug = options.get('debug') or conf.get('debug', False)
- debug = debug in [True, "True", "1"]
- verbose = options.get('verbose') or conf.get('verbose', False)
- verbose = verbose in [True, "True", "1"]
- if debug or verbose:
- config_file = config.find_config_file(options, args)
- print "Using config file:", config_file
# Start services
try:
# Load Service API server
- conf, app = config.load_paste_app('server', options, args)
+ conf, app = config.load_paste_app('keystone-legacy-auth', options, args)
+ debug = options.get('debug') or conf.get('debug', False)
+ debug = debug in [True, "True", "1"]
+ verbose = options.get('verbose') or conf.get('verbose', False)
+ verbose = verbose in [True, "True", "1"]
+ if debug or verbose:
+ config_file = config.find_config_file(options, args)
+ print "Using config file:", config_file
+
server = wsgi.Server()
- server.start(app, int(conf['bind_port']), conf['bind_host'])
- print "Service API listening on %s:%s" % (conf['bind_host'],
- conf['bind_port'])
+ server.start(app, int(conf['server_bind_port']),
+ conf['server_bind_host'])
+ print "Service API listening on %s:%s" % (conf['server_bind_host'],
+ conf['server_bind_port'])
server.wait()
except RuntimeError, e:
sys.exit("ERROR: %s" % e)
diff --git a/bin/keystone-manage b/bin/keystone-manage
index 496d5337..df8d055b 100755
--- a/bin/keystone-manage
+++ b/bin/keystone-manage
@@ -76,7 +76,7 @@ def Main():
parser.error('No object type specified for first argument')
object_type = args[0]
- if object_type in ['user', 'tenant', 'role', 'baseURLs' , 'token']:
+ if object_type in ['user', 'tenant', 'role', 'baseURLs' , 'token', 'tenant_baseURL']:
pass
else:
parser.error('%s is not a supported object type' % object_type)
@@ -124,9 +124,9 @@ def Main():
tenant = args[4]
object.tenant_id = tenant
db_api.user_create(object)
- print "User created successfully. ID=%s" % object.id
+ print "SUCCESS: User %s created." % object.id
except Exception as exc:
- print "ERROR: Failed to create user: %s" % exc
+ print "ERROR: Failed to create user %s: %s" % (object_id, exc)
return
elif command == "disable":
try:
@@ -135,9 +135,9 @@ def Main():
raise IndexError("User %s not found" % object_id)
object.enabled = False
db_api.user_update(object_id, object)
- print "User disabled: %s" % object.id
+ print "SUCCESS: User %s disabled." % object.id
except Exception as exc:
- print "ERROR: Failed to disable user: %s" % exc
+ print "ERROR: Failed to disable user %s: %s" % (object_id, exc)
return
elif command == "list":
try:
@@ -168,10 +168,10 @@ def Main():
object.id = object_id
object.enabled = True
db_api.tenant_create(object)
- print "Tenant created successfully. ID=%s" % object.id
+ print "SUCCESS: Tenant %s created." % object.id
return
except Exception as exc:
- print "ERROR: Failed to create tenant: %s" % exc
+ print "ERROR: Failed to create tenant %s: %s" % (object_id, exc)
return
elif command == "list":
try:
@@ -183,7 +183,7 @@ def Main():
for row in objects:
print row.id, row.enabled
except Exception, e:
- print 'Error getting all users:', str(e)
+ print 'Error getting all users: %s', str(e)
return
elif command == "disable":
try:
@@ -192,9 +192,9 @@ def Main():
raise IndexError("Tenant %s not found" % object_id)
object.enabled = False
db_api.tenant_update(object_id, object)
- print "Tenant disabled: %s" % object.id
+ print "SUCCESS: Tenant %s disabled." % object.id
except Exception as exc:
- print "ERROR: Failed to disable tenant: %s" % exc
+ print "ERROR: Failed to disable tenant %s: %s" % (object_id, exc)
return
elif object_type == "role":
if command == "add":
@@ -202,10 +202,10 @@ def Main():
object = db_models.Role()
object.id = object_id
db_api.role_create(object)
- print "Role created successfully. ID=%s" % object.id
+ print "SUCCESS: Role %s created successfully." % object.id
return
except Exception as exc:
- print "ERROR: Failed to create role: %s" % exc
+ print "ERROR: Failed to create role %s: %s" % (object_id, exc)
return
elif command == "list":
if len(args) == 3:
@@ -214,7 +214,8 @@ def Main():
objects = db_api.tenant_role_assignments_get(tenant)
if objects == None:
raise IndexError("Assignments not found")
- print 'user', 'role'
+ print 'Role assignments for tenant %s' % tenant
+ print 'User', 'Role'
print '-' * 20
for row in objects:
print row.user_id, row.role_id
@@ -228,7 +229,8 @@ def Main():
objects = db_api.role_get_all()
if objects == None:
raise IndexError("Roles not found")
- print 'role'
+ print 'All roles'
+ print 'Role'
print '-' * 20
for row in objects:
print row.id
@@ -251,15 +253,16 @@ def Main():
if tenant != None:
object.tenant_id = tenant
db_api.user_role_add(object)
- print "Successfully granted %s the %s role on %s" %\
+ print "SUCCESS: Granted %s the %s role on %s." %\
(object.user_id, object.role_id, object.tenant_id)
except Exception as exc:
- print "ERROR: Failed to grant role: %s" % exc
+ print "ERROR: Failed to grant role %s to %s on %s: %s" % (object_id, user, tenant, exc)
return
elif object_type == "baseURLs":
if command == "add":
if len(args) < 8:
- parser.error("Missing arguments: baseURLs add 'region' 'service'"\
+ parser.error("Missing arguments: baseURLs add " \
+ "'region' 'service'" \
"'publicURL' 'adminURL' 'internalURL' 'enabled'")
region = args[2]
service = args[3]
@@ -276,10 +279,12 @@ def Main():
object.internal_url = internal_url
object.enabled = enabled
object = db_api.baseurls_create(object)
- print "BaseURl created successfully. ID=%s" % object.id
+ print "SUCCESS: Created BaseURL for %s pointing to %s." % \
+ (object.service, object.public_url)
return
except Exception as exc:
- print "ERROR: Failed to create BaseURLs: %s" % exc
+ print "ERROR: Failed to create BaseURL for %s: %s" % (service,
+ exc)
return
elif command == "list":
if len(args) == 3:
@@ -288,8 +293,9 @@ def Main():
objects = db_api.baseurls_ref_get_by_tenant(tenant)
if objects == None:
raise IndexError("URLs not found")
+ print 'Endpoints (BaseURLs) for tenant %s' % tenant
print 'service', 'region', 'Public URL'
- print '-' * 20
+ print '-' * 30
for row in objects:
print row.service, row.region, row.public_url
except Exception, e:
@@ -302,6 +308,7 @@ def Main():
objects = db_api.baseurls_get_all()
if objects == None:
raise IndexError("URLs not found")
+ print 'All Endpoints (BaseURLs)'
print 'service', 'region', 'Public URL'
print '-' * 20
for row in objects:
@@ -309,6 +316,25 @@ def Main():
except Exception, e:
print 'Error getting all BaseURLs:', str(e)
return
+ elif object_type == "tenant_baseURL":
+ if command == "add":
+ if len(args) < 4:
+ parser.error("Missing arguments: baseURLs add 'tenant'\
+ 'baseURL'")
+
+ tenant_id = args[2]
+ baseURLs_id = args[3]
+ try:
+ object = db_models.TenantBaseURLAssociation()
+ object.tenant_id = tenant_id
+ object.baseURLs_id = baseURLs_id
+ object = db_api.baseurls_ref_add(object)
+ print "SUCCESS: BaseURL %s added to tenant %s." % \
+ (baseURLs_id, tenant_id)
+ return
+ except Exception as exc:
+ print "ERROR: Failed to create BaseURL Ref: %s" % exc
+ return
elif object_type == "token":
if command == "add":
if len(args) < 6:
@@ -324,10 +350,10 @@ def Main():
"%Y%m%dT%H:%M")
object.expires = tuple_time
db_api.token_create(object)
- print "Token created successfully. ID=%s" % object.token_id
+ print "SUCCESS: Token %s created." % object.token_id
return
except Exception as exc:
- print "ERROR: Failed to create token: %s" % exc
+ print "ERROR: Failed to create token %s: %s" % (object_id, exc)
return
elif command == "list":
try:
@@ -348,13 +374,14 @@ def Main():
raise IndexError("Token %s not found" % object_id)
else:
db_api.token_delete(object_id)
- print 'Token %s deleted' % object_id
+ print 'SUCCESS: Token %s deleted.' % object_id
except Exception, e:
- print 'Error deleting token %s:' % object_id, str(e)
+ print 'ERROR: Failed to delete token %s: %s' % \
+ object_id, str(e)
return
# Command not handled
- print ("Fail: %s %s not yet supported" % (object_type, command))
+ print ("ERROR: %s %s not yet supported" % (object_type, command))
if __name__ == '__main__':
diff --git a/bin/sampledata.sh b/bin/sampledata.sh
index 47fa21f7..46135dd2 100755
--- a/bin/sampledata.sh
+++ b/bin/sampledata.sh
@@ -38,10 +38,9 @@
./keystone-manage $* role grant Admin joeadmin ANOTHER:TENANT
#BaseURLs
-./keystone-manage $* baseURLs add DFW cloudFiles public.cloudfiles.com admin.cloudfiles.com internal.cloudfiles.com 1
-#v1.0 URLs
-./keystone-manage $* baseURLs add DFW X-Storage-Url https://storage.clouddrive.com/v1/%tenant_id% https://storage.clouddrive.com/v1/%tenant_id% https://storage.clouddrive.com/v1/%tenant_id% 1
-./keystone-manage $* baseURLs add DFW X-Server-Management-Url https://servers.api.rackspacecloud.com/v1.0/%tenant_id% https://servers.api.rackspacecloud.com/v1.0/%tenant_id% https://servers.api.rackspacecloud.com/v1.0/%tenant_id% 1
+./keystone-manage $* baseURLs add DFW cloudFiles http://127.0.0.1:8888/v1/AUTH_%tenant_id% admin.cloudfiles.com internal.cloudfiles.com 1
+./keystone-manage $* baseURLs add DFW cloudFilesCDN https://storage.clouddrive.com/v1/%tenant_id% https://storage.clouddrive.com/v1/%tenant_id% https://storage.clouddrive.com/v1/%tenant_id% 1
+./keystone-manage $* baseURLs add DFW cloudServers http://localhost:8008/v1.0/%tenant_id% https://servers.api.rackspacecloud.com/v1.0/%tenant_id% https://servers.api.rackspacecloud.com/v1.0/%tenant_id% 1
# Groups
#./keystone-manage $* group add Admin 1234
@@ -58,3 +57,8 @@
./keystone-manage $* token add 999888777666 admin 1234 2015-02-05T00:00
./keystone-manage $* token add 000999 admin 1234 2010-02-05T00:00
./keystone-manage $* token add 999888777 disabled 1234 2015-02-05T00:00
+
+#Tenant Role
+./keystone-manage $*tenant_baseURL add 1234 1
+./keystone-manage $*tenant_baseURL add 1234 2
+./keystone-manage $*tenant_baseURL add 1234 3 \ No newline at end of file
diff --git a/docs/guide/src/docbkx/identitydevguide.xml b/docs/guide/src/docbkx/identitydevguide.xml
index 5af5c532..f30cb51b 100644..100755
--- a/docs/guide/src/docbkx/identitydevguide.xml
+++ b/docs/guide/src/docbkx/identitydevguide.xml
@@ -60,7 +60,7 @@
</copyright>
<releaseinfo>API v2.0</releaseinfo>
<productname>Keystone - OpenStack Identity</productname>
- <pubdate>2011-06-01</pubdate>
+ <pubdate>2011-06-10</pubdate>
<legalnotice role="apache2">
<annotation>
<remark>Copyright details are filled in by the template.</remark>
@@ -106,11 +106,18 @@
resources are accessible with it. A token may be
revoked at anytime and is valid for a finite duration.
</para>
+ <para>
+ While Keystone supports token-based authentication in this release,
+ the intention is for it to support additional protocols in the
+ future. The desire is to have it be an integration service, and not
+ a full-fledged identity store and management solution.
+ </para>
</section>
<section>
<title>Tenant</title>
<para>
- Depending on the operator, a tenant may map to a customer,
+ A container used to group or isolate resources and/or identity
+ objects. Depending on the operator, a tenant may map to a customer,
account, organization, or project.
</para>
</section>
@@ -118,12 +125,9 @@
<title>User</title>
<para>
Users have a login and may be assigned tokens to access
- resources.
+ resources. Users may be directly assigned to a particular tenant and
+ behave as if they are contained in that tenant.
</para>
- <note>
- This is a Rackspace extensions to support a local identity store.
- Extending this to work on any backing store is out of scope.
- </note>
</section>
<section>
<title>Role</title>
@@ -133,15 +137,6 @@
and operators. Tenant administrators may assign roles to users.
</para>
</section>
- <section>
- <title>Group</title>
- <para>
- A group of users. Groups may be used to organize and assign
- privileges to a group of related users. For example, an operator
- may create a "delinquent" group, which will assign limited
- privileges to users who have past due bills.
- </para>
- </section>
</chapter>
<chapter>
<title>General API Information</title>
@@ -740,11 +735,11 @@ Host: identity.api.openstack.org/v1.1/
<section>
<title>Overview</title>
<para>The operations described in this chapter allow clients to authenticate and get
- access tokens and endpoints. </para>
+ access tokens and service endpoints. </para>
</section>
<section>
<title>Core Service API Proposal</title>
- <note>The following table of calls is proposed as code Keystone APIs</note>
+ <note>The following table of calls is proposed as core Keystone APIs</note>
<informaltable rules="all">
&URI_REFHEAD;
<tbody>
@@ -829,21 +824,28 @@ Host: identity.api.openstack.org/v1.1/
serviceUnavailable(<errorcode>503</errorcode>)</simpara>
<para>
The operation returns a list of tenants which the caller has
- access to.
+ access to. This call must be authenticated, so a valid token must
+ be passed in as a header.
</para>
- &NO_REQUEST;
<example>
- <title>XML Tenants Response</title>
- <programlisting language="xml">
-<xi:include href="samples/tenants.xml" parse="text"/>
+ <title>Tenants Request with Auth Token</title>
+ <programlisting language="text">
+<xi:include href="samples/tenants-request.txt" parse="text"/>
</programlisting>
</example>
+ &NO_REQUEST;
<example>
<title>JSON Tenants Response</title>
<programlisting language="javascript">
<xi:include href="samples/tenants.json" parse="text"/>
</programlisting>
</example>
+ <example>
+ <title>XML Tenants Response</title>
+ <programlisting language="xml">
+<xi:include href="samples/tenants.xml" parse="text"/>
+</programlisting>
+ </example>
</section>
</chapter>
@@ -853,11 +855,89 @@ Host: identity.api.openstack.org/v1.1/
<section>
<title>Overview</title>
<para>The operations described in this chapter allow service developers to get and validate
- access tokens, manage users, and manage tenants. </para>
+ access tokens, manage users, tenants, roles, and service endpoints. </para>
</section>
<section>
<title>Core Admin API Proposal</title>
<note>The following table of calls is proposed as core Keystone Admin APIs</note>
+
+<section>
+ <title>Admin Access</title>
+ <para>Most calls on the Admin API require authentication. The only calls available without authentication are the calls to discover the service (getting version info, WADL contract, dev guide, help, etc…) and the call to authenticate and get a token.</para>
+<para>
+Authentication is performed by passing in a valid token in the <code>X-Auth-Token</code> header on the request from the client.
+Keystone will verify the token has (or belongs to a user that has) the <code>Admin</code> role.
+</para>
+<para>
+ See the readme file or administrator guides for how to bootstrap Keystone and create your first administrator.
+</para>
+ <table rules="all">
+ <caption>Authentication Header</caption>
+ <thead>
+ <tr>
+ <td>Header Type</td>
+ <td>Name</td>
+ <td>Value</td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>HTTP/1.1 Request</td>
+ <td>X-Auth-Token</td>
+ <td>txfa8426a08eaf</td>
+ </tr>
+ </tbody>
+ </table>
+</section>
+
+ <section>
+ <title>Users</title>
+ <informaltable rules="all">
+ &LONG_URI_REFHEAD;
+ <tbody>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/users</td>
+ <td colspan="3">Create a User.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/users</td>
+ <td colspan="3">Get a list of users.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/users/<parameter>userId</parameter></td>
+ <td colspan="3">Get a user.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/users/<parameter>userId</parameter></td>
+ <td colspan="3">Update a user.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &DELETE; </td>
+ <td colspan="4">/users/<parameter>userId</parameter></td>
+ <td colspan="3">Delete a user.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/users/<parameter>userId</parameter>/<parameter>password</parameter></td>
+ <td colspan="3">Update a user password.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/users/<parameter>userId</parameter>/<parameter>enabled</parameter></td>
+ <td colspan="3">Enable/Disable user.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/users/<parameter>userId</parameter>/<parameter>tenant</parameter></td>
+ <td colspan="3">Update user tenant.</td>
+ </tr>
+ </tbody>
+ </informaltable>
+ </section>
<section>
<title>Tokens</title>
<informaltable rules="all">
@@ -871,7 +951,7 @@ Host: identity.api.openstack.org/v1.1/
<tr>
<td colspan="1"> &DELETE; </td>
<td colspan="4">/tokens/<parameter>tokenId</parameter></td>
- <td colspan="3"> Revoke an existing token.</td>
+ <td colspan="3">Revoke an existing token.</td>
</tr>
</tbody>
</informaltable>
@@ -887,15 +967,36 @@ Host: identity.api.openstack.org/v1.1/
<td colspan="4">/tenants</td>
<td colspan="3">Get a list of tenants.</td>
</tr>
- <tr>
- <td colspan="1"> &GET; </td>
- <td colspan="4">/tenants/<parameter>tenantId</parameter></td>
- <td colspan="3">Get a tenant.</td>
- </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter></td>
+ <td colspan="3">Get a tenant.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/tenants</td>
+ <td colspan="3">Create a tenant.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter></td>
+ <td colspan="3">Update a tenant.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &DELETE; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter></td>
+ <td colspan="3">Delete a tenant.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter>/users</td>
+ <td colspan="3">Get a tenant's users.</td>
+ </tr>
+
</tbody>
</informaltable>
- </section>
-
+ </section>
+
<section>
<title>Endpoints (BaseURLs)</title>
<informaltable rules="all">
@@ -1008,6 +1109,7 @@ Host: identity.api.openstack.org/v1.1/
</tbody>
</informaltable>
</section>
+
<important>All other APIs listed in this section will be extensions used for this
reference implementation of Keystone to support user and tenant management</important>
</section>
@@ -1198,7 +1300,7 @@ Host: identity.api.openstack.org/v1.1/
<tr>
<td colspan="1"> &PUT; </td>
<td colspan="4">/tenants/<parameter>tenantId</parameter></td>
- <td colspan="3">Update a tenant..</td>
+ <td colspan="3">Update a tenant.</td>
</tr>
</tbody>
</informaltable>
@@ -1676,4 +1778,123 @@ Host: identity.api.openstack.org/v1.1/
</section>
</section>
</chapter>
+
+ <chapter>
+ <title>Appendix</title>
+ <section>
+ <title>Rackspace Extenison Proposal</title>
+ <section>
+ <title>Concepts</title>
+ <para>
+ The concepts that are specific to Rackspace extensions are:
+ </para>
+ <section>
+ <title>Group</title>
+ <para>
+ A group of users. Groups may be used to organize and assign
+ privileges to a group of related users. For example, an operator
+ may create a "delinquent" group, which will assign limited
+ privileges to users who have past due bills.
+ </para>
+ </section>
+ </section>
+
+ <note>The following table of calls is proposed as Rackspace-specific
+ extensions for Keystone APIs in this version (2.0)</note>
+
+ <section>
+ <title>Global Groups</title>
+ <informaltable rules="all">
+ &LONG_URI_REFHEAD;
+ <tbody>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/groups</td>
+ <td colspan="3">Create a global group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/groups</td>
+ <td colspan="3">Get a list of global groups.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/groups/<parameter>groupId</parameter></td>
+ <td colspan="3">Get a global group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/groups/<parameter>groupId</parameter></td>
+ <td colspan="3">Update a global group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &DELETE; </td>
+ <td colspan="4">/groups<parameter>/groupId</parameter></td>
+ <td colspan="3">Delete a global group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/groups/<parameter>groupId</parameter>/users</td>
+ <td colspan="3">Get a list of users of a global group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/groups/<parameter>groupId</parameter>/users/<parameter>userId</parameter></td>
+ <td colspan="3">Add user to a global group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &DELETE; </td>
+ <td colspan="4">/groups/<parameter>groupId</parameter>/users/<parameter>userId</parameter></td>
+ <td colspan="3">Delete user from a global group.</td>
+ </tr>
+ </tbody>
+ </informaltable>
+ </section>
+ <section>
+ <title>Tenant Groups</title>
+ <informaltable rules="all">
+ &LONG_URI_REFHEAD;
+ <tbody>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter>/groups</td>
+ <td colspan="3">Get a list of tenant groups.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &POST; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter>/groups</td>
+ <td colspan="3">Create a tenant group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter>/groups/<parameter>groupId</parameter></td>
+ <td colspan="3">Get a tenant group with the specified id.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter>/groups/<parameter>groupId</parameter></td>
+ <td colspan="3">Update a tenant group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &GET; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter>/groups/<parameter>groupId</parameter>/users</td>
+ <td colspan="3">List tenant group users.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &PUT; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter>/groups/<parameter>groupId</parameter>/users/<parameter>userId</parameter></td>
+ <td colspan="3">Add a user to a tenant group.</td>
+ </tr>
+ <tr>
+ <td colspan="1"> &DELETE; </td>
+ <td colspan="4">/tenants/<parameter>tenantId</parameter>/groups/<parameter>groupId</parameter>/users/<parameter>userId</parameter></td>
+ <td colspan="3">Remove user from tenant group.</td>
+ </tr>
+ </tbody>
+ </informaltable>
+ </section>
+
+ </section>
+ </chapter>
+
</book>
diff --git a/docs/guide/src/docbkx/samples/group.json b/docs/guide/src/docbkx/samples/group.json
new file mode 100644
index 00000000..07dc0a10
--- /dev/null
+++ b/docs/guide/src/docbkx/samples/group.json
@@ -0,0 +1 @@
+{"group": {"id": "test_global_group", "description": "A description ..."}} \ No newline at end of file
diff --git a/docs/guide/src/docbkx/samples/group.xml b/docs/guide/src/docbkx/samples/group.xml
new file mode 100644
index 00000000..0f285307
--- /dev/null
+++ b/docs/guide/src/docbkx/samples/group.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<group xmlns="http://docs.openstack.org/identity/api/v2.0" id="test group">
+ <description>A Description of the group</description>
+</group>
diff --git a/docs/guide/src/docbkx/samples/groups.json b/docs/guide/src/docbkx/samples/groups.json
new file mode 100644
index 00000000..06dd58a0
--- /dev/null
+++ b/docs/guide/src/docbkx/samples/groups.json
@@ -0,0 +1 @@
+{"groups": {"values": [{"id": "test_global_group_add", "description": "A description ..."}], "links": []}} \ No newline at end of file
diff --git a/docs/guide/src/docbkx/samples/groups.xml b/docs/guide/src/docbkx/samples/groups.xml
new file mode 100644
index 00000000..a429fdb3
--- /dev/null
+++ b/docs/guide/src/docbkx/samples/groups.xml
@@ -0,0 +1,5 @@
+<groups xmlns="http://docs.openstack.org/identity/api/v2.0">
+ <group xmlns="http://docs.openstack.org/identity/api/v2.0" id="test_global_group_add">
+ <description>A Description of the group</description>
+ </group>
+</groups>
diff --git a/docs/guide/src/docbkx/samples/tenants-request.txt b/docs/guide/src/docbkx/samples/tenants-request.txt
new file mode 100644
index 00000000..9dbf85e5
--- /dev/null
+++ b/docs/guide/src/docbkx/samples/tenants-request.txt
@@ -0,0 +1,5 @@
+GET /v2.0/tenants HTTP/1.1
+Host: identity.api.openstack.org
+Content-Type: application/json
+X-Auth-Token: fa8426a0-8eaf-4d22-8e13-7c1b16a9370c
+Accept: application/json \ No newline at end of file
diff --git a/docs/guide/src/docbkx/samples/tenants.json b/docs/guide/src/docbkx/samples/tenants.json
index 7fb848f7..a2fa2608 100644
--- a/docs/guide/src/docbkx/samples/tenants.json
+++ b/docs/guide/src/docbkx/samples/tenants.json
@@ -1,3 +1,8 @@
+HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Content-Length: 100
+Date: Sun, 1 Jan 2011 9:00:00 GMT
+
{"tenants": {
"values" : [
{
diff --git a/docs/guide/src/docbkx/samples/tenants.xml b/docs/guide/src/docbkx/samples/tenants.xml
index cda2f662..2a9e9c3b 100644
--- a/docs/guide/src/docbkx/samples/tenants.xml
+++ b/docs/guide/src/docbkx/samples/tenants.xml
@@ -1,3 +1,8 @@
+HTTP/1.1 200 OK
+Content-Type: application/xml; charset=UTF-8
+Content-Length: 200
+Date: Sun, 1 Jan 2011 9:00:00 GMT
+
<?xml version="1.0" encoding="UTF-8"?>
<tenants xmlns="http://docs.openstack.org/identity/api/v2.0">
<tenant enabled="true" id="1234">
diff --git a/docs/swift-quick-start.txt b/docs/swift-quick-start.txt
deleted file mode 100644
index f201327b..00000000
--- a/docs/swift-quick-start.txt
+++ /dev/null
@@ -1,121 +0,0 @@
-Quick Start to Integrating Swift and Keystone
----------------------------------------------
-
-1. Install Swift with the included TempAuth. This step is beyond the scope of
- this quick start; see http://swift.openstack.org/development_saio.html for
- a Swift development set up guide.
-
-2. Obtain and install a source copy of Keystone::
-
- git clone https://github.com/rackspace/keystone.git ~/keystone
- cd ~/keystone && sudo python setup.py develop
-
-3. Move included configuration out of the way::
-
- mv ~/keystone/etc ~/keystone/etc-orig
-
-4. Create /etc/keystone configuration directory::
-
- sudo mkdir /etc/keystone
- sudo chmod <user>:<user> /etc/keystone
-
-5. Create /etc/keystone/keystone.conf::
-
- [DEFAULT]
- verbose = True
- debug = True
- default_store = sqlite
- log_file = /etc/keystone/keystone.log
- sql_connection = sqlite:////etc/keystone/keystone.db
- sql_idle_timeout = 30
-
- [app:admin]
- paste.app_factory = keystone.server:admin_app_factory
- bind_host = 0.0.0.0
- bind_port = 8081
-
- [app:server]
- paste.app_factory = keystone.server:app_factory
- bind_host = 0.0.0.0
- bind_port = 8080
-
-6. Start up the Keystone service::
-
- ~/keystone/bin/keystone
-
-7. Create the sample data entries::
-
- cd ~/keystone/bin && ./sampledata.sh
-
-8. Configure Swift's proxy server to use Keystone instead of TempAuth. Here's
- an example /etc/swift/proxy-server.conf::
-
- [DEFAULT]
- bind_port = 8888
- user = <user>
-
- [pipeline:main]
- pipeline = catch_errors cache keystone proxy-server
-
- [app:proxy-server]
- use = egg:swift#proxy
- allow_account_management = true
-
- [filter:keystone]
- use = egg:keystone#tokenauth
- auth_protocol = http
- auth_host = 127.0.0.1
- auth_port = 8081
- admin_token = 999888777666
- delay_auth_decision = 0
- service_protocol = http
- service_host = 127.0.0.1
- service_port = 8100
- service_pass = dTpw
-
- [filter:cache]
- use = egg:swift#memcache
- set log_name = cache
-
- [filter:catch_errors]
- use = egg:swift#catch_errors
-
-9. Restart the Swift proxy to invoke the new configuration::
-
- swift-init proxy restart
-
-10. Obtain an x-auth-token to use::
-
- curl -i http://127.0.0.1:8080/v1.0 \
- -H 'x-auth-user: joeuser' -H 'x-auth-key: secrete'
-
-11. Create an account in Swift using the x-auth-token from above::
-
- curl -X PUT http://127.0.0.1:8888/v1/joeuser \
- -H 'x-auth-token: <token>'
-
-12. Create a container in Swift::
-
- curl -X PUT http://127.0.0.1:8888/v1/joeuser/container \
- -H 'x-auth-token: <token>'
-
-13. Upload an object::
-
- curl -X PUT http://127.0.0.1:8888/v1/joeuser/container/object \
- -H 'x-auth-token: <token>' --data-binary 'test object'
-
-14. Do some listings::
-
- curl http://127.0.0.1:8888/v1/joeuser -H 'x-auth-token: <token>'
- curl http://127.0.0.1:8888/v1/joeuser/container \
- -H 'x-auth-token: <token>'
-
-
-Notes
------
-
-* Keystone does not yet return x-storage-url, so standard Swift tools won't
- work yet.
-* Keystone currently allows any valid token to do anything.
-
-But, it works as a demo!
diff --git a/etc/keystone.conf b/etc/keystone.conf
index e9c59046..7da598fc 100644..100755
--- a/etc/keystone.conf
+++ b/etc/keystone.conf
@@ -26,6 +26,15 @@ sql_connection = sqlite:///../keystone/keystone.db
#
sql_idle_timeout = 30
+#Dictionary Maps every service to a header.Missing services would get header X_(SERVICE_NAME) Key => Service Name, Value => Header Name
+service-header-mappings = {'cloudServers' : 'X-Server-Management-Url' , 'cloudFiles' : 'X-Storage-Url', 'cloudFilesCDN' : 'X-CDN-Management-Url'}
+
+# Address to bind the API server
+#TODO Properties defined within app not available via pipeline.Till then server props stay outside.
+server_bind_host = 0.0.0.0
+
+# Port the bind the API server to
+server_bind_port = 8080
[app:admin]
paste.app_factory = keystone.server:admin_app_factory
@@ -39,8 +48,11 @@ bind_port = 8081
[app:server]
paste.app_factory = keystone.server:app_factory
-# Address to bind the API server
-bind_host = 0.0.0.0
+[pipeline:keystone-legacy-auth]
+pipeline =
+ legacy_auth
+ server
+
+[filter:legacy_auth]
+paste.filter_factory = keystone.frontends.legacy_token_auth:filter_factory
-# Port the bind the API server to
-bind_port = 8080
diff --git a/keystone/auth_protocols/nova_auth_token.py b/keystone/auth_protocols/nova_auth_token.py
index e9d61b74..3a3221ec 100644
--- a/keystone/auth_protocols/nova_auth_token.py
+++ b/keystone/auth_protocols/nova_auth_token.py
@@ -61,6 +61,9 @@ class KeystoneAuthShim(wsgi.Middleware):
user_ref = self.auth.get_user(user_id)
except:
user_ref = self.auth.create_user(user_id)
+ # set admin if user has admin role
+ if user_ref.is_admin() != (req.headers.get('X_ROLE', None) == 'Admin'):
+ self.auth.modify_user(user_ref, admin=req.headers.get('X_ROLE') == 'Admin')
project_id = req.headers['X_TENANT']
try:
project_ref = self.auth.get_project(project_id)
diff --git a/keystone/common/config.py b/keystone/common/config.py
index 34281192..34281192 100644..100755
--- a/keystone/common/config.py
+++ b/keystone/common/config.py
diff --git a/keystone/content/identitydevguide.pdf b/keystone/content/identitydevguide.pdf
index b3a7f978..2113e625 100644
--- a/keystone/content/identitydevguide.pdf
+++ b/keystone/content/identitydevguide.pdf
Binary files differ
diff --git a/keystone/db/sqlalchemy/api.py b/keystone/db/sqlalchemy/api.py
index adca784f..df1d4d4e 100644..100755
--- a/keystone/db/sqlalchemy/api.py
+++ b/keystone/db/sqlalchemy/api.py
@@ -1212,3 +1212,13 @@ def baseurls_ref_delete(id, session=None):
with session.begin():
baseurls_ref = baseurls_ref_get(id, session)
session.delete(baseurls_ref)
+
+
+def tenant_baseurls_get_all(tenant_id, session=None):
+ if not session:
+ session = get_session()
+ tba = aliased(models.TenantBaseURLAssociation)
+ baseUrls = aliased(models.BaseUrls)
+ return session.query(baseUrls).join((tba,
+ tba.baseURLs_id == baseUrls.id)).\
+ filter(tba.tenant_id == tenant_id).all()
diff --git a/test/__init__.py b/keystone/frontends/__init__.py
index e69de29b..e69de29b 100644
--- a/test/__init__.py
+++ b/keystone/frontends/__init__.py
diff --git a/keystone/frontends/legacy_token_auth.py b/keystone/frontends/legacy_token_auth.py
new file mode 100644
index 00000000..dcd03477
--- /dev/null
+++ b/keystone/frontends/legacy_token_auth.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+# 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.
+# Not Yet PEP8 standardized
+"""
+RACKSPACE LEGACY AUTH - STUB
+
+This WSGI component
+- transforms rackspace auth header credentials to keystone credentials
+and makes an authentication call on keystone.- transforms response it
+receives into custom headers defined in properties and returns
+the response.
+"""
+import os
+import sys
+import optparse
+import httplib
+import json
+import ast
+
+from webob.exc import Request, Response
+from paste.deploy import loadapp
+from webob.exc import HTTPUnauthorized, HTTPInternalServerError
+
+POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
+ os.pardir,
+ os.pardir,
+ os.pardir))
+if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'keystone', '__init__.py')):
+ sys.path.insert(0, POSSIBLE_TOPDIR)
+
+import keystone
+import keystone.utils as utils
+from keystone.common import wsgi
+from keystone.common import config
+
+PROTOCOL_NAME = "Legacy Authentication"
+
+
+class AuthProtocol(object):
+ """Legacy Auth Middleware that handles authenticating client calls"""
+
+ def __init__(self, app, conf):
+ """ Common initialization code """
+ print "Starting the %s component" % PROTOCOL_NAME
+ self.conf = conf
+ self.app = app
+
+ """Handle 1.0 and 1.1 calls via middleware.
+ Right now Iam treating every call of 1.0 and 1.1 as call
+ to authenticate"""
+ def __call__(self, env, start_response):
+ """ Handle incoming request. Transform. And send downstream. """
+ self.start_response = start_response
+ self.env = env
+ self.request = Request(env)
+ if self.request.path.startswith('/v1.0'
+ ) or self.request.path.startswith('/v1.1'):
+ params = {"passwordCredentials":
+ {"username": utils.get_auth_user(self.request),
+ "password": utils.get_auth_key(self.request)}}
+ #Make request to keystone
+ new_request = Request.blank('/v2.0/tokens')
+ new_request.headers['Content-type'] = 'application/json'
+ new_request.accept = 'text/json'
+ new_request.body = json.dumps(params)
+ new_request.method = 'POST'
+ response = new_request.get_response(self.app)
+ #Handle failures.
+ if not str(response.status).startswith('20'):
+ return response(env, start_response)
+ headers = self.transform_keystone_auth_to_legacy_headers(
+ json.loads(response.body))
+ resp = utils.send_legacy_result(204, headers)
+ return resp(env, start_response)
+ else:
+ # Other calls pass to downstream WSGI component
+ return self.app(self.env, self.start_response)
+
+ def transform_keystone_auth_to_legacy_headers(self, content):
+ headers = {}
+ if "auth" in content:
+ auth = content["auth"]
+ if "token" in auth:
+ headers["X-Auth-Token"] = auth["token"]["id"]
+ if "serviceCatalog" in auth:
+ services = auth["serviceCatalog"]
+ service_mappings = ast.literal_eval(
+ self.conf["service-header-mappings"])
+ for service in services:
+ service_name = service
+ service_urls = ''
+ for endpoint in services[service_name]:
+ if len(service_urls) > 0:
+ service_urls += ','
+ service_urls += endpoint["publicURL"]
+ if len(service_urls) > 0:
+ if service_mappings.get(service_name):
+ headers[service_mappings.get(
+ service_name)] = service_urls
+ else:
+ #For Services that are not mapped,
+ #use X- prefix followed by service name.
+ headers['X-' + service_name.upper()] = service_urls
+ return headers
+
+
+def filter_factory(global_conf, **local_conf):
+ """Returns a WSGI filter app for use with paste.deploy."""
+ conf = global_conf.copy()
+ conf.update(local_conf)
+
+ def auth_filter(app):
+ return AuthProtocol(app, conf)
+ return auth_filter
diff --git a/keystone/logic/service.py b/keystone/logic/service.py
index 0108feb1..4de20832 100755
--- a/keystone/logic/service.py
+++ b/keystone/logic/service.py
@@ -64,6 +64,12 @@ class IdentityService(object):
else:
dtoken = db_api.token_for_user_tenant(duser.id,
credentials.tenant_id)
+ tenant_id = None
+ if credentials.tenant_id:
+ tenant_id = credentials.tenant_id
+ else:
+ tenant_id = duser.tenant_id
+
if not dtoken or dtoken.expires < datetime.now():
# Create new token
dtoken = db_models.Token()
@@ -73,8 +79,9 @@ class IdentityService(object):
dtoken.tenant_id = credentials.tenant_id
dtoken.expires = datetime.now() + timedelta(days=1)
db_api.token_create(dtoken)
-
- return self.__get_auth_data(dtoken)
+ #if tenant_id is passed in the call that tenant_id is passed else
+ #user's default tenant_id is used.
+ return self.__get_auth_data(dtoken, tenant_id)
def validate_token(self, admin_token, token_id, belongs_to=None):
self.__validate_token(admin_token)
@@ -838,12 +845,13 @@ class IdentityService(object):
#
- def __get_auth_data(self, dtoken):
+ def __get_auth_data(self, dtoken, tenant_id):
"""return AuthData object for a token"""
-
- token = auth.Token(dtoken.expires, dtoken.token_id, dtoken.tenant_id)
-
- return auth.AuthData(token)
+ base_urls = None
+ if tenant_id != None:
+ base_urls = db_api.tenant_baseurls_get_all(tenant_id)
+ token = auth.Token(dtoken.expires, dtoken.token_id, tenant_id)
+ return auth.AuthData(token, base_urls)
def __get_validate_data(self, dtoken, duser):
"""return ValidateData object for a token/user pair"""
diff --git a/keystone/logic/types/auth.py b/keystone/logic/types/auth.py
index 13dbf6cb..c52c66da 100644..100755
--- a/keystone/logic/types/auth.py
+++ b/keystone/logic/types/auth.py
@@ -120,24 +120,78 @@ class User(object):
class AuthData(object):
"Authentation Information returned upon successful login."
- def __init__(self, token):
+ def __init__(self, token, base_urls=None):
self.token = token
+ self.base_urls = base_urls
+ self.d = {}
+ if self.base_urls != None:
+ self.__convert_baseurls_to_dict()
def to_xml(self):
dom = etree.Element("auth",
- xmlns="http://docs.openstack.org/identity/api/v2.0")
+ xmlns="http://docs.openstack.org/identity/api/v2.0")
token = etree.Element("token",
expires=self.token.expires.isoformat())
token.set("id", self.token.token_id)
dom.append(token)
+ if self.base_urls != None:
+ service_catalog = etree.Element("serviceCatalog")
+ for key, key_base_urls in self.d.items():
+ service = etree.Element("service",
+ name=key)
+ for base_url in key_base_urls:
+ endpoint = etree.Element("endpoint")
+ if base_url.region:
+ endpoint.set("region", base_url.region)
+ if base_url.public_url:
+ endpoint.set("publicURL",
+ base_url.public_url.replace('%tenant_id%',\
+ self.token.tenant_id))
+ if base_url.admin_url:
+ endpoint.set("adminURL",
+ base_url.admin_url.replace('%tenant_id%',\
+ self.token.tenant_id))
+ if base_url.internal_url:
+ endpoint.set("internalURL",
+ base_url.internal_url.replace('%tenant_id%',\
+ self.token.tenant_id))
+ service.append(endpoint)
+ service_catalog.append(service)
+ dom.append(service_catalog)
return etree.tostring(dom)
+ def __convert_baseurls_to_dict(self):
+ for base_url in self.base_urls:
+ if base_url.service not in self.d:
+ self.d[base_url.service] = list()
+ self.d[base_url.service].append(base_url)
+
def to_json(self):
token = {}
token["id"] = self.token.token_id
token["expires"] = self.token.expires.isoformat()
auth = {}
auth["token"] = token
+ if self.base_urls != None:
+ service_catalog = {}
+ for key, key_base_urls in self.d.items():
+ endpoints = []
+ for base_url in key_base_urls:
+ endpoint = {}
+ if base_url.region:
+ endpoint["region"] = base_url.region
+ if base_url.public_url:
+ endpoint["publicURL"] = base_url.public_url.replace( \
+ '%tenant_id%', self.token.tenant_id)
+ if base_url.admin_url:
+ endpoint["adminURL"] = base_url.admin_url.replace( \
+ '%tenant_id%', self.token.tenant_id)
+ if base_url.internal_url:
+ endpoint["internalURL"] = base_url.internal_url.\
+ replace('%tenant_id%', self.token.tenant_id)
+ endpoints.append(endpoint)
+ service_catalog[key] = endpoints
+ auth["serviceCatalog"] = service_catalog
ret = {}
ret["auth"] = auth
return json.dumps(ret)
diff --git a/keystone/server.py b/keystone/server.py
index fd4b50d7..139a47d8 100644..100755
--- a/keystone/server.py
+++ b/keystone/server.py
@@ -175,37 +175,6 @@ class AuthController(wsgi.Controller):
service.revoke_token(utils.get_auth_token(req), token_id))
-class LegacyAuthController(wsgi.Controller):
- """
- Auth Controller for v1.x -
- Controller for token related operations
- """
-
- def __init__(self, options):
- self.options = options
- self.request = None
-
- @utils.wrap_error
- def authenticate(self, req):
- self.request = req
-
- creds = auth.PasswordCredentials(utils.get_auth_user(req),
- utils.get_auth_key(req),
- None)
-
- """HTTP/1.1 204 No Content
- Date: Mon, 12 Nov 2007 15:32:21 GMT
- X-Storage-Url: https://storage.clouddrive.com/v1/CF_xer7_34
- X-CDN-Management-Url: https://cdn.clouddrive.com/v1/CF_xer7_34
- X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
- Content-Length: 0
- Content-Type: text/plain; charset=UTF-8"""
-
- result = service.authenticate(creds)
- headers = {"X-Auth-Token": result.token.token_id}
- return utils.send_legacy_result(204, headers)
-
-
class TenantController(wsgi.Controller):
"""
Tenant Controller -
@@ -563,22 +532,8 @@ class KeystoneAPI(wsgi.Router):
db_api.configure_db(options)
- # Legacy Token Operations
- auth_controller = AuthController(options)
- legacy_auth_controller = LegacyAuthController(options)
- mapper.connect("/v1.0", controller=legacy_auth_controller,
- action="authenticate")
- mapper.connect("/v1.0/", controller=legacy_auth_controller,
- action="authenticate")
-
- mapper.connect("/v1.1/tokens", controller=auth_controller,
- action="authenticate",
- conditions=dict(method=["POST"]))
- mapper.connect("/v1.1/tokens/", controller=auth_controller,
- action="authenticate",
- conditions=dict(method=["POST"]))
-
# Token Operations
+ auth_controller = AuthController(options)
mapper.connect("/v2.0/tokens", controller=auth_controller,
action="authenticate",
conditions=dict(method=["POST"]))
@@ -627,20 +582,6 @@ class KeystoneAdminAPI(wsgi.Router):
mapper = routes.Mapper()
db_api.configure_db(options)
-
- # Legacy Token Operations
- legacy_auth_controller = LegacyAuthController(options)
- mapper.connect("/v1.0", controller=legacy_auth_controller,
- action="authenticate")
- mapper.connect("/v1.0/", controller=legacy_auth_controller,
- action="authenticate")
- mapper.connect("/v1.1/tokens", controller=legacy_auth_controller,
- action="authenticate",
- conditions=dict(method=["POST"]))
- mapper.connect("/v1.1/tokens/", controller=legacy_auth_controller,
- action="authenticate",
- conditions=dict(method=["POST"]))
-
# Token Operations
auth_controller = AuthController(options)
mapper.connect("/v2.0/tokens", controller=auth_controller,
@@ -735,7 +676,7 @@ class KeystoneAdminAPI(wsgi.Router):
controller=user_controller,
action="set_user_password",
conditions=dict(method=["PUT"]))
- mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}/add",
+ mapper.connect("/v2.0/tenants/{tenant_id}/users/{user_id}/add",
controller=user_controller,
action="add_user_tenant",
conditions=dict(method=["PUT"]))
diff --git a/test/EchoSOAPUI.xml b/keystone/test/EchoSOAPUI.xml
index 8a74eee0..8a74eee0 100644
--- a/test/EchoSOAPUI.xml
+++ b/keystone/test/EchoSOAPUI.xml
diff --git a/test/IdentitySOAPUI.xml b/keystone/test/IdentitySOAPUI.xml
index 3cf2984e..3cf2984e 100644
--- a/test/IdentitySOAPUI.xml
+++ b/keystone/test/IdentitySOAPUI.xml
diff --git a/test/unit/__init__.py b/keystone/test/__init__.py
index e69de29b..e69de29b 100644
--- a/test/unit/__init__.py
+++ b/keystone/test/__init__.py
diff --git a/test/functional/base.py b/keystone/test/functional/base.py
index 2baffc4a..2baffc4a 100644
--- a/test/functional/base.py
+++ b/keystone/test/functional/base.py
diff --git a/test/functional/ksapi.py b/keystone/test/functional/ksapi.py
index 9c426109..9c426109 100644
--- a/test/functional/ksapi.py
+++ b/keystone/test/functional/ksapi.py
diff --git a/test/functional/run_tests.py b/keystone/test/functional/run_tests.py
index 86b9ec92..e700eb63 100755
--- a/test/functional/run_tests.py
+++ b/keystone/test/functional/run_tests.py
@@ -15,16 +15,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import base
try:
import dtest
except:
print "DTest framework needed. Try running 'pip install dtest'"
exit()
-
import sys
-import base
-
def add_opts(opts):
"""Adds options specific to this test suite."""
diff --git a/test/functional/sample_test.py b/keystone/test/functional/sample_test.py
index ef8ee27a..ef8ee27a 100644
--- a/test/functional/sample_test.py
+++ b/keystone/test/functional/sample_test.py
diff --git a/test/functional/simplerest.py b/keystone/test/functional/simplerest.py
index fd5e0882..fd5e0882 100644
--- a/test/functional/simplerest.py
+++ b/keystone/test/functional/simplerest.py
diff --git a/test/functional/test_tokens.py b/keystone/test/functional/test_tokens.py
index a30c4c9a..a30c4c9a 100644
--- a/test/functional/test_tokens.py
+++ b/keystone/test/functional/test_tokens.py
diff --git a/keystone/test/unit/__init__.py b/keystone/test/unit/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/keystone/test/unit/__init__.py
diff --git a/test/unit/base.py b/keystone/test/unit/base.py
index 0d59bba1..0d59bba1 100644
--- a/test/unit/base.py
+++ b/keystone/test/unit/base.py
diff --git a/test/unit/decorators.py b/keystone/test/unit/decorators.py
index 17a7d432..17a7d432 100644
--- a/test/unit/decorators.py
+++ b/keystone/test/unit/decorators.py
diff --git a/test/unit/test_BaseURLs.py b/keystone/test/unit/test_BaseURLs.py
index fa352f93..fa352f93 100644
--- a/test/unit/test_BaseURLs.py
+++ b/keystone/test/unit/test_BaseURLs.py
diff --git a/test/unit/test_auth.py b/keystone/test/unit/test_auth.py
index e51cbbb6..e51cbbb6 100644
--- a/test/unit/test_auth.py
+++ b/keystone/test/unit/test_auth.py
diff --git a/test/unit/test_authentication.py b/keystone/test/unit/test_authentication.py
index 16160d48..74089023 100644..100755
--- a/test/unit/test_authentication.py
+++ b/keystone/test/unit/test_authentication.py
@@ -38,15 +38,29 @@ class AuthenticationTest(unittest.TestCase):
#self.user = utils.get_user()
self.userdisabled = utils.get_userdisabled()
self.auth_token = utils.get_auth_token()
+ utils.create_baseurls_ref(self.tenant, "1",
+ str(self.auth_token))
+ utils.create_baseurls_ref(self.tenant, "2",
+ str(self.auth_token))
+ utils.create_baseurls_ref(self.tenant, "3",
+ str(self.auth_token))
#self.exp_auth_token = utils.get_exp_auth_token()
#self.disabled_token = utils.get_disabled_token()
def tearDown(self):
+ utils.delete_all_baseurls_ref(self.tenant, self.auth_token)
utils.delete_token(self.token, self.auth_token)
def test_a_authorize(self):
resp, content = utils.get_token('joeuser', 'secrete', self.tenant)
self.assertEqual(200, int(resp['status']))
+ obj = content
+ if not "auth" in obj:
+ raise fault.BadRequestFault("Expecting Auth")
+ auth = obj["auth"]
+ if not "serviceCatalog" in auth:
+ raise fault.BadRequestFault("Expecting Service Catalog")
+
self.assertEqual('application/json', utils.content_type(resp))
def test_a_authorize_xml(self):
@@ -54,11 +68,26 @@ class AuthenticationTest(unittest.TestCase):
self.tenant)
self.assertEqual(200, int(resp['status']))
self.assertEqual('application/xml', utils.content_type(resp))
+ #verify content
+ dom = etree.Element("root")
+ dom.append(etree.fromstring(content))
+ auth = dom.find("{http://docs.openstack.org/identity/api/v2.0}" \
+ "auth")
+ if auth == None:
+ self.fail("Expecting Auth")
+ service_catalog = auth.find(
+ "{http://docs.openstack.org/identity/api/v2.0}" \
+ "serviceCatalog")
+ if service_catalog == None:
+ self.fail("Expecting Service Catalog")
def test_a_authorize_legacy(self):
resp, content = utils.get_token_legacy('joeuser', 'secrete')
self.assertEqual(204, int(resp['status']))
self.assertTrue(resp['x-auth-token'])
+ self.assertTrue(resp['x-server-management-url'])
+ self.assertTrue(resp['x-storage-url'])
+ self.assertTrue(resp['x-cdn-management-url'])
def test_a_authorize_user_disabled(self):
header = httplib2.Http(".cache")
diff --git a/test/unit/test_authn_v2.py b/keystone/test/unit/test_authn_v2.py
index af9d725b..af9d725b 100644
--- a/test/unit/test_authn_v2.py
+++ b/keystone/test/unit/test_authn_v2.py
diff --git a/test/unit/test_common.py b/keystone/test/unit/test_common.py
index e77f7fc8..be017285 100644..100755
--- a/test/unit/test_common.py
+++ b/keystone/test/unit/test_common.py
@@ -25,7 +25,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.abspath(__file__),
import unittest
URL = 'http://localhost:8081/v2.0/'
-URLv1 = 'http://localhost:8081/v1.0/'
+URLv1 = 'http://localhost:8080/v1.0/'
def get_token(user, pswd, tenant_id, kind=''):
header = httplib2.Http(".cache")
diff --git a/test/unit/test_exthandler.py b/keystone/test/unit/test_exthandler.py
index 4379e03f..4379e03f 100644
--- a/test/unit/test_exthandler.py
+++ b/keystone/test/unit/test_exthandler.py
diff --git a/test/unit/test_groups.py b/keystone/test/unit/test_groups.py
index 2d7a7e00..2d7a7e00 100644
--- a/test/unit/test_groups.py
+++ b/keystone/test/unit/test_groups.py
diff --git a/test/unit/test_keystone.py b/keystone/test/unit/test_keystone.py
index 3b17d9b2..3b17d9b2 100644
--- a/test/unit/test_keystone.py
+++ b/keystone/test/unit/test_keystone.py
diff --git a/test/unit/test_roles.py b/keystone/test/unit/test_roles.py
index 10b16d27..10b16d27 100644
--- a/test/unit/test_roles.py
+++ b/keystone/test/unit/test_roles.py
diff --git a/test/unit/test_server.py b/keystone/test/unit/test_server.py
index 294b1e54..294b1e54 100644
--- a/test/unit/test_server.py
+++ b/keystone/test/unit/test_server.py
diff --git a/test/unit/test_tenant_groups.py b/keystone/test/unit/test_tenant_groups.py
index 21bb9221..21bb9221 100644
--- a/test/unit/test_tenant_groups.py
+++ b/keystone/test/unit/test_tenant_groups.py
diff --git a/test/unit/test_tenants.py b/keystone/test/unit/test_tenants.py
index bc639904..bc639904 100644
--- a/test/unit/test_tenants.py
+++ b/keystone/test/unit/test_tenants.py
diff --git a/test/unit/test_token.py b/keystone/test/unit/test_token.py
index 0754f777..0754f777 100644
--- a/test/unit/test_token.py
+++ b/keystone/test/unit/test_token.py
diff --git a/test/unit/test_users.py b/keystone/test/unit/test_users.py
index 083da21f..083da21f 100644
--- a/test/unit/test_users.py
+++ b/keystone/test/unit/test_users.py
diff --git a/test/unit/test_version.py b/keystone/test/unit/test_version.py
index 3e98935e..3e98935e 100644
--- a/test/unit/test_version.py
+++ b/keystone/test/unit/test_version.py
diff --git a/setup.py b/setup.py
index 2c54da52..1ddf18eb 100644
--- a/setup.py
+++ b/setup.py
@@ -37,7 +37,7 @@ setup(
entry_points={
'paste.app_factory': ['main=identity:app_factory'],
'paste.filter_factory': [
- 'remoteauth=keystone:remoteauth_factory',
+ 'remoteauth=keystone.middleware.remoteauth:remoteauth_factory',
'tokenauth=keystone.auth_protocols.auth_token:filter_factory',
],
},
diff --git a/test/kill.sql b/test/kill.sql
deleted file mode 100644
index 66e3733f..00000000
--- a/test/kill.sql
+++ /dev/null
@@ -1,10 +0,0 @@
---
--- Clean up the DB
---
-
-delete from users;
-delete from tenants;
-delete from groups;
-delete from user_group_association;
-delete from user_tenant_association;
-delete from token;
diff --git a/tools/management/delgroup.py b/tools/management/delgroup.py
deleted file mode 100755
index 1b48cd77..00000000
--- a/tools/management/delgroup.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog group_id"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 1:
- parser.error("Incorrect number of arguments")
- else:
- index = args[0]
-
- try:
- o = db_api.group_get(index)
- if o == None:
- raise IndexError("Group %s not found", index)
- else:
- db_api.group_delete(index)
- print 'Group', index, 'deleted.'
-
- except Exception, e:
- print 'Error deleting group', index, str(e)
-
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/getgroup.py b/tools/management/getgroup.py
deleted file mode 100755
index 9bb0e41f..00000000
--- a/tools/management/getgroup.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog group_id"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 1:
- parser.error("Incorrect number of arguments")
- else:
- index = args[0]
-
- try:
- o = db_api.group_get(index)
- if o == None:
- raise IndexError("Group %s not found", index)
-
- print o.id, o.desc
- except Exception, e:
- print 'Error getting group', index, str(e)
-
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/getgroups.py b/tools/management/getgroups.py
deleted file mode 100755
index 2fc94cb9..00000000
--- a/tools/management/getgroups.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog "
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 0:
- parser.error("Incorrect number of arguments")
- else:
- try:
- u = db_api.group_get_all()
- if u == None:
- raise IndexError("Groups not found")
- for row in u:
- print row.id
- except Exception, e:
- print 'Error getting groups:', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/getgroupusers.py b/tools/management/getgroupusers.py
deleted file mode 100755
index 1d663eb4..00000000
--- a/tools/management/getgroupusers.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog group_id"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 1:
- parser.error("Incorrect number of arguments")
- else:
- group_id = args[0]
-
- try:
- g = db_api.group_users(group_id)
- if g == None:
- raise IndexError("Group users not found")
- for row in g:
- print row
- except Exception, e:
- print 'Error getting group users for group', group_id, ':', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/getuser.py b/tools/management/getuser.py
deleted file mode 100755
index af0ba89f..00000000
--- a/tools/management/getuser.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog username"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 1:
- parser.error("Incorrect number of arguments")
- else:
- username = args[0]
- try:
- u = db_api.user_get(username)
- if u == None:
- raise IndexError("User not found")
- print u.id, u.email, u.enabled
- except Exception, e:
- print 'Error finding user', username, ':', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/getusergroups.py b/tools/management/getusergroups.py
deleted file mode 100755
index 33801a93..00000000
--- a/tools/management/getusergroups.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog user_id"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 1:
- parser.error("Incorrect number of arguments")
- else:
- username = args[0]
- try:
- g = db_api.user_groups(username)
- if g == None:
- raise IndexError("User groups not found")
- for row in g:
- print row
- except Exception, e:
- print 'Error getting user groups for user', user_id, ':', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/groupadd.py b/tools/management/groupadd.py
deleted file mode 100755
index 11329e44..00000000
--- a/tools/management/groupadd.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-from keystone.db.sqlalchemy import models
-
-
-def main():
- usage = "usage: %prog group_id group_desc"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 2:
- parser.error("Incorrect number of arguments")
- else:
- group_id = args[0]
- group_desc = args[1]
- try:
- g = models.Group()
- g.id = group_id
- g.desc = group_desc
- db_api.group_create(g)
- print 'Group', g.id, 'created.'
- except Exception, e:
- print 'Error creating group', group_id, ':', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/setuserlock.py b/tools/management/setuserlock.py
deleted file mode 100755
index 7cfa8c15..00000000
--- a/tools/management/setuserlock.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog username enabled"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 2:
- parser.error("Incorrect number of arguments")
- else:
- username = args[0]
- enabled = args[1].capitalize().strip()
-
- if enabled == 'True' or enabled == '1':
- enabled = 1
- elif enabled == 'False' or enabled == '0':
- enabled = 0
- else:
- parser.error("Incorrect arguments value")
-
- try:
- u = db_api.user_get(username)
- if u == None:
- raise IndexError("User not found")
- else:
- values = {'enabled': enabled}
- db_api.user_update(username, values)
- print 'User', u.id, 'updated. Enabled =', enabled
- except Exception, e:
- print 'Error updating user', username, ':', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/setuserpswd.py b/tools/management/setuserpswd.py
deleted file mode 100755
index abfddbda..00000000
--- a/tools/management/setuserpswd.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog username password"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 2:
- parser.error("Incorrect number of arguments")
- else:
- username = args[0]
- password = args[1]
- try:
- u = db_api.user_get(username)
- if u == None:
- raise IndexError("User not found")
- else:
- values = {'password': password}
- db_api.user_update(username, values)
- print 'User', u.id, 'updated.'
- except Exception, e:
- print 'Error updating user', username, ':', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/updategroup.py b/tools/management/updategroup.py
deleted file mode 100755
index 35b4ef66..00000000
--- a/tools/management/updategroup.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-from keystone.db.sqlalchemy import models
-
-
-def main():
- usage = "usage: %prog group_id group_desc"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 2:
- parser.error("Incorrect number of arguments")
- else:
- group = args[0]
- desc = args[1]
- try:
- g = db_api.group_get(group)
- if g == None:
- raise IndexError("Group not found")
- else:
- values = {'desc': desc}
- db_api.group_update(group, values)
- print 'Group', g.id, 'updated.'
- except Exception, e:
- print 'Error updating user', group, ':', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/userdel.py b/tools/management/userdel.py
deleted file mode 100755
index f76bc632..00000000
--- a/tools/management/userdel.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog username"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 1:
- parser.error("Incorrect number of arguments")
- else:
- username = args[0]
- try:
- u = db_api.user_get(username)
- if u == None:
- raise IndexError("User not found")
- else:
- db_api.user_delete(username)
- print 'User', username, 'deleted.'
- except Exception, e:
- print 'Error deleting user', username, ':', str(e)
-
-if __name__ == '__main__':
- main()
diff --git a/tools/management/userupdate.py b/tools/management/userupdate.py
deleted file mode 100755
index 5196d681..00000000
--- a/tools/management/userupdate.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import sys
-
-# 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)
-
-import optparse
-import keystone.db.sqlalchemy.api as db_api
-
-
-def main():
- usage = "usage: %prog username email"
- parser = optparse.OptionParser(usage)
- options, args = parser.parse_args()
- if len(args) != 2:
- parser.error("Incorrect number of arguments")
- else:
- username = args[0]
- email = args[1]
- try:
- u = db_api.user_get(username)
- if u == None:
- raise IndexError("User not found")
- else:
- values = {'email': email}
- db_api.user_update(username, values)
- print 'User', u.id, 'updated.'
- except Exception, e:
- print 'Error updating user', username, ':', str(e)
-
-if __name__ == '__main__':
- main()