Merge "Add new share replica quotas to the CLI"

This commit is contained in:
Zuul 2020-04-08 14:45:57 +00:00 committed by Gerrit Code Review
commit b7b7d9a02f
8 changed files with 176 additions and 37 deletions

View File

@ -27,7 +27,7 @@ from manilaclient import utils
LOG = logging.getLogger(__name__)
MAX_VERSION = '2.52'
MAX_VERSION = '2.53'
MIN_VERSION = '2.0'
DEPRECATED_VERSION = '1.0'
_VERSIONED_METHOD_MAP = {}

View File

@ -24,6 +24,8 @@ from manilaclient import api_versions
from manilaclient.tests.functional import base
from manilaclient.tests.functional import utils
REPLICA_QUOTAS_MICROVERSION = '2.53'
def _get_share_type_quota_values(project_quota_value):
project_quota_value = int(project_quota_value)
@ -153,6 +155,16 @@ class QuotasReadWriteTest(base.BaseTestCase):
self.admin_client.manila,
cmd, microversion='2.39')
@ddt.data('--share-replicas', '--replica-gigabytes')
@utils.skip_if_microversion_not_supported("2.52")
def test_update_quotas_for_share_replicas_using_too_old_microversion(self,
arg):
cmd = 'quota-update %s %s 10' % (self.project_id, arg)
self.assertRaises(
exceptions.CommandFailed,
self.admin_client.manila,
cmd, microversion='2.52')
@ddt.data('--share-groups', '--share-group-snapshots')
@utils.skip_if_microversion_not_supported("2.40")
def test_update_share_type_quotas_for_share_groups(self, arg):
@ -164,7 +176,7 @@ class QuotasReadWriteTest(base.BaseTestCase):
cmd, microversion='2.40')
@ddt.data(*set([
"2.39", "2.40", api_versions.MAX_VERSION,
"2.39", "2.40", REPLICA_QUOTAS_MICROVERSION, api_versions.MAX_VERSION,
]))
def test_update_share_type_quotas_positive(self, microversion):
if not utils.is_microversion_supported(microversion):
@ -184,6 +196,20 @@ class QuotasReadWriteTest(base.BaseTestCase):
'snapshot_gigabytes': _get_share_type_quota_values(
p_quotas['snapshot_gigabytes']),
}
supports_share_replica_quotas = (
api_versions.APIVersion(microversion) >= api_versions.APIVersion(
REPLICA_QUOTAS_MICROVERSION))
if supports_share_replica_quotas:
st_custom_quotas['share_replicas'] = _get_share_type_quota_values(
p_quotas['share_replicas']
)
st_custom_quotas['replica_gigabytes'] = (
_get_share_type_quota_values(p_quotas['replica_gigabytes']))
replica_params = (' --share-replicas %s '
'--replica-gigabytes %s') % (
st_custom_quotas['share_replicas'],
st_custom_quotas['replica_gigabytes'])
# Update quotas for share type
cmd = ('quota-update %s --share-type %s '
@ -194,6 +220,9 @@ class QuotasReadWriteTest(base.BaseTestCase):
st_custom_quotas['gigabytes'],
st_custom_quotas['snapshots'],
st_custom_quotas['snapshot_gigabytes'])
if supports_share_replica_quotas:
cmd += replica_params
self.admin_client.manila(cmd, microversion=microversion)
# Verify share type quotas

View File

