Skip to content

Commit eac38fe

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "quota: Add 'quota delete' command"
2 parents 7d67a0b + 45bec04 commit eac38fe

8 files changed

Lines changed: 197 additions & 5 deletions

File tree

doc/source/cli/data/cinder.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ qos-show,volume qos show,Shows a specified qos specs.
9191
quota-class-show,quota show --class,Lists quotas for a quota class.
9292
quota-class-update,quota set --class,Updates quotas for a quota class.
9393
quota-defaults,quota show --default,Lists default quotas for a tenant.
94-
quota-delete,,Delete the quotas for a tenant.
94+
quota-delete,quota delete --volume,Delete the quotas for a tenant.
9595
quota-show,quota show,Lists quotas for a tenant.
9696
quota-update,quota set,Updates quotas for a tenant.
9797
quota-usage,,Lists quota usage for a tenant.

doc/source/cli/data/neutron.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ qos-policy-list,network qos policy list,List QoS policies that belong to a given
188188
qos-policy-show,network qos policy show,Show information of a given qos policy.
189189
qos-policy-update,network qos policy set,Update a given qos policy.
190190
quota-default-show,quota show --default,Show default quotas for a given tenant.
191-
quota-delete,,Delete defined quotas of a given tenant.
191+
quota-delete,quota delete --network,Delete defined quotas of a given tenant.
192192
quota-list,quota list,List quotas of all tenants who have non-default quota values.
193193
quota-show,quota show,Show quotas for a given tenant.
194194
quota-update,quota set,Define tenant's quotas not to use defaults.

doc/source/cli/data/nova.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pause,server pause,Pause a server.
7070
quota-class-show,quota show --class,List the quotas for a quota class.
7171
quota-class-update,quota set --class,Update the quotas for a quota class.
7272
quota-defaults,quota list,List the default quotas for a tenant.
73-
quota-delete,quota set,Delete quota for a tenant/user so their quota will Revert back to default.
73+
quota-delete,quota delete --compute,Delete quota for a tenant/user so their quota will Revert back to default.
7474
quota-show,quota show,List the quotas for a tenant/user.
7575
quota-update,quota set,Update the quotas for a tenant/user.
7676
reboot,server reboot,Reboot a server.

openstackclient/common/quota.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,3 +697,82 @@ def take_action(self, parsed_args):
697697
info['project_name'] = project_name
698698

699699
return zip(*sorted(info.items()))
700+
701+
702+
class DeleteQuota(command.Command):
703+
_description = _(
704+
"Delete configured quota for a project and revert to defaults."
705+
)
706+
707+
def get_parser(self, prog_name):
708+
parser = super().get_parser(prog_name)
709+
parser.add_argument(
710+
'project',
711+
metavar='<project>',
712+
help=_('Delete quotas for this project (name or ID)'),
713+
)
714+
option = parser.add_mutually_exclusive_group()
715+
option.add_argument(
716+
'--all',
717+
action='store_const',
718+
const='all',
719+
dest='service',
720+
default='all',
721+
help=_('Delete project quotas for all services (default)'),
722+
)
723+
option.add_argument(
724+
'--compute',
725+
action='store_const',
726+
const='compute',
727+
dest='service',
728+
default='all',
729+
help=_(
730+
'Delete compute quotas for the project '
731+
'(including network quotas when using nova-network)'
732+
),
733+
)
734+
option.add_argument(
735+
'--volume',
736+
action='store_const',
737+
const='volume',
738+
dest='service',
739+
default='all',
740+
help=_('Delete volume quotas for the project'),
741+
)
742+
option.add_argument(
743+
'--network',
744+
action='store_const',
745+
const='network',
746+
dest='service',
747+
default='all',
748+
help=_('Delete network quotas for the project'),
749+
)
750+
return parser
751+
752+
def take_action(self, parsed_args):
753+
identity_client = self.app.client_manager.identity
754+
project = utils.find_resource(
755+
identity_client.projects,
756+
parsed_args.project,
757+
)
758+
759+
# compute quotas
760+
if parsed_args.service in {'all', 'compute'}:
761+
compute_client = self.app.client_manager.compute
762+
compute_client.quotas.delete(project)
763+
764+
# volume quotas
765+
if parsed_args.service in {'all', 'volume'}:
766+
volume_client = self.app.client_manager.volume
767+
volume_client.quotas.delete(project)
768+
769+
# network quotas (but only if we're not using nova-network, otherwise
770+
# we already deleted the quotas in the compute step)
771+
if (
772+
parsed_args.service in {'all', 'network'}
773+
and self.app.client_manager.is_network_endpoint_enabled()
774+
):
775+
network_client = self.app.client_manager.network
776+
network_client.quotas.delete(project)
777+
778+
return None

openstackclient/tests/unit/common/test_quota.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ def setUp(self):
6262
self.app.client_manager.volume.quota_classes
6363
self.volume_quotas_class_mock.reset_mock()
6464

