Added support of per-tenant-user quotas
Added new keys '--user' in v1.shell to quota-show, quota-update. Added command quota-delete, that provides ability for admins to be able to delete a non-default quota (absolute limit) for a tenant or user, so that tenant's quota will revert back to the configured default. Added 'responce_key' parameter to Manager._update function Added '--force' parameter to quota-update to support new functionality on server Fixes help output, when in 'manila help' was displayed only first string of command documentation Implement bp: user-quota-support Change-Id: Ibfe9ccf83ea43d5af6652342f1fe6a88c78a0364
This commit is contained in:
parent
c6fa2fcf4b
commit
e5562354e4
@ -157,10 +157,14 @@ class Manager(utils.HookableMixin):
|
||||
def _delete(self, url):
|
||||
resp, body = self.api.client.delete(url)
|
||||
|
||||
def _update(self, url, body, **kwargs):
|
||||
def _update(self, url, body, response_key=None, **kwargs):
|
||||
self.run_hooks('modify_body_for_update', body, **kwargs)
|
||||
resp, body = self.api.client.put(url, body=body)
|
||||
return body
|
||||
if body:
|
||||
if response_key:
|
||||
return self.resource_class(self, body[response_key])
|
||||
else:
|
||||
return self.resource_class(self, body)
|
||||
|
||||
|
||||
class ManagerWithFind(Manager):
|
||||
|
@ -274,7 +274,7 @@ class OpenStackManilaShell(object):
|
||||
command = attr[3:].replace('_', '-')
|
||||
callback = getattr(actions_module, attr)
|
||||
desc = callback.__doc__ or ''
|
||||
help = desc.strip().split('\n')[0]
|
||||
help = desc.strip()
|
||||
arguments = getattr(callback, 'arguments', [])
|
||||
|
||||
subparser = subparsers.add_parser(
|
||||
|
@ -30,25 +30,42 @@ class QuotaSet(base.Resource):
|
||||
class QuotaSetManager(base.ManagerWithFind):
|
||||
resource_class = QuotaSet
|
||||
|
||||
def get(self, tenant_id):
|
||||
def get(self, tenant_id, user_id=None):
|
||||
if hasattr(tenant_id, 'tenant_id'):
|
||||
tenant_id = tenant_id.tenant_id
|
||||
return self._get("/os-quota-sets/%s" % (tenant_id), "quota_set")
|
||||
if user_id:
|
||||
url = "/os-quota-sets/%s?user_id=%s" % (tenant_id, user_id)
|
||||
else:
|
||||
url = "/os-quota-sets/%s" % tenant_id
|
||||
return self._get(url, "quota_set")
|
||||
|
||||
def update(self, tenant_id, shares=None, snapshots=None, gigabytes=None):
|
||||
def update(self, tenant_id, shares=None, snapshots=None, gigabytes=None,
|
||||
force=None, user_id=None):
|
||||
|
||||
body = {'quota_set': {
|
||||
'tenant_id': tenant_id,
|
||||
'shares': shares,
|
||||
'snapshots': snapshots,
|
||||
'gigabytes': gigabytes}}
|
||||
'gigabytes': gigabytes,
|
||||
'force': force}}
|
||||
|
||||
for key in body['quota_set'].keys():
|
||||
if body['quota_set'][key] is None:
|
||||
body['quota_set'].pop(key)
|
||||
if user_id:
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
else:
|
||||
url = '/os-quota-sets/%s' % tenant_id
|
||||
|
||||
self._update('/os-quota-sets/%s' % (tenant_id), body)
|
||||
return self._update(url, body, 'quota_set')
|
||||
|
||||
def defaults(self, tenant_id):
|
||||
return self._get('/os-quota-sets/%s/defaults' % tenant_id,
|
||||
'quota_set')
|
||||
|
||||
def delete(self, tenant_id, user_id=None):
|
||||
if user_id:
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
else:
|
||||
url = '/os-quota-sets/%s' % tenant_id
|
||||
self._delete(url)
|
||||
|
@ -19,6 +19,7 @@ import sys
|
||||
import time
|
||||
|
||||
from manilaclient import exceptions
|
||||
from manilaclient.v1 import quotas
|
||||
from manilaclient import utils
|
||||
|
||||
|
||||
@ -126,20 +127,32 @@ def _quota_update(manager, identifier, args):
|
||||
updates[resource] = val
|
||||
|
||||
if updates:
|
||||
manager.update(identifier, **updates)
|
||||
# default value of force is None to make sure this client
|
||||
# will be compatibile 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)
|
||||
|
||||
|
||||
@utils.arg('--tenant',
|
||||
metavar='<tenant-id>',
|
||||
default=None,
|
||||
help='ID of tenant to list the quotas for.')
|
||||
@utils.arg('--user',
|
||||
metavar='<user-id>',
|
||||
default=None,
|
||||
help='ID of user to list the quotas for.')
|
||||
def do_quota_show(cs, args):
|
||||
"""List the quotas for a tenant/user."""
|
||||
|
||||
if not args.tenant:
|
||||
_quota_show(cs.quotas.get(cs.client.tenant_id))
|
||||
_quota_show(cs.quotas.get(cs.client.tenant_id, user_id=args.user))
|
||||
else:
|
||||
_quota_show(cs.quotas.get(args.tenant))
|
||||
_quota_show(cs.quotas.get(args.tenant, user_id=args.user))
|
||||
|
||||
|
||||
@utils.arg('--tenant',
|
||||
@ -158,6 +171,10 @@ def do_quota_defaults(cs, args):
|
||||
@utils.arg('tenant',
|
||||
metavar='<tenant_id>',
|
||||
help='UUID of tenant to set the quotas for.')
|
||||
@utils.arg('--user',
|
||||
metavar='<user-id>',
|
||||
default=None,
|
||||
help='ID of user to set the quotas for.')
|
||||
@utils.arg('--shares',
|
||||
metavar='<shares>',
|
||||
type=int, default=None,
|
||||
@ -170,13 +187,36 @@ def do_quota_defaults(cs, args):
|
||||
metavar='<gigabytes>',
|
||||
type=int, default=None,
|
||||
help='New value for the "gigabytes" quota.')
|
||||
@utils.arg('--force',
|
||||
dest='force',
|
||||
action="store_true",
|
||||
default=None,
|
||||
help='Whether force update the quota even if the already used'
|
||||
' and reserved exceeds the new quota')
|
||||
@utils.service_type('share')
|
||||
def do_quota_update(cs, args):
|
||||
"""Update the quotas for a tenant."""
|
||||
"""Update the quotas for a tenant/user."""
|
||||
|
||||
_quota_update(cs.quotas, args.tenant, args)
|
||||
|
||||
|
||||
@utils.arg('--tenant',
|
||||
metavar='<tenant-id>',
|
||||
help='ID of tenant to delete quota for.')
|
||||
@utils.arg('--user',
|
||||
metavar='<user-id>',
|
||||
help='ID of user to delete quota for.')
|
||||
def do_quota_delete(cs, args):
|
||||
"""Delete quota for a tenant/user so their quota will Revert
|
||||
back to default.
|
||||
"""
|
||||
|
||||
if not args.tenant:
|
||||
cs.quotas.delete(cs.client.tenant_id, user_id=args.user)
|
||||
else:
|
||||
cs.quotas.delete(args.tenant, user_id=args.user)
|
||||
|
||||
|
||||
@utils.arg('class_name',
|
||||
metavar='<class>',
|
||||
help='Name of quota class to list the quotas for.')
|
||||
|
@ -127,6 +127,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
'snapshots': 2,
|
||||
'gigabytes': 1}})
|
||||
|
||||
def delete_os_quota_sets_test(self, **kw):
|
||||
return (202, {}, {})
|
||||
#
|
||||
# List all extensions
|
||||
#
|
||||
|
@ -27,6 +27,13 @@ class QuotaSetsTest(utils.TestCase):
|
||||
cs.quotas.get(tenant_id)
|
||||
cs.assert_called('GET', '/os-quota-sets/%s' % tenant_id)
|
||||
|
||||
def test_user_quotas_get(self):
|
||||
tenant_id = 'test'
|
||||
user_id = 'fake_user'
|
||||
cs.quotas.get(tenant_id, user_id=user_id)
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
cs.assert_called('GET', url)
|
||||
|
||||
def test_tenant_quotas_defaults(self):
|
||||
tenant_id = 'test'
|
||||
cs.quotas.defaults(tenant_id)
|
||||
@ -38,6 +45,36 @@ class QuotaSetsTest(utils.TestCase):
|
||||
q.update(snapshots=2)
|
||||
cs.assert_called('PUT', '/os-quota-sets/test')
|
||||
|
||||
def test_update_user_quota(self):
|
||||
tenant_id = 'test'
|
||||
user_id = 'fake_user'
|
||||
q = cs.quotas.get(tenant_id)
|
||||
q.update(shares=2, user_id=user_id)
|
||||
q.update(snapshots=2, user_id=user_id)
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
cs.assert_called('PUT', url)
|
||||
|
||||
def test_force_update_quota(self):
|
||||
q = cs.quotas.get('test')
|
||||
q.update(shares=2, force=True)
|
||||
cs.assert_called(
|
||||
'PUT', '/os-quota-sets/test',
|
||||
{'quota_set': {'force': True,
|
||||
'shares': 2,
|
||||
'tenant_id': 'test'}})
|
||||
|
||||
def test_quotas_delete(self):
|
||||
tenant_id = 'test'
|
||||
cs.quotas.delete(tenant_id)
|
||||
cs.assert_called('DELETE', '/os-quota-sets/%s' % tenant_id)
|
||||
|
||||
def test_user_quotas_delete(self):
|
||||
tenant_id = 'test'
|
||||
user_id = 'fake_user'
|
||||
cs.quotas.delete(tenant_id, user_id=user_id)
|
||||
url = '/os-quota-sets/%s?user_id=%s' % (tenant_id, user_id)
|
||||
cs.assert_called('DELETE', url)
|
||||
|
||||
def test_refresh_quota(self):
|
||||
q = cs.quotas.get('test')
|
||||
q2 = cs.quotas.get('test')
|
||||
|
Loading…
x
Reference in New Issue
Block a user