Session loading from conf
Allow loading session objects from oslo.config. We want a generic way to do this for auth_token middleware and for servers creating session objects for inter-service communication. DocImpact: This is the first step in standardizing all the config options across projects. There are no changes to the config options that keystoneclient actually consumes in this review. Implements: blueprint standard-client-params Change-Id: I1e83280b2f76f16041ed8d5ed598db70210112bd
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from oslo.config import cfg
|
||||
import requests
|
||||
import six
|
||||
from six.moves import urllib
|
||||
@@ -355,12 +356,26 @@ class Session(object):
|
||||
functionswithout session arguments.
|
||||
|
||||
"""
|
||||
verify = kwargs.pop('verify', None)
|
||||
cacert = kwargs.pop('cacert', None)
|
||||
cert = kwargs.pop('cert', None)
|
||||
key = kwargs.pop('key', None)
|
||||
insecure = kwargs.pop('insecure', False)
|
||||
params = {}
|
||||
|
||||
for attr in ('verify', 'cacert', 'cert', 'key', 'insecure',
|
||||
'timeout', 'session', 'original_ip', 'user_agent'):
|
||||
try:
|
||||
params[attr] = kwargs.pop(attr)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return cls._make(**params)
|
||||
|
||||
@classmethod
|
||||
def _make(cls, insecure=False, verify=None, cacert=None, cert=None,
|
||||
key=None, **kwargs):
|
||||
"""Create a session with individual certificate parameters.
|
||||
|
||||
Some parameters used to create a session don't lend themselves to be
|
||||
loaded from config/CLI etc. Create a session by converting those
|
||||
parameters into session __init__ parameters.
|
||||
"""
|
||||
if verify is None:
|
||||
if insecure:
|
||||
verify = False
|
||||
@@ -372,11 +387,7 @@ class Session(object):
|
||||
# requests lib form of having the cert and key as a tuple
|
||||
cert = (cert, key)
|
||||
|
||||
return cls(verify=verify, cert=cert,
|
||||
timeout=kwargs.pop('timeout', None),
|
||||
session=kwargs.pop('session', None),
|
||||
original_ip=kwargs.pop('original_ip', None),
|
||||
user_agent=kwargs.pop('user_agent', None))
|
||||
return cls(verify=verify, cert=cert, **kwargs)
|
||||
|
||||
def get_token(self, auth=None):
|
||||
"""Return a token as provided by the auth plugin.
|
||||
@@ -432,3 +443,106 @@ class Session(object):
|
||||
raise exceptions.MissingAuthPlugin(msg)
|
||||
|
||||
return auth.invalidate()
|
||||
|
||||
@utils.positional.classmethod()
|
||||
def get_conf_options(cls, deprecated_opts=None):
|
||||
"""Get the oslo.config options that are needed for a session.
|
||||
|
||||
These may be useful without being registered for config file generation
|
||||
or to manipulate the options before registering them yourself.
|
||||
|
||||
The options that are set are:
|
||||
:cafile: The certificate authority filename.
|
||||
:certfile: The client certificate file to present.
|
||||
:keyfile: The key for the client certificate.
|
||||
:insecure: Whether to ignore SSL verification.
|
||||
:timeout: The max time to wait for HTTP connections.
|
||||
|
||||
:param dict deprecated_opts: Deprecated options that should be included
|
||||
in the definition of new options. This should be a dictionary from
|
||||
the name of the new option to a list of oslo.DeprecatedOpts that
|
||||
correspond to the new option. (optional)
|
||||
|
||||
Example to support the 'ca_file' option pointing to the new
|
||||
'cafile' option name::
|
||||
|
||||
old_opt = oslo.cfg.DeprecatedOpt('ca_file', 'old_group')
|
||||
deprecated_opts={'cafile': [old_opt]}
|
||||
|
||||
:returns: A list of oslo.config options.
|
||||
"""
|
||||
if deprecated_opts is None:
|
||||
deprecated_opts = {}
|
||||
|
||||
return [cfg.StrOpt('cafile',
|
||||
deprecated_opts=deprecated_opts.get('cafile'),
|
||||
help='PEM encoded Certificate Authority to use '
|
||||
'when verifying HTTPs connections.'),
|
||||
cfg.StrOpt('certfile',
|
||||
deprecated_opts=deprecated_opts.get('certfile'),
|
||||
help='PEM encoded client certificate cert file'),
|
||||
cfg.StrOpt('keyfile',
|
||||
deprecated_opts=deprecated_opts.get('keyfile'),
|
||||
help='PEM encoded client certificate key file'),
|
||||
cfg.BoolOpt('insecure',
|
||||
default=False,
|
||||
deprecated_opts=deprecated_opts.get('insecure'),
|
||||
help='Verify HTTPS connections.'),
|
||||
cfg.IntOpt('timeout',
|
||||
deprecated_opts=deprecated_opts.get('timeout'),
|
||||
help='Timeout value for http requests'),
|
||||
]
|
||||
|
||||
@utils.positional.classmethod()
|
||||
def register_conf_options(cls, conf, group, deprecated_opts=None):
|
||||
"""Register the oslo.config options that are needed for a session.
|
||||
|
||||
The options that are set are:
|
||||
:cafile: The certificate authority filename.
|
||||
:certfile: The client certificate file to present.
|
||||
:keyfile: The key for the client certificate.
|
||||
:insecure: Whether to ignore SSL verification.
|
||||
:timeout: The max time to wait for HTTP connections.
|
||||
|
||||
:param oslo.config.Cfg conf: config object to register with.
|
||||
:param string group: The ini group to register options in.
|
||||
:param dict deprecated_opts: Deprecated options that should be included
|
||||
in the definition of new options. This should be a dictionary from
|
||||
the name of the new option to a list of oslo.DeprecatedOpts that
|
||||
correspond to the new option. (optional)
|
||||
|
||||
Example to support the 'ca_file' option pointing to the new
|
||||
'cafile' option name::
|
||||
|
||||
old_opt = oslo.cfg.DeprecatedOpt('ca_file', 'old_group')
|
||||
deprecated_opts={'cafile': [old_opt]}
|
||||
|
||||
:returns: The list of options that was registered.
|
||||
"""
|
||||
opts = cls.get_conf_options(deprecated_opts=deprecated_opts)
|
||||
conf.register_group(cfg.OptGroup(group))
|
||||
conf.register_opts(opts, group=group)
|
||||
return opts
|
||||
|
||||
@classmethod
|
||||
def load_from_conf_options(cls, conf, group, **kwargs):
|
||||
"""Create a session object from an oslo.config object.
|
||||
|
||||
The options must have been previously registered with
|
||||
register_conf_options.
|
||||
|
||||
:param oslo.config.Cfg conf: config object to register with.
|
||||
:param string group: The ini group to register options in.
|
||||
:param dict kwargs: Additional parameters to pass to session
|
||||
construction.
|
||||
:returns: A new session object.
|
||||
"""
|
||||
c = conf[group]
|
||||
|
||||
kwargs['insecure'] = c.insecure
|
||||
kwargs['cacert'] = c.cafile
|
||||
kwargs['cert'] = c.certfile
|
||||
kwargs['key'] = c.keyfile
|
||||
kwargs['timeout'] = c.timeout
|
||||
|
||||
return cls._make(**kwargs)
|
||||
|
@@ -14,12 +14,15 @@ import uuid
|
||||
|
||||
import httpretty
|
||||
import mock
|
||||
from oslo.config import cfg
|
||||
import requests
|
||||
import six
|
||||
from testtools import matchers
|
||||
|
||||
from keystoneclient import adapter
|
||||
from keystoneclient.auth import base
|
||||
from keystoneclient import exceptions
|
||||
from keystoneclient.openstack.common.fixture import config
|
||||
from keystoneclient.openstack.common import jsonutils
|
||||
from keystoneclient import session as client_session
|
||||
from keystoneclient.tests import utils
|
||||
@@ -599,3 +602,62 @@ class AdapterTest(utils.TestCase):
|
||||
with mock.patch.object(adpt, 'request') as m:
|
||||
getattr(adpt, method)(url)
|
||||
m.assert_called_once_with(url, method.upper())
|
||||
|
||||
|
||||
class ConfLoadingTests(utils.TestCase):
|
||||
|
||||
GROUP = 'sessiongroup'
|
||||
|
||||
def setUp(self):
|
||||
super(ConfLoadingTests, self).setUp()
|
||||
|
||||
self.conf_fixture = self.useFixture(config.Config())
|
||||
client_session.Session.register_conf_options(self.conf_fixture.conf,
|
||||
self.GROUP)
|
||||
|
||||
def config(self, **kwargs):
|
||||
kwargs['group'] = self.GROUP
|
||||
self.conf_fixture.config(**kwargs)
|
||||
|
||||
def get_session(self, **kwargs):
|
||||
return client_session.Session.load_from_conf_options(
|
||||
self.conf_fixture.conf,
|
||||
self.GROUP,
|
||||
**kwargs)
|
||||
|
||||
def test_insecure_timeout(self):
|
||||
self.config(insecure=True, timeout=5)
|
||||
s = self.get_session()
|
||||
|
||||
self.assertFalse(s.verify)
|
||||
self.assertEqual(5, s.timeout)
|
||||
|
||||
def test_client_certs(self):
|
||||
cert = '/path/to/certfile'
|
||||
key = '/path/to/keyfile'
|
||||
|
||||
self.config(certfile=cert, keyfile=key)
|
||||
s = self.get_session()
|
||||
|
||||
self.assertTrue(s.verify)
|
||||
self.assertEqual((cert, key), s.cert)
|
||||
|
||||
def test_cacert(self):
|
||||
cafile = '/path/to/cacert'
|
||||
|
||||
self.config(cafile=cafile)
|
||||
s = self.get_session()
|
||||
|
||||
self.assertEqual(cafile, s.verify)
|
||||
|
||||
def test_deprecated(self):
|
||||
def new_deprecated():
|
||||
return cfg.DeprecatedOpt(uuid.uuid4().hex, group=uuid.uuid4().hex)
|
||||
|
||||
opt_names = ['cafile', 'certfile', 'keyfile', 'insecure', 'timeout']
|
||||
depr = dict([(n, [new_deprecated()]) for n in opt_names])
|
||||
opts = client_session.Session.get_conf_options(deprecated_opts=depr)
|
||||
|
||||
self.assertThat(opt_names, matchers.HasLength(len(opts)))
|
||||
for opt in opts:
|
||||
self.assertIn(depr[opt.name][0], opt.deprecated_opts)
|
||||
|
Reference in New Issue
Block a user