summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorStephen Finucane <sfinucan@redhat.com>2022-09-23 15:24:43 +0100
committerStephen Finucane <sfinucan@redhat.com>2022-09-30 10:55:47 +0100
commit44443f78561ce4f23d202a42de4a4ceac2ffa097 (patch)
tree3cabb7f6dd5945c27a370de5959b5c9ec09b018c /openstackclient
parent45bec041b206678de36f2f463ac6872b785e592e (diff)
downloadpython-openstackclient-44443f78561ce4f23d202a42de4a4ceac2ffa097.tar.gz
quota: Add support for detailed volume quotas
We were stating that this was not supported. That is not true. Correct the oversight. Change-Id: Ib9d9db641a18e142be0a1eccff783e7cccdf2db5 Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/common/quota.py26
-rw-r--r--openstackclient/tests/unit/common/test_quota.py37
-rw-r--r--openstackclient/tests/unit/volume/v2/fakes.py29
3 files changed, 82 insertions, 10 deletions
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index 0110feb6..8477da90 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -143,6 +143,7 @@ class BaseQuota(object):
def get_volume_quota(self, client, parsed_args):
quota_class = (
parsed_args.quota_class if 'quota_class' in parsed_args else False)
+ detail = parsed_args.detail if 'detail' in parsed_args else False
default = parsed_args.default if 'default' in parsed_args else False
try:
if quota_class:
@@ -153,7 +154,7 @@ class BaseQuota(object):
if default:
quota = client.quotas.defaults(project)
else:
- quota = client.quotas.get(project)
+ quota = client.quotas.get(project, usage=detail)
except Exception as e:
if type(e).__name__ == 'EndpointNotFound':
return {}
@@ -195,7 +196,7 @@ class BaseQuota(object):
# more consistent
for key, values in network_quota.items():
if type(values) is dict and "used" in values:
- values[u'in_use'] = values.pop("used")
+ values['in_use'] = values.pop("used")
network_quota[key] = values
return network_quota
else:
@@ -205,7 +206,8 @@ class BaseQuota(object):
class ListQuota(command.Lister, BaseQuota):
_description = _(
"List quotas for all projects with non-default quota values or "
- "list detailed quota information for requested project")
+ "list detailed quota information for requested project"
+ )
def _get_detailed_quotas(self, parsed_args):
columns = (
@@ -222,10 +224,21 @@ class ListQuota(command.Lister, BaseQuota):
)
quotas = {}
if parsed_args.compute:
- quotas.update(self.get_compute_quota(
- self.app.client_manager.compute, parsed_args))
+ quotas.update(
+ self.get_compute_quota(
+ self.app.client_manager.compute,
+ parsed_args,
+ )
+ )
if parsed_args.network:
quotas.update(self.get_network_quota(parsed_args))
+ if parsed_args.volume:
+ quotas.update(
+ self.get_volume_quota(
+ self.app.client_manager.volume,
+ parsed_args,
+ ),
+ )
result = []
for resource, values in quotas.items():
@@ -359,8 +372,7 @@ class ListQuota(command.Lister, BaseQuota):
if parsed_args.volume:
if parsed_args.detail:
- LOG.warning("Volume service doesn't provide detailed quota"
- " information")
+ return self._get_detailed_quotas(parsed_args)
volume_client = self.app.client_manager.volume
for p in project_ids:
try:
diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py
index 087443c1..58007208 100644
--- a/openstackclient/tests/unit/common/test_quota.py
+++ b/openstackclient/tests/unit/common/test_quota.py
@@ -279,6 +279,37 @@ class TestQuotaList(TestQuota):
self.assertEqual(
sorted(detailed_reference_data), sorted(ret_quotas))
+ def test_quota_list_details_volume(self):
+ detailed_quota = (
+ volume_fakes.FakeQuota.create_one_detailed_quota())
+
+ detailed_column_header = (
+ 'Resource',
+ 'In Use',
+ 'Reserved',
+ 'Limit',
+ )
+ detailed_reference_data = (
+ self._get_detailed_reference_data(detailed_quota))
+
+ self.volume.quotas.get = mock.Mock(return_value=detailed_quota)
+
+ arglist = [
+ '--detail',
+ '--volume',
+ ]
+ verifylist = [
+ ('detail', True),
+ ('volume', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ ret_quotas = list(data)
+
+ self.assertEqual(detailed_column_header, columns)
+ self.assertEqual(sorted(detailed_reference_data), sorted(ret_quotas))
+
def test_quota_list_compute(self):
# Two projects with non-default quotas
self.compute.quotas.get = mock.Mock(
@@ -1001,7 +1032,7 @@ class TestQuotaSet(TestQuota):
class TestQuotaShow(TestQuota):
def setUp(self):
- super(TestQuotaShow, self).setUp()
+ super().setUp()
self.compute_quota = compute_fakes.FakeQuota.create_one_comp_quota()
self.compute_quotas_mock.get.return_value = self.compute_quota
@@ -1066,7 +1097,7 @@ class TestQuotaShow(TestQuota):
self.projects[0].id, detail=False
)
self.volume_quotas_mock.get.assert_called_once_with(
- self.projects[0].id,
+ self.projects[0].id, usage=False
)
self.network.get_quota.assert_called_once_with(
self.projects[0].id, details=False
@@ -1128,7 +1159,7 @@ class TestQuotaShow(TestQuota):
identity_fakes.project_id, detail=False
)
self.volume_quotas_mock.get.assert_called_once_with(
- identity_fakes.project_id,
+ identity_fakes.project_id, usage=False
)
self.network.get_quota.assert_called_once_with(
identity_fakes.project_id, details=False
diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py
index 96e381d3..6da69f8f 100644
--- a/openstackclient/tests/unit/volume/v2/fakes.py
+++ b/openstackclient/tests/unit/volume/v2/fakes.py
@@ -1193,6 +1193,35 @@ class FakeQuota(object):
return quota
+ @staticmethod
+ def create_one_detailed_quota(attrs=None):
+ """Create one quota"""
+ attrs = attrs or {}
+
+ quota_attrs = {
+ 'volumes': {'limit': 3, 'in_use': 1, 'reserved': 0},
+ 'per_volume_gigabytes': {'limit': -1, 'in_use': 0, 'reserved': 0},
+ 'snapshots': {'limit': 10, 'in_use': 0, 'reserved': 0},
+ 'gigabytes': {'limit': 1000, 'in_use': 5, 'reserved': 0},
+ 'backups': {'limit': 10, 'in_use': 0, 'reserved': 0},
+ 'backup_gigabytes': {'limit': 1000, 'in_use': 0, 'reserved': 0},
+ 'volumes_lvmdriver-1': {'limit': -1, 'in_use': 1, 'reserved': 0},
+ 'gigabytes_lvmdriver-1': {'limit': -1, 'in_use': 5, 'reserved': 0},
+ 'snapshots_lvmdriver-1': {'limit': -1, 'in_use': 0, 'reserved': 0},
+ 'volumes___DEFAULT__': {'limit': -1, 'in_use': 0, 'reserved': 0},
+ 'gigabytes___DEFAULT__': {'limit': -1, 'in_use': 0, 'reserved': 0},
+ 'snapshots___DEFAULT__': {'limit': -1, 'in_use': 0, 'reserved': 0},
+ 'groups': {'limit': 10, 'in_use': 0, 'reserved': 0},
+ 'id': uuid.uuid4().hex,
+ }
+ quota_attrs.update(attrs)
+
+ quota = fakes.FakeResource(
+ info=copy.deepcopy(quota_attrs),
+ loaded=True)
+
+ return quota
+
class FakeLimits(object):
"""Fake limits"""