Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Alexander_Naumov:SLE-12:Update
python-novaclient.1737
0002-Support-using-the-Keystone-V3-API-from-the...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0002-Support-using-the-Keystone-V3-API-from-the-Nova-CLI.patch of Package python-novaclient.1737
From d27223eb767c5a6d1d11699ff7891d87f4dcf8e7 Mon Sep 17 00:00:00 2001 From: David Hu <david.hu@hp.com> Date: Thu, 23 Oct 2014 01:50:49 -0700 Subject: [PATCH 2/2] Support using the Keystone V3 API from the Nova CLI This changeset enables support for Keystone V3 authentication on the Nova CLI. This provides consistency between using novaclient as the Nova CLI and using it as a library as the Keystone V3 support already exists for the libary usecase. The bulk of the change surrounds the use of the keystoneclient session object for authentication, retriving the service catalog, and HTTP connection/session management. Co-Authored-By: Morgan Fainberg <morgan.fainberg@gmail.com> Change-Id: Iece9f41320a8770176c7eeb5acd86be4d80cc58f (cherry picked from commit 8597a0c234ef643905d8e356a3986b79b52989c3) --- novaclient/client.py | 15 +++++ novaclient/shell.py | 112 ++++++++++++++++++++++++++---------- novaclient/tests/test_shell.py | 91 +++++++++++++++++++++++++---- novaclient/tests/v1_1/test_shell.py | 1 + novaclient/tests/v3/test_shell.py | 1 + novaclient/v1_1/client.py | 2 - novaclient/v1_1/shell.py | 63 +++++++++++++------- novaclient/v3/client.py | 2 - novaclient/v3/shell.py | 64 ++++++++++++++------- 9 files changed, 268 insertions(+), 83 deletions(-) diff --git a/novaclient/client.py b/novaclient/client.py index b0d9aea..f4ce0eb 100644 --- a/novaclient/client.py +++ b/novaclient/client.py @@ -136,20 +136,35 @@ class CompletionCache(object): class SessionClient(adapter.LegacyJsonAdapter): + def __init__(self, *args, **kwargs): + self.times = [] + super(SessionClient, self).__init__(*args, **kwargs) + def request(self, url, method, **kwargs): # NOTE(jamielennox): The standard call raises errors from # keystoneclient, where we need to raise the novaclient errors. raise_exc = kwargs.pop('raise_exc', True) + start_time = time.time() resp, body = super(SessionClient, self).request(url, method, raise_exc=False, **kwargs) + end_time = time.time() + self.times.append(('%s %s' % (method, url), + start_time, end_time)) + if raise_exc and resp.status_code >= 400: raise exceptions.from_response(resp, body, url, method) return resp, body + def get_timings(self): + return self.times + + def reset_timings(self): + self.times = [] + def _original_only(f): """Indicates and enforces that this function can only be used if we are diff --git a/novaclient/shell.py b/novaclient/shell.py index d8da433..53169d5 100644 --- a/novaclient/shell.py +++ b/novaclient/shell.py @@ -28,7 +28,11 @@ import logging import os import pkgutil import sys +import time +from keystoneclient.auth.identity.generic import password +from keystoneclient.auth.identity.generic import token +from keystoneclient.auth.identity import v3 as identity from keystoneclient import session as ksession from oslo.utils import encodeutils from oslo.utils import strutils @@ -232,6 +236,7 @@ class NovaClientArgumentParser(argparse.ArgumentParser): class OpenStackComputeShell(object): + times = [] def _append_global_identity_args(self, parser): # Register the CLI arguments that have moved to the session object. @@ -240,6 +245,14 @@ class OpenStackComputeShell(object): parser.set_defaults(insecure=utils.env('NOVACLIENT_INSECURE', default=False)) + identity.Password.register_argparse_arguments(parser) + + parser.set_defaults(os_username=utils.env('OS_USERNAME', + 'NOVA_USERNAME')) + parser.set_defaults(os_password=utils.env('OS_PASSWORD', + 'NOVA_PASSWORD')) + parser.set_defaults(os_auth_url=utils.env('OS_AUTH_URL', 'NOVA_URL')) + def get_base_parser(self): parser = NovaClientArgumentParser( prog='nova', @@ -281,22 +294,9 @@ class OpenStackComputeShell(object): default=utils.env('OS_AUTH_TOKEN'), help='Defaults to env[OS_AUTH_TOKEN]') - parser.add_argument('--os-username', - metavar='<auth-user-name>', - default=utils.env('OS_USERNAME', 'NOVA_USERNAME'), - help=_('Defaults to env[OS_USERNAME].')) parser.add_argument('--os_username', 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', - metavar='<auth-password>', - default=utils.env('OS_PASSWORD', 'NOVA_PASSWORD'), - help=_('Defaults to env[OS_PASSWORD].')) parser.add_argument('--os_password', help=argparse.SUPPRESS) @@ -312,10 +312,6 @@ class OpenStackComputeShell(object): default=utils.env('OS_TENANT_ID'), help=_('Defaults to env[OS_TENANT_ID].')) - parser.add_argument('--os-auth-url', - metavar='<auth-url>', - default=utils.env('OS_AUTH_URL', 'NOVA_URL'), - help=_('Defaults to env[OS_AUTH_URL].')) parser.add_argument('--os_auth_url', help=argparse.SUPPRESS) @@ -511,6 +507,19 @@ class OpenStackComputeShell(object): logging.basicConfig(level=logging.DEBUG, format=streamformat) + def _get_keystone_auth(self, session, auth_url, **kwargs): + auth_token = kwargs.pop('auth_token', None) + if auth_token: + return token.Token(auth_url, auth_token, **kwargs) + else: + return password.Password(auth_url, + username=kwargs.pop('username'), + user_id=kwargs.pop('user_id'), + password=kwargs.pop('password'), + user_domain_id=kwargs.pop('user_domain_id'), + user_domain_name=kwargs.pop('user_domain_name'), + **kwargs) + def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser() @@ -570,6 +579,9 @@ class OpenStackComputeShell(object): cacert = args.os_cacert timeout = args.timeout + keystone_session = None + keystone_auth = None + # We may have either, both or none of these. # If we have both, we don't need USERNAME, PASSWORD etc. # Fill in the blanks from the SecretsHelper if possible. @@ -603,6 +615,13 @@ class OpenStackComputeShell(object): must_auth = not (cliutils.isunauthenticated(args.func) or (auth_token and management_url)) + # Do not use Keystone session for cases with no session support. The + # presence of auth_plugin means os_auth_system is present and is not + # keystone. + use_session = True + if auth_plugin or bypass_url or os_cache or volume_service_name: + use_session = False + # FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if must_auth: @@ -615,11 +634,14 @@ class OpenStackComputeShell(object): "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: - raise exc.CommandError(_("You must provide a tenant name " - "or tenant id via --os-tenant-name, " - "--os-tenant-id, env[OS_TENANT_NAME] " - "or env[OS_TENANT_ID]")) + if not any([args.os_tenant_name, args.os_tenant_id, + args.os_project_id, args.os_project_name]): + raise exc.CommandError(_("You must provide a project name or" + " project id via --os-project-name," + " --os-project-id, env[OS_PROJECT_ID]" + " or env[OS_PROJECT_NAME]. You may" + " use os-project and os-tenant" + " interchangeably.")) if not os_auth_url: if os_auth_system and os_auth_system != 'keystone': @@ -632,13 +654,39 @@ class OpenStackComputeShell(object): "default url with --os-auth-system " "or env[OS_AUTH_SYSTEM]")) + project_id = args.os_project_id or args.os_tenant_id + project_name = args.os_project_name or args.os_tenant_name + if use_session: + # Not using Nova auth plugin, so use keystone + start_time = time.time() + keystone_session = ksession.Session.load_from_cli_options(args) + keystone_auth = self._get_keystone_auth( + keystone_session, + args.os_auth_url, + username=args.os_username, + user_id=args.os_user_id, + user_domain_id=args.os_user_domain_id, + user_domain_name=args.os_user_domain_name, + password=args.os_password, + auth_token=args.os_auth_token, + project_id=project_id, + project_name=project_name, + project_domain_id=args.os_project_domain_id, + project_domain_name=args.os_project_domain_name) + end_time = time.time() + self.times.append(('%s %s' % ('auth_url', args.os_auth_url), + start_time, end_time)) + if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): - if not os_tenant_name and not os_tenant_id: - raise exc.CommandError(_("You must provide a tenant name " - "or tenant id via --os-tenant-name, " - "--os-tenant-id, env[OS_TENANT_NAME] " - "or env[OS_TENANT_ID]")) + if not any([args.os_tenant_id, args.os_tenant_name, + args.os_project_id, args.os_project_name]): + raise exc.CommandError(_("You must provide a project name or" + " project id via --os-project-name," + " --os-project-id, env[OS_PROJECT_ID]" + " or env[OS_PROJECT_NAME]. You may" + " use os-project and os-tenant" + " interchangeably.")) if not os_auth_url: raise exc.CommandError(_("You must provide an auth url " @@ -658,6 +706,7 @@ class OpenStackComputeShell(object): timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, cacert=cacert, timeout=timeout, + session=keystone_session, auth=keystone_auth, completion_cache=completion_cache) # Now check for the password/token of which pieces of the @@ -691,7 +740,11 @@ class OpenStackComputeShell(object): # This does a couple of bits which are useful even if we've # got the token + service URL already. It exits fast in that case. if not cliutils.isunauthenticated(args.func): - self.cs.authenticate() + if not use_session: + # Only call authenticate() if Nova auth plugin is used. + # If keystone is used, authentication is handled as part + # of session. + self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError(_("Invalid OpenStack Nova credentials.")) except exc.AuthorizationFailure: @@ -720,12 +773,13 @@ class OpenStackComputeShell(object): volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, + session=keystone_session, auth=keystone_auth, cacert=cacert, timeout=timeout) args.func(self.cs, args) if args.timings: - self._dump_timings(self.cs.get_timings()) + self._dump_timings(self.times + self.cs.get_timings()) def _dump_timings(self, timings): class Tyme(object): diff --git a/novaclient/tests/test_shell.py b/novaclient/tests/test_shell.py index 240965d..3fcbb6e 100644 --- a/novaclient/tests/test_shell.py +++ b/novaclient/tests/test_shell.py @@ -16,8 +16,10 @@ import re import sys import fixtures +from keystoneclient import fixture import mock import prettytable +import requests_mock import six from testtools import matchers @@ -29,16 +31,33 @@ from novaclient.tests import utils FAKE_ENV = {'OS_USERNAME': 'username', 'OS_PASSWORD': 'password', 'OS_TENANT_NAME': 'tenant_name', - 'OS_AUTH_URL': 'http://no.where'} + 'OS_AUTH_URL': 'http://no.where/v2.0'} FAKE_ENV2 = {'OS_USER_ID': 'user_id', 'OS_PASSWORD': 'password', 'OS_TENANT_ID': 'tenant_id', - 'OS_AUTH_URL': 'http://no.where'} + 'OS_AUTH_URL': 'http://no.where/v2.0'} + +FAKE_ENV3 = {'OS_USER_ID': 'user_id', + 'OS_PASSWORD': 'password', + 'OS_TENANT_ID': 'tenant_id', + 'OS_AUTH_URL': 'http://no.where/v2.0', + 'NOVA_ENDPOINT_TYPE': 'novaURL', + 'OS_ENDPOINT_TYPE': 'osURL'} + + +def _create_ver_list(versions): + return {'versions': {'values': versions}} class ShellTest(utils.TestCase): + _msg_no_tenant_project = ("You must provide a project name or project" + " id via --os-project-name, --os-project-id," + " env[OS_PROJECT_ID] or env[OS_PROJECT_NAME]." + " You may use os-project and os-tenant" + " interchangeably.") + def make_env(self, exclude=None, fake_env=FAKE_ENV): env = dict((k, v) for k, v in fake_env.items() if k != exclude) self.useFixture(fixtures.MonkeyPatch('os.environ', env)) @@ -72,6 +91,12 @@ class ShellTest(utils.TestCase): sys.stderr = orig_stderr return (stdout, stderr) + def register_keystone_discovery_fixture(self, mreq): + v2_url = "http://no.where/v2.0" + v2_version = fixture.V2Discovery(v2_url) + mreq.register_uri('GET', v2_url, json=_create_ver_list([v2_version]), + status_code=200) + def test_help_unknown_command(self): self.assertRaises(exceptions.CommandError, self.shell, 'help foofoo') @@ -156,9 +181,7 @@ class ShellTest(utils.TestCase): self.fail('CommandError not raised') def test_no_tenant_name(self): - required = ('You must provide a tenant name or tenant id' - ' via --os-tenant-name, --os-tenant-id,' - ' env[OS_TENANT_NAME] or env[OS_TENANT_ID]') + required = self._msg_no_tenant_project self.make_env(exclude='OS_TENANT_NAME') try: self.shell('list') @@ -168,14 +191,12 @@ class ShellTest(utils.TestCase): self.fail('CommandError not raised') def test_no_tenant_id(self): - required = ('You must provide a tenant name or tenant id' - ' via --os-tenant-name, --os-tenant-id,' - ' env[OS_TENANT_NAME] or env[OS_TENANT_ID]',) + required = self._msg_no_tenant_project self.make_env(exclude='OS_TENANT_ID', fake_env=FAKE_ENV2) try: self.shell('list') except exceptions.CommandError as message: - self.assertEqual(required, message.args) + self.assertEqual(required, message.args[0]) else: self.fail('CommandError not raised') @@ -192,9 +213,35 @@ class ShellTest(utils.TestCase): else: self.fail('CommandError not raised') + @mock.patch('novaclient.client.Client') + @requests_mock.Mocker() + def test_nova_endpoint_type(self, mock_client, m_requests): + self.make_env(fake_env=FAKE_ENV3) + self.register_keystone_discovery_fixture(m_requests) + self.shell('list') + client_kwargs = mock_client.call_args_list[0][1] + self.assertEqual(client_kwargs['endpoint_type'], 'novaURL') + + @mock.patch('novaclient.client.Client') + @requests_mock.Mocker() + def test_os_endpoint_type(self, mock_client, m_requests): + self.make_env(exclude='NOVA_ENDPOINT_TYPE', fake_env=FAKE_ENV3) + self.register_keystone_discovery_fixture(m_requests) + self.shell('list') + client_kwargs = mock_client.call_args_list[0][1] + self.assertEqual(client_kwargs['endpoint_type'], 'osURL') + + @mock.patch('novaclient.client.Client') + def test_default_endpoint_type(self, mock_client): + self.make_env() + self.shell('list') + client_kwargs = mock_client.call_args_list[0][1] + self.assertEqual(client_kwargs['endpoint_type'], 'publicURL') + @mock.patch('sys.stdin', side_effect=mock.MagicMock) @mock.patch('getpass.getpass', return_value='password') - def test_password(self, mock_getpass, mock_stdin): + @requests_mock.Mocker() + def test_password(self, mock_getpass, mock_stdin, m_requests): mock_stdin.encoding = "utf-8" # default output of empty tables differs depending between prettytable @@ -211,6 +258,7 @@ class ShellTest(utils.TestCase): '+----+------+--------+------------+-------------+----------+\n' ) self.make_env(exclude='OS_PASSWORD') + self.register_keystone_discovery_fixture(m_requests) stdout, stderr = self.shell('list') self.assertEqual((stdout + stderr), ex) @@ -272,3 +320,26 @@ class ShellTest(utils.TestCase): # We expect the normal usage as a result self.assertIn('Command-line interface to the OpenStack Nova API', sys.stdout.getvalue()) + + @mock.patch.object(novaclient.shell.OpenStackComputeShell, 'main') + def test_main_keyboard_interrupt(self, mock_compute_shell): + # Ensure that exit code is 130 for KeyboardInterrupt + mock_compute_shell.side_effect = KeyboardInterrupt() + try: + novaclient.shell.main() + except SystemExit as ex: + self.assertEqual(ex.code, 1) + + +class ShellTestKeystoneV3(ShellTest): + def make_env(self, exclude=None, fake_env=FAKE_ENV): + if 'OS_AUTH_URL' in fake_env: + fake_env.update({'OS_AUTH_URL': 'http://no.where/v3'}) + env = dict((k, v) for k, v in fake_env.items() if k != exclude) + self.useFixture(fixtures.MonkeyPatch('os.environ', env)) + + def register_keystone_discovery_fixture(self, mreq): + v3_url = "http://no.where/v3" + v3_version = fixture.V3Discovery(v3_url) + mreq.register_uri('GET', v3_url, json=_create_ver_list([v3_version]), + status_code=200) diff --git a/novaclient/tests/v1_1/test_shell.py b/novaclient/tests/v1_1/test_shell.py index 9d44d65..faca3ca 100644 --- a/novaclient/tests/v1_1/test_shell.py +++ b/novaclient/tests/v1_1/test_shell.py @@ -56,6 +56,7 @@ class ShellTest(utils.TestCase): 'NOVA_PROJECT_ID': 'project_id', 'OS_COMPUTE_API_VERSION': '1.1', 'NOVA_URL': 'http://no.where', + 'OS_AUTH_URL': 'http://no.where/v2.0', } def setUp(self): diff --git a/novaclient/tests/v3/test_shell.py b/novaclient/tests/v3/test_shell.py index 68931a1..5f202ab 100644 --- a/novaclient/tests/v3/test_shell.py +++ b/novaclient/tests/v3/test_shell.py @@ -51,6 +51,7 @@ class ShellTest(utils.TestCase): 'NOVA_PROJECT_ID': 'project_id', 'OS_COMPUTE_API_VERSION': '3', 'NOVA_URL': 'http://no.where', + 'OS_AUTH_URL': 'http://no.where/v2.0', } def setUp(self): diff --git a/novaclient/v1_1/client.py b/novaclient/v1_1/client.py index 2e79e5b..70d5298 100644 --- a/novaclient/v1_1/client.py +++ b/novaclient/v1_1/client.py @@ -217,11 +217,9 @@ class Client(object): def set_management_url(self, url): self.client.set_management_url(url) - @client._original_only def get_timings(self): return self.client.get_timings() - @client._original_only def reset_timings(self): self.client.reset_timings() diff --git a/novaclient/v1_1/shell.py b/novaclient/v1_1/shell.py index 457ebc1..bc703df 100644 --- a/novaclient/v1_1/shell.py +++ b/novaclient/v1_1/shell.py @@ -33,6 +33,7 @@ from oslo.utils import strutils from oslo.utils import timeutils import six +from novaclient import client from novaclient import exceptions from novaclient.openstack.common.gettextutils import _ from novaclient.openstack.common import uuidutils @@ -2735,7 +2736,12 @@ def do_usage(cs, args): if args.tenant: usage = cs.usage.get(args.tenant, start, end) else: - usage = cs.usage.get(cs.client.tenant_id, start, end) + if isinstance(cs.client, client.SessionClient): + auth = cs.client.auth + project_id = auth.get_auth_ref(cs.client.session).project_id + usage = cs.usage.get(project_id, start, end) + else: + usage = cs.usage.get(cs.client.tenant_id, start, end) print(_("Usage from %(start)s to %(end)s:") % {'start': start.strftime(dateformat), @@ -3232,23 +3238,32 @@ def ensure_service_catalog_present(cs): def do_endpoints(cs, _args): """Discover endpoints that get returned from the authenticate services.""" - ensure_service_catalog_present(cs) + if isinstance(cs.client, client.SessionClient): + auth = cs.client.auth + sc = auth.get_access(cs.client.session).service_catalog + for service in sc.get_data(): + _print_endpoints(service, cs.client.region_name) + else: + ensure_service_catalog_present(cs) - catalog = cs.client.service_catalog.catalog - region = cs.client.region_name + catalog = cs.client.service_catalog.catalog + region = cs.client.region_name + for service in catalog['access']['serviceCatalog']: + _print_endpoints(service, region) - for service in catalog['access']['serviceCatalog']: - name, endpoints = service["name"], service["endpoints"] - try: - endpoint = _get_first_endpoint(endpoints, region) - utils.print_dict(endpoint, name) - except LookupError: - print(_("WARNING: %(service)s has no endpoint in %(region)s! " - "Available endpoints for this service:") % - {'service': name, 'region': region}) - for other_endpoint in endpoints: - utils.print_dict(other_endpoint, name) +def _print_endpoints(service, region): + name, endpoints = service["name"], service["endpoints"] + + try: + endpoint = _get_first_endpoint(endpoints, region) + utils.print_dict(endpoint, name) + except LookupError: + print(_("WARNING: %(service)s has no endpoint in %(region)s! " + "Available endpoints for this service:") % + {'service': name, 'region': region}) + for other_endpoint in endpoints: + utils.print_dict(other_endpoint, name) def _get_first_endpoint(endpoints, region): @@ -3274,11 +3289,19 @@ def _get_first_endpoint(endpoints, region): help=_('wrap PKI tokens to a specified length, or 0 to disable')) def do_credentials(cs, _args): """Show user credentials returned from auth.""" - ensure_service_catalog_present(cs) - catalog = cs.client.service_catalog.catalog - utils.print_dict(catalog['access']['user'], "User Credentials", - wrap=int(_args.wrap)) - utils.print_dict(catalog['access']['token'], "Token", wrap=int(_args.wrap)) + if isinstance(cs.client, client.SessionClient): + auth = cs.client.auth + sc = auth.get_access(cs.client.session).service_catalog + utils.print_dict(sc.catalog['user'], 'User Credentials', + wrap=int(_args.wrap)) + utils.print_dict(sc.get_token(), 'Token', wrap=int(_args.wrap)) + else: + ensure_service_catalog_present(cs) + catalog = cs.client.service_catalog.catalog + utils.print_dict(catalog['access']['user'], "User Credentials", + wrap=int(_args.wrap)) + utils.print_dict(catalog['access']['token'], "Token", + wrap=int(_args.wrap)) @utils.arg('server', metavar='<server>', help=_('Name or ID of server.')) diff --git a/novaclient/v3/client.py b/novaclient/v3/client.py index a30f919..6967ea4 100644 --- a/novaclient/v3/client.py +++ b/novaclient/v3/client.py @@ -174,11 +174,9 @@ class Client(object): def set_management_url(self, url): self.client.set_management_url(url) - @client._original_only def get_timings(self): return self.client.get_timings() - @client._original_only def reset_timings(self): self.client.reset_timings() diff --git a/novaclient/v3/shell.py b/novaclient/v3/shell.py index 3d17e28..af19809 100644 --- a/novaclient/v3/shell.py +++ b/novaclient/v3/shell.py @@ -31,6 +31,7 @@ from oslo.utils import strutils from oslo.utils import timeutils import six +from novaclient import client from novaclient import exceptions from novaclient.openstack.common.gettextutils import _ from novaclient.openstack.common import uuidutils @@ -2140,7 +2141,12 @@ def do_usage(cs, args): if args.tenant: usage = cs.usage.get(args.tenant, start, end) else: - usage = cs.usage.get(cs.client.tenant_id, start, end) + if isinstance(cs.client, client.SessionClient): + auth = cs.client.auth + project_id = auth.get_auth_ref(cs.client.session).project_id + usage = cs.usage.get(project_id, start, end) + else: + usage = cs.usage.get(cs.client.tenant_id, start, end) print("Usage from %s to %s:" % (start.strftime(dateformat), end.strftime(dateformat))) @@ -2645,23 +2651,33 @@ def ensure_service_catalog_present(cs): def do_endpoints(cs, _args): """Discover endpoints that get returned from the authenticate services.""" - ensure_service_catalog_present(cs) + if isinstance(cs.client, client.SessionClient): + auth = cs.client.auth + sc = auth.get_Access(cs.client.session).service_catalog + for service in sc.get_data(): + _print_endpoints(service, cs.client.region_name) + else: + ensure_service_catalog_present(cs) - catalog = cs.client.service_catalog.catalog - region = cs.client.region_name + catalog = cs.client.service_catalog.catalog + region = cs.client.region_name - for service in catalog['access']['serviceCatalog']: - name, endpoints = service["name"], service["endpoints"] + for service in catalog['access']['serviceCatalog']: + _print_endpoints(service, region) - try: - endpoint = _get_first_endpoint(endpoints, region) - utils.print_dict(endpoint, name) - except LookupError: - print(_("WARNING: %(service)s has no endpoint in %(region)s! " - "Available endpoints for this service:") % - {'service': name, 'region': region}) - for other_endpoint in endpoints: - utils.print_dict(other_endpoint, name) + +def _print_endpoints(service, region): + name, endpoints = service["name"], service["endpoints"] + + try: + endpoint = _get_first_endpoint(endpoints, region) + utils.print_dict(endpoint, name) + except LookupError: + print(_("WARNING: %(service)s has no endpoint in %(region)s! " + "Available endpoints for this service:") % + {'service': name, 'region': region}) + for other_endpoint in endpoints: + utils.print_dict(other_endpoint, name) def _get_first_endpoint(endpoints, region): @@ -2687,11 +2703,19 @@ def _get_first_endpoint(endpoints, region): help='wrap PKI tokens to a specified length, or 0 to disable') def do_credentials(cs, _args): """Show user credentials returned from auth.""" - ensure_service_catalog_present(cs) - catalog = cs.client.service_catalog.catalog - utils.print_dict(catalog['access']['user'], "User Credentials", - wrap=int(_args.wrap)) - utils.print_dict(catalog['access']['token'], "Token", wrap=int(_args.wrap)) + if isinstance(cs.client, client.SessionClient): + auth = cs.client.auth + sc = auth.get_access(cs.client.session).service_catalog + utils.print_dict(sc.catalog['user'], 'User Credentials', + wrap=int(_args.wrap)) + utils.print_dict(sc.get_token(), 'Token', wrap=int(_args.wrap)) + else: + ensure_service_catalog_present(cs) + catalog = cs.client.service_catalog.catalog + utils.print_dict(catalog['access']['user'], "User Credentials", + wrap=int(_args.wrap)) + utils.print_dict(catalog['access']['token'], "Token", + wrap=int(_args.wrap)) def do_extension_list(cs, _args): -- 2.3.7
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor