Commit 27eac499 authored by openstack's avatar openstack

Add return-request-id-to-caller function(v3/contrib)

Added return-request-id-to-caller function to resources and resource
managers in the following files.

* keystoneclient/v3/projects.py
* keystoneclient/v3/registered_limits.py
* keystoneclient/v3/roles.py
* keystoneclient/v3/limits.py
* keystoneclient/v3/contrib/federation/saml.py

Also made changes in base.py for _put() method so that if
include_metadata is True, the response data should include request_id
instead of returning None as response.

Change-Id: Ifc0ec9a9d666cccfee3b08ac61596a3692307f23
Implements: blueprint return-request-id-to-caller
parent fee326e5
......@@ -214,6 +214,10 @@ class Manager(object):
else:
return self._prepare_return_value(
resp, self.resource_class(self, body))
# In some cases (e.g. 'add_endpoint_to_project' from endpoint_filters
# resource), PUT request may not return a body so return None as
# response along with request_id if include_metadata is True.
return self._prepare_return_value(resp, body)
def _patch(self, url, body=None, response_key=None, **kwargs):
"""Update an object with PATCH method.
......
......@@ -656,7 +656,7 @@ class ImpliedRoleTests(utils.ClientTestCase, utils.CrudTests):
implied_role_id = uuid.uuid4().hex
self.stub_url('HEAD',
['roles', prior_role_id, 'implies', implied_role_id],
status_code=200)
status_code=204)
result = self.manager.check(prior_role_id, implied_role_id)
self.assertTrue(result)
......
......@@ -37,7 +37,7 @@ class SamlManager(base.Manager):
headers, body = self._create_common_request(service_provider, token_id)
resp, body = self.client.post(SAML2_ENDPOINT, json=body,
headers=headers)
return resp.text
return self._prepare_return_value(resp, resp.text)
def create_ecp_assertion(self, service_provider, token_id):
"""Create an ECP wrapped SAML assertion from a token.
......@@ -56,7 +56,7 @@ class SamlManager(base.Manager):
headers, body = self._create_common_request(service_provider, token_id)
resp, body = self.client.post(ECP_ENDPOINT, json=body,
headers=headers)
return resp.text
return self._prepare_return_value(resp, resp.text)
def _create_common_request(self, service_provider, token_id):
headers = {'Content-Type': 'application/json'}
......
......@@ -70,7 +70,9 @@ class LimitManager(base.CrudManager):
body = {self.collection_key: [limit_data]}
resp, body = self.client.post('/limits', body=body)
limit = body[self.collection_key].pop()
return self.resource_class(self, limit)
return self._prepare_return_value(resp,
self.resource_class(
self, limit))
def update(self, limit, project=None, service=None, resource_name=None,
resource_limit=None, description=None, **kwargs):
......
......@@ -278,7 +278,7 @@ class ProjectManager(base.CrudManager):
"""
url = "/projects/%s/tags/%s" % (base.getid(project),
urllib.parse.quote(tag))
self.client.put(url)
return self._put(url)
def update_tags(self, project, tags):
"""Update tag list of a project.
......@@ -295,7 +295,7 @@ class ProjectManager(base.CrudManager):
for tag in tags:
tag = urllib.parse.quote(tag)
resp, body = self.client.put(url, body={"tags": tags})
return body['tags']
return self._prepare_return_value(resp, body['tags'])
def delete_tag(self, project, tag):
"""Remove tag from project.
......@@ -304,7 +304,7 @@ class ProjectManager(base.CrudManager):
:param tag: str name of tag to remove from project
"""
self._delete(
return self._delete(
"/projects/%s/tags/%s" % (base.getid(project),
urllib.parse.quote(tag)))
......@@ -318,7 +318,8 @@ class ProjectManager(base.CrudManager):
"""
url = "/projects/%s/tags" % base.getid(project)
resp, body = self.client.get(url)
return self._encode_tags(body['tags'])
body['tags'] = self._encode_tags(body['tags'])
return self._prepare_return_value(resp, body['tags'])
def check_tag(self, project, tag):
"""Check if tag is associated with project.
......@@ -332,9 +333,9 @@ class ProjectManager(base.CrudManager):
url = "/projects/%s/tags/%s" % (base.getid(project),
urllib.parse.quote(tag))
try:
self.client.head(url)
resp, body = self.client.head(url)
# no errors means found the tag
return True
except exceptions.NotFound:
# 404 means tag not in project
return False
return self._prepare_return_value(resp, True)
except exceptions.HttpError as ex:
# return false with request_id if include_metadata=True
return self._prepare_return_value(ex.response, False)
......@@ -69,7 +69,9 @@ class RegisteredLimitManager(base.CrudManager):
body = {self.collection_key: [limit_data]}
resp, body = self.client.post('/registered_limits', body=body)
registered_limit = body[self.collection_key].pop()
return self.resource_class(self, registered_limit)
return self._prepare_return_value(resp,
self.resource_class(
self, registered_limit))
def update(self, registered_limit, service=None, resource_name=None,
default_limit=None, description=None, region=None, **kwargs):
......
......@@ -455,7 +455,8 @@ class InferenceRuleManager(base.CrudManager):
"""
url_tail = self._implied_role_url_tail(prior_role, implied_role)
_resp, body = self.client.put("/roles" + url_tail)
return self.resource_class(self, body['role_inference'])
return self._prepare_return_value(
_resp, self.resource_class(self, body['role_inference']))
def delete(self, prior_role, implied_role):
"""Delete an inference rule.
......@@ -478,7 +479,7 @@ class InferenceRuleManager(base.CrudManager):
"""
url_tail = self._implied_role_url_tail(prior_role, implied_role)
return self.client.delete("/roles" + url_tail)
return self._delete("/roles" + url_tail)
def get(self, prior_role, implied_role):
"""Retrieve an inference rule.
......@@ -499,7 +500,8 @@ class InferenceRuleManager(base.CrudManager):
"""
url_tail = self._implied_role_url_tail(prior_role, implied_role)
_resp, body = self.client.get("/roles" + url_tail)
return self.resource_class(self, body['role_inference'])
return self._prepare_return_value(
_resp, self.resource_class(self, body['role_inference']))
def list(self, prior_role):
"""List all roles that a role may imply.
......@@ -518,7 +520,8 @@ class InferenceRuleManager(base.CrudManager):
"""
url_tail = ('/%s/implies' % base.getid(prior_role))
_resp, body = self.client.get("/roles" + url_tail)
return self.resource_class(self, body['role_inference'])
return self._prepare_return_value(
_resp, self.resource_class(self, body['role_inference']))
def check(self, prior_role, implied_role):
"""Check if an inference rule exists.
......@@ -538,7 +541,7 @@ class InferenceRuleManager(base.CrudManager):
"""
url_tail = self._implied_role_url_tail(prior_role, implied_role)
return self.client.head("/roles" + url_tail)
return self._head("/roles" + url_tail)
def list_inference_roles(self):
"""List all rule inferences.
......
......@@ -3,5 +3,11 @@ features:
- >
[`blueprint return-request-id-to-caller
<https://blueprints.launchpad.net/python-keystoneclient/+spec/return-request-id-to-caller>`_]
Added support to return "x-openstack-request-id" header in request_ids attribute
for better tracing.
Instantiating client with ``include_metadata=True`` will cause manager response to return data
along with request_ids for better tracing. Refer [`using-api-v3
<https://docs.openstack.org/python-keystoneclient/latest/using-api-v3.html#getting-metadata-responses>`_]
Added support to return "x-openstack-request-id" header in request_ids attribute if
``include_metadata=True``. Also, for APIs which return response as None, client will return request_ids
as well if ``include_metadata`` is True.
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment