Coverage for manila/api/v2/router.py: 100%

185 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-02-18 22:19 +0000

1# Copyright 2011 OpenStack LLC. 

2# Copyright 2011 United States Government as represented by the 

3# Administrator of the National Aeronautics and Space Administration. 

4# Copyright (c) 2015 Mirantis inc. 

5# All Rights Reserved. 

6# 

7# Licensed under the Apache License, Version 2.0 (the "License"); you may 

8# not use this file except in compliance with the License. You may obtain 

9# a copy of the License at 

10# 

11# http://www.apache.org/licenses/LICENSE-2.0 

12# 

13# Unless required by applicable law or agreed to in writing, software 

14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

16# License for the specific language governing permissions and limitations 

17# under the License. 

18 

19""" 

20WSGI middleware for OpenStack Share API v2. 

21""" 

22 

23from manila.api import extensions 

24import manila.api.openstack 

25from manila.api.v2 import availability_zones 

26from manila.api.v2 import limits 

27from manila.api.v2 import messages 

28from manila.api.v2 import quota_class_sets 

29from manila.api.v2 import quota_sets 

30from manila.api.v2 import resource_locks 

31from manila.api.v2 import scheduler_stats 

32from manila.api.v2 import security_service 

33from manila.api.v2 import services 

34from manila.api.v2 import share_access_metadata 

35from manila.api.v2 import share_accesses 

36from manila.api.v2 import share_backups 

37from manila.api.v2 import share_export_locations 

38from manila.api.v2 import share_group_snapshots 

39from manila.api.v2 import share_group_type_specs 

40from manila.api.v2 import share_group_types 

41from manila.api.v2 import share_groups 

42from manila.api.v2 import share_instance_export_locations 

43from manila.api.v2 import share_instances 

44from manila.api.v2 import share_manage 

45from manila.api.v2 import share_network_subnets 

46from manila.api.v2 import share_networks 

47from manila.api.v2 import share_replica_export_locations 

48from manila.api.v2 import share_replicas 

49from manila.api.v2 import share_servers 

50from manila.api.v2 import share_snapshot_export_locations 

51from manila.api.v2 import share_snapshot_instance_export_locations 

52from manila.api.v2 import share_snapshot_instances 

53from manila.api.v2 import share_snapshots 

54from manila.api.v2 import share_transfer 

55from manila.api.v2 import share_types 

56from manila.api.v2 import share_types_extra_specs 

57from manila.api.v2 import share_unmanage 

58from manila.api.v2 import shares 

59from manila.api import versions 

60 

61 

62class APIRouter(manila.api.openstack.APIRouter): 

63 """Route API requests. 

64 

65 Routes requests on the OpenStack API to the appropriate controller 

66 and method. 

67 """ 

68 ExtensionManager = extensions.ExtensionManager 

69 

70 def _setup_routes(self, mapper): 

71 self.resources["versions"] = versions.create_resource() 

72 mapper.connect("versions", "/", 

73 controller=self.resources["versions"], 

74 action="index") 

75 

76 mapper.redirect("", "/") 

77 

78 self.resources["availability_zones_legacy"] = ( 

79 availability_zones.create_resource_legacy()) 

80 # TODO(vponomaryov): "os-availability-zone" is deprecated 

81 # since v2.7. Remove it when minimum API version becomes equal to 

82 # or greater than v2.7. 

83 mapper.resource("availability-zone", 

84 "os-availability-zone", 

85 controller=self.resources["availability_zones_legacy"]) 

86 

87 self.resources["availability_zones"] = ( 

88 availability_zones.create_resource()) 

89 mapper.resource("availability-zone", 

90 "availability-zones", 

91 controller=self.resources["availability_zones"]) 

92 

93 self.resources["services_legacy"] = services.create_resource_legacy() 

94 # TODO(vponomaryov): "os-services" is deprecated 

95 # since v2.7. Remove it when minimum API version becomes equal to 

96 # or greater than v2.7. 

97 mapper.resource("service", 

98 "os-services", 

99 controller=self.resources["services_legacy"]) 

100 

101 self.resources["services"] = services.create_resource() 

102 mapper.resource("service", 

103 "services", 

104 controller=self.resources["services"]) 

105 for path_prefix in ['/{project_id}', '']: 

