Remove plugin.load_from_conf_options and argparse

The intention with putting load_from_conf_options and
load_form_argparse_arguments on the plugin object was so that a plugin
could specify refinements for how you load from CLI or similar. This was
ok whilst keystoneauth/keystoneclient controlled all the loading
mechanisms but with openstack-client-config this scheme wouldn't work.

Remove the methods from the classes (keep the methods a user would use)
until we can figure out a more extensible way for a plugin to specify
loading refinements.

Change-Id: I13c3fc2819f95cb95de5e7e8ba9f0a055d69ebf1
This commit is contained in:
Jamie Lennox 2015-08-24 18:17:28 +10:00
parent 02786d67a0
commit dcea6b89ee
5 changed files with 39 additions and 145 deletions

View File

@ -176,91 +176,3 @@ class BaseLoader(object):
to create the plugin.
"""
return self.plugin_class(**kwargs)
def register_argparse_arguments(self, parser):
"""Register the CLI options provided by a specific plugin.
Given a plugin class convert it's options into argparse arguments and
add them to a parser.
:param parser: the parser to attach argparse options.
:type parser: argparse.ArgumentParser
"""
for opt in self.get_options():
parser.add_argument(*opt.argparse_args,
default=opt.argparse_default,
metavar=opt.metavar,
help=opt.help,
dest='os_%s' % opt.dest)
def load_from_argparse_arguments(self, namespace, **kwargs):
"""Load a specific plugin object from an argparse result.
Convert the results of a parse into the specified plugin.
:param namespace: The result from CLI parsing.
:type namespace: argparse.Namespace
:returns: An auth plugin, or None if a name is not provided.
:rtype: :py:class:`keystonauth.auth.BaseAuthPlugin`
"""
def _getter(opt):
return getattr(namespace, 'os_%s' % opt.dest)
return self.load_from_options_getter(_getter, **kwargs)
def register_conf_options(self, conf, group):
"""Register the oslo_config options that are needed for a plugin.
:param conf: A config object.
:type conf: oslo_config.cfg.ConfigOpts
:param string group: The group name that options should be read from.
"""
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):
"""Load the plugin from a CONF object.
Convert the options already registered into a real plugin.
:param conf: A config object.
:type conf: oslo_config.cfg.ConfigOpts
:param string group: The group name that options should be read from.
:returns: An authentication Plugin.
:rtype: :py:class:`keystonauth.auth.BaseAuthPlugin`
"""
def _getter(opt):
return conf[group][opt.dest]
return self.load_from_options_getter(_getter, **kwargs)
def load_from_options_getter(self, getter, **kwargs):
"""Load a plugin from a getter function that returns appropriate values
To handle cases other than the provided CONF and CLI loading you can
specify a custom loader function that will be queried for the option
value.
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
:returns: An authentication Plugin.
:rtype: :py:class:`keystonauth.auth.BaseAuthPlugin`
"""
plugin_opts = self.get_options()
for opt in plugin_opts:
val = getter(opt)
if val is not None:
val = opt.type(val)
kwargs.setdefault(opt.dest, val)
return self.load_from_options(**kwargs)

View File

@ -17,6 +17,15 @@ from keystoneauth1 import _utils as utils
from keystoneauth1.loading import base
def _register_plugin_argparse_arguments(parser, plugin):
for opt in plugin.get_options():
parser.add_argument(*opt.argparse_args,
default=opt.argparse_default,
metavar=opt.metavar,
help=opt.help,
dest='os_%s' % opt.dest)
@utils.positional()
def register_argparse_arguments(parser, argv, default=None):
"""Register CLI options needed to create a plugin.
@ -56,7 +65,7 @@ def register_argparse_arguments(parser, argv, default=None):
plugin = base.get_plugin_loader(options.os_auth_plugin)
group = parser.add_argument_group('Authentication Options', msg)
plugin.register_argparse_arguments(group)
_register_plugin_argparse_arguments(group, plugin)
return plugin
@ -82,4 +91,12 @@ def load_from_argparse_arguments(namespace, **kwargs):
else:
plugin = base.get_plugin_loader(namespace.os_auth_plugin)
return plugin.load_from_argparse_arguments(namespace, **kwargs)
plugin_opts = plugin.get_options()
for opt in plugin_opts:
val = getattr(namespace, 'os_%s' % opt.dest)
if val is not None:
val = opt.type(val)
kwargs.setdefault(opt.dest, val)
return plugin.load_from_options(**kwargs)

