From 19ea565c2fe21695e1ed586ed3cf4bf626879337 Mon Sep 17 00:00:00 2001 From: Julie Pichon Date: Thu, 3 Jul 2014 07:52:35 +0100 Subject: [PATCH] Remove use of "quota_tenant_usages" in Volumes page Replace it instead with a direct call to the Cinder limits. The generic usage quotas method performs some operations that can be costly when there is a large number of volumes. Change-Id: Ib5601d34a1854f4b190b3bc106504f384561fc30 Partial-Bug: #1334608 --- openstack_dashboard/api/cinder.py | 1 + .../project/volumes/backups/tests.py | 9 ++-- .../project/volumes/snapshots/tests.py | 10 ++-- .../dashboards/project/volumes/test.py | 11 ++-- .../project/volumes/volumes/tables.py | 12 +++-- .../project/volumes/volumes/tests.py | 51 +++++++++---------- 6 files changed, 47 insertions(+), 47 deletions(-) diff --git a/openstack_dashboard/api/cinder.py b/openstack_dashboard/api/cinder.py index bbab69f0c6..5b022ea649 100644 --- a/openstack_dashboard/api/cinder.py +++ b/openstack_dashboard/api/cinder.py @@ -353,6 +353,7 @@ def volume_type_extra_delete(request, type_id, keys): return vol_type.unset_keys([keys]) +@memoized def tenant_absolute_limits(request): limits = cinderclient(request).limits.get().absolute limits_dict = {} diff --git a/openstack_dashboard/dashboards/project/volumes/backups/tests.py b/openstack_dashboard/dashboards/project/volumes/backups/tests.py index 8b22b140d0..2fc4c61638 100644 --- a/openstack_dashboard/dashboards/project/volumes/backups/tests.py +++ b/openstack_dashboard/dashboards/project/volumes/backups/tests.py @@ -17,7 +17,6 @@ from mox import IsA # noqa from openstack_dashboard import api from openstack_dashboard.test import helpers as test -from openstack_dashboard.usage import quotas INDEX_URL = reverse('horizon:project:volumes:index') @@ -58,8 +57,8 @@ class VolumeBackupsViewTests(test.TestCase): 'volume_list', 'volume_backup_supported', 'volume_backup_list', - 'volume_backup_delete'), - quotas: ('tenant_quota_usages',)}) + 'volume_backup_delete', + 'tenant_absolute_limits')}) def test_delete_volume_backup(self): vol_backups = self.cinder_volume_backups.list() volumes = self.cinder_volumes.list() @@ -85,8 +84,8 @@ class VolumeBackupsViewTests(test.TestCase): AndReturn(vol_backups) api.cinder.volume_list(IsA(http.HttpRequest)). \ AndReturn(volumes) - quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes(). \ - AndReturn(self.quota_usages.first()) + api.cinder.tenant_absolute_limits(IsA(http.HttpRequest))\ + .MultipleTimes().AndReturn(self.cinder_limits['absolute']) self.mox.ReplayAll() formData = {'action': diff --git a/openstack_dashboard/dashboards/project/volumes/snapshots/tests.py b/openstack_dashboard/dashboards/project/volumes/snapshots/tests.py index 57fe0eb6d3..26e6d66953 100644 --- a/openstack_dashboard/dashboards/project/volumes/snapshots/tests.py +++ b/openstack_dashboard/dashboards/project/volumes/snapshots/tests.py @@ -106,12 +106,12 @@ class VolumeSnapshotsViewTests(test.TestCase): self.assertRedirectsNoFollow(res, VOLUME_SNAPSHOTS_TAB_URL) @test.create_stubs({api.nova: ('server_list',), - api.cinder: ('volume_snapshot_list', + api.cinder: ('tenant_absolute_limits', + 'volume_snapshot_list', 'volume_list', 'volume_backup_supported', 'volume_backup_list', - 'volume_snapshot_delete'), - quotas: ('tenant_quota_usages',)}) + 'volume_snapshot_delete')}) def test_delete_volume_snapshot(self): vol_snapshots = self.cinder_volume_snapshots.list() volumes = self.cinder_volumes.list() @@ -138,8 +138,8 @@ class VolumeSnapshotsViewTests(test.TestCase): AndReturn(vol_backups) api.cinder.volume_list(IsA(http.HttpRequest)). \ AndReturn(volumes) - quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes(). \ - AndReturn(self.quota_usages.first()) + api.cinder.tenant_absolute_limits(IsA(http.HttpRequest)).MultipleTimes(). \ + AndReturn(self.cinder_limits['absolute']) self.mox.ReplayAll() formData = {'action': diff --git a/openstack_dashboard/dashboards/project/volumes/test.py b/openstack_dashboard/dashboards/project/volumes/test.py index 405461c793..6cf39c0ba4 100644 --- a/openstack_dashboard/dashboards/project/volumes/test.py +++ b/openstack_dashboard/dashboards/project/volumes/test.py @@ -19,20 +19,19 @@ from mox import IsA # noqa from openstack_dashboard import api from openstack_dashboard.test import helpers as test -from openstack_dashboard.usage import quotas INDEX_URL = reverse('horizon:project:volumes:index') class VolumeAndSnapshotsTests(test.TestCase): - @test.create_stubs({api.cinder: ('volume_list', + @test.create_stubs({api.cinder: ('tenant_absolute_limits', + 'volume_list', 'volume_snapshot_list', 'volume_backup_supported', 'volume_backup_list', ), - api.nova: ('server_list',), - quotas: ('tenant_quota_usages',)}) + api.nova: ('server_list',)}) def _test_index(self, backup_supported=True): vol_backups = self.cinder_volume_backups.list() vol_snaps = self.cinder_volume_snapshots.list() @@ -51,8 +50,8 @@ class VolumeAndSnapshotsTests(test.TestCase): api.cinder.volume_backup_list(IsA(http.HttpRequest)).\ AndReturn(vol_backups) api.cinder.volume_list(IsA(http.HttpRequest)).AndReturn(volumes) - quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes(). \ - AndReturn(self.quota_usages.first()) + api.cinder.tenant_absolute_limits(IsA(http.HttpRequest)).MultipleTimes(). \ + AndReturn(self.cinder_limits['absolute']) self.mox.ReplayAll() res = self.client.get(INDEX_URL) diff --git a/openstack_dashboard/dashboards/project/volumes/volumes/tables.py b/openstack_dashboard/dashboards/project/volumes/volumes/tables.py index b582e7d6d3..5959d18385 100644 --- a/openstack_dashboard/dashboards/project/volumes/volumes/tables.py +++ b/openstack_dashboard/dashboards/project/volumes/volumes/tables.py @@ -28,7 +28,6 @@ from horizon import tables from openstack_dashboard import api from openstack_dashboard.api import cinder from openstack_dashboard import policy -from openstack_dashboard.usage import quotas DELETABLE_STATES = ("available", "error", "error_extending") @@ -97,9 +96,14 @@ class CreateVolume(tables.LinkAction): super(CreateVolume, self).__init__(attrs, **kwargs) def allowed(self, request, volume=None): - usages = quotas.tenant_quota_usages(request) - if usages['gigabytes']['available'] <= 0 or\ - usages['volumes']['available'] <= 0: + limits = api.cinder.tenant_absolute_limits(request) + + gb_available = (limits.get('maxTotalVolumeGigabytes', float("inf")) + - limits.get('totalGigabytesUsed', 0)) + volumes_available = (limits.get('maxTotalVolumes', float("inf")) + - limits.get('totalVolumesUsed', 0)) + + if gb_available <= 0 or volumes_available <= 0: if "disabled" not in self.classes: self.classes = [c for c in self.classes] + ['disabled'] self.verbose_name = string_concat(self.verbose_name, ' ', diff --git a/openstack_dashboard/dashboards/project/volumes/volumes/tests.py b/openstack_dashboard/dashboards/project/volumes/volumes/tests.py index 354ebdba1c..43c0889b2d 100644 --- a/openstack_dashboard/dashboards/project/volumes/volumes/tests.py +++ b/openstack_dashboard/dashboards/project/volumes/volumes/tests.py @@ -704,13 +704,13 @@ class VolumeViewTests(test.TestCase): ' volumes.'] self.assertEqual(res.context['form'].errors['__all__'], expected_error) - @test.create_stubs({cinder: ('volume_list', + @test.create_stubs({cinder: ('tenant_absolute_limits', + 'volume_list', 'volume_snapshot_list', 'volume_backup_supported', 'volume_backup_list', 'volume_delete',), - api.nova: ('server_list',), - quotas: ('tenant_quota_usages',)}) + api.nova: ('server_list',)}) def test_delete_volume(self): volumes = self.cinder_volumes.list() volume = self.cinder_volumes.first() @@ -735,8 +735,8 @@ class VolumeViewTests(test.TestCase): api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\ AndReturn([self.servers.list(), False]) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(volumes) - quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes().\ - AndReturn(self.quota_usages.first()) + cinder.tenant_absolute_limits(IsA(http.HttpRequest)).MultipleTimes().\ + AndReturn(self.cinder_limits['absolute']) self.mox.ReplayAll() @@ -745,13 +745,13 @@ class VolumeViewTests(test.TestCase): self.assertIn("Scheduled deletion of Volume: Volume name", [m.message for m in res.context['messages']]) - @test.create_stubs({cinder: ('volume_list', + @test.create_stubs({cinder: ('tenant_absolute_limits', + 'volume_list', 'volume_snapshot_list', 'volume_backup_supported', 'volume_backup_list', 'volume_delete',), - api.nova: ('server_list',), - quotas: ('tenant_quota_usages',)}) + api.nova: ('server_list',)}) def test_delete_volume_error_existing_snapshot(self): volume = self.cinder_volumes.first() volumes = self.cinder_volumes.list() @@ -779,9 +779,8 @@ class VolumeViewTests(test.TestCase): AndReturn(self.cinder_volume_backups.list()) cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(volumes) - quotas.tenant_quota_usages(IsA(http.HttpRequest)).MultipleTimes().\ - AndReturn(self.quota_usages.first()) - + cinder.tenant_absolute_limits(IsA(http.HttpRequest)).MultipleTimes().\ + AndReturn(self.cinder_limits['absolute']) self.mox.ReplayAll() url = VOLUME_INDEX_URL @@ -845,8 +844,7 @@ class VolumeViewTests(test.TestCase): widgets.HiddenInput)) @test.create_stubs({cinder: ('volume_get',), - api.nova: ('server_get', 'server_list',), - quotas: ('tenant_quota_usages',)}) + api.nova: ('server_list',)}) def test_edit_attachments_attached_volume(self): servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] @@ -872,15 +870,15 @@ class VolumeViewTests(test.TestCase): server.id) self.assertEqual(res.status_code, 200) - @test.create_stubs({cinder: ('volume_list', + @test.create_stubs({cinder: ('tenant_absolute_limits', + 'volume_list', 'volume_snapshot_list', 'volume_backup_supported', 'volume_backup_list',), - api.nova: ('server_list',), - quotas: ('tenant_quota_usages',)}) + api.nova: ('server_list',)}) def test_create_button_disabled_when_quota_exceeded(self): - quota_usages = self.quota_usages.first() - quota_usages['volumes']['available'] = 0 + limits = self.cinder_limits['absolute'] + limits['totalVolumesUsed'] = limits['maxTotalVolumes'] volumes = self.cinder_volumes.list() api.cinder.volume_backup_supported(IsA(http.HttpRequest)). \ @@ -895,9 +893,8 @@ class VolumeViewTests(test.TestCase): cinder.volume_backup_list(IsA(http.HttpRequest))\ .AndReturn(self.cinder_volume_backups.list()) cinder.volume_list(IsA(http.HttpRequest)).AndReturn(volumes) - quotas.tenant_quota_usages(IsA(http.HttpRequest))\ - .MultipleTimes().AndReturn(quota_usages) - + cinder.tenant_absolute_limits(IsA(http.HttpRequest))\ + .MultipleTimes().AndReturn(limits) self.mox.ReplayAll() res = self.client.get(VOLUME_INDEX_URL) @@ -1065,14 +1062,14 @@ class VolumeViewTests(test.TestCase): self._test_encryption(True) @test.create_stubs({cinder: ('volume_list', 'volume_snapshot_list', - 'volume_backup_supported'), - api.nova: ('server_list',), - quotas: ('tenant_quota_usages',)}) + 'volume_backup_supported', + 'tenant_absolute_limits'), + api.nova: ('server_list',)}) def _test_encryption(self, encryption): volumes = self.volumes.list() for volume in volumes: volume.encrypted = encryption - quota_usages = self.quota_usages.first() + limits = self.cinder_limits['absolute'] cinder.volume_backup_supported(IsA(http.HttpRequest))\ .MultipleTimes().AndReturn(False) @@ -1082,8 +1079,8 @@ class VolumeViewTests(test.TestCase): cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([]) api.nova.server_list(IsA(http.HttpRequest), search_opts=None)\ .AndReturn([self.servers.list(), False]) - quotas.tenant_quota_usages(IsA(http.HttpRequest))\ - .MultipleTimes().AndReturn(quota_usages) + cinder.tenant_absolute_limits(IsA(http.HttpRequest))\ + .MultipleTimes().AndReturn(limits) self.mox.ReplayAll()