Allow to pass global request id for remaining objects

This change also allows passing ironic API microversion in places
where it was not possible previously, for consistency.

Story: 2007611
Task: 39602
Change-Id: I08a1d2227138e1c57ce865f159d0fc68ae95d8f0
This commit is contained in:
Vladyslav Drok 2020-05-06 19:23:57 +02:00
parent 4449f7184f
commit 3aff1bb2ae
7 changed files with 210 additions and 70 deletions

View File

@ -328,7 +328,9 @@ class AllocationWaitTest(testtools.TestCase):
self.assertIs(result, allocations[2])
self.assertEqual(3, mock_get.call_count)
self.assertEqual(2, mock_sleep.call_count)
mock_get.assert_called_with(self.mgr, 'alloc1')
mock_get.assert_called_with(
self.mgr, 'alloc1', os_ironic_api_version=None,
global_request_id=None)
def test_error(self, mock_get, mock_sleep):
allocations = [
@ -342,7 +344,9 @@ class AllocationWaitTest(testtools.TestCase):
self.assertEqual(2, mock_get.call_count)
self.assertEqual(1, mock_sleep.call_count)
mock_get.assert_called_with(self.mgr, 'alloc1')
mock_get.assert_called_with(
self.mgr, 'alloc1', os_ironic_api_version=None,
global_request_id=None)
def test_timeout(self, mock_get, mock_sleep):
mock_get.return_value = self._fake_allocation('allocating')
@ -350,4 +354,6 @@ class AllocationWaitTest(testtools.TestCase):
self.assertRaises(exc.StateTransitionTimeout,
self.mgr.wait, 'alloc1', timeout=0.001)
mock_get.assert_called_with(self.mgr, 'alloc1')
mock_get.assert_called_with(
self.mgr, 'alloc1', os_ironic_api_version=None,
global_request_id=None)

View File

@ -161,7 +161,8 @@ class DriverManagerTest(testtools.TestCase):
_list_mock.assert_called_once_with(
self.mgr,
'/v1/drivers/%s/raid/logical_disk_properties' % DRIVER2['name'])
'/v1/drivers/%s/raid/logical_disk_properties' % DRIVER2['name'],
os_ironic_api_version=None, global_request_id=None)
self.assertEqual({}, properties)
@mock.patch.object(driver.DriverManager, 'update', autospec=True)
@ -179,9 +180,10 @@ class DriverManagerTest(testtools.TestCase):
for http_method in ('POST', 'PUT', 'PATCH'):
kwargs['http_method'] = http_method
self.mgr.vendor_passthru(**kwargs)
update_mock.assert_called_once_with(mock.ANY, final_path,
vendor_passthru_args,
http_method=http_method)
update_mock.assert_called_once_with(
mock.ANY, final_path, vendor_passthru_args,
http_method=http_method, os_ironic_api_version=None,
global_request_id=None)
update_mock.reset_mock()
@mock.patch.object(driver.DriverManager, 'get', autospec=True)
@ -194,7 +196,9 @@ class DriverManagerTest(testtools.TestCase):
final_path = 'driver_name/vendor_passthru/method'
self.mgr.vendor_passthru(**kwargs)
get_mock.assert_called_once_with(mock.ANY, final_path)
get_mock.assert_called_once_with(
mock.ANY, final_path, os_ironic_api_version=None,
global_request_id=None)
@mock.patch.object(driver.DriverManager, 'delete', autospec=True)
def test_vendor_passthru_delete(self, delete_mock):
@ -206,7 +210,9 @@ class DriverManagerTest(testtools.TestCase):
final_path = 'driver_name/vendor_passthru/method'
self.mgr.vendor_passthru(**kwargs)
delete_mock.assert_called_once_with(mock.ANY, final_path)
delete_mock.assert_called_once_with(
mock.ANY, final_path, os_ironic_api_version=None,
global_request_id=None)
@mock.patch.object(driver.DriverManager, 'delete', autospec=True)
def test_vendor_passthru_unknown_http_method(self, delete_mock):

View File