View File

@ -105,6 +105,16 @@ def load_from_conf_options(conf, group, **kwargs):
if not name:
return None
plugin_class = base.get_plugin_loader(name)
plugin_class.register_conf_options(conf, group)
return plugin_class.load_from_conf_options(conf, group, **kwargs)
plugin = base.get_plugin_loader(name)
plugin_opts = plugin.get_options()
oslo_opts = [o._to_oslo_opt() for o in plugin_opts]
conf.register_opts(oslo_opts, group=group)
for opt in plugin_opts:
val = conf[group][opt.dest]
if val is not None:
val = opt.type(val)
kwargs.setdefault(opt.dest, val)
return plugin.load_from_options(**kwargs)

View File

@ -1,47 +0,0 @@
# 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 uuid
import six
from keystoneauth1.tests.unit.auth import utils
class TestOtherLoading(utils.TestCase):
def test_loading_getter(self):
called_opts = []
vals = {'a-int': 44,
'a-bool': False,
'a-float': 99.99,
'a-str': 'value'}
val = uuid.uuid4().hex
def _getter(opt):
called_opts.append(opt.name)
# return str because oslo.config should convert them back
return str(vals[opt.name])
p = utils.MockLoader().load_from_options_getter(_getter, other=val)
self.assertEqual(set(vals), set(called_opts))
for k, v in six.iteritems(vals):
# replace - to _ because it's the dest used to create kwargs
self.assertEqual(v, p[k.replace('-', '_')])
# check that additional kwargs get passed through
self.assertEqual(val, p['other'])

View File

@ -17,6 +17,7 @@ import fixtures
import mock
from keystoneauth1 import loading
from keystoneauth1.loading import cli
from keystoneauth1 import plugin
from keystoneauth1.tests.unit.auth import utils
@ -164,19 +165,20 @@ class CliTests(utils.TestCase):
self.env('OS_A_STR', val)
klass = loading.register_argparse_arguments(self.p, [], default=name)
self.assertIsInstance(klass, utils.MockLoader)
opts = self.p.parse_args([])
a = klass.load_from_argparse_arguments(opts)
a = loading.load_from_argparse_arguments(opts)
self.assertEqual(val, a['a_str'])
def test_deprecated_cli_options(self):
TesterLoader().register_argparse_arguments(self.p)
cli._register_plugin_argparse_arguments(self.p, TesterLoader())
val = uuid.uuid4().hex
opts = self.p.parse_args(['--os-test-other', val])
self.assertEqual(val, opts.os_test_opt)
def test_deprecated_multi_cli_options(self):
TesterLoader().register_argparse_arguments(self.p)
cli._register_plugin_argparse_arguments(self.p, TesterLoader())
val1 = uuid.uuid4().hex
val2 = uuid.uuid4().hex
# argarse rules say that the last specified wins.
@ -188,7 +190,7 @@ class CliTests(utils.TestCase):
val = uuid.uuid4().hex
with mock.patch.dict('os.environ', {'OS_TEST_OTHER': val}):
TesterLoader().register_argparse_arguments(self.p)
cli._register_plugin_argparse_arguments(self.p, TesterLoader())
opts = self.p.parse_args([])
self.assertEqual(val, opts.os_test_opt)
@ -199,7 +201,7 @@ class CliTests(utils.TestCase):
with mock.patch.dict('os.environ', {'OS_TEST_OPT': val1,
'OS_TEST_OTHER': val2}):
TesterLoader().register_argparse_arguments(self.p)
cli._register_plugin_argparse_arguments(self.p, TesterLoader())
opts = self.p.parse_args([])
self.assertEqual(val1, opts.os_test_opt)