@ -20,6 +20,8 @@ from manilaclient import api_versions
from manilaclient.tests.unit import utils
from manilaclient.v2 import quotas
REPLICA_QUOTAS_MICROVERSION = '2.53'
@ddt.ddt
class QuotaSetsTest(utils.TestCase):
@ -104,6 +106,8 @@ class QuotaSetsTest(utils.TestCase):
("2.7", {}), ("2.7", {"force": True}),
("2.38", {}), ("2.38", {"force": True}),
("2.39", {}), ("2.39", {"force": True}),
("2.53", {}), ("2.53", {"force": True, "share_replicas": 8,
"replica_gigabytes": 9}),
)
@ddt.unpack
def test_update_quota(self, microversion, extra_data):
@ -131,7 +135,8 @@ class QuotaSetsTest(utils.TestCase):
manager._update.assert_called_once_with(
expected_url, expected_body, "quota_set")
@ddt.data("2.6", "2.7", "2.38", "2.39", "2.40")
@ddt.data("2.6", "2.7", "2.38", "2.39", "2.40",
REPLICA_QUOTAS_MICROVERSION)
def test_update_user_quota(self, microversion):
tenant_id = 'test'
user_id = 'fake_user'
@ -157,13 +162,22 @@ class QuotaSetsTest(utils.TestCase):
'share_networks': expected_body['quota_set']['share_networks'],
'user_id': user_id,
}
if microversion == '2.40':
if (api_versions.APIVersion(microversion) >=
api_versions.APIVersion('2.40')):
expected_body['quota_set']['share_groups'] = 6
expected_body['quota_set']['share_group_snapshots'] = 7
kwargs['share_groups'] = expected_body['quota_set'][
'share_groups']
kwargs['share_group_snapshots'] = expected_body['quota_set'][
'share_group_snapshots']
if (api_versions.APIVersion(microversion) >=
api_versions.APIVersion(REPLICA_QUOTAS_MICROVERSION)):
expected_body['quota_set']['share_replicas'] = 8
expected_body['quota_set']['replica_gigabytes'] = 9
kwargs['share_replicas'] = expected_body['quota_set'][
'share_replicas']
kwargs['replica_gigabytes'] = expected_body['quota_set'][
'replica_gigabytes']
with mock.patch.object(manager, '_update',
mock.Mock(return_value='fake_update')):
@ -172,11 +186,12 @@ class QuotaSetsTest(utils.TestCase):
manager._update.assert_called_once_with(
expected_url, expected_body, "quota_set")
def test_update_share_type_quota(self):
@ddt.data('2.39', REPLICA_QUOTAS_MICROVERSION)
def test_update_share_type_quota(self, microversion):
tenant_id = 'fake_tenant_id'
share_type = 'fake_share_type'
manager = self._get_manager('2.39')
resource_path = self._get_resource_path('2.39')
manager = self._get_manager(microversion)
resource_path = self._get_resource_path(microversion)
expected_url = "%s/%s?share_type=%s" % (
resource_path, tenant_id, share_type)
expected_body = {
@ -188,11 +203,16 @@ class QuotaSetsTest(utils.TestCase):
'snapshot_gigabytes': 4,
},
}
kwargs = {}
if microversion >= REPLICA_QUOTAS_MICROVERSION:
expected_body['quota_set']['share_replicas'] = 8
expected_body['quota_set']['replica_gigabytes'] = 9
kwargs = {'share_replicas': 8, 'replica_gigabytes': 9}
with mock.patch.object(manager, '_update',
mock.Mock(return_value='fake_update')):
manager.update(
tenant_id, shares=1, snapshots=2, gigabytes=3,
snapshot_gigabytes=4, share_type=share_type)
snapshot_gigabytes=4, share_type=share_type, **kwargs)
manager._update.assert_called_once_with(
expected_url, expected_body, "quota_set")

View File

@ -2379,6 +2379,8 @@ class ShellTest(test_utils.TestCase):
('--share-groups 0', {'share_groups': 0}),
('--share-group-snapshots 13', {'share_group_snapshots': 13}),
('--share-group-snapshots 0', {'share_group_snapshots': 0}),
('--share-replicas 15', {'share_replicas': 15}),
('--replica_gigabytes 100', {'replica_gigabytes': 100}),
)
@ddt.unpack
def test_quota_update(self, cmd, expected_body):

View File

