From 7ccc5b28facd431705bcd90c184641d538ae659f Mon Sep 17 00:00:00 2001 From: Adrian Turjak Date: Mon, 12 Feb 2018 17:18:58 +1300 Subject: [PATCH] Smaller Quota changes ignore change history Update the quota logic to ignore change history if the current change in quota is downward. Change-Id: Iacbab882c3031db3d126a15dfb42c3cc8baa713e Fixes-Bug: 1746137 --- adjutant/actions/v1/resources.py | 22 +++++++-- adjutant/api/v1/tests/test_api_openstack.py | 54 +++++++++++++++++++-- adjutant/common/quota.py | 10 ++++ 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/adjutant/actions/v1/resources.py b/adjutant/actions/v1/resources.py index 0361613..bc8ca7d 100644 --- a/adjutant/actions/v1/resources.py +++ b/adjutant/actions/v1/resources.py @@ -288,6 +288,7 @@ class UpdateProjectQuotasAction(BaseAction, QuotaMixin): cancelled__exact=False, project_id__exact=self.project_id) + changed_in_period = False # Check to see if there have been any updates in the relavent regions # recently for task in task_list: @@ -295,10 +296,7 @@ class UpdateProjectQuotasAction(BaseAction, QuotaMixin): intersect = set(action.action_data[ 'regions']).intersection(self.regions) if intersect: - self.add_note( - "Quota has already been updated within the auto " - "approve time limit.") - return False + changed_in_period = True region_sizes = [] @@ -315,17 +313,33 @@ class UpdateProjectQuotasAction(BaseAction, QuotaMixin): # Check for preapproved_quotas preapproved_quotas = [] + smaller_quotas = [] # If all region sizes are the same if region_sizes.count(region_sizes[0]) == len(region_sizes): preapproved_quotas = quota_manager.get_quota_change_options( region_sizes[0]) + smaller_quotas = quota_manager.get_smaller_quota_options( + region_sizes[0]) + + if self.size in smaller_quotas: + self.add_note( + "Quota size '%s' is in list of smaller quotas: %s" % + (self.size, smaller_quotas)) + return True + + if changed_in_period: + self.add_note( + "Quota has already been updated within the auto " + "approve time limit.") + return False if self.size not in preapproved_quotas: self.add_note( "Quota size '%s' not in preapproved list: %s" % (self.size, preapproved_quotas)) return False + self.add_note( "Quota size '%s' in preapproved list: %s" % (self.size, preapproved_quotas)) diff --git a/adjutant/api/v1/tests/test_api_openstack.py b/adjutant/api/v1/tests/test_api_openstack.py index e9f3e2a..d3c6074 100644 --- a/adjutant/api/v1/tests/test_api_openstack.py +++ b/adjutant/api/v1/tests/test_api_openstack.py @@ -533,7 +533,7 @@ class QuotaAPITests(APITestCase): # Then check to see the quotas have changed self.check_quota_cache('RegionOne', project.id, 'medium') - data = {'size': 'small', + data = {'size': 'large', 'regions': ['RegionOne']} response = self.client.post(url, data, headers=admin_headers, format='json') @@ -564,7 +564,51 @@ class QuotaAPITests(APITestCase): {'notes': ['Task completed successfully.']} ) - # Quotas should have changed to small + # Quotas should have changed to large + self.check_quota_cache('RegionOne', project.id, 'large') + + def test_update_quota_history_smaller(self): + """ + Update quota to a smaller quota right after a change to a larger + quota. Should auto approve to smaller quotas regardless of history. + """ + project = fake_clients.FakeProject( + name="test_project", id='test_project_id') + + user = fake_clients.FakeUser( + name="test@example.com", password="123", email="test@example.com") + + setup_identity_cache(projects=[project], users=[user]) + + admin_headers = { + 'project_name': "test_project", + 'project_id': project.id, + 'roles': "project_admin,_member_,project_mod", + 'username': "test@example.com", + 'user_id': "user_id", + 'authenticated': True + } + + url = "/v1/openstack/quotas/" + + data = {'size': 'medium', + 'regions': ['RegionOne']} + response = self.client.post(url, data, + headers=admin_headers, format='json') + # First check we can actually access the page correctly + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Then check to see the quotas have changed + self.check_quota_cache('RegionOne', project.id, 'medium') + + data = {'size': 'small', + 'regions': ['RegionOne']} + response = self.client.post(url, data, + headers=admin_headers, format='json') + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Then check to see the quotas have changed self.check_quota_cache('RegionOne', project.id, 'small') def test_update_quota_old_history(self): @@ -953,7 +997,7 @@ class QuotaAPITests(APITestCase): self.check_quota_cache('RegionTwo', project.id, 'medium') - data = {'size': 'small'} + data = {'size': 'large'} response = self.client.post(url, data, headers=headers, format='json') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) @@ -983,9 +1027,9 @@ class QuotaAPITests(APITestCase): {'notes': ['Task completed successfully.']} ) - self.check_quota_cache('RegionOne', project.id, 'small') + self.check_quota_cache('RegionOne', project.id, 'large') - self.check_quota_cache('RegionTwo', project.id, 'small') + self.check_quota_cache('RegionTwo', project.id, 'large') def test_set_multi_quota_single_history(self): """ diff --git a/adjutant/common/quota.py b/adjutant/common/quota.py index c909974..824a04c 100644 --- a/adjutant/common/quota.py +++ b/adjutant/common/quota.py @@ -214,6 +214,16 @@ class QuotaManager(object): return quota_change_list + def get_smaller_quota_options(self, quota_size): + """ Get the quota sizes smaller than the current size.""" + quota_list = settings.QUOTA_SIZES_ASC + try: + list_position = quota_list.index(quota_size) + except ValueError: + return [] + + return quota_list[:list_position] + def get_region_quota_data(self, region_id): current_quota = self.get_current_region_quota(region_id) current_quota_size = self.get_quota_size(current_quota)