Skip to content

Commit d9d23fb

Browse files
author
Ben Miller
committed
Working Icehouse federation
1 parent 1eb7aba commit d9d23fb

3 files changed

Lines changed: 67 additions & 24 deletions

File tree

openstackclient/common/clientmanager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def __init__(self, token=None, url=None, auth_url=None,
4949
user_domain_id=None, user_domain_name=None,
5050
project_domain_id=None, project_domain_name=None,
5151
region_name=None, api_version=None, verify=True,
52-
trust_id=None, timing=None):
52+
trust_id=None, timing=None, federated=False):
5353
self._token = token
5454
self._url = url
5555
self._auth_url = auth_url
@@ -68,6 +68,7 @@ def __init__(self, token=None, url=None, auth_url=None,
6868
self._trust_id = trust_id
6969
self._service_catalog = None
7070
self.timing = timing
71+
self.federated = federated
7172

7273
# verify is the Requests-compatible form
7374
self._verify = verify

openstackclient/identity/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
LOG = logging.getLogger(__name__)
2323

24-
DEFAULT_IDENTITY_API_VERSION = '2.0'
24+
DEFAULT_IDENTITY_API_VERSION = '3'
2525
API_VERSION_OPTION = 'os_identity_api_version'
2626
API_NAME = 'identity'
2727
API_VERSIONS = {
@@ -65,6 +65,7 @@ def make_client(instance):
6565
cacert=instance._cacert,
6666
insecure=instance._insecure,
6767
trust_id=instance._trust_id,
68+
federated=instance.federated,
6869
)
6970
instance.auth_ref = client.auth_ref
7071
return client

openstackclient/shell.py

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,10 @@ def build_option_parser(self, description, version):
328328
help='Trust ID to use when authenticating. '
329329
'This can only be used with Keystone v3 API '
330330
'(Env: OS_TRUST_ID)')
331+
parser.add_argument('--federated', '-F',
332+
dest="federated",
333+
action='store_true',
334+
help="Login via Federated Authentication")
331335

332336
return parser
333337

@@ -348,13 +352,34 @@ def authenticate_user(self):
348352
" either --os-url or env[OS_URL]")
349353

350354
else:
351-
# Validate password flow auth
352-
if not self.options.os_username:
353-
raise exc.CommandError(
354-
"You must provide a username via"
355-
" either --os-username or env[OS_USERNAME]")
355+
if self.options.federated:
356+
#check for an environment variable and a valid v3 auth_url
357+
if "OS_IDENTITY_API_VERSION" in os.environ:
358+
if os.environ.get('OS_IDENTITY_API_VERSION') != '3' \
359+
or 'v2' in self.options.os_auth_url \
360+
or 'V2' in self.options.os_auth_url:
361+
raise exc.CommandError(
362+
"Federated authentication has only been, "
363+
"configured to work with the v3 API "
364+
"you must set env[OS_IDENTITY_API_VERSION]=3 "
365+
"and target a v3 Keystone endpoint.")
366+
else:
367+
raise exc.CommandError(
368+
"If using Federated authentication,"
369+
" you must set env[OS_IDENTITY_API_VERSION]=3 ")
370+
if not self.options.os_auth_url:
371+
raise exc.CommandError(
372+
"If using Federated authentication,"
373+
" you must specify an endpoint with "
374+
"--os-auth-url")
375+
else:
376+
# Validate password flow auth
377+
if not self.options.os_username:
378+
raise exc.CommandError(
379+
"You must provide a username via"
380+
" either --os-username or env[OS_USERNAME]")
356381

357-
if not self.options.os_password:
382+
if not self.options.os_password and not self.options.federated:
358383
# No password, if we've got a tty, try prompting for it
359384
if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty():
360385
# Check for Ctl-D
@@ -365,23 +390,38 @@ def authenticate_user(self):
365390
# No password because we did't have a tty or the
366391
# user Ctl-D when prompted?
367392
if not self.options.os_password:
393+
# No password, if we've got a tty, try prompting for it
394+
if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty():
395+
# Check for Ctl-D
396+
try:
397+
self.options.os_password = getpass.getpass()
398+
except EOFError:
399+
pass
400+
# No password because we did't have a tty or the
401+
# user Ctl-D when prompted?
402+
if not self.options.os_password:
403+
raise exc.CommandError(
404+
"You must provide a password via"
405+
" either --os-password, or env[OS_PASSWORD], "
406+
" or prompted response")
407+
408+
if not ((self.options.os_project_id
409+
or self.options.os_project_name) or
410+
(self.options.os_domain_id
411+
or self.options.os_domain_name) or
412+
self.options.os_trust_id):
368413
raise exc.CommandError(
369-
"You must provide a password via"
370-
" either --os-password, or env[OS_PASSWORD], "
371-
" or prompted response")
372-
373-
if not ((self.options.os_project_id
374-
or self.options.os_project_name) or
375-
(self.options.os_domain_id
376-
or self.options.os_domain_name) or
377-
self.options.os_trust_id):
378-
raise exc.CommandError(
379-
"You must provide authentication scope as a project "
380-
"or a domain via --os-project-id or env[OS_PROJECT_ID], "
381-
"--os-project-name or env[OS_PROJECT_NAME], "
382-
"--os-domain-id or env[OS_DOMAIN_ID], or"
383-
"--os-domain-name or env[OS_DOMAIN_NAME], or "
384-
"--os-trust-id or env[OS_TRUST_ID].")
414+
"You must provide authentication scope as a project "
415+
"or a domain via --os-project-id or env[OS_PROJECT_ID], "
416+
"--os-project-name or env[OS_PROJECT_NAME], "
417+
"--os-domain-id or env[OS_DOMAIN_ID], or"
418+
"--os-domain-name or env[OS_DOMAIN_NAME], or "
419+
"--os-trust-id or env[OS_TRUST_ID].")
420+
421+
if not self.options.os_auth_url:
422+
raise exc.CommandError(
423+
"You must provide an auth url via"
424+
" either --os-auth-url or via env[OS_AUTH_URL]")
385425

386426
if not self.options.os_auth_url:
387427
raise exc.CommandError(
@@ -421,6 +461,7 @@ def authenticate_user(self):
421461
timing=self.options.timing,
422462
api_version=self.api_version,
423463
trust_id=self.options.os_trust_id,
464+
federated=self.options.federated
424465
)
425466
return
426467

0 commit comments

Comments
 (0)