Coverage for nova/policies/servers.py: 100%

12 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-17 15:08 +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. 

12 

13 

14from oslo_policy import policy 

15 

16from nova.policies import base 

17 

18 

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' 

24 

25DEPRECATED_POLICY = policy.DeprecatedRule( 

26 'os_compute_api:os-flavor-extra-specs:index', 

27 base.RULE_ADMIN_OR_OWNER, 

28) 

29 

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""" 

35 

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']), 

70 

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. 

146 

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. 

150 

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. 

181 

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. 

224 

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. 

242 

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. 

294 

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. 

299 

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] 

489 

490 

491def list_rules(): 

492 return rules