@ -19,6 +19,7 @@ from manilaclient.common.apiclient import base as common_base
RESOURCE_PATH_LEGACY = '/os-quota-class-sets'
RESOURCE_PATH = '/quota-class-sets'
REPLICA_QUOTAS_MICROVERSION = "2.53"
class QuotaClassSet(common_base.Resource):
@ -52,7 +53,8 @@ class QuotaClassSetManager(base.ManagerWithFind):
def _do_update(self, class_name, shares=None, gigabytes=None,
snapshots=None, snapshot_gigabytes=None,
share_networks=None, resource_path=RESOURCE_PATH):
share_networks=None, share_replicas=None,
replica_gigabytes=None, resource_path=RESOURCE_PATH):
body = {
'quota_class_set': {
'class_name': class_name,
@ -61,6 +63,8 @@ class QuotaClassSetManager(base.ManagerWithFind):
'gigabytes': gigabytes,
'snapshot_gigabytes': snapshot_gigabytes,
'share_networks': share_networks,
"share_replicas": share_replicas,
"replica_gigabytes": replica_gigabytes
}
}
@ -78,12 +82,24 @@ class QuotaClassSetManager(base.ManagerWithFind):
def update(self, class_name, shares=None, gigabytes=None,
snapshots=None, snapshot_gigabytes=None, share_networks=None):
return self._do_update(
class_name, shares, gigabytes, snapshots, snapshot_gigabytes,
share_networks, RESOURCE_PATH_LEGACY)
class_name, shares=shares, gigabytes=gigabytes,
snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes,
share_networks=share_networks, resource_path=RESOURCE_PATH_LEGACY)
@api_versions.wraps("2.7") # noqa
@api_versions.wraps("2.7", "2.52") # noqa
def update(self, class_name, shares=None, gigabytes=None,
snapshots=None, snapshot_gigabytes=None, share_networks=None):
return self._do_update(
class_name, shares, gigabytes, snapshots, snapshot_gigabytes,
share_networks, RESOURCE_PATH)
class_name, shares=shares, gigabytes=gigabytes,
snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes,
share_networks=share_networks, resource_path=RESOURCE_PATH)
@api_versions.wraps(REPLICA_QUOTAS_MICROVERSION) # noqa
def update(self, class_name, shares=None, gigabytes=None,
snapshots=None, snapshot_gigabytes=None, share_networks=None,
share_replicas=None, replica_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, resource_path=RESOURCE_PATH)

View File