106 # project_id is optional 

107 mapper.connect("services", 

108 "%s/services/ensure-shares" % path_prefix, 

109 controller=self.resources["services"], 

110 action="ensure_shares", 

111 conditions={"method": ["POST"]}) 

112 

113 self.resources["quota_sets_legacy"] = ( 

114 quota_sets.create_resource_legacy()) 

115 # TODO(vponomaryov): "os-quota-sets" is deprecated 

116 # since v2.7. Remove it when minimum API version becomes equal to 

117 # or greater than v2.7. 

118 mapper.resource("quota-set", 

119 "os-quota-sets", 

120 controller=self.resources["quota_sets_legacy"], 

121 member={"defaults": "GET"}) 

122 

123 self.resources["quota_sets"] = quota_sets.create_resource() 

124 mapper.resource("quota-set", 

125 "quota-sets", 

126 controller=self.resources["quota_sets"], 

127 member={"defaults": "GET", 

128 "detail": "GET"}) 

129 

130 self.resources["quota_class_sets_legacy"] = ( 

131 quota_class_sets.create_resource_legacy()) 

132 # TODO(vponomaryov): "os-quota-class-sets" is deprecated 

133 # since v2.7. Remove it when minimum API version becomes equal to 

134 # or greater than v2.7. 

135 mapper.resource("quota-class-set", 

136 "os-quota-class-sets", 

137 controller=self.resources["quota_class_sets_legacy"]) 

138 

139 self.resources["quota_class_sets"] = quota_class_sets.create_resource() 

140 mapper.resource("quota-class-set", 

141 "quota-class-sets", 

142 controller=self.resources["quota_class_sets"]) 

143 

144 self.resources["share_manage"] = share_manage.create_resource() 

145 # TODO(vponomaryov): "os-share-manage" is deprecated 

146 # since v2.7. Remove it when minimum API version becomes equal to 

147 # or greater than v2.7. 

148 mapper.resource("share_manage", 

149 "os-share-manage", 

150 controller=self.resources["share_manage"]) 

151 

152 self.resources["share_unmanage"] = share_unmanage.create_resource() 

153 # TODO(vponomaryov): "os-share-unmanage" is deprecated 

154 # since v2.7. Remove it when minimum API version becomes equal to 

155 # or greater than v2.7. 

156 mapper.resource("share_unmanage", 

157 "os-share-unmanage", 

158 controller=self.resources["share_unmanage"], 

159 member={"unmanage": "POST"}) 

160 

161 self.resources["shares"] = shares.create_resource() 

162 mapper.resource("share", "shares", 

163 controller=self.resources["shares"], 

164 collection={"detail": "GET"}, 

165 member={"action": "POST"}) 

166 

167 for path_prefix in ['/{project_id}', '']: 

168 # project_id is optional 

169 mapper.connect("shares", 

170 "%s/shares/manage" % path_prefix, 

171 controller=self.resources["shares"], 

172 action="manage", 

173 conditions={"method": ["POST"]}) 

174 

175 for path_prefix in ['/{project_id}', '']: 

176 # project_id is optional 

177 mapper.connect("share_metadata", 

178 "%s/shares/{resource_id}/metadata" 

179 % path_prefix, 

180 controller=self.resources["shares"], 

181 action="create_metadata", 

182 conditions={"method": ["POST"]}) 

183 mapper.connect("share_metadata", 

184 "%s/shares/{resource_id}/metadata" 

185 % path_prefix, 

186 controller=self.resources["shares"], 

187 action="update_all_metadata", 

188 conditions={"method": ["PUT"]}) 

189 mapper.connect("share_metadata", 

190 "%s/shares/{resource_id}/metadata/{key}" 

191 % path_prefix, 

192 controller=self.resources["shares"], 

193 action="update_metadata_item", 

194 conditions={"method": ["POST"]}) 

195 mapper.connect("share_metadata", 

196 "%s/shares/{resource_id}/metadata" 

197 % path_prefix, 

198 controller=self.resources["shares"], 

199 action="index_metadata", 

200 conditions={"method": ["GET"]}) 

201 mapper.connect("share_metadata", 

202 "%s/shares/{resource_id}/metadata/{key}" 

203 % path_prefix, 

204 controller=self.resources["shares"], 

205 action="show_metadata", 

206 conditions={"method": ["GET"]}) 

