Merge "Move session loading into loading module"
This commit is contained in:
commit
505af7a61b
229
keystoneauth1/loading/session.py
Normal file
229
keystoneauth1/loading/session.py
Normal file
@ -0,0 +1,229 @@
|
||||
# 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 argparse
|
||||
import os
|
||||
|
||||
try:
|
||||
from oslo_config import cfg
|
||||
except ImportError:
|
||||
cfg = None
|
||||
|
||||
from keystoneauth1 import _utils as utils
|
||||
from keystoneauth1.loading import base
|
||||
from keystoneauth1 import session
|
||||
|
||||
|
||||
def _positive_non_zero_float(argument_value):
|
||||
if argument_value is None:
|
||||
return None
|
||||
try:
|
||||
value = float(argument_value)
|
||||
except ValueError:
|
||||
msg = "%s must be a float" % argument_value
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
if value <= 0:
|
||||
msg = "%s must be greater than 0" % argument_value
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
return value
|
||||
|
||||
|
||||
class Session(base.BaseLoader):
|
||||
|
||||
@property
|
||||
def plugin_class(self):
|
||||
return session.Session
|
||||
|
||||
def get_options(self):
|
||||
return []
|
||||
|
||||
@utils.positional(1)
|
||||
def load_from_options(self,
|
||||
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
|
||||
else:
|
||||
verify = cacert or True
|
||||
|
||||
if cert and key:
|
||||
# passing cert and key together is deprecated in favour of the
|
||||
# requests lib form of having the cert and key as a tuple
|
||||
cert = (cert, key)
|
||||
|
||||
return super(Session, self).load_from_options(verify=verify,
|
||||
cert=cert,
|
||||
**kwargs)
|
||||
|
||||
def register_argparse_arguments(self, parser):
|
||||
parser.add_argument('--insecure',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Explicitly allow client to perform '
|
||||
'"insecure" TLS (https) requests. The '
|
||||
'server\'s certificate will not be verified '
|
||||
'against any certificate authorities. This '
|
||||
'option should be used with caution.')
|
||||
|
||||
parser.add_argument('--os-cacert',
|
||||
metavar='<ca-certificate>',
|
||||
default=os.environ.get('OS_CACERT'),
|
||||
help='Specify a CA bundle file to use in '
|
||||
'verifying a TLS (https) server certificate. '
|
||||
'Defaults to env[OS_CACERT].')
|
||||
|
||||
parser.add_argument('--os-cert',
|
||||
metavar='<certificate>',
|
||||
default=os.environ.get('OS_CERT'),
|
||||
help='Defaults to env[OS_CERT].')
|
||||
|
||||
parser.add_argument('--os-key',
|
||||
metavar='<key>',
|
||||
default=os.environ.get('OS_KEY'),
|
||||
help='Defaults to env[OS_KEY].')
|
||||
|
||||
parser.add_argument('--timeout',
|
||||
default=600,
|
||||
type=_positive_non_zero_float,
|
||||
metavar='<seconds>',
|
||||
help='Set request timeout (in seconds).')
|
||||
|
||||
def load_from_argparse_arguments(self, namespace, **kwargs):
|
||||
kwargs['insecure'] = namespace.insecure
|
||||
kwargs['cacert'] = namespace.os_cacert
|
||||
kwargs['cert'] = namespace.os_cert
|
||||
kwargs['key'] = namespace.os_key
|
||||
kwargs['timeout'] = namespace.timeout
|
||||
|
||||
return super(Session, self).load_from_argparse_arguments(namespace,
|
||||
**kwargs)
|
||||
|
||||
def _get_conf_options(self, deprecated_opts=None):
|
||||
"""Get the oslo_config options that are needed for a
|
||||
:py:class:`.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 dict from the
|
||||
name of the new option to a list of oslo.DeprecatedOpts that
|
||||
correspond to the new option. (optional)
|
||||
|
||||
For 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 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. ")
|
||||
|
||||
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'),
|
||||
]
|
||||
|
||||
def register_conf_options(self, 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 dict from the
|
||||
name of the new option to a list of oslo.DeprecatedOpts that
|
||||
correspond to the new option. (optional)
|
||||
|
||||
For 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 = self._get_conf_options(deprecated_opts=deprecated_opts)
|
||||
conf.register_group(cfg.OptGroup(group))
|
||||
conf.register_opts(opts, group=group)
|
||||
return opts
|
||||
|
||||
def load_from_conf_options(self, 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.
|
||||
:rtype: :py:class:`.Session`
|
||||
"""
|
||||
c = conf[group]
|
||||
|
||||
kwargs['insecure'] = c.insecure
|
||||
kwargs['cacert'] = c.cafile
|
||||
kwargs['cert'] = c.certfile
|
||||
kwargs['key'] = c.keyfile
|
||||
kwargs['timeout'] = c.timeout
|
||||
|
||||
return super(Session, self).load_from_conf_options(conf,
|
||||
group,
|
||||
**kwargs)
|
@ -10,18 +10,15 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import functools
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from oslo_config import cfg
|
||||
import requests
|
||||
import six
|
||||
from six.moves import urllib
|
||||
@ -44,20 +41,6 @@ USER_AGENT = 'keystoneauth1'
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _positive_non_zero_float(argument_value):
|
||||
if argument_value is None:
|
||||
return None
|
||||
try:
|
||||
value = float(argument_value)
|
||||
except ValueError:
|
||||
msg = "%s must be a float" % argument_value
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
if value <= 0:
|
||||
msg = "%s must be greater than 0" % argument_value
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
return value
|
||||
|
||||
|
||||
class _JSONEncoder(json.JSONEncoder):
|
||||
|
||||
def default(self, o):
|
||||
@ -550,28 +533,6 @@ class Session(object):
|
||||
"""
|
||||
return self.request(url, 'PATCH', **kwargs)
|
||||
|
||||
@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
|
||||
else:
|
||||
verify = cacert or True
|
||||
|
||||
if cert and key:
|
||||
# passing cert and key together is deprecated in favour of the
|
||||
# requests lib form of having the cert and key as a tuple
|
||||
cert = (cert, key)
|
||||
|
||||
return cls(verify=verify, cert=cert, **kwargs)
|
||||
|
||||
def _auth_required(self, auth, msg):
|
||||
if not auth:
|
||||
auth = self.auth
|
||||
@ -735,169 +696,6 @@ class Session(object):
|
||||
auth = self._auth_required(auth, 'get project_id')
|
||||
return auth.get_project_id(self)
|
||||
|
||||
@utils.positional.classmethod()
|
||||
def get_conf_options(cls, deprecated_opts=None):
|
||||
"""Get the oslo_config options that are needed for a
|
||||
:py:class:`.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 dict from the
|
||||
name of the new option to a list of oslo.DeprecatedOpts that
|
||||
correspond to the new option. (optional)
|
||||
|
||||
For 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 dict from the
|
||||
name of the new option to a list of oslo.DeprecatedOpts that
|
||||
correspond to the new option. (optional)
|
||||
|
||||
For 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.
|
||||
:rtype: :py:class:`.Session`
|
||||
"""
|
||||
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)
|
||||
|
||||
@staticmethod
|
||||
def register_cli_options(parser):
|
||||
"""Register the argparse arguments that are needed for a session.
|
||||
|
||||
:param argparse.ArgumentParser parser: parser to add to.
|
||||
"""
|
||||
parser.add_argument('--insecure',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Explicitly allow client to perform '
|
||||
'"insecure" TLS (https) requests. The '
|
||||
'server\'s certificate will not be verified '
|
||||
'against any certificate authorities. This '
|
||||
'option should be used with caution.')
|
||||
|
||||
parser.add_argument('--os-cacert',
|
||||
metavar='<ca-certificate>',
|
||||
default=os.environ.get('OS_CACERT'),
|
||||
help='Specify a CA bundle file to use in '
|
||||
'verifying a TLS (https) server certificate. '
|
||||
'Defaults to env[OS_CACERT].')
|
||||
|
||||
parser.add_argument('--os-cert',
|
||||
metavar='<certificate>',
|
||||
default=os.environ.get('OS_CERT'),
|
||||
help='Defaults to env[OS_CERT].')
|
||||
|
||||
parser.add_argument('--os-key',
|
||||
metavar='<key>',
|
||||
default=os.environ.get('OS_KEY'),
|
||||
help='Defaults to env[OS_KEY].')
|
||||
|
||||
parser.add_argument('--timeout',
|
||||
default=600,
|
||||
type=_positive_non_zero_float,
|
||||
metavar='<seconds>',
|
||||
help='Set request timeout (in seconds).')
|
||||
|
||||
@classmethod
|
||||
def load_from_cli_options(cls, args, **kwargs):
|
||||
"""Create a :py:class:`.Session` object from CLI arguments.
|
||||
|
||||
The CLI arguments must have been registered with
|
||||
:py:meth:`.register_cli_options`.
|
||||
|
||||
:param Namespace args: result of parsed arguments.
|
||||
|
||||
:returns: A new session object.
|
||||
:rtype: :py:class:`.Session`
|
||||
"""
|
||||
kwargs['insecure'] = args.insecure
|
||||
kwargs['cacert'] = args.os_cacert
|
||||
kwargs['cert'] = args.os_cert
|
||||
kwargs['key'] = args.os_key
|
||||
kwargs['timeout'] = args.timeout
|
||||
|
||||
return cls._make(**kwargs)
|
||||
|
||||
|
||||
class TCPKeepAliveAdapter(requests.adapters.HTTPAdapter):
|
||||
"""The custom adapter used to set TCP Keep-Alive on all connections.
|
||||
|
@ -25,6 +25,7 @@ from testtools import matchers
|
||||
|
||||
from keystoneauth1 import adapter
|
||||
from keystoneauth1 import exceptions
|
||||
from keystoneauth1.loading import session as session_loader
|
||||
from keystoneauth1 import plugin
|
||||
from keystoneauth1 import session as client_session
|
||||
from keystoneauth1.tests.unit import utils
|
||||
@ -827,15 +828,15 @@ class ConfLoadingTests(utils.TestCase):
|
||||
super(ConfLoadingTests, self).setUp()
|
||||
|
||||
self.conf_fixture = self.useFixture(config.Config())
|
||||
client_session.Session.register_conf_options(self.conf_fixture.conf,
|
||||
self.GROUP)
|
||||
session_loader.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(
|
||||
return session_loader.Session().load_from_conf_options(
|
||||
self.conf_fixture.conf,
|
||||
self.GROUP,
|
||||
**kwargs)
|
||||
@ -871,7 +872,7 @@ class ConfLoadingTests(utils.TestCase):
|
||||
|
||||
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)
|
||||
opts = session_loader.Session()._get_conf_options(deprecated_opts=depr)
|
||||
|
||||
self.assertThat(opt_names, matchers.HasLength(len(opts)))
|
||||
for opt in opts:
|
||||
@ -884,11 +885,12 @@ class CliLoadingTests(utils.TestCase):
|
||||
super(CliLoadingTests, self).setUp()
|
||||
|
||||
self.parser = argparse.ArgumentParser()
|
||||
client_session.Session.register_cli_options(self.parser)
|
||||
session_loader.Session().register_argparse_arguments(self.parser)
|
||||
|
||||
def get_session(self, val, **kwargs):
|
||||
args = self.parser.parse_args(val.split())
|
||||
return client_session.Session.load_from_cli_options(args, **kwargs)
|
||||
return session_loader.Session().load_from_argparse_arguments(args,
|
||||
**kwargs)
|
||||
|
||||
def test_insecure_timeout(self):
|
||||
s = self.get_session('--insecure --timeout 5.5')
|
||||
|
Loading…
x
Reference in New Issue
Block a user