@ -19,6 +19,7 @@ from manilaclient.common.apiclient import base as common_base
RESOURCE_PATH_LEGACY = '/os-quota-sets'
RESOURCE_PATH = '/quota-sets'
REPLICA_QUOTAS_MICROVERSION = "2.53"
class QuotaSet(common_base.Resource):
@ -93,6 +94,7 @@ class QuotaSetManager(base.ManagerWithFind):
share_networks=None,
force=None, user_id=None, share_type=None,
share_groups=None, share_group_snapshots=None,
share_replicas=None, replica_gigabytes=None,
resource_path=RESOURCE_PATH):
self._check_user_id_and_share_type_args(user_id, share_type)
body = {
@ -106,6 +108,8 @@ class QuotaSetManager(base.ManagerWithFind):
'share_groups': share_groups,
'share_group_snapshots': share_group_snapshots,
'force': force,
'share_replicas': share_replicas,
'replica_gigabytes': replica_gigabytes,
},
}
@ -145,14 +149,17 @@ class QuotaSetManager(base.ManagerWithFind):
share_networks, force, user_id, resource_path=RESOURCE_PATH,
)
@api_versions.wraps("2.39", "2.39") # noqa
def update(self, tenant_id, user_id=None, share_type=None,
shares=None, snapshots=None, gigabytes=None,
snapshot_gigabytes=None, share_networks=None, force=None):
def _validate_st_and_sn_in_same_request(self, share_type, share_networks):
if share_type and share_networks:
raise ValueError(
"'share_networks' quota can be set only for project or user, "
"not share type.")
@api_versions.wraps("2.39", "2.39") # noqa
def update(self, tenant_id, user_id=None, share_type=None,
shares=None, snapshots=None, gigabytes=None,
snapshot_gigabytes=None, share_networks=None, force=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,
@ -160,16 +167,13 @@ class QuotaSetManager(base.ManagerWithFind):
resource_path=RESOURCE_PATH,
)
@api_versions.wraps("2.40") # noqa
@api_versions.wraps("2.40", "2.52") # noqa
def update(self, tenant_id, user_id=None, share_type=None,
shares=None, snapshots=None, gigabytes=None,
snapshot_gigabytes=None, share_networks=None,
share_groups=None, share_group_snapshots=None,
force=None):
if share_type and share_networks:
raise ValueError(
"'share_networks' quota can be set only for project or user, "
"not share type.")
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,
@ -179,6 +183,24 @@ class QuotaSetManager(base.ManagerWithFind):
resource_path=RESOURCE_PATH,
)
@api_versions.wraps(REPLICA_QUOTAS_MICROVERSION) # noqa
def update(self, tenant_id, user_id=None, share_type=None,
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):
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,
resource_path=RESOURCE_PATH
)
@api_versions.wraps("1.0", "2.6")
def defaults(self, tenant_id):
return self._get(

View File

@ -29,7 +29,6 @@ from manilaclient.common.apiclient import utils as apiclient_utils
from manilaclient.common import cliutils
from manilaclient.common import constants
from manilaclient import exceptions
from manilaclient.v2 import quotas
def _poll_for_status(poll_fn, obj_id, action, final_ok_states,
@ -391,10 +390,12 @@ _quota_resources = [
'gigabytes',
'snapshot_gigabytes',
'share_networks',
'share_replicas',
'replica_gigabytes'
]
def _quota_update(manager, identifier, args):
def _quota_class_update(manager, identifier, args):
updates = {}
for resource in _quota_resources:
val = getattr(args, resource, None)
@ -402,15 +403,7 @@ def _quota_update(manager, identifier, args):
updates[resource] = val
if updates:
# default value of force is None to make sure this client
# will be compatible with old nova server
force_update = getattr(args, 'force', None)
user_id = getattr(args, 'user', None)
if isinstance(manager, quotas.QuotaSetManager):
manager.update(identifier, force=force_update, user_id=user_id,
**updates)
else:
manager.update(identifier, **updates)
manager.update(identifier, **updates)
@cliutils.arg(
@ -537,6 +530,23 @@ def do_quota_defaults(cs, args):
help="UUID or name of a share type to set the quotas for. Optional. "
"Mutually exclusive with '--user-id'. "
"Available only for microversion >= 2.39")
@cliutils.arg(
'--share-replicas',
'--share_replicas',
'--replicas',
metavar='<share-replicas>',
type=int,
default=None,
help='New value for the "share_replicas" quota. Available only for '
'microversion >= 2.53')
@cliutils.arg(
'--replica-gigabytes',
'--replica_gigabytes',
metavar='<replica-gigabytes>',
type=int,
default=None,
help='New value for the "replica_gigabytes" quota. Available only for '
'microversion >= 2.53')
@cliutils.arg(
'--force',
dest='force',
@ -570,10 +580,16 @@ def do_quota_update(cs, args):
"'2.40' API microversion.")
elif args.share_type is not None:
raise exceptions.CommandError(
"Share type quotas handle only 'shares', 'gigabytes', "
"'snapshots' and 'snapshot_gigabytes' resources.")
"Share type quotas cannot be used to constrain share groups.")
kwargs["share_groups"] = args.share_groups
kwargs["share_group_snapshots"] = args.share_group_snapshots
if args.share_replicas is not None or args.replica_gigabytes is not None:
if cs.api_version < api_versions.APIVersion("2.53"):
raise exceptions.CommandError(
"'share replica' quotas are available only starting with "
"'2.53' API microversion.")
kwargs["share_replicas"] = args.share_replicas
kwargs["replica_gigabytes"] = args.replica_gigabytes
cs.quotas.update(**kwargs)
@ -665,10 +681,34 @@ def do_quota_class_show(cs, args):
default=None,
action='single_alias',
help='New value for the "share_networks" quota.')
@cliutils.arg(
'--share-replicas',
'--share_replicas', # alias
'--replicas', # alias
metavar='<share-replicas>',
type=int,
default=None,
action='single_alias',
help='New value for the "share_replicas" quota. Available only for '
'microversion >= 2.53')
@cliutils.arg(
'--replica-gigabytes',
'--replica_gigabytes', # alias
metavar='<replica-gigabytes>',
type=int,
default=None,
action='single_alias',
help='New value for the "replica_gigabytes" quota. Available only for '
'microversion >= 2.53')
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:
if cs.api_version < api_versions.APIVersion("2.53"):
raise exceptions.CommandError(
"'share replica' quotas are available only starting with "
"'2.53' API microversion.")
_quota_update(cs.quota_classes, args.class_name, args)
_quota_class_update(cs.quota_classes, args.class_name, args)
def do_absolute_limits(cs, args):

View File

@ -0,0 +1,10 @@
---
features:
- |
Added support for two new quotas for share replicas:
`share_replicas` and `replica_gigabytes`.
upgrade:
- |
Due to the new 'share_replicas' and 'replica_gigabytes' quotas for
share replicas, it is now possible to hit an 'over limit' error
while creating replicated shares and share replicas.