Merge "Support passing client certificates for server version requests"
This commit is contained in:
		@@ -70,7 +70,7 @@ for svc in ('volume', 'volumev2', 'volumev3'):
 | 
			
		||||
    discover.add_catalog_discover_hack(svc, re.compile(r'/v[12]/\w+/?$'), '/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_server_version(url, insecure=False, cacert=None):
 | 
			
		||||
def get_server_version(url, insecure=False, cacert=None, cert=None):
 | 
			
		||||
    """Queries the server via the naked endpoint and gets version info.
 | 
			
		||||
 | 
			
		||||
    :param url: url of the cinder endpoint
 | 
			
		||||
@@ -78,6 +78,10 @@ def get_server_version(url, insecure=False, cacert=None):
 | 
			
		||||
                     (https) requests
 | 
			
		||||
    :param cacert: Specify a CA bundle file to use in verifying a TLS
 | 
			
		||||
                            (https) server certificate
 | 
			
		||||
    :param cert: A client certificate to pass to requests. These are of the
 | 
			
		||||
                 same form as requests expects. Either a single filename
 | 
			
		||||
                 containing both the certificate and key or a tuple containing
 | 
			
		||||
                 the path to the certificate then a path to the key. (optional)
 | 
			
		||||
    :returns: APIVersion object for min and max version supported by
 | 
			
		||||
              the server
 | 
			
		||||
    """
 | 
			
		||||
@@ -115,7 +119,7 @@ def get_server_version(url, insecure=False, cacert=None):
 | 
			
		||||
                verify_cert = cacert
 | 
			
		||||
            else:
 | 
			
		||||
                verify_cert = True
 | 
			
		||||
        response = requests.get(version_url, verify=verify_cert)
 | 
			
		||||
        response = requests.get(version_url, verify=verify_cert, cert=cert)
 | 
			
		||||
        data = json.loads(response.text)
 | 
			
		||||
        versions = data['versions']
 | 
			
		||||
        for version in versions:
 | 
			
		||||
@@ -135,9 +139,10 @@ def get_server_version(url, insecure=False, cacert=None):
 | 
			
		||||
            api_versions.APIVersion(current_version))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_highest_client_server_version(url, insecure=False, cacert=None):
 | 
			
		||||
def get_highest_client_server_version(url, insecure=False,
 | 
			
		||||
                                      cacert=None, cert=None):
 | 
			
		||||
    """Returns highest supported version by client and server as a string."""
 | 
			
		||||
    min_server, max_server = get_server_version(url, insecure, cacert)
 | 
			
		||||
    min_server, max_server = get_server_version(url, insecure, cacert, cert)
 | 
			
		||||
    max_client = api_versions.APIVersion(api_versions.MAX_VERSION)
 | 
			
		||||
    return min(max_server, max_client).get_string()
 | 
			
		||||
 | 
			
		||||
@@ -286,7 +291,7 @@ class HTTPClient(object):
 | 
			
		||||
                 endpoint_type='publicURL', service_type=None,
 | 
			
		||||
                 service_name=None, volume_service_name=None,
 | 
			
		||||
                 os_endpoint=None, retries=None,
 | 
			
		||||
                 http_log_debug=False, cacert=None,
 | 
			
		||||
                 http_log_debug=False, cacert=None, cert=None,
 | 
			
		||||
                 auth_system='keystone', auth_plugin=None, api_version=None,
 | 
			
		||||
                 logger=None, user_domain_name='Default',
 | 
			
		||||
                 project_domain_name='Default', global_request_id=None):
 | 
			
		||||
@@ -324,7 +329,7 @@ class HTTPClient(object):
 | 
			
		||||
        self.timeout = timeout
 | 
			
		||||
        self.user_domain_name = user_domain_name
 | 
			
		||||
        self.project_domain_name = project_domain_name
 | 
			
		||||
 | 
			
		||||
        self.cert = cert
 | 
			
		||||
        if insecure:
 | 
			
		||||
            self.verify_cert = False
 | 
			
		||||
        else:
 | 
			
		||||
