summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2019-11-01 19:16:15 +0000
committerGerrit Code Review <review@openstack.org>2019-11-01 19:16:15 +0000
commitbe583164cbf97aaf4e7cb9bd496bf740f43aa542 (patch)
tree1286c1f4d57c57af6460f654c39c263b02bd9b64
parentb5a8a2ca18a6a3dd3e1bbe9ac2b9b167b99e7b4d (diff)
parent492cf46f63c829ec722c0b8fb06de678e85afc5e (diff)
downloadcinder-stable/ocata.tar.gz
Merge "Add Generic Volume Group Into Quota Management" into stable/ocataocata-eolstable/ocata
-rw-r--r--cinder/api/contrib/quota_classes.py17
-rw-r--r--cinder/api/contrib/quotas.py31
-rw-r--r--cinder/quota_utils.py9
-rw-r--r--cinder/tests/unit/api/contrib/test_quotas.py5
-rw-r--r--cinder/tests/unit/api/contrib/test_quotas_classes.py7
-rw-r--r--releasenotes/notes/generic-group-quota-manage-support-559629ad07a406f4.yaml3
6 files changed, 55 insertions, 17 deletions
diff --git a/cinder/api/contrib/quota_classes.py b/cinder/api/contrib/quota_classes.py
index a694d856c..bffd1a56f 100644
--- a/cinder/api/contrib/quota_classes.py
+++ b/cinder/api/contrib/quota_classes.py
@@ -25,6 +25,7 @@ from cinder import utils
QUOTAS = quota.QUOTAS
+GROUP_QUOTAS = quota.GROUP_QUOTAS
authorize = extensions.extension_authorizer('volume', 'quota_classes')
@@ -46,9 +47,11 @@ class QuotaClassSetsController(wsgi.Controller):
db.sqlalchemy.api.authorize_quota_class_context(context, id)
except exception.NotAuthorized:
raise webob.exc.HTTPForbidden()
+ quota_set = QUOTAS.get_class_quotas(context, id)
+ group_quota_set = GROUP_QUOTAS.get_class_quotas(context, id)
+ quota_set.update(group_quota_set)
- return self._format_quota_set(id,
- QUOTAS.get_class_quotas(context, id))
+ return self._format_quota_set(id, quota_set)
def update(self, req, id, body):
context = req.environ['cinder.context']
@@ -63,7 +66,7 @@ class QuotaClassSetsController(wsgi.Controller):
raise webob.exc.HTTPBadRequest(explanation=msg)
for key, value in body['quota_class_set'].items():
- if key in QUOTAS:
+ if key in QUOTAS or key in GROUP_QUOTAS:
try:
value = utils.validate_integer(value, key, min_value=-1,
max_value=db.MAX_INT)
@@ -72,8 +75,12 @@ class QuotaClassSetsController(wsgi.Controller):
db.quota_class_create(context, quota_class, key, value)
except exception.AdminRequired:
raise webob.exc.HTTPForbidden()
- return {'quota_class_set': QUOTAS.get_class_quotas(context,
- quota_class)}
+
+ quota_set = QUOTAS.get_class_quotas(context, quota_class)
+ group_quota_set = GROUP_QUOTAS.get_class_quotas(context, quota_class)
+ quota_set.update(group_quota_set)
+
+ return {'quota_class_set': quota_set}
class Quota_classes(extensions.ExtensionDescriptor):
diff --git a/cinder/api/contrib/quotas.py b/cinder/api/contrib/quotas.py
index 1dbe8201f..334426eed 100644
--- a/cinder/api/contrib/quotas.py
+++ b/cinder/api/contrib/quotas.py
@@ -28,6 +28,7 @@ from cinder import quota_utils
from cinder import utils
QUOTAS = quota.QUOTAS
+GROUP_QUOTAS = quota.GROUP_QUOTAS
NON_QUOTA_KEYS = ['tenant_id', 'id']
authorize_update = extensions.extension_authorizer('volume', 'quotas:update')
@@ -63,6 +64,9 @@ class QuotaSetsController(wsgi.Controller):
def _get_quotas(self, context, id, usages=False):
values = QUOTAS.get_project_quotas(context, id, usages=usages)
+ group_values = GROUP_QUOTAS.get_project_quotas(context, id,
+ usages=usages)
+ values.update(group_values)
if usages:
return values
@@ -225,7 +229,8 @@ class QuotaSetsController(wsgi.Controller):
# NOTE(ankit): Pass #1 - In this loop for body['quota_set'].items(),
# we figure out if we have any bad keys.
for key, value in body['quota_set'].items():
- if (key not in QUOTAS and key not in NON_QUOTA_KEYS):
+ if (key not in QUOTAS and key not in GROUP_QUOTAS and key not in
+ NON_QUOTA_KEYS):
bad_keys.append(key)
continue
@@ -259,6 +264,10 @@ class QuotaSetsController(wsgi.Controller):
# resources.
quota_values = QUOTAS.get_project_quotas(context, target_project_id,
defaults=False)
+ group_quota_values = GROUP_QUOTAS.get_project_quotas(context,
+ target_project_id,
+ defaults=False)
+ quota_values.update(group_quota_values)
valid_quotas = {}
reservations = []
for key in body['quota_set'].keys():
@@ -326,17 +335,20 @@ class QuotaSetsController(wsgi.Controller):
res_change = new_quota_from_target_proj - orig_quota_from_target_proj
if res_change != 0:
deltas = {res: res_change}
+ resources = QUOTAS.resources
+ resources.update(GROUP_QUOTAS.resources)
reservations += quota_utils.update_alloc_to_next_hard_limit(
- ctxt, QUOTAS.resources, deltas, res, None, target_project.id)
+ ctxt, resources, deltas, res, None, target_project.id)
return reservations
def defaults(self, req, id):
context = req.environ['cinder.context']
authorize_show(context)
-
- return self._format_quota_set(id, QUOTAS.get_defaults(
- context, project_id=id))
+ defaults = QUOTAS.get_defaults(context, project_id=id)
+ group_defaults = GROUP_QUOTAS.get_defaults(context, project_id=id)
+ defaults.update(group_defaults)
+ return self._format_quota_set(id, defaults)
def delete(self, req, id):
"""Delete Quota for a particular tenant.
@@ -366,6 +378,9 @@ class QuotaSetsController(wsgi.Controller):
try:
project_quotas = QUOTAS.get_project_quotas(
ctxt, proj_id, usages=True, defaults=False)
+ project_group_quotas = GROUP_QUOTAS.get_project_quotas(
+ ctxt, proj_id, usages=True, defaults=False)
+ project_quotas.update(project_group_quotas)
except exception.NotAuthorized:
raise webob.exc.HTTPForbidden()
@@ -382,6 +397,7 @@ class QuotaSetsController(wsgi.Controller):
parent_id)
defaults = QUOTAS.get_defaults(ctxt, proj_id)
+ defaults.update(GROUP_QUOTAS.get_defaults(ctxt, proj_id))
# If the project which is being deleted has allocated part of its
# quota to its subprojects, then subprojects' quotas should be
# deleted first.
@@ -416,8 +432,11 @@ class QuotaSetsController(wsgi.Controller):
ctxt = req.environ['cinder.context']
params = req.params
try:
+ resources = QUOTAS.resources
+ resources.update(GROUP_QUOTAS.resources)
+
quota_utils.validate_setup_for_nested_quota_use(
- ctxt, QUOTAS.resources, quota.NestedDbQuotaDriver(),
+ ctxt, resources, quota.NestedDbQuotaDriver(),
fix_allocated_quotas=params.get('fix_allocated_quotas'))
except exception.InvalidNestedQuotaSetup as e:
raise webob.exc.HTTPBadRequest(explanation=e.msg)
diff --git a/cinder/quota_utils.py b/cinder/quota_utils.py
index eee4ddf28..0425b6f0c 100644
--- a/cinder/quota_utils.py
+++ b/cinder/quota_utils.py
@@ -147,6 +147,7 @@ def update_alloc_to_next_hard_limit(context, resources, deltas, res,
expire, project_id):
from cinder import quota
QUOTAS = quota.QUOTAS
+ GROUP_QUOTAS = quota.GROUP_QUOTAS
reservations = []
projects = get_project_hierarchy(context, project_id,
parents_as_ids=True).parents
@@ -156,8 +157,12 @@ def update_alloc_to_next_hard_limit(context, resources, deltas, res,
while projects and not hard_limit_found:
cur_proj_id = list(projects)[0]
projects = projects[cur_proj_id]
- cur_quota_lim = QUOTAS.get_by_project_or_default(
- context, cur_proj_id, res)
+ if res == 'groups':
+ cur_quota_lim = GROUP_QUOTAS.get_by_project_or_default(
+ context, cur_proj_id, res)
+ else:
+ cur_quota_lim = QUOTAS.get_by_project_or_default(
+ context, cur_proj_id, res)
hard_limit_found = (cur_quota_lim != -1)
cur_quota = {res: cur_quota_lim}
cur_delta = {res: deltas[res]}
diff --git a/cinder/tests/unit/api/contrib/test_quotas.py b/cinder/tests/unit/api/contrib/test_quotas.py
index cf499136f..8753fa476 100644
--- a/cinder/tests/unit/api/contrib/test_quotas.py
+++ b/cinder/tests/unit/api/contrib/test_quotas.py
@@ -43,13 +43,14 @@ CONF = cfg.CONF
def make_body(root=True, gigabytes=1000, snapshots=10,
volumes=10, backups=10, backup_gigabytes=1000,
- tenant_id=fake.PROJECT_ID, per_volume_gigabytes=-1):
+ tenant_id=fake.PROJECT_ID, per_volume_gigabytes=-1, groups=10):
resources = {'gigabytes': gigabytes,
'snapshots': snapshots,
'volumes': volumes,
'backups': backups,
'backup_gigabytes': backup_gigabytes,
- 'per_volume_gigabytes': per_volume_gigabytes, }
+ 'per_volume_gigabytes': per_volume_gigabytes,
+ 'groups': groups}
# need to consider preexisting volume types as well
volume_types = db.volume_type_get_all(context.get_admin_context())
diff --git a/cinder/tests/unit/api/contrib/test_quotas_classes.py b/cinder/tests/unit/api/contrib/test_quotas_classes.py
index 945f693cb..d0b158702 100644
--- a/cinder/tests/unit/api/contrib/test_quotas_classes.py
+++ b/cinder/tests/unit/api/contrib/test_quotas_classes.py
@@ -33,19 +33,21 @@ from cinder.volume import volume_types
QUOTAS = quota.QUOTAS
+GROUP_QUOTAS = quota.GROUP_QUOTAS
def make_body(root=True, gigabytes=1000, snapshots=10,
volumes=10, backups=10,
backup_gigabytes=1000, per_volume_gigabytes=-1,
volume_types_faked=None,
- tenant_id=fake.PROJECT_ID):
+ tenant_id=fake.PROJECT_ID, groups=10):
resources = {'gigabytes': gigabytes,
'snapshots': snapshots,
'volumes': volumes,
'backups': backups,
'per_volume_gigabytes': per_volume_gigabytes,
- 'backup_gigabytes': backup_gigabytes}
+ 'backup_gigabytes': backup_gigabytes,
+ 'groups': groups}
if not volume_types_faked:
volume_types_faked = {'fake_type': None}
for volume_type in volume_types_faked:
@@ -68,6 +70,7 @@ def make_response_body(root=True, ctxt=None, quota_class='foo',
if not ctxt:
ctxt = context.get_admin_context()
resources.update(QUOTAS.get_class_quotas(ctxt, quota_class))
+ resources.update(GROUP_QUOTAS.get_class_quotas(ctxt, quota_class))
if not request_body and not request_body['quota_class_set']:
resources.update(request_body['quota_class_set'])
diff --git a/releasenotes/notes/generic-group-quota-manage-support-559629ad07a406f4.yaml b/releasenotes/notes/generic-group-quota-manage-support-559629ad07a406f4.yaml
new file mode 100644
index 000000000..cc058ac78
--- /dev/null
+++ b/releasenotes/notes/generic-group-quota-manage-support-559629ad07a406f4.yaml
@@ -0,0 +1,3 @@
+---
+features:
+ - Generic group is added into quota management.