@ -34,7 +34,7 @@ class AllocationManager(base.CreateManager):
def list(self, resource_class=None, state=None, node=None, limit=None,
marker=None, sort_key=None, sort_dir=None, fields=None,
owner=None):
owner=None, os_ironic_api_version=None, global_request_id=None):
"""Retrieve a list of allocations.
:param resource_class: Optional, get allocations with this resource
@ -63,6 +63,12 @@ class AllocationManager(base.CreateManager):
of the resource to be returned.
:param owner: Optional, project that owns the allocation.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:returns: A list of allocations.
:raises: InvalidAttribute if a subset of fields is requested with
detail option set.
@ -83,35 +89,51 @@ class AllocationManager(base.CreateManager):
path = '?' + '&'.join(filters)
else:
path = ''
header_values = {"os_ironic_api_version": os_ironic_api_version,
"global_request_id": global_request_id}
if limit is None:
return self._list(self._path(path), "allocations")
return self._list(self._path(path), "allocations", **header_values)
else:
return self._list_pagination(self._path(path), "allocations",
limit=limit)
limit=limit, **header_values)
def get(self, allocation_id, fields=None):
def get(self, allocation_id, fields=None, os_ironic_api_version=None,
global_request_id=None):
"""Get an allocation with the specified identifier.
:param allocation_id: The UUID or name of an allocation.
:param fields: Optional, a list with a specified set of fields
of the resource to be returned. Can not be used
when 'detail' is set.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:returns: an :class:`Allocation` object.
"""
return self._get(resource_id=allocation_id, fields=fields)
return self._get(resource_id=allocation_id, fields=fields,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def delete(self, allocation_id):
def delete(self, allocation_id, os_ironic_api_version=None,
global_request_id=None):
"""Delete the Allocation.
:param allocation_id: The UUID or name of an allocation.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
"""
return self._delete(resource_id=allocation_id)
return self._delete(resource_id=allocation_id,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def wait(self, allocation_id, timeout=0, poll_interval=1,
poll_delay_function=None):
poll_delay_function=None, os_ironic_api_version=None,
global_request_id=None):
"""Wait for the Allocation to become active.
:param timeout: timeout in seconds, no timeout if 0.
@ -119,6 +141,10 @@ class AllocationManager(base.CreateManager):
:param poll_delay_function: function to use to wait between polls
(defaults to time.sleep). Should take one argument - delay time
in seconds. Any exceptions raised inside it will abort the wait.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:return: updated :class:`Allocation` object.
:raises: StateTransitionFailed if allocation reaches the error state.
:raises: StateTransitionTimeout on timeout.
@ -129,7 +155,9 @@ class AllocationManager(base.CreateManager):
'timeout': timeout}
for _count in utils.poll(timeout, poll_interval, poll_delay_function,
timeout_msg):
allocation = self.get(allocation_id)
allocation = self.get(allocation_id,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
if allocation.state == 'error':
raise exc.StateTransitionFailed(
_('Allocation %(allocation)s failed: %(error)s') %
@ -143,10 +171,17 @@ class AllocationManager(base.CreateManager):
{'allocation': allocation_id,
'actual': allocation.state})
def update(self, allocation_id, patch):
def update(self, allocation_id, patch, os_ironic_api_version=None,
global_request_id=None):
"""Updates the Allocation. Only 'name' and 'extra' field are allowed.
:param allocation_id: The UUID or name of an allocation.
:param patch: a json PATCH document to apply to this allocation.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
"""
return self._update(resource_id=allocation_id, patch=patch)
return self._update(resource_id=allocation_id, patch=patch,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)

View File

@ -31,7 +31,8 @@ class ChassisManager(base.CreateManager):
_creation_attributes = ['description', 'extra', 'uuid']
def list(self, marker=None, limit=None, sort_key=None,
sort_dir=None, detail=False, fields=None):
sort_dir=None, detail=False, fields=None,
os_ironic_api_version=None, global_request_id=None):
"""Retrieve a list of chassis.
:param marker: Optional, the UUID of a chassis, eg the last
@ -58,6 +59,12 @@ class ChassisManager(base.CreateManager):
of the resource to be returned. Can not be used
when 'detail' is set.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:returns: A list of chassis.
"""
@ -76,16 +83,18 @@ class ChassisManager(base.CreateManager):
path += 'detail'
if filters:
path += '?' + '&'.join(filters)
header_values = {"os_ironic_api_version": os_ironic_api_version,
"global_request_id": global_request_id}
if limit is None:
return self._list(self._path(path), "chassis")
return self._list(self._path(path), "chassis", **header_values)
else:
return self._list_pagination(self._path(path), "chassis",
limit=limit)
limit=limit, **header_values)
def list_nodes(self, chassis_id, marker=None, limit=None,
sort_key=None, sort_dir=None, detail=False, fields=None,
associated=None, maintenance=None, provision_state=None):
associated=None, maintenance=None, provision_state=None,
os_ironic_api_version=None, global_request_id=None):
"""List all the nodes for a given chassis.
:param chassis_id: The UUID of the chassis.
@ -127,6 +136,12 @@ class ChassisManager(base.CreateManager):
:param provision_state: Optional. String value to get only nodes in
that provision state.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:returns: A list of nodes.
"""
@ -153,18 +168,28 @@ class ChassisManager(base.CreateManager):
if filters:
path += '?' + '&'.join(filters)
header_values = {"os_ironic_api_version": os_ironic_api_version,
"global_request_id": global_request_id}
if limit is None:
return self._list(self._path(path), "nodes")
return self._list(self._path(path), "nodes", **header_values)
else:
return self._list_pagination(self._path(path), "nodes",
limit=limit)
limit=limit, **header_values)
def get(self, chassis_id, fields=None):
return self._get(resource_id=chassis_id, fields=fields)
def get(self, chassis_id, fields=None, os_ironic_api_version=None,
global_request_id=None):
return self._get(resource_id=chassis_id, fields=fields,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def delete(self, chassis_id):
return self._delete(resource_id=chassis_id)
def delete(self, chassis_id, os_ironic_api_version=None,
global_request_id=None):
return self._delete(resource_id=chassis_id,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def update(self, chassis_id, patch):
return self._update(resource_id=chassis_id, patch=patch)
def update(self, chassis_id, patch, os_ironic_api_version=None,
global_request_id=None):
return self._update(resource_id=chassis_id, patch=patch,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)

View File

@ -26,7 +26,8 @@ class ConductorManager(base.Manager):
_resource_name = 'conductors'
def list(self, marker=None, limit=None, sort_key=None, sort_dir=None,
fields=None, detail=False):
fields=None, detail=False, os_ironic_api_version=None,
global_request_id=None):
"""Retrieve a list of conductors.
:param marker: Optional, the hostname of a conductor, eg the last
@ -53,6 +54,12 @@ class ConductorManager(base.Manager):
:param detail: Optional, boolean whether to return detailed information
about conductors.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:returns: A list of conductors.
"""
@ -68,12 +75,16 @@ class ConductorManager(base.Manager):
path = ''
if filters:
path += '?' + '&'.join(filters)
header_values = {"os_ironic_api_version": os_ironic_api_version,
"global_request_id": global_request_id}
if limit is None:
return self._list(self._path(path), "conductors")
return self._list(self._path(path), "conductors", **header_values)
else:
return self._list_pagination(self._path(path), "conductors",
limit=limit)
limit=limit, **header_values)
def get(self, hostname, fields=None):
return self._get(resource_id=hostname, fields=fields)
def get(self, hostname, fields=None, os_ironic_api_version=None,
global_request_id=None):
return self._get(resource_id=hostname, fields=fields,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)

