Remove oslo_config from auth plugin loading

There is still the possibility of a dependency in session, however this
is the main usage. Defines a new option type schema.

Change-Id: Ie508dff449a92c9ea01c46285c10888135e93a97
This commit is contained in:
Jamie Lennox 2015-08-05 13:42:12 +10:00
parent efcadd6937
commit 5e74fed6b5
14 changed files with 177 additions and 110 deletions

View File

@ -13,6 +13,7 @@
from keystoneauth1.loading.base import * # noqa
from keystoneauth1.loading.cli import * # noqa
from keystoneauth1.loading.conf import * # noqa
from keystoneauth1.loading.opts import * # noqa
__all__ = [
@ -32,4 +33,7 @@ __all__ = [
'get_plugin_options',
'load_from_conf_options',
'register_conf_options',
# loading.opts
'Opt',
]

View File

@ -10,8 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from keystoneauth1 import loading
@ -21,7 +19,7 @@ class BaseIdentityLoader(loading.BaseLoader):
options = super(BaseIdentityLoader, self).get_options()
options.extend([
cfg.StrOpt('auth-url', help='Authentication URL'),
loading.Opt('auth-url', help='Authentication URL'),
])
return options

View File

@ -10,9 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from keystoneauth1 import identity
from keystoneauth1 import loading
from keystoneauth1.loading._plugins.identity import base
@ -22,17 +21,17 @@ class GenericBaseLoader(base.BaseIdentityLoader):
options = super(GenericBaseLoader, self).get_options()
options.extend([
cfg.StrOpt('domain-id', help='Domain ID to scope to'),
cfg.StrOpt('domain-name', help='Domain name to scope to'),
cfg.StrOpt('tenant-id', help='Tenant ID to scope to'),
cfg.StrOpt('tenant-name', help='Tenant name to scope to'),
cfg.StrOpt('project-id', help='Project ID to scope to'),
cfg.StrOpt('project-name', help='Project name to scope to'),
cfg.StrOpt('project-domain-id',
loading.Opt('domain-id', help='Domain ID to scope to'),
loading.Opt('domain-name', help='Domain name to scope to'),
loading.Opt('tenant-id', help='Tenant ID to scope to'),
loading.Opt('tenant-name', help='Tenant name to scope to'),
loading.Opt('project-id', help='Project ID to scope to'),
loading.Opt('project-name', help='Project name to scope to'),
loading.Opt('project-domain-id',
help='Domain ID containing project'),
cfg.StrOpt('project-domain-name',
loading.Opt('project-domain-name',
help='Domain name containing project'),
cfg.StrOpt('trust-id', help='Trust ID'),
loading.Opt('trust-id', help='Trust ID'),
])
return options
@ -48,7 +47,7 @@ class Token(GenericBaseLoader):
options = super(Token, self).get_options()
options.extend([
cfg.StrOpt('token', help='Token to authenticate with'),
loading.Opt('token', help='Token to authenticate with'),
])
return options
@ -63,13 +62,13 @@ class Password(GenericBaseLoader):
def get_options(cls):
options = super(Password, cls).get_options()
options.extend([
cfg.StrOpt('user-id', help='User id'),
cfg.StrOpt('user-name',
loading.Opt('user-id', help='User id'),
loading.Opt('user-name',
dest='username',
help='Username',
deprecated_name='username'),
cfg.StrOpt('user-domain-id', help="User's domain id"),
cfg.StrOpt('user-domain-name', help="User's domain name"),
cfg.StrOpt('password', help="User's password"),
deprecated=[loading.Opt('username')]),
loading.Opt('user-domain-id', help="User's domain id"),
loading.Opt('user-domain-name', help="User's domain name"),
loading.Opt('password', help="User's password"),
])
return options

View File

@ -10,9 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from keystoneauth1 import identity
from keystoneauth1 import loading
from keystoneauth1.loading._plugins.identity import base
@ -22,9 +21,9 @@ class BaseV2Loader(base.BaseIdentityLoader):
options = super(BaseV2Loader, self).get_options()
options.extend([
cfg.StrOpt('tenant-id', help='Tenant ID'),
cfg.StrOpt('tenant-name', help='Tenant Name'),
cfg.StrOpt('trust-id', help='Trust ID'),
loading.Opt('tenant-id', help='Tenant ID'),
loading.Opt('tenant-name', help='Tenant Name'),
loading.Opt('trust-id', help='Trust ID'),
])
return options
@ -40,7 +39,7 @@ class V2Token(BaseV2Loader):
options = super(V2Token, self).get_options()
options.extend([
cfg.StrOpt('token', secret=True, help='Token'),
loading.Opt('token', secret=True, help='Token'),
])
return options
@ -56,12 +55,12 @@ class V2Password(BaseV2Loader):
options = super(V2Password, self).get_options()
options.extend([
cfg.StrOpt('user-name',
loading.Opt('user-name',
dest='username',
deprecated_name='username',
deprecated=[loading.Opt('username')],
help='Username to login with'),
cfg.StrOpt('user-id', help='User ID to longin with'),
cfg.StrOpt('password', secret=True, help='Password to use'),
loading.Opt('user-id', help='User ID to longin with'),
loading.Opt('password', secret=True, help='Password to use'),
])
return options

View File

@ -10,9 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from keystoneauth1 import identity
from keystoneauth1 import loading
from keystoneauth1.loading._plugins.identity import base
@ -22,15 +21,15 @@ class BaseV3Loader(base.BaseIdentityLoader):
options = super(BaseV3Loader, self).get_options()
options.extend([
cfg.StrOpt('domain-id', help='Domain ID to scope to'),
cfg.StrOpt('domain-name', help='Domain name to scope to'),
cfg.StrOpt('project-id', help='Project ID to scope to'),
cfg.StrOpt('project-name', help='Project name to scope to'),
cfg.StrOpt('project-domain-id',
loading.Opt('domain-id', help='Domain ID to scope to'),
loading.Opt('domain-name', help='Domain name to scope to'),
loading.Opt('project-id', help='Project ID to scope to'),
loading.Opt('project-name', help='Project name to scope to'),
loading.Opt('project-domain-id',
help='Domain ID containing project'),
cfg.StrOpt('project-domain-name',
loading.Opt('project-domain-name',
help='Domain name containing project'),
cfg.StrOpt('trust-id', help='Trust ID'),
loading.Opt('trust-id', help='Trust ID'),
])
return options
@ -46,14 +45,14 @@ class Password(BaseV3Loader):
options = super(Password, self).get_options()
options.extend([
cfg.StrOpt('user-id', help='User ID'),
cfg.StrOpt('user-name',
loading.Opt('user-id', help='User ID'),
loading.Opt('user-name',
dest='username',
help='Username',
deprecated_name='username'),
cfg.StrOpt('user-domain-id', help="User's domain id"),
cfg.StrOpt('user-domain-name', help="User's domain name"),
cfg.StrOpt('password', secret=True, help="User's password"),
deprecated=[loading.Opt('username')]),
loading.Opt('user-domain-id', help="User's domain id"),
loading.Opt('user-domain-name', help="User's domain name"),
loading.Opt('password', secret=True, help="User's password"),
])
return options
@ -69,7 +68,7 @@ class Token(BaseV3Loader):
options = super(Token, self).get_options()
options.extend([
cfg.StrOpt('token',
loading.Opt('token',
secret=True,
help='Token to authenticate with'),
])
@ -83,9 +82,9 @@ class FederatedBase(BaseV3Loader):
options = super(FederatedBase, self).get_options()
options.extend([
cfg.StrOpt('identity-provider',
loading.Opt('identity-provider',
help="Identity Provider's name"),
cfg.StrOpt('protocol',
loading.Opt('protocol',
help='Protocol for federated plugin'),
])

View File

@ -10,8 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from keystoneauth1 import loading
from keystoneauth1 import token_endpoint
@ -26,9 +24,9 @@ class TokenEndpoint(loading.BaseLoader):
options = super(TokenEndpoint, self).get_options()
options.extend([
cfg.StrOpt('endpoint',
loading.Opt('endpoint',
help='The endpoint that will always be used'),
cfg.StrOpt('token',
loading.Opt('token',
secret=True,
help='The token that will always be used'),
])

View File

@ -11,7 +11,6 @@
# under the License.
import abc
import os
import six
import stevedore
@ -104,27 +103,9 @@ class BaseLoader(object):
:param parser: the parser to attach argparse options.
:type parser: argparse.ArgumentParser
"""
# NOTE(jamielennox): ideally oslo_config would be smart enough to
# handle all the Opt manipulation that goes on in this file. However it
# is currently not. Options are handled in as similar a way as
# possible to oslo_config such that when available we should be able to
# transition.
for opt in self.get_options():
args = []
envs = []
for o in [opt] + opt.deprecated_opts:
args.append('--os-%s' % o.name)
envs.append('OS_%s' % o.name.replace('-', '_').upper())
# select the first ENV that is not false-y or return None
env_vars = (os.environ.get(e) for e in envs)
default = six.next(six.moves.filter(None, env_vars), None)
parser.add_argument(*args,
default=default or opt.default,
parser.add_argument(*opt.argparse_args,
default=opt.argparse_default,
metavar=opt.metavar,
help=opt.help,
dest='os_%s' % opt.dest)
@ -153,7 +134,7 @@ class BaseLoader(object):
:type conf: oslo_config.cfg.ConfigOpts
:param string group: The group name that options should be read from.
"""
plugin_opts = self.get_options()
plugin_opts = [o._to_oslo_opt() for o in self.get_options()]
conf.register_opts(plugin_opts, group=group)
def load_from_conf_options(self, conf, group, **kwargs):
@ -181,8 +162,8 @@ class BaseLoader(object):
specify a custom loader function that will be queried for the option
value.
The getter is a function that takes one value, an
:py:class:`oslo_config.cfg.Opt` and returns a value to load with.
The getter is a function that takes one value, a
:py:class:`keystoneauth1.loading.Opt` and returns a value to load with.
:param getter: A function that returns a value for the given opt.
:type getter: callable

View File

@ -10,14 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from keystoneauth1.loading import base
from keystoneauth1.loading import opts
_AUTH_PLUGIN_OPT = cfg.StrOpt('auth_plugin', help='Name of the plugin to load')
_AUTH_PLUGIN_OPT = opts.Opt('auth_plugin', help='Name of the plugin to load')
_section_help = 'Config Section from which to load plugin specific options'
_AUTH_SECTION_OPT = cfg.StrOpt('auth_section', help=_section_help)
_AUTH_SECTION_OPT = opts.Opt('auth_section', help=_section_help)
def get_common_conf_options():
@ -64,7 +63,7 @@ def register_conf_options(conf, group):
:type conf: oslo_config.cfg.ConfigOpts
:param string group: The ini group to register options in.
"""
conf.register_opt(_AUTH_SECTION_OPT, group=group)
conf.register_opt(_AUTH_SECTION_OPT._to_oslo_opt(), group=group)
# NOTE(jamielennox): plugins are allowed to specify a 'section' which is
# the group that auth options should be taken from. If not present they
@ -74,7 +73,7 @@ def register_conf_options(conf, group):
if conf[group].auth_section:
group = conf[group].auth_section
conf.register_opt(_AUTH_PLUGIN_OPT, group=group)
conf.register_opt(_AUTH_PLUGIN_OPT._to_oslo_opt(), group=group)
def load_from_conf_options(conf, group, **kwargs):

View File

@ -0,0 +1,87 @@
# 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.
import itertools
import os
try:
from oslo_config import cfg
except ImportError:
cfg = None
from keystoneauth1 import _utils as utils
class Opt(object):
@utils.positional()
def __init__(self,
name,
type=str,
help=None,
secret=False,
dest=None,
deprecated=None,
default=None,
metavar=None):
if not callable(type):
raise TypeError('type must be callable')
if dest is None:
dest = name.replace('-', '_')
self.name = name
self.type = type
self.help = help
self.secret = secret
self.dest = dest
self.deprecated = [] if deprecated is None else deprecated
self.default = default
self.metavar = metavar
def __repr__(self):
return '<Opt: %s>' % self.name
def _to_oslo_opt(self):
if not cfg:
raise ImportError("oslo.config is not an automatic dependency of "
"keystoneauth. If you wish to use oslo.config "
"you need to import it into your application's "
"requirements file. ")
deprecated_opts = [o._to_oslo_opt() for o in self.deprecated]
return cfg.Opt(name=self.name,
type=self.type,
help=self.help,
secret=self.secret,
dest=self.dest,
deprecated_opts=deprecated_opts,
metavar=self.metavar)
@property
def _all_opts(self):
return itertools.chain([self], self.deprecated)
@property
def argparse_args(self):
return ['--os-%s' % o.name for o in self._all_opts]
@property
def argparse_default(self):
# select the first ENV that is not false-y or return None
for o in self._all_opts:
v = os.environ.get('OS_%s' % self.name.replace('-', '_').upper())
if v:
return v
return self.default

View File

@ -14,7 +14,6 @@ import functools
import uuid
import mock
from oslo_config import cfg
import six
from keystoneauth1 import access
@ -41,6 +40,12 @@ class MockPlugin(plugin.BaseAuthPlugin):
return 'http://test'
class BoolType(object):
def __call__(self, value):
return value.lower() in ('1', 'true', 't', 'yes', 'y')
class MockLoader(loading.BaseLoader):
INT_DESC = 'test int'
@ -55,10 +60,10 @@ class MockLoader(loading.BaseLoader):
def get_options(self):
return [
cfg.IntOpt('a-int', default='3', help=self.INT_DESC),
cfg.BoolOpt('a-bool', help=self.BOOL_DESC),
cfg.FloatOpt('a-float', help=self.FLOAT_DESC),
cfg.StrOpt('a-str', help=self.STR_DESC, default=self.STR_DEFAULT),
loading.Opt('a-int', default=3, type=int, help=self.INT_DESC),
loading.Opt('a-bool', type=BoolType(), help=self.BOOL_DESC),
loading.Opt('a-float', type=float, help=self.FLOAT_DESC),
loading.Opt('a-str', help=self.STR_DESC, default=self.STR_DEFAULT),
]

View File

@ -15,7 +15,6 @@ import uuid
import fixtures
import mock
from oslo_config import cfg
from keystoneauth1 import base
from keystoneauth1 import loading
@ -38,9 +37,9 @@ class TesterLoader(loading.BaseLoader):
# NOTE(jamielennox): this is kind of horrible. If you specify this as
# a deprecated_name= value it will convert - to _ which is not what we
# want for a CLI option.
deprecated = [cfg.DeprecatedOpt('test-other')]
deprecated = [loading.Opt('test-other')]
return [
cfg.StrOpt('test-opt', help='tester', deprecated_opts=deprecated)
loading.Opt('test-opt', help='tester', deprecated=deprecated)
]

View File

@ -13,7 +13,6 @@
import uuid
import mock
from oslo_config import cfg
from oslo_config import fixture as config
import stevedore
@ -157,14 +156,14 @@ class ConfTests(utils.TestCase):
def inner(driver):
for p in driver.plugin().get_options():
self.assertIsInstance(p, cfg.Opt)
self.assertIsInstance(p, loading.Opt)
manager.map(inner)
def test_get_common(self):
opts = loading.get_common_conf_options()
for opt in opts:
self.assertIsInstance(opt, cfg.Opt)
self.assertIsInstance(opt, loading.Opt)
self.assertEqual(2, len(opts))
def test_get_named(self):

View File

@ -4,7 +4,6 @@
argparse
iso8601>=0.1.9
oslo.config>=1.11.0 # Apache-2.0
requests>=2.5.2
six>=1.9.0
stevedore>=1.5.0 # Apache-2.0

View File

@ -11,6 +11,7 @@ keyring!=3.3,>=2.1
mock>=1.2
mox3>=0.7.0
oauthlib>=0.6
oslo.config>=1.11.0 # Apache-2.0
oslosphinx>=2.5.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
pycrypto>=2.6