Allow user ID for authentication
In Keystone V3 user names are no longer necessarily unique accross domains. A user can still authenticate a user in the non default domain via the V2 API providng they use IDs instead of names. Tenant_ID is already supported, this change adds support for user ID Change-Id: I36ba75f3e67c8cdb959e31923d5e557414ab6f9b
This commit is contained in:
parent
d0b6550d66
commit
dd8bde71ff
@ -64,8 +64,9 @@ class HTTPClient(object):
|
|||||||
os_cache=False, no_cache=True,
|
os_cache=False, no_cache=True,
|
||||||
http_log_debug=False, auth_system='keystone',
|
http_log_debug=False, auth_system='keystone',
|
||||||
auth_plugin=None, auth_token=None,
|
auth_plugin=None, auth_token=None,
|
||||||
cacert=None, tenant_id=None):
|
cacert=None, tenant_id=None, user_id=None):
|
||||||
self.user = user
|
self.user = user
|
||||||
|
self.user_id = user_id
|
||||||
self.password = password
|
self.password = password
|
||||||
self.projectid = projectid
|
self.projectid = projectid
|
||||||
self.tenant_id = tenant_id
|
self.tenant_id = tenant_id
|
||||||
@ -456,6 +457,10 @@ class HTTPClient(object):
|
|||||||
if self.auth_token:
|
if self.auth_token:
|
||||||
body = {"auth": {
|
body = {"auth": {
|
||||||
"token": {"id": self.auth_token}}}
|
"token": {"id": self.auth_token}}}
|
||||||
|
elif self.user_id:
|
||||||
|
body = {"auth": {
|
||||||
|
"passwordCredentials": {"userId": self.user_id,
|
||||||
|
"password": self._get_password()}}}
|
||||||
else:
|
else:
|
||||||
body = {"auth": {
|
body = {"auth": {
|
||||||
"passwordCredentials": {"username": self.user,
|
"passwordCredentials": {"username": self.user,
|
||||||
|
@ -285,6 +285,11 @@ class OpenStackComputeShell(object):
|
|||||||
parser.add_argument('--os_username',
|
parser.add_argument('--os_username',
|
||||||
help=argparse.SUPPRESS)
|
help=argparse.SUPPRESS)
|
||||||
|
|
||||||
|
parser.add_argument('--os-user-id',
|
||||||
|
metavar='<auth-user-id>',
|
||||||
|
default=utils.env('OS_USER_ID'),
|
||||||
|
help=_('Defaults to env[OS_USER_ID].'))
|
||||||
|
|
||||||
parser.add_argument('--os-password',
|
parser.add_argument('--os-password',
|
||||||
metavar='<auth-password>',
|
metavar='<auth-password>',
|
||||||
default=utils.env('OS_PASSWORD', 'NOVA_PASSWORD'),
|
default=utils.env('OS_PASSWORD', 'NOVA_PASSWORD'),
|
||||||
@ -550,6 +555,7 @@ class OpenStackComputeShell(object):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
os_username = args.os_username
|
os_username = args.os_username
|
||||||
|
os_user_id = args.os_user_id
|
||||||
os_password = None # Fetched and set later as needed
|
os_password = None # Fetched and set later as needed
|
||||||
os_tenant_name = args.os_tenant_name
|
os_tenant_name = args.os_tenant_name
|
||||||
os_tenant_id = args.os_tenant_id
|
os_tenant_id = args.os_tenant_id
|
||||||
@ -606,9 +612,10 @@ class OpenStackComputeShell(object):
|
|||||||
auth_plugin.parse_opts(args)
|
auth_plugin.parse_opts(args)
|
||||||
|
|
||||||
if not auth_plugin or not auth_plugin.opts:
|
if not auth_plugin or not auth_plugin.opts:
|
||||||
if not os_username:
|
if not os_username and not os_user_id:
|
||||||
raise exc.CommandError(_("You must provide a username "
|
raise exc.CommandError(_("You must provide a username "
|
||||||
"via either --os-username or env[OS_USERNAME]"))
|
"or user id via --os-username, --os-user-id, "
|
||||||
|
"env[OS_USERNAME] or env[OS_USER_ID]"))
|
||||||
|
|
||||||
if not os_tenant_name and not os_tenant_id:
|
if not os_tenant_name and not os_tenant_id:
|
||||||
raise exc.CommandError(_("You must provide a tenant name "
|
raise exc.CommandError(_("You must provide a tenant name "
|
||||||
@ -639,8 +646,9 @@ class OpenStackComputeShell(object):
|
|||||||
raise exc.CommandError(_("You must provide an auth url "
|
raise exc.CommandError(_("You must provide an auth url "
|
||||||
"via either --os-auth-url or env[OS_AUTH_URL]"))
|
"via either --os-auth-url or env[OS_AUTH_URL]"))
|
||||||
|
|
||||||
self.cs = client.Client(options.os_compute_api_version, os_username,
|
self.cs = client.Client(options.os_compute_api_version,
|
||||||
os_password, os_tenant_name, tenant_id=os_tenant_id,
|
os_username, os_password, os_tenant_name,
|
||||||
|
tenant_id=os_tenant_id, user_id=os_user_id,
|
||||||
auth_url=os_auth_url, insecure=insecure,
|
auth_url=os_auth_url, insecure=insecure,
|
||||||
region_name=os_region_name, endpoint_type=endpoint_type,
|
region_name=os_region_name, endpoint_type=endpoint_type,
|
||||||
extensions=self.extensions, service_type=service_type,
|
extensions=self.extensions, service_type=service_type,
|
||||||
|
@ -32,7 +32,7 @@ FAKE_ENV = {'OS_USERNAME': 'username',
|
|||||||
'OS_TENANT_NAME': 'tenant_name',
|
'OS_TENANT_NAME': 'tenant_name',
|
||||||
'OS_AUTH_URL': 'http://no.where'}
|
'OS_AUTH_URL': 'http://no.where'}
|
||||||
|
|
||||||
FAKE_ENV2 = {'OS_USERNAME': 'username',
|
FAKE_ENV2 = {'OS_USER_ID': 'user_id',
|
||||||
'OS_PASSWORD': 'password',
|
'OS_PASSWORD': 'password',
|
||||||
'OS_TENANT_ID': 'tenant_id',
|
'OS_TENANT_ID': 'tenant_id',
|
||||||
'OS_AUTH_URL': 'http://no.where'}
|
'OS_AUTH_URL': 'http://no.where'}
|
||||||
@ -133,25 +133,38 @@ class ShellTest(utils.TestCase):
|
|||||||
matchers.MatchesRegex(r, re.DOTALL | re.MULTILINE))
|
matchers.MatchesRegex(r, re.DOTALL | re.MULTILINE))
|
||||||
|
|
||||||
def test_no_username(self):
|
def test_no_username(self):
|
||||||
required = ('You must provide a username'
|
required = ('You must provide a username or user id'
|
||||||
' via either --os-username or env[OS_USERNAME]',)
|
' via --os-username, --os-user-id,'
|
||||||
|
' env[OS_USERNAME] or env[OS_USER_ID]')
|
||||||
self.make_env(exclude='OS_USERNAME')
|
self.make_env(exclude='OS_USERNAME')
|
||||||
try:
|
try:
|
||||||
self.shell('list')
|
self.shell('list')
|
||||||
except exceptions.CommandError as message:
|
except exceptions.CommandError as message:
|
||||||
self.assertEqual(required, message.args)
|
self.assertEqual(required, message.args[0])
|
||||||
|
else:
|
||||||
|
self.fail('CommandError not raised')
|
||||||
|
|
||||||
|
def test_no_user_id(self):
|
||||||
|
required = ('You must provide a username or user id'
|
||||||
|
' via --os-username, --os-user-id,'
|
||||||
|
' env[OS_USERNAME] or env[OS_USER_ID]')
|
||||||
|
self.make_env(exclude='OS_USER_ID', fake_env=FAKE_ENV2)
|
||||||
|
try:
|
||||||
|
self.shell('list')
|
||||||
|
except exceptions.CommandError as message:
|
||||||
|
self.assertEqual(required, message.args[0])
|
||||||
else:
|
else:
|
||||||
self.fail('CommandError not raised')
|
self.fail('CommandError not raised')
|
||||||
|
|
||||||
def test_no_tenant_name(self):
|
def test_no_tenant_name(self):
|
||||||
required = ('You must provide a tenant name or tenant id'
|
required = ('You must provide a tenant name or tenant id'
|
||||||
' via --os-tenant-name, --os-tenant-id,'
|
' via --os-tenant-name, --os-tenant-id,'
|
||||||
' env[OS_TENANT_NAME] or env[OS_TENANT_ID]',)
|
' env[OS_TENANT_NAME] or env[OS_TENANT_ID]')
|
||||||
self.make_env(exclude='OS_TENANT_NAME')
|
self.make_env(exclude='OS_TENANT_NAME')
|
||||||
try:
|
try:
|
||||||
self.shell('list')
|
self.shell('list')
|
||||||
except exceptions.CommandError as message:
|
except exceptions.CommandError as message:
|
||||||
self.assertEqual(required, message.args)
|
self.assertEqual(required, message.args[0])
|
||||||
else:
|
else:
|
||||||
self.fail('CommandError not raised')
|
self.fail('CommandError not raised')
|
||||||
|
|
||||||
|
@ -73,12 +73,13 @@ class Client(object):
|
|||||||
bypass_url=None, os_cache=False, no_cache=True,
|
bypass_url=None, os_cache=False, no_cache=True,
|
||||||
http_log_debug=False, auth_system='keystone',
|
http_log_debug=False, auth_system='keystone',
|
||||||
auth_plugin=None, auth_token=None,
|
auth_plugin=None, auth_token=None,
|
||||||
cacert=None, tenant_id=None):
|
cacert=None, tenant_id=None, user_id=None):
|
||||||
# FIXME(comstud): Rename the api_key argument above when we
|
# FIXME(comstud): Rename the api_key argument above when we
|
||||||
# know it's not being used as keyword argument
|
# know it's not being used as keyword argument
|
||||||
password = api_key
|
password = api_key
|
||||||
self.projectid = project_id
|
self.projectid = project_id
|
||||||
self.tenant_id = tenant_id
|
self.tenant_id = tenant_id
|
||||||
|
self.user_id = user_id
|
||||||
self.flavors = flavors.FlavorManager(self)
|
self.flavors = flavors.FlavorManager(self)
|
||||||
self.flavor_access = flavor_access.FlavorAccessManager(self)
|
self.flavor_access = flavor_access.FlavorAccessManager(self)
|
||||||
self.images = images.ImageManager(self)
|
self.images = images.ImageManager(self)
|
||||||
@ -126,6 +127,7 @@ class Client(object):
|
|||||||
|
|
||||||
self.client = client.HTTPClient(username,
|
self.client = client.HTTPClient(username,
|
||||||
password,
|
password,
|
||||||
|
user_id=user_id,
|
||||||
projectid=project_id,
|
projectid=project_id,
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
auth_url=auth_url,
|
auth_url=auth_url,
|
||||||
|
@ -59,9 +59,10 @@ class Client(object):
|
|||||||
bypass_url=None, os_cache=False, no_cache=True,
|
bypass_url=None, os_cache=False, no_cache=True,
|
||||||
http_log_debug=False, auth_system='keystone',
|
http_log_debug=False, auth_system='keystone',
|
||||||
auth_plugin=None, auth_token=None,
|
auth_plugin=None, auth_token=None,
|
||||||
cacert=None, tenant_id=None):
|
cacert=None, tenant_id=None, user_id=None):
|
||||||
self.projectid = project_id
|
self.projectid = project_id
|
||||||
self.tenant_id = tenant_id
|
self.tenant_id = tenant_id
|
||||||
|
self.user_id = user_id
|
||||||
self.os_cache = os_cache or not no_cache
|
self.os_cache = os_cache or not no_cache
|
||||||
#TODO(bnemec): Add back in v3 extensions
|
#TODO(bnemec): Add back in v3 extensions
|
||||||
self.agents = agents.AgentsManager(self)
|
self.agents = agents.AgentsManager(self)
|
||||||
@ -91,6 +92,7 @@ class Client(object):
|
|||||||
|
|
||||||
self.client = client.HTTPClient(username,
|
self.client = client.HTTPClient(username,
|
||||||
password,
|
password,
|
||||||
|
user_id=user_id,
|
||||||
projectid=project_id,
|
projectid=project_id,
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
auth_url=auth_url,
|
auth_url=auth_url,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user