[policy in code] Add support for message, worker, cluster resources

This patch adds policy in code support for message, worker
and cluster resources and depends on the basic patch [1].

[1]: https://review.openstack.org/#/c/506976/

Change-Id: I04c0b79175c69d25ca6fcb50ec604123f3f09933
Partial-Implements: blueprint policy-in-code
This commit is contained in:
TommyLike 2017-09-27 14:56:06 +08:00
parent 43a3152581
commit c52b7ef584
9 changed files with 186 additions and 41 deletions

View File

@ -19,6 +19,7 @@ from cinder.api.v3.views import clusters as clusters_view
from cinder import exception
from cinder.i18n import _
from cinder import objects
from cinder.policies import clusters as policy
from cinder import utils
@ -28,13 +29,12 @@ class ClusterController(wsgi.Controller):
'frozen', 'active_backend_id'}
replication_fields = {'replication_status', 'frozen', 'active_backend_id'}
policy_checker = wsgi.Controller.get_policy_checker('clusters')
@wsgi.Controller.api_version(mv.CLUSTER_SUPPORT)
def show(self, req, id, binary='cinder-volume'):
"""Return data for a given cluster name with optional binary."""
# Let the wsgi middleware convert NotAuthorized exceptions
context = self.policy_checker(req, 'get')
context = req.environ['cinder.context']
context.authorize(policy.GET_POLICY)
# Let the wsgi middleware convert NotFound exceptions
cluster = objects.Cluster.get_by_id(context, None, binary=binary,
name=id, services_summary=True)
@ -60,7 +60,8 @@ class ClusterController(wsgi.Controller):
def _get_clusters(self, req, detail):
# Let the wsgi middleware convert NotAuthorized exceptions
context = self.policy_checker(req, 'get_all')
context = req.environ['cinder.context']
context.authorize(policy.GET_ALL_POLICY)
replication_data = req.api_version_request.matches(
mv.REPLICATION_CLUSTER)
filters = dict(req.GET)
@ -93,7 +94,8 @@ class ClusterController(wsgi.Controller):
# update endpoint API.
# Let the wsgi middleware convert NotAuthorized exceptions
context = self.policy_checker(req, 'update')
context = req.environ['cinder.context']
context.authorize(policy.UPDATE_POLICY)
if id not in ('enable', 'disable'):
raise exception.NotFound(message=_("Unknown action"))

View File

@ -23,18 +23,7 @@ from cinder.api.v3.views import messages as messages_view
from cinder.message import api as message_api
from cinder.message import defined_messages
from cinder.message import message_field
import cinder.policy
def check_policy(context, action, target_obj=None):
target = {
'project_id': context.project_id,
'user_id': context.user_id,
}
target.update(target_obj or {})
_action = 'message:%s' % action
cinder.policy.enforce(context, _action, target)
from cinder.policies import messages as policy
class MessagesController(wsgi.Controller):
@ -68,7 +57,7 @@ class MessagesController(wsgi.Controller):
# Not found exception will be handled at the wsgi level
message = self.message_api.get(context, id)
check_policy(context, 'get', message)
context.authorize(policy.GET_POLICY)
self._build_user_message(message)
return self._view_builder.detail(req, message)
@ -80,7 +69,7 @@ class MessagesController(wsgi.Controller):
# Not found exception will be handled at the wsgi level
message = self.message_api.get(context, id)
check_policy(context, 'delete', message)
context.authorize(policy.DELETE_POLICY, target_obj=message)
self.message_api.delete(context, message)
return webob.Response(status_int=http_client.NO_CONTENT)
@ -90,7 +79,7 @@ class MessagesController(wsgi.Controller):
"""Returns a list of messages, transformed through view builder."""
context = req.environ['cinder.context']
api_version = req.api_version_request
check_policy(context, 'get_all')
context.authorize(policy.GET_ALL_POLICY)
filters = None
marker = None
limit = None

View File

