Add share group quotas
Add support for share group quotas implemented on server side [1]. [1] I397a8e886226cb22fa50abdf2a4a938bb04c655d Change-Id: Ib2b12d906c54c05faf8a72ac851d100e25023d50 Implements Blueprint add-share-groups-quota
This commit is contained in:
parent
8045f4d24e
commit
6964524f4c
@ -27,7 +27,7 @@ from manilaclient import utils
|
|||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
MAX_VERSION = '2.39'
|
MAX_VERSION = '2.40'
|
||||||
MIN_VERSION = '2.0'
|
MIN_VERSION = '2.0'
|
||||||
DEPRECATED_VERSION = '1.0'
|
DEPRECATED_VERSION = '1.0'
|
||||||
_VERSIONED_METHOD_MAP = {}
|
_VERSIONED_METHOD_MAP = {}
|
||||||
|
@ -20,6 +20,7 @@ from tempest.lib.cli import output_parser
|
|||||||
from tempest.lib.common.utils import data_utils
|
from tempest.lib.common.utils import data_utils
|
||||||
from tempest.lib import exceptions
|
from tempest.lib import exceptions
|
||||||
|
|
||||||
|
from manilaclient import api_versions
|
||||||
from manilaclient.tests.functional import base
|
from manilaclient.tests.functional import base
|
||||||
from manilaclient.tests.functional import utils
|
from manilaclient.tests.functional import utils
|
||||||
|
|
||||||
@ -54,12 +55,12 @@ class QuotasReadWriteTest(base.BaseTestCase):
|
|||||||
)
|
)
|
||||||
self.st_id = self.share_type["ID"]
|
self.st_id = self.share_type["ID"]
|
||||||
|
|
||||||
def _verify_current_st_quotas_equal_to(self, quotas):
|
def _verify_current_st_quotas_equal_to(self, quotas, microversion):
|
||||||
# Read share type quotas
|
# Read share type quotas
|
||||||
cmd = 'quota-show --tenant-id %s --share-type %s' % (
|
cmd = 'quota-show --tenant-id %s --share-type %s' % (
|
||||||
self.project_id, self.st_id)
|
self.project_id, self.st_id)
|
||||||
st_quotas_raw = self.admin_client.manila(
|
st_quotas_raw = self.admin_client.manila(
|
||||||
cmd, microversion=self.microversion)
|
cmd, microversion=microversion)
|
||||||
st_quotas = output_parser.details(st_quotas_raw)
|
st_quotas = output_parser.details(st_quotas_raw)
|
||||||
|
|
||||||
# Verify that quotas
|
# Verify that quotas
|
||||||
@ -71,11 +72,109 @@ class QuotasReadWriteTest(base.BaseTestCase):
|
|||||||
self.assertIn(key, quotas)
|
self.assertIn(key, quotas)
|
||||||
self.assertEqual(int(quotas[key]), int(value))
|
self.assertEqual(int(quotas[key]), int(value))
|
||||||
|
|
||||||
def test_update_share_type_quotas_positive(self):
|
def _verify_current_quotas_equal_to(self, quotas, microversion):
|
||||||
|
# Read quotas
|
||||||
|
cmd = 'quota-show --tenant-id %s' % self.project_id
|
||||||
|
quotas_raw = self.admin_client.manila(
|
||||||
|
cmd, microversion=microversion)
|
||||||
|
quotas = output_parser.details(quotas_raw)
|
||||||
|
|
||||||
|
# Verify that quotas
|
||||||
|
self.assertGreater(len(quotas), 3)
|
||||||
|
for key, value in quotas.items():
|
||||||
|
if key not in ('shares', 'gigabytes', 'snapshots',
|
||||||
|
'snapshot_gigabytes',
|
||||||
|
'share_groups', 'share_group_snapshots'):
|
||||||
|
continue
|
||||||
|
self.assertIn(key, quotas)
|
||||||
|
self.assertEqual(int(quotas[key]), int(value))
|
||||||
|
|
||||||
|
@ddt.data(*set([
|
||||||
|
"2.40", api_versions.MAX_VERSION,
|
||||||
|
]))
|
||||||
|
def test_update_quotas_for_share_groups(self, microversion):
|
||||||
|
if not utils.is_microversion_supported(microversion):
|
||||||
|
msg = "Microversion '%s' not supported." % microversion
|
||||||
|
raise self.skipException(msg)
|
||||||
|
|
||||||
|
# Get default quotas
|
||||||
|
cmd = 'quota-defaults'
|
||||||
|
quotas_raw = self.admin_client.manila(cmd, microversion=microversion)
|
||||||
|
default_quotas = output_parser.details(quotas_raw)
|
||||||
|
|
||||||
# Get project quotas
|
# Get project quotas
|
||||||
cmd = 'quota-show --tenant-id %s ' % self.project_id
|
cmd = 'quota-show --tenant-id %s ' % self.project_id
|
||||||
quotas_raw = self.admin_client.manila(
|
quotas_raw = self.admin_client.manila(cmd, microversion=microversion)
|
||||||
cmd, microversion=self.microversion)
|
p_quotas = output_parser.details(quotas_raw)
|
||||||
|
|
||||||
|
# Define custom share group quotas for project
|
||||||
|
p_custom_quotas = {
|
||||||
|
'share_groups': -1 if int(p_quotas['share_groups']) != -1 else 999,
|
||||||
|
'share_group_snapshots': -1 if int(
|
||||||
|
p_quotas['share_group_snapshots']) != -1 else 999,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update share group quotas for project
|
||||||
|
cmd = ('quota-update %s --share-groups %s '
|
||||||
|
'--share-group-snapshots %s') % (
|
||||||
|
self.project_id,
|
||||||
|
p_custom_quotas['share_groups'],
|
||||||
|
p_custom_quotas['share_group_snapshots'],
|
||||||
|
)
|
||||||
|
self.admin_client.manila(cmd, microversion=microversion)
|
||||||
|
|
||||||
|
# Verify quotas
|
||||||
|
self._verify_current_quotas_equal_to(p_custom_quotas, microversion)
|
||||||
|
|
||||||
|
# Reset quotas
|
||||||
|
cmd = 'quota-delete --tenant-id %s --share-type %s' % (
|
||||||
|
self.project_id, self.st_id)
|
||||||
|
self.admin_client.manila(cmd, microversion=microversion)
|
||||||
|
|
||||||
|
# Verify quotas after reset
|
||||||
|
self._verify_current_quotas_equal_to(default_quotas, microversion)
|
||||||
|
|
||||||
|
# Return project quotas back
|
||||||
|
cmd = ('quota-update %s --share-groups %s '
|
||||||
|
'--share-group-snapshots %s') % (
|
||||||
|
self.project_id,
|
||||||
|
p_quotas['share_groups'], p_quotas['share_group_snapshots'])
|
||||||
|
self.admin_client.manila(cmd, microversion=microversion)
|
||||||
|
|
||||||
|
# Verify quotas after reset
|
||||||
|
self._verify_current_quotas_equal_to(p_quotas, microversion)
|
||||||
|
|
||||||
|
@ddt.data('--share-groups', '--share-group-snapshots')
|
||||||
|
@utils.skip_if_microversion_not_supported("2.39")
|
||||||
|
def test_update_quotas_for_share_groups_using_too_old_microversion(self,
|
||||||
|
arg):
|
||||||
|
cmd = 'quota-update %s %s 13' % (self.project_id, arg)
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.CommandFailed,
|
||||||
|
self.admin_client.manila,
|
||||||
|
cmd, microversion='2.39')
|
||||||
|
|
||||||
|
@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):
|
||||||
|
cmd = 'quota-update %s --share-type %s %s 13' % (
|
||||||
|
self.project_id, self.st_id, arg)
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.CommandFailed,
|
||||||
|
self.admin_client.manila,
|
||||||
|
cmd, microversion='2.40')
|
||||||
|
|
||||||
|
@ddt.data(*set([
|
||||||
|
"2.39", "2.40", api_versions.MAX_VERSION,
|
||||||
|
]))
|
||||||
|
def test_update_share_type_quotas_positive(self, microversion):
|
||||||
|
if not utils.is_microversion_supported(microversion):
|
||||||
|
msg = "Microversion '%s' not supported." % microversion
|
||||||
|
raise self.skipException(msg)
|
||||||
|
|
||||||
|
# Get project quotas
|
||||||
|
cmd = 'quota-show --tenant-id %s ' % self.project_id
|
||||||
|
quotas_raw = self.admin_client.manila(cmd, microversion=microversion)
|
||||||
p_quotas = output_parser.details(quotas_raw)
|
p_quotas = output_parser.details(quotas_raw)
|
||||||
|
|
||||||
# Define share type quotas
|
# Define share type quotas
|
||||||
@ -96,18 +195,18 @@ class QuotasReadWriteTest(base.BaseTestCase):
|
|||||||
st_custom_quotas['gigabytes'],
|
st_custom_quotas['gigabytes'],
|
||||||
st_custom_quotas['snapshots'],
|
st_custom_quotas['snapshots'],
|
||||||
st_custom_quotas['snapshot_gigabytes'])
|
st_custom_quotas['snapshot_gigabytes'])
|
||||||
self.admin_client.manila(cmd, microversion=self.microversion)
|
self.admin_client.manila(cmd, microversion=microversion)
|
||||||
|
|
||||||
# Verify share type quotas
|
# Verify share type quotas
|
||||||
self._verify_current_st_quotas_equal_to(st_custom_quotas)
|
self._verify_current_st_quotas_equal_to(st_custom_quotas, microversion)
|
||||||
|
|
||||||
# Reset share type quotas
|
# Reset share type quotas
|
||||||
cmd = 'quota-delete --tenant-id %s --share-type %s' % (
|
cmd = 'quota-delete --tenant-id %s --share-type %s' % (
|
||||||
self.project_id, self.st_id)
|
self.project_id, self.st_id)
|
||||||
self.admin_client.manila(cmd, microversion=self.microversion)
|
self.admin_client.manila(cmd, microversion=microversion)
|
||||||
|
|
||||||
# Verify share type quotas after reset
|
# Verify share type quotas after reset
|
||||||
self._verify_current_st_quotas_equal_to(p_quotas)
|
self._verify_current_st_quotas_equal_to(p_quotas, microversion)
|
||||||
|
|
||||||
@utils.skip_if_microversion_not_supported("2.38")
|
@utils.skip_if_microversion_not_supported("2.38")
|
||||||
def test_read_share_type_quotas_with_too_old_microversion(self):
|
def test_read_share_type_quotas_with_too_old_microversion(self):
|
||||||
|
@ -302,6 +302,9 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
|||||||
}
|
}
|
||||||
return (200, {}, instances)
|
return (200, {}, instances)
|
||||||
|
|
||||||
|
def put_quota_sets_1234(self, *args, **kwargs):
|
||||||
|
return (200, {}, {})
|
||||||
|
|
||||||
def get_quota_sets_1234(self, *args, **kwargs):
|
def get_quota_sets_1234(self, *args, **kwargs):
|
||||||
quota_set = {
|
quota_set = {
|
||||||
'quota_set': {
|
'quota_set': {
|
||||||
|
@ -131,7 +131,7 @@ class QuotaSetsTest(utils.TestCase):
|
|||||||
manager._update.assert_called_once_with(
|
manager._update.assert_called_once_with(
|
||||||
expected_url, expected_body, "quota_set")
|
expected_url, expected_body, "quota_set")
|
||||||
|
|
||||||
@ddt.data("2.6", "2.7", "2.38", "2.39")
|
@ddt.data("2.6", "2.7", "2.38", "2.39", "2.40")
|
||||||
def test_update_user_quota(self, microversion):
|
def test_update_user_quota(self, microversion):
|
||||||
tenant_id = 'test'
|
tenant_id = 'test'
|
||||||
user_id = 'fake_user'
|
user_id = 'fake_user'
|
||||||
@ -148,11 +148,26 @@ class QuotaSetsTest(utils.TestCase):
|
|||||||
'share_networks': 5,
|
'share_networks': 5,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
kwargs = {
|
||||||
|
'shares': expected_body['quota_set']['shares'],
|
||||||
|
'snapshots': expected_body['quota_set']['snapshots'],
|
||||||
|
'gigabytes': expected_body['quota_set']['gigabytes'],
|
||||||
|
'snapshot_gigabytes': expected_body['quota_set'][
|
||||||
|
'snapshot_gigabytes'],
|
||||||
|
'share_networks': expected_body['quota_set']['share_networks'],
|
||||||
|
'user_id': user_id,
|
||||||
|
}
|
||||||
|
if microversion == '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']
|
||||||
|
|
||||||
with mock.patch.object(manager, '_update',
|
with mock.patch.object(manager, '_update',
|
||||||
mock.Mock(return_value='fake_update')):
|
mock.Mock(return_value='fake_update')):
|
||||||
manager.update(
|
manager.update(tenant_id, **kwargs)
|
||||||
tenant_id, shares=1, snapshots=2, gigabytes=3,
|
|
||||||
snapshot_gigabytes=4, share_networks=5, user_id=user_id)
|
|
||||||
|
|
||||||
manager._update.assert_called_once_with(
|
manager._update.assert_called_once_with(
|
||||||
expected_url, expected_body, "quota_set")
|
expected_url, expected_body, "quota_set")
|
||||||
|
@ -1804,6 +1804,38 @@ class ShellTest(test_utils.TestCase):
|
|||||||
)
|
)
|
||||||
mock_print_dict.assert_called_once_with(mock.ANY)
|
mock_print_dict.assert_called_once_with(mock.ANY)
|
||||||
|
|
||||||
|
@ddt.data(
|
||||||
|
('--shares 13', {'shares': 13}),
|
||||||
|
('--gigabytes 14', {'gigabytes': 14}),
|
||||||
|
('--snapshots 15', {'snapshots': 15}),
|
||||||
|
('--snapshot-gigabytes 13', {'snapshot_gigabytes': 13}),
|
||||||
|
('--share-networks 13', {'share_networks': 13}),
|
||||||
|
('--share-groups 13', {'share_groups': 13}),
|
||||||
|
('--share-groups 0', {'share_groups': 0}),
|
||||||
|
('--share-group-snapshots 13', {'share_group_snapshots': 13}),
|
||||||
|
('--share-group-snapshots 0', {'share_group_snapshots': 0}),
|
||||||
|
)
|
||||||
|
@ddt.unpack
|
||||||
|
def test_quota_update(self, cmd, expected_body):
|
||||||
|
self.run_command('quota-update 1234 %s' % cmd)
|
||||||
|
|
||||||
|
expected = {'quota_set': expected_body}
|
||||||
|
self.assert_called('PUT', '/quota-sets/1234', body=expected)
|
||||||
|
|
||||||
|
@ddt.data(
|
||||||
|
"quota-update 1234 --share-groups 13 --share-type foo",
|
||||||
|
"quota-update 1234 --share-group-snapshots 14 --share-type bar",
|
||||||
|
("quota-update 1234 --share-groups 13 --share-type foo "
|
||||||
|
"--share-group-snapshots 14"),
|
||||||
|
"--os-share-api-version 2.39 quota-update 1234 --share-groups 13",
|
||||||
|
("--os-share-api-version 2.39 quota-update 1234 "
|
||||||
|
"--share-group-snapshots 13"),
|
||||||
|
("--os-share-api-version 2.38 quota-update 1234 --shares 5 "
|
||||||
|
"--share-type foo"),
|
||||||
|
)
|
||||||
|
def test_quota_update_with_wrong_combinations(self, cmd):
|
||||||
|
self.assertRaises(exceptions.CommandError, self.run_command, cmd)
|
||||||
|
|
||||||
@mock.patch.object(cliutils, 'print_list', mock.Mock())
|
@mock.patch.object(cliutils, 'print_list', mock.Mock())
|
||||||
def test_pool_list_with_detail(self):
|
def test_pool_list_with_detail(self):
|
||||||
self.run_command('pool-list --detail')
|
self.run_command('pool-list --detail')
|
||||||
|
@ -90,8 +90,10 @@ class QuotaSetManager(base.ManagerWithFind):
|
|||||||
|
|
||||||
def _do_update(self, tenant_id, shares=None, snapshots=None,
|
def _do_update(self, tenant_id, shares=None, snapshots=None,
|
||||||
gigabytes=None, snapshot_gigabytes=None,
|
gigabytes=None, snapshot_gigabytes=None,
|
||||||
share_networks=None, force=None, user_id=None,
|
share_networks=None,
|
||||||
share_type=None, resource_path=RESOURCE_PATH):
|
force=None, user_id=None, share_type=None,
|
||||||
|
share_groups=None, share_group_snapshots=None,
|
||||||
|
resource_path=RESOURCE_PATH):
|
||||||
self._check_user_id_and_share_type_args(user_id, share_type)
|
self._check_user_id_and_share_type_args(user_id, share_type)
|
||||||
body = {
|
body = {
|
||||||
'quota_set': {
|
'quota_set': {
|
||||||
@ -101,6 +103,8 @@ class QuotaSetManager(base.ManagerWithFind):
|
|||||||
'gigabytes': gigabytes,
|
'gigabytes': gigabytes,
|
||||||
'snapshot_gigabytes': snapshot_gigabytes,
|
'snapshot_gigabytes': snapshot_gigabytes,
|
||||||
'share_networks': share_networks,
|
'share_networks': share_networks,
|
||||||
|
'share_groups': share_groups,
|
||||||
|
'share_group_snapshots': share_group_snapshots,
|
||||||
'force': force,
|
'force': force,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -141,10 +145,26 @@ class QuotaSetManager(base.ManagerWithFind):
|
|||||||
share_networks, force, user_id, resource_path=RESOURCE_PATH,
|
share_networks, force, user_id, resource_path=RESOURCE_PATH,
|
||||||
)
|
)
|
||||||
|
|
||||||
@api_versions.wraps("2.39") # noqa
|
@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):
|
||||||
|
if share_type and share_networks:
|
||||||
|
raise ValueError(
|
||||||
|
"'share_networks' quota can be set only for project or user, "
|
||||||
|
"not share type.")
|
||||||
|
return self._do_update(
|
||||||
|
tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes,
|
||||||
|
share_networks, force, user_id,
|
||||||
|
share_type=share_type,
|
||||||
|
resource_path=RESOURCE_PATH,
|
||||||
|
)
|
||||||
|
|
||||||
|
@api_versions.wraps("2.40") # noqa
|
||||||
def update(self, tenant_id, user_id=None, share_type=None,
|
def update(self, tenant_id, user_id=None, share_type=None,
|
||||||
shares=None, snapshots=None, gigabytes=None,
|
shares=None, snapshots=None, gigabytes=None,
|
||||||
snapshot_gigabytes=None, share_networks=None,
|
snapshot_gigabytes=None, share_networks=None,
|
||||||
|
share_groups=None, share_group_snapshots=None,
|
||||||
force=None):
|
force=None):
|
||||||
if share_type and share_networks:
|
if share_type and share_networks:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
@ -154,6 +174,8 @@ class QuotaSetManager(base.ManagerWithFind):
|
|||||||
tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes,
|
tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes,
|
||||||
share_networks, force, user_id,
|
share_networks, force, user_id,
|
||||||
share_type=share_type,
|
share_type=share_type,
|
||||||
|
share_groups=share_groups,
|
||||||
|
share_group_snapshots=share_group_snapshots,
|
||||||
resource_path=RESOURCE_PATH,
|
resource_path=RESOURCE_PATH,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -372,13 +372,6 @@ _quota_resources = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def _quota_show(quotas):
|
|
||||||
quota_dict = {}
|
|
||||||
for resource in _quota_resources:
|
|
||||||
quota_dict[resource] = getattr(quotas, resource, None)
|
|
||||||
cliutils.print_dict(quota_dict)
|
|
||||||
|
|
||||||
|
|
||||||
def _quota_update(manager, identifier, args):
|
def _quota_update(manager, identifier, args):
|
||||||
updates = {}
|
updates = {}
|
||||||
for resource in _quota_resources:
|
for resource in _quota_resources:
|
||||||
@ -450,7 +443,7 @@ def do_quota_show(cs, args):
|
|||||||
def do_quota_defaults(cs, args):
|
def do_quota_defaults(cs, args):
|
||||||
"""List the default quotas for a tenant."""
|
"""List the default quotas for a tenant."""
|
||||||
project = args.tenant_id or cs.keystone_client.project_id
|
project = args.tenant_id or cs.keystone_client.project_id
|
||||||
_quota_show(cs.quotas.defaults(project))
|
_quota_set_pretty_show(cs.quotas.defaults(project))
|
||||||
|
|
||||||
|
|
||||||
@cliutils.arg(
|
@cliutils.arg(
|
||||||
@ -497,6 +490,21 @@ def do_quota_defaults(cs, args):
|
|||||||
default=None,
|
default=None,
|
||||||
action='single_alias',
|
action='single_alias',
|
||||||
help='New value for the "share_networks" quota.')
|
help='New value for the "share_networks" quota.')
|
||||||
|
@cliutils.arg(
|
||||||
|
'--share-groups', '--share_groups', '--groups',
|
||||||
|
metavar='<share_groups>',
|
||||||
|
type=int,
|
||||||
|
default=None,
|
||||||
|
action='single_alias',
|
||||||
|
help='New value for the "share_groups" quota.')
|
||||||
|
@cliutils.arg(
|
||||||
|
'--share-group-snapshots', '--share_group_snapshots',
|
||||||
|
'--group-snapshots', '--group_snapshots',
|
||||||
|
metavar='<share_group_snapshots>',
|
||||||
|
type=int,
|
||||||
|
default=None,
|
||||||
|
action='single_alias',
|
||||||
|
help='New value for the "share_group_snapshots" quota.')
|
||||||
@cliutils.arg(
|
@cliutils.arg(
|
||||||
'--share-type',
|
'--share-type',
|
||||||
'--share_type',
|
'--share_type',
|
||||||
@ -533,6 +541,17 @@ def do_quota_update(cs, args):
|
|||||||
"'share type' quotas are available only starting with "
|
"'share type' quotas are available only starting with "
|
||||||
"'2.39' API microversion.")
|
"'2.39' API microversion.")
|
||||||
kwargs["share_type"] = args.share_type
|
kwargs["share_type"] = args.share_type
|
||||||
|
if args.share_groups is not None or args.share_group_snapshots is not None:
|
||||||
|
if cs.api_version < api_versions.APIVersion("2.40"):
|
||||||
|
raise exceptions.CommandError(
|
||||||
|
"'share group' quotas are available only starting with "
|
||||||
|
"'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.")
|
||||||
|
kwargs["share_groups"] = args.share_groups
|
||||||
|
kwargs["share_group_snapshots"] = args.share_group_snapshots
|
||||||
cs.quotas.update(**kwargs)
|
cs.quotas.update(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@ -583,7 +602,7 @@ def do_quota_delete(cs, args):
|
|||||||
def do_quota_class_show(cs, args):
|
def do_quota_class_show(cs, args):
|
||||||
"""List the quotas for a quota class."""
|
"""List the quotas for a quota class."""
|
||||||
|
|
||||||
_quota_show(cs.quota_classes.get(args.class_name))
|
_quota_set_pretty_show(cs.quota_classes.get(args.class_name))
|
||||||
|
|
||||||
|
|
||||||
@cliutils.arg(
|
@cliutils.arg(
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Added support for share group and share group snapshot quotas.
|
||||||
|
upgrade:
|
||||||
|
- After addition of share group and share group snapshot quotas, it is now
|
||||||
|
possible to get 'over limit' error creating share groups and share group
|
||||||
|
snapshots.
|
Loading…
x
Reference in New Issue
Block a user