diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py index b1491700b1..0504b15298 100644 --- a/openstackclient/common/quota.py +++ b/openstackclient/common/quota.py @@ -739,6 +739,40 @@ class ShowQuota(command.Lister): default=False, 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 def take_action(self, parsed_args): @@ -748,32 +782,39 @@ class ShowQuota(command.Lister): project_info = get_project(self.app, parsed_args.project) project = project_info['id'] - # NOTE(dtroyer): These quota API calls do not validate the project or - # class arguments and return what appears to be the default quota - # values if the project or class does not exist. If this is determined - # to be the intended behaviour of the API we will validate the argument - # with Identity ourselves later. - compute_quota_info = get_compute_quotas( - self.app, - project, - detail=parsed_args.usage, - quota_class=parsed_args.quota_class, - default=parsed_args.default, - ) - volume_quota_info = get_volume_quotas( - self.app, - project, - detail=parsed_args.usage, - quota_class=parsed_args.quota_class, - default=parsed_args.default, - ) - network_quota_info = get_network_quotas( - self.app, - project, - detail=parsed_args.usage, - quota_class=parsed_args.quota_class, - default=parsed_args.default, - ) + compute_quota_info = {} + volume_quota_info = {} + network_quota_info = {} + + # NOTE(stephenfin): These quota API calls do not validate the project + # or class arguments and return what appears to be the default quota + # values if the project or class does not exist. This is expected + # behavior. However, we have already checked for the presence of the + # project above so it shouldn't be an issue. + if parsed_args.service in {'all', 'compute'}: + compute_quota_info = get_compute_quotas( + self.app, + project, + detail=parsed_args.usage, + quota_class=parsed_args.quota_class, + default=parsed_args.default, + ) + if parsed_args.service in {'all', 'volume'}: + volume_quota_info = get_volume_quotas( + self.app, + project, + detail=parsed_args.usage, + quota_class=parsed_args.quota_class, + 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.update(compute_quota_info) diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py index 53aab5f246..0900200e96 100644 --- a/openstackclient/tests/unit/common/test_quota.py +++ b/openstackclient/tests/unit/common/test_quota.py @@ -1087,6 +1087,7 @@ class TestQuotaShow(TestQuota): self.projects[0].name, ] verifylist = [ + ('service', 'all'), ('project', self.projects[0].name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1107,6 +1108,67 @@ class TestQuotaShow(TestQuota): ) 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): arglist = [ '--default', diff --git a/releasenotes/notes/quota-show-service-options-ba48d6eca8ffc4f9.yaml b/releasenotes/notes/quota-show-service-options-ba48d6eca8ffc4f9.yaml new file mode 100644 index 0000000000..b171d1931d --- /dev/null +++ b/releasenotes/notes/quota-show-service-options-ba48d6eca8ffc4f9.yaml @@ -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.