quota: Allow showing project-specific quotas

Add '--compute', '--network' and '--volume' options to the 'quota show'
command, along with a default '--all' option, allowing us to restrict
quotas shown to an individual service.

Change-Id: I122b765df01887b8d916ee6567ffb7768fcb4392
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
Stephen Finucane 2022-09-23 18:16:53 +01:00
parent 04e68e0d5a
commit 00e7019022
3 changed files with 134 additions and 26 deletions
openstackclient
common
tests/unit/common
releasenotes/notes

@ -739,6 +739,40 @@ class ShowQuota(command.Lister):
default=False, default=False,
help=_('Show details about quotas usage'), help=_('Show details about quotas usage'),
) )
service_group = parser.add_mutually_exclusive_group()
service_group.add_argument(
'--all',
action='store_const',
const='all',
dest='service',
default='all',
help=_('Show quotas for all services'),
)
service_group.add_argument(
'--compute',
action='store_const',
const='compute',
dest='service',
default='all',
help=_('Show compute quota'),
)
service_group.add_argument(
'--volume',
action='store_const',
const='volume',
dest='service',
default='all',
help=_('Show volume quota'),
)
service_group.add_argument(
'--network',
action='store_const',
const='network',
dest='service',
default='all',
help=_('Show network quota'),
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -748,32 +782,39 @@ class ShowQuota(command.Lister):
project_info = get_project(self.app, parsed_args.project) project_info = get_project(self.app, parsed_args.project)
project = project_info['id'] project = project_info['id']
# NOTE(dtroyer): These quota API calls do not validate the project or compute_quota_info = {}
# class arguments and return what appears to be the default quota volume_quota_info = {}
# values if the project or class does not exist. If this is determined network_quota_info = {}
# to be the intended behaviour of the API we will validate the argument
# with Identity ourselves later. # NOTE(stephenfin): These quota API calls do not validate the project
compute_quota_info = get_compute_quotas( # or class arguments and return what appears to be the default quota
self.app, # values if the project or class does not exist. This is expected
project, # behavior. However, we have already checked for the presence of the
detail=parsed_args.usage, # project above so it shouldn't be an issue.
quota_class=parsed_args.quota_class, if parsed_args.service in {'all', 'compute'}:
default=parsed_args.default, compute_quota_info = get_compute_quotas(
) self.app,
volume_quota_info = get_volume_quotas( project,
self.app, detail=parsed_args.usage,
project, quota_class=parsed_args.quota_class,
detail=parsed_args.usage, default=parsed_args.default,
quota_class=parsed_args.quota_class, )
default=parsed_args.default, if parsed_args.service in {'all', 'volume'}:
) volume_quota_info = get_volume_quotas(
network_quota_info = get_network_quotas( self.app,
self.app, project,
project, detail=parsed_args.usage,
detail=parsed_args.usage, quota_class=parsed_args.quota_class,
quota_class=parsed_args.quota_class, default=parsed_args.default,
default=parsed_args.default, )
) if parsed_args.service in {'all', 'network'}:
network_quota_info = get_network_quotas(
self.app,
project,
detail=parsed_args.usage,
quota_class=parsed_args.quota_class,
default=parsed_args.default,
)
info = {} info = {}
info.update(compute_quota_info) info.update(compute_quota_info)

@ -1087,6 +1087,7 @@ class TestQuotaShow(TestQuota):
self.projects[0].name, self.projects[0].name,
] ]
verifylist = [ verifylist = [
('service', 'all'),
('project', self.projects[0].name), ('project', self.projects[0].name),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -1107,6 +1108,67 @@ class TestQuotaShow(TestQuota):
) )
self.assertNotCalled(self.network.get_quota_default) self.assertNotCalled(self.network.get_quota_default)
def test_quota_show__with_compute(self):
arglist = [
'--compute',
self.projects[0].name,
]
verifylist = [
('service', 'compute'),
('project', self.projects[0].name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.compute_quotas_mock.get.assert_called_once_with(
self.projects[0].id,
detail=False,
)
self.volume_quotas_mock.get.assert_not_called()
self.network.get_quota.assert_not_called()
def test_quota_show__with_volume(self):
arglist = [
'--volume',
self.projects[0].name,
]
verifylist = [
('service', 'volume'),
('project', self.projects[0].name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.compute_quotas_mock.get.assert_not_called()
self.volume_quotas_mock.get.assert_called_once_with(
self.projects[0].id,
usage=False,
)
self.network.get_quota.assert_not_called()
def test_quota_show__with_network(self):
arglist = [
'--network',
self.projects[0].name,
]
verifylist = [
('service', 'network'),
('project', self.projects[0].name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.compute_quotas_mock.get.assert_not_called()
self.volume_quotas_mock.get.assert_not_called()
self.network.get_quota.assert_called_once_with(
self.projects[0].id,
details=False,
)
self.assertNotCalled(self.network.get_quota_default)
def test_quota_show__with_default(self): def test_quota_show__with_default(self):
arglist = [ arglist = [
'--default', '--default',

@ -0,0 +1,5 @@
---
features:
- |
The ``quota show`` command now allows you to show quotas for a specific
service using the ``--compute``, ``--volume``, or ``--network`` options.