Skip to content

Commit b39712f

Browse files
committed
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
1 parent 9acbae3 commit b39712f

File tree

4 files changed

+163
-19
lines changed

4 files changed

+163
-19
lines changed

nova/api/openstack/compute/volumes.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def __init__(self):
104104
def show(self, req, id):
105105
"""Return data about the given volume."""
106106
context = req.environ['nova.context']
107-
context.can(vol_policies.BASE_POLICY_NAME)
107+
context.can(vol_policies.POLICY_NAME % 'show')
108108

109109
try:
110110
vol = self.volume_api.get(context, id)
@@ -119,7 +119,7 @@ def show(self, req, id):
119119
def delete(self, req, id):
120120
"""Delete a volume."""
121121
context = req.environ['nova.context']
122-
context.can(vol_policies.BASE_POLICY_NAME)
122+
context.can(vol_policies.POLICY_NAME % 'delete')
123123

124124
try:
125125
self.volume_api.delete(context, id)
@@ -133,19 +133,22 @@ def delete(self, req, id):
133133
@wsgi.expected_errors(())
134134
def index(self, req):
135135
"""Returns a summary list of volumes."""
136+
context = req.environ['nova.context']
137+
context.can(vol_policies.POLICY_NAME % 'list')
136138
return self._items(req, entity_maker=_translate_volume_summary_view)
137139

138140
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
139141
@validation.query_schema(volumes_schema.detail_query)
140142
@wsgi.expected_errors(())
141143
def detail(self, req):
142144
"""Returns a detailed list of volumes."""
145+
context = req.environ['nova.context']
146+
context.can(vol_policies.POLICY_NAME % 'detail')
143147
return self._items(req, entity_maker=_translate_volume_detail_view)
144148

145149
def _items(self, req, entity_maker):
146150
"""Returns a list of volumes, transformed through entity_maker."""
147151
context = req.environ['nova.context']
148-
context.can(vol_policies.BASE_POLICY_NAME)
149152

150153
volumes = self.volume_api.get_all(context)
151154
limited_list = common.limited(volumes, req)
@@ -158,7 +161,7 @@ def _items(self, req, entity_maker):
158161
def create(self, req, body):
159162
"""Creates a new volume."""
160163
context = req.environ['nova.context']
161-
context.can(vol_policies.BASE_POLICY_NAME)
164+
context.can(vol_policies.POLICY_NAME % 'create')
162165

163166
vol = body['volume']
164167

@@ -573,7 +576,7 @@ def __init__(self):
573576
def show(self, req, id):
574577
"""Return data about the given snapshot."""
575578
context = req.environ['nova.context']
576-
context.can(vol_policies.BASE_POLICY_NAME)
579+
context.can(vol_policies.POLICY_NAME % 'snapshots:show')
577580

578581
try:
579582
vol = self.volume_api.get_snapshot(context, id)
@@ -588,7 +591,7 @@ def show(self, req, id):
588591
def delete(self, req, id):
589592
"""Delete a snapshot."""
590593
context = req.environ['nova.context']
591-
context.can(vol_policies.BASE_POLICY_NAME)
594+
context.can(vol_policies.POLICY_NAME % 'snapshots:delete')
592595

593596
try:
594597
self.volume_api.delete_snapshot(context, id)
@@ -600,19 +603,22 @@ def delete(self, req, id):
600603
@wsgi.expected_errors(())
601604
def index(self, req):
602605
"""Returns a summary list of snapshots."""
606+
context = req.environ['nova.context']
607+
context.can(vol_policies.POLICY_NAME % 'snapshots:list')
603608
return self._items(req, entity_maker=_translate_snapshot_summary_view)
604609

605610
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
606611
@validation.query_schema(volumes_schema.detail_query)
607612
@wsgi.expected_errors(())
608613
def detail(self, req):
609614
"""Returns a detailed list of snapshots."""
615+
context = req.environ['nova.context']
616+
context.can(vol_policies.POLICY_NAME % 'snapshots:detail')
610617
return self._items(req, entity_maker=_translate_snapshot_detail_view)
611618

612619
def _items(self, req, entity_maker):
613620
"""Returns a list of snapshots, transformed through entity_maker."""
614621
context = req.environ['nova.context']
615-
context.can(vol_policies.BASE_POLICY_NAME)
616622

617623
snapshots = self.volume_api.get_all_snapshots(context)
618624
limited_list = common.limited(snapshots, req)
@@ -625,7 +631,7 @@ def _items(self, req, entity_maker):
625631
def create(self, req, body):
626632
"""Creates a new snapshot."""
627633
context = req.environ['nova.context']
628-
context.can(vol_policies.BASE_POLICY_NAME)
634+
context.can(vol_policies.POLICY_NAME % 'snapshots:create')
629635

