Support adding to existing reservation inventory

update_reservation_inventory() in placement client just overwrote
the reservation inventory with the given total number. This is
inconvenient for example reallocation cases where we don't know
how much inventory we already have.

This patch tweaks it to consider the existing inventory and add on
rather than overwrite it.

Change-Id: I962808283e37e3235cd17d74407aa1d39d1e0fc6
Blueprint: placement-api
This commit is contained in:
Tetsuro Nakamura 2019-01-23 08:56:40 +00:00 committed by Pierre Riteau
parent b7e72674ad
commit 81f3ba9bb3
2 changed files with 100 additions and 16 deletions

View File

@ -425,6 +425,81 @@ class TestPlacementClient(tests.TestCase):
json=expected_data)
self.assertEqual(mock_put_json, result)
@mock.patch('blazar.utils.openstack.placement.'
'BlazarPlacementClient.get_resource_provider')
@mock.patch('blazar.utils.openstack.placement.'
'BlazarPlacementClient.get')
@mock.patch('keystoneauth1.session.Session.request')
def test_add_reservation_inventory(self, kss_req, client_get, get_rp):
host_uuid = uuidutils.generate_uuid()
host_name = "compute-1"
rp_uuid = uuidutils.generate_uuid()
rp_name = "blazar_compute-1"
# Build the mock of current resource provider
mock_get_rp_json = {'uuid': rp_uuid,
'name': rp_name,
'generation': 0,
'parent_provider_uuid': host_uuid}
get_rp.return_value = mock_get_rp_json
# Build the mock of "current" inventory for get_inventory()
curr_gen = 11
mock_get_inv_json = {
'inventories': {
'CUSTOM_RESERVATION_CURR': {
"allocation_ratio": 1.0,
"max_unit": 1,
"min_unit": 1,
"reserved": 0,
"step_size": 1,
"total": 1
},
},
"resource_provider_generation": curr_gen
}
client_get.return_value = fake_requests.FakeResponse(
200, content=jsonutils.dumps(mock_get_inv_json))
# Build the mock of "updated" inventory for update_inventory()
update_gen = 12
mock_put_json = {
'inventories': {
'CUSTOM_RESERVATION_CURR': {
"allocation_ratio": 1.0,
"max_unit": 1,
"min_unit": 1,
"reserved": 0,
"step_size": 1,
"total": 3
},
},
"resource_provider_generation": update_gen
}
kss_req.return_value = fake_requests.FakeResponse(
200, content=jsonutils.dumps(mock_put_json))
result = self.client.update_reservation_inventory(
host_name, 'curr', 2, additional=True)
expected_data = {
'inventories': {
'CUSTOM_RESERVATION_CURR': {
"allocation_ratio": 1.0,
"max_unit": 1,
"min_unit": 1,
"reserved": 0,
"step_size": 1,
"total": 3
}
},
"resource_provider_generation": curr_gen
}
expected_url = '/resource_providers/%s/inventories' % rp_uuid
self._assert_keystone_called_once(kss_req, expected_url, 'PUT',
json=expected_data)
self.assertEqual(mock_put_json, result)
@mock.patch('blazar.utils.openstack.placement.'
'BlazarPlacementClient.get_resource_provider')
@mock.patch('blazar.utils.openstack.placement.'

View File

@ -283,18 +283,35 @@ class BlazarPlacementClient(object):
return resp.json()
raise exceptions.ResourceProviderNotFound(resource_provider=rp_uuid)
def update_inventory(self, rp_uuid, inv_data):
def update_inventory(self, rp_uuid, rc_name, num, additional):
"""Update the inventory for the resource provider.
:param rp_uuid: The resource provider UUID for the operation
:param inv_data: The new inventory for the resource provider
:param rc_name: The resource class name of the inventory to update
:param num: The total inventory to add/update
:param additional: Add the given number amounts to the existing if
True, else just overwrite the total value
:raises: ResourceProviderNotFound or InventoryUpdateFailed error.
"""
curr = self.get_inventory(rp_uuid)
inventories = curr['inventories']
generation = curr['resource_provider_generation']
inventories.update(inv_data)
if additional and rc_name in inventories:
inventories[rc_name]["total"] += num
else:
inv_data = {
rc_name: {
"allocation_ratio": 1.0,
"max_unit": 1,
"min_unit": 1,
"reserved": 0,
"step_size": 1,
"total": num
},
}
inventories.update(inv_data)
payload = {
'inventories': inventories,
@ -324,7 +341,8 @@ class BlazarPlacementClient(object):
raise exceptions.InventoryUpdateFailed(resource_provider=rp_uuid)
def update_reservation_inventory(self, host_name, reserv_uuid, num):
def update_reservation_inventory(self, host_name, reserv_uuid, num,
additional=False):
"""Update the reservation inventory for the reservation provider.
:param host_name: The name of the target host
@ -341,20 +359,11 @@ class BlazarPlacementClient(object):
rp = self.create_reservation_provider(host_name)
rp_uuid = rp['uuid']
# Build inventory data
# Get resource class name
reserv_uuid = reserv_uuid.upper().replace("-", "_")
rc_name = 'CUSTOM_RESERVATION_' + reserv_uuid
inv_data = {
rc_name: {
"allocation_ratio": 1.0,
"max_unit": 1,
"min_unit": 1,
"reserved": 0,
"step_size": 1,
"total": num
},
}
return self.update_inventory(rp_uuid, inv_data)
return self.update_inventory(rp_uuid, rc_name, num, additional)
def delete_reservation_inventory(self, host_name, reserv_uuid):
"""Delete the reservation inventory for the reservation provider.