[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 import exception
from cinder.i18n import _ from cinder.i18n import _
from cinder import objects from cinder import objects
from cinder.policies import clusters as policy
from cinder import utils from cinder import utils
@ -28,13 +29,12 @@ class ClusterController(wsgi.Controller):
'frozen', 'active_backend_id'} 'frozen', 'active_backend_id'}
replication_fields = {'replication_status', '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) @wsgi.Controller.api_version(mv.CLUSTER_SUPPORT)
def show(self, req, id, binary='cinder-volume'): def show(self, req, id, binary='cinder-volume'):
"""Return data for a given cluster name with optional binary.""" """Return data for a given cluster name with optional binary."""
# Let the wsgi middleware convert NotAuthorized exceptions # 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 # Let the wsgi middleware convert NotFound exceptions
cluster = objects.Cluster.get_by_id(context, None, binary=binary, cluster = objects.Cluster.get_by_id(context, None, binary=binary,
name=id, services_summary=True) name=id, services_summary=True)
@ -60,7 +60,8 @@ class ClusterController(wsgi.Controller):
def _get_clusters(self, req, detail): def _get_clusters(self, req, detail):
# Let the wsgi middleware convert NotAuthorized exceptions # 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( replication_data = req.api_version_request.matches(
mv.REPLICATION_CLUSTER) mv.REPLICATION_CLUSTER)
filters = dict(req.GET) filters = dict(req.GET)
@ -93,7 +94,8 @@ class ClusterController(wsgi.Controller):
# update endpoint API. # update endpoint API.
# Let the wsgi middleware convert NotAuthorized exceptions # 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'): if id not in ('enable', 'disable'):
raise exception.NotFound(message=_("Unknown action")) 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 api as message_api
from cinder.message import defined_messages from cinder.message import defined_messages
from cinder.message import message_field from cinder.message import message_field
import cinder.policy from cinder.policies import messages as 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)
class MessagesController(wsgi.Controller): class MessagesController(wsgi.Controller):
@ -68,7 +57,7 @@ class MessagesController(wsgi.Controller):
# Not found exception will be handled at the wsgi level # Not found exception will be handled at the wsgi level
message = self.message_api.get(context, id) message = self.message_api.get(context, id)
check_policy(context, 'get', message) context.authorize(policy.GET_POLICY)
self._build_user_message(message) self._build_user_message(message)
return self._view_builder.detail(req, 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 # Not found exception will be handled at the wsgi level
message = self.message_api.get(context, id) 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) self.message_api.delete(context, message)
return webob.Response(status_int=http_client.NO_CONTENT) 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.""" """Returns a list of messages, transformed through view builder."""
context = req.environ['cinder.context'] context = req.environ['cinder.context']
api_version = req.api_version_request api_version = req.api_version_request
check_policy(context, 'get_all') context.authorize(policy.GET_ALL_POLICY)
filters = None filters = None
marker = None marker = None
limit = None limit = None

View File

@ -24,6 +24,7 @@ from cinder import exception
from cinder.i18n import _ from cinder.i18n import _
from cinder import objects from cinder import objects
from cinder.objects import cleanable from cinder.objects import cleanable
from cinder.policies import workers as policy
from cinder.scheduler import rpcapi as sch_rpc from cinder.scheduler import rpcapi as sch_rpc
from cinder import utils from cinder import utils
@ -33,8 +34,6 @@ class WorkerController(wsgi.Controller):
'is_up', 'disabled', 'resource_id', 'resource_type', 'is_up', 'disabled', 'resource_id', 'resource_type',
'until'} 'until'}
policy_checker = wsgi.Controller.get_policy_checker('workers')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.sch_api = sch_rpc.SchedulerAPI() self.sch_api = sch_rpc.SchedulerAPI()
@ -104,7 +103,8 @@ class WorkerController(wsgi.Controller):
def cleanup(self, req, body=None): def cleanup(self, req, body=None):
"""Do the cleanup on resources from a specific service/host/node.""" """Do the cleanup on resources from a specific service/host/node."""
# Let the wsgi middleware convert NotAuthorized exceptions # 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 {} body = body or {}
params = self._prepare_params(ctxt, body, self.allowed_clean_keys) 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 attachments
from cinder.policies import base from cinder.policies import base
from cinder.policies import clusters
from cinder.policies import messages
from cinder.policies import workers
def list_rules(): def list_rules():
return itertools.chain( return itertools.chain(
base.list_rules(), 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", "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", "group:list_replication_targets": "rule:admin_or_owner",
"scheduler_extension:scheduler_stats:get_pools" : "rule:admin_api", "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"
} }