Support client certificate/key

This change enables to specify a client certificate/key with:
 * os-client-config config
 * Connection cert argument:
   * client certificate path via a string
   * client certificate/key paths via a tuple

Closes-Bug: #1569508
Related-Bug: #1569513
Change-Id: I657b19708fd45acaa705af6d877c50ef89df79fe
This commit is contained in:
Cedric Brandily 2016-04-12 20:29:27 +02:00
parent a784148b52
commit 46236ae559
2 changed files with 15 additions and 4 deletions

View File

@ -142,13 +142,19 @@ def from_config(cloud_name=None, cloud_config=None, options=None):
if 'insecure' in cloud_config.config: if 'insecure' in cloud_config.config:
auth['verify'] = not bool(cloud_config.config['insecure']) auth['verify'] = not bool(cloud_config.config['insecure'])
cert = cloud_config.config.get('cert')
if cert:
key = cloud_config.config.get('key')
auth['cert'] = (cert, key) if key else cert
return Connection(profile=prof, **auth) return Connection(profile=prof, **auth)
class Connection(object): class Connection(object):
def __init__(self, session=None, authenticator=None, profile=None, def __init__(self, session=None, authenticator=None, profile=None,
verify=True, user_agent=None, auth_plugin="password", verify=True, cert=None, user_agent=None,
auth_plugin="password",
**auth_args): **auth_args):
"""Create a context for a connection to a cloud provider. """Create a context for a connection to a cloud provider.
@ -179,6 +185,11 @@ class Connection(object):
this parameter will be used to create a transport. If ``verify`` this parameter will be used to create a transport. If ``verify``
is set to true, which is the default, the SSL cert will be is set to true, which is the default, the SSL cert will be
verified. It can also be set to a CA_BUNDLE path. verified. It can also be set to a CA_BUNDLE path.
:param cert: If a transport is not provided to the connection then this
parameter will be used to create a transport. `cert` allows to
provide a client certificate file path or a tuple with client
certificate and key paths.
:type cert: str or tuple
:param str user_agent: If a transport is not provided to the :param str user_agent: If a transport is not provided to the
connection, this parameter will be used when creating a transport. connection, this parameter will be used when creating a transport.
The value given here will be prepended to the default, which is The value given here will be prepended to the default, which is
@ -196,7 +207,7 @@ class Connection(object):
**auth_args) **auth_args)
self.profile = profile if profile else _profile.Profile() self.profile = profile if profile else _profile.Profile()
self.session = session if session else _session.Session( self.session = session if session else _session.Session(
self.profile, auth=self.authenticator, verify=verify, self.profile, auth=self.authenticator, verify=verify, cert=cert,
user_agent=user_agent) user_agent=user_agent)
self._open() self._open()

View File

@ -46,8 +46,8 @@ class TestConnection(base.TestCase):
mock_profile = mock.Mock() mock_profile = mock.Mock()
mock_profile.get_services = mock.Mock(return_value=[]) mock_profile.get_services = mock.Mock(return_value=[])
conn = connection.Connection(profile=mock_profile, authenticator='2', conn = connection.Connection(profile=mock_profile, authenticator='2',
verify=True, user_agent='1') verify=True, cert='cert', user_agent='1')
args = {'auth': '2', 'user_agent': '1', 'verify': True} args = {'auth': '2', 'user_agent': '1', 'verify': True, 'cert': 'cert'}
mock_session_init.assert_called_with(mock_profile, **args) mock_session_init.assert_called_with(mock_profile, **args)
self.assertEqual(mock_session_init, conn.session) self.assertEqual(mock_session_init, conn.session)