diff --git a/api-ref/source/v1/hosts.inc b/api-ref/source/v1/hosts.inc index eac05b3c..26c3e196 100644 --- a/api-ref/source/v1/hosts.inc +++ b/api-ref/source/v1/hosts.inc @@ -268,6 +268,7 @@ Request .. rest_parameters:: parameters.yaml - lease_id: allocation_lease_id_query + - reservation_id: allocation_reservation_id_query Response -------- @@ -306,6 +307,7 @@ Request - host_id: host_id_path - lease_id: allocation_lease_id_query + - reservation_id: allocation_reservation_id_query Response -------- diff --git a/api-ref/source/v1/parameters.yaml b/api-ref/source/v1/parameters.yaml index 99b3dbbf..a335c222 100644 --- a/api-ref/source/v1/parameters.yaml +++ b/api-ref/source/v1/parameters.yaml @@ -20,6 +20,12 @@ allocation_lease_id_query: in: query required: false type: string +allocation_reservation_id_query: + description: | + Filter allocations results by reservation id + in: query + required: false + type: string # variables in body diff --git a/blazar/db/sqlalchemy/utils.py b/blazar/db/sqlalchemy/utils.py index 715e8d0d..ec0f0e3a 100644 --- a/blazar/db/sqlalchemy/utils.py +++ b/blazar/db/sqlalchemy/utils.py @@ -89,7 +89,8 @@ def get_reservations_by_host_ids(host_ids, start_date, end_date): def get_reservation_allocations_by_host_ids(host_ids, start_date, end_date, - lease_id=None): + lease_id=None, + reservation_id=None): session = get_session() border0 = models.Lease.end_date < start_date border1 = models.Lease.start_date > end_date @@ -100,6 +101,8 @@ def get_reservation_allocations_by_host_ids(host_ids, start_date, end_date, .filter(~sa.or_(border0, border1))) if lease_id: query = query.filter(models.Reservation.lease_id == lease_id) + if reservation_id: + query = query.filter(models.Reservation.id == reservation_id) return query.all() diff --git a/blazar/db/utils.py b/blazar/db/utils.py index 1ede7d03..61c77a87 100644 --- a/blazar/db/utils.py +++ b/blazar/db/utils.py @@ -112,9 +112,12 @@ def get_reservations_by_host_ids(host_ids, start_date, end_date): def get_reservation_allocations_by_host_ids(host_ids, start_date, end_date, - lease_id=None): - return IMPL.get_reservation_allocations_by_host_ids(host_ids, start_date, - end_date, lease_id) + lease_id=None, + reservation_id=None): + return IMPL.get_reservation_allocations_by_host_ids(host_ids, + start_date, end_date, + lease_id, + reservation_id) def get_plugin_reservation(resource_type, resource_id): diff --git a/blazar/plugins/oshosts/host_plugin.py b/blazar/plugins/oshosts/host_plugin.py index 448fe112..a66e1724 100644 --- a/blazar/plugins/oshosts/host_plugin.py +++ b/blazar/plugins/oshosts/host_plugin.py @@ -83,7 +83,7 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper): freepool_name = CONF.nova.aggregate_freepool_name pool = None query_options = { - QUERY_TYPE_ALLOCATION: ['lease_id'] + QUERY_TYPE_ALLOCATION: ['lease_id', 'reservation_id'] } def __init__(self): @@ -521,7 +521,8 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper): allocs = host_allocations[host_id] return {"resource_id": host_id, "reservations": allocs} - def query_host_allocations(self, hosts, lease_id=None): + def query_host_allocations(self, hosts, lease_id=None, + reservation_id=None): """Return dict of host and its allocations. The list element forms @@ -540,7 +541,7 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper): # To reduce overhead, this method only executes one query # to get the allocation information allocs = db_utils.get_reservation_allocations_by_host_ids( - hosts, start, end, lease_id) + hosts, start, end, lease_id, reservation_id) hosts_allocs = {} for reservation, alloc in allocs: diff --git a/blazar/tests/db/sqlalchemy/test_utils.py b/blazar/tests/db/sqlalchemy/test_utils.py index 4e58af89..983216fa 100644 --- a/blazar/tests/db/sqlalchemy/test_utils.py +++ b/blazar/tests/db/sqlalchemy/test_utils.py @@ -455,6 +455,26 @@ class SQLAlchemyDBUtilsTestCase(tests.DBTestCase): self.assertListEqual(expected, [(r['id'], a['id']) for r, a in ret]) + def test_get_reservation_allocations_by_host_ids_with_reservation_id(self): + def create_allocation_tuple(lease_id): + reservation = db_api.reservation_get_all_by_lease_id(lease_id)[0] + allocation = db_api.host_allocation_get_all_by_values( + reservation_id=reservation['id'])[0] + return (reservation['id'], allocation['id']) + + self._setup_leases() + reservation1 = db_api.reservation_get_all_by_lease_id('lease1')[0] + + # query allocations of lease1 + expected = [ + create_allocation_tuple('lease1'), + ] + ret = db_utils.get_reservation_allocations_by_host_ids( + ['r1', 'r2'], '2030-01-01 08:00', '2030-01-01 15:00', + reservation_id=reservation1['id']) + + self.assertListEqual(expected, [(r['id'], a['id']) for r, a in ret]) + def test_get_plugin_reservation_with_host(self): patch_host_reservation_get = self.patch(db_api, 'host_reservation_get') patch_host_reservation_get.return_value = { diff --git a/blazar/tests/plugins/oshosts/test_physical_host_plugin.py b/blazar/tests/plugins/oshosts/test_physical_host_plugin.py index 5cd84726..349d7b20 100644 --- a/blazar/tests/plugins/oshosts/test_physical_host_plugin.py +++ b/blazar/tests/plugins/oshosts/test_physical_host_plugin.py @@ -521,6 +521,43 @@ class PhysicalHostPluginTestCase(tests.TestCase): self.assertListEqual(expected, ret) + def test_list_allocations_with_reservation_id(self): + def reservation_allocation_tuple(r_id, l_id, h_id): + return ({'id': r_id, 'lease_id': l_id}, {'compute_host_id': h_id}) + + self.db_get_reserv_allocs = self.patch( + self.db_utils, 'get_reservation_allocations_by_host_ids') + + # Expecting a list of (Reservation, Allocation) + self.db_get_reserv_allocs.return_value = [ + reservation_allocation_tuple('reservation-1', 'lease-1', 'host-1'), + reservation_allocation_tuple('reservation-1', 'lease-1', 'host-2'), + ] + + expected = [ + { + 'resource_id': 'host-1', + 'reservations': [ + {'id': 'reservation-1', 'lease_id': 'lease-1'}, + ] + }, + { + 'resource_id': 'host-2', + 'reservations': [ + {'id': 'reservation-1', 'lease_id': 'lease-1'}, + ] + }, + ] + ret = self.fake_phys_plugin.list_allocations( + {'reservation_id': 'reservation-1'}) + + # Sort returned value to use assertListEqual + for r in ret: + r['reservations'].sort(key=lambda x: x['id']) + ret.sort(key=lambda x: x['resource_id']) + + self.assertListEqual(expected, ret) + def test_get_allocations(self): def reservation_allocation_tuple(r_id, l_id, h_id): return ({'id': r_id, 'lease_id': l_id}, {'compute_host_id': h_id}) @@ -577,6 +614,32 @@ class PhysicalHostPluginTestCase(tests.TestCase): self.assertDictEqual(expected, ret) + def test_get_allocations_with_reservation_id(self): + def reservation_allocation_tuple(r_id, l_id, h_id): + return ({'id': r_id, 'lease_id': l_id}, {'compute_host_id': h_id}) + + self.db_get_reserv_allocs = self.patch( + self.db_utils, 'get_reservation_allocations_by_host_ids') + + # Expecting a list of (Reservation, Allocation) + self.db_get_reserv_allocs.return_value = [ + reservation_allocation_tuple('reservation-1', 'lease-1', 'host-1'), + ] + + expected = { + 'resource_id': 'host-1', + 'reservations': [ + {'id': 'reservation-1', 'lease_id': 'lease-1'}, + ] + } + ret = self.fake_phys_plugin.get_allocations( + 'host-1', {'reservation_id': 'reservation-1'}) + + # sort returned value to use assertListEqual + ret['reservations'].sort(key=lambda x: x['id']) + + self.assertDictEqual(expected, ret) + def test_get_allocations_with_invalid_host(self): def reservation_allocation_tuple(r_id, l_id, h_id): return ({'id': r_id, 'lease_id': l_id}, {'compute_host_id': h_id})