207 mapper.connect("share_metadata", 

208 "%s/shares/{resource_id}/metadata/{key}" 

209 % path_prefix, 

210 controller=self.resources["shares"], 

211 action="delete_metadata", 

212 conditions={"method": ["DELETE"]}) 

213 

214 self.resources["share_instances"] = share_instances.create_resource() 

215 mapper.resource("share_instance", "share_instances", 

216 controller=self.resources["share_instances"], 

217 collection={"detail": "GET"}, 

218 member={"action": "POST"}) 

219 

220 self.resources["share_instance_export_locations"] = ( 

221 share_instance_export_locations.create_resource()) 

222 

223 for path_prefix in ['/{project_id}', '']: 

224 # project_id is optional 

225 mapper.connect("share_instances", 

226 ("%s/share_instances/{share_instance_id}" 

227 "/export_locations" % path_prefix), 

228 controller=self.resources[ 

229 "share_instance_export_locations"], 

230 action="index", 

231 conditions={"method": ["GET"]}) 

232 

233 mapper.connect("share_instances", 

234 ("%s/share_instances/{share_instance_id}" 

235 "/export_locations" 

236 "/{export_location_uuid}" % path_prefix), 

237 controller=self.resources[ 

238 "share_instance_export_locations"], 

239 action="show", 

240 conditions={"method": ["GET"]}) 

241 

242 mapper.connect("share_instance", 

243 "%s/shares/{share_id}/instances" % path_prefix, 

244 controller=self.resources["share_instances"], 

245 action="get_share_instances", 

246 conditions={"method": ["GET"]}) 

247 

248 self.resources["share_export_locations"] = ( 

249 share_export_locations.create_resource()) 

250 mapper.connect("shares", 

251 "%s/shares/{share_id}" 

252 "/export_locations" % path_prefix, 

253 controller=self.resources["share_export_locations"], 

254 action="index", 

255 conditions={"method": ["GET"]}) 

256 mapper.connect("shares", 

257 ("%s/shares/{share_id}/export_locations" 

258 "/{export_location_uuid}" % path_prefix), 

259 controller=self.resources["share_export_locations"], 

260 action="show", 

261 conditions={"method": ["GET"]}) 

262 mapper.connect("export_locations_metadata", 

263 "%s/shares/{share_id}/export_locations" 

264 "/{resource_id}/metadata" % path_prefix, 

265 controller=self.resources["share_export_locations"], 

266 action="create_metadata", 

267 conditions={"method": ["POST"]}) 

268 mapper.connect("export_locations_metadata", 

269 "%s/shares/{share_id}/export_locations" 

270 "/{resource_id}/metadata" % path_prefix, 

271 controller=self.resources["share_export_locations"], 

272 action="update_all_metadata", 

273 conditions={"method": ["PUT"]}) 

274 mapper.connect("export_locations_metadata", 

275 "%s/shares/{share_id}/export_locations/" 

276 "{resource_id}/metadata/{key}" 

277 % path_prefix, 

278 controller=self.resources["share_export_locations"], 

279 action="update_metadata_item", 

280 conditions={"method": ["POST"]}) 

281 mapper.connect("export_locations_metadata", 

282 "%s/shares/{share_id}/export_locations/" 

283 "{resource_id}/metadata" % path_prefix, 

284 controller=self.resources["share_export_locations"], 

285 action="index_metadata", 

286 conditions={"method": ["GET"]}) 

287 mapper.connect("export_locations_metadata", 

288 "%s/shares/{share_id}/export_locations/" 

289 "{resource_id}/metadata/{key}" 

290 % path_prefix, 

291 controller=self.resources["share_export_locations"], 

292 action="show_metadata", 

293 conditions={"method": ["GET"]}) 

294 mapper.connect("export_locations_metadata", 

295 "%s/shares/{share_id}/export_locations/" 

296 "{resource_id}/metadata/{key}" 

297 % path_prefix, 

298 controller=self.resources["share_export_locations"], 

299 action="delete_metadata", 

300 conditions={"method": ["DELETE"]}) 

301 

302 self.resources["snapshots"] = share_snapshots.create_resource() 

