diff options
Diffstat (limited to 'openstackclient/api/auth.py')
| -rw-r--r-- | openstackclient/api/auth.py | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/openstackclient/api/auth.py b/openstackclient/api/auth.py new file mode 100644 index 00000000..2bd5271f --- /dev/null +++ b/openstackclient/api/auth.py @@ -0,0 +1,180 @@ +# 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. +# + +"""Authentication Library""" + +import argparse +import logging + +import stevedore + +from keystoneclient.auth import base + +from openstackclient.common import exceptions as exc +from openstackclient.common import utils + + +LOG = logging.getLogger(__name__) + + +# Initialize the list of Authentication plugins early in order +# to get the command-line options +PLUGIN_LIST = stevedore.ExtensionManager( + base.PLUGIN_NAMESPACE, + invoke_on_load=False, + propagate_map_exceptions=True, +) +# TODO(dtroyer): add some method to list the plugins for the +# --os_auth_plugin option + +# Get the command line options so the help action has them available +OPTIONS_LIST = {} +for plugin in PLUGIN_LIST: + for o in plugin.plugin.get_options(): + os_name = o.dest.lower().replace('_', '-') + os_env_name = 'OS_' + os_name.upper().replace('-', '_') + OPTIONS_LIST.setdefault(os_name, {'env': os_env_name, 'help': ''}) + # TODO(mhu) simplistic approach, would be better to only add + # help texts if they vary from one auth plugin to another + # also the text rendering is ugly in the CLI ... + OPTIONS_LIST[os_name]['help'] += 'With %s: %s\n' % ( + plugin.name, + o.help, + ) + + +def _guess_authentication_method(options): + """If no auth plugin was specified, pick one based on other options""" + + if options.os_url: + # service token authentication, do nothing + return + auth_plugin = None + if options.os_password: + if options.os_identity_api_version == '3': + auth_plugin = 'v3password' + elif options.os_identity_api_version == '2.0': + auth_plugin = 'v2password' + else: + # let keystoneclient figure it out itself + auth_plugin = 'password' + elif options.os_token: + if options.os_identity_api_version == '3': + auth_plugin = 'v3token' + elif options.os_identity_api_version == '2.0': + auth_plugin = 'v2token' + else: + # let keystoneclient figure it out itself + auth_plugin = 'token' + else: + raise exc.CommandError( + "Could not figure out which authentication method " + "to use, please set --os-auth-plugin" + ) + LOG.debug("No auth plugin selected, picking %s from other " + "options" % auth_plugin) + options.os_auth_plugin = auth_plugin + + +def build_auth_params(cmd_options): + auth_params = {} + if cmd_options.os_url: + return {'token': cmd_options.os_token} + if cmd_options.os_auth_plugin: + auth_plugin = base.get_plugin_class(cmd_options.os_auth_plugin) + plugin_options = auth_plugin.get_options() + for option in plugin_options: + option_name = 'os_' + option.dest + LOG.debug('fetching option %s' % option_name) + auth_params[option.dest] = getattr(cmd_options, option_name, None) + # grab tenant from project for v2.0 API compatibility + if cmd_options.os_auth_plugin.startswith("v2"): + auth_params['tenant_id'] = getattr( + cmd_options, + 'os_project_id', + None, + ) + auth_params['tenant_name'] = getattr( + cmd_options, + 'os_project_name', + None, + ) + else: + # delay the plugin choice, grab every option + plugin_options = set([o.replace('-', '_') for o in OPTIONS_LIST]) + for option in plugin_options: + option_name = 'os_' + option + LOG.debug('fetching option %s' % option_name) + auth_params[option] = getattr(cmd_options, option_name, None) + return auth_params + + +def build_auth_plugins_option_parser(parser): + """Auth plugins options builder + + Builds dynamically the list of options expected by each available + authentication plugin. + + """ + available_plugins = [plugin.name for plugin in PLUGIN_LIST] + parser.add_argument( + '--os-auth-plugin', + metavar='<OS_AUTH_PLUGIN>', + default=utils.env('OS_AUTH_PLUGIN'), + help='The authentication method to use. If this option is not set, ' + 'openstackclient will attempt to guess the authentication method ' + 'to use based on the other options. If this option is set, ' + 'the --os-identity-api-version argument must be consistent ' + 'with the version of the method.\nAvailable methods are ' + + ', '.join(available_plugins), + choices=available_plugins + ) + # make sur we catch old v2.0 env values + envs = { + 'OS_PROJECT_NAME': utils.env( + 'OS_PROJECT_NAME', + default=utils.env('OS_TENANT_NAME') + ), + 'OS_PROJECT_ID': utils.env( + 'OS_PROJECT_ID', + default=utils.env('OS_TENANT_ID') + ), + } + for o in OPTIONS_LIST: + # remove allusion to tenants from v2.0 API + if 'tenant' not in o: + parser.add_argument( + '--os-' + o, + metavar='<auth-%s>' % o, + default=envs.get(OPTIONS_LIST[o]['env'], + utils.env(OPTIONS_LIST[o]['env'])), + help='%s\n(Env: %s)' % (OPTIONS_LIST[o]['help'], + OPTIONS_LIST[o]['env']), + ) + # add tenant-related options for compatibility + # this is deprecated but still used in some tempest tests... + parser.add_argument( + '--os-tenant-name', + metavar='<auth-tenant-name>', + dest='os_project_name', + default=utils.env('OS_TENANT_NAME'), + help=argparse.SUPPRESS, + ) + parser.add_argument( + '--os-tenant-id', + metavar='<auth-tenant-id>', + dest='os_project_id', + default=utils.env('OS_TENANT_ID'), + help=argparse.SUPPRESS, + ) + return parser |
