Reworks quotas and services panels into System Info panel.
This is a step towards combining all the "read only" data about an OpenStack cloud into one place for admin inspection. Implements blueprint system-info-panel. Change-Id: I2dc52a855c1c8a488fb9c66b82e0faca765b3812
This commit is contained in:
parent
0e328995ec
commit
2f98befe3f
@ -183,7 +183,8 @@ def novaclient(request):
|
|||||||
request.user.token.id,
|
request.user.token.id,
|
||||||
project_id=request.user.tenant_id,
|
project_id=request.user.tenant_id,
|
||||||
auth_url=url_for(request, 'compute'),
|
auth_url=url_for(request, 'compute'),
|
||||||
insecure=insecure)
|
insecure=insecure,
|
||||||
|
http_log_debug=settings.DEBUG)
|
||||||
c.client.auth_token = request.user.token.id
|
c.client.auth_token = request.user.token.id
|
||||||
c.client.management_url = url_for(request, 'compute')
|
c.client.management_url = url_for(request, 'compute')
|
||||||
return c
|
return c
|
||||||
|
@ -22,8 +22,8 @@ import horizon
|
|||||||
class SystemPanels(horizon.PanelGroup):
|
class SystemPanels(horizon.PanelGroup):
|
||||||
slug = "admin"
|
slug = "admin"
|
||||||
name = _("System Panel")
|
name = _("System Panel")
|
||||||
panels = ('overview', 'instances', 'volumes', 'services', 'flavors',
|
panels = ('overview', 'instances', 'volumes', 'flavors',
|
||||||
'images', 'projects', 'users', 'quotas', 'networks',)
|
'images', 'projects', 'users', 'networks', 'info')
|
||||||
|
|
||||||
|
|
||||||
class Admin(horizon.Dashboard):
|
class Admin(horizon.Dashboard):
|
||||||
|
@ -26,8 +26,8 @@ from openstack_dashboard.dashboards.admin import dashboard
|
|||||||
|
|
||||||
|
|
||||||
class Quotas(horizon.Panel):
|
class Quotas(horizon.Panel):
|
||||||
name = _("Quotas")
|
name = _("System Info")
|
||||||
slug = 'quotas'
|
slug = 'info'
|
||||||
|
|
||||||
|
|
||||||
dashboard.Admin.register(Quotas)
|
dashboard.Admin.register(Quotas)
|
@ -1,6 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django import template
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
@ -9,6 +8,36 @@ from horizon import tables
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class QuotaFilterAction(tables.FilterAction):
|
||||||
|
def filter(self, table, tenants, filter_string):
|
||||||
|
q = filter_string.lower()
|
||||||
|
|
||||||
|
def comp(tenant):
|
||||||
|
if q in tenant.name.lower():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
return filter(comp, tenants)
|
||||||
|
|
||||||
|
|
||||||
|
def get_quota_name(quota):
|
||||||
|
return quota.name.replace("_", " ").title()
|
||||||
|
|
||||||
|
|
||||||
|
class QuotasTable(tables.DataTable):
|
||||||
|
name = tables.Column(get_quota_name, verbose_name=_('Quota Name'))
|
||||||
|
limit = tables.Column("limit", verbose_name=_('Limit'))
|
||||||
|
|
||||||
|
def get_object_id(self, obj):
|
||||||
|
return obj.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
name = "quotas"
|
||||||
|
verbose_name = _("Quotas")
|
||||||
|
table_actions = (QuotaFilterAction,)
|
||||||
|
multi_select = False
|
||||||
|
|
||||||
|
|
||||||
class ServiceFilterAction(tables.FilterAction):
|
class ServiceFilterAction(tables.FilterAction):
|
||||||
def filter(self, table, services, filter_string):
|
def filter(self, table, services, filter_string):
|
||||||
q = filter_string.lower()
|
q = filter_string.lower()
|
62
openstack_dashboard/dashboards/admin/info/tabs.py
Normal file
62
openstack_dashboard/dashboards/admin/info/tabs.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2012 Nebula, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import tabs
|
||||||
|
|
||||||
|
from openstack_dashboard.api import keystone
|
||||||
|
from openstack_dashboard.usage import quotas
|
||||||
|
from .tables import QuotasTable, ServicesTable
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultQuotasTab(tabs.TableTab):
|
||||||
|
table_classes = (QuotasTable,)
|
||||||
|
name = _("Default Quotas")
|
||||||
|
slug = "quotas"
|
||||||
|
template_name = ("horizon/common/_detail_table.html")
|
||||||
|
|
||||||
|
def get_quotas_data(self):
|
||||||
|
request = self.tab_group.request
|
||||||
|
try:
|
||||||
|
quota_set = quotas.get_default_quota_data(request)
|
||||||
|
data = quota_set.items
|
||||||
|
except:
|
||||||
|
data = []
|
||||||
|
exceptions.handle(self.request, _('Unable to get quota info.'))
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class ServicesTab(tabs.TableTab):
|
||||||
|
table_classes = (ServicesTable,)
|
||||||
|
name = _("Services")
|
||||||
|
slug = "services"
|
||||||
|
template_name = ("horizon/common/_detail_table.html")
|
||||||
|
|
||||||
|
def get_services_data(self):
|
||||||
|
request = self.tab_group.request
|
||||||
|
services = []
|
||||||
|
for i, service in enumerate(request.user.service_catalog):
|
||||||
|
service['id'] = i
|
||||||
|
services.append(keystone.Service(service))
|
||||||
|
return services
|
||||||
|
|
||||||
|
|
||||||
|
class SystemInfoTabs(tabs.TabGroup):
|
||||||
|
slug = "system_info"
|
||||||
|
tabs = (ServicesTab, DefaultQuotasTab,)
|
||||||
|
sticky = True
|
@ -0,0 +1,15 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "System Info" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block page_header %}
|
||||||
|
{% include "horizon/common/_page_header.html" with title=_("System Info")%}
|
||||||
|
{% endblock page_header %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12">
|
||||||
|
{{ tab_group.render }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
71
openstack_dashboard/dashboards/admin/info/tests.py
Normal file
71
openstack_dashboard/dashboards/admin/info/tests.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2012 Nebula, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django import http
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from mox import IsA
|
||||||
|
|
||||||
|
from openstack_dashboard.test import helpers as test
|
||||||
|
from openstack_dashboard import api
|
||||||
|
|
||||||
|
INDEX_URL = reverse('horizon:admin:info:index')
|
||||||
|
|
||||||
|
|
||||||
|
class ServicessViewTests(test.BaseAdminViewTests):
|
||||||
|
def test_index(self):
|
||||||
|
self.mox.StubOutWithMock(api.nova, 'default_quota_get')
|
||||||
|
self.mox.StubOutWithMock(api.cinder, 'default_quota_get')
|
||||||
|
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.quotas.nova)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.get(INDEX_URL)
|
||||||
|
|
||||||
|
self.assertTemplateUsed(res, 'admin/info/index.html')
|
||||||
|
|
||||||
|
services_tab = res.context['tab_group'].get_tab('services')
|
||||||
|
self.assertQuerysetEqual(services_tab._tables['services'].data,
|
||||||
|
['<Service: compute>',
|
||||||
|
'<Service: volume>',
|
||||||
|
'<Service: image>',
|
||||||
|
'<Service: identity (native backend)>',
|
||||||
|
'<Service: object-store>',
|
||||||
|
'<Service: network>',
|
||||||
|
'<Service: ec2>'])
|
||||||
|
|
||||||
|
quotas_tab = res.context['tab_group'].get_tab('quotas')
|
||||||
|
self.assertQuerysetEqual(quotas_tab._tables['quotas'].data,
|
||||||
|
['<Quota: (injected_file_content_bytes, 1)>',
|
||||||
|
'<Quota: (metadata_items, 1)>',
|
||||||
|
'<Quota: (injected_files, 1)>',
|
||||||
|
'<Quota: (gigabytes, 1000)>',
|
||||||
|
'<Quota: (ram, 10000)>',
|
||||||
|
'<Quota: (floating_ips, 1)>',
|
||||||
|
'<Quota: (instances, 10)>',
|
||||||
|
'<Quota: (volumes, 1)>',
|
||||||
|
'<Quota: (cores, 10)>',
|
||||||
|
'<Quota: (injected_file_content_bytes, 1)>',
|
||||||
|
'<Quota: (metadata_items, 1)>',
|
||||||
|
'<Quota: (injected_files, 1)>',
|
||||||
|
'<Quota: (gigabytes, 1000)>',
|
||||||
|
'<Quota: (ram, 10000)>',
|
||||||
|
'<Quota: (floating_ips, 1)>',
|
||||||
|
'<Quota: (instances, 10)>',
|
||||||
|
'<Quota: (volumes, 1)>',
|
||||||
|
'<Quota: (cores, 10)>'])
|
@ -23,5 +23,5 @@ from django.conf.urls.defaults import patterns, url
|
|||||||
from .views import IndexView
|
from .views import IndexView
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = patterns('openstack_dashboard.dashboards.admin.quotas.views',
|
urlpatterns = patterns('openstack_dashboard.dashboards.admin.info.views',
|
||||||
url(r'^$', IndexView.as_view(), name='index'))
|
url(r'^$', IndexView.as_view(), name='index'))
|
@ -18,10 +18,16 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from django.conf.urls.defaults import patterns, url
|
import logging
|
||||||
|
|
||||||
from .views import IndexView
|
from horizon import tabs
|
||||||
|
|
||||||
|
from .tabs import SystemInfoTabs
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = patterns('openstack_dashboard.dashboards.admin.services.views',
|
LOG = logging.getLogger(__name__)
|
||||||
url(r'^$', IndexView.as_view(), name='index'))
|
|
||||||
|
|
||||||
|
class IndexView(tabs.TabbedTableView):
|
||||||
|
tab_group_class = SystemInfoTabs
|
||||||
|
template_name = 'admin/info/index.html'
|
@ -1,38 +0,0 @@
|
|||||||
import logging
|
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
|
|
||||||
from horizon import tables
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class QuotaFilterAction(tables.FilterAction):
|
|
||||||
def filter(self, table, tenants, filter_string):
|
|
||||||
q = filter_string.lower()
|
|
||||||
|
|
||||||
def comp(tenant):
|
|
||||||
if q in tenant.name.lower():
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
return filter(comp, tenants)
|
|
||||||
|
|
||||||
|
|
||||||
def get_quota_name(quota):
|
|
||||||
return quota.name.replace("_", " ").title()
|
|
||||||
|
|
||||||
|
|
||||||
class QuotasTable(tables.DataTable):
|
|
||||||
name = tables.Column(get_quota_name, verbose_name=_('Quota Name'))
|
|
||||||
limit = tables.Column("limit", verbose_name=_('Limit'))
|
|
||||||
|
|
||||||
def get_object_id(self, obj):
|
|
||||||
return obj.name
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
name = "quotas"
|
|
||||||
verbose_name = _("Quotas")
|
|
||||||
table_actions = (QuotaFilterAction,)
|
|
||||||
multi_select = False
|
|
@ -1,13 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% block title %}Quotas{% endblock %}
|
|
||||||
|
|
||||||
{% block page_header %}
|
|
||||||
{% url horizon:admin:quotas:index as refresh_link %}
|
|
||||||
{# to make searchable false, just remove it from the include statement #}
|
|
||||||
{% include "horizon/common/_page_header.html" with title=_("Default Quotas") refresh_link=refresh_link searchable="true" %}
|
|
||||||
{% endblock page_header %}
|
|
||||||
|
|
||||||
{% block main %}
|
|
||||||
{{ table.render }}
|
|
||||||
{% endblock %}
|
|
@ -1 +0,0 @@
|
|||||||
#FIXME(gabriel): Needs tests!
|
|
@ -1,47 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Copyright 2012 Nebula, Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from django.utils.translation import ugettext as _
|
|
||||||
|
|
||||||
from horizon import exceptions
|
|
||||||
from horizon import tables
|
|
||||||
|
|
||||||
from openstack_dashboard import api
|
|
||||||
from .tables import QuotasTable
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class IndexView(tables.DataTableView):
|
|
||||||
table_class = QuotasTable
|
|
||||||
template_name = 'admin/quotas/index.html'
|
|
||||||
|
|
||||||
def get_data(self):
|
|
||||||
try:
|
|
||||||
quota_set = api.default_quota_get(self.request,
|
|
||||||
self.request.user.tenant_id)
|
|
||||||
data = quota_set.items
|
|
||||||
except:
|
|
||||||
data = []
|
|
||||||
exceptions.handle(self.request, _('Unable to get quota info.'))
|
|
||||||
return data
|
|
@ -1,33 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Copyright 2012 Nebula, Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
|
|
||||||
import horizon
|
|
||||||
|
|
||||||
from openstack_dashboard.dashboards.admin import dashboard
|
|
||||||
|
|
||||||
|
|
||||||
class Services(horizon.Panel):
|
|
||||||
name = _("Services")
|
|
||||||
slug = 'services'
|
|
||||||
|
|
||||||
|
|
||||||
dashboard.Admin.register(Services)
|
|
@ -1,14 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% block title %}Services{% endblock %}
|
|
||||||
|
|
||||||
{% block page_header %}
|
|
||||||
{% url horizon:admin:services:index as refresh_link %}
|
|
||||||
{# to make searchable false, just remove it from the include statement #}
|
|
||||||
{% include "horizon/common/_page_header.html" with title=_("Services") refresh_link=refresh_link searchable="true" %}
|
|
||||||
{% endblock page_header %}
|
|
||||||
|
|
||||||
{% block main %}
|
|
||||||
{{ table.render }}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 Nebula, Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
|
||||||
|
|
||||||
from openstack_dashboard.test import helpers as test
|
|
||||||
|
|
||||||
|
|
||||||
INDEX_URL = reverse('horizon:admin:services:index')
|
|
||||||
|
|
||||||
|
|
||||||
class ServicessViewTests(test.BaseAdminViewTests):
|
|
||||||
def test_index(self):
|
|
||||||
res = self.client.get(INDEX_URL)
|
|
||||||
self.assertTemplateUsed(res, 'admin/services/index.html')
|
|
||||||
self.assertQuerysetEqual(res.context['table'].data,
|
|
||||||
['<Service: compute>',
|
|
||||||
'<Service: volume>',
|
|
||||||
'<Service: image>',
|
|
||||||
'<Service: identity (native backend)>',
|
|
||||||
'<Service: object-store>',
|
|
||||||
'<Service: network>',
|
|
||||||
'<Service: ec2>'])
|
|
@ -1,41 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Copyright 2012 Nebula, Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from horizon import tables
|
|
||||||
|
|
||||||
from openstack_dashboard import api
|
|
||||||
from .tables import ServicesTable
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class IndexView(tables.DataTableView):
|
|
||||||
table_class = ServicesTable
|
|
||||||
template_name = 'admin/services/index.html'
|
|
||||||
|
|
||||||
def get_data(self):
|
|
||||||
services = []
|
|
||||||
for i, service in enumerate(self.request.user.service_catalog):
|
|
||||||
service['id'] = i
|
|
||||||
services.append(api.keystone.Service(service))
|
|
||||||
return services
|
|
@ -280,6 +280,7 @@ def data(TEST):
|
|||||||
injected_files='1',
|
injected_files='1',
|
||||||
cores='10')
|
cores='10')
|
||||||
quota = quotas.QuotaSet(quotas.QuotaSetManager(None), quota_data)
|
quota = quotas.QuotaSet(quotas.QuotaSetManager(None), quota_data)
|
||||||
|
TEST.quotas.nova = QuotaSetWrapper(quota)
|
||||||
TEST.quotas.add(QuotaSetWrapper(quota))
|
TEST.quotas.add(QuotaSetWrapper(quota))
|
||||||
|
|
||||||
# Quota Usages
|
# Quota Usages
|
||||||
|
Loading…
x
Reference in New Issue
Block a user