Merge "[policy in code] Add support for qos and quota resources"
This commit is contained in:
commit
d961c1e08c
@ -26,6 +26,7 @@ from cinder.api.openstack import wsgi
|
||||
from cinder.api.views import qos_specs as view_qos_specs
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder.policies import qos_specs as policy
|
||||
from cinder import rpc
|
||||
from cinder import utils
|
||||
from cinder.volume import qos_specs
|
||||
@ -33,17 +34,6 @@ from cinder.volume import qos_specs
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
authorize_create = extensions.extension_authorizer('volume',
|
||||
'qos_specs_manage:create')
|
||||
authorize_get = extensions.extension_authorizer('volume',
|
||||
'qos_specs_manage:get')
|
||||
authorize_get_all = extensions.extension_authorizer('volume',
|
||||
'qos_specs_manage:get_all')
|
||||
authorize_update = extensions.extension_authorizer('volume',
|
||||
'qos_specs_manage:update')
|
||||
authorize_delete = extensions.extension_authorizer('volume',
|
||||
'qos_specs_manage:delete')
|
||||
|
||||
|
||||
def _check_specs(context, specs_id):
|
||||
# Not found exception will be handled at the wsgi level
|
||||
@ -65,7 +55,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
def index(self, req):
|
||||
"""Returns the list of qos_specs."""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_get_all(context)
|
||||
context.authorize(policy.GET_ALL_POLICY)
|
||||
|
||||
params = req.params.copy()
|
||||
|
||||
@ -84,7 +74,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
|
||||
def create(self, req, body=None):
|
||||
context = req.environ['cinder.context']
|
||||
authorize_create(context)
|
||||
context.authorize(policy.CREATE_POLICY)
|
||||
|
||||
self.assert_valid_body(body, 'qos_specs')
|
||||
|
||||
@ -128,7 +118,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
|
||||
def update(self, req, id, body=None):
|
||||
context = req.environ['cinder.context']
|
||||
authorize_update(context)
|
||||
context.authorize(policy.UPDATE_POLICY)
|
||||
|
||||
self.assert_valid_body(body, 'qos_specs')
|
||||
specs = body['qos_specs']
|
||||
@ -158,7 +148,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
def show(self, req, id):
|
||||
"""Return a single qos spec item."""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_get(context)
|
||||
context.authorize(policy.GET_POLICY)
|
||||
|
||||
# Not found exception will be handled at the wsgi level
|
||||
spec = qos_specs.get_qos_specs(context, id)
|
||||
@ -168,7 +158,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
def delete(self, req, id):
|
||||
"""Deletes an existing qos specs."""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_delete(context)
|
||||
context.authorize(policy.DELETE_POLICY)
|
||||
|
||||
# Convert string to bool type in strict manner
|
||||
force = utils.get_bool_param('force', req.params)
|
||||
@ -204,7 +194,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
def delete_keys(self, req, id, body):
|
||||
"""Deletes specified keys in qos specs."""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_delete(context)
|
||||
context.authorize(policy.DELETE_POLICY)
|
||||
|
||||
if not (body and 'keys' in body
|
||||
and isinstance(body.get('keys'), list)):
|
||||
@ -232,7 +222,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
def associations(self, req, id):
|
||||
"""List all associations of given qos specs."""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_get_all(context)
|
||||
context.authorize(policy.GET_ALL_POLICY)
|
||||
|
||||
LOG.debug("Get associations for qos_spec id: %s", id)
|
||||
|
||||
@ -262,7 +252,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
def associate(self, req, id):
|
||||
"""Associate a qos specs with a volume type."""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_update(context)
|
||||
context.authorize(policy.UPDATE_POLICY)
|
||||
|
||||
type_id = req.params.get('vol_type_id', None)
|
||||
|
||||
@ -311,7 +301,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
def disassociate(self, req, id):
|
||||
"""Disassociate a qos specs from a volume type."""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_update(context)
|
||||
context.authorize(policy.UPDATE_POLICY)
|
||||
|
||||
type_id = req.params.get('vol_type_id', None)
|
||||
|
||||
@ -351,7 +341,7 @@ class QoSSpecsController(wsgi.Controller):
|
||||
def disassociate_all(self, req, id):
|
||||
"""Disassociate a qos specs from all volume types."""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_update(context)
|
||||
context.authorize(policy.UPDATE_POLICY)
|
||||
|
||||
LOG.debug("Disassociate qos_spec: %s from all.", id)
|
||||
|
||||
|
@ -19,6 +19,7 @@ from cinder.api import extensions
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
from cinder.policies import quota_class as policy
|
||||
from cinder import quota
|
||||
from cinder import utils
|
||||
|
||||
@ -27,9 +28,6 @@ QUOTAS = quota.QUOTAS
|
||||
GROUP_QUOTAS = quota.GROUP_QUOTAS
|
||||
|
||||
|
||||
authorize = extensions.extension_authorizer('volume', 'quota_classes')
|
||||
|
||||
|
||||
class QuotaClassSetsController(wsgi.Controller):
|
||||
|
||||
def _format_quota_set(self, quota_class, quota_set):
|
||||
@ -41,7 +39,7 @@ class QuotaClassSetsController(wsgi.Controller):
|
||||
|
||||
def show(self, req, id):
|
||||
context = req.environ['cinder.context']
|
||||
authorize(context)
|
||||
context.authorize(policy.MANAGE_POLICY)
|
||||
try:
|
||||
db.sqlalchemy.api.authorize_quota_class_context(context, id)
|
||||
except exception.NotAuthorized:
|
||||
@ -54,7 +52,7 @@ class QuotaClassSetsController(wsgi.Controller):
|
||||
|
||||
def update(self, req, id, body):
|
||||
context = req.environ['cinder.context']
|
||||
authorize(context)
|
||||
context.authorize(policy.MANAGE_POLICY)
|
||||
self.validate_string_length(id, 'quota_class_name',
|
||||
min_length=1, max_length=255)
|
||||
|
||||
|
@ -24,6 +24,7 @@ from cinder import db
|
||||
from cinder.db.sqlalchemy import api as sqlalchemy_api
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder.policies import quotas as policy
|
||||
from cinder import quota
|
||||
from cinder import quota_utils
|
||||
from cinder import utils
|
||||
@ -34,10 +35,6 @@ QUOTAS = quota.QUOTAS
|
||||
GROUP_QUOTAS = quota.GROUP_QUOTAS
|
||||
NON_QUOTA_KEYS = ['tenant_id', 'id']
|
||||
|
||||
authorize_update = extensions.extension_authorizer('volume', 'quotas:update')
|
||||
authorize_show = extensions.extension_authorizer('volume', 'quotas:show')
|
||||
authorize_delete = extensions.extension_authorizer('volume', 'quotas:delete')
|
||||
|
||||
|
||||
class QuotaSetsController(wsgi.Controller):
|
||||
|
||||
@ -169,7 +166,7 @@ class QuotaSetsController(wsgi.Controller):
|
||||
:param id: target project id that needs to be shown
|
||||
"""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_show(context)
|
||||
context.authorize(policy.SHOW_POLICY)
|
||||
params = req.params
|
||||
target_project_id = id
|
||||
|
||||
@ -212,7 +209,7 @@ class QuotaSetsController(wsgi.Controller):
|
||||
the resources if the update succeeds
|
||||
"""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_update(context)
|
||||
context.authorize(policy.UPDATE_POLICY)
|
||||
self.validate_string_length(id, 'quota_set_name',
|
||||
min_length=1, max_length=255)
|
||||
|
||||
@ -354,7 +351,7 @@ class QuotaSetsController(wsgi.Controller):
|
||||
|
||||
def defaults(self, req, id):
|
||||
context = req.environ['cinder.context']
|
||||
authorize_show(context)
|
||||
context.authorize(policy.SHOW_POLICY)
|
||||
defaults = QUOTAS.get_defaults(context, project_id=id)
|
||||
group_defaults = GROUP_QUOTAS.get_defaults(context, project_id=id)
|
||||
defaults.update(group_defaults)
|
||||
@ -371,7 +368,7 @@ class QuotaSetsController(wsgi.Controller):
|
||||
:param id: target project id that needs to be deleted
|
||||
"""
|
||||
context = req.environ['cinder.context']
|
||||
authorize_delete(context)
|
||||
context.authorize(policy.DELETE_POLICY)
|
||||
|
||||
if QUOTAS.using_nested_quotas():
|
||||
self._delete_nested_quota(context, id)
|
||||
@ -440,6 +437,7 @@ class QuotaSetsController(wsgi.Controller):
|
||||
no child quota would be larger than it's parent).
|
||||
"""
|
||||
ctxt = req.environ['cinder.context']
|
||||
ctxt.authorize(policy.VALIDATE_NESTED_QUOTA_POLICY)
|
||||
params = req.params
|
||||
try:
|
||||
resources = QUOTAS.resources
|
||||
|
@ -27,6 +27,9 @@ from cinder.policies import group_types
|
||||
from cinder.policies import groups
|
||||
from cinder.policies import manageable_snapshots
|
||||
from cinder.policies import messages
|
||||
from cinder.policies import qos_specs
|
||||
from cinder.policies import quota_class
|
||||
from cinder.policies import quotas
|
||||
from cinder.policies import snapshot_actions
|
||||
from cinder.policies import snapshot_metadata
|
||||
from cinder.policies import snapshots
|
||||
@ -51,4 +54,7 @@ def list_rules():
|
||||
group_snapshots.list_rules(),
|
||||
group_snapshot_actions.list_rules(),
|
||||
group_actions.list_rules(),
|
||||
qos_specs.list_rules(),
|
||||
quota_class.list_rules(),
|
||||
quotas.list_rules(),
|
||||
)
|
||||
|
103
cinder/policies/qos_specs.py
Normal file
103
cinder/policies/qos_specs.py
Normal file
@ -0,0 +1,103 @@
|
||||
# Copyright (c) 2017 Huawei Technologies Co., Ltd.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
from cinder.policies import base
|
||||
|
||||
|
||||
CREATE_POLICY = 'volume_extension:qos_specs_manage:create'
|
||||
GET_POLICY = 'volume_extension:qos_specs_manage:get'
|
||||
GET_ALL_POLICY = 'volume_extension:qos_specs_manage:get_all'
|
||||
UPDATE_POLICY = 'volume_extension:qos_specs_manage:update'
|
||||
DELETE_POLICY = 'volume_extension:qos_specs_manage:delete'
|
||||
|
||||
|
||||
qos_specs_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
name=GET_ALL_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="List qos specs or list all associations.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/qos-specs'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/qos-specs/{qos_id}/associations'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=GET_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Show qos specs.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/qos-specs/{qos_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=CREATE_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Create qos specs.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/qos-specs'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=UPDATE_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Update qos specs (including updating association).",
|
||||
operations=[
|
||||
{
|
||||
'method': 'PUT',
|
||||
'path': '/qos-specs/{qos_id}'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/qos-specs/{qos_id}/disassociate_all'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/qos-specs/{qos_id}/associate'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/qos-specs/{qos_id}/disassociate'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=DELETE_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="delete qos specs or unset one specified qos key.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/qos-specs/{qos_id}'
|
||||
},
|
||||
{
|
||||
'method': 'PUT',
|
||||
'path': '/qos-specs/{qos_id}/delete_keys'
|
||||
}
|
||||
])
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return qos_specs_policies
|
43
cinder/policies/quota_class.py
Normal file
43
cinder/policies/quota_class.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2017 Huawei Technologies Co., Ltd.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
from cinder.policies import base
|
||||
|
||||
|
||||
MANAGE_POLICY = 'volume_extension:quota_classes'
|
||||
|
||||
|
||||
quota_class_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
name=MANAGE_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Show or update project quota class.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/os-quota-class-sets/{project_id}'
|
||||
},
|
||||
{
|
||||
'method': 'PUT',
|
||||
'path': '/os-quota-class-sets/{project_id}'
|
||||
}
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return quota_class_policies
|
81
cinder/policies/quotas.py
Normal file
81
cinder/policies/quotas.py
Normal file
@ -0,0 +1,81 @@
|
||||
# Copyright (c) 2017 Huawei Technologies Co., Ltd.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
from cinder.policies import base
|
||||
|
||||
|
||||
SHOW_POLICY = 'volume_extension:quotas:show'
|
||||
UPDATE_POLICY = 'volume_extension:quotas:update'
|
||||
DELETE_POLICY = 'volume_extension:quotas:delete'
|
||||
VALIDATE_NESTED_QUOTA_POLICY = \
|
||||
'volume_extension:quota_classes:validate_setup_for_nested_quota_use'
|
||||
|
||||
|
||||
quota_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
name=SHOW_POLICY,
|
||||
check_str="",
|
||||
description="Show project quota (including usage and default).",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/os-quota-sets/{project_id}'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/os-quota-sets/{project_id}/default'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/os-quota-sets/{project_id}?usage=True'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=UPDATE_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Update project quota.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'PUT',
|
||||
'path': '/os-quota-sets/{project_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=DELETE_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Delete project quota.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/os-quota-sets/{project_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=VALIDATE_NESTED_QUOTA_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Validate setup for nested quota.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/os-quota-sets/validate_setup_for_nested_quota_use'
|
||||
}
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return quota_policies
|
@ -63,21 +63,12 @@
|
||||
"volume_extension:volume_type_access:removeProjectAccess": "rule:admin_api",
|
||||
"volume_extension:volume_type_encryption": "rule:admin_api",
|
||||
"volume_extension:volume_encryption_metadata": "rule:admin_or_owner",
|
||||
"volume_extension:qos_specs_manage:create": "rule:admin_api",
|
||||
"volume_extension:qos_specs_manage:get": "rule:admin_api",
|
||||
"volume_extension:qos_specs_manage:get_all": "rule:admin_api",
|
||||
"volume_extension:qos_specs_manage:update": "rule:admin_api",
|
||||
"volume_extension:qos_specs_manage:delete": "rule:admin_api",
|
||||
"volume_extension:extended_snapshot_attributes": "",
|
||||
"volume_extension:volume_image_metadata": "",
|
||||
"volume_extension:volume_host_attribute": "rule:admin_api",
|
||||
"volume_extension:volume_tenant_attribute": "rule:admin_api",
|
||||
"volume_extension:volume_mig_status_attribute": "rule:admin_api",
|
||||
"volume_extension:hosts": "rule:admin_api",
|
||||
"volume_extension:quotas:show": "",
|
||||
"volume_extension:quotas:update": "rule:admin_api",
|
||||
"volume_extension:quotas:delete": "rule:admin_api",
|
||||
"volume_extension:quota_classes": "rule:admin_api",
|
||||
"volume_extension:services:index": "",
|
||||
"volume_extension:services:update" : "rule:admin_api",
|
||||
"volume_extension:volume_manage": "rule:admin_api",
|
||||
|
@ -33,18 +33,6 @@
|
||||
"volume_extension:volume_encryption_metadata": "rule:admin_or_owner",
|
||||
"volume_extension:volume_image_metadata": "rule:admin_or_owner",
|
||||
|
||||
"volume_extension:qos_specs_manage:create": "rule:admin_api",
|
||||
"volume_extension:qos_specs_manage:get": "rule:admin_api",
|
||||
"volume_extension:qos_specs_manage:get_all": "rule:admin_api",
|
||||
"volume_extension:qos_specs_manage:update": "rule:admin_api",
|
||||
"volume_extension:qos_specs_manage:delete": "rule:admin_api",
|
||||
|
||||
"volume_extension:quotas:show": "",
|
||||
"volume_extension:quotas:update": "rule:admin_api",
|
||||
"volume_extension:quotas:delete": "rule:admin_api",
|
||||
"volume_extension:quota_classes": "rule:admin_api",
|
||||
"volume_extension:quota_classes:validate_setup_for_nested_quota_use": "rule:admin_api",
|
||||
|
||||
"volume_extension:volume_admin_actions:reset_status": "rule:admin_api",
|
||||
"volume_extension:volume_admin_actions:force_delete": "rule:admin_api",
|
||||
"volume_extension:volume_admin_actions:force_detach": "rule:admin_api",
|
||||
|
Loading…
x
Reference in New Issue
Block a user