Add the ability to get absolute limits from Cinder
This will be used in a later patch to check quota usage
for volume snapshots before attempting to create new
volume snapshots, so we can avoid an OverLimit error.
Change-Id: Ica7c087708e86494d285fc3905a5740fd1356e5f
Related-Bug: #1731986
(cherry picked from commit ad389244ba
)
This commit is contained in:
parent
7ab98b5345
commit
02acd2d1bc
|
@ -15,6 +15,7 @@
|
|||
|
||||
from cinderclient import api_versions as cinder_api_versions
|
||||
from cinderclient import exceptions as cinder_exception
|
||||
from cinderclient.v2 import limits as cinder_limits
|
||||
from keystoneauth1 import loading as ks_loading
|
||||
from keystoneclient import exceptions as keystone_exception
|
||||
import mock
|
||||
|
@ -752,6 +753,36 @@ class CinderApiTestCase(test.NoDBTestCase):
|
|||
self.assertRaises(NotImplementedError,
|
||||
self.api.update, self.ctx, '', '')
|
||||
|
||||
@mock.patch('nova.volume.cinder.cinderclient')
|
||||
def test_get_absolute_limits_forbidden(self, cinderclient):
|
||||
"""Tests to make sure we gracefully handle a Forbidden error raised
|
||||
from python-cinderclient when getting limits.
|
||||
"""
|
||||
cinderclient.return_value.limits.get.side_effect = (
|
||||
cinder_exception.Forbidden(403))
|
||||
self.assertRaises(
|
||||
exception.Forbidden, self.api.get_absolute_limits, self.ctx)
|
||||
|
||||
@mock.patch('nova.volume.cinder.cinderclient')
|
||||
def test_get_absolute_limits(self, cinderclient):
|
||||
"""Tests the happy path of getting the absolute limits."""
|
||||
expected_limits = {
|
||||
"totalSnapshotsUsed": 0,
|
||||
"maxTotalBackups": 10,
|
||||
"maxTotalVolumeGigabytes": 1000,
|
||||
"maxTotalSnapshots": 10,
|
||||
"maxTotalBackupGigabytes": 1000,
|
||||
"totalBackupGigabytesUsed": 0,
|
||||
"maxTotalVolumes": 10,
|
||||
"totalVolumesUsed": 0,
|
||||
"totalBackupsUsed": 0,
|
||||
"totalGigabytesUsed": 0
|
||||
}
|
||||
limits_obj = cinder_limits.Limits(None, {'absolute': expected_limits})
|
||||
cinderclient.return_value.limits.get.return_value = limits_obj
|
||||
actual_limits = self.api.get_absolute_limits(self.ctx)
|
||||
self.assertDictEqual(expected_limits, actual_limits)
|
||||
|
||||
@mock.patch('nova.volume.cinder.cinderclient')
|
||||
def test_get_snapshot(self, mock_cinderclient):
|
||||
snapshot_id = 'snapshot_id'
|
||||
|
|
|
@ -543,6 +543,23 @@ class API(object):
|
|||
def update(self, context, volume_id, fields):
|
||||
raise NotImplementedError()
|
||||
|
||||
@translate_cinder_exception
|
||||
def get_absolute_limits(self, context):
|
||||
"""Returns quota limit and usage information for the given tenant
|
||||
|
||||
See the <volumev3>/v3/{project_id}/limits API reference for details.
|
||||
|
||||
:param context: The nova RequestContext for the user request. Note
|
||||
that the limit information returned from Cinder is specific to
|
||||
the project_id within this context.
|
||||
:returns: dict of absolute limits
|
||||
"""
|
||||
# cinderclient returns a generator of AbsoluteLimit objects, so iterate
|
||||
# over the generator and return a dictionary which is easier for the
|
||||
# nova client-side code to handle.
|
||||
limits = cinderclient(context).limits.get().absolute
|
||||
return {limit.name: limit.value for limit in limits}
|
||||
|
||||
@translate_snapshot_exception
|
||||
def get_snapshot(self, context, snapshot_id):
|
||||
item = cinderclient(context).volume_snapshots.get(snapshot_id)
|
||||
|
|
Loading…
Reference in New Issue