630636
snapshot = body['snapshot']
631637
volume_id = snapshot['volume_id']

nova/policies/volumes.py

Lines changed: 129 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,181 @@
1919

2020

2121
BASE_POLICY_NAME = 'os_compute_api:os-volumes'
22+
POLICY_NAME = 'os_compute_api:os-volumes:%s'
23+
24+
DEPRECATED_POLICY = policy.DeprecatedRule(
25+
BASE_POLICY_NAME,
26+
base.RULE_ADMIN_OR_OWNER,
27+
)
28+
29+
DEPRECATED_REASON = """
30+
Nova API policies are introducing new default roles with scope_type
31+
capabilities. Old policies are deprecated and silently going to be ignored
32+
in nova 23.0.0 release.
33+
"""
2234

2335

2436
volumes_policies = [
2537
policy.DocumentedRuleDefault(
26-
name=BASE_POLICY_NAME,
27-
check_str=base.RULE_ADMIN_OR_OWNER,
28-
description="""Manage volumes for use with the Compute API.
29-
30-
Lists, shows details, creates, and deletes volumes and
31-
snapshots. These APIs are proxy calls to the Volume service.
32-
These are all deprecated.
33-
""",
38+
name=POLICY_NAME % 'list',
39+
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
40+
description="""List volumes.
41+
42+
This API is a proxy call to the Volume service. It is deprecated.""",
3443
operations=[
3544
{
3645
'method': 'GET',
3746
'path': '/os-volumes'
3847
},
48+
],
49+
scope_types=['system', 'project'],
50+
deprecated_rule=DEPRECATED_POLICY,
51+
deprecated_reason=DEPRECATED_REASON,
52+
deprecated_since='22.0.0'),
53+
policy.DocumentedRuleDefault(
54+
name=POLICY_NAME % 'create',
55+
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
56+
description="""Create volume.
57+
58+
This API is a proxy call to the Volume service. It is deprecated.""",
59+
operations=[
3960
{
4061
'method': 'POST',
4162
'path': '/os-volumes'
4263
},
64+
],
65+
scope_types=['system', 'project'],
66+
deprecated_rule=DEPRECATED_POLICY,
67+
deprecated_reason=DEPRECATED_REASON,
68+
deprecated_since='22.0.0'),
69+
policy.DocumentedRuleDefault(
70+
name=POLICY_NAME % 'detail',
71+
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
72+
description="""List volumes detail.
73+
74+
This API is a proxy call to the Volume service. It is deprecated.""",
75+
operations=[
4376
{
4477
'method': 'GET',
4578
'path': '/os-volumes/detail'
4679
},
80+
],
81+
scope_types=['system', 'project'],
82+
deprecated_rule=DEPRECATED_POLICY,
83+
deprecated_reason=DEPRECATED_REASON,
84+
deprecated_since='22.0.0'),
85+
policy.DocumentedRuleDefault(
86+
name=POLICY_NAME % 'show',
87+
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
88+
description="""Show volume.
89+
90+
This API is a proxy call to the Volume service. It is deprecated.""",
91+
operations=[
4792
{
4893
'method': 'GET',
4994
'path': '/os-volumes/{volume_id}'
5095
},
96+
],
97+
scope_types=['system', 'project'],
98+
deprecated_rule=DEPRECATED_POLICY,
99+
deprecated_reason=DEPRECATED_REASON,
100+
deprecated_since='22.0.0'),
101+
policy.DocumentedRuleDefault(
102+
name=POLICY_NAME % 'delete',
103+
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
104+
description="""Delete volume.
105+
106+
This API is a proxy call to the Volume service. It is deprecated.""",
107+
operations=[
51108
{
52109
'method': 'DELETE',
53110
'path': '/os-volumes/{volume_id}'
54111
},
112+
],
113+
scope_types=['system', 'project'],
114+
deprecated_rule=DEPRECATED_POLICY,
115+
deprecated_reason=DEPRECATED_REASON,
116+
deprecated_since='22.0.0'),
117+
policy.DocumentedRuleDefault(
118+
name=POLICY_NAME % 'snapshots:list',
119+
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
120+
description="""List snapshots.
121+
122+
This API is a proxy call to the Volume service. It is deprecated.""",
123+
operations=[
55124
{
56125
'method': 'GET',
57126
'path': '/os-snapshots'
58127
},
128+
],
129+
scope_types=['system', 'project'],
130+
deprecated_rule=DEPRECATED_POLICY,
131+
deprecated_reason=DEPRECATED_REASON,
132+
deprecated_since='22.0.0'),
133+
policy.DocumentedRuleDefault(
134+
name=POLICY_NAME % 'snapshots:create',
135+
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
136+
description="""Create snapshots.
137+
138+
This API is a proxy call to the Volume service. It is deprecated.""",
139+
operations=[
59140
{
60141
'method': 'POST',
61142
'path': '/os-snapshots'
62143
},
144+
],
145+
scope_types=['system', 'project'],
146+
deprecated_rule=DEPRECATED_POLICY,
147+
deprecated_reason=DEPRECATED_REASON,
148+
deprecated_since='22.0.0'),
149+
policy.DocumentedRuleDefault(
150+
name=POLICY_NAME % 'snapshots:detail',
151+
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
152+
description="""List snapshots details.
153+
154+
This API is a proxy call to the Volume service. It is deprecated.""",
155+
operations=[
63156
{
64157
'method': 'GET',
65158
'path': '/os-snapshots/detail'
66159
},
160+
],
161+
scope_types=['system', 'project'],
162+
deprecated_rule=DEPRECATED_POLICY,
163+
deprecated_reason=DEPRECATED_REASON,
164+
deprecated_since='22.0.0'),
165+
policy.DocumentedRuleDefault(
166+
name=POLICY_NAME % 'snapshots:show',
167+
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
168+
description="""Show snapshot.
169+
170+
This API is a proxy call to the Volume service. It is deprecated.""",
171+
operations=[
67172
{
68173
'method': 'GET',
69174
'path': '/os-snapshots/{snapshot_id}'
70175
},
176+
],
177+
scope_types=['system', 'project'],
178+
deprecated_rule=DEPRECATED_POLICY,
179+
deprecated_reason=DEPRECATED_REASON,
180+
deprecated_since='22.0.0'),
181+
policy.DocumentedRuleDefault(
182+
name=POLICY_NAME % 'snapshots:delete',
183+
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
184+
description="""Delete snapshot.
185+
186+
This API is a proxy call to the Volume service. It is deprecated.""",
187+
operations=[
71188
{
72189
'method': 'DELETE',
73190
'path': '/os-snapshots/{snapshot_id}'
74191
}
75192
],
76-
scope_types=['system', 'project']),
193+
scope_types=['system', 'project'],
194+
deprecated_rule=DEPRECATED_POLICY,
195+
deprecated_reason=DEPRECATED_REASON,
196+
deprecated_since='22.0.0'),
77197
]
78198

