Add per share gigabytes quota to the CLI

- Added support to new quota 'per_share_gigabytes' which
can be configured to limit the size of individual share.

Closes-Bug: #1918961
Change-Id: Ibe150f051f6ef0d5a7b27fa0321262866757796b
This commit is contained in:
kpdev 2021-04-09 12:57:55 +02:00 committed by Goutham Pacha Ravi
parent 5ff8b70cdb
commit 1f31818d2f
9 changed files with 141 additions and 5 deletions

View File

@ -132,6 +132,14 @@ class QuotaSet(command.Command):
default=None,
help=_('Force update the quota.')
)
parser.add_argument(
'--per-share-gigabytes',
metavar='<per-share-gigabytes>',
type=int,
default=None,
help=_("New value for the 'per-share-gigabytes' quota."
"Available only for microversion >= 2.62")
)
return parser
def take_action(self, parsed_args):
@ -153,6 +161,7 @@ class QuotaSet(command.Command):
"gigabytes": parsed_args.gigabytes,
"snapshot_gigabytes": parsed_args.snapshot_gigabytes,
"share_networks": parsed_args.share_networks,
"per_share_gigabytes": parsed_args.per_share_gigabytes,
}
if parsed_args.share_type is not None:
@ -186,6 +195,13 @@ class QuotaSet(command.Command):
"is available only starting with API microversion '2.53'.")
)
kwargs["replica_gigabytes"] = parsed_args.replica_gigabytes
if parsed_args.per_share_gigabytes is not None:
if share_client.api_version < api_versions.APIVersion('2.62'):
raise exceptions.CommandError(_(
"'per share gigabytes' quotas are available only "
"starting with '2.62' API microversion.")
)
kwargs["per_share_gigabytes"] = parsed_args.per_share_gigabytes
if all(value is None for value in kwargs.values()):
raise exceptions.CommandError(_(
@ -194,7 +210,7 @@ class QuotaSet(command.Command):
"resources: 'shares', 'snapshots', 'gigabytes', "
"'snapshot-gigabytes', 'share-networks', 'share-type', "
"'share-groups', 'share group snapshots', 'share-replicas', "
"'replica-gigabytes'"))
"'replica-gigabytes', 'per-share-gigabytes'"))
project_id = None
if parsed_args.project:

View File

@ -371,7 +371,8 @@ class FakeQuotaSet(object):
'share_networks': 10,
'shares': 50,
'shapshot_gigabytes': 1000,
'snapshots': 50
'snapshots': 50,
'per_share_gigabytes': -1,
}
quotas_info.update(attrs)

View File

@ -72,6 +72,7 @@ class TestQuotaSet(TestQuotas):
shares=40,
snapshot_gigabytes=None,
snapshots=None,
per_share_gigabytes=None,
tenant_id=self.project.id,
user_id=None)
self.assertIsNone(result)
@ -99,6 +100,7 @@ class TestQuotaSet(TestQuotas):
shares=None,
snapshot_gigabytes=None,
snapshots=None,
per_share_gigabytes=None,
tenant_id=self.project.id,
user_id=None)
self.assertIsNone(result)
@ -127,6 +129,7 @@ class TestQuotaSet(TestQuotas):
shares=None,
snapshot_gigabytes=None,
snapshots=None,
per_share_gigabytes=None,
tenant_id=self.project.id,
user_id=None)
self.assertIsNone(result)
@ -157,6 +160,7 @@ class TestQuotaSet(TestQuotas):
snapshot_gigabytes=None,
snapshots=None,
tenant_id=self.project.id,
per_share_gigabytes=None,
user_id=None)
self.assertIsNone(result)
@ -235,6 +239,7 @@ class TestQuotaSet(TestQuotas):
shares=None,
snapshot_gigabytes=None,
snapshots=None,
per_share_gigabytes=None,
tenant_id=self.project.id,
user_id=None)
self.assertIsNone(result)
@ -253,6 +258,38 @@ class TestQuotaSet(TestQuotas):
self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args)
def test_quota_set_per_share_gigabytes(self):
self.app.client_manager.share.api_version = api_versions.APIVersion(
'2.62'
)
arglist = [
'--project', self.project.id,
'--per-share-gigabytes', '10',
]
verifylist = [
('project', self.project.id),
('per_share_gigabytes', 10)
]
with mock.patch('osc_lib.utils.find_resource') as mock_find_resource:
mock_find_resource.return_value = self.project
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.quotas_mock.update.assert_called_with(
force=None,
gigabytes=None,
share_networks=None,
shares=None,
snapshot_gigabytes=None,
snapshots=None,
per_share_gigabytes=10,
tenant_id=self.project.id,
user_id=None)
self.assertIsNone(result)
class TestQuotaShow(TestQuotas):
project = identity_fakes.FakeProject.create_one_project()

View File

@ -179,6 +179,11 @@ class QuotaSetsTest(utils.TestCase):
'share_replicas']
kwargs['replica_gigabytes'] = expected_body['quota_set'][
'replica_gigabytes']
if (api_versions.APIVersion(microversion) >=
api_versions.APIVersion('2.62')):
expected_body['quota_set']['per_share_gigabytes'] = 10
kwargs['per_share_gigabytes'] = expected_body['quota_set'][
'per_share_gigabytes']
with mock.patch.object(manager, '_update',
mock.Mock(return_value='fake_update')):
@ -209,6 +214,9 @@ class QuotaSetsTest(utils.TestCase):
expected_body['quota_set']['share_replicas'] = 8
expected_body['quota_set']['replica_gigabytes'] = 9
kwargs = {'share_replicas': 8, 'replica_gigabytes': 9}
if microversion >= '2.62':
expected_body['quota_set']['per_share_gigabytes'] = 10
kwargs = {'per_share_gigabytes': 10}
with mock.patch.object(manager, '_update',
mock.Mock(return_value='fake_update')):
manager.update(

View File

@ -2514,6 +2514,7 @@ class ShellTest(test_utils.TestCase):
('--share-group-snapshots 0', {'share_group_snapshots': 0}),
('--share-replicas 15', {'share_replicas': 15}),
('--replica_gigabytes 100', {'replica_gigabytes': 100}),
('--per_share_gigabytes 101', {'per_share_gigabytes': 101}),
)
@ddt.unpack
def test_quota_update(self, cmd, expected_body):

View File

@ -54,7 +54,8 @@ class QuotaClassSetManager(base.ManagerWithFind):
def _do_update(self, class_name, shares=None, gigabytes=None,
snapshots=None, snapshot_gigabytes=None,
share_networks=None, share_replicas=None,
replica_gigabytes=None, resource_path=RESOURCE_PATH):
replica_gigabytes=None, per_share_gigabytes=None,
resource_path=RESOURCE_PATH):
body = {
'quota_class_set': {
'class_name': class_name,
@ -64,7 +65,8 @@ class QuotaClassSetManager(base.ManagerWithFind):
'snapshot_gigabytes': snapshot_gigabytes,
'share_networks': share_networks,
"share_replicas": share_replicas,
"replica_gigabytes": replica_gigabytes
"replica_gigabytes": replica_gigabytes,
'per_share_gigabytes': per_share_gigabytes,
}
}
@ -103,3 +105,16 @@ class QuotaClassSetManager(base.ManagerWithFind):
snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes,
share_networks=share_networks, share_replicas=share_replicas,
replica_gigabytes=replica_gigabytes, resource_path=RESOURCE_PATH)
@api_versions.wraps("2.62") # noqa
def update(self, class_name, shares=None, gigabytes=None, # noqa
snapshots=None, snapshot_gigabytes=None, share_networks=None,
share_replicas=None, replica_gigabytes=None,
per_share_gigabytes=None):
return self._do_update(
class_name, shares=shares, gigabytes=gigabytes,
snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes,
share_networks=share_networks, share_replicas=share_replicas,
replica_gigabytes=replica_gigabytes,
per_share_gigabytes=per_share_gigabytes,
resource_path=RESOURCE_PATH)

View File

