diff --git a/examples/common.py b/examples/common.py index 1ccea2a070..2e7985292b 100755 --- a/examples/common.py +++ b/examples/common.py @@ -84,12 +84,6 @@ def base_parser(parser): """ # Global arguments - parser.add_argument( - '--os-url', - metavar='', - default=env('OS_URL'), - help='Defaults to env[OS_URL]', - ) parser.add_argument( '--os-region-name', metavar='', diff --git a/openstackclient/api/auth.py b/openstackclient/api/auth.py index 2097d716e4..ba51bee1ff 100644 --- a/openstackclient/api/auth.py +++ b/openstackclient/api/auth.py @@ -16,13 +16,9 @@ import argparse import logging -from six.moves.urllib import parse as urlparse import stevedore -from oslo_config import cfg - from keystoneclient.auth import base -from keystoneclient.auth.identity.generic import password as ksc_password from openstackclient.common import exceptions as exc from openstackclient.common import utils @@ -201,96 +197,3 @@ def build_auth_plugins_option_parser(parser): help=argparse.SUPPRESS, ) return parser - - -class TokenEndpoint(base.BaseAuthPlugin): - """Auth plugin to handle traditional token/endpoint usage - - Implements the methods required to handle token authentication - with a user-specified token and service endpoint; no Identity calls - are made for re-scoping, service catalog lookups or the like. - - The purpose of this plugin is to get rid of the special-case paths - in the code to handle this authentication format. Its primary use - is for bootstrapping the Keystone database. - """ - - def __init__(self, url, token, **kwargs): - """A plugin for static authentication with an existing token - - :param string url: Service endpoint - :param string token: Existing token - """ - super(TokenEndpoint, self).__init__() - self.endpoint = url - self.token = token - - def get_endpoint(self, session, **kwargs): - """Return the supplied endpoint""" - return self.endpoint - - def get_token(self, session): - """Return the supplied token""" - return self.token - - def get_auth_ref(self, session, **kwargs): - """Stub this method for compatibility""" - return None - - # Override this because it needs to be a class method... - @classmethod - def get_options(self): - options = super(TokenEndpoint, self).get_options() - - options.extend([ - # Maintain name 'url' for compatibility - cfg.StrOpt('url', - help='Specific service endpoint to use'), - cfg.StrOpt('token', - secret=True, - help='Authentication token to use'), - ]) - - return options - - -class OSCGenericPassword(ksc_password.Password): - """Auth plugin hack to work around broken Keystone configurations - - The default Keystone configuration uses http://localhost:xxxx in - admin_endpoint and public_endpoint and are returned in the links.href - attribute by the version routes. Deployments that do not set these - are unusable with newer keystoneclient version discovery. - - """ - - def create_plugin(self, session, version, url, raw_status=None): - """Handle default Keystone endpoint configuration - - Build the actual API endpoint from the scheme, host and port of the - original auth URL and the rest from the returned version URL. - """ - - ver_u = urlparse.urlparse(url) - - # Only hack this if it is the default setting - if ver_u.netloc.startswith('localhost'): - auth_u = urlparse.urlparse(self.auth_url) - # from original auth_url: scheme, netloc - # from api_url: path, query (basically, the rest) - url = urlparse.urlunparse(( - auth_u.scheme, - auth_u.netloc, - ver_u.path, - ver_u.params, - ver_u.query, - ver_u.fragment, - )) - LOG.debug('Version URL updated: %s' % url) - - return super(OSCGenericPassword, self).create_plugin( - session=session, - version=version, - url=url, - raw_status=raw_status, - ) diff --git a/openstackclient/api/auth_plugin.py b/openstackclient/api/auth_plugin.py new file mode 100644 index 0000000000..a995476ae0 --- /dev/null +++ b/openstackclient/api/auth_plugin.py @@ -0,0 +1,118 @@ +# 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 Plugin Library""" + +import logging + +from oslo_config import cfg +from six.moves.urllib import parse as urlparse + +from keystoneclient.auth import base +from keystoneclient.auth.identity.generic import password as ksc_password + + +LOG = logging.getLogger(__name__) + + +class TokenEndpoint(base.BaseAuthPlugin): + """Auth plugin to handle traditional token/endpoint usage + + Implements the methods required to handle token authentication + with a user-specified token and service endpoint; no Identity calls + are made for re-scoping, service catalog lookups or the like. + + The purpose of this plugin is to get rid of the special-case paths + in the code to handle this authentication format. Its primary use + is for bootstrapping the Keystone database. + """ + + def __init__(self, url, token, **kwargs): + """A plugin for static authentication with an existing token + + :param string url: Service endpoint + :param string token: Existing token + """ + super(TokenEndpoint, self).__init__() + self.endpoint = url + self.token = token + + def get_endpoint(self, session, **kwargs): + """Return the supplied endpoint""" + return self.endpoint + + def get_token(self, session): + """Return the supplied token""" + return self.token + + def get_auth_ref(self, session, **kwargs): + """Stub this method for compatibility""" + return None + + # Override this because it needs to be a class method... + @classmethod + def get_options(self): + options = super(TokenEndpoint, self).get_options() + + options.extend([ + # Maintain name 'url' for compatibility + cfg.StrOpt('url', + help='Specific service endpoint to use'), + cfg.StrOpt('token', + secret=True, + help='Authentication token to use'), + ]) + + return options + + +class OSCGenericPassword(ksc_password.Password): + """Auth plugin hack to work around broken Keystone configurations + + The default Keystone configuration uses http://localhost:xxxx in + admin_endpoint and public_endpoint and are returned in the links.href + attribute by the version routes. Deployments that do not set these + are unusable with newer keystoneclient version discovery. + + """ + + def create_plugin(self, session, version, url, raw_status=None): + """Handle default Keystone endpoint configuration + + Build the actual API endpoint from the scheme, host and port of the + original auth URL and the rest from the returned version URL. + """ + + ver_u = urlparse.urlparse(url) + + # Only hack this if it is the default setting + if ver_u.netloc.startswith('localhost'): + auth_u = urlparse.urlparse(self.auth_url) + # from original auth_url: scheme, netloc + # from api_url: path, query (basically, the rest) + url = urlparse.urlunparse(( + auth_u.scheme, + auth_u.netloc, + ver_u.path, + ver_u.params, + ver_u.query, + ver_u.fragment, + )) + LOG.debug('Version URL updated: %s' % url) + + return super(OSCGenericPassword, self).create_plugin( + session=session, + version=version, + url=url, + raw_status=raw_status, + ) diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index c430791933..ad6a2e2046 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -120,7 +120,7 @@ class ClientManager(object): # password auth is requested. if (self.auth_plugin_name.endswith('password') and not self._cli_options.os_password): - self._cli_options.os_password = self.pw_callback() + self._cli_options.os_password = self._pw_callback() (auth_plugin, self._auth_params) = auth.build_auth_params( self.auth_plugin_name, diff --git a/openstackclient/shell.py b/openstackclient/shell.py index b61da2b941..3cfd731219 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -188,12 +188,6 @@ class OpenStackShell(app.App): description, version) - # service token auth argument - parser.add_argument( - '--os-url', - metavar='', - default=utils.env('OS_URL'), - help='Defaults to env[OS_URL]') # Global arguments parser.add_argument( '--os-region-name', diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py index ce85e73749..3648bf5756 100644 --- a/openstackclient/tests/common/test_clientmanager.py +++ b/openstackclient/tests/common/test_clientmanager.py @@ -20,6 +20,7 @@ from keystoneclient import service_catalog from oslo_serialization import jsonutils from openstackclient.api import auth +from openstackclient.api import auth_plugin from openstackclient.common import clientmanager from openstackclient.common import exceptions as exc from openstackclient.tests import fakes @@ -100,7 +101,7 @@ class TestClientManager(utils.TestCase): ) self.assertIsInstance( client_manager.auth, - auth.TokenEndpoint, + auth_plugin.TokenEndpoint, ) self.assertFalse(client_manager._insecure) self.assertTrue(client_manager._verify) diff --git a/setup.cfg b/setup.cfg index 4da2bfa0e6..012d62b12f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,8 +28,8 @@ console_scripts = openstack = openstackclient.shell:main keystoneclient.auth.plugin = - token_endpoint = openstackclient.api.auth:TokenEndpoint - osc_password = openstackclient.api.auth:OSCGenericPassword + token_endpoint = openstackclient.api.auth_plugin:TokenEndpoint + osc_password = openstackclient.api.auth_plugin:OSCGenericPassword openstack.cli = command_list = openstackclient.common.module:ListCommand