303 mapper.resource("snapshot", "snapshots", 

304 controller=self.resources["snapshots"], 

305 collection={"detail": "GET"}, 

306 member={"action": "POST"}) 

307 for path_prefix in ['/{project_id}', '']: 

308 # project_id is optional 

309 mapper.connect("snapshots_metadata", 

310 "%s/snapshots/{resource_id}/metadata" 

311 % path_prefix, 

312 controller=self.resources["snapshots"], 

313 action="create_metadata", 

314 conditions={"method": ["POST"]}) 

315 mapper.connect("snapshots_metadata", 

316 "%s/snapshots/{resource_id}/metadata" 

317 % path_prefix, 

318 controller=self.resources["snapshots"], 

319 action="update_all_metadata", 

320 conditions={"method": ["PUT"]}) 

321 mapper.connect("snapshots_metadata", 

322 "%s/snapshots/{resource_id}/metadata/{key}" 

323 % path_prefix, 

324 controller=self.resources["snapshots"], 

325 action="update_metadata_item", 

326 conditions={"method": ["POST"]}) 

327 mapper.connect("snapshots_metadata", 

328 "%s/snapshots/{resource_id}/metadata" 

329 % path_prefix, 

330 controller=self.resources["snapshots"], 

331 action="index_metadata", 

332 conditions={"method": ["GET"]}) 

333 mapper.connect("snapshots_metadata", 

334 "%s/snapshots/{resource_id}/metadata/{key}" 

335 % path_prefix, 

336 controller=self.resources["snapshots"], 

337 action="show_metadata", 

338 conditions={"method": ["GET"]}) 

339 mapper.connect("snapshots_metadata", 

340 "%s/snapshots/{resource_id}/metadata/{key}" 

341 % path_prefix, 

342 controller=self.resources["snapshots"], 

343 action="delete_metadata", 

344 conditions={"method": ["DELETE"]}) 

345 

346 for path_prefix in ['/{project_id}', '']: 

347 # project_id is optional 

348 mapper.connect("snapshots", 

349 "%s/snapshots/manage" % path_prefix, 

350 controller=self.resources["snapshots"], 

351 action="manage", 

352 conditions={"method": ["POST"]}) 

353 

354 mapper.connect("snapshots", 

355 "%s/snapshots/{snapshot_id}" 

356 "/access-list" % path_prefix, 

357 controller=self.resources["snapshots"], 

358 action="access_list", 

359 conditions={"method": ["GET"]}) 

360 

361 self.resources["share_snapshot_export_locations"] = ( 

362 share_snapshot_export_locations.create_resource()) 

363 mapper.connect("snapshots", 

364 "%s/snapshots/{snapshot_id}" 

365 "/export-locations" % path_prefix, 

366 controller=self.resources[ 

367 "share_snapshot_export_locations"], 

368 action="index", 

369 conditions={"method": ["GET"]}) 

370 

371 mapper.connect("snapshots", 

372 "%s/snapshots/{snapshot_id}/export-locations" 

373 "/{export_location_id}" % path_prefix, 

374 controller=self.resources[ 

375 "share_snapshot_export_locations"], 

376 action="show", 

377 conditions={"method": ["GET"]}) 

378 

379 self.resources['snapshot_instances'] = ( 

380 share_snapshot_instances.create_resource()) 

381 mapper.resource("snapshot-instance", "snapshot-instances", 

382 controller=self.resources['snapshot_instances'], 

383 collection={'detail': 'GET'}, 

384 member={'action': 'POST'}) 

385 

386 self.resources["share_snapshot_instance_export_locations"] = ( 

387 share_snapshot_instance_export_locations.create_resource()) 

388 

389 for path_prefix in ['/{project_id}', '']: 

390 # project_id is optional 

391 mapper.connect("snapshot-instance", 

392 "%s/snapshot-instances/{snapshot_instance_id}" 

393 "/export-locations" % path_prefix, 

394 controller=self.resources[ 

395 "share_snapshot_instance_export_locations"], 

396 action="index", 

397 conditions={"method": ["GET"]}) 

398 

