Allow setting quota of other tenants
Currently, the quota API/CLI allows users to set quotas for current tenant only. However, admin users needs the ability to set quota for other tenants. For example: $ source /opt/stack/devstack/openrc admin admin $ openstack appcontainer quota update --containers 100 <DEMO_TENANT_UUID> Depends-On: https://review.openstack.org/627075 Change-Id: Ia147575d3e8d2c6d54bddd98846f0c9e3e518ec3 Related-Bug: #1807620
This commit is contained in:
parent
77046229b8
commit
eedf5c7fdd
@ -52,6 +52,10 @@ class UpdateQuota(command.ShowOne):
|
||||
metavar='<disk>',
|
||||
help='The number of gigabytes of container Disk '
|
||||
'allowed per project')
|
||||
parser.add_argument(
|
||||
'project_id',
|
||||
metavar='<project_id>',
|
||||
help='The UUID of project in a multi-project cloud')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@ -61,7 +65,7 @@ class UpdateQuota(command.ShowOne):
|
||||
opts['memory'] = parsed_args.memory
|
||||
opts['cpu'] = parsed_args.cpu
|
||||
opts['disk'] = parsed_args.disk
|
||||
quota = client.quotas.update(**opts)
|
||||
quota = client.quotas.update(parsed_args.project_id, **opts)
|
||||
columns = _quota_columns(quota)
|
||||
return columns, utils.get_item_properties(quota, columns)
|
||||
|
||||
@ -77,11 +81,17 @@ class GetQuota(command.ShowOne):
|
||||
'--usages',
|
||||
action='store_true',
|
||||
help='Whether show quota usage statistic or not')
|
||||
parser.add_argument(
|
||||
'project_id',
|
||||
metavar='<project_id>',
|
||||
help='The UUID of project in a multi-project cloud')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = _get_client(self, parsed_args)
|
||||
quota = client.quotas.get(usages=parsed_args.usages)
|
||||
quota = client.quotas.get(
|
||||
parsed_args.project_id,
|
||||
usages=parsed_args.usages)
|
||||
columns = _quota_columns(quota)
|
||||
return columns, utils.get_item_properties(quota, columns)
|
||||
|
||||
@ -91,9 +101,17 @@ class GetDefaultQuota(command.ShowOne):
|
||||
|
||||
log = logging.getLogger(__name__ + '.GetDefeaultQuota')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GetDefaultQuota, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'project_id',
|
||||
metavar='<project_id>',
|
||||
help='The UUID of project in a multi-project cloud')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = _get_client(self, parsed_args)
|
||||
default_quota = client.quotas.defaults()
|
||||
default_quota = client.quotas.defaults(parsed_args.project_id)
|
||||
columns = _quota_columns(default_quota)
|
||||
return columns, utils.get_item_properties(
|
||||
default_quota, columns)
|
||||
@ -104,10 +122,18 @@ class DeleteQuota(command.Command):
|
||||
|
||||
log = logging.getLogger(__name__ + '.DeleteQuota')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteQuota, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'project_id',
|
||||
metavar='<project_id>',
|
||||
help='The UUID of project in a multi-project cloud')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = _get_client(self, parsed_args)
|
||||
try:
|
||||
client.quotas.delete()
|
||||
client.quotas.delete(parsed_args.project_id)
|
||||
print(_('Request to delete quotas has been accepted.'))
|
||||
except Exception as e:
|
||||
print("Delete for quotas failed: %(e)s" % {'e': e})
|
||||
|
@ -40,7 +40,7 @@ MODIFIED_USAGE_QUOTAS = {
|
||||
}
|
||||
|
||||
fake_responses = {
|
||||
'/v1/quotas':
|
||||
'/v1/quotas/test_project_id':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
@ -55,14 +55,14 @@ fake_responses = {
|
||||
None
|
||||
)
|
||||
},
|
||||
'/v1/quotas/defaults':
|
||||
'/v1/quotas/test_project_id/defaults':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
DEFAULT_QUOTAS
|
||||
)
|
||||
},
|
||||
'/v1/quotas?usages=True':
|
||||
'/v1/quotas/test_project_id?usages=True':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
@ -80,9 +80,9 @@ class QuotaManagerTest(testtools.TestCase):
|
||||
self.mgr = quotas.QuotaManager(self.api)
|
||||
|
||||
def test_quotas_get_defaults(self):
|
||||
quotas = self.mgr.defaults()
|
||||
quotas = self.mgr.defaults('test_project_id')
|
||||
expect = [
|
||||
('GET', '/v1/quotas/defaults', {}, None)
|
||||
('GET', '/v1/quotas/test_project_id/defaults', {}, None)
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(quotas.containers, DEFAULT_QUOTAS['containers'])
|
||||
|
@ -22,16 +22,18 @@ class QuotaManager(base.Manager):
|
||||
resource_class = Quota
|
||||
|
||||
@staticmethod
|
||||
def _path():
|
||||
def _path(project_id):
|
||||
if project_id is not None:
|
||||
return '/v1/quotas/{}'.format(project_id)
|
||||
return '/v1/quotas'
|
||||
|
||||
def get(self, **kwargs):
|
||||
def get(self, project_id, **kwargs):
|
||||
if not kwargs.get('usages'):
|
||||
kwargs = {}
|
||||
return self._list(self._path(), qparams=kwargs)[0]
|
||||
return self._list(self._path(project_id), qparams=kwargs)[0]
|
||||
|
||||
def update(self, containers=None, memory=None,
|
||||
cpu=None, disk=None):
|
||||
def update(self, project_id, containers=None,
|
||||
memory=None, cpu=None, disk=None):
|
||||
resources = {}
|
||||
if cpu is not None:
|
||||
resources['cpu'] = cpu
|
||||
@ -41,10 +43,10 @@ class QuotaManager(base.Manager):
|
||||
resources['containers'] = containers
|
||||
if disk is not None:
|
||||
resources['disk'] = disk
|
||||
return self._update(self._path(), resources, method='PUT')
|
||||
return self._update(self._path(project_id), resources, method='PUT')
|
||||
|
||||
def defaults(self):
|
||||
return self._list(self._path() + '/defaults')[0]
|
||||
def defaults(self, project_id):
|
||||
return self._list(self._path(project_id) + '/defaults')[0]
|
||||
|
||||
def delete(self):
|
||||
return self._delete(self._path())
|
||||
def delete(self, project_id):
|
||||
return self._delete(self._path(project_id))
|
||||
|
@ -33,9 +33,14 @@ from zunclient.common import cliutils as utils
|
||||
metavar='<disk>',
|
||||
type=int,
|
||||
help='The number of gigabytes of container Disk allowed per project')
|
||||
@utils.arg(
|
||||
'project_id',
|
||||
metavar='<project_id>',
|
||||
help='The UUID of project in a multi-project cloud')
|
||||
def do_quota_update(cs, args):
|
||||
"""Print an updated quotas for a project"""
|
||||
utils.print_dict(cs.quotas.update(containers=args.containers,
|
||||
utils.print_dict(cs.quotas.update(args.project_id,
|
||||
containers=args.containers,
|
||||
memory=args.memory,
|
||||
cpu=args.cpu,
|
||||
disk=args.disk)._info)
|
||||
@ -46,20 +51,34 @@ def do_quota_update(cs, args):
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Whether show quota usage statistic or not')
|
||||
@utils.arg(
|
||||
'project_id',
|
||||
metavar='<project_id>',
|
||||
help='The UUID of project in a multi-project cloud')
|
||||
def do_quota_get(cs, args):
|
||||
"""Print a quotas for a project with usages (optional)"""
|
||||
if args.usages:
|
||||
utils.print_dict(cs.quotas.get(usages=args.usages)._info,
|
||||
value_fields=('limit', 'in_use'))
|
||||
utils.print_dict(
|
||||
cs.quotas.get(args.project_id, usages=args.usages)._info,
|
||||
value_fields=('limit', 'in_use'))
|
||||
else:
|
||||
utils.print_dict(cs.quotas.get(usages=args.usages)._info)
|
||||
utils.print_dict(
|
||||
cs.quotas.get(args.project_id, usages=args.usages)._info)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'project_id',
|
||||
metavar='<project_id>',
|
||||
help='The UUID of project in a multi-project cloud')
|
||||
def do_quota_defaults(cs, args):
|
||||
"""Print a default quotas for a project"""
|
||||
utils.print_dict(cs.quotas.defaults()._info)
|
||||
utils.print_dict(cs.quotas.defaults(args.project_id)._info)
|
||||
|
||||
|
||||
@utils.arg(
|
||||
'project_id',
|
||||
metavar='<project_id>',
|
||||
help='The UUID of project in a multi-project cloud')
|
||||
def do_quota_delete(cs, args):
|
||||
"""Delete quotas for a project"""
|
||||
cs.quotas.delete()
|
||||
cs.quotas.delete(args.project_id)
|
||||
|
Loading…
Reference in New Issue
Block a user