From 986e90248b462b1e8c8e2033caee68ebd50e0bf8 Mon Sep 17 00:00:00 2001 From: Akihiro Motoki Date: Mon, 15 Jan 2018 06:09:09 +0900 Subject: [PATCH] Exclude nova-network quotas properly openstack_dashboard.api.nova.QuotaSet was introduced to exclude nova-network properly, but it did not work because QuotaSet does not support 'in' and 'del' operations. This commit fixes the logic and add a unit test. Closes-Bug: #1743589 Change-Id: I8c3bfe985cccdf53fd555bf185c293806c14b6f6 --- openstack_dashboard/api/base.py | 4 ++- openstack_dashboard/api/nova.py | 6 ---- .../test/unit/api/test_nova.py | 36 +++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/openstack_dashboard/api/base.py b/openstack_dashboard/api/base.py index 3cae884a3e..c8d2ebdc2d 100644 --- a/openstack_dashboard/api/base.py +++ b/openstack_dashboard/api/base.py @@ -208,6 +208,8 @@ class QuotaSet(Sequence): use the `get` method to retrieve a specific quota, but otherwise it behaves much like a list or tuple, particularly in supporting iteration. """ + ignore_quotas = {} + def __init__(self, apiresource=None): self.items = [] if apiresource: @@ -217,7 +219,7 @@ class QuotaSet(Sequence): items = apiresource.items() for k, v in items: - if k == 'id': + if k == 'id' or k in self.ignore_quotas: continue self[k] = v diff --git a/openstack_dashboard/api/nova.py b/openstack_dashboard/api/nova.py index 8c699ff938..e8f32f5adb 100644 --- a/openstack_dashboard/api/nova.py +++ b/openstack_dashboard/api/nova.py @@ -246,12 +246,6 @@ class QuotaSet(base.QuotaSet): "security_group_rules", } - def __init__(self, apiresource=None): - super(QuotaSet, self).__init__(apiresource) - for name in self.ignore_quotas: - if name in self.items: - del self.items[name] - def get_auth_params_from_request(request): """Extracts properties needed by novaclient call from the request object. diff --git a/openstack_dashboard/test/unit/api/test_nova.py b/openstack_dashboard/test/unit/api/test_nova.py index 0141520916..e6dcbc9fa1 100644 --- a/openstack_dashboard/test/unit/api/test_nova.py +++ b/openstack_dashboard/test/unit/api/test_nova.py @@ -26,6 +26,7 @@ import mock from novaclient import api_versions from novaclient import exceptions as nova_exceptions from novaclient.v2 import flavor_access as nova_flavor_access +from novaclient.v2 import quotas from novaclient.v2 import servers from horizon import exceptions as horizon_exceptions @@ -715,3 +716,38 @@ class ComputeApiTests(test.APIMockTestCase): self.assertEqual(ret_val.id, servergroup.id) novaclient.versions.get_current.assert_called_once_with() novaclient.server_groups.get.assert_called_once_with(servergroup.id) + + @mock.patch.object(api.nova, 'novaclient') + def test_tenant_quota_get(self, mock_novaclient): + tenant_id = '10' + quota_data = { + 'cores': 20, + 'injected_file_content_bytes': 10240, + 'injected_file_path_bytes': 255, + 'injected_files': 5, + 'instances': 10, + 'key_pairs': 100, + 'metadata_items': 128, + 'ram': 51200, + 'server_group_members': 10, + 'server_groups': 10, + 'fixed_ips': -1, + 'floating_ips': 10, + 'security_groups': 10, + 'security_group_rules': 20, + } + nova_qs = quotas.QuotaSet(quotas.QuotaSetManager(None), quota_data) + + novaclient = mock_novaclient.return_value + novaclient.quotas.get.return_value = nova_qs + + ret_val = api.nova.tenant_quota_get(self.request, tenant_id) + ret_keys = [q.name for q in ret_val] + ignore_keys = {'fixed_ips', 'floating_ips', + 'security_groups', 'security_group_rules'} + expected_keys = set(quota_data.keys()) - ignore_keys + # Check ignore_keys are not included + self.assertEqual(expected_keys, set(ret_keys)) + for key in expected_keys: + self.assertEqual(quota_data[key], ret_val.get(key).limit) + novaclient.quotas.get.assert_called_once_with(tenant_id)