399 mapper.connect("snapshot-instance", 

400 "%s/snapshot-instances/{snapshot_instance_id}" 

401 "/export-locations" 

402 "/{export_location_id}" % path_prefix, 

403 controller=self.resources[ 

404 "share_snapshot_instance_export_locations"], 

405 action="show", 

406 conditions={"method": ["GET"]}) 

407 

408 self.resources["limits"] = limits.create_resource() 

409 mapper.resource("limit", "limits", 

410 controller=self.resources["limits"]) 

411 

412 self.resources["security_services"] = ( 

413 security_service.create_resource()) 

414 mapper.resource("security-service", "security-services", 

415 controller=self.resources["security_services"], 

416 collection={"detail": "GET"}) 

417 

418 self.resources["share_networks"] = share_networks.create_resource() 

419 mapper.resource(share_networks.RESOURCE_NAME, 

420 "share-networks", 

421 controller=self.resources["share_networks"], 

422 collection={"detail": "GET"}, 

423 member={"action": "POST"}) 

424 

425 for path_prefix in ['/{project_id}', '']: 

426 # project_id is optional 

427 self.resources["share_network_subnets"] = ( 

428 share_network_subnets.create_resource()) 

429 mapper.connect("share-networks", 

430 "%s/share-networks/{share_network_id}" 

431 "/subnets" % path_prefix, 

432 controller=self.resources["share_network_subnets"], 

433 action="create", 

434 conditions={"method": ["POST"]}) 

435 mapper.connect("share-networks", 

436 "%s/share-networks/{share_network_id}" 

437 "/subnets/{share_network_subnet_id}" % path_prefix, 

438 controller=self.resources["share_network_subnets"], 

439 action="delete", 

440 conditions={"method": ["DELETE"]}) 

441 mapper.connect("share-networks", 

442 "%s/share-networks/{share_network_id}" 

443 "/subnets/{share_network_subnet_id}" % path_prefix, 

444 controller=self.resources["share_network_subnets"], 

445 action="show", 

446 conditions={"method": ["GET"]}) 

447 mapper.connect("share-networks", 

448 "%s/share-networks/{share_network_id}" 

449 "/subnets" % path_prefix, 

450 controller=self.resources["share_network_subnets"], 

451 action="index", 

452 conditions={"method": ["GET"]}) 

453 

454 for path_prefix in ['/{project_id}', '']: 

455 # project_id is optional 

456 mapper.connect("subnets_metadata", 

457 "%s/share-networks/{share_network_id}" 

458 "/subnets/{resource_id}/metadata" % path_prefix, 

459 controller=self.resources["share_network_subnets"], 

460 action="create_metadata", 

461 conditions={"method": ["POST"]}) 

462 mapper.connect("subnets_metadata", 

463 "%s/share-networks/{share_network_id}" 

464 "/subnets/{resource_id}/metadata" % path_prefix, 

465 controller=self.resources["share_network_subnets"], 

466 action="update_all_metadata", 

467 conditions={"method": ["PUT"]}) 

468 mapper.connect("subnets_metadata", 

469 "%s/share-networks/{share_network_id}" 

470 "/subnets/{resource_id}" 

471 "/metadata/{key}" % path_prefix, 

472 controller=self.resources["share_network_subnets"], 

473 action="update_metadata_item", 

474 conditions={"method": ["POST"]}) 

475 mapper.connect("subnets_metadata", 

476 "%s/share-networks/{share_network_id}" 

477 "/subnets/{resource_id}/metadata" % path_prefix, 

478 controller=self.resources["share_network_subnets"], 

479 action="index_metadata", 

480 conditions={"method": ["GET"]}) 

481 mapper.connect("subnets_metadata", 

482 "%s/share-networks/{share_network_id}" 

483 "/subnets/{resource_id}" 

484 "/metadata/{key}" % path_prefix, 

485 controller=self.resources["share_network_subnets"], 

486 action="show_metadata", 

487 conditions={"method": ["GET"]}) 

488 mapper.connect("subnets_metadata", 

489 "%s/share-networks/{share_network_id}" 

490 "/subnets/{resource_id}" 

491 "/metadata/{key}" % path_prefix, 

492 controller=self.resources["share_network_subnets"], 

493 action="delete_metadata", 

494 conditions={"method": ["DELETE"]}) 

495 

496 self.resources["share_servers"] = share_servers.create_resource() 