@ -24,6 +24,7 @@ from cinder import exception
from cinder.i18n import _
from cinder import objects
from cinder.objects import cleanable
from cinder.policies import workers as policy
from cinder.scheduler import rpcapi as sch_rpc
from cinder import utils
@ -33,8 +34,6 @@ class WorkerController(wsgi.Controller):
'is_up', 'disabled', 'resource_id', 'resource_type',
'until'}
policy_checker = wsgi.Controller.get_policy_checker('workers')
def __init__(self, *args, **kwargs):
self.sch_api = sch_rpc.SchedulerAPI()
@ -104,7 +103,8 @@ class WorkerController(wsgi.Controller):
def cleanup(self, req, body=None):
"""Do the cleanup on resources from a specific service/host/node."""
# Let the wsgi middleware convert NotAuthorized exceptions
ctxt = self.policy_checker(req, 'cleanup')
ctxt = req.environ['cinder.context']
ctxt.authorize(policy.CLEAN_POLICY)
body = body or {}
params = self._prepare_params(ctxt, body, self.allowed_clean_keys)

View File

@ -17,10 +17,16 @@ import itertools
from cinder.policies import attachments
from cinder.policies import base
from cinder.policies import clusters
from cinder.policies import messages
from cinder.policies import workers
def list_rules():
return itertools.chain(
base.list_rules(),
attachments.list_rules()
attachments.list_rules(),
messages.list_rules(),
clusters.list_rules(),
workers.list_rules()
)

View File

@ -0,0 +1,65 @@
# 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
GET_POLICY = 'clusters:get'
GET_ALL_POLICY = 'clusters:get_all'
UPDATE_POLICY = 'clusters:update'
clusters_policies = [
policy.DocumentedRuleDefault(
name=GET_ALL_POLICY,
check_str=base.RULE_ADMIN_API,
description="""List clusters.""",
operations=[
{
'method': 'GET',
'path': '/clusters'
},
{
'method': 'GET',
'path': '/clusters/detail'
}
]),
policy.DocumentedRuleDefault(
name=GET_POLICY,
check_str=base.RULE_ADMIN_API,
description="""Show cluster.""",
operations=[
{
'method': 'GET',
'path': '/clusters/{cluster_id}'
}
]),
policy.DocumentedRuleDefault(
name=UPDATE_POLICY,
check_str=base.RULE_ADMIN_API,
description="""Update cluster.""",
operations=[
{
'method': 'PUT',
'path': '/clusters/{cluster_id}'
}
]),
]
def list_rules():
return clusters_policies

View File

@ -0,0 +1,61 @@
# 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
DELETE_POLICY = 'message:delete'
GET_POLICY = 'message:get'
GET_ALL_POLICY = 'message:get_all'
messages_policies = [
policy.DocumentedRuleDefault(
name=GET_ALL_POLICY,
check_str=base.RULE_ADMIN_OR_OWNER,
description="""List messages.""",
operations=[
{
'method': 'GET',
'path': '/messages'
}
]),
policy.DocumentedRuleDefault(
name=GET_POLICY,
check_str=base.RULE_ADMIN_OR_OWNER,
description="""Show message.""",
operations=[
{
'method': 'GET',
'path': '/messages/{message_id}'
}
]),
policy.DocumentedRuleDefault(
name=DELETE_POLICY,
check_str=base.RULE_ADMIN_OR_OWNER,
description="""Delete message.""",
operations=[
{
'method': 'DELETE',
'path': '/messages/{message_id}'
}
]),
]
def list_rules():
return messages_policies

View File

@ -0,0 +1,39 @@
# 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
CLEAN_POLICY = 'workers:cleanup'
workers_policies = [
policy.DocumentedRuleDefault(
name=CLEAN_POLICY,
check_str=base.RULE_ADMIN_API,
description="""Clean up workers.""",
operations=[
{
'method': 'POST',
'path': '/workers/cleanup'
}
])
]
def list_rules():
return workers_policies

View File

@ -149,13 +149,4 @@
"scheduler_extension:scheduler_stats:get_pools" : "rule:admin_api",
"message:delete": "rule:admin_or_owner",
"message:get": "rule:admin_or_owner",
"message:get_all": "rule:admin_or_owner",
"clusters:get": "rule:admin_api",
"clusters:get_all": "rule:admin_api",
"clusters:update": "rule:admin_api",
"workers:cleanup": "rule:admin_api"
}

View File

@ -141,13 +141,5 @@
"group:list_replication_targets": "rule:admin_or_owner",
"scheduler_extension:scheduler_stats:get_pools" : "rule:admin_api",
"message:delete": "rule:admin_or_owner",
"message:get": "rule:admin_or_owner",
"message:get_all": "rule:admin_or_owner",
"clusters:get": "rule:admin_api",
"clusters:get_all": "rule:admin_api",
"clusters:update": "rule:admin_api",
"workers:cleanup": "rule:admin_api"
}