View File

@ -27,7 +27,8 @@ class DeployTemplateManager(base.CreateManager):
_resource_name = 'deploy_templates'
def list(self, limit=None, marker=None, sort_key=None, sort_dir=None,
detail=False, fields=None):
detail=False, fields=None, os_ironic_api_version=None,
global_request_id=None):
"""Retrieve a list of deploy templates.
:param marker: Optional, the UUID of a deploy template, eg the last
@ -54,6 +55,12 @@ class DeployTemplateManager(base.CreateManager):
of the resource to be returned. Can not be used
when 'detail' is set.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:returns: A list of deploy templates.
"""
@ -69,18 +76,29 @@ class DeployTemplateManager(base.CreateManager):
path = ''
if filters:
path += '?' + '&'.join(filters)
header_values = {"os_ironic_api_version": os_ironic_api_version,
"global_request_id": global_request_id}
if limit is None:
return self._list(self._path(path), "deploy_templates")
return self._list(self._path(path), "deploy_templates",
**header_values)
else:
return self._list_pagination(self._path(path), "deploy_templates",
limit=limit)
limit=limit, **header_values)
def get(self, template_id, fields=None):
return self._get(resource_id=template_id, fields=fields)
def get(self, template_id, fields=None, os_ironic_api_version=None,
global_request_id=None):
return self._get(resource_id=template_id, fields=fields,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def delete(self, template_id):
return self._delete(resource_id=template_id)
def delete(self, template_id, os_ironic_api_version=None,
global_request_id=None):
return self._delete(resource_id=template_id,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def update(self, template_id, patch):
return self._update(resource_id=template_id, patch=patch)
def update(self, template_id, patch, os_ironic_api_version=None,
global_request_id=None):
return self._update(resource_id=template_id, patch=patch,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)

View File

@ -27,7 +27,8 @@ class DriverManager(base.Manager):
resource_class = Driver
_resource_name = 'drivers'
def list(self, driver_type=None, detail=None):
def list(self, driver_type=None, detail=None, os_ironic_api_version=None,
global_request_id=None):
"""Retrieve a list of drivers.
:param driver_type: Optional, string to filter the drivers by type.
@ -36,6 +37,10 @@ class DriverManager(base.Manager):
about drivers. Default is None means not to send the arg
to the server due to older versions of the server cannot
handle filtering on detail.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:returns: A list of drivers.
"""
filters = []
@ -47,26 +52,45 @@ class DriverManager(base.Manager):
path = ''
if filters:
path = '?' + '&'.join(filters)
return self._list(self._path(path), self._resource_name,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
return self._list(self._path(path), self._resource_name)
def get(self, driver_name, os_ironic_api_version=None,
global_request_id=None):
return self._get(resource_id=driver_name,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def get(self, driver_name):
return self._get(resource_id=driver_name)
def update(self, driver_name, patch, http_method='PATCH'):
def update(self, driver_name, patch, http_method='PATCH',
os_ironic_api_version=None, global_request_id=None):
return self._update(resource_id=driver_name, patch=patch,
method=http_method)
method=http_method,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def delete(self, driver_name):
return self._delete(resource_id=driver_name)
def delete(self, driver_name, os_ironic_api_version=None,
global_request_id=None):
return self._delete(resource_id=driver_name,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def properties(self, driver_name):
return self._get_as_dict('%s/properties' % driver_name)
def properties(self, driver_name, os_ironic_api_version=None,
global_request_id=None):
return self._get_as_dict('%s/properties' % driver_name,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)
def raid_logical_disk_properties(self, driver_name):
def raid_logical_disk_properties(self, driver_name,
os_ironic_api_version=None,
global_request_id=None):
"""Returns the RAID logical disk properties for the driver.
:param driver_name: Name of the driver.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
:returns: A dictionary containing the properties that can be mentioned
for RAID logical disks and a textual description for them. It
returns an empty dictionary on error.
@ -74,7 +98,9 @@ class DriverManager(base.Manager):
info = None
try:
info = self._list(
'/v1/drivers/%s/raid/logical_disk_properties' % driver_name)[0]
'/v1/drivers/%s/raid/logical_disk_properties' % driver_name,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)[0]
except IndexError:
pass
@ -83,7 +109,8 @@ class DriverManager(base.Manager):
return {}
def vendor_passthru(self, driver_name, method, args=None,
http_method=None):
http_method=None, os_ironic_api_version=None,
global_request_id=None):
"""Issue requests for vendor-specific actions on a given driver.
:param driver_name: The name of the driver.
@ -91,6 +118,10 @@ class DriverManager(base.Manager):
:param args: Optional. The arguments to be passed to the method.
:param http_method: The HTTP method to use on the request.
Defaults to POST.
:param os_ironic_api_version: String version (e.g. "1.35") to use for
the request. If not specified, the client's default is used.
:param global_request_id: String containing global request ID header
value (in form "req-<UUID>") to use for the request.
"""
if args is None:
args = {}
@ -100,16 +131,24 @@ class DriverManager(base.Manager):
http_method = http_method.upper()
header_values = {"os_ironic_api_version": os_ironic_api_version,
"global_request_id": global_request_id}
path = "%s/vendor_passthru/%s" % (driver_name, method)
if http_method in ('POST', 'PUT', 'PATCH'):
return self.update(path, args, http_method=http_method)
return self.update(path, args, http_method=http_method,
**header_values)
elif http_method == 'DELETE':
return self.delete(path)
return self.delete(path, **header_values)
elif http_method == 'GET':
return self.get(path)
return self.get(path, **header_values)
else:
raise exc.InvalidAttribute(
_('Unknown HTTP method: %s') % http_method)
def get_vendor_passthru_methods(self, driver_name):
return self._get_as_dict("%s/vendor_passthru/methods" % driver_name)
def get_vendor_passthru_methods(self, driver_name,
os_ironic_api_version=None,
global_request_id=None):
return self._get_as_dict("%s/vendor_passthru/methods" % driver_name,
os_ironic_api_version=os_ironic_api_version,
global_request_id=global_request_id)