From 0ce6c7f6c02dd196057f3c2e750758cd04b9978e Mon Sep 17 00:00:00 2001 From: asmita singh Date: Thu, 28 Mar 2019 06:18:39 +0000 Subject: [PATCH] Lease creation/updation should fail for invalid affinity If user passes invalid affinity values (abc, 2), the lease is getting created/updated successfully. This patch will return 400 error if user passes invalid affinity values to lease create and update APIs. APIImpact: 1)Return 400 instead of 201 when lease is created with invalid affinity for resource_type 'virtual:instance'. 2)Return 400 instead of 200 when lease is updated with invalid affinity for resource_type 'virtual:instance'. Change-Id: I3170a0957de43fd2b7bcd32eca375da2d1f17360 Closes-Bug: #1821576 --- api-ref/source/v1/parameters.yaml | 8 ++++---- blazar/plugins/instances/instance_plugin.py | 8 ++++++++ .../plugins/instances/test_instance_plugin.py | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/api-ref/source/v1/parameters.yaml b/api-ref/source/v1/parameters.yaml index b0bfcddd..490a1dad 100644 --- a/api-ref/source/v1/parameters.yaml +++ b/api-ref/source/v1/parameters.yaml @@ -377,16 +377,16 @@ reservation: type: object reservation_affinity: description: | - The affinity of instances to reserve. + The affinity of instances to reserve. The value should be ``True``, ``False`` or ``None``. in: body required: true - type: boolean + type: trilean reservation_affinity_optional: description: | - The affinity of instances to reserve. + The affinity of instances to reserve. The value should be ``True``, ``False`` or ``None``. in: body required: false - type: boolean + type: trilean reservation_aggregate_id: description: | The aggregate ID of the reservation. diff --git a/blazar/plugins/instances/instance_plugin.py b/blazar/plugins/instances/instance_plugin.py index 82985e82..1d67a204 100644 --- a/blazar/plugins/instances/instance_plugin.py +++ b/blazar/plugins/instances/instance_plugin.py @@ -43,6 +43,8 @@ RESERVATION_PREFIX = 'reservation' FLAVOR_EXTRA_SPEC = "aggregate_instance_extra_specs:" + RESERVATION_PREFIX INSTANCE_DELETION_TIMEOUT = 10 * 60 * 1000 # 10 minutes +NONE_VALUES = ('None', 'none', None) + class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper): """Plugin for virtual instance resources.""" @@ -399,6 +401,12 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper): except ValueError as e: raise mgr_exceptions.MalformedParameter(six.text_type(e)) + if 'affinity' in values: + if (values['affinity'] not in NONE_VALUES and + not strutils.is_valid_boolstr(values['affinity'])): + raise mgr_exceptions.MalformedParameter( + param='affinity (must be a bool value or None)') + def reserve_resource(self, reservation_id, values): self._check_missing_reservation_params(values) self._validate_reservation_params(values) diff --git a/blazar/tests/plugins/instances/test_instance_plugin.py b/blazar/tests/plugins/instances/test_instance_plugin.py index 7e717627..eb2472e7 100644 --- a/blazar/tests/plugins/instances/test_instance_plugin.py +++ b/blazar/tests/plugins/instances/test_instance_plugin.py @@ -142,6 +142,17 @@ class TestVirtualInstancePlugin(tests.TestCase): 'server_group_id': 2, 'aggregate_id': 3}) + @ddt.data("abc", 2, "2") + def test_affinity_error(self, value): + plugin = instance_plugin.VirtualInstancePlugin() + inputs = self.get_input_values(2, 4018, 10, 1, value, + '2030-01-01 08:00', '2030-01-01 08:00', + 'lease-1', '') + self.assertRaises(mgr_exceptions.MalformedParameter, + plugin.reserve_resource, 'reservation_id', inputs) + self.assertRaises(mgr_exceptions.MalformedParameter, + plugin.update_reservation, 'reservation_id', inputs) + @ddt.data(-1, 0, '0', 'one') def test_error_with_amount(self, value): plugin = instance_plugin.VirtualInstancePlugin() @@ -400,7 +411,8 @@ class TestVirtualInstancePlugin(tests.TestCase): expected_query = ['vcpus >= 2', 'memory_mb >= 2048', 'local_gb >= 100'] mock_host_get_query.assert_called_once_with(expected_query) - def test_pickup_host_with_no_affinity(self): + @ddt.data('None', 'none', None) + def test_pickup_host_with_no_affinity(self, value): def fake_get_reservation_by_host(host_id, start, end): return [] @@ -435,7 +447,7 @@ class TestVirtualInstancePlugin(tests.TestCase): 'memory_mb': 4096, 'disk_gb': 200, 'amount': 2, - 'affinity': None, + 'affinity': value, 'resource_properties': '', 'start_date': datetime.datetime(2030, 1, 1, 8, 00), 'end_date': datetime.datetime(2030, 1, 1, 12, 00)