summaryrefslogtreecommitdiff
path: root/troveclient/shell.py
diff options
context:
space:
mode:
authorBob Thyne <bob.thyne@hp.com>2014-11-12 23:21:15 -0800
committerBob Thyne <bob.thyne@hp.com>2014-12-01 15:58:36 -0800
commit4f1fb53ecbcdf8bb9d42cbc962e0c55915629659 (patch)
treeedfa256eb7e1686da98bada8a78c78b90358e1d7 /troveclient/shell.py
parentefb0f37f8ded8365a1e6b75b259b5e3d9a01a943 (diff)
downloadpython-troveclient-4f1fb53ecbcdf8bb9d42cbc962e0c55915629659.tar.gz
Adds support for Keystone V3 API
Updated trove client to support Keystone V3 API. The Keystoneclient session object is used for authentication, retrieving the service catalog and HTTP connection/session management. Added additional CLI parameters for Keystone V3. Added tests using requests_mock instead of mocking completely the session object like the previous failed patch: https://review.openstack.org/#/c/102315 Change-Id: Ib804c0a45b3b4d3f8670ec642b2c2fd1be6cd656
Diffstat (limited to 'troveclient/shell.py')
-rw-r--r--troveclient/shell.py203
1 files changed, 127 insertions, 76 deletions
diff --git a/troveclient/shell.py b/troveclient/shell.py
index e03a2e9..3738d30 100644
--- a/troveclient/shell.py
+++ b/troveclient/shell.py
@@ -32,16 +32,23 @@ import sys
import pkg_resources
import six
+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 ks_session
+
import troveclient
import troveclient.extension
from troveclient import client
from troveclient.openstack.common.apiclient import exceptions as exc
from troveclient.openstack.common import gettextutils as gtu
+from troveclient.openstack.common.gettextutils import _ # noqa
from troveclient.openstack.common import strutils
from troveclient import utils
from troveclient.v1 import shell as shell_v1
+
DEFAULT_OS_DATABASE_API_VERSION = "1.0"
DEFAULT_TROVE_ENDPOINT_TYPE = 'publicURL'
DEFAULT_TROVE_SERVICE_TYPE = 'database'
@@ -98,53 +105,9 @@ class OpenStackTroveShell(object):
default=False),
help="Print debugging output.")
- parser.add_argument('--os-username',
- metavar='<auth-user-name>',
- default=utils.env('OS_USERNAME',
- 'TROVE_USERNAME'),
- help='Defaults to env[OS_USERNAME].')
- parser.add_argument('--os_username',
- help=argparse.SUPPRESS)
-
- parser.add_argument('--os-password',
- metavar='<auth-password>',
- default=utils.env('OS_PASSWORD',
- 'TROVE_PASSWORD'),
- help='Defaults to env[OS_PASSWORD].')
- parser.add_argument('--os_password',
- help=argparse.SUPPRESS)
-
- parser.add_argument('--os-tenant-name',
- metavar='<auth-tenant-name>',
- default=utils.env('OS_TENANT_NAME',
- 'TROVE_PROJECT_ID'),
- help='Defaults to env[OS_TENANT_NAME].')
- parser.add_argument('--os_tenant_name',
- help=argparse.SUPPRESS)
-
- parser.add_argument('--os-tenant-id',
- metavar='<auth-tenant-id>',
- default=utils.env('OS_TENANT_ID',
- 'TROVE_TENANT_ID'),
- help='Defaults to env[OS_TENANT_ID].')
- parser.add_argument('--os_tenant_id',
- help=argparse.SUPPRESS)
-
- parser.add_argument('--os-auth-url',
- metavar='<auth-url>',
- default=utils.env('OS_AUTH_URL',
- 'TROVE_URL'),
- help='Defaults to env[OS_AUTH_URL].')
- parser.add_argument('--os_auth_url',
- help=argparse.SUPPRESS)
-
- parser.add_argument('--os-region-name',
- metavar='<region-name>',
- default=utils.env('OS_REGION_NAME',
- 'TROVE_REGION_NAME'),
- help='Defaults to env[OS_REGION_NAME].')
- parser.add_argument('--os_region_name',
- help=argparse.SUPPRESS)
+ parser.add_argument('--os-auth-system',
+ metavar='<auth-system>',
+ default=utils.env('OS_AUTH_SYSTEM'))
parser.add_argument('--service-type',
metavar='<service-type>',
@@ -196,19 +159,6 @@ class OpenStackTroveShell(object):
parser.add_argument('--os_database_api_version',
help=argparse.SUPPRESS)
- parser.add_argument('--os-cacert',
- metavar='<ca-certificate>',
- default=utils.env('OS_CACERT', default=None),
- help='Specify a CA bundle file to use in '
- 'verifying a TLS (https) server certificate. '
- 'Defaults to env[OS_CACERT].')
-
- parser.add_argument('--insecure',
- default=utils.env('TROVECLIENT_INSECURE',
- default=False),
- action='store_true',
- help=argparse.SUPPRESS)
-
parser.add_argument('--retries',
metavar='<retries>',
type=int,
@@ -223,8 +173,45 @@ class OpenStackTroveShell(object):
help='Output JSON instead of prettyprint. '
'Defaults to env[OS_JSON_OUTPUT].')
+ self._append_global_identity_args(parser)
+
return parser
+ def _append_global_identity_args(self, parser):
+ # Register CLI identity related arguments
+
+ # Use Keystoneclient API to register common V3 CLI arguments
+ ks_session.Session.register_cli_options(parser)
+ identity.Password.register_argparse_arguments(parser)
+
+ parser.add_argument('--os-tenant-name',
+ metavar='<auth-tenant-name>',
+ default=utils.env('OS_TENANT_NAME'),
+ help='Tenant to request authorization on. '
+ 'Defaults to env[OS_TENANT_NAME].')
+ parser.add_argument('--os_tenant_name',
+ help=argparse.SUPPRESS)
+
+ parser.add_argument('--os-tenant-id',
+ metavar='<tenant-id>',
+ default=utils.env('OS_TENANT_ID'),
+ help='Tenant to request authorization on. '
+ 'Defaults to env[OS_TENANT_ID].')
+ parser.add_argument('--os_tenant_id',
+ help=argparse.SUPPRESS)
+
+ parser.add_argument('--os-auth-token',
+ default=utils.env('OS_AUTH_TOKEN'),
+ help='Defaults to env[OS_AUTH_TOKEN]')
+
+ parser.add_argument('--os-region-name',
+ metavar='<region-name>',
+ default=utils.env('OS_REGION_NAME'),
+ help='Specify the region to use. '
+ 'Defaults to env[OS_REGION_NAME].')
+ parser.add_argument('--os_region_name',
+ help=argparse.SUPPRESS)
+
def get_subcommand_parser(self, version):
parser = self.get_base_parser()
@@ -334,17 +321,16 @@ class OpenStackTroveShell(object):
if not debug:
return
- streamhandler = logging.StreamHandler()
streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s"
- streamhandler.setFormatter(logging.Formatter(streamformat))
- logger.setLevel(logging.DEBUG)
- logger.addHandler(streamhandler)
+ logging.basicConfig(level=logging.DEBUG,
+ format=streamformat)
def main(self, argv):
# Parse args once to find version and debug settings
parser = self.get_base_parser()
(options, args) = parser.parse_known_args(argv)
self.setup_debugging(options.debug)
+ self.options = options
# build available subcommands based on version
self.extensions = self._discover_extensions(
@@ -373,14 +359,19 @@ class OpenStackTroveShell(object):
(os_username, os_password, os_tenant_name, os_auth_url,
os_region_name, os_tenant_id, endpoint_type, insecure,
service_type, service_name, database_service_name,
- cacert, bypass_url) = (
+ cacert, bypass_url, os_auth_system) = (
args.os_username, args.os_password,
args.os_tenant_name, args.os_auth_url,
args.os_region_name, args.os_tenant_id,
args.endpoint_type, args.insecure,
args.service_type, args.service_name,
args.database_service_name,
- args.os_cacert, args.bypass_url)
+ args.os_cacert, args.bypass_url, args.os_auth_system)
+
+ if os_auth_system and os_auth_system != "keystone":
+ auth_plugin = troveclient.auth_plugin.load_plugin(os_auth_system)
+ else:
+ auth_plugin = None
if not endpoint_type:
endpoint_type = DEFAULT_TROVE_ENDPOINT_TYPE
@@ -403,26 +394,64 @@ class OpenStackTroveShell(object):
"via either --os-password or via "
"env[OS_PASSWORD]")
- if not (os_tenant_name or os_tenant_id):
- raise exc.CommandError("You must provide a tenant_id "
- "via either --os-tenant-id or "
- "env[OS_TENANT_ID]")
-
if not os_auth_url:
raise exc.CommandError(
"You must provide an auth url "
"via either --os-auth-url or env[OS_AUTH_URL]")
- if not (os_tenant_name or os_tenant_id):
+ # V3 stuff
+ project_info_provided = (self.options.os_tenant_name or
+ self.options.os_tenant_id or
+ (self.options.os_project_name and
+ (self.options.os_project_domain_name or
+ self.options.os_project_domain_id)) or
+ self.options.os_project_id)
+
+ if (not project_info_provided):
raise exc.CommandError(
- "You must provide a tenant_id "
- "via either --os-tenant-id or env[OS_TENANT_ID]")
+ _("You must provide a tenant_name, tenant_id, "
+ "project_id or project_name (with "
+ "project_domain_name or project_domain_id) via "
+ " --os-tenant-name (env[OS_TENANT_NAME]),"
+ " --os-tenant-id (env[OS_TENANT_ID]),"
+ " --os-project-id (env[OS_PROJECT_ID])"
+ " --os-project-name (env[OS_PROJECT_NAME]),"
+ " --os-project-domain-id "
+ "(env[OS_PROJECT_DOMAIN_ID])"
+ " --os-project-domain-name "
+ "(env[OS_PROJECT_DOMAIN_NAME])"))
if not os_auth_url:
raise exc.CommandError(
"You must provide an auth url "
"via either --os-auth-url or env[OS_AUTH_URL]")
+ use_session = True
+ if auth_plugin or bypass_url:
+ use_session = False
+
+ keystone_session = None
+ keystone_auth = None
+ if use_session:
+ project_id = args.os_project_id or args.os_tenant_id
+ project_name = args.os_project_name or args.os_tenant_name
+
+ keystone_session = (ks_session.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)
+
self.cs = client.Client(options.os_database_api_version, os_username,
os_password, os_tenant_name, os_auth_url,
insecure, region_name=os_region_name,
@@ -435,17 +464,25 @@ class OpenStackTroveShell(object):
retries=options.retries,
http_log_debug=args.debug,
cacert=cacert,
- bypass_url=bypass_url)
+ bypass_url=bypass_url,
+ auth_system=os_auth_system,
+ auth_plugin=auth_plugin,
+ session=keystone_session,
+ auth=keystone_auth)
try:
if not utils.isunauthenticated(args.func):
- self.cs.authenticate()
+ # If Keystone is used, authentication is handled as
+ # part of session.
+ if not use_session:
+ self.cs.authenticate()
except exc.Unauthorized:
raise exc.CommandError("Invalid OpenStack Trove credentials.")
except exc.AuthorizationFailure:
raise exc.CommandError("Unable to authorize user")
endpoint_api_version = self.cs.get_database_api_version_from_endpoint()
+
if endpoint_api_version != options.os_database_api_version:
msg = (("Database API version is set to %s "
"but you are accessing a %s endpoint. "
@@ -498,6 +535,20 @@ class OpenStackTroveShell(object):
else:
self.parser.print_help()
+ 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)
+
# I'm picky about my shell help.
class OpenStackHelpFormatter(argparse.HelpFormatter):