[policy in code] Add support for backup resource
This patch adds policy in code support for backup resources and depends on the basic patch [1]. [1]: https://review.openstack.org/#/c/506976/ Change-Id: I9a79b5ececc587e80129cc980930e168e805b139 Partial-Implements: blueprint policy-in-code
This commit is contained in:
parent
274ce06f58
commit
1462d9c2e4
@ -79,10 +79,10 @@ class AdminController(wsgi.Controller):
|
||||
return update
|
||||
|
||||
def authorize(self, context, action_name):
|
||||
# NOTE(tommylikehu): We have two different ways to authorize during
|
||||
# TODO(tommylike): We have two different ways to authorize during
|
||||
# implementing code base policies, the if/else statement can be
|
||||
# removed when all resources are upgraded.
|
||||
if self.resource_name in ['snapshot']:
|
||||
if self.resource_name in ['backup', 'snapshot']:
|
||||
context.authorize(
|
||||
'volume_extension:%(resource)s_admin_actions:%(action)s' %
|
||||
{'resource': self.resource_name,
|
||||
|
@ -22,9 +22,9 @@ from cinder.api.contrib import backups as backups_v2
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import backups as backup_views
|
||||
from cinder.backup import api as backup_api
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder.policies import backups as policy
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -81,7 +81,7 @@ class BackupsController(backups_v2.BackupsController):
|
||||
resp_backup = self._view_builder.detail(req, backup)
|
||||
if req_version.matches(mv.BACKUP_PROJECT):
|
||||
try:
|
||||
backup_api.check_policy(context, 'backup_project_attribute')
|
||||
context.authorize(policy.BACKUP_ATTRIBUTES_POLICY)
|
||||
self._add_backup_project_attribute(req, resp_backup['backup'])
|
||||
except exception.PolicyNotAuthorized:
|
||||
pass
|
||||
@ -94,7 +94,7 @@ class BackupsController(backups_v2.BackupsController):
|
||||
|
||||
if req_version.matches(mv.BACKUP_PROJECT):
|
||||
try:
|
||||
backup_api.check_policy(context, 'backup_project_attribute')
|
||||
context.authorize(policy.BACKUP_ATTRIBUTES_POLICY)
|
||||
for bak in resp_backup['backups']:
|
||||
self._add_backup_project_attribute(req, bak)
|
||||
except exception.PolicyNotAuthorized:
|
||||
|
@ -36,6 +36,7 @@ from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import objects
|
||||
from cinder.objects import fields
|
||||
from cinder.policies import backups as policy
|
||||
import cinder.policy
|
||||
from cinder import quota
|
||||
from cinder import quota_utils
|
||||
@ -56,15 +57,6 @@ QUOTAS = quota.QUOTAS
|
||||
IMPORT_VOLUME_ID = '00000000-0000-0000-0000-000000000000'
|
||||
|
||||
|
||||
def check_policy(context, action):
|
||||
target = {
|
||||
'project_id': context.project_id,
|
||||
'user_id': context.user_id,
|
||||
}
|
||||
_action = 'backup:%s' % action
|
||||
cinder.policy.enforce(context, _action, target)
|
||||
|
||||
|
||||
class API(base.Base):
|
||||
"""API for interacting with the volume backup manager."""
|
||||
|
||||
@ -74,7 +66,7 @@ class API(base.Base):
|
||||
super(API, self).__init__(db)
|
||||
|
||||
def get(self, context, backup_id):
|
||||
check_policy(context, 'get')
|
||||
context.authorize(policy.GET_POLICY)
|
||||
return objects.Backup.get_by_id(context, backup_id)
|
||||
|
||||
def _check_support_to_force_delete(self, context, backup_host):
|
||||
@ -93,7 +85,7 @@ class API(base.Base):
|
||||
:raises BackupDriverException:
|
||||
:raises ServiceNotFound:
|
||||
"""
|
||||
check_policy(context, 'delete')
|
||||
context.authorize(policy.DELETE_POLICY)
|
||||
if not force and backup.status not in [fields.BackupStatus.AVAILABLE,
|
||||
fields.BackupStatus.ERROR]:
|
||||
msg = _('Backup status must be available or error')
|
||||
@ -118,7 +110,7 @@ class API(base.Base):
|
||||
|
||||
def get_all(self, context, search_opts=None, marker=None, limit=None,
|
||||
offset=None, sort_keys=None, sort_dirs=None):
|
||||
check_policy(context, 'get_all')
|
||||
context.authorize(policy.GET_ALL_POLICY)
|
||||
|
||||
search_opts = search_opts or {}
|
||||
|
||||
@ -204,7 +196,7 @@ class API(base.Base):
|
||||
container, incremental=False, availability_zone=None,
|
||||
force=False, snapshot_id=None, metadata=None):
|
||||
"""Make the RPC call to create a volume backup."""
|
||||
check_policy(context, 'create')
|
||||
context.authorize(policy.CREATE_POLICY)
|
||||
utils.check_metadata_properties(metadata)
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
snapshot = None
|
||||
@ -341,7 +333,7 @@ class API(base.Base):
|
||||
|
||||
def restore(self, context, backup_id, volume_id=None, name=None):
|
||||
"""Make the RPC call to restore a volume backup."""
|
||||
check_policy(context, 'restore')
|
||||
context.authorize(policy.RESTORE_POLICY)
|
||||
backup = self.get(context, backup_id)
|
||||
if backup['status'] != fields.BackupStatus.AVAILABLE:
|
||||
msg = _('Backup status must be available')
|
||||
@ -444,7 +436,7 @@ class API(base.Base):
|
||||
:returns: contains 'backup_url' and 'backup_service'
|
||||
:raises InvalidBackup:
|
||||
"""
|
||||
check_policy(context, 'backup-export')
|
||||
context.authorize(policy.EXPORT_POLICY)
|
||||
backup = self.get(context, backup_id)
|
||||
if backup['status'] != fields.BackupStatus.AVAILABLE:
|
||||
msg = (_('Backup status must be available and not %s.') %
|
||||
@ -537,7 +529,7 @@ class API(base.Base):
|
||||
:raises ServiceNotFound:
|
||||
:raises InvalidInput:
|
||||
"""
|
||||
check_policy(context, 'backup-import')
|
||||
context.authorize(policy.IMPORT_POLICY)
|
||||
|
||||
# NOTE(ronenkat): since we don't have a backup-scheduler
|
||||
# we need to find a host that support the backup service
|
||||
@ -563,7 +555,7 @@ class API(base.Base):
|
||||
return backup
|
||||
|
||||
def update(self, context, backup_id, fields):
|
||||
check_policy(context, 'update')
|
||||
context.authorize(policy.UPDATE_POLICY)
|
||||
backup = self.get(context, backup_id)
|
||||
backup.update(fields)
|
||||
backup.save()
|
||||
|
@ -16,6 +16,8 @@
|
||||
import itertools
|
||||
|
||||
from cinder.policies import attachments
|
||||
from cinder.policies import backup_actions
|
||||
from cinder.policies import backups
|
||||
from cinder.policies import base
|
||||
from cinder.policies import clusters
|
||||
from cinder.policies import manageable_snapshots
|
||||
@ -37,4 +39,6 @@ def list_rules():
|
||||
snapshots.list_rules(),
|
||||
snapshot_actions.list_rules(),
|
||||
manageable_snapshots.list_rules(),
|
||||
backups.list_rules(),
|
||||
backup_actions.list_rules(),
|
||||
)
|
||||
|
49
cinder/policies/backup_actions.py
Normal file
49
cinder/policies/backup_actions.py
Normal file
@ -0,0 +1,49 @@
|
||||
# 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
|
||||
|
||||
|
||||
BASE_POLICY_NAME = 'volume_extension:backup_admin_actions:%s'
|
||||
|
||||
|
||||
backup_actions_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
name=BASE_POLICY_NAME % 'reset_status',
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Reset status of a backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/backups/{backup_id}/action (os-reset_status)'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=BASE_POLICY_NAME % 'force_delete',
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Force delete a backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/backups/{backup_id}/action (os-force_delete)'
|
||||
}
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return backup_actions_policies
|
134
cinder/policies/backups.py
Normal file
134
cinder/policies/backups.py
Normal file
@ -0,0 +1,134 @@
|
||||
# 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_ALL_POLICY = 'backup:get_all'
|
||||
GET_POLICY = 'backup:get'
|
||||
CREATE_POLICY = 'backup:create'
|
||||
UPDATE_POLICY = 'backup:update'
|
||||
DELETE_POLICY = 'backup:delete'
|
||||
RESTORE_POLICY = 'backup:restore'
|
||||
IMPORT_POLICY = 'backup:backup-import'
|
||||
EXPORT_POLICY = 'backup:export-import'
|
||||
BACKUP_ATTRIBUTES_POLICY = 'backup:backup_project_attribute'
|
||||
|
||||
backups_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
name=GET_ALL_POLICY,
|
||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
||||
description="List backups.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/backups'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/backups/detail'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=BACKUP_ATTRIBUTES_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="List backups or show backup with project attributes.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/backups/{backup_id}'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/backups/detail'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=CREATE_POLICY,
|
||||
check_str="",
|
||||
description="Create backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/backups'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=GET_POLICY,
|
||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
||||
description="Show backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/backups/{backup_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=UPDATE_POLICY,
|
||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
||||
description="Update backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'PUT',
|
||||
'path': '/backups/{backup_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=DELETE_POLICY,
|
||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
||||
description="Delete backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/backups/{backup_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=RESTORE_POLICY,
|
||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
||||
description="Restore backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/backups/{backup_id}/restore'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=IMPORT_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Import backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/backups/{backup_id}/import_record'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=EXPORT_POLICY,
|
||||
check_str=base.RULE_ADMIN_API,
|
||||
description="Export backup.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/backups/{backup_id}/export_record'
|
||||
}
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return backups_policies
|
@ -44,8 +44,6 @@
|
||||
"volume:thaw_host": "rule:admin_api",
|
||||
"volume:revert_to_snapshot": "",
|
||||
"volume_extension:volume_admin_actions:reset_status": "rule:admin_api",
|
||||
"volume_extension:backup_admin_actions:reset_status": "rule:admin_api",
|
||||
"volume_extension:backup_admin_actions:force_delete": "rule:admin_api",
|
||||
"volume_extension:volume_admin_actions:force_delete": "rule:admin_api",
|
||||
"volume_extension:volume_admin_actions:force_detach": "rule:admin_api",
|
||||
"volume_extension:volume_admin_actions:migrate_volume": "rule:admin_api",
|
||||
@ -95,16 +93,10 @@
|
||||
"volume:get_transfer": "",
|
||||
"volume:get_all_transfers": "",
|
||||
|
||||
"backup:create" : "",
|
||||
"backup:delete": "",
|
||||
"backup:get": "",
|
||||
"backup:get_all": "",
|
||||
"backup:restore": "",
|
||||
"backup:backup-import": "rule:admin_api",
|
||||
"backup:backup-export": "rule:admin_api",
|
||||
"backup:update": "rule:admin_or_owner",
|
||||
"backup:backup_project_attribute": "rule:admin_api",
|
||||
|
||||
|
||||
"consistencygroup:create" : "",
|
||||
"consistencygroup:delete": "",
|
||||
|
@ -46,7 +46,6 @@
|
||||
"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:backup_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",
|
||||
"volume_extension:backup_admin_actions:force_delete": "rule:admin_api",
|
||||
@ -79,16 +78,6 @@
|
||||
"volume:freeze_host": "rule:admin_api",
|
||||
"volume:thaw_host": "rule:admin_api",
|
||||
|
||||
"backup:create" : "",
|
||||
"backup:delete": "rule:admin_or_owner",
|
||||
"backup:get": "rule:admin_or_owner",
|
||||
"backup:get_all": "rule:admin_or_owner",
|
||||
"backup:restore": "rule:admin_or_owner",
|
||||
"backup:backup-import": "rule:admin_api",
|
||||
"backup:backup-export": "rule:admin_api",
|
||||
"backup:update": "rule:admin_or_owner",
|
||||
"backup:backup_project_attribute": "rule:admin_api",
|
||||
|
||||
"consistencygroup:create" : "group:nobody",
|
||||
"consistencygroup:delete": "group:nobody",
|
||||
"consistencygroup:update": "group:nobody",
|
||||
|
Loading…
Reference in New Issue
Block a user