Add new default roles in volumes policies

This adds new defaults roles in volumes API policies.
These policies are made granular and default to
PROJECT_READER_OR_SYSTEM_READER and PROJECT_MEMBER_OR_SYSTEM_ADMIN.

Partial implement blueprint policy-defaults-refresh-deprecated-apis

Change-Id: I37fa825b0e915e83da7023564a29811dcdfa058d
This commit is contained in:
Ghanshyam Mann 2020-07-23 20:55:44 -05:00
parent 9acbae3619
commit b39712f03e
4 changed files with 162 additions and 18 deletions

View File

@ -104,7 +104,7 @@ class VolumeController(wsgi.Controller):
def show(self, req, id):
"""Return data about the given volume."""
context = req.environ['nova.context']
context.can(vol_policies.BASE_POLICY_NAME)
context.can(vol_policies.POLICY_NAME % 'show')
try:
vol = self.volume_api.get(context, id)
@ -119,7 +119,7 @@ class VolumeController(wsgi.Controller):
def delete(self, req, id):
"""Delete a volume."""
context = req.environ['nova.context']
context.can(vol_policies.BASE_POLICY_NAME)
context.can(vol_policies.POLICY_NAME % 'delete')
try:
self.volume_api.delete(context, id)
@ -133,6 +133,8 @@ class VolumeController(wsgi.Controller):
@wsgi.expected_errors(())
def index(self, req):
"""Returns a summary list of volumes."""
context = req.environ['nova.context']
context.can(vol_policies.POLICY_NAME % 'list')
return self._items(req, entity_maker=_translate_volume_summary_view)
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@ -140,12 +142,13 @@ class VolumeController(wsgi.Controller):
@wsgi.expected_errors(())
def detail(self, req):
"""Returns a detailed list of volumes."""
context = req.environ['nova.context']
context.can(vol_policies.POLICY_NAME % 'detail')
return self._items(req, entity_maker=_translate_volume_detail_view)
def _items(self, req, entity_maker):
"""Returns a list of volumes, transformed through entity_maker."""
context = req.environ['nova.context']
context.can(vol_policies.BASE_POLICY_NAME)
volumes = self.volume_api.get_all(context)
limited_list = common.limited(volumes, req)
@ -158,7 +161,7 @@ class VolumeController(wsgi.Controller):
def create(self, req, body):
"""Creates a new volume."""
context = req.environ['nova.context']
context.can(vol_policies.BASE_POLICY_NAME)
context.can(vol_policies.POLICY_NAME % 'create')
vol = body['volume']
@ -573,7 +576,7 @@ class SnapshotController(wsgi.Controller):
def show(self, req, id):
"""Return data about the given snapshot."""
context = req.environ['nova.context']
context.can(vol_policies.BASE_POLICY_NAME)
context.can(vol_policies.POLICY_NAME % 'snapshots:show')
try:
vol = self.volume_api.get_snapshot(context, id)
@ -588,7 +591,7 @@ class SnapshotController(wsgi.Controller):
def delete(self, req, id):
"""Delete a snapshot."""
context = req.environ['nova.context']
context.can(vol_policies.BASE_POLICY_NAME)
context.can(vol_policies.POLICY_NAME % 'snapshots:delete')
try:
self.volume_api.delete_snapshot(context, id)
@ -600,6 +603,8 @@ class SnapshotController(wsgi.Controller):
@wsgi.expected_errors(())
def index(self, req):
"""Returns a summary list of snapshots."""
context = req.environ['nova.context']
context.can(vol_policies.POLICY_NAME % 'snapshots:list')
return self._items(req, entity_maker=_translate_snapshot_summary_view)
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@ -607,12 +612,13 @@ class SnapshotController(wsgi.Controller):
@wsgi.expected_errors(())
def detail(self, req):
"""Returns a detailed list of snapshots."""
context = req.environ['nova.context']
context.can(vol_policies.POLICY_NAME % 'snapshots:detail')
return self._items(req, entity_maker=_translate_snapshot_detail_view)
def _items(self, req, entity_maker):
"""Returns a list of snapshots, transformed through entity_maker."""
context = req.environ['nova.context']
context.can(vol_policies.BASE_POLICY_NAME)
snapshots = self.volume_api.get_all_snapshots(context)
limited_list = common.limited(snapshots, req)
@ -625,7 +631,7 @@ class SnapshotController(wsgi.Controller):
def create(self, req, body):
"""Creates a new snapshot."""
context = req.environ['nova.context']
context.can(vol_policies.BASE_POLICY_NAME)
context.can(vol_policies.POLICY_NAME % 'snapshots:create')
snapshot = body['snapshot']
volume_id = snapshot['volume_id']

