Tabbify quota default panel
Part of blueprint horizon-plugin-tab-for-info-and-quotas Change-Id: I71e23835161244b2173a6444cc00d94639df2f1b
This commit is contained in:
parent
d09170e02a
commit
a965f42c7b
@ -42,9 +42,18 @@ class UpdateDefaultQuotas(tables.LinkAction):
|
||||
return quotas.enabled_quotas(request)
|
||||
|
||||
|
||||
def get_quota_name(quota):
|
||||
class UpdateDefaultComputeQuotas(UpdateDefaultQuotas):
|
||||
name = 'update_compute_defaults'
|
||||
step = 'update_default_compute_quotas'
|
||||
|
||||
|
||||
class UpdateDefaultVolumeQuotas(UpdateDefaultQuotas):
|
||||
name = 'update_volume_defaults'
|
||||
step = 'update_default_volume_quotas'
|
||||
|
||||
|
||||
def get_compute_quota_name(quota):
|
||||
QUOTA_NAMES = {
|
||||
# Nova
|
||||
'injected_file_content_bytes': _('Injected File Content Bytes'),
|
||||
'injected_file_path_bytes': _('Length of Injected File Path'),
|
||||
'metadata_items': _('Metadata Items'),
|
||||
@ -55,7 +64,26 @@ def get_quota_name(quota):
|
||||
'key_pairs': _('Key Pairs'),
|
||||
'server_group_members': _('Server Group Members'),
|
||||
'server_groups': _('Server Groups'),
|
||||
# Cinder
|
||||
}
|
||||
return QUOTA_NAMES.get(quota.name, quota.name.replace("_", " ").title())
|
||||
|
||||
|
||||
class ComputeQuotasTable(tables.DataTable):
|
||||
name = tables.Column(get_compute_quota_name, verbose_name=_('Quota Name'))
|
||||
limit = tables.Column("limit", verbose_name=_('Limit'))
|
||||
|
||||
def get_object_id(self, obj):
|
||||
return obj.name
|
||||
|
||||
class Meta(object):
|
||||
name = "compute_quotas"
|
||||
verbose_name = _("Compute Quotas")
|
||||
table_actions = (QuotaFilterAction, UpdateDefaultComputeQuotas)
|
||||
multi_select = False
|
||||
|
||||
|
||||
def get_volume_quota_name(quota):
|
||||
QUOTA_NAMES = {
|
||||
'volumes': _('Volumes'),
|
||||
'snapshots': _('Volume Snapshots'),
|
||||
'backups': _('Backups'),
|
||||
@ -64,14 +92,6 @@ def get_quota_name(quota):
|
||||
'per_volume_gigabytes': _('Per Volume Size (GiB)'),
|
||||
'groups': _('Volume Groups'),
|
||||
'dm-crypt': _('dm-crypt'),
|
||||
# Neutron
|
||||
'network': _('Networks'),
|
||||
'subnet': _('Subnets'),
|
||||
'port': _('Ports'),
|
||||
'router': _('Routers'),
|
||||
'floatingip': _('Floating IPs'),
|
||||
'security_group': _('Security Groups'),
|
||||
'security_group_rule': _('Security Group Rules'),
|
||||
}
|
||||
|
||||
QUOTA_DYNAMIC_NAMES = {
|
||||
@ -89,15 +109,45 @@ def get_quota_name(quota):
|
||||
return QUOTA_NAMES.get(quota.name, quota.name.replace("_", " ").title())
|
||||
|
||||
|
||||
class QuotasTable(tables.DataTable):
|
||||
name = tables.Column(get_quota_name, verbose_name=_('Quota Name'))
|
||||
class VolumeQuotasTable(tables.DataTable):
|
||||
name = tables.Column(get_volume_quota_name, verbose_name=_('Quota Name'))
|
||||
limit = tables.Column("limit", verbose_name=_('Limit'))
|
||||
|
||||
def get_object_id(self, obj):
|
||||
return obj.name
|
||||
|
||||
class Meta(object):
|
||||
name = "quotas"
|
||||
verbose_name = _("Quotas")
|
||||
name = "volume_quotas"
|
||||
verbose_name = _("Volume Quotas")
|
||||
table_actions = (QuotaFilterAction, UpdateDefaultQuotas)
|
||||
multi_select = False
|
||||
|
||||
|
||||
def get_network_quota_name(quota):
|
||||
QUOTA_NAMES = {
|
||||
'network': _('Networks'),
|
||||
'subnet': _('Subnets'),
|
||||
'port': _('Ports'),
|
||||
'subnetpool': _('Subnet Pool'),
|
||||
'router': _('Routers'),
|
||||
'floatingip': _('Floating IPs'),
|
||||
'security_group': _('Security Groups'),
|
||||
'security_group_rule': _('Security Group Rules'),
|
||||
'rbac_policy': _('RBAC Policies'),
|
||||
'trunk': _('Trunks'),
|
||||
}
|
||||
return QUOTA_NAMES.get(quota.name, quota.name.replace("_", " ").title())
|
||||
|
||||
|
||||
class NetworkQuotasTable(tables.DataTable):
|
||||
name = tables.Column(get_network_quota_name, verbose_name=_('Quota Name'))
|
||||
limit = tables.Column("limit", verbose_name=_('Limit'))
|
||||
|
||||
def get_object_id(self, obj):
|
||||
return obj.name
|
||||
|
||||
class Meta(object):
|
||||
name = "network_quotas"
|
||||
verbose_name = _("Network Quotas")
|
||||
table_actions = (QuotaFilterAction,)
|
||||
multi_select = False
|
||||
|
@ -17,28 +17,73 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import tabs
|
||||
|
||||
from openstack_dashboard.usage import quotas
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.dashboards.admin.defaults import tables
|
||||
|
||||
|
||||
class DefaultQuotasTab(tabs.TableTab):
|
||||
table_classes = (tables.QuotasTable,)
|
||||
name = _("Default Quotas")
|
||||
slug = "quotas"
|
||||
class ComputeQuotasTab(tabs.TableTab):
|
||||
table_classes = (tables.ComputeQuotasTable,)
|
||||
name = _("Compute Quotas")
|
||||
slug = "compute_quotas"
|
||||
template_name = ("horizon/common/_detail_table.html")
|
||||
|
||||
def get_quotas_data(self):
|
||||
def get_compute_quotas_data(self):
|
||||
request = self.tab_group.request
|
||||
tenant_id = request.user.tenant_id
|
||||
try:
|
||||
data = quotas.get_default_quota_data(request)
|
||||
data = api.nova.default_quota_get(request, tenant_id)
|
||||
except Exception:
|
||||
data = []
|
||||
exceptions.handle(self.request, _('Unable to get quota info.'))
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get nova quota info.'))
|
||||
return data
|
||||
|
||||
def allowed(self, request):
|
||||
return api.base.is_service_enabled(request, 'compute')
|
||||
|
||||
|
||||
class VolumeQuotasTab(tabs.TableTab):
|
||||
table_classes = (tables.VolumeQuotasTable,)
|
||||
name = _("Volume Quotas")
|
||||
slug = "volume_quotas"
|
||||
template_name = ("horizon/common/_detail_table.html")
|
||||
|
||||
def get_volume_quotas_data(self):
|
||||
request = self.tab_group.request
|
||||
tenant_id = request.user.tenant_id
|
||||
try:
|
||||
data = api.cinder.default_quota_get(request, tenant_id)
|
||||
except Exception:
|
||||
data = []
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get cinder quota info.'))
|
||||
return data
|
||||
|
||||
def allowed(self, request):
|
||||
return api.cinder.is_volume_service_enabled(request)
|
||||
|
||||
|
||||
class NetworkQuotasTab(tabs.TableTab):
|
||||
table_classes = (tables.NetworkQuotasTable,)
|
||||
name = _("Network Quotas")
|
||||
slug = "network_quotas"
|
||||
template_name = ("horizon/common/_detail_table.html")
|
||||
|
||||
def get_network_quotas_data(self):
|
||||
request = self.tab_group.request
|
||||
try:
|
||||
data = api.neutron.default_quota_get(request)
|
||||
except Exception:
|
||||
data = []
|
||||
exceptions.handle(self.request,
|
||||
_('Unable to get neutron quota info.'))
|
||||
return data
|
||||
|
||||
def allowed(self, request):
|
||||
return api.base.is_service_enabled(request, 'network')
|
||||
|
||||
|
||||
class DefaultsTabs(tabs.TabGroup):
|
||||
slug = "defaults"
|
||||
tabs = (DefaultQuotasTab,)
|
||||
tabs = (ComputeQuotasTab, VolumeQuotasTab, NetworkQuotasTab)
|
||||
sticky = True
|
||||
|
@ -25,16 +25,6 @@ INDEX_URL = reverse('horizon:admin:defaults:index')
|
||||
|
||||
class ServicesViewTests(test.BaseAdminViewTests):
|
||||
def test_index(self):
|
||||
self._test_index(neutron_enabled=True)
|
||||
|
||||
def test_index_with_neutron_disabled(self):
|
||||
self._test_index(neutron_enabled=False)
|
||||
|
||||
def test_index_with_neutron_sg_disabled(self):
|
||||
self._test_index(neutron_enabled=True,
|
||||
neutron_sg_enabled=False)
|
||||
|
||||
def _test_index(self, neutron_enabled=True, neutron_sg_enabled=True):
|
||||
# Neutron does not have an API for getting default system
|
||||
# quotas. When not using Neutron, the floating ips quotas
|
||||
# should be in the list.
|
||||
@ -42,27 +32,24 @@ class ServicesViewTests(test.BaseAdminViewTests):
|
||||
self.mox.StubOutWithMock(api.cinder, 'default_quota_get')
|
||||
self.mox.StubOutWithMock(api.cinder, 'is_volume_service_enabled')
|
||||
self.mox.StubOutWithMock(api.base, 'is_service_enabled')
|
||||
if neutron_enabled:
|
||||
self.mox.StubOutWithMock(api.neutron, 'is_extension_supported')
|
||||
self.mox.StubOutWithMock(api.neutron, 'is_router_enabled')
|
||||
self.mox.StubOutWithMock(api.neutron, 'default_quota_get')
|
||||
self.mox.StubOutWithMock(quotas, 'enabled_quotas')
|
||||
|
||||
api.cinder.is_volume_service_enabled(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.base.is_service_enabled(IsA(http.HttpRequest), 'compute') \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \
|
||||
.MultipleTimes().AndReturn(neutron_enabled)
|
||||
|
||||
.MultipleTimes().AndReturn(True)
|
||||
compute_quotas = [q.name for q in self.quotas.nova]
|
||||
quotas.enabled_quotas(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(compute_quotas)
|
||||
api.nova.default_quota_get(IsA(http.HttpRequest),
|
||||
self.tenant.id).AndReturn(self.quotas.nova)
|
||||
api.cinder.default_quota_get(IsA(http.HttpRequest), self.tenant.id) \
|
||||
.AndReturn(self.cinder_quotas.first())
|
||||
if neutron_enabled:
|
||||
api.neutron.is_extension_supported(
|
||||
IsA(http.HttpRequest),
|
||||
'security-group').MultipleTimes().AndReturn(neutron_sg_enabled)
|
||||
api.neutron.is_router_enabled(
|
||||
IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
||||
api.neutron.default_quota_get(
|
||||
IsA(http.HttpRequest)).AndReturn(self.neutron_quotas.first())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
@ -70,21 +57,40 @@ class ServicesViewTests(test.BaseAdminViewTests):
|
||||
|
||||
self.assertTemplateUsed(res, 'admin/defaults/index.html')
|
||||
|
||||
quotas_tab = res.context['tab_group'].get_tab('quotas')
|
||||
expected_tabs = ['<Quota: (injected_file_content_bytes, 1)>',
|
||||
expected_data = [
|
||||
'<Quota: (injected_file_content_bytes, 1)>',
|
||||
'<Quota: (metadata_items, 1)>',
|
||||
'<Quota: (injected_files, 1)>',
|
||||
'<Quota: (gigabytes, 1000)>',
|
||||
'<Quota: (ram, 10000)>',
|
||||
'<Quota: (instances, 10)>',
|
||||
'<Quota: (snapshots, 1)>',
|
||||
'<Quota: (volumes, 1)>',
|
||||
'<Quota: (cores, 10)>',
|
||||
'<Quota: (key_pairs, 100)>',
|
||||
'<Quota: (injected_file_path_bytes, 255)>']
|
||||
'<Quota: (injected_file_path_bytes, 255)>',
|
||||
]
|
||||
self._check_quotas_data(res, 'compute_quotas', expected_data)
|
||||
|
||||
self.assertQuerysetEqual(quotas_tab._tables['quotas'].data,
|
||||
expected_tabs,
|
||||
expected_data = [
|
||||
'<Quota: (gigabytes, 1000)>',
|
||||
'<Quota: (snapshots, 1)>',
|
||||
'<Quota: (volumes, 1)>',
|
||||
]
|
||||
self._check_quotas_data(res, 'volume_quotas', expected_data)
|
||||
|
||||
expected_data = [
|
||||
'<Quota: (network, 10)>',
|
||||
'<Quota: (subnet, 10)>',
|
||||
'<Quota: (port, 50)>',
|
||||
'<Quota: (router, 10)>',
|
||||
'<Quota: (floatingip, 50)>',
|
||||
'<Quota: (security_group, 20)>',
|
||||
'<Quota: (security_group_rule, 100)>',
|
||||
]
|
||||
self._check_quotas_data(res, 'network_quotas', expected_data)
|
||||
|
||||
def _check_quotas_data(self, res, slug, expected_data):
|
||||
quotas_tab = res.context['tab_group'].get_tab(slug)
|
||||
self.assertQuerysetEqual(quotas_tab._tables[slug].data,
|
||||
expected_data,
|
||||
ordered=False)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user