79199

nova/tests/unit/fake_policy.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,16 @@
160160
"os_compute_api:os-shelve:unshelve": "",
161161
"os_compute_api:os-suspend-server:suspend": "",
162162
"os_compute_api:os-suspend-server:resume": "",
163-
"os_compute_api:os-volumes": "",
163+
"os_compute_api:os-volumes:list": "",
164+
"os_compute_api:os-volumes:detail": "",
165+
"os_compute_api:os-volumes:create": "",
166+
"os_compute_api:os-volumes:show": "",
167+
"os_compute_api:os-volumes:delete": "",
168+
"os_compute_api:os-volumes:snapshots:create": "",
169+
"os_compute_api:os-volumes:snapshots:show": "",
170+
"os_compute_api:os-volumes:snapshots:delete": "",
171+
"os_compute_api:os-volumes:snapshots:list": "",
172+
"os_compute_api:os-volumes:snapshots:detail": "",
164173
"os_compute_api:os-volumes-attachments:index": "",
165174
"os_compute_api:os-volumes-attachments:show": "",
166175
"os_compute_api:os-volumes-attachments:create": "",

nova/tests/unit/test_policy.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,10 @@ def setUp(self):
445445
"os_compute_api:os-server-groups:delete",
446446
"os_compute_api:os-shelve:shelve",
447447
"os_compute_api:os-shelve:unshelve",
448-
"os_compute_api:os-volumes",
448+
"os_compute_api:os-volumes:create",
449+
"os_compute_api:os-volumes:delete",
450+
"os_compute_api:os-volumes:snapshots:create",
451+
"os_compute_api:os-volumes:snapshots:delete",
449452
"os_compute_api:os-volumes-attachments:create",
450453
"os_compute_api:os-volumes-attachments:delete",
451454
"os_compute_api:os-volumes-attachments:update",
@@ -489,6 +492,12 @@ def setUp(self):
489492
"os_compute_api:os-server-password:show",
490493
"os_compute_api:os-server-tags:index",
491494
"os_compute_api:os-server-tags:show",
495+
"os_compute_api:os-volumes:list",
496+
"os_compute_api:os-volumes:detail",
497+
"os_compute_api:os-volumes:show",
498+
"os_compute_api:os-volumes:snapshots:show",
499+
"os_compute_api:os-volumes:snapshots:list",
500+
"os_compute_api:os-volumes:snapshots:detail",
492501
)
493502

494503
self.allow_nobody_rules = (

0 commit comments

Comments
 (0)