Merge "Fix quotas retrieval for shares and snapshots tables"
This commit is contained in:
commit
01a7b5773a
|
@ -21,7 +21,6 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from django.utils.translation import ungettext_lazy
|
||||
from horizon import exceptions
|
||||
from horizon import tables
|
||||
from openstack_dashboard.usage import quotas
|
||||
|
||||
from manila_ui.api import manila
|
||||
|
||||
|
@ -57,8 +56,13 @@ class CreateShareSnapshot(tables.LinkAction):
|
|||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, share=None):
|
||||
usages = quotas.tenant_quota_usages(request)
|
||||
if usages['snapshots']['available'] <= 0:
|
||||
usages = manila.tenant_absolute_limits(request)
|
||||
snapshots_allowed = (usages['maxTotalShareSnapshots'] >
|
||||
usages['totalShareSnapshotsUsed'] and
|
||||
usages['maxTotalSnapshotGigabytes'] >
|
||||
usages['totalSnapshotGigabytesUsed'])
|
||||
|
||||
if not snapshots_allowed:
|
||||
if "disabled" not in self.classes:
|
||||
self.classes = [c for c in self.classes] + ['disabled']
|
||||
self.verbose_name = string_concat(
|
||||
|
@ -145,6 +149,7 @@ class EditShareSnapshot(tables.LinkAction):
|
|||
|
||||
|
||||
class ShareSnapshotShareNameColumn(tables.Column):
|
||||
|
||||
def get_link_url(self, snapshot):
|
||||
return reverse(self.link, args=(snapshot.share_id,))
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ from django.utils.translation import ungettext_lazy
|
|||
from horizon import exceptions
|
||||
from horizon import messages
|
||||
from horizon import tables
|
||||
from openstack_dashboard.usage import quotas
|
||||
|
||||
from manila_ui.api import manila
|
||||
from manila_ui.dashboards.project.share_snapshots import tables as ss_tables
|
||||
|
@ -87,8 +86,13 @@ class CreateShare(tables.LinkAction):
|
|||
policy_rules = (("share", "share:create"),)
|
||||
|
||||
def allowed(self, request, share=None):
|
||||
usages = quotas.tenant_quota_usages(request)
|
||||
if usages['shares']['available'] <= 0:
|
||||
usages = manila.tenant_absolute_limits(request)
|
||||
shares_allowed = (usages['maxTotalShares'] >
|
||||
usages['totalSharesUsed'] and
|
||||
usages['maxTotalShareGigabytes'] >
|
||||
usages['totalShareGigabytesUsed'])
|
||||
|
||||
if not shares_allowed:
|
||||
if "disabled" not in self.classes:
|
||||
self.classes = [c for c in self.classes] + ['disabled']
|
||||
self.verbose_name = string_concat(self.verbose_name, ' ',
|
||||
|
@ -97,6 +101,7 @@ class CreateShare(tables.LinkAction):
|
|||
self.verbose_name = _("Create Share")
|
||||
classes = [c for c in self.classes if c != "disabled"]
|
||||
self.classes = classes
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ from django.urls import reverse
|
|||
import mock
|
||||
from openstack_dashboard.api import keystone as api_keystone
|
||||
from openstack_dashboard.api import neutron as api_neutron
|
||||
from openstack_dashboard.usage import quotas
|
||||
|
||||
from manila_ui.api import manila as api_manila
|
||||
from manila_ui.dashboards.admin import utils
|
||||
|
@ -53,9 +52,6 @@ class SharesTests(test.BaseAdminViewTests):
|
|||
api_manila, "share_snapshot_list", mock.Mock(return_value=snaps))
|
||||
self.mock_object(
|
||||
api_neutron, "is_service_enabled", mock.Mock(return_value=[True]))
|
||||
self.mock_object(
|
||||
quotas, "tenant_quota_usages",
|
||||
mock.Mock(return_value=test_data.quota_usage))
|
||||
|
||||
res = self.client.get(INDEX_URL)
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ import ddt
|
|||
from django.core.handlers import wsgi
|
||||
import mock
|
||||
|
||||
from manila_ui.api import manila as api_manila
|
||||
from manila_ui.dashboards.project.share_snapshots import tables
|
||||
from manila_ui.tests.dashboards.project import test_data
|
||||
from manila_ui.tests import helpers as base
|
||||
|
||||
|
||||
|
@ -36,23 +38,38 @@ class CreateSnapshotTests(base.APITestCase):
|
|||
return type("Share", (object, ), kwargs)()
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch('openstack_dashboard.usage.quotas.tenant_quota_usages')
|
||||
def test_allowed_with_snapshot_support_attr(self, snapshot_support,
|
||||
mock_quota_usages):
|
||||
mock_quota_usages.return_value = {'snapshots': {'available': 1}}
|
||||
def test_allowed_with_snapshot_support_attr(self, snapshot_support):
|
||||
self.mock_object(
|
||||
api_manila, "tenant_absolute_limits",
|
||||
mock.Mock(return_value=test_data.limits))
|
||||
|
||||
share = self._get_fake_share(snapshot_support=snapshot_support)
|
||||
|
||||
result = self.create_snapshot.allowed(self.request, share)
|
||||
|
||||
self.assertEqual(snapshot_support, result)
|
||||
mock_quota_usages.assert_called_once_with(self.request)
|
||||
|
||||
@mock.patch('openstack_dashboard.usage.quotas.tenant_quota_usages')
|
||||
def test_allowed_no_snapshot_support_attr(self, mock_quota_usages):
|
||||
mock_quota_usages.return_value = {'snapshots': {'available': 1}}
|
||||
def test_allowed_no_snapshot_support_attr(self):
|
||||
self.mock_object(
|
||||
api_manila, "tenant_absolute_limits",
|
||||
mock.Mock(return_value=test_data.limits))
|
||||
share = self._get_fake_share()
|
||||
|
||||
result = self.create_snapshot.allowed(self.request, share)
|
||||
|
||||
self.assertNotIn('disabled', self.create_snapshot.classes)
|
||||
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_allowed_no_snapshot_support_attr_no_quota(self):
|
||||
self.mock_object(
|
||||
api_manila, "tenant_absolute_limits",
|
||||
mock.Mock(return_value=test_data.limits_negative))
|
||||
|
||||
share = self._get_fake_share()
|
||||
|
||||
result = self.create_snapshot.allowed(self.request, share)
|
||||
|
||||
self.assertIn('disabled', self.create_snapshot.classes)
|
||||
|
||||
self.assertTrue(result)
|
||||
mock_quota_usages.assert_called_once_with(self.request)
|
||||
|
|
|
@ -18,7 +18,6 @@ from django.urls import reverse
|
|||
from horizon import messages as horizon_messages
|
||||
import mock
|
||||
from openstack_dashboard.api import neutron
|
||||
from openstack_dashboard.usage import quotas
|
||||
import six
|
||||
|
||||
from manila_ui.api import manila as api_manila
|
||||
|
@ -55,6 +54,9 @@ class ShareViewTests(test.APITestCase):
|
|||
self.mock_object(horizon_messages, "success")
|
||||
FAKE_ENVIRON = {'REQUEST_METHOD': 'GET', 'wsgi.input': 'fake_input'}
|
||||
self.request = wsgi.WSGIRequest(FAKE_ENVIRON)
|
||||
self.mock_object(
|
||||
api_manila, "tenant_absolute_limits",
|
||||
mock.Mock(return_value=test_data.limits))
|
||||
|
||||
def test_index(self):
|
||||
snaps = [test_data.snapshot, test_data.snapshot_mount_support]
|
||||
|
@ -70,10 +72,10 @@ class ShareViewTests(test.APITestCase):
|
|||
api_manila, "share_network_list",
|
||||
mock.Mock(return_value=share_networks))
|
||||
self.mock_object(
|
||||
neutron, "is_service_enabled", mock.Mock(return_value=[True]))
|
||||
api_manila, "tenant_absolute_limits",
|
||||
mock.Mock(return_value=test_data.limits))
|
||||
self.mock_object(
|
||||
quotas, "tenant_quota_usages",
|
||||
mock.Mock(return_value=test_data.quota_usage))
|
||||
neutron, "is_service_enabled", mock.Mock(return_value=[True]))
|
||||
|
||||
res = self.client.get(INDEX_URL)
|
||||
|
||||
|
@ -83,6 +85,7 @@ class ShareViewTests(test.APITestCase):
|
|||
mock.ANY, detailed=True)
|
||||
api_manila.share_list.assert_called_with(mock.ANY)
|
||||
api_manila.share_network_list.assert_called_with(mock.ANY)
|
||||
api_manila.tenant_absolute_limits.assert_called_with(mock.ANY)
|
||||
|
||||
@mock.patch.object(api_manila, 'availability_zone_list')
|
||||
def test_create_share(self, az_list):
|
||||
|
@ -354,14 +357,7 @@ class ShareViewTests(test.APITestCase):
|
|||
|
||||
def test_extend_share_get(self):
|
||||
share = test_data.share
|
||||
usage_limit = {
|
||||
'maxTotalShareGigabytes': 250,
|
||||
'totalShareGigabytesUsed': 20,
|
||||
}
|
||||
url = reverse('horizon:project:shares:extend', args=[share.id])
|
||||
self.mock_object(
|
||||
api_manila, "tenant_absolute_limits",
|
||||
mock.Mock(return_value=usage_limit))
|
||||
self.mock_object(
|
||||
neutron, "is_service_enabled", mock.Mock(return_value=[True]))
|
||||
|
||||
|
@ -373,15 +369,8 @@ class ShareViewTests(test.APITestCase):
|
|||
|
||||
def test_extend_share_open_form_successfully(self):
|
||||
self.share.size = 5
|
||||
usage_limit = {
|
||||
'maxTotalShareGigabytes': self.share.size + 50,
|
||||
'totalShareGigabytesUsed': self.share.size,
|
||||
}
|
||||
url = reverse('horizon:project:shares:extend', args=[self.share.id])
|
||||
self.mock_object(api_manila, "share_extend")
|
||||
self.mock_object(
|
||||
api_manila, 'tenant_absolute_limits',
|
||||
mock.Mock(return_value=usage_limit))
|
||||
|
||||
response = self.client.get(url)
|
||||
|
||||
|
@ -392,15 +381,8 @@ class ShareViewTests(test.APITestCase):
|
|||
api_manila.tenant_absolute_limits.assert_called_once_with(mock.ANY)
|
||||
|
||||
def test_extend_share_get_with_api_exception(self):
|
||||
usage_limit = {
|
||||
'maxTotalShareGigabytes': self.share.size + 50,
|
||||
'totalShareGigabytesUsed': self.share.size,
|
||||
}
|
||||
url = reverse('horizon:project:shares:extend', args=[self.share.id])
|
||||
self.mock_object(api_manila, "share_extend")
|
||||
self.mock_object(
|
||||
api_manila, 'tenant_absolute_limits',
|
||||
mock.Mock(return_value=usage_limit))
|
||||
self.mock_object(
|
||||
api_manila, "share_get",
|
||||
mock.Mock(return_value=Exception('Fake share NotFound exception')))
|
||||
|
@ -421,6 +403,7 @@ class ShareViewTests(test.APITestCase):
|
|||
usage_limit = {
|
||||
'maxTotalShareGigabytes': self.share.size + 50,
|
||||
'totalShareGigabytesUsed': self.share.size,
|
||||
|
||||
}
|
||||
url = reverse('horizon:project:shares:extend', args=[self.share.id])
|
||||
self.mock_object(api_manila, "share_extend")
|
||||
|
@ -443,11 +426,11 @@ class ShareViewTests(test.APITestCase):
|
|||
def test_extend_share_post_with_invalid_value(self, new_size):
|
||||
self.share.size = 5
|
||||
form_data = {'new_size': new_size}
|
||||
url = reverse('horizon:project:shares:extend', args=[self.share.id])
|
||||
usage_limit = {
|
||||
'maxTotalShareGigabytes': self.share.size + 50,
|
||||
'totalShareGigabytesUsed': self.share.size,
|
||||
}
|
||||
url = reverse('horizon:project:shares:extend', args=[self.share.id])
|
||||
self.mock_object(api_manila, "share_extend")
|
||||
self.mock_object(
|
||||
api_manila, 'tenant_absolute_limits',
|
||||
|
@ -464,17 +447,10 @@ class ShareViewTests(test.APITestCase):
|
|||
def test_extend_share_post_with_api_exception(self):
|
||||
self.share.size = 5
|
||||
form_data = {'new_size': 30}
|
||||
usage_limit = {
|
||||
'maxTotalShareGigabytes': self.share.size + 50,
|
||||
'totalShareGigabytesUsed': self.share.size,
|
||||
}
|
||||
url = reverse('horizon:project:shares:extend', args=[self.share.id])
|
||||
self.mock_object(
|
||||
api_manila, "share_extend",
|
||||
mock.Mock(return_value=Exception('Fake API exception')))
|
||||
self.mock_object(
|
||||
api_manila, 'tenant_absolute_limits',
|
||||
mock.Mock(return_value=usage_limit))
|
||||
|
||||
response = self.client.post(url, form_data)
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
# under the License.
|
||||
import collections
|
||||
|
||||
from manilaclient.v2 import quotas
|
||||
from manilaclient.v2 import security_services
|
||||
from manilaclient.v2 import share_export_locations
|
||||
from manilaclient.v2 import share_group_snapshots
|
||||
|
@ -28,9 +27,6 @@ from manilaclient.v2 import share_snapshots
|
|||
from manilaclient.v2 import share_types
|
||||
from manilaclient.v2 import shares
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.usage import quotas as usage_quotas
|
||||
|
||||
|
||||
class FakeAPIClient(object):
|
||||
client = "fake_client"
|
||||
|
@ -474,24 +470,23 @@ share_group_snapshot_nameless = share_group_snapshots.ShareGroupSnapshot(
|
|||
'members': []}
|
||||
)
|
||||
|
||||
# Quota Sets
|
||||
quota_data = dict(shares='1',
|
||||
share_snapshots='1',
|
||||
share_gigabytes='1000')
|
||||
quota = quotas.QuotaSet(quotas.QuotaSetManager(FakeAPIClient), quota_data)
|
||||
|
||||
# Quota Usages
|
||||
quota_usage_data = {'gigabytes': {'used': 0, 'quota': 1000},
|
||||
'shares': {'used': 0, 'quota': 10},
|
||||
'snapshots': {'used': 0, 'quota': 10},
|
||||
'share_networks': {'used': 0, 'quota': 10}}
|
||||
quota_usage = usage_quotas.QuotaUsage()
|
||||
for k, v in quota_usage_data.items():
|
||||
quota_usage.add_quota(api.base.Quota(k, v['quota']))
|
||||
quota_usage.tally(k, v['used'])
|
||||
|
||||
# Manila Limits
|
||||
limits = {"absolute": {"totalSharesUsed": 1,
|
||||
"totalShareGigabytesUsed": 5,
|
||||
"maxTotalShareGigabytes": 1000,
|
||||
"maxTotalShares": 10}}
|
||||
limits = {"totalSharesUsed": 1,
|
||||
"totalShareSnapshotsUsed": 1,
|
||||
"totalShareGigabytesUsed": 500,
|
||||
"totalSnapshotGigabytesUsed": 500,
|
||||
"maxTotalShares": 10,
|
||||
"maxTotalShareSnapshots": 10,
|
||||
"maxTotalShareGigabytes": 1000,
|
||||
"maxTotalSnapshotGigabytes": 1000,
|
||||
}
|
||||
|
||||
limits_negative = {"totalSharesUsed": 10,
|
||||
"totalShareSnapshotsUsed": 10,
|
||||
"totalShareGigabytesUsed": 1000,
|
||||
"totalSnapshotGigabytesUsed": 1000,
|
||||
"maxTotalShares": 10,
|
||||
"maxTotalShareSnapshots": 10,
|
||||
"maxTotalShareGigabytes": 1000,
|
||||
"maxTotalSnapshotGigabytes": 1000,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
fixes:
|
||||
- |
|
||||
Fixed missing "Create Share" button on the "Shares" dashboard.
|
Loading…
Reference in New Issue