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:
Jamie Lennox
2014-05-21 08:45:54 +10:00
parent 1e993c36a5
commit fe0c2f926a
2 changed files with 186 additions and 10 deletions

View File

@@ -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)

View File

@@ -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)