497 mapper.resource("share_server", 

498 "share-servers", 

499 controller=self.resources["share_servers"], 

500 member={"action": "POST"}) 

501 

502 for path_prefix in ['/{project_id}', '']: 

503 # project_id is optional 

504 mapper.connect("details", 

505 "%s/share-servers/{id}/details" % path_prefix, 

506 controller=self.resources["share_servers"], 

507 action="details", 

508 conditions={"method": ["GET"]}) 

509 mapper.connect("share_servers", 

510 "%s/share-servers/manage" % path_prefix, 

511 controller=self.resources["share_servers"], 

512 action="manage", 

513 conditions={"method": ["POST"]}) 

514 

515 self.resources["types"] = share_types.create_resource() 

516 mapper.resource("type", "types", 

517 controller=self.resources["types"], 

518 collection={"detail": "GET", "default": "GET"}, 

519 member={"action": "POST", 

520 "os-share-type-access": "GET", 

521 "share_type_access": "GET"}) 

522 

523 self.resources["extra_specs"] = ( 

524 share_types_extra_specs.create_resource()) 

525 mapper.resource("extra_spec", "extra_specs", 

526 controller=self.resources["extra_specs"], 

527 parent_resource=dict(member_name="type", 

528 collection_name="types")) 

529 

530 self.resources["scheduler_stats"] = scheduler_stats.create_resource() 

531 for path_prefix in ['/{project_id}', '']: 

532 # project_id is optional 

533 mapper.connect("pools", 

534 "%s/scheduler-stats/pools" % path_prefix, 

535 controller=self.resources["scheduler_stats"], 

536 action="pools_index", 

537 conditions={"method": ["GET"]}) 

538 mapper.connect("pools", 

539 "%s/scheduler-stats/pools/detail" % path_prefix, 

540 controller=self.resources["scheduler_stats"], 

541 action="pools_detail", 

542 conditions={"method": ["GET"]}) 

543 

544 self.resources["share-groups"] = share_groups.create_resource() 

545 mapper.resource( 

546 "share-group", 

547 "share-groups", 

548 controller=self.resources["share-groups"], 

549 collection={"detail": "GET"}) 

550 for path_prefix in ['/{project_id}', '']: 

551 # project_id is optional 

552 mapper.connect( 

553 "share-groups", 

554 "%s/share-groups/{id}/action" % path_prefix, 

555 controller=self.resources["share-groups"], 

556 action="action", 

557 conditions={"method": ["POST"]}) 

558 

559 self.resources["share-group-types"] = ( 

560 share_group_types.create_resource()) 

561 mapper.resource( 

562 "share-group-type", 

563 "share-group-types", 

564 controller=self.resources["share-group-types"], 

565 collection={"detail": "GET", "default": "GET"}, 

566 member={"action": "POST"}) 

567 for path_prefix in ['/{project_id}', '']: 

568 # project_id is optional 

569 mapper.connect( 

570 "share-group-types", 

571 "%s/share-group-types/{id}/access" % path_prefix, 

572 controller=self.resources["share-group-types"], 

573 action="share_group_type_access", 

574 conditions={"method": ["GET"]}) 

575 

576 # NOTE(ameade): These routes can be simplified when the following 

577 # issue is fixed: https://github.com/bbangert/routes/issues/68 

578 self.resources["group-specs"] = ( 

579 share_group_type_specs.create_resource()) 

580 

581 for path_prefix in ['/{project_id}', '']: 

582 # project_id is optional 

583 mapper.connect( 

584 "share-group-types", 

585 "%s/share-group-types/{id}/group-specs" % path_prefix, 

586 controller=self.resources["group-specs"], 

587 action="index", 

588 conditions={"method": ["GET"]}) 

589 mapper.connect( 

590 "share-group-types", 

591 "%s/share-group-types/{id}/group-specs" % path_prefix, 

592 controller=self.resources["group-specs"], 

593 action="create", 

594 conditions={"method": ["POST"]}) 

595 mapper.connect( 

596 "share-group-types", 

597 "%s/share-group-types/{id}/group-specs/{key}" % path_prefix, 

598 controller=self.resources["group-specs"], 

599 action="show", 

600 conditions={"method": ["GET"]}) 