65+
self.app.client_manager.network.quotas = mock.Mock()
66+
self.network_quotas_mock = self.app.client_manager.network.quotas
67+
6568
self.app.client_manager.auth_ref = mock.Mock()
6669
self.app.client_manager.auth_ref.service_catalog = mock.Mock()
6770
self.service_catalog_mock = \
@@ -1154,3 +1157,107 @@ def test_network_quota_show_remove_empty(self):
11541157
self.assertEqual(len(network_fakes.QUOTA) - 1, len(result))
11551158
# Go back to default mock
11561159
self.network.get_quota = orig_get_quota
1160+
1161+
1162+
class TestQuotaDelete(TestQuota):
1163+
"""Test cases for quota delete command"""
1164+
1165+
def setUp(self):
1166+
super().setUp()
1167+
1168+
self.cmd = quota.DeleteQuota(self.app, None)
1169+
1170+
def test_delete(self):
1171+
"""Delete all quotas"""
1172+
arglist = [
1173+
self.projects[0].id,
1174+
]
1175+
verifylist = [
1176+
('service', 'all'),
1177+
('project', self.projects[0].id),
1178+
]
1179+
1180+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1181+
1182+
result = self.cmd.take_action(parsed_args)
1183+
1184+
self.assertIsNone(result)
1185+
self.projects_mock.get.assert_called_once_with(self.projects[0].id)
1186+
self.compute_quotas_mock.delete.assert_called_once_with(
1187+
self.projects[0],
1188+
)
1189+
self.volume_quotas_mock.delete.assert_called_once_with(
1190+
self.projects[0],
1191+
)
1192+
self.network_quotas_mock.delete.assert_called_once_with(
1193+
self.projects[0],
1194+
)
1195+
1196+
def test_delete__compute(self):
1197+
"""Delete compute quotas only"""
1198+
arglist = [
1199+
'--compute',
1200+
self.projects[0].id,
1201+
]
1202+
verifylist = [
1203+
('service', 'compute'),
1204+
('project', self.projects[0].id),
1205+
]
1206+
1207+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1208+
1209+
result = self.cmd.take_action(parsed_args)
1210+
1211+
self.assertIsNone(result)
1212+
self.projects_mock.get.assert_called_once_with(self.projects[0].id)
1213+
self.compute_quotas_mock.delete.assert_called_once_with(
1214+
self.projects[0],
1215+
)
1216+
self.volume_quotas_mock.delete.assert_not_called()
1217+
self.network_quotas_mock.delete.assert_not_called()
1218+
1219+
def test_delete__volume(self):
1220+
"""Delete volume quotas only"""
1221+
arglist = [
1222+
'--volume',
1223+
self.projects[0].id,
1224+
]
1225+
verifylist = [
1226+
('service', 'volume'),
1227+
('project', self.projects[0].id),
1228+
]
1229+
1230+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1231+
1232+
result = self.cmd.take_action(parsed_args)
1233+
1234+
self.assertIsNone(result)
1235+
self.projects_mock.get.assert_called_once_with(self.projects[0].id)
1236+
self.compute_quotas_mock.delete.assert_not_called()
1237+
self.volume_quotas_mock.delete.assert_called_once_with(
1238+
self.projects[0],
1239+
)
1240+
self.network_quotas_mock.delete.assert_not_called()
1241+
1242+
def test_delete__network(self):
1243+
"""Delete network quotas only"""
1244+
arglist = [
1245+
'--network',
1246+
self.projects[0].id,
1247+
]
1248+
verifylist = [
1249+
('service', 'network'),
1250+
('project', self.projects[0].id),
1251+
]
1252+
1253+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1254+
1255+
result = self.cmd.take_action(parsed_args)
1256+
1257+
self.assertIsNone(result)
1258+
self.projects_mock.get.assert_called_once_with(self.projects[0].id)
1259+
self.compute_quotas_mock.delete.assert_not_called()
1260+
self.volume_quotas_mock.delete.assert_not_called()
1261+
self.network_quotas_mock.delete.assert_called_once_with(
1262+
self.projects[0],
1263+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
features:
3+
- |
4+
Added a new command, ``quota delete``, that will allow admins delete quotas
5+
set for projects. Supported by the compute, volume, and network services.

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ openstack.common =
4949
quota_list = openstackclient.common.quota:ListQuota
5050
quota_set = openstackclient.common.quota:SetQuota
5151
quota_show = openstackclient.common.quota:ShowQuota
52+
quota_delete = openstackclient.common.quota:DeleteQuota
5253
versions_show = openstackclient.common.versions:ShowVersions
5354

5455
openstack.compute.v2 =

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ show-source = True
134134
# H203: Use assertIs(Not)None to check for None
135135
enable-extensions = H203
136136
exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools,releasenotes
137-
# W504 is disabled since you must choose between this or W503
138-
ignore = W504
137+
# W503 and W504 are disabled since they're not very useful
138+
ignore = W503,W504
139139
import-order-style = pep8
140140
application_import_names = openstackclient

0 commit comments

Comments
 (0)