Coverage for nova/policies/servers.py: 100%
12 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
14from oslo_policy import policy
16from nova.policies import base
19SERVERS = 'os_compute_api:servers:%s'
20NETWORK_ATTACH_EXTERNAL = 'network:attach_external_network'
21ZERO_DISK_FLAVOR = SERVERS % 'create:zero_disk_flavor'
22REQUESTED_DESTINATION = 'compute:servers:create:requested_destination'
23CROSS_CELL_RESIZE = 'compute:servers:resize:cross_cell'
25DEPRECATED_POLICY = policy.DeprecatedRule(
26 'os_compute_api:os-flavor-extra-specs:index',
27 base.RULE_ADMIN_OR_OWNER,
28)
30DEPRECATED_REASON = """
31Policies for showing flavor extra specs in server APIs response is
32separated as new policy. This policy is deprecated only for that but
33not for list extra specs and showing it in flavor API response.
34"""
36rules = [
37 policy.DocumentedRuleDefault(
38 name=SERVERS % 'index',
39 check_str=base.PROJECT_READER_OR_ADMIN,
40 description="List all servers",
41 operations=[
42 {
43 'method': 'GET',
44 'path': '/servers'
45 }
46 ],
47 scope_types=['project']),
48 policy.DocumentedRuleDefault(
49 name=SERVERS % 'detail',
50 check_str=base.PROJECT_READER_OR_ADMIN,
51 description="List all servers with detailed information",
52 operations=[
53 {
54 'method': 'GET',
55 'path': '/servers/detail'
56 }
57 ],
58 scope_types=['project']),
59 policy.DocumentedRuleDefault(
60 name=SERVERS % 'index:get_all_tenants',
61 check_str=base.ADMIN,
62 description="List all servers for all projects",
63 operations=[
64 {
65 'method': 'GET',
66 'path': '/servers'
67 }
68 ],
69 scope_types=['project']),
71 policy.DocumentedRuleDefault(
72 name=SERVERS % 'detail:get_all_tenants',
73 check_str=base.ADMIN,
74 description="List all servers with detailed information for "
75 " all projects",
76 operations=[
77 {
78 'method': 'GET',
79 'path': '/servers/detail'
80 }
81 ],
82 scope_types=['project']),
83 policy.DocumentedRuleDefault(
84 name=SERVERS % 'allow_all_filters',
85 check_str=base.ADMIN,
86 description="Allow all filters when listing servers",
87 operations=[
88 {
89 'method': 'GET',
90 'path': '/servers'
91 },
92 {
93 'method': 'GET',
94 'path': '/servers/detail'
95 }
96 ],
97 scope_types=['project']),
98 policy.DocumentedRuleDefault(
99 name=SERVERS % 'show',
100 check_str=base.PROJECT_READER_OR_ADMIN,
101 description="Show a server",
102 operations=[
103 {
104 'method': 'GET',
105 'path': '/servers/{server_id}'
106 }
107 ],
108 scope_types=['project']),
109 policy.DocumentedRuleDefault(
110 name=SERVERS % 'show:flavor-extra-specs',
111 check_str=base.PROJECT_READER_OR_ADMIN,
112 description="Starting with microversion 2.47, the flavor and its "
113 "extra specs used for a server is also returned in the response "
114 "when showing server details, updating a server or rebuilding a "
115 "server.",
116 operations=[
117 # Microversion 2.47 operations for servers:
118 {
119 'path': '/servers/detail',
120 'method': 'GET'
121 },
122 {
123 'path': '/servers/{server_id}',
124 'method': 'GET'
125 },
126 {
127 'path': '/servers/{server_id}',
128 'method': 'PUT'
129 },
130 {
131 'path': '/servers/{server_id}/action (rebuild)',
132 'method': 'POST'
133 },
134 ],
135 scope_types=['project'],
136 deprecated_rule=DEPRECATED_POLICY,
137 deprecated_reason=DEPRECATED_REASON,
138 deprecated_since='25.0.0'),
139 # the details in host_status are pretty sensitive, only admins
140 # should do that by default.
141 policy.DocumentedRuleDefault(
142 name=SERVERS % 'show:host_status',
143 check_str=base.ADMIN,
144 description="""
145Show a server with additional host status information.
147This means host_status will be shown irrespective of status value. If showing
148only host_status UNKNOWN is desired, use the
149``os_compute_api:servers:show:host_status:unknown-only`` policy rule.
151Microvision 2.75 added the ``host_status`` attribute in the
152``PUT /servers/{server_id}`` and ``POST /servers/{server_id}/action (rebuild)``
153API responses which are also controlled by this policy rule, like the
154``GET /servers*`` APIs.
155""",
156 operations=[
157 {
158 'method': 'GET',
159 'path': '/servers/{server_id}'
160 },
161 {
162 'method': 'GET',
163 'path': '/servers/detail'
164 },
165 {
166 'method': 'PUT',
167 'path': '/servers/{server_id}'
168 },
169 {
170 'method': 'POST',
171 'path': '/servers/{server_id}/action (rebuild)'
172 }
173 ],
174 scope_types=['project']),
175 policy.DocumentedRuleDefault(
176 name=SERVERS % 'show:host_status:unknown-only',
177 check_str=base.ADMIN,
178 description="""
179Show a server with additional host status information, only if host status is
180UNKNOWN.
182This policy rule will only be enforced when the
183``os_compute_api:servers:show:host_status`` policy rule does not pass for the
184request. An example policy configuration could be where the
185``os_compute_api:servers:show:host_status`` rule is set to allow admin-only and
186the ``os_compute_api:servers:show:host_status:unknown-only`` rule is set to
187allow everyone.
188""",
189 operations=[
190 {
191 'method': 'GET',
192 'path': '/servers/{server_id}'
193 },
194 {
195 'method': 'GET',
196 'path': '/servers/detail'
197 },
198 {
199 'method': 'PUT',
200 'path': '/servers/{server_id}'
201 },
202 {
203 'method': 'POST',
204 'path': '/servers/{server_id}/action (rebuild)'
205 }
206 ],
207 scope_types=['project'],),
208 policy.DocumentedRuleDefault(
209 name=SERVERS % 'create',
210 check_str=base.PROJECT_MEMBER_OR_ADMIN,
211 description="Create a server",
212 operations=[
213 {
214 'method': 'POST',
215 'path': '/servers'
216 }
217 ],
218 scope_types=['project']),
219 policy.DocumentedRuleDefault(
220 name=SERVERS % 'create:forced_host',
221 check_str=base.ADMIN,
222 description="""
223Create a server on the specified host and/or node.
225In this case, the server is forced to launch on the specified
226host and/or node by bypassing the scheduler filters unlike the
227``compute:servers:create:requested_destination`` rule.
228""",
229 operations=[
230 {
231 'method': 'POST',
232 'path': '/servers'
233 }
234 ],
235 scope_types=['project']),
236 policy.DocumentedRuleDefault(
237 name=REQUESTED_DESTINATION,
238 check_str=base.ADMIN,
239 description="""
240Create a server on the requested compute service host and/or
241hypervisor_hostname.
243In this case, the requested host and/or hypervisor_hostname is
244validated by the scheduler filters unlike the
245``os_compute_api:servers:create:forced_host`` rule.
246""",
247 operations=[
248 {
249 'method': 'POST',
250 'path': '/servers'
251 }
252 ],
253 scope_types=['project']),
254 policy.DocumentedRuleDefault(
255 name=SERVERS % 'create:attach_volume',
256 check_str=base.PROJECT_MEMBER_OR_ADMIN,
257 description="Create a server with the requested volume attached to it",
258 operations=[
259 {
260 'method': 'POST',
261 'path': '/servers'
262 }
263 ],
264 scope_types=['project']),
265 policy.DocumentedRuleDefault(
266 name=SERVERS % 'create:attach_network',
267 check_str=base.PROJECT_MEMBER_OR_ADMIN,
268 description="Create a server with the requested network attached "
269 " to it",
270 operations=[
271 {
272 'method': 'POST',
273 'path': '/servers'
274 }
275 ],
276 scope_types=['project']),
277 policy.DocumentedRuleDefault(
278 name=SERVERS % 'create:trusted_certs',
279 check_str=base.PROJECT_MEMBER_OR_ADMIN,
280 description="Create a server with trusted image certificate IDs",
281 operations=[
282 {
283 'method': 'POST',
284 'path': '/servers'
285 }
286 ],
287 scope_types=['project']),
288 policy.DocumentedRuleDefault(
289 name=ZERO_DISK_FLAVOR,
290 check_str=base.ADMIN,
291 description="""
292This rule controls the compute API validation behavior of creating a server
293with a flavor that has 0 disk, indicating the server should be volume-backed.
295For a flavor with disk=0, the root disk will be set to exactly the size of the
296image used to deploy the instance. However, in this case the filter_scheduler
297cannot select the compute host based on the virtual image size. Therefore, 0
298should only be used for volume booted instances or for testing purposes.
300WARNING: It is a potential security exposure to enable this policy rule
301if users can upload their own images since repeated attempts to
302create a disk=0 flavor instance with a large image can exhaust
303the local disk of the compute (or shared storage cluster). See bug
304https://bugs.launchpad.net/nova/+bug/1739646 for details.
305""",
306 operations=[
307 {
308 'method': 'POST',
309 'path': '/servers'
310 }
311 ],
312 scope_types=['project']),
313 policy.DocumentedRuleDefault(
314 name=NETWORK_ATTACH_EXTERNAL,
315 check_str=base.ADMIN,
316 description="Attach an unshared external network to a server",
317 operations=[
318 # Create a server with a requested network or port.
319 {
320 'method': 'POST',
321 'path': '/servers'
322 },
323 # Attach a network or port to an existing server.
324 {
325 'method': 'POST',
326 'path': '/servers/{server_id}/os-interface'
327 }
328 ],
329 scope_types=['project']),
330 policy.DocumentedRuleDefault(
331 name=SERVERS % 'delete',
332 check_str=base.PROJECT_MEMBER_OR_ADMIN,
333 description="Delete a server",
334 operations=[
335 {
336 'method': 'DELETE',
337 'path': '/servers/{server_id}'
338 }
339 ],
340 scope_types=['project']),
341 policy.DocumentedRuleDefault(
342 name=SERVERS % 'update',
343 check_str=base.PROJECT_MEMBER_OR_ADMIN,
344 description="Update a server",
345 operations=[
346 {
347 'method': 'PUT',
348 'path': '/servers/{server_id}'
349 }
350 ],
351 scope_types=['project']),
352 policy.DocumentedRuleDefault(
353 name=SERVERS % 'confirm_resize',
354 check_str=base.PROJECT_MEMBER_OR_ADMIN,
355 description="Confirm a server resize",
356 operations=[
357 {
358 'method': 'POST',
359 'path': '/servers/{server_id}/action (confirmResize)'
360 }
361 ],
362 scope_types=['project']),
363 policy.DocumentedRuleDefault(
364 name=SERVERS % 'revert_resize',
365 check_str=base.PROJECT_MEMBER_OR_ADMIN,
366 description="Revert a server resize",
367 operations=[
368 {
369 'method': 'POST',
370 'path': '/servers/{server_id}/action (revertResize)'
371 }
372 ],
373 scope_types=['project']),
374 policy.DocumentedRuleDefault(
375 name=SERVERS % 'reboot',
376 check_str=base.PROJECT_MEMBER_OR_ADMIN,
377 description="Reboot a server",
378 operations=[
379 {
380 'method': 'POST',
381 'path': '/servers/{server_id}/action (reboot)'
382 }
383 ],
384 scope_types=['project']),
385 policy.DocumentedRuleDefault(
386 name=SERVERS % 'resize',
387 check_str=base.PROJECT_MEMBER_OR_ADMIN,
388 description="Resize a server",
389 operations=[
390 {
391 'method': 'POST',
392 'path': '/servers/{server_id}/action (resize)'
393 }
394 ],
395 scope_types=['project']),
396 policy.DocumentedRuleDefault(
397 name=CROSS_CELL_RESIZE,
398 check_str=base.RULE_NOBODY,
399 description="Resize a server across cells. By default, this is "
400 "disabled for all users and recommended to be tested in a "
401 "deployment for admin users before opening it up to non-admin users. "
402 "Resizing within a cell is the default preferred behavior even if "
403 "this is enabled. ",
404 operations=[
405 {
406 'method': 'POST',
407 'path': '/servers/{server_id}/action (resize)'
408 }
409 ],
410 scope_types=['project']),
411 policy.DocumentedRuleDefault(
412 name=SERVERS % 'rebuild',
413 check_str=base.PROJECT_MEMBER_OR_ADMIN,
414 description="Rebuild a server",
415 operations=[
416 {
417 'method': 'POST',
418 'path': '/servers/{server_id}/action (rebuild)'
419 }
420 ],
421 scope_types=['project']),
422 policy.DocumentedRuleDefault(
423 name=SERVERS % 'rebuild:trusted_certs',
424 check_str=base.PROJECT_MEMBER_OR_ADMIN,
425 description="Rebuild a server with trusted image certificate IDs",
426 operations=[
427 {
428 'method': 'POST',
429 'path': '/servers/{server_id}/action (rebuild)'
430 }
431 ],
432 scope_types=['project']),
433 policy.DocumentedRuleDefault(
434 name=SERVERS % 'create_image',
435 check_str=base.PROJECT_MEMBER_OR_ADMIN,
436 description="Create an image from a server",
437 operations=[
438 {
439 'method': 'POST',
440 'path': '/servers/{server_id}/action (createImage)'
441 }
442 ],
443 scope_types=['project']),
444 policy.DocumentedRuleDefault(
445 name=SERVERS % 'create_image:allow_volume_backed',
446 check_str=base.PROJECT_MEMBER_OR_ADMIN,
447 description="Create an image from a volume backed server",
448 operations=[
449 {
450 'method': 'POST',
451 'path': '/servers/{server_id}/action (createImage)'
452 }
453 ],
454 scope_types=['project']),
455 policy.DocumentedRuleDefault(
456 name=SERVERS % 'start',
457 check_str=base.PROJECT_MEMBER_OR_ADMIN,
458 description="Start a server",
459 operations=[
460 {
461 'method': 'POST',
462 'path': '/servers/{server_id}/action (os-start)'
463 }
464 ],
465 scope_types=['project']),
466 policy.DocumentedRuleDefault(
467 name=SERVERS % 'stop',
468 check_str=base.PROJECT_MEMBER_OR_ADMIN,
469 description="Stop a server",
470 operations=[
471 {
472 'method': 'POST',
473 'path': '/servers/{server_id}/action (os-stop)'
474 }
475 ],
476 scope_types=['project']),
477 policy.DocumentedRuleDefault(
478 name=SERVERS % 'trigger_crash_dump',
479 check_str=base.PROJECT_MEMBER_OR_ADMIN,
480 description="Trigger crash dump in a server",
481 operations=[
482 {
483 'method': 'POST',
484 'path': '/servers/{server_id}/action (trigger_crash_dump)'
485 }
486 ],
487 scope_types=['project']),
488]
491def list_rules():
492 return rules