diff options
-rw-r--r-- | cinderclient/client.py | 13 | ||||
-rw-r--r-- | cinderclient/tests/unit/test_http.py | 33 |
2 files changed, 41 insertions, 5 deletions
diff --git a/cinderclient/client.py b/cinderclient/client.py index a6cbe2c..1364923 100644 --- a/cinderclient/client.py +++ b/cinderclient/client.py @@ -63,6 +63,7 @@ V1_SERVICE_TYPE = 'volume' SERVICE_TYPES = {'1': V1_SERVICE_TYPE, '2': V2_SERVICE_TYPE, '3': V3_SERVICE_TYPE} +REQ_ID_HEADER = 'X-OpenStack-Request-ID' # tell keystoneclient that we can ignore the /v1|v2/{project_id} component of # the service catalog when doing discovery lookups @@ -125,10 +126,12 @@ def _log_request_id(logger, resp, service_name): class SessionClient(adapter.LegacyJsonAdapter): + global_request_id = None def __init__(self, *args, **kwargs): self.api_version = kwargs.pop('api_version', None) self.api_version = self.api_version or api_versions.APIVersion() + self.global_request_id = kwargs.pop('global_request_id', None) self.retries = kwargs.pop('retries', 0) self._logger = logging.getLogger(__name__) super(SessionClient, self).__init__(*args, **kwargs) @@ -137,6 +140,10 @@ class SessionClient(adapter.LegacyJsonAdapter): kwargs.setdefault('headers', kwargs.get('headers', {})) api_versions.update_headers(kwargs["headers"], self.api_version) kwargs.setdefault('authenticated', False) + + if self.global_request_id: + kwargs['headers'].setdefault(REQ_ID_HEADER, self.global_request_id) + # Note(tpatil): The standard call raises errors from # keystoneauth, here we need to raise the cinderclient errors. raise_exc = kwargs.pop('raise_exc', True) @@ -231,12 +238,13 @@ class HTTPClient(object): http_log_debug=False, cacert=None, auth_system='keystone', auth_plugin=None, api_version=None, logger=None, user_domain_name='Default', - project_domain_name='Default'): + project_domain_name='Default', global_request_id=None): self.user = user self.password = password self.projectid = projectid self.tenant_id = tenant_id self.api_version = api_version or api_versions.APIVersion() + self.global_request_id = global_request_id if auth_system and auth_system != 'keystone' and not auth_plugin: raise exceptions.AuthSystemNotFound(auth_system) @@ -335,6 +343,9 @@ class HTTPClient(object): kwargs['data'] = json.dumps(kwargs.pop('body')) api_versions.update_headers(kwargs["headers"], self.api_version) + if self.global_request_id: + kwargs['headers'].setdefault(REQ_ID_HEADER, self.global_request_id) + if self.timeout: kwargs.setdefault('timeout', self.timeout) self.http_log_req((url, method,), kwargs) diff --git a/cinderclient/tests/unit/test_http.py b/cinderclient/tests/unit/test_http.py index 8eb78f7..f74b9d0 100644 --- a/cinderclient/tests/unit/test_http.py +++ b/cinderclient/tests/unit/test_http.py @@ -14,6 +14,7 @@ import json import mock import requests +import uuid from cinderclient import client from cinderclient import exceptions @@ -69,14 +70,15 @@ timeout_error_request = mock.Mock( side_effect=requests.exceptions.Timeout) -def get_client(retries=0): +def get_client(retries=0, **kwargs): cl = client.HTTPClient("username", "password", - "project_id", "auth_test", retries=retries) + "project_id", "auth_test", retries=retries, + **kwargs) return cl -def get_authed_client(retries=0): - cl = get_client(retries=retries) +def get_authed_client(retries=0, **kwargs): + cl = get_client(retries=retries, **kwargs) cl.management_url = "http://example.com" cl.auth_token = "token" cl.get_service_url = mock.Mock(return_value="http://example.com") @@ -114,6 +116,29 @@ class ClientTest(utils.TestCase): test_get_call() + def test_get_global_id(self): + global_id = "req-%s" % uuid.uuid4() + cl = get_authed_client(global_request_id=global_id) + + @mock.patch.object(requests, "request", mock_request) + @mock.patch('time.time', mock.Mock(return_value=1234)) + def test_get_call(): + resp, body = cl.get("/hi") + headers = {"X-Auth-Token": "token", + "X-Auth-Project-Id": "project_id", + "X-OpenStack-Request-ID": global_id, + "User-Agent": cl.USER_AGENT, + 'Accept': 'application/json', } + mock_request.assert_called_with( + "GET", + "http://example.com/hi", + headers=headers, + **self.TEST_REQUEST_BASE) + # Automatic JSON parsing + self.assertEqual({"hi": "there"}, body) + + test_get_call() + def test_get_reauth_0_retries(self): cl = get_authed_client(retries=0) |