601 mapper.connect( 

602 "share-group-types", 

603 "%s/share-group-types/{id}/group-specs/{key}" % path_prefix, 

604 controller=self.resources["group-specs"], 

605 action="delete", 

606 conditions={"method": ["DELETE"]}) 

607 mapper.connect( 

608 "share-group-types", 

609 "%s/share-group-types/{id}/group-specs/{key}" % path_prefix, 

610 controller=self.resources["group-specs"], 

611 action="update", 

612 conditions={"method": ["PUT"]}) 

613 

614 self.resources["share-group-snapshots"] = ( 

615 share_group_snapshots.create_resource()) 

616 mapper.resource( 

617 "share-group-snapshot", 

618 "share-group-snapshots", 

619 controller=self.resources["share-group-snapshots"], 

620 collection={"detail": "GET"}, 

621 member={"members": "GET", "action": "POST"}) 

622 

623 for path_prefix in ['/{project_id}', '']: 

624 # project_id is optional 

625 mapper.connect( 

626 "share-group-snapshots", 

627 "%s/share-group-snapshots/{id}/action" % path_prefix, 

628 controller=self.resources["share-group-snapshots"], 

629 action="action", 

630 conditions={"method": ["POST"]}) 

631 

632 self.resources['share-replicas'] = share_replicas.create_resource() 

633 mapper.resource("share-replica", "share-replicas", 

634 controller=self.resources['share-replicas'], 

635 collection={'detail': 'GET'}, 

636 member={'action': 'POST'}) 

637 

638 self.resources['share_transfers'] = ( 

639 share_transfer.create_resource()) 

640 mapper.resource("share-transfer", "share-transfers", 

641 controller=self.resources['share_transfers'], 

642 collection={'detail': 'GET'}, 

643 member={'accept': 'POST'}) 

644 

645 self.resources["share-replica-export-locations"] = ( 

646 share_replica_export_locations.create_resource()) 

647 for path_prefix in ['/{project_id}', '']: 

648 # project_id is optional 

649 mapper.connect("share-replicas", 

650 ("%s/share-replicas/{share_replica_id}" 

651 "/export-locations" % path_prefix), 

652 controller=self.resources[ 

653 "share-replica-export-locations"], 

654 action="index", 

655 conditions={"method": ["GET"]}) 

656 mapper.connect("share-replicas", 

657 ("%s/share-replicas/{share_replica_id}" 

658 "/export-locations" 

659 "/{export_location_uuid}" % path_prefix), 

660 controller=self.resources[ 

661 "share-replica-export-locations"], 

662 action="show", 

663 conditions={"method": ["GET"]}) 

664 

665 self.resources['messages'] = messages.create_resource() 

666 mapper.resource("message", "messages", 

667 controller=self.resources['messages']) 

668 

669 self.resources["share-access-rules"] = share_accesses.create_resource() 

670 mapper.resource( 

671 "share-access-rule", 

672 "share-access-rules", 

673 controller=self.resources["share-access-rules"], 

674 collection={"detail": "GET"}) 

675 

676 for path_prefix in ['/{project_id}', '']: 

677 # project_id is optional 

678 self.resources["access-metadata"] = ( 

679 share_access_metadata.create_resource()) 

680 access_metadata_controller = self.resources["access-metadata"] 

681 mapper.connect("share-access-rules", 

682 "%s/share-access-rules" 

683 "/{access_id}/metadata" % path_prefix, 

684 controller=access_metadata_controller, 

685 action="update", 

686 conditions={"method": ["PUT"]}) 

687 

688 mapper.connect("share-access-rules", 

689 "%s/share-access-rules" 

690 "/{access_id}/metadata/{key}" % path_prefix, 

691 controller=access_metadata_controller, 

692 action="delete", 

693 conditions={"method": ["DELETE"]}) 

694 

695 self.resources['share-backups'] = share_backups.create_resource() 

696 mapper.resource("share-backup", 

697 "share-backups", 

698 controller=self.resources['share-backups'], 

699 collection={'detail': 'GET'}, 

700 member={'action': 'POST'}) 

701 

702 self.resources["resource_locks"] = resource_locks.create_resource() 

703 mapper.resource("resource-lock", "resource-locks", 

704 controller=self.resources["resource_locks"])