View File

@ -19,61 +19,181 @@ from nova.policies import base
BASE_POLICY_NAME = 'os_compute_api:os-volumes'
POLICY_NAME = 'os_compute_api:os-volumes:%s'
DEPRECATED_POLICY = policy.DeprecatedRule(
BASE_POLICY_NAME,
base.RULE_ADMIN_OR_OWNER,
)
DEPRECATED_REASON = """
Nova API policies are introducing new default roles with scope_type
capabilities. Old policies are deprecated and silently going to be ignored
in nova 23.0.0 release.
"""
volumes_policies = [
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME,
check_str=base.RULE_ADMIN_OR_OWNER,
description="""Manage volumes for use with the Compute API.
name=POLICY_NAME % 'list',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="""List volumes.
Lists, shows details, creates, and deletes volumes and
snapshots. These APIs are proxy calls to the Volume service.
These are all deprecated.
""",
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'GET',
'path': '/os-volumes'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'create',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
description="""Create volume.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'POST',
'path': '/os-volumes'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'detail',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="""List volumes detail.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'GET',
'path': '/os-volumes/detail'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'show',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="""Show volume.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'GET',
'path': '/os-volumes/{volume_id}'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'delete',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
description="""Delete volume.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'DELETE',
'path': '/os-volumes/{volume_id}'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'snapshots:list',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="""List snapshots.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'GET',
'path': '/os-snapshots'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'snapshots:create',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
description="""Create snapshots.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'POST',
'path': '/os-snapshots'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'snapshots:detail',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="""List snapshots details.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'GET',
'path': '/os-snapshots/detail'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'snapshots:show',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="""Show snapshot.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'GET',
'path': '/os-snapshots/{snapshot_id}'
},
],
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'snapshots:delete',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
description="""Delete snapshot.
This API is a proxy call to the Volume service. It is deprecated.""",
operations=[
{
'method': 'DELETE',
'path': '/os-snapshots/{snapshot_id}'
}
],
scope_types=['system', 'project']),
scope_types=['system', 'project'],
deprecated_rule=DEPRECATED_POLICY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since='22.0.0'),
]

View File

@ -160,7 +160,16 @@ policy_data = """
"os_compute_api:os-shelve:unshelve": "",
"os_compute_api:os-suspend-server:suspend": "",
"os_compute_api:os-suspend-server:resume": "",
"os_compute_api:os-volumes": "",
"os_compute_api:os-volumes:list": "",
"os_compute_api:os-volumes:detail": "",
"os_compute_api:os-volumes:create": "",
"os_compute_api:os-volumes:show": "",
"os_compute_api:os-volumes:delete": "",
"os_compute_api:os-volumes:snapshots:create": "",
"os_compute_api:os-volumes:snapshots:show": "",
"os_compute_api:os-volumes:snapshots:delete": "",
"os_compute_api:os-volumes:snapshots:list": "",
"os_compute_api:os-volumes:snapshots:detail": "",
"os_compute_api:os-volumes-attachments:index": "",
"os_compute_api:os-volumes-attachments:show": "",
"os_compute_api:os-volumes-attachments:create": "",

View File

@ -445,7 +445,10 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
"os_compute_api:os-server-groups:delete",
"os_compute_api:os-shelve:shelve",
"os_compute_api:os-shelve:unshelve",
"os_compute_api:os-volumes",
"os_compute_api:os-volumes:create",
"os_compute_api:os-volumes:delete",
"os_compute_api:os-volumes:snapshots:create",
"os_compute_api:os-volumes:snapshots:delete",
"os_compute_api:os-volumes-attachments:create",
"os_compute_api:os-volumes-attachments:delete",
"os_compute_api:os-volumes-attachments:update",
@ -489,6 +492,12 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
"os_compute_api:os-server-password:show",
"os_compute_api:os-server-tags:index",
"os_compute_api:os-server-tags:show",
"os_compute_api:os-volumes:list",
"os_compute_api:os-volumes:detail",
"os_compute_api:os-volumes:show",
"os_compute_api:os-volumes:snapshots:show",
"os_compute_api:os-volumes:snapshots:list",
"os_compute_api:os-volumes:snapshots:detail",
)
self.allow_nobody_rules = (