@ -95,6 +95,7 @@ class QuotaSetManager(base.ManagerWithFind):
force=None, user_id=None, share_type=None,
share_groups=None, share_group_snapshots=None,
share_replicas=None, replica_gigabytes=None,
per_share_gigabytes=None,
resource_path=RESOURCE_PATH):
self._check_user_id_and_share_type_args(user_id, share_type)
body = {
@ -110,6 +111,7 @@ class QuotaSetManager(base.ManagerWithFind):
'force': force,
'share_replicas': share_replicas,
'replica_gigabytes': replica_gigabytes,
'per_share_gigabytes': per_share_gigabytes,
},
}
@ -201,6 +203,26 @@ class QuotaSetManager(base.ManagerWithFind):
resource_path=RESOURCE_PATH
)
@api_versions.wraps("2.62") # noqa
def update(self, tenant_id, user_id=None, share_type=None, # noqa
shares=None, snapshots=None, gigabytes=None,
snapshot_gigabytes=None, share_networks=None,
share_groups=None, share_group_snapshots=None,
share_replicas=None, replica_gigabytes=None, force=None,
per_share_gigabytes=None):
self._validate_st_and_sn_in_same_request(share_type, share_networks)
return self._do_update(
tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes,
share_networks, force, user_id,
share_type=share_type,
share_groups=share_groups,
share_group_snapshots=share_group_snapshots,
share_replicas=share_replicas,
replica_gigabytes=replica_gigabytes,
per_share_gigabytes=per_share_gigabytes,
resource_path=RESOURCE_PATH
)
@api_versions.wraps("1.0", "2.6")
def defaults(self, tenant_id):
return self._get(

View File

@ -445,7 +445,8 @@ _quota_resources = [
'snapshot_gigabytes',
'share_networks',
'share_replicas',
'replica_gigabytes'
'replica_gigabytes',
'per_share_gigabytes'
]
@ -614,6 +615,14 @@ def do_quota_defaults(cs, args):
default=None,
help='Whether force update the quota even if the already used '
'and reserved exceeds the new quota.')
@cliutils.arg(
'--per-share-gigabytes',
'--per_share_gigabytes',
metavar='<per-share-gigabytes>',
type=int,
default=None,
help='New value for the "per_share_gigabytes" quota. Available only for '
'microversion >= 2.62')
@api_versions.wraps("1.0")
def do_quota_update(cs, args):
"""Update the quotas for a project/user and/or share type (Admin only)."""
@ -650,6 +659,13 @@ def do_quota_update(cs, args):
"'2.53' API microversion.")
kwargs["share_replicas"] = args.share_replicas
kwargs["replica_gigabytes"] = args.replica_gigabytes
if args.per_share_gigabytes is not None:
if cs.api_version < api_versions.APIVersion("2.62"):
raise exceptions.CommandError(
"'per share gigabytes' quotas are available only starting "
"with '2.62' API microversion.")
kwargs["per_share_gigabytes"] = args.per_share_gigabytes
cs.quotas.update(**kwargs)
@ -763,6 +779,15 @@ def do_quota_class_show(cs, args):
action='single_alias',
help='New value for the "replica_gigabytes" quota. Available only for '
'microversion >= 2.53')
@cliutils.arg(
'--per-share-gigabytes',
'--per_share_gigabytes', # alias
metavar='<per-share-gigabytes>',
type=int,
default=None,
action='single_alias',
help='New value for the "per_share_gigabytes" quota. Available only for '
'microversion >= 2.62')
def do_quota_class_update(cs, args):
"""Update the quotas for a quota class (Admin only)."""
if args.share_replicas is not None or args.replica_gigabytes is not None:
@ -770,6 +795,11 @@ def do_quota_class_update(cs, args):
raise exceptions.CommandError(
"'share replica' quotas are available only starting with "
"'2.53' API microversion.")
if args.per_share_gigabytes is not None:
if cs.api_version < api_versions.APIVersion("2.62"):
raise exceptions.CommandError(
"'per_share_gigabytes' quota is available only starting "
"with '2.62' API microversion.")
_quota_class_update(cs.quota_classes, args.class_name, args)

View File

@ -0,0 +1,6 @@
---
features:
- Added support for per share gigabytes quotas.
upgrade:
- After addition of per share gigabytes quotas, it is now possible
to get 'over limit' error while creating a share.