Merge "Enable snapshot quota setting"
This commit is contained in:
commit
144fda877f
|
@ -30,6 +30,12 @@
|
||||||
{% blocktrans with used=usage.quotas.volumes.used|intcomma available=usage.quotas.volumes.quota|intcomma %} Used <span> {{ used }} </span> of <span> {{ available }} </span>{% endblocktrans %}
|
{% blocktrans with used=usage.quotas.volumes.used|intcomma available=usage.quotas.volumes.quota|intcomma %} Used <span> {{ used }} </span> of <span> {{ available }} </span>{% endblocktrans %}
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="d3_quota_bar">
|
||||||
|
<div class="d3_pie_chart" data-used="{% widthratio usage.quotas.snapshots.used usage.quotas.snapshots.quota 100 %}"></div>
|
||||||
|
<strong>{% trans "Available Snapshots" %} <br />
|
||||||
|
{% blocktrans with used=usage.quotas.snapshots.used|intcomma available=usage.quotas.snapshots.quota|intcomma %} Used <span> {{ used }} </span> of <span> {{ available }} </span>{% endblocktrans %}
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
<div class="d3_quota_bar">
|
<div class="d3_quota_bar">
|
||||||
<div class="d3_pie_chart" data-used="{% widthratio usage.quotas.gigabytes.used usage.quotas.gigabytes.quota 100 %}"></div>
|
<div class="d3_pie_chart" data-used="{% widthratio usage.quotas.gigabytes.used usage.quotas.gigabytes.quota 100 %}"></div>
|
||||||
<strong>{% trans "Available Volume Storage" %} <br />
|
<strong>{% trans "Available Volume Storage" %} <br />
|
||||||
|
|
|
@ -31,7 +31,7 @@ class ServicesViewTests(test.BaseAdminViewTests):
|
||||||
api.nova.default_quota_get(IsA(http.HttpRequest),
|
api.nova.default_quota_get(IsA(http.HttpRequest),
|
||||||
self.tenant.id).AndReturn(self.quotas.nova)
|
self.tenant.id).AndReturn(self.quotas.nova)
|
||||||
api.cinder.default_quota_get(IsA(http.HttpRequest), self.tenant.id) \
|
api.cinder.default_quota_get(IsA(http.HttpRequest), self.tenant.id) \
|
||||||
.AndReturn(self.quotas.nova)
|
.AndReturn(self.cinder_quotas.first())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ class ServicesViewTests(test.BaseAdminViewTests):
|
||||||
'<Quota: (floating_ips, 1)>',
|
'<Quota: (floating_ips, 1)>',
|
||||||
'<Quota: (fixed_ips, 10)>',
|
'<Quota: (fixed_ips, 10)>',
|
||||||
'<Quota: (instances, 10)>',
|
'<Quota: (instances, 10)>',
|
||||||
|
'<Quota: (snapshots, 1)>',
|
||||||
'<Quota: (volumes, 1)>',
|
'<Quota: (volumes, 1)>',
|
||||||
'<Quota: (cores, 10)>',
|
'<Quota: (cores, 10)>',
|
||||||
'<Quota: (security_groups, 10)>',
|
'<Quota: (security_groups, 10)>',
|
||||||
|
|
|
@ -58,9 +58,12 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||||
return project_info
|
return project_info
|
||||||
|
|
||||||
def _get_quota_info(self, quota):
|
def _get_quota_info(self, quota):
|
||||||
|
cinder_quota = self.cinder_quotas.first()
|
||||||
quota_data = {}
|
quota_data = {}
|
||||||
for field in quotas.QUOTA_FIELDS:
|
for field in quotas.NOVA_QUOTA_FIELDS:
|
||||||
quota_data[field] = int(quota.get(field).limit)
|
quota_data[field] = int(quota.get(field).limit)
|
||||||
|
for field in quotas.CINDER_QUOTA_FIELDS:
|
||||||
|
quota_data[field] = int(cinder_quota.get(field).limit)
|
||||||
return quota_data
|
return quota_data
|
||||||
|
|
||||||
def _get_workflow_data(self, project, quota):
|
def _get_workflow_data(self, project, quota):
|
||||||
|
@ -403,9 +406,12 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||||
|
|
||||||
class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||||
def _get_quota_info(self, quota):
|
def _get_quota_info(self, quota):
|
||||||
|
cinder_quota = self.cinder_quotas.first()
|
||||||
quota_data = {}
|
quota_data = {}
|
||||||
for field in quotas.QUOTA_FIELDS:
|
for field in quotas.NOVA_QUOTA_FIELDS:
|
||||||
quota_data[field] = int(quota.get(field).limit)
|
quota_data[field] = int(quota.get(field).limit)
|
||||||
|
for field in quotas.CINDER_QUOTA_FIELDS:
|
||||||
|
quota_data[field] = int(cinder_quota.get(field).limit)
|
||||||
return quota_data
|
return quota_data
|
||||||
|
|
||||||
@test.create_stubs({api.keystone: ('get_default_role',
|
@test.create_stubs({api.keystone: ('get_default_role',
|
||||||
|
|
|
@ -51,6 +51,7 @@ class UpdateProjectQuotaAction(workflows.Action):
|
||||||
injected_file_content_bytes = forms.IntegerField(min_value=-1,
|
injected_file_content_bytes = forms.IntegerField(min_value=-1,
|
||||||
label=ifcb_label)
|
label=ifcb_label)
|
||||||
volumes = forms.IntegerField(min_value=-1, label=_("Volumes"))
|
volumes = forms.IntegerField(min_value=-1, label=_("Volumes"))
|
||||||
|
snapshots = forms.IntegerField(min_value=-1, label=_("Snapshots"))
|
||||||
gigabytes = forms.IntegerField(min_value=-1, label=_("Gigabytes"))
|
gigabytes = forms.IntegerField(min_value=-1, label=_("Gigabytes"))
|
||||||
ram = forms.IntegerField(min_value=-1, label=_("RAM (MB)"))
|
ram = forms.IntegerField(min_value=-1, label=_("RAM (MB)"))
|
||||||
floating_ips = forms.IntegerField(min_value=-1, label=_("Floating IPs"))
|
floating_ips = forms.IntegerField(min_value=-1, label=_("Floating IPs"))
|
||||||
|
|
|
@ -25,14 +25,21 @@ from mox import IsA
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.api import cinder
|
from openstack_dashboard.api import cinder
|
||||||
from openstack_dashboard.test import helpers as test
|
from openstack_dashboard.test import helpers as test
|
||||||
|
from openstack_dashboard.usage import quotas
|
||||||
|
|
||||||
|
|
||||||
INDEX_URL = reverse('horizon:project:images_and_snapshots:index')
|
INDEX_URL = reverse('horizon:project:images_and_snapshots:index')
|
||||||
|
|
||||||
|
|
||||||
class VolumeSnapshotsViewTests(test.TestCase):
|
class VolumeSnapshotsViewTests(test.TestCase):
|
||||||
|
@test.create_stubs({quotas: ('tenant_quota_usages',)})
|
||||||
def test_create_snapshot_get(self):
|
def test_create_snapshot_get(self):
|
||||||
volume = self.volumes.first()
|
volume = self.volumes.first()
|
||||||
|
usage = {'gigabytes': {'available': 250},
|
||||||
|
'snapshots': {'available': 6}}
|
||||||
|
quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse('horizon:project:volumes:create_snapshot',
|
url = reverse('horizon:project:volumes:create_snapshot',
|
||||||
args=[volume.id])
|
args=[volume.id])
|
||||||
res = self.client.get(url)
|
res = self.client.get(url)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends "horizon/common/_modal_form.html" %}
|
{% extends "horizon/common/_modal_form.html" %}
|
||||||
{% load i18n horizon humanize %}
|
{% load i18n %}
|
||||||
{% load url from future %}
|
{% load url from future %}
|
||||||
|
|
||||||
{% block form_id %}{% endblock %}
|
{% block form_id %}{% endblock %}
|
||||||
|
@ -16,38 +16,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right quota-dynamic">
|
<div class="right quota-dynamic">
|
||||||
<h3>{% trans "Description" %}:</h3>
|
{% include "project/volumes/_quota.html" with usages=usages %}
|
||||||
|
|
||||||
<p>{% trans "Volumes are block devices that can be attached to instances." %}</p>
|
|
||||||
|
|
||||||
<h3>{% trans "Volume Quotas" %}</h3>
|
|
||||||
|
|
||||||
<div class="quota_title clearfix">
|
|
||||||
<strong>{% trans "Total Gigabytes" %} <span>({{ usages.gigabytes.used|intcomma }} {% trans "GB" %})</span></strong>
|
|
||||||
<p>{{ usages.gigabytes.available|quota:_("GB")|intcomma }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="quota_size" data-progress-indicator-for="id_size" data-quota-limit="{{ usages.gigabytes.quota }}" data-quota-used="{{ usages.gigabytes.used }}" class="quota_bar">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="quota_title clearfix">
|
|
||||||
<strong>{% trans "Number of Volumes" %} <span>({{ usages.volumes.used|intcomma }})</span></strong>
|
|
||||||
<p>{{ usages.volumes.available|quota|intcomma }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="quota_volumes" data-progress-indicator-step-by="1" data-quota-limit="{{ usages.volumes.quota }}" data-quota-used="{{ usages.volumes.used }}" class="quota_bar">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
if(typeof horizon.Quota !== 'undefined') {
|
|
||||||
horizon.Quota.init();
|
|
||||||
} else {
|
|
||||||
addHorizonLoadEvent(function() {
|
|
||||||
horizon.Quota.init();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block modal-footer %}
|
{% block modal-footer %}
|
||||||
|
|
|
@ -9,15 +9,14 @@
|
||||||
{% block modal-header %}{% trans "Create Volume Snapshot" %}{% endblock %}
|
{% block modal-header %}{% trans "Create Volume Snapshot" %}{% endblock %}
|
||||||
|
|
||||||
{% block modal-body %}
|
{% block modal-body %}
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
{% include "horizon/common/_form_fields.html" %}
|
{% include "horizon/common/_form_fields.html" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right quota-dynamic">
|
||||||
<h3>{% trans "Description" %}:</h3>
|
{% include "project/volumes/_quota.html" with usages=usages snapshot_quota=True %}
|
||||||
<p>{% trans "Volumes are block devices that can be attached to instances." %}</p>
|
</div>
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block modal-footer %}
|
{% block modal-footer %}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
{% load i18n horizon humanize %}
|
||||||
|
|
||||||
|
<h3>{% trans "Description" %}:</h3>
|
||||||
|
|
||||||
|
<p>{% trans "Volumes are block devices that can be attached to instances." %}</p>
|
||||||
|
|
||||||
|
<h3>{% trans "Volume Quotas" %}</h3>
|
||||||
|
|
||||||
|
<div class="quota_title clearfix">
|
||||||
|
<strong>{% trans "Total Gigabytes" %} <span>({{ usages.gigabytes.used|intcomma }} {% trans "GB" %})</span></strong>
|
||||||
|
<p>{{ usages.gigabytes.available|quota:_("GB")|intcomma }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="quota_size" data-progress-indicator-for="id_size" data-quota-limit="{{ usages.gigabytes.quota }}" data-quota-used="{{ usages.gigabytes.used }}" class="quota_bar">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if snapshot_quota %}
|
||||||
|
<div class="quota_title clearfix">
|
||||||
|
<strong>{% trans "Number of Snapshots" %} <span>({{ usages.snapshots.used|intcomma }})</span></strong>
|
||||||
|
<p>{{ usages.snapshots.available|quota|intcomma }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="quota_snapshots" data-progress-indicator-step-by="1" data-quota-limit="{{ usages.snapshots.quota }}" data-quota-used="{{ usages.snapshots.used }}" class="quota_bar">
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="quota_title clearfix">
|
||||||
|
<strong>{% trans "Number of Volumes" %} <span>({{ usages.volumes.used|intcomma }})</span></strong>
|
||||||
|
<p>{{ usages.volumes.available|quota|intcomma }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="quota_volumes" data-progress-indicator-step-by="1" data-quota-limit="{{ usages.volumes.quota }}" data-quota-used="{{ usages.volumes.used }}" class="quota_bar">
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
if(typeof horizon.Quota !== 'undefined') {
|
||||||
|
horizon.Quota.init();
|
||||||
|
} else {
|
||||||
|
addHorizonLoadEvent(function() {
|
||||||
|
horizon.Quota.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -113,6 +113,10 @@ class CreateSnapshotView(forms.ModalFormView):
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(CreateSnapshotView, self).get_context_data(**kwargs)
|
context = super(CreateSnapshotView, self).get_context_data(**kwargs)
|
||||||
context['volume_id'] = self.kwargs['volume_id']
|
context['volume_id'] = self.kwargs['volume_id']
|
||||||
|
try:
|
||||||
|
context['usages'] = quotas.tenant_quota_usages(self.request)
|
||||||
|
except:
|
||||||
|
exceptions.handle(self.request)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# 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 cinderclient.v1 import quotas
|
||||||
|
from openstack_dashboard.api.base import Quota, QuotaSet as QuotaSetWrapper
|
||||||
|
from openstack_dashboard.usage.quotas import QuotaUsage
|
||||||
|
from .utils import TestDataContainer
|
||||||
|
|
||||||
|
|
||||||
|
def data(TEST):
|
||||||
|
TEST.cinder_quotas = TestDataContainer()
|
||||||
|
TEST.cinder_quota_usages = TestDataContainer()
|
||||||
|
|
||||||
|
# Quota Sets
|
||||||
|
quota_data = dict(volumes='1',
|
||||||
|
snapshots='1',
|
||||||
|
gigabytes='1000')
|
||||||
|
quota = quotas.QuotaSet(quotas.QuotaSetManager(None), quota_data)
|
||||||
|
#TEST.quotas.cinder = QuotaSetWrapper(quota)
|
||||||
|
TEST.cinder_quotas.add(QuotaSetWrapper(quota))
|
||||||
|
|
||||||
|
# Quota Usages
|
||||||
|
quota_usage_data = {'gigabytes': {'used': 0,
|
||||||
|
'quota': 1000},
|
||||||
|
'instances': {'used': 0,
|
||||||
|
'quota': 10},
|
||||||
|
'snapshots': {'used': 0,
|
||||||
|
'quota': 10}}
|
||||||
|
quota_usage = QuotaUsage()
|
||||||
|
for k, v in quota_usage_data.items():
|
||||||
|
quota_usage.add_quota(Quota(k, v['quota']))
|
||||||
|
quota_usage.tally(k, v['used'])
|
||||||
|
|
||||||
|
TEST.cinder_quota_usages.add(quota_usage)
|
|
@ -18,6 +18,7 @@ def load_test_data(load_onto=None):
|
||||||
from . import glance_data
|
from . import glance_data
|
||||||
from . import keystone_data
|
from . import keystone_data
|
||||||
from . import nova_data
|
from . import nova_data
|
||||||
|
from . import cinder_data
|
||||||
from . import quantum_data
|
from . import quantum_data
|
||||||
from . import swift_data
|
from . import swift_data
|
||||||
from . import heat_data
|
from . import heat_data
|
||||||
|
@ -27,6 +28,7 @@ def load_test_data(load_onto=None):
|
||||||
keystone_data.data,
|
keystone_data.data,
|
||||||
glance_data.data,
|
glance_data.data,
|
||||||
nova_data.data,
|
nova_data.data,
|
||||||
|
cinder_data.data,
|
||||||
quantum_data.data,
|
quantum_data.data,
|
||||||
swift_data.data,
|
swift_data.data,
|
||||||
heat_data.data)
|
heat_data.data)
|
||||||
|
|
|
@ -45,6 +45,8 @@ class QuotaTests(test.APITestCase):
|
||||||
'cores': {'available': 8, 'used': 2, 'quota': 10}}
|
'cores': {'available': 8, 'used': 2, 'quota': 10}}
|
||||||
if with_volume:
|
if with_volume:
|
||||||
quotas.update({'volumes': {'available': 0, 'used': 3, 'quota': 1},
|
quotas.update({'volumes': {'available': 0, 'used': 3, 'quota': 1},
|
||||||
|
'snapshots': {'available': 0, 'used': 3,
|
||||||
|
'quota': 1},
|
||||||
'gigabytes': {'available': 920, 'used': 80,
|
'gigabytes': {'available': 920, 'used': 80,
|
||||||
'quota': 1000}})
|
'quota': 1000}})
|
||||||
return quotas
|
return quotas
|
||||||
|
@ -54,7 +56,8 @@ class QuotaTests(test.APITestCase):
|
||||||
'tenant_quota_get',),
|
'tenant_quota_get',),
|
||||||
api.network: ('tenant_floating_ip_list',),
|
api.network: ('tenant_floating_ip_list',),
|
||||||
quotas: ('is_service_enabled',),
|
quotas: ('is_service_enabled',),
|
||||||
cinder: ('volume_list', 'tenant_quota_get',)})
|
cinder: ('volume_list', 'volume_snapshot_list',
|
||||||
|
'tenant_quota_get',)})
|
||||||
def test_tenant_quota_usages(self):
|
def test_tenant_quota_usages(self):
|
||||||
quotas.is_service_enabled(IsA(http.HttpRequest),
|
quotas.is_service_enabled(IsA(http.HttpRequest),
|
||||||
'volume').AndReturn(True)
|
'volume').AndReturn(True)
|
||||||
|
@ -68,8 +71,10 @@ class QuotaTests(test.APITestCase):
|
||||||
.AndReturn([self.servers.list(), False])
|
.AndReturn([self.servers.list(), False])
|
||||||
cinder.volume_list(IsA(http.HttpRequest)) \
|
cinder.volume_list(IsA(http.HttpRequest)) \
|
||||||
.AndReturn(self.volumes.list())
|
.AndReturn(self.volumes.list())
|
||||||
|
cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
|
||||||
|
.AndReturn(self.snapshots.list())
|
||||||
cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
|
cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
|
||||||
.AndReturn(self.quotas.first())
|
.AndReturn(self.cinder_quotas.first())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
@ -139,7 +144,8 @@ class QuotaTests(test.APITestCase):
|
||||||
'tenant_quota_get',),
|
'tenant_quota_get',),
|
||||||
api.network: ('tenant_floating_ip_list',),
|
api.network: ('tenant_floating_ip_list',),
|
||||||
quotas: ('is_service_enabled',),
|
quotas: ('is_service_enabled',),
|
||||||
cinder: ('volume_list', 'tenant_quota_get',)})
|
cinder: ('volume_list', 'volume_snapshot_list',
|
||||||
|
'tenant_quota_get',)})
|
||||||
def test_tenant_quota_usages_unlimited_quota(self):
|
def test_tenant_quota_usages_unlimited_quota(self):
|
||||||
inf_quota = self.quotas.first()
|
inf_quota = self.quotas.first()
|
||||||
inf_quota['ram'] = -1
|
inf_quota['ram'] = -1
|
||||||
|
@ -156,8 +162,10 @@ class QuotaTests(test.APITestCase):
|
||||||
.AndReturn([self.servers.list(), False])
|
.AndReturn([self.servers.list(), False])
|
||||||
cinder.volume_list(IsA(http.HttpRequest)) \
|
cinder.volume_list(IsA(http.HttpRequest)) \
|
||||||
.AndReturn(self.volumes.list())
|
.AndReturn(self.volumes.list())
|
||||||
|
cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
|
||||||
|
.AndReturn(self.snapshots.list())
|
||||||
cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
|
cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
|
||||||
.AndReturn(inf_quota)
|
.AndReturn(self.cinder_quotas.first())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ NOVA_QUOTA_FIELDS = ("metadata_items",
|
||||||
"security_group_rules",)
|
"security_group_rules",)
|
||||||
|
|
||||||
CINDER_QUOTA_FIELDS = ("volumes",
|
CINDER_QUOTA_FIELDS = ("volumes",
|
||||||
|
"snapshots",
|
||||||
"gigabytes",)
|
"gigabytes",)
|
||||||
|
|
||||||
QUOTA_FIELDS = NOVA_QUOTA_FIELDS + CINDER_QUOTA_FIELDS
|
QUOTA_FIELDS = NOVA_QUOTA_FIELDS + CINDER_QUOTA_FIELDS
|
||||||
|
@ -136,8 +137,10 @@ def tenant_quota_usages(request):
|
||||||
|
|
||||||
if 'volumes' not in disabled_quotas:
|
if 'volumes' not in disabled_quotas:
|
||||||
volumes = cinder.volume_list(request)
|
volumes = cinder.volume_list(request)
|
||||||
|
snapshots = cinder.volume_snapshot_list(request)
|
||||||
usages.tally('gigabytes', sum([int(v.size) for v in volumes]))
|
usages.tally('gigabytes', sum([int(v.size) for v in volumes]))
|
||||||
usages.tally('volumes', len(volumes))
|
usages.tally('volumes', len(volumes))
|
||||||
|
usages.tally('snapshots', len(snapshots))
|
||||||
|
|
||||||
# Sum our usage based on the flavors of the instances.
|
# Sum our usage based on the flavors of the instances.
|
||||||
for flavor in [flavors[instance.flavor['id']] for instance in instances]:
|
for flavor in [flavors[instance.flavor['id']] for instance in instances]:
|
||||||
|
|
Loading…
Reference in New Issue