@@ -405,6 +410,7 @@ class HTTPClient(object):
 | 
			
		||||
            method,
 | 
			
		||||
            url,
 | 
			
		||||
            verify=self.verify_cert,
 | 
			
		||||
            cert=self.cert,
 | 
			
		||||
            **kwargs)
 | 
			
		||||
        self.http_log_resp(resp)
 | 
			
		||||
 | 
			
		||||
@@ -701,7 +707,7 @@ def _construct_http_client(username=None, password=None, project_id=None,
 | 
			
		||||
                           os_endpoint=None, retries=None,
 | 
			
		||||
                           http_log_debug=False,
 | 
			
		||||
                           auth_system='keystone', auth_plugin=None,
 | 
			
		||||
                           cacert=None, tenant_id=None,
 | 
			
		||||
                           cacert=None, cert=None, tenant_id=None,
 | 
			
		||||
                           session=None,
 | 
			
		||||
                           auth=None, api_version=None,
 | 
			
		||||
                           **kwargs):
 | 
			
		||||
@@ -741,6 +747,7 @@ def _construct_http_client(username=None, password=None, project_id=None,
 | 
			
		||||
                          retries=retries,
 | 
			
		||||
                          http_log_debug=http_log_debug,
 | 
			
		||||
                          cacert=cacert,
 | 
			
		||||
                          cert=cert,
 | 
			
		||||
                          auth_system=auth_system,
 | 
			
		||||
                          auth_plugin=auth_plugin,
 | 
			
		||||
                          logger=logger,
 | 
			
		||||
 
 | 
			
		||||
@@ -365,7 +365,9 @@ class GetAPIVersionTestCase(utils.TestCase):
 | 
			
		||||
 | 
			
		||||
        cinderclient.client.get_server_version(url, True)
 | 
			
		||||
 | 
			
		||||
        mock_request.assert_called_once_with(expected_url, verify=False)
 | 
			
		||||
        mock_request.assert_called_once_with(expected_url,
 | 
			
		||||
                                             verify=False,
 | 
			
		||||
                                             cert=None)
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cinderclient.client.requests.get')
 | 
			
		||||
    def test_get_server_version_cacert(self, mock_request):
 | 
			
		||||
@@ -383,7 +385,29 @@ class GetAPIVersionTestCase(utils.TestCase):
 | 
			
		||||
        cacert = '/path/to/cert'
 | 
			
		||||
        cinderclient.client.get_server_version(url, cacert=cacert)
 | 
			
		||||
 | 
			
		||||
        mock_request.assert_called_once_with(expected_url, verify=cacert)
 | 
			
		||||
        mock_request.assert_called_once_with(expected_url,
 | 
			
		||||
                                             verify=cacert,
 | 
			
		||||
                                             cert=None)
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cinderclient.client.requests.get')
 | 
			
		||||
    def test_get_server_version_cert(self, mock_request):
 | 
			
		||||
        mock_response = utils.TestResponse({
 | 
			
		||||
            "status_code": 200,
 | 
			
		||||
            "text": json.dumps(fakes.fake_request_get_no_v3())
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        mock_request.return_value = mock_response
 | 
			
		||||
 | 
			
		||||
        url = (
 | 
			
		||||
            "https://192.168.122.127:8776/v3/e5526285ebd741b1819393f772f11fc3")
 | 
			
		||||
        expected_url = "https://192.168.122.127:8776/"
 | 
			
		||||
 | 
			
		||||
        client_cert = '/path/to/cert'
 | 
			
		||||
        cinderclient.client.get_server_version(url, cert=client_cert)
 | 
			
		||||
 | 
			
		||||
        mock_request.assert_called_once_with(expected_url,
 | 
			
		||||
                                             verify=True,
 | 
			
		||||
                                             cert=client_cert)
 | 
			
		||||
 | 
			
		||||
    @mock.patch('cinderclient.client.requests.get')
 | 
			
		||||
    @ddt.data('3.12', '3.40')
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ REQUEST_ID = ['req-test-request-id']
 | 
			
		||||
class TestCase(testtools.TestCase):
 | 
			
		||||
    TEST_REQUEST_BASE = {
 | 
			
		||||
        'verify': True,
 | 
			
		||||
        'cert': None
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -56,9 +56,9 @@ class Client(object):
 | 
			
		||||
                 endpoint_type='publicURL', extensions=None,
 | 
			
		||||
                 service_type='volumev2', service_name=None,
 | 
			
		||||
                 volume_service_name=None, os_endpoint=None, retries=0,
 | 
			
		||||
                 http_log_debug=False, cacert=None, auth_system='keystone',
 | 
			
		||||
                 auth_plugin=None, session=None, api_version=None,
 | 
			
		||||
                 logger=None, **kwargs):
 | 
			
		||||
                 http_log_debug=False, cacert=None, cert=None,
 | 
			
		||||
                 auth_system='keystone', auth_plugin=None, session=None,
 | 
			
		||||
                 api_version=None, logger=None, **kwargs):
 | 
			
		||||
        # FIXME(comstud): Rename the api_key argument above when we
 | 
			
		||||
        # know it's not being used as keyword argument
 | 
			
		||||
        password = api_key
 | 
			
		||||
@@ -118,6 +118,7 @@ class Client(object):
 | 
			
		||||
            retries=retries,
 | 
			
		||||
            http_log_debug=http_log_debug,
 | 
			
		||||
            cacert=cacert,
 | 
			
		||||
            cert=cert,
 | 
			
		||||
            auth_system=auth_system,
 | 
			
		||||
            auth_plugin=auth_plugin,
 | 
			
		||||
            session=session,
 | 
			
		||||
 
 | 
			
		||||
@@ -63,9 +63,9 @@ class Client(object):
 | 
			
		||||
                 endpoint_type='publicURL', extensions=None,
 | 
			
		||||
                 service_type='volumev3', service_name=None,
 | 
			
		||||
                 volume_service_name=None, os_endpoint=None, retries=0,
 | 
			
		||||
                 http_log_debug=False, cacert=None, auth_system='keystone',
 | 
			
		||||
                 auth_plugin=None, session=None, api_version=None,
 | 
			
		||||
                 logger=None, **kwargs):
 | 
			
		||||
                 http_log_debug=False, cacert=None, cert=None,
 | 
			
		||||
                 auth_system='keystone', auth_plugin=None, session=None,
 | 
			
		||||
                 api_version=None, logger=None, **kwargs):
 | 
			
		||||
        # FIXME(comstud): Rename the api_key argument above when we
 | 
			
		||||
        # know it's not being used as keyword argument
 | 
			
		||||
        password = api_key
 | 
			
		||||
@@ -131,6 +131,7 @@ class Client(object):
 | 
			
		||||
            retries=retries,
 | 
			
		||||
            http_log_debug=http_log_debug,
 | 
			
		||||
            cacert=cacert,
 | 
			
		||||
            cert=cert,
 | 
			
		||||
            auth_system=auth_system,
 | 
			
		||||
            auth_plugin=auth_plugin,
 | 
			
		||||
            session=session,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								releasenotes/notes/bug-1915996-3aaa5e2548eb7c93.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								releasenotes/notes/bug-1915996-3aaa5e2548eb7c93.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
---
 | 
			
		||||
fixes:
 | 
			
		||||
  - |
 | 
			
		||||
    `Bug #1915996 <https://bugs.launchpad.net/python-cinderclient/+bug/1915996>`_:
 | 
			
		||||
    Passing client certificates for mTLS connections was not supported
 | 
			
		||||
    and now has been fixed.
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user