1use async_trait::async_trait;
17use chrono::{DateTime, Utc};
18use http::{Method, StatusCode};
19use serde_json::{json, Map, Value};
20use std::sync::Arc;
21use tokio::sync::Mutex as AsyncMutex;
22
23use fakecloud_core::pagination::paginate_checked;
24use fakecloud_core::service::{AwsRequest, AwsResponse, AwsService, AwsServiceError};
25use fakecloud_persistence::SnapshotStore;
26
27use crate::state::{
28 framework_arn, legal_hold_arn, plan_arn, recovery_point_arn, report_plan_arn,
29 restore_testing_plan_arn, tiering_configuration_arn, vault_arn, PlanRecord, PlanVersion,
30 RestoreTestingPlanRecord, RestoreTestingSelectionRecord, SelectionRecord, SharedBackupState,
31 TagMap, VaultRecord,
32};
33
34const SUPPORTED_RESOURCE_TYPES: &[&str] = &[
37 "Aurora",
38 "CloudFormation",
39 "DocumentDB",
40 "DynamoDB",
41 "EBS",
42 "EC2",
43 "EFS",
44 "FSx",
45 "Neptune",
46 "RDS",
47 "Redshift",
48 "S3",
49 "SAP HANA on Amazon EC2",
50 "Storage Gateway",
51 "Timestream",
52 "VirtualMachine",
53];
54
55pub const BACKUP_ACTIONS: &[&str] = &[
56 "AssociateBackupVaultMpaApprovalTeam",
57 "CancelLegalHold",
58 "CreateBackupPlan",
59 "CreateBackupSelection",
60 "CreateBackupVault",
61 "CreateFramework",
62 "CreateLegalHold",
63 "CreateLogicallyAirGappedBackupVault",
64 "CreateReportPlan",
65 "CreateRestoreAccessBackupVault",
66 "CreateRestoreTestingPlan",
67 "CreateRestoreTestingSelection",
68 "CreateTieringConfiguration",
69 "DeleteBackupPlan",
70 "DeleteBackupSelection",
71 "DeleteBackupVault",
72 "DeleteBackupVaultAccessPolicy",
73 "DeleteBackupVaultLockConfiguration",
74 "DeleteBackupVaultNotifications",
75 "DeleteFramework",
76 "DeleteRecoveryPoint",
77 "DeleteReportPlan",
78 "DeleteRestoreTestingPlan",
79 "DeleteRestoreTestingSelection",
80 "DeleteTieringConfiguration",
81 "DescribeBackupJob",
82 "DescribeBackupVault",
83 "DescribeCopyJob",
84 "DescribeFramework",
85 "DescribeGlobalSettings",
86 "DescribeProtectedResource",
87 "DescribeRecoveryPoint",
88 "DescribeRegionSettings",
89 "DescribeReportJob",
90 "DescribeReportPlan",
91 "DescribeRestoreJob",
92 "DescribeScanJob",
93 "DisassociateBackupVaultMpaApprovalTeam",
94 "DisassociateRecoveryPoint",
95 "DisassociateRecoveryPointFromParent",
96 "ExportBackupPlanTemplate",
97 "GetBackupPlan",
98 "GetBackupPlanFromJSON",
99 "GetBackupPlanFromTemplate",
100 "GetBackupSelection",
101 "GetBackupVaultAccessPolicy",
102 "GetBackupVaultNotifications",
103 "GetLegalHold",
104 "GetPITRMalwareScanResults",
105 "GetRecoveryPointIndexDetails",
106 "GetRecoveryPointRestoreMetadata",
107 "GetRestoreJobMetadata",
108 "GetRestoreTestingInferredMetadata",
109 "GetRestoreTestingPlan",
110 "GetRestoreTestingSelection",
111 "GetSupportedResourceTypes",
112 "GetTieringConfiguration",
113 "ListBackupJobSummaries",
114 "ListBackupJobs",
115 "ListBackupPlanTemplates",
116 "ListBackupPlanVersions",
117 "ListBackupPlans",
118 "ListBackupSelections",
119 "ListBackupVaults",
120 "ListCopyJobSummaries",
121 "ListCopyJobs",
122 "ListFrameworks",
123 "ListIndexedRecoveryPoints",
124 "ListLegalHolds",
125 "ListProtectedResources",
126 "ListProtectedResourcesByBackupVault",
127 "ListRecoveryPointsByBackupVault",
128 "ListRecoveryPointsByLegalHold",
129 "ListRecoveryPointsByResource",
130 "ListReportJobs",
131 "ListReportPlans",
132 "ListRestoreAccessBackupVaults",
133 "ListRestoreJobSummaries",
134 "ListRestoreJobs",
135 "ListRestoreJobsByProtectedResource",
136 "ListRestoreTestingPlans",
137 "ListRestoreTestingSelections",
138 "ListScanJobSummaries",
139 "ListScanJobs",
140 "ListTags",
141 "ListTieringConfigurations",
142 "PutBackupVaultAccessPolicy",
143 "PutBackupVaultLockConfiguration",
144 "PutBackupVaultNotifications",
145 "PutRestoreValidationResult",
146 "RevokeRestoreAccessBackupVault",
147 "StartBackupJob",
148 "StartCopyJob",
149 "StartReportJob",
150 "StartRestoreJob",
151 "StartScanJob",
152 "StopBackupJob",
153 "TagResource",
154 "UntagResource",
155 "UpdateBackupPlan",
156 "UpdateFramework",
157 "UpdateGlobalSettings",
158 "UpdateRecoveryPointIndexSettings",
159 "UpdateRecoveryPointLifecycle",
160 "UpdateRegionSettings",
161 "UpdateReportPlan",
162 "UpdateRestoreTestingPlan",
163 "UpdateRestoreTestingSelection",
164 "UpdateTieringConfiguration",
165];
166
167pub struct BackupService {
168 state: SharedBackupState,
169 snapshot_store: Option<Arc<dyn SnapshotStore>>,
170 snapshot_lock: Arc<AsyncMutex<()>>,
171}
172
173type Labels = Vec<String>;
175
176impl BackupService {
177 pub fn new(state: SharedBackupState) -> Self {
178 Self {
179 state,
180 snapshot_store: None,
181 snapshot_lock: Arc::new(AsyncMutex::new(())),
182 }
183 }
184
185 pub fn with_snapshot_store(mut self, store: Arc<dyn SnapshotStore>) -> Self {
186 self.snapshot_store = Some(store);
187 self
188 }
189
190 async fn save_snapshot(&self) {
191 crate::persistence::save_snapshot(
192 &self.state,
193 self.snapshot_store.clone(),
194 &self.snapshot_lock,
195 )
196 .await;
197 }
198
199 pub fn snapshot_hook(&self) -> Option<fakecloud_persistence::SnapshotHook> {
201 let store = self.snapshot_store.clone()?;
202 let state = self.state.clone();
203 let lock = self.snapshot_lock.clone();
204 Some(Arc::new(move || {
205 let state = state.clone();
206 let store = store.clone();
207 let lock = lock.clone();
208 Box::pin(async move {
209 crate::persistence::save_snapshot(&state, Some(store), &lock).await;
210 })
211 }))
212 }
213
214 fn resolve_action(req: &AwsRequest) -> Option<(&'static str, Labels)> {
218 let raw = req.raw_path.split('?').next().unwrap_or(&req.raw_path);
219 let trimmed = raw.strip_prefix('/').unwrap_or(raw);
225 let segs: Vec<&str> = if trimmed.is_empty() {
226 Vec::new()
227 } else {
228 trimmed.split('/').collect()
229 };
230 let m = &req.method;
231 let d = |s: &str| decode(s);
232 let one = |a| Some((a, Vec::new()));
233 macro_rules! l {
234 ($a:expr, $($x:expr),*) => { Some(($a, vec![$($x),*])) };
235 }
236 match (m, segs.as_slice()) {
237 (&Method::PUT, ["backup", "plans"]) => one("CreateBackupPlan"),
239 (&Method::GET, ["backup", "plans"]) => one("ListBackupPlans"),
240 (&Method::GET, ["backup", "plans", id]) => l!("GetBackupPlan", d(id)),
241 (&Method::POST, ["backup", "plans", id]) => l!("UpdateBackupPlan", d(id)),
242 (&Method::DELETE, ["backup", "plans", id]) => l!("DeleteBackupPlan", d(id)),
243 (&Method::GET, ["backup", "plans", id, "versions"]) => {
244 l!("ListBackupPlanVersions", d(id))
245 }
246 (&Method::PUT, ["backup", "plans", id, "selections"]) => {
247 l!("CreateBackupSelection", d(id))
248 }
249 (&Method::GET, ["backup", "plans", id, "selections"]) => {
250 l!("ListBackupSelections", d(id))
251 }
252 (&Method::GET, ["backup", "plans", id, "selections", sid]) => {
253 l!("GetBackupSelection", d(id), d(sid))
254 }
255 (&Method::DELETE, ["backup", "plans", id, "selections", sid]) => {
256 l!("DeleteBackupSelection", d(id), d(sid))
257 }
258 (&Method::GET, ["backup", "plans", id, "toTemplate"]) => {
259 l!("ExportBackupPlanTemplate", d(id))
260 }
261 (&Method::POST, ["backup", "template", "json", "toPlan"]) => {
262 one("GetBackupPlanFromJSON")
263 }
264 (&Method::GET, ["backup", "template", "plans"]) => one("ListBackupPlanTemplates"),
265 (&Method::GET, ["backup", "template", "plans", tid, "toPlan"]) => {
266 l!("GetBackupPlanFromTemplate", d(tid))
267 }
268 (&Method::GET, ["backup-vaults"]) => one("ListBackupVaults"),
270 (&Method::PUT, ["backup-vaults", name]) => l!("CreateBackupVault", d(name)),
271 (&Method::GET, ["backup-vaults", name]) => l!("DescribeBackupVault", d(name)),
272 (&Method::DELETE, ["backup-vaults", name]) => l!("DeleteBackupVault", d(name)),
273 (&Method::PUT, ["backup-vaults", name, "access-policy"]) => {
274 l!("PutBackupVaultAccessPolicy", d(name))
275 }
276 (&Method::GET, ["backup-vaults", name, "access-policy"]) => {
277 l!("GetBackupVaultAccessPolicy", d(name))
278 }
279 (&Method::DELETE, ["backup-vaults", name, "access-policy"]) => {
280 l!("DeleteBackupVaultAccessPolicy", d(name))
281 }
282 (&Method::PUT, ["backup-vaults", name, "vault-lock"]) => {
283 l!("PutBackupVaultLockConfiguration", d(name))
284 }
285 (&Method::DELETE, ["backup-vaults", name, "vault-lock"]) => {
286 l!("DeleteBackupVaultLockConfiguration", d(name))
287 }
288 (&Method::PUT, ["backup-vaults", name, "notification-configuration"]) => {
289 l!("PutBackupVaultNotifications", d(name))
290 }
291 (&Method::GET, ["backup-vaults", name, "notification-configuration"]) => {
292 l!("GetBackupVaultNotifications", d(name))
293 }
294 (&Method::DELETE, ["backup-vaults", name, "notification-configuration"]) => {
295 l!("DeleteBackupVaultNotifications", d(name))
296 }
297 (&Method::PUT, ["backup-vaults", name, "mpaApprovalTeam"]) => {
298 l!("AssociateBackupVaultMpaApprovalTeam", d(name))
299 }
300 (&Method::POST, ["backup-vaults", name, "mpaApprovalTeam"]) => {
301 l!("DisassociateBackupVaultMpaApprovalTeam", d(name))
302 }
303 (&Method::GET, ["backup-vaults", name, "recovery-points"]) => {
304 l!("ListRecoveryPointsByBackupVault", d(name))
305 }
306 (&Method::GET, ["backup-vaults", name, "recovery-points", rp]) => {
307 l!("DescribeRecoveryPoint", d(name), d(rp))
308 }
309 (&Method::DELETE, ["backup-vaults", name, "recovery-points", rp]) => {
310 l!("DeleteRecoveryPoint", d(name), d(rp))
311 }
312 (&Method::POST, ["backup-vaults", name, "recovery-points", rp]) => {
313 l!("UpdateRecoveryPointLifecycle", d(name), d(rp))
314 }
315 (&Method::GET, ["backup-vaults", name, "recovery-points", rp, "index"]) => {
316 l!("GetRecoveryPointIndexDetails", d(name), d(rp))
317 }
318 (&Method::POST, ["backup-vaults", name, "recovery-points", rp, "index"]) => {
319 l!("UpdateRecoveryPointIndexSettings", d(name), d(rp))
320 }
321 (&Method::GET, ["backup-vaults", name, "recovery-points", rp, "restore-metadata"]) => {
322 l!("GetRecoveryPointRestoreMetadata", d(name), d(rp))
323 }
324 (&Method::POST, ["backup-vaults", name, "recovery-points", rp, "disassociate"]) => {
325 l!("DisassociateRecoveryPoint", d(name), d(rp))
326 }
327 (
328 &Method::DELETE,
329 ["backup-vaults", name, "recovery-points", rp, "parentAssociation"],
330 ) => {
331 l!("DisassociateRecoveryPointFromParent", d(name), d(rp))
332 }
333 (&Method::GET, ["backup-vaults", name, "resources"]) => {
334 l!("ListProtectedResourcesByBackupVault", d(name))
335 }
336 (&Method::PUT, ["logically-air-gapped-backup-vaults", name]) => {
338 l!("CreateLogicallyAirGappedBackupVault", d(name))
339 }
340 (
341 &Method::GET,
342 ["logically-air-gapped-backup-vaults", name, "restore-access-backup-vaults"],
343 ) => {
344 l!("ListRestoreAccessBackupVaults", d(name))
345 }
346 (
347 &Method::DELETE,
348 ["logically-air-gapped-backup-vaults", name, "restore-access-backup-vaults", arn],
349 ) => {
350 l!("RevokeRestoreAccessBackupVault", d(name), d(arn))
351 }
352 (&Method::PUT, ["restore-access-backup-vaults"]) => {
353 one("CreateRestoreAccessBackupVault")
354 }
355 (&Method::POST, ["legal-holds"]) => one("CreateLegalHold"),
357 (&Method::GET, ["legal-holds"]) => one("ListLegalHolds"),
358 (&Method::GET, ["legal-holds", id]) => l!("GetLegalHold", d(id)),
359 (&Method::DELETE, ["legal-holds", id]) => l!("CancelLegalHold", d(id)),
360 (&Method::GET, ["legal-holds", id, "recovery-points"]) => {
361 l!("ListRecoveryPointsByLegalHold", d(id))
362 }
363 (&Method::POST, ["audit", "frameworks"]) => one("CreateFramework"),
365 (&Method::GET, ["audit", "frameworks"]) => one("ListFrameworks"),
366 (&Method::GET, ["audit", "frameworks", name]) => l!("DescribeFramework", d(name)),
367 (&Method::PUT, ["audit", "frameworks", name]) => l!("UpdateFramework", d(name)),
368 (&Method::DELETE, ["audit", "frameworks", name]) => l!("DeleteFramework", d(name)),
369 (&Method::POST, ["audit", "report-plans"]) => one("CreateReportPlan"),
370 (&Method::GET, ["audit", "report-plans"]) => one("ListReportPlans"),
371 (&Method::GET, ["audit", "report-plans", name]) => l!("DescribeReportPlan", d(name)),
372 (&Method::PUT, ["audit", "report-plans", name]) => l!("UpdateReportPlan", d(name)),
373 (&Method::DELETE, ["audit", "report-plans", name]) => l!("DeleteReportPlan", d(name)),
374 (&Method::GET, ["audit", "report-jobs"]) => one("ListReportJobs"),
375 (&Method::GET, ["audit", "report-jobs", id]) => l!("DescribeReportJob", d(id)),
376 (&Method::POST, ["audit", "report-jobs", name]) => l!("StartReportJob", d(name)),
377 (&Method::GET, ["audit", "backup-job-summaries"]) => one("ListBackupJobSummaries"),
378 (&Method::GET, ["audit", "copy-job-summaries"]) => one("ListCopyJobSummaries"),
379 (&Method::GET, ["audit", "restore-job-summaries"]) => one("ListRestoreJobSummaries"),
380 (&Method::GET, ["audit", "scan-job-summaries"]) => one("ListScanJobSummaries"),
381 (&Method::GET, ["backup-jobs"]) => one("ListBackupJobs"),
383 (&Method::PUT, ["backup-jobs"]) => one("StartBackupJob"),
384 (&Method::GET, ["backup-jobs", id]) => l!("DescribeBackupJob", d(id)),
385 (&Method::POST, ["backup-jobs", id]) => l!("StopBackupJob", d(id)),
386 (&Method::GET, ["copy-jobs"]) => one("ListCopyJobs"),
387 (&Method::PUT, ["copy-jobs"]) => one("StartCopyJob"),
388 (&Method::GET, ["copy-jobs", id]) => l!("DescribeCopyJob", d(id)),
389 (&Method::GET, ["restore-jobs"]) => one("ListRestoreJobs"),
390 (&Method::PUT, ["restore-jobs"]) => one("StartRestoreJob"),
391 (&Method::GET, ["restore-jobs", id]) => l!("DescribeRestoreJob", d(id)),
392 (&Method::GET, ["restore-jobs", id, "metadata"]) => l!("GetRestoreJobMetadata", d(id)),
393 (&Method::PUT, ["restore-jobs", id, "validations"]) => {
394 l!("PutRestoreValidationResult", d(id))
395 }
396 (&Method::GET, ["scan", "jobs"]) => one("ListScanJobs"),
397 (&Method::GET, ["scan", "jobs", id]) => l!("DescribeScanJob", d(id)),
398 (&Method::PUT, ["scan", "job"]) => one("StartScanJob"),
399 (&Method::GET, ["scan", "pitr-malware-scan-results"]) => {
400 one("GetPITRMalwareScanResults")
401 }
402 (&Method::GET, ["resources"]) => one("ListProtectedResources"),
404 (&Method::GET, ["resources", arn]) => l!("DescribeProtectedResource", d(arn)),
405 (&Method::GET, ["resources", arn, "recovery-points"]) => {
406 l!("ListRecoveryPointsByResource", d(arn))
407 }
408 (&Method::GET, ["resources", arn, "restore-jobs"]) => {
409 l!("ListRestoreJobsByProtectedResource", d(arn))
410 }
411 (&Method::PUT, ["restore-testing", "plans"]) => one("CreateRestoreTestingPlan"),
413 (&Method::GET, ["restore-testing", "plans"]) => one("ListRestoreTestingPlans"),
414 (&Method::GET, ["restore-testing", "inferred-metadata"]) => {
415 one("GetRestoreTestingInferredMetadata")
416 }
417 (&Method::GET, ["restore-testing", "plans", name]) => {
418 l!("GetRestoreTestingPlan", d(name))
419 }
420 (&Method::PUT, ["restore-testing", "plans", name]) => {
421 l!("UpdateRestoreTestingPlan", d(name))
422 }
423 (&Method::DELETE, ["restore-testing", "plans", name]) => {
424 l!("DeleteRestoreTestingPlan", d(name))
425 }
426 (&Method::PUT, ["restore-testing", "plans", name, "selections"]) => {
427 l!("CreateRestoreTestingSelection", d(name))
428 }
429 (&Method::GET, ["restore-testing", "plans", name, "selections"]) => {
430 l!("ListRestoreTestingSelections", d(name))
431 }
432 (&Method::GET, ["restore-testing", "plans", name, "selections", sname]) => {
433 l!("GetRestoreTestingSelection", d(name), d(sname))
434 }
435 (&Method::PUT, ["restore-testing", "plans", name, "selections", sname]) => {
436 l!("UpdateRestoreTestingSelection", d(name), d(sname))
437 }
438 (&Method::DELETE, ["restore-testing", "plans", name, "selections", sname]) => {
439 l!("DeleteRestoreTestingSelection", d(name), d(sname))
440 }
441 (&Method::PUT, ["tiering-configurations"]) => one("CreateTieringConfiguration"),
443 (&Method::GET, ["tiering-configurations"]) => one("ListTieringConfigurations"),
444 (&Method::GET, ["tiering-configurations", name]) => {
445 l!("GetTieringConfiguration", d(name))
446 }
447 (&Method::PUT, ["tiering-configurations", name]) => {
448 l!("UpdateTieringConfiguration", d(name))
449 }
450 (&Method::DELETE, ["tiering-configurations", name]) => {
451 l!("DeleteTieringConfiguration", d(name))
452 }
453 (&Method::GET, ["indexes", "recovery-point"]) => one("ListIndexedRecoveryPoints"),
455 (&Method::GET, ["global-settings"]) => one("DescribeGlobalSettings"),
456 (&Method::PUT, ["global-settings"]) => one("UpdateGlobalSettings"),
457 (&Method::GET, ["account-settings"]) => one("DescribeRegionSettings"),
458 (&Method::PUT, ["account-settings"]) => one("UpdateRegionSettings"),
459 (&Method::GET, ["supported-resource-types"]) => one("GetSupportedResourceTypes"),
460 (&Method::GET, ["tags", arn]) => l!("ListTags", d(arn)),
461 (&Method::POST, ["tags", arn]) => l!("TagResource", d(arn)),
462 (&Method::POST, ["untag", arn]) => l!("UntagResource", d(arn)),
463 _ => None,
464 }
465 }
466}
467
468const MUTATING: &[&str] = &[
469 "CreateBackupPlan",
470 "CreateBackupSelection",
471 "CreateBackupVault",
472 "CreateFramework",
473 "CreateLegalHold",
474 "CreateLogicallyAirGappedBackupVault",
475 "CreateReportPlan",
476 "CreateRestoreAccessBackupVault",
477 "CreateRestoreTestingPlan",
478 "CreateRestoreTestingSelection",
479 "CreateTieringConfiguration",
480 "DeleteBackupPlan",
481 "DeleteBackupSelection",
482 "DeleteBackupVault",
483 "DeleteBackupVaultAccessPolicy",
484 "DeleteBackupVaultLockConfiguration",
485 "DeleteBackupVaultNotifications",
486 "DeleteFramework",
487 "DeleteRecoveryPoint",
488 "DeleteReportPlan",
489 "DeleteRestoreTestingPlan",
490 "DeleteRestoreTestingSelection",
491 "DeleteTieringConfiguration",
492 "AssociateBackupVaultMpaApprovalTeam",
493 "DisassociateBackupVaultMpaApprovalTeam",
494 "DisassociateRecoveryPoint",
495 "DisassociateRecoveryPointFromParent",
496 "CancelLegalHold",
497 "PutBackupVaultAccessPolicy",
498 "PutBackupVaultLockConfiguration",
499 "PutBackupVaultNotifications",
500 "PutRestoreValidationResult",
501 "RevokeRestoreAccessBackupVault",
502 "StartBackupJob",
503 "StartCopyJob",
504 "StartReportJob",
505 "StartRestoreJob",
506 "StartScanJob",
507 "StopBackupJob",
508 "TagResource",
509 "UntagResource",
510 "UpdateBackupPlan",
511 "UpdateFramework",
512 "UpdateGlobalSettings",
513 "UpdateRecoveryPointIndexSettings",
514 "UpdateRecoveryPointLifecycle",
515 "UpdateRegionSettings",
516 "UpdateReportPlan",
517 "UpdateRestoreTestingPlan",
518 "UpdateRestoreTestingSelection",
519 "UpdateTieringConfiguration",
520 "DescribeBackupJob",
522 "DescribeCopyJob",
523 "DescribeRestoreJob",
524];
525
526#[async_trait]
527impl AwsService for BackupService {
528 fn service_name(&self) -> &str {
529 "backup"
530 }
531
532 async fn handle(&self, req: AwsRequest) -> Result<AwsResponse, AwsServiceError> {
533 let (action, labels) = Self::resolve_action(&req).ok_or_else(|| {
534 AwsServiceError::aws_error(
535 StatusCode::NOT_FOUND,
536 "UnknownOperationException",
537 format!("Unknown operation: {} {}", req.method, req.raw_path),
538 )
539 })?;
540
541 let result = self.dispatch(action, &labels, &req);
542
543 if MUTATING.contains(&action)
544 && matches!(result.as_ref(), Ok(resp) if resp.status.is_success())
545 {
546 self.save_snapshot().await;
547 }
548 result
549 }
550
551 fn supported_actions(&self) -> &[&str] {
552 BACKUP_ACTIONS
553 }
554}
555
556impl BackupService {
557 #[allow(clippy::too_many_lines)]
558 fn dispatch(
559 &self,
560 action: &str,
561 l: &[String],
562 req: &AwsRequest,
563 ) -> Result<AwsResponse, AwsServiceError> {
564 validate_query_constraints(action, req)?;
565 match action {
566 "CreateBackupPlan" => self.create_backup_plan(req),
567 "GetBackupPlan" => self.get_backup_plan(req, &l[0]),
568 "UpdateBackupPlan" => self.update_backup_plan(req, &l[0]),
569 "DeleteBackupPlan" => self.delete_backup_plan(req, &l[0]),
570 "ListBackupPlans" => self.list_backup_plans(req),
571 "ListBackupPlanVersions" => self.list_backup_plan_versions(req, &l[0]),
572 "ListBackupPlanTemplates" => self.list_backup_plan_templates(req),
573 "GetBackupPlanFromJSON" => self.get_backup_plan_from_json(req),
574 "GetBackupPlanFromTemplate" => self.get_backup_plan_from_template(req, &l[0]),
575 "ExportBackupPlanTemplate" => self.export_backup_plan_template(req, &l[0]),
576 "CreateBackupSelection" => self.create_backup_selection(req, &l[0]),
577 "GetBackupSelection" => self.get_backup_selection(req, &l[0], &l[1]),
578 "DeleteBackupSelection" => self.delete_backup_selection(req, &l[0], &l[1]),
579 "ListBackupSelections" => self.list_backup_selections(req, &l[0]),
580 "CreateBackupVault" => self.create_backup_vault(req, &l[0], "BACKUP_VAULT"),
581 "CreateLogicallyAirGappedBackupVault" => self.create_lag_vault(req, &l[0]),
582 "CreateRestoreAccessBackupVault" => self.create_restore_access_vault(req),
583 "DescribeBackupVault" => self.describe_backup_vault(req, &l[0]),
584 "DeleteBackupVault" => self.delete_backup_vault(req, &l[0]),
585 "ListBackupVaults" => self.list_backup_vaults(req),
586 "ListRestoreAccessBackupVaults" => self.list_restore_access_vaults(req, &l[0]),
587 "RevokeRestoreAccessBackupVault" => self.revoke_restore_access_vault(req, &l[0], &l[1]),
588 "PutBackupVaultAccessPolicy" => self.put_vault_access_policy(req, &l[0]),
589 "GetBackupVaultAccessPolicy" => self.get_vault_access_policy(req, &l[0]),
590 "DeleteBackupVaultAccessPolicy" => self.delete_vault_access_policy(req, &l[0]),
591 "PutBackupVaultLockConfiguration" => self.put_vault_lock(req, &l[0]),
592 "DeleteBackupVaultLockConfiguration" => self.delete_vault_lock(req, &l[0]),
593 "PutBackupVaultNotifications" => self.put_vault_notifications(req, &l[0]),
594 "GetBackupVaultNotifications" => self.get_vault_notifications(req, &l[0]),
595 "DeleteBackupVaultNotifications" => self.delete_vault_notifications(req, &l[0]),
596 "AssociateBackupVaultMpaApprovalTeam" => self.associate_mpa(req, &l[0]),
597 "DisassociateBackupVaultMpaApprovalTeam" => self.disassociate_mpa(req, &l[0]),
598 "DescribeRecoveryPoint" => self.describe_recovery_point(req, &l[0], &l[1]),
599 "DeleteRecoveryPoint" => self.delete_recovery_point(req, &l[0], &l[1]),
600 "UpdateRecoveryPointLifecycle" => {
601 self.update_recovery_point_lifecycle(req, &l[0], &l[1])
602 }
603 "GetRecoveryPointIndexDetails" => self.get_rp_index_details(req, &l[0], &l[1]),
604 "UpdateRecoveryPointIndexSettings" => self.update_rp_index_settings(req, &l[0], &l[1]),
605 "GetRecoveryPointRestoreMetadata" => self.get_rp_restore_metadata(req, &l[0], &l[1]),
606 "DisassociateRecoveryPoint" => self.disassociate_recovery_point(req, &l[0], &l[1]),
607 "DisassociateRecoveryPointFromParent" => self.disassociate_rp_parent(req, &l[0], &l[1]),
608 "ListRecoveryPointsByBackupVault" => self.list_rp_by_vault(req, &l[0]),
609 "ListRecoveryPointsByResource" => self.list_rp_by_resource(req, &l[0]),
610 "ListRecoveryPointsByLegalHold" => self.list_rp_by_legal_hold(req, &l[0]),
611 "ListIndexedRecoveryPoints" => self.list_indexed_recovery_points(req),
612 "ListProtectedResources" => self.list_protected_resources(req),
613 "ListProtectedResourcesByBackupVault" => self.list_protected_by_vault(req, &l[0]),
614 "DescribeProtectedResource" => self.describe_protected_resource(req, &l[0]),
615 "StartBackupJob" => self.start_backup_job(req),
617 "DescribeBackupJob" => self.describe_backup_job(req, &l[0]),
618 "StopBackupJob" => self.stop_backup_job(req, &l[0]),
619 "ListBackupJobs" => self.list_backup_jobs(req),
620 "StartCopyJob" => self.start_copy_job(req),
621 "DescribeCopyJob" => self.describe_copy_job(req, &l[0]),
622 "ListCopyJobs" => self.list_copy_jobs(req),
623 "StartRestoreJob" => self.start_restore_job(req),
624 "DescribeRestoreJob" => self.describe_restore_job(req, &l[0]),
625 "ListRestoreJobs" => self.list_restore_jobs(req),
626 "ListRestoreJobsByProtectedResource" => self.list_restore_jobs_by_resource(req, &l[0]),
627 "GetRestoreJobMetadata" => self.get_restore_job_metadata(req, &l[0]),
628 "PutRestoreValidationResult" => self.put_restore_validation(req, &l[0]),
629 "StartScanJob" => self.start_scan_job(req),
630 "DescribeScanJob" => self.describe_scan_job(req, &l[0]),
631 "ListScanJobs" => self.list_scan_jobs(req),
632 "GetPITRMalwareScanResults" => self.get_pitr_malware_scan_results(req),
633 "ListBackupJobSummaries" => self.list_job_summaries(req, "BackupJobSummaries"),
634 "ListCopyJobSummaries" => self.list_job_summaries(req, "CopyJobSummaries"),
635 "ListRestoreJobSummaries" => self.list_job_summaries(req, "RestoreJobSummaries"),
636 "ListScanJobSummaries" => self.list_job_summaries(req, "ScanJobSummaries"),
637 "CreateFramework" => self.create_framework(req),
639 "DescribeFramework" => self.describe_framework(req, &l[0]),
640 "UpdateFramework" => self.update_framework(req, &l[0]),
641 "DeleteFramework" => self.delete_framework(req, &l[0]),
642 "ListFrameworks" => self.list_frameworks(req),
643 "CreateReportPlan" => self.create_report_plan(req),
645 "DescribeReportPlan" => self.describe_report_plan(req, &l[0]),
646 "UpdateReportPlan" => self.update_report_plan(req, &l[0]),
647 "DeleteReportPlan" => self.delete_report_plan(req, &l[0]),
648 "ListReportPlans" => self.list_report_plans(req),
649 "StartReportJob" => self.start_report_job(req, &l[0]),
650 "DescribeReportJob" => self.describe_report_job(req, &l[0]),
651 "ListReportJobs" => self.list_report_jobs(req),
652 "CreateLegalHold" => self.create_legal_hold(req),
654 "GetLegalHold" => self.get_legal_hold(req, &l[0]),
655 "CancelLegalHold" => self.cancel_legal_hold(req, &l[0]),
656 "ListLegalHolds" => self.list_legal_holds(req),
657 "CreateRestoreTestingPlan" => self.create_rtp(req),
659 "GetRestoreTestingPlan" => self.get_rtp(req, &l[0]),
660 "UpdateRestoreTestingPlan" => self.update_rtp(req, &l[0]),
661 "DeleteRestoreTestingPlan" => self.delete_rtp(req, &l[0]),
662 "ListRestoreTestingPlans" => self.list_rtp(req),
663 "CreateRestoreTestingSelection" => self.create_rts(req, &l[0]),
664 "GetRestoreTestingSelection" => self.get_rts(req, &l[0], &l[1]),
665 "UpdateRestoreTestingSelection" => self.update_rts(req, &l[0], &l[1]),
666 "DeleteRestoreTestingSelection" => self.delete_rts(req, &l[0], &l[1]),
667 "ListRestoreTestingSelections" => self.list_rts(req, &l[0]),
668 "GetRestoreTestingInferredMetadata" => self.get_rt_inferred_metadata(req),
669 "CreateTieringConfiguration" => self.create_tiering(req),
671 "GetTieringConfiguration" => self.get_tiering(req, &l[0]),
672 "UpdateTieringConfiguration" => self.update_tiering(req, &l[0]),
673 "DeleteTieringConfiguration" => self.delete_tiering(req, &l[0]),
674 "ListTieringConfigurations" => self.list_tiering(req),
675 "DescribeGlobalSettings" => self.describe_global_settings(req),
677 "UpdateGlobalSettings" => self.update_global_settings(req),
678 "DescribeRegionSettings" => self.describe_region_settings(req),
679 "UpdateRegionSettings" => self.update_region_settings(req),
680 "GetSupportedResourceTypes" => Ok(ok(json!({
681 "ResourceTypes": SUPPORTED_RESOURCE_TYPES,
682 }))),
683 "ListTags" => self.list_tags(req, &l[0]),
684 "TagResource" => self.tag_resource(req, &l[0]),
685 "UntagResource" => self.untag_resource(req, &l[0]),
686 _ => Err(AwsServiceError::action_not_implemented("backup", action)),
687 }
688 }
689}
690
691include!("handlers.rs");