Skip to main content

fakecloud_ec2/service/
mod.rs

1//! EC2 service entrypoint: `ec2Query` dispatch over the per-account state.
2
3mod capacity;
4mod cvpn;
5mod dhcp;
6mod eip;
7mod endpoint;
8mod eni;
9mod firewall_model;
10mod fleet;
11mod ice;
12mod image;
13pub(crate) mod instance;
14mod ipam;
15mod ipam_discovery;
16mod ipam_policy;
17mod lgw;
18mod meta;
19mod nacl;
20mod ni;
21mod reserved;
22mod rest;
23mod routing;
24mod sg;
25mod snapshot;
26mod subnet;
27mod tags;
28mod tgw;
29mod tgw_mcast;
30mod tgw_peering;
31mod va;
32mod volume;
33mod vpc;
34mod vpn;
35
36use async_trait::async_trait;
37use http::StatusCode;
38use parking_lot::RwLock;
39use std::sync::Arc;
40
41use tokio::sync::Mutex as AsyncMutex;
42
43use fakecloud_core::multi_account::MultiAccountState;
44use fakecloud_core::service::{AwsRequest, AwsResponse, AwsService, AwsServiceError};
45use fakecloud_persistence::SnapshotStore;
46
47use crate::runtime::Ec2Runtime;
48use crate::state::{Ec2Snapshot, SharedEc2State, EC2_SNAPSHOT_SCHEMA_VERSION};
49
50/// EC2 read actions all start with `Describe`, `Get`, `Search`, or `List`;
51/// every other action mutates state. The inverse formulation guarantees no
52/// mutation is ever missed, and the hot-path reads (Describe*) are excluded so
53/// polling never triggers a snapshot write.
54fn is_mutating_action(action: &str) -> bool {
55    !(action.starts_with("Describe")
56        || action.starts_with("Get")
57        || action.starts_with("Search")
58        || action.starts_with("List"))
59}
60
61/// Every EC2 action this build implements. The conformance audit cross-checks
62/// this list against the handwritten `#[test_action("ec2", …)]` tests, so an
63/// action added here without a test fails the build. Grows one resource-family
64/// batch at a time toward full 767-op parity.
65pub const SUPPORTED_ACTIONS: &[&str] = &[
66    // Tagging subsystem (shared by every resource family)
67    "CreateTags",
68    "DeleteTags",
69    "DescribeTags",
70    // Region / AZ / account describe primitives
71    "DescribeRegions",
72    "DescribeAvailabilityZones",
73    "DescribeAccountAttributes",
74    // VPCs
75    "CreateVpc",
76    "CreateDefaultVpc",
77    "DeleteVpc",
78    "DescribeVpcs",
79    "ModifyVpcAttribute",
80    "DescribeVpcAttribute",
81    "ModifyVpcTenancy",
82    "AssociateVpcCidrBlock",
83    "DisassociateVpcCidrBlock",
84    // DHCP options
85    "CreateDhcpOptions",
86    "DeleteDhcpOptions",
87    "DescribeDhcpOptions",
88    "AssociateDhcpOptions",
89    // Subnets
90    "CreateSubnet",
91    "CreateDefaultSubnet",
92    "CreateSecondarySubnet",
93    "DeleteSubnet",
94    "DeleteSecondarySubnet",
95    "DescribeSubnets",
96    "DescribeSecondarySubnets",
97    "ModifySubnetAttribute",
98    "AssociateSubnetCidrBlock",
99    "DisassociateSubnetCidrBlock",
100    "CreateSubnetCidrReservation",
101    "DeleteSubnetCidrReservation",
102    "GetSubnetCidrReservations",
103    // Security groups
104    "CreateSecurityGroup",
105    "DeleteSecurityGroup",
106    "DescribeSecurityGroups",
107    "AuthorizeSecurityGroupIngress",
108    "AuthorizeSecurityGroupEgress",
109    "RevokeSecurityGroupIngress",
110    "RevokeSecurityGroupEgress",
111    "DescribeSecurityGroupRules",
112    "ModifySecurityGroupRules",
113    "UpdateSecurityGroupRuleDescriptionsIngress",
114    "UpdateSecurityGroupRuleDescriptionsEgress",
115    "AssociateSecurityGroupVpc",
116    "DisassociateSecurityGroupVpc",
117    "DescribeSecurityGroupVpcAssociations",
118    "GetSecurityGroupsForVpc",
119    "DescribeStaleSecurityGroups",
120    "DescribeSecurityGroupReferences",
121    // Route tables
122    "CreateRouteTable",
123    "DeleteRouteTable",
124    "DescribeRouteTables",
125    "CreateRoute",
126    "DeleteRoute",
127    "ReplaceRoute",
128    "AssociateRouteTable",
129    "DisassociateRouteTable",
130    "ReplaceRouteTableAssociation",
131    // Internet gateways
132    "CreateInternetGateway",
133    "DeleteInternetGateway",
134    "DescribeInternetGateways",
135    "AttachInternetGateway",
136    "DetachInternetGateway",
137    // Egress-only internet gateways
138    "CreateEgressOnlyInternetGateway",
139    "DeleteEgressOnlyInternetGateway",
140    "DescribeEgressOnlyInternetGateways",
141    // NAT gateways
142    "CreateNatGateway",
143    "DeleteNatGateway",
144    "DescribeNatGateways",
145    "AssignPrivateNatGatewayAddress",
146    "AssociateNatGatewayAddress",
147    "DisassociateNatGatewayAddress",
148    "UnassignPrivateNatGatewayAddress",
149    // Elastic IPs
150    "AllocateAddress",
151    "ReleaseAddress",
152    "DescribeAddresses",
153    "AssociateAddress",
154    "DisassociateAddress",
155    "DescribeAddressesAttribute",
156    "ModifyAddressAttribute",
157    "ResetAddressAttribute",
158    "MoveAddressToVpc",
159    "RestoreAddressToClassic",
160    "AcceptAddressTransfer",
161    "EnableAddressTransfer",
162    "DisableAddressTransfer",
163    "DescribeAddressTransfers",
164    "DescribeMovingAddresses",
165    // Key pairs
166    "CreateKeyPair",
167    "ImportKeyPair",
168    "DeleteKeyPair",
169    "DescribeKeyPairs",
170    // Placement groups
171    "CreatePlacementGroup",
172    "DeletePlacementGroup",
173    "DescribePlacementGroups",
174    "GetGroupsForCapacityReservation",
175    // Network interfaces
176    "CreateNetworkInterface",
177    "DeleteNetworkInterface",
178    "DescribeNetworkInterfaces",
179    "AttachNetworkInterface",
180    "DetachNetworkInterface",
181    "ModifyNetworkInterfaceAttribute",
182    "ResetNetworkInterfaceAttribute",
183    "DescribeNetworkInterfaceAttribute",
184    "CreateNetworkInterfacePermission",
185    "DeleteNetworkInterfacePermission",
186    "DescribeNetworkInterfacePermissions",
187    "AssignPrivateIpAddresses",
188    "UnassignPrivateIpAddresses",
189    "AssignIpv6Addresses",
190    "UnassignIpv6Addresses",
191    // Instances
192    "RunInstances",
193    "StartInstances",
194    "StopInstances",
195    "RebootInstances",
196    "TerminateInstances",
197    "MonitorInstances",
198    "UnmonitorInstances",
199    "DescribeInstances",
200    "DescribeInstanceStatus",
201    "DescribeInstanceTypes",
202    "GetInstanceTypesFromInstanceRequirements",
203    "DescribeInstanceAttribute",
204    "ModifyInstanceAttribute",
205    "ResetInstanceAttribute",
206    "ModifyInstancePlacement",
207    "ModifyInstanceMetadataOptions",
208    "ModifyInstanceMaintenanceOptions",
209    "ModifyInstanceCpuOptions",
210    "ModifyInstanceNetworkPerformanceOptions",
211    "ModifyInstanceEventStartTime",
212    "DescribeInstanceCreditSpecifications",
213    "ModifyInstanceCreditSpecification",
214    "GetInstanceMetadataDefaults",
215    "ModifyInstanceMetadataDefaults",
216    "RegisterInstanceEventNotificationAttributes",
217    "DeregisterInstanceEventNotificationAttributes",
218    "DescribeInstanceEventNotificationAttributes",
219    "ReportInstanceStatus",
220    "DescribeInstanceTopology",
221    // EBS volumes
222    "CreateVolume",
223    "DeleteVolume",
224    "DescribeVolumes",
225    "AttachVolume",
226    "DetachVolume",
227    "ModifyVolume",
228    "DescribeVolumesModifications",
229    "DescribeVolumeStatus",
230    "DescribeVolumeAttribute",
231    "ModifyVolumeAttribute",
232    "EnableVolumeIO",
233    "ListVolumesInRecycleBin",
234    "RestoreVolumeFromRecycleBin",
235    // EBS encryption defaults
236    "GetEbsEncryptionByDefault",
237    "EnableEbsEncryptionByDefault",
238    "DisableEbsEncryptionByDefault",
239    "GetEbsDefaultKmsKeyId",
240    "ModifyEbsDefaultKmsKeyId",
241    "ResetEbsDefaultKmsKeyId",
242    // EBS snapshots
243    "CreateSnapshot",
244    "CreateSnapshots",
245    "DeleteSnapshot",
246    "DescribeSnapshots",
247    "CopySnapshot",
248    "DescribeSnapshotAttribute",
249    "ModifySnapshotAttribute",
250    "ResetSnapshotAttribute",
251    "ModifySnapshotTier",
252    "DescribeSnapshotTierStatus",
253    "RestoreSnapshotTier",
254    "ListSnapshotsInRecycleBin",
255    "RestoreSnapshotFromRecycleBin",
256    "LockSnapshot",
257    "UnlockSnapshot",
258    "DescribeLockedSnapshots",
259    "GetSnapshotBlockPublicAccessState",
260    "EnableSnapshotBlockPublicAccess",
261    "DisableSnapshotBlockPublicAccess",
262    "EnableFastSnapshotRestores",
263    "DisableFastSnapshotRestores",
264    "DescribeFastSnapshotRestores",
265    // AMIs (images)
266    "CreateImage",
267    "RegisterImage",
268    "DeregisterImage",
269    "DescribeImages",
270    "CopyImage",
271    "DescribeImageAttribute",
272    "ModifyImageAttribute",
273    "ResetImageAttribute",
274    "EnableImage",
275    "DisableImage",
276    "AttachImageWatermark",
277    "DetachImageWatermark",
278    "EnableImageDeprecation",
279    "DisableImageDeprecation",
280    "EnableImageDeregistrationProtection",
281    "DisableImageDeregistrationProtection",
282    "CancelImageLaunchPermission",
283    "RestoreImageFromRecycleBin",
284    "ListImagesInRecycleBin",
285    "EnableImageBlockPublicAccess",
286    "DisableImageBlockPublicAccess",
287    "GetImageBlockPublicAccessState",
288    "EnableAllowedImagesSettings",
289    "DisableAllowedImagesSettings",
290    "GetAllowedImagesSettings",
291    "ReplaceImageCriteriaInAllowedImagesSettings",
292    "CreateStoreImageTask",
293    "DescribeStoreImageTasks",
294    "CreateRestoreImageTask",
295    "DescribeFastLaunchImages",
296    // Network ACLs
297    "CreateNetworkAcl",
298    "DeleteNetworkAcl",
299    "DescribeNetworkAcls",
300    "CreateNetworkAclEntry",
301    "DeleteNetworkAclEntry",
302    "ReplaceNetworkAclEntry",
303    "ReplaceNetworkAclAssociation",
304    // VPC peering
305    "CreateVpcPeeringConnection",
306    "DeleteVpcPeeringConnection",
307    "DescribeVpcPeeringConnections",
308    "AcceptVpcPeeringConnection",
309    "RejectVpcPeeringConnection",
310    "ModifyVpcPeeringConnectionOptions",
311    // VPC endpoints
312    "CreateVpcEndpoint",
313    "DeleteVpcEndpoints",
314    "DescribeVpcEndpoints",
315    "ModifyVpcEndpoint",
316    "DescribeVpcEndpointServices",
317    "DescribeVpcEndpointConnections",
318    "AcceptVpcEndpointConnections",
319    "RejectVpcEndpointConnections",
320    "CreateVpcEndpointServiceConfiguration",
321    "DeleteVpcEndpointServiceConfigurations",
322    "DescribeVpcEndpointServiceConfigurations",
323    "ModifyVpcEndpointServiceConfiguration",
324    "DescribeVpcEndpointServicePermissions",
325    "ModifyVpcEndpointServicePermissions",
326    "ModifyVpcEndpointServicePayerResponsibility",
327    "StartVpcEndpointServicePrivateDnsVerification",
328    "CreateVpcEndpointConnectionNotification",
329    "DeleteVpcEndpointConnectionNotifications",
330    "DescribeVpcEndpointConnectionNotifications",
331    "ModifyVpcEndpointConnectionNotification",
332    "DescribeVpcEndpointAssociations",
333    // Flow logs
334    "CreateFlowLogs",
335    "DeleteFlowLogs",
336    "DescribeFlowLogs",
337    "GetFlowLogsIntegrationTemplate",
338    // Launch templates
339    "CreateLaunchTemplate",
340    "CreateLaunchTemplateVersion",
341    "DeleteLaunchTemplate",
342    "DeleteLaunchTemplateVersions",
343    "DescribeLaunchTemplates",
344    "DescribeLaunchTemplateVersions",
345    "GetLaunchTemplateData",
346    "ModifyLaunchTemplate",
347    // Spot instances + fleet
348    "RequestSpotInstances",
349    "DescribeSpotInstanceRequests",
350    "CancelSpotInstanceRequests",
351    "RequestSpotFleet",
352    "DescribeSpotFleetRequests",
353    "CancelSpotFleetRequests",
354    "ModifySpotFleetRequest",
355    "DescribeSpotFleetInstances",
356    "DescribeSpotFleetRequestHistory",
357    "DescribeSpotPriceHistory",
358    "GetSpotPlacementScores",
359    "CreateSpotDatafeedSubscription",
360    "DeleteSpotDatafeedSubscription",
361    "DescribeSpotDatafeedSubscription",
362    // EC2 fleets
363    "CreateFleet",
364    "DeleteFleets",
365    "DescribeFleets",
366    "ModifyFleet",
367    "DescribeFleetHistory",
368    "DescribeFleetInstances",
369    // Capacity reservations
370    "CreateCapacityReservation",
371    "CancelCapacityReservation",
372    "DescribeCapacityReservations",
373    "ModifyCapacityReservation",
374    "GetCapacityReservationUsage",
375    "CreateCapacityReservationFleet",
376    "CancelCapacityReservationFleets",
377    "DescribeCapacityReservationFleets",
378    "ModifyCapacityReservationFleet",
379    "ModifyInstanceCapacityReservationAttributes",
380    "CreateCapacityReservationBySplitting",
381    "MoveCapacityReservationInstances",
382    "DescribeCapacityReservationBillingRequests",
383    "AssociateCapacityReservationBillingOwner",
384    "DisassociateCapacityReservationBillingOwner",
385    "AcceptCapacityReservationBillingOwnership",
386    "RejectCapacityReservationBillingOwnership",
387    "DescribeCapacityBlockOfferings",
388    "DescribeCapacityBlocks",
389    "PurchaseCapacityBlock",
390    "DescribeCapacityBlockStatus",
391    "DescribeCapacityBlockExtensionHistory",
392    "DescribeCapacityBlockExtensionOfferings",
393    "PurchaseCapacityBlockExtension",
394    "DescribeCapacityReservationTopology",
395    "CreateInterruptibleCapacityReservationAllocation",
396    "UpdateInterruptibleCapacityReservationAllocation",
397    // Reserved instances
398    "DescribeReservedInstances",
399    "DescribeReservedInstancesOfferings",
400    "PurchaseReservedInstancesOffering",
401    "DescribeReservedInstancesListings",
402    "CreateReservedInstancesListing",
403    "CancelReservedInstancesListing",
404    "DescribeReservedInstancesModifications",
405    "ModifyReservedInstances",
406    "GetReservedInstancesExchangeQuote",
407    "AcceptReservedInstancesExchangeQuote",
408    "DeleteQueuedReservedInstances",
409    // Dedicated hosts
410    "AllocateHosts",
411    "DescribeHosts",
412    "ModifyHosts",
413    "ReleaseHosts",
414    "DescribeMacHosts",
415    // Transit gateway core
416    "CreateTransitGateway",
417    "DeleteTransitGateway",
418    "DescribeTransitGateways",
419    "ModifyTransitGateway",
420    "CreateTransitGatewayVpcAttachment",
421    "DeleteTransitGatewayVpcAttachment",
422    "DescribeTransitGatewayVpcAttachments",
423    "ModifyTransitGatewayVpcAttachment",
424    "AcceptTransitGatewayVpcAttachment",
425    "RejectTransitGatewayVpcAttachment",
426    "DescribeTransitGatewayAttachments",
427    "CreateTransitGatewayRouteTable",
428    "DeleteTransitGatewayRouteTable",
429    "DescribeTransitGatewayRouteTables",
430    "AssociateTransitGatewayRouteTable",
431    "DisassociateTransitGatewayRouteTable",
432    "EnableTransitGatewayRouteTablePropagation",
433    "DisableTransitGatewayRouteTablePropagation",
434    "CreateTransitGatewayRoute",
435    "DeleteTransitGatewayRoute",
436    "ReplaceTransitGatewayRoute",
437    "SearchTransitGatewayRoutes",
438    "ExportTransitGatewayRoutes",
439    "GetTransitGatewayRouteTableAssociations",
440    "GetTransitGatewayRouteTablePropagations",
441    "GetTransitGatewayAttachmentPropagations",
442    "CreateTransitGatewayPrefixListReference",
443    "DeleteTransitGatewayPrefixListReference",
444    "ModifyTransitGatewayPrefixListReference",
445    "GetTransitGatewayPrefixListReferences",
446    // Transit gateway peering / connect / policy / announcements
447    "CreateTransitGatewayPeeringAttachment",
448    "DeleteTransitGatewayPeeringAttachment",
449    "DescribeTransitGatewayPeeringAttachments",
450    "AcceptTransitGatewayPeeringAttachment",
451    "RejectTransitGatewayPeeringAttachment",
452    "CreateTransitGatewayConnect",
453    "DeleteTransitGatewayConnect",
454    "DescribeTransitGatewayConnects",
455    "CreateTransitGatewayConnectPeer",
456    "DeleteTransitGatewayConnectPeer",
457    "DescribeTransitGatewayConnectPeers",
458    "CreateTransitGatewayPolicyTable",
459    "DeleteTransitGatewayPolicyTable",
460    "DescribeTransitGatewayPolicyTables",
461    "AssociateTransitGatewayPolicyTable",
462    "DisassociateTransitGatewayPolicyTable",
463    "GetTransitGatewayPolicyTableAssociations",
464    "GetTransitGatewayPolicyTableEntries",
465    "CreateTransitGatewayRouteTableAnnouncement",
466    "DeleteTransitGatewayRouteTableAnnouncement",
467    "DescribeTransitGatewayRouteTableAnnouncements",
468    // Transit gateway multicast / metering / client-vpn-attach
469    "CreateTransitGatewayMulticastDomain",
470    "DeleteTransitGatewayMulticastDomain",
471    "DescribeTransitGatewayMulticastDomains",
472    "AssociateTransitGatewayMulticastDomain",
473    "DisassociateTransitGatewayMulticastDomain",
474    "AcceptTransitGatewayMulticastDomainAssociations",
475    "RejectTransitGatewayMulticastDomainAssociations",
476    "GetTransitGatewayMulticastDomainAssociations",
477    "RegisterTransitGatewayMulticastGroupMembers",
478    "RegisterTransitGatewayMulticastGroupSources",
479    "DeregisterTransitGatewayMulticastGroupMembers",
480    "DeregisterTransitGatewayMulticastGroupSources",
481    "SearchTransitGatewayMulticastGroups",
482    "CreateTransitGatewayMeteringPolicy",
483    "DeleteTransitGatewayMeteringPolicy",
484    "DescribeTransitGatewayMeteringPolicies",
485    "ModifyTransitGatewayMeteringPolicy",
486    "CreateTransitGatewayMeteringPolicyEntry",
487    "DeleteTransitGatewayMeteringPolicyEntry",
488    "GetTransitGatewayMeteringPolicyEntries",
489    "AcceptTransitGatewayClientVpnAttachment",
490    "DeleteTransitGatewayClientVpnAttachment",
491    "RejectTransitGatewayClientVpnAttachment",
492    // Site-to-Site VPN
493    "CreateCustomerGateway",
494    "DeleteCustomerGateway",
495    "DescribeCustomerGateways",
496    "CreateVpnGateway",
497    "DeleteVpnGateway",
498    "DescribeVpnGateways",
499    "AttachVpnGateway",
500    "DetachVpnGateway",
501    "CreateVpnConnection",
502    "DeleteVpnConnection",
503    "DescribeVpnConnections",
504    "ModifyVpnConnection",
505    "ModifyVpnConnectionOptions",
506    "CreateVpnConnectionRoute",
507    "DeleteVpnConnectionRoute",
508    "ModifyVpnTunnelOptions",
509    "ModifyVpnTunnelCertificate",
510    "ReplaceVpnTunnel",
511    "GetActiveVpnTunnelStatus",
512    "GetVpnTunnelReplacementStatus",
513    "GetVpnConnectionDeviceTypes",
514    "GetVpnConnectionDeviceSampleConfiguration",
515    "CreateVpnConcentrator",
516    "DeleteVpnConcentrator",
517    "DescribeVpnConcentrators",
518    // Client VPN
519    "CreateClientVpnEndpoint",
520    "DeleteClientVpnEndpoint",
521    "DescribeClientVpnEndpoints",
522    "ModifyClientVpnEndpoint",
523    "CreateClientVpnRoute",
524    "DeleteClientVpnRoute",
525    "DescribeClientVpnRoutes",
526    "AuthorizeClientVpnIngress",
527    "RevokeClientVpnIngress",
528    "DescribeClientVpnAuthorizationRules",
529    "AssociateClientVpnTargetNetwork",
530    "DisassociateClientVpnTargetNetwork",
531    "DescribeClientVpnTargetNetworks",
532    "ApplySecurityGroupsToClientVpnTargetNetwork",
533    "DescribeClientVpnConnections",
534    "TerminateClientVpnConnections",
535    "ExportClientVpnClientCertificateRevocationList",
536    "ExportClientVpnClientConfiguration",
537    "ImportClientVpnClientCertificateRevocationList",
538    // IPAM core
539    "CreateIpam",
540    "DeleteIpam",
541    "DescribeIpams",
542    "ModifyIpam",
543    "CreateIpamScope",
544    "DeleteIpamScope",
545    "DescribeIpamScopes",
546    "ModifyIpamScope",
547    "CreateIpamPool",
548    "DeleteIpamPool",
549    "DescribeIpamPools",
550    "ModifyIpamPool",
551    "ProvisionIpamPoolCidr",
552    "DeprovisionIpamPoolCidr",
553    "GetIpamPoolCidrs",
554    "AllocateIpamPoolCidr",
555    "ReleaseIpamPoolAllocation",
556    "GetIpamPoolAllocations",
557    "GetIpamResourceCidrs",
558    "ModifyIpamResourceCidr",
559    "GetIpamAddressHistory",
560    "EnableIpamOrganizationAdminAccount",
561    "DisableIpamOrganizationAdminAccount",
562    // IPAM resource discovery / BYOASN / BYOIP / external tokens
563    "CreateIpamResourceDiscovery",
564    "DeleteIpamResourceDiscovery",
565    "DescribeIpamResourceDiscoveries",
566    "ModifyIpamResourceDiscovery",
567    "AssociateIpamResourceDiscovery",
568    "DisassociateIpamResourceDiscovery",
569    "DescribeIpamResourceDiscoveryAssociations",
570    "GetIpamDiscoveredAccounts",
571    "GetIpamDiscoveredPublicAddresses",
572    "GetIpamDiscoveredResourceCidrs",
573    "AssociateIpamByoasn",
574    "DisassociateIpamByoasn",
575    "ProvisionIpamByoasn",
576    "DeprovisionIpamByoasn",
577    "DescribeIpamByoasn",
578    "MoveByoipCidrToIpam",
579    "CreateIpamExternalResourceVerificationToken",
580    "DeleteIpamExternalResourceVerificationToken",
581    "DescribeIpamExternalResourceVerificationTokens",
582    // IPAM policies + prefix-list resolvers
583    "CreateIpamPolicy",
584    "DeleteIpamPolicy",
585    "DescribeIpamPolicies",
586    "EnableIpamPolicy",
587    "DisableIpamPolicy",
588    "GetEnabledIpamPolicy",
589    "GetIpamPolicyAllocationRules",
590    "ModifyIpamPolicyAllocationRules",
591    "GetIpamPolicyOrganizationTargets",
592    "CreateIpamPrefixListResolver",
593    "DeleteIpamPrefixListResolver",
594    "DescribeIpamPrefixListResolvers",
595    "ModifyIpamPrefixListResolver",
596    "CreateIpamPrefixListResolverTarget",
597    "DeleteIpamPrefixListResolverTarget",
598    "DescribeIpamPrefixListResolverTargets",
599    "ModifyIpamPrefixListResolverTarget",
600    "GetIpamPrefixListResolverRules",
601    "GetIpamPrefixListResolverVersions",
602    "GetIpamPrefixListResolverVersionEntries",
603    // Verified Access
604    "CreateVerifiedAccessInstance",
605    "DeleteVerifiedAccessInstance",
606    "DescribeVerifiedAccessInstances",
607    "ModifyVerifiedAccessInstance",
608    "CreateVerifiedAccessTrustProvider",
609    "DeleteVerifiedAccessTrustProvider",
610    "DescribeVerifiedAccessTrustProviders",
611    "ModifyVerifiedAccessTrustProvider",
612    "AttachVerifiedAccessTrustProvider",
613    "DetachVerifiedAccessTrustProvider",
614    "CreateVerifiedAccessGroup",
615    "DeleteVerifiedAccessGroup",
616    "DescribeVerifiedAccessGroups",
617    "ModifyVerifiedAccessGroup",
618    "GetVerifiedAccessGroupPolicy",
619    "ModifyVerifiedAccessGroupPolicy",
620    "CreateVerifiedAccessEndpoint",
621    "DeleteVerifiedAccessEndpoint",
622    "DescribeVerifiedAccessEndpoints",
623    "ModifyVerifiedAccessEndpoint",
624    "GetVerifiedAccessEndpointPolicy",
625    "ModifyVerifiedAccessEndpointPolicy",
626    "GetVerifiedAccessEndpointTargets",
627    "DescribeVerifiedAccessInstanceLoggingConfigurations",
628    "ModifyVerifiedAccessInstanceLoggingConfiguration",
629    "ExportVerifiedAccessInstanceClientConfiguration",
630    // Network Insights
631    "CreateNetworkInsightsPath",
632    "DeleteNetworkInsightsPath",
633    "DescribeNetworkInsightsPaths",
634    "StartNetworkInsightsAnalysis",
635    "DeleteNetworkInsightsAnalysis",
636    "DescribeNetworkInsightsAnalyses",
637    "CreateNetworkInsightsAccessScope",
638    "DeleteNetworkInsightsAccessScope",
639    "DescribeNetworkInsightsAccessScopes",
640    "GetNetworkInsightsAccessScopeContent",
641    "StartNetworkInsightsAccessScopeAnalysis",
642    "DeleteNetworkInsightsAccessScopeAnalysis",
643    "DescribeNetworkInsightsAccessScopeAnalyses",
644    "GetNetworkInsightsAccessScopeAnalysisFindings",
645    // Outpost / local gateway / CoIP / carrier
646    "CreateCarrierGateway",
647    "DeleteCarrierGateway",
648    "DescribeCarrierGateways",
649    "CreateCoipPool",
650    "DeleteCoipPool",
651    "DescribeCoipPools",
652    "CreateCoipCidr",
653    "DeleteCoipCidr",
654    "GetCoipPoolUsage",
655    "CreateLocalGatewayRouteTable",
656    "DeleteLocalGatewayRouteTable",
657    "DescribeLocalGatewayRouteTables",
658    "CreateLocalGatewayRoute",
659    "DeleteLocalGatewayRoute",
660    "ModifyLocalGatewayRoute",
661    "SearchLocalGatewayRoutes",
662    "CreateLocalGatewayRouteTableVpcAssociation",
663    "DeleteLocalGatewayRouteTableVpcAssociation",
664    "DescribeLocalGatewayRouteTableVpcAssociations",
665    "CreateLocalGatewayVirtualInterface",
666    "DeleteLocalGatewayVirtualInterface",
667    "DescribeLocalGatewayVirtualInterfaces",
668    "CreateLocalGatewayVirtualInterfaceGroup",
669    "DeleteLocalGatewayVirtualInterfaceGroup",
670    "DescribeLocalGatewayVirtualInterfaceGroups",
671    "CreateLocalGatewayRouteTableVirtualInterfaceGroupAssociation",
672    "DeleteLocalGatewayRouteTableVirtualInterfaceGroupAssociation",
673    "DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociations",
674    "DescribeLocalGateways",
675    // Instance Connect / fast launch / serial console / console output
676    "CreateInstanceConnectEndpoint",
677    "DeleteInstanceConnectEndpoint",
678    "DescribeInstanceConnectEndpoints",
679    "ModifyInstanceConnectEndpoint",
680    "EnableFastLaunch",
681    "DisableFastLaunch",
682    "EnableSerialConsoleAccess",
683    "DisableSerialConsoleAccess",
684    "GetSerialConsoleAccessStatus",
685    "GetConsoleOutput",
686    "GetConsoleScreenshot",
687    "GetPasswordData",
688    // Remainder sweep (long tail -> full 767-op parity)
689    "CreateCapacityReservationCancellationQuote",
690    "DescribeCapacityReservationCancellationQuotes",
691    "DescribeIpamPoolAllocations",
692    "ModifyIpamPoolAllocation",
693    "DescribeAccountVpcEncryptionControl",
694    "ModifyAccountVpcEncryptionControl",
695    "ModifyVpcEndpointPayerResponsibility",
696    "AdvertiseByoipCidr",
697    "AssociateEnclaveCertificateIamRole",
698    "AssociateIamInstanceProfile",
699    "AssociateInstanceEventWindow",
700    "AssociateRouteServer",
701    "AssociateTrunkInterface",
702    "AttachClassicLinkVpc",
703    "BundleInstance",
704    "CancelBundleTask",
705    "CancelConversionTask",
706    "CancelDeclarativePoliciesReport",
707    "CancelExportTask",
708    "CancelImportTask",
709    "ConfirmProductInstance",
710    "CopyFpgaImage",
711    "CopyVolumes",
712    "CreateCapacityManagerDataExport",
713    "CreateDelegateMacVolumeOwnershipTask",
714    "CreateFpgaImage",
715    "CreateImageUsageReport",
716    "CreateInstanceEventWindow",
717    "CreateInstanceExportTask",
718    "CreateMacSystemIntegrityProtectionModificationTask",
719    "CreateManagedPrefixList",
720    "CreatePublicIpv4Pool",
721    "CreateReplaceRootVolumeTask",
722    "CreateRouteServer",
723    "CreateRouteServerEndpoint",
724    "CreateRouteServerPeer",
725    "CreateSecondaryNetwork",
726    "CreateTrafficMirrorFilter",
727    "CreateTrafficMirrorFilterRule",
728    "CreateTrafficMirrorSession",
729    "CreateTrafficMirrorTarget",
730    "CreateVpcBlockPublicAccessExclusion",
731    "CreateVpcEncryptionControl",
732    "DeleteCapacityManagerDataExport",
733    "DeleteFpgaImage",
734    "DeleteImageUsageReport",
735    "DeleteInstanceEventWindow",
736    "DeleteManagedPrefixList",
737    "DeletePublicIpv4Pool",
738    "DeleteRouteServer",
739    "DeleteRouteServerEndpoint",
740    "DeleteRouteServerPeer",
741    "DeleteSecondaryNetwork",
742    "DeleteTrafficMirrorFilter",
743    "DeleteTrafficMirrorFilterRule",
744    "DeleteTrafficMirrorSession",
745    "DeleteTrafficMirrorTarget",
746    "DeleteVpcBlockPublicAccessExclusion",
747    "DeleteVpcEncryptionControl",
748    "DeprovisionByoipCidr",
749    "DeprovisionPublicIpv4PoolCidr",
750    "DescribeAggregateIdFormat",
751    "DescribeAwsNetworkPerformanceMetricSubscriptions",
752    "DescribeBundleTasks",
753    "DescribeByoipCidrs",
754    "DescribeCapacityManagerDataExports",
755    "DescribeClassicLinkInstances",
756    "DescribeConversionTasks",
757    "DescribeDeclarativePoliciesReports",
758    "DescribeElasticGpus",
759    "DescribeExportImageTasks",
760    "DescribeExportTasks",
761    "DescribeFpgaImageAttribute",
762    "DescribeFpgaImages",
763    "DescribeHostReservationOfferings",
764    "DescribeHostReservations",
765    "DescribeIamInstanceProfileAssociations",
766    "DescribeIdFormat",
767    "DescribeIdentityIdFormat",
768    "DescribeImageReferences",
769    "DescribeImageUsageReportEntries",
770    "DescribeImageUsageReports",
771    "DescribeImportImageTasks",
772    "DescribeImportSnapshotTasks",
773    "DescribeInstanceEventWindows",
774    "DescribeInstanceImageMetadata",
775    "DescribeInstanceSqlHaHistoryStates",
776    "DescribeInstanceSqlHaStates",
777    "DescribeInstanceTypeOfferings",
778    "DescribeIpv6Pools",
779    "DescribeMacModificationTasks",
780    "DescribeManagedPrefixLists",
781    "DescribeOutpostLags",
782    "DescribePrefixLists",
783    "DescribePrincipalIdFormat",
784    "DescribePublicIpv4Pools",
785    "DescribeReplaceRootVolumeTasks",
786    "DescribeRouteServerEndpoints",
787    "DescribeRouteServerPeers",
788    "DescribeRouteServers",
789    "DescribeScheduledInstanceAvailability",
790    "DescribeScheduledInstances",
791    "DescribeSecondaryInterfaces",
792    "DescribeSecondaryNetworks",
793    "DescribeServiceLinkVirtualInterfaces",
794    "DescribeTrafficMirrorFilterRules",
795    "DescribeTrafficMirrorFilters",
796    "DescribeTrafficMirrorSessions",
797    "DescribeTrafficMirrorTargets",
798    "DescribeTrunkInterfaceAssociations",
799    "DescribeVpcBlockPublicAccessExclusions",
800    "DescribeVpcBlockPublicAccessOptions",
801    "DescribeVpcClassicLink",
802    "DescribeVpcClassicLinkDnsSupport",
803    "DescribeVpcEncryptionControls",
804    "DetachClassicLinkVpc",
805    "DisableAwsNetworkPerformanceMetricSubscription",
806    "DisableCapacityManager",
807    "DisableInstanceSqlHaStandbyDetections",
808    "DisableRouteServerPropagation",
809    "DisableVgwRoutePropagation",
810    "DisableVpcClassicLink",
811    "DisableVpcClassicLinkDnsSupport",
812    "DisassociateEnclaveCertificateIamRole",
813    "DisassociateIamInstanceProfile",
814    "DisassociateInstanceEventWindow",
815    "DisassociateRouteServer",
816    "DisassociateTrunkInterface",
817    "EnableAwsNetworkPerformanceMetricSubscription",
818    "EnableCapacityManager",
819    "EnableInstanceSqlHaStandbyDetections",
820    "EnableReachabilityAnalyzerOrganizationSharing",
821    "EnableRouteServerPropagation",
822    "EnableVgwRoutePropagation",
823    "EnableVpcClassicLink",
824    "EnableVpcClassicLinkDnsSupport",
825    "ExportImage",
826    "GetAssociatedEnclaveCertificateIamRoles",
827    "GetAssociatedIpv6PoolCidrs",
828    "GetAwsNetworkPerformanceData",
829    "GetCapacityManagerAttributes",
830    "GetCapacityManagerMetricData",
831    "GetCapacityManagerMetricDimensions",
832    "GetCapacityManagerMonitoredTagKeys",
833    "GetDeclarativePoliciesReportSummary",
834    "GetDefaultCreditSpecification",
835    "GetHostReservationPurchasePreview",
836    "GetImageAncestry",
837    "GetInstanceTpmEkPub",
838    "GetInstanceUefiData",
839    "GetManagedPrefixListAssociations",
840    "GetManagedPrefixListEntries",
841    "GetManagedResourceVisibility",
842    "GetRouteServerAssociations",
843    "GetRouteServerPropagations",
844    "GetRouteServerRoutingDatabase",
845    "GetVpcResourcesBlockingEncryptionEnforcement",
846    "ImportImage",
847    "ImportInstance",
848    "ImportSnapshot",
849    "ImportVolume",
850    "ModifyAvailabilityZoneGroup",
851    "ModifyDefaultCreditSpecification",
852    "ModifyFpgaImageAttribute",
853    "ModifyIdFormat",
854    "ModifyIdentityIdFormat",
855    "ModifyInstanceEventWindow",
856    "ModifyManagedPrefixList",
857    "ModifyManagedResourceVisibility",
858    "ModifyPrivateDnsNameOptions",
859    "ModifyPublicIpDnsNameOptions",
860    "ModifyRouteServer",
861    "ModifyTrafficMirrorFilterNetworkServices",
862    "ModifyTrafficMirrorFilterRule",
863    "ModifyTrafficMirrorSession",
864    "ModifyVpcBlockPublicAccessExclusion",
865    "ModifyVpcBlockPublicAccessOptions",
866    "ModifyVpcEncryptionControl",
867    "ProvisionByoipCidr",
868    "ProvisionPublicIpv4PoolCidr",
869    "PurchaseHostReservation",
870    "PurchaseScheduledInstances",
871    "ReplaceIamInstanceProfileAssociation",
872    "ResetFpgaImageAttribute",
873    "RestoreManagedPrefixListVersion",
874    "RunScheduledInstances",
875    "SendDiagnosticInterrupt",
876    "StartDeclarativePoliciesReport",
877    "UpdateCapacityManagerMonitoredTagKeys",
878    "UpdateCapacityManagerOrganizationsAccess",
879    "WithdrawByoipCidr",
880];
881
882/// Amazon EC2 service.
883pub struct Ec2Service {
884    pub(crate) state: SharedEc2State,
885    /// Optional container runtime backing instances with real containers.
886    /// `None` runs the metadata-only control plane (no Docker/Podman/k8s).
887    pub(crate) runtime: Option<Arc<Ec2Runtime>>,
888    pub(crate) snapshot_store: Option<Arc<dyn SnapshotStore>>,
889    pub(crate) snapshot_lock: Arc<AsyncMutex<()>>,
890}
891
892impl Ec2Service {
893    /// Construct a service over a fresh, empty account-partitioned state.
894    pub fn new() -> Self {
895        Self {
896            state: Arc::new(RwLock::new(MultiAccountState::new(
897                "000000000000",
898                "us-east-1",
899                "",
900            ))),
901            runtime: None,
902            snapshot_store: None,
903            snapshot_lock: Arc::new(AsyncMutex::new(())),
904        }
905    }
906
907    /// Construct a service over a shared state handle (used by the server so
908    /// persistence/snapshots can be wired in later batches).
909    pub fn with_state(state: SharedEc2State) -> Self {
910        Self {
911            state,
912            runtime: None,
913            snapshot_store: None,
914            snapshot_lock: Arc::new(AsyncMutex::new(())),
915        }
916    }
917
918    /// Synchronous dispatch for the subset of EC2 control-plane actions the
919    /// CloudFormation provisioner needs (VPC/Subnet/SecurityGroup/RouteTable/
920    /// InternetGateway create + delete). Routing through the real handlers
921    /// keeps CFN-provisioned EC2 resources identical to API-created ones
922    /// (default SG/NACL/route-table, id formats, tags) instead of re-deriving
923    /// them. None of these actions need the container runtime.
924    pub fn provision_sync(&self, request: &AwsRequest) -> Result<AwsResponse, AwsServiceError> {
925        match request.action.as_str() {
926            "CreateVpc" => vpc::create_vpc(self, request),
927            "DeleteVpc" => vpc::delete_vpc(self, request),
928            "CreateSubnet" => subnet::create_subnet(self, request),
929            "DeleteSubnet" => subnet::delete_subnet(self, request),
930            "CreateSecurityGroup" => sg::create_security_group(self, request),
931            "DeleteSecurityGroup" => sg::delete_security_group(self, request),
932            "CreateRouteTable" => routing::create_route_table(self, request),
933            "DeleteRouteTable" => routing::delete_route_table(self, request),
934            "CreateInternetGateway" => routing::create_internet_gateway(self, request),
935            "DeleteInternetGateway" => routing::delete_internet_gateway(self, request),
936            // Attribute / rule application the CloudFormation provisioner issues
937            // after a Create so VPC DNS attributes, subnet MapPublicIpOnLaunch,
938            // and inline SecurityGroup ingress/egress rules from a template are
939            // actually applied (not silently dropped).
940            "ModifyVpcAttribute" => vpc::modify_vpc_attribute(self, request),
941            "ModifySubnetAttribute" => subnet::modify_subnet_attribute(self, request),
942            "AuthorizeSecurityGroupIngress" => sg::authorize_security_group_ingress(self, request),
943            "AuthorizeSecurityGroupEgress" => sg::authorize_security_group_egress(self, request),
944            other => Err(AwsServiceError::action_not_implemented("ec2", other)),
945        }
946    }
947
948    /// Attach a container runtime so `RunInstances` boots real containers.
949    /// Passing `None` leaves the service in metadata-only mode.
950    pub fn with_runtime(mut self, runtime: Option<Arc<Ec2Runtime>>) -> Self {
951        self.runtime = runtime;
952        self
953    }
954
955    /// Attach a persistence snapshot store so control-plane mutations are
956    /// written through to disk. Backing containers are reconciled separately on
957    /// restart via [`Ec2Service::recover_persisted_containers`].
958    pub fn with_snapshot_store(mut self, store: Arc<dyn SnapshotStore>) -> Self {
959        self.snapshot_store = Some(store);
960        self
961    }
962
963    /// Persist current state as a snapshot. Held across the
964    /// clone-serialize-write sequence to prevent stale-last writes, with serde
965    /// + file I/O offloaded to the blocking pool.
966    async fn save_snapshot(&self) {
967        save_ec2_snapshot(
968            &self.state,
969            self.snapshot_store.clone(),
970            &self.snapshot_lock,
971        )
972        .await;
973    }
974
975    /// Build a hook that persists the current EC2 state when invoked, or `None`
976    /// in memory mode. The CloudFormation provisioner mutates `state` directly
977    /// and uses this to write a CFN-provisioned resource through to disk, the
978    /// same way a direct mutating API call would.
979    pub fn snapshot_hook(&self) -> Option<fakecloud_persistence::SnapshotHook> {
980        let store = self.snapshot_store.clone()?;
981        let state = self.state.clone();
982        let lock = self.snapshot_lock.clone();
983        Some(Arc::new(move || {
984            let state = state.clone();
985            let store = store.clone();
986            let lock = lock.clone();
987            Box::pin(async move {
988                save_ec2_snapshot(&state, Some(store), &lock).await;
989            })
990        }))
991    }
992
993    /// Clone the shared state handle so the server can expose read-only
994    /// introspection endpoints (`GET /_fakecloud/ec2/instances`).
995    pub fn shared_state(&self) -> SharedEc2State {
996        self.state.clone()
997    }
998
999    /// Re-derive the security-group/NACL firewall model from current state and
1000    /// (re)apply it via the runtime's nftables enforcer (#1745 phase 3).
1001    ///
1002    /// Cheap no-op when there's no runtime or enforcement is disabled — the
1003    /// common case — so it's safe to call liberally after any mutation that can
1004    /// change the ruleset (RunInstances, Terminate, Authorize/Revoke,
1005    /// network-ACL edits). Runs in the background so it never blocks the API
1006    /// response.
1007    pub(crate) fn spawn_firewall_reconcile(&self) {
1008        let Some(runtime) = self.runtime.clone() else {
1009            return;
1010        };
1011        if !runtime.network_isolation_enforced() {
1012            return;
1013        }
1014        let state = self.state.clone();
1015        tokio::spawn(async move {
1016            firewall_model::reconcile(&state, &runtime).await;
1017        });
1018    }
1019
1020    /// Rebuild the backing-container runtime state for persisted instances
1021    /// after a fakecloud restart, mirroring RDS/ElastiCache
1022    /// `recover_persisted_containers`.
1023    ///
1024    /// On an ungraceful restart the new process has a new PID, so the shared
1025    /// reaper removes every EC2 container labeled with the *previous* PID; an
1026    /// instance that persisted as `running` with a `container_id` would
1027    /// otherwise be left pointing at a removed container, with every
1028    /// subsequent Stop/Start/Reboot/Terminate a silent no-op (bug-hunt
1029    /// 2026-06-15 finding 0.3). For each such instance we flip it to `pending`
1030    /// and spawn a fresh backing container in the background, reconciling it to
1031    /// `running` (with the new id/IP) when it's up, or `stopped` on failure.
1032    /// Instances persisted as `stopped`/`terminated` are left as-is —
1033    /// StartInstances revives the former. No-op when no runtime is configured
1034    /// or there are no instances to recover.
1035    /// Flip every `pending` (code 0) instance to `running` (code 16) in
1036    /// metadata-only mode, then persist. Used on restart so an instance whose
1037    /// background boot flip was lost across a restart still reaches `running`,
1038    /// and directly by the RunInstances background task when no runtime is
1039    /// wired so the persisted snapshot captures `running`, not `pending` (M12).
1040    pub(crate) async fn reconcile_pending_metadata_only(&self) {
1041        let flipped = {
1042            let mut accounts = self.state.write();
1043            let mut n = 0;
1044            for (_, state) in accounts.iter_mut() {
1045                for inst in state.instances.values_mut() {
1046                    if inst.state_code == 0 {
1047                        inst.state_code = 16;
1048                        inst.state_name = "running".to_string();
1049                        n += 1;
1050                    }
1051                }
1052            }
1053            n
1054        };
1055        if flipped > 0 {
1056            self.save_snapshot().await;
1057        }
1058    }
1059
1060    // (helper `recovery_terminal_wins` is defined at module scope below.)
1061
1062    pub async fn recover_persisted_containers(&self) {
1063        let Some(runtime) = self.runtime.clone() else {
1064            // Metadata-only mode: there is no container to reconcile, but an
1065            // instance persisted mid-boot (state `pending`, code 0) would stay
1066            // stuck pending forever because the background flip-to-running that
1067            // RunInstances spawned never ran in this process. Flip any such
1068            // instance to `running` so a restart self-heals (M12).
1069            self.reconcile_pending_metadata_only().await;
1070            return;
1071        };
1072
1073        struct Pending {
1074            account_id: String,
1075            id: String,
1076            user_data: Option<String>,
1077            tags: std::collections::BTreeMap<String, String>,
1078            network: Option<crate::runtime::InstanceNetwork>,
1079        }
1080
1081        let pending: Vec<Pending> = {
1082            let mut accounts = self.state.write();
1083            let mut out = Vec::new();
1084            for (_, state) in accounts.iter_mut() {
1085                let account_id = state.account_id.clone();
1086                // Snapshot the tag map first so we don't hold two borrows of
1087                // `state` at once when re-deriving per-instance Pod tags.
1088                let tag_snapshot: std::collections::BTreeMap<String, Vec<crate::state::Tag>> =
1089                    state.tags.clone();
1090                // Which subnets are public (have an IGW default route), computed
1091                // before the mutable instance loop so we can re-derive each
1092                // recovered instance's `internal` flag without a second borrow.
1093                let public_subnets: std::collections::HashSet<String> = state
1094                    .subnets
1095                    .keys()
1096                    .filter(|sid| crate::defaults::subnet_is_public(state, sid))
1097                    .cloned()
1098                    .collect();
1099                for (id, inst) in state.instances.iter_mut() {
1100                    // Only running/pending instances need a live container; the
1101                    // stale container_id is dropped (the reaper removed it).
1102                    if !matches!(inst.state_name.as_str(), "running" | "pending") {
1103                        continue;
1104                    }
1105                    let tags = tag_snapshot
1106                        .get(id)
1107                        .map(|t| {
1108                            t.iter()
1109                                .map(|tag| (tag.key.clone(), tag.value.clone()))
1110                                .collect()
1111                        })
1112                        .unwrap_or_default();
1113                    let network =
1114                        inst.subnet_id
1115                            .clone()
1116                            .map(|sid| crate::runtime::InstanceNetwork {
1117                                internal: !public_subnets.contains(&sid),
1118                                subnet_id: sid,
1119                            });
1120                    inst.state_code = 0;
1121                    inst.state_name = "pending".to_string();
1122                    inst.container_id = None;
1123                    out.push(Pending {
1124                        account_id: account_id.clone(),
1125                        id: id.clone(),
1126                        user_data: inst.user_data.clone(),
1127                        tags,
1128                        network,
1129                    });
1130                }
1131            }
1132            out
1133        };
1134
1135        if pending.is_empty() {
1136            return;
1137        }
1138        tracing::info!(
1139            count = pending.len(),
1140            "recovering backing containers for persisted ec2 instances",
1141        );
1142
1143        let mut handles = Vec::new();
1144        for p in pending {
1145            let runtime = runtime.clone();
1146            let state = self.state.clone();
1147            handles.push(tokio::spawn(async move {
1148                let running = runtime
1149                    .run_instance(
1150                        &p.account_id,
1151                        &p.id,
1152                        p.user_data.as_deref(),
1153                        &p.tags,
1154                        p.network.as_ref(),
1155                    )
1156                    .await;
1157                let reap = {
1158                    let mut accounts = state.write();
1159                    match (
1160                        accounts
1161                            .get_mut(&p.account_id)
1162                            .and_then(|s| s.instances.get_mut(&p.id)),
1163                        running,
1164                    ) {
1165                        (Some(inst), Ok(r)) => {
1166                            // A concurrent Terminate (code 48) or Stop (code 80)
1167                            // during the recovery window wins: don't resurrect the
1168                            // instance to `running`, and drop the container we just
1169                            // started (a terminated/stopped instance owns none).
1170                            // Mirrors the both-terminal guard in
1171                            // `instance::reconcile_started`. Guarding only code 48
1172                            // let a concurrent StopInstances get clobbered back to
1173                            // `running` with a fresh container (bug-hunt
1174                            // restart-dataloss).
1175                            if recovery_terminal_wins(inst.state_code) {
1176                                true
1177                            } else {
1178                                inst.state_code = 16;
1179                                inst.state_name = "running".to_string();
1180                                inst.private_ip = r.private_ip;
1181                                inst.container_id = Some(r.container_id);
1182                                false
1183                            }
1184                        }
1185                        (Some(inst), Err(error)) => {
1186                            // A concurrent Terminate (code 48) or Stop (code 80)
1187                            // wins over a boot failure too: leave the terminal
1188                            // state as-is rather than overwriting it to `stopped`.
1189                            // The unguarded write here previously clobbered a
1190                            // concurrent TerminateInstances (code 48) to `stopped`
1191                            // (bug-hunt restart-dataloss).
1192                            if recovery_terminal_wins(inst.state_code) {
1193                                false
1194                            } else {
1195                                tracing::error!(
1196                                    %error,
1197                                    instance_id = %p.id,
1198                                    "failed to recover ec2 backing container after restart",
1199                                );
1200                                inst.state_code = 80;
1201                                inst.state_name = "stopped".to_string();
1202                                inst.container_id = None;
1203                                false
1204                            }
1205                        }
1206                        // Deleted during recovery: stop the container we just
1207                        // started so it isn't orphaned (mirrors ElastiCache).
1208                        (None, Ok(_)) => true,
1209                        (None, Err(_)) => false,
1210                    }
1211                };
1212                if reap {
1213                    runtime.terminate_instance(&p.id).await;
1214                }
1215            }));
1216        }
1217
1218        // Once every instance is back up, (re)apply the security-group
1219        // firewall. The startup reaper cleared the previous process's nft
1220        // table / NetworkPolicies, and the per-instance recovery tasks above
1221        // don't reconcile — without this, recovered instances would run
1222        // unfiltered until some unrelated later op happened to trigger a
1223        // reconcile (#1745; bug-hunt 2026-06-18 finding 4.1). No-op when
1224        // enforcement is disabled.
1225        {
1226            let runtime = runtime.clone();
1227            let state = self.state.clone();
1228            tokio::spawn(async move {
1229                for h in handles {
1230                    let _ = h.await;
1231                }
1232                if runtime.network_isolation_enforced() {
1233                    firewall_model::reconcile(&state, &runtime).await;
1234                }
1235            });
1236        }
1237    }
1238}
1239
1240impl Default for Ec2Service {
1241    fn default() -> Self {
1242        Self::new()
1243    }
1244}
1245
1246/// Persist the current EC2 state as a snapshot. Offloads the serde + blocking
1247/// file write to the Tokio blocking pool. Noop when `store` is `None` (memory
1248/// mode). Shared by `Ec2Service::save_snapshot` and the CloudFormation
1249/// provisioner persist hook so both route through the same serialize-and-write
1250/// path. Backing containers are not serialized; they are reconciled on restart
1251/// via `Ec2Service::recover_persisted_containers`.
1252pub async fn save_ec2_snapshot(
1253    state: &SharedEc2State,
1254    store: Option<Arc<dyn SnapshotStore>>,
1255    lock: &AsyncMutex<()>,
1256) {
1257    let Some(store) = store else {
1258        return;
1259    };
1260    let _guard = lock.lock().await;
1261    let snapshot = Ec2Snapshot {
1262        schema_version: EC2_SNAPSHOT_SCHEMA_VERSION,
1263        accounts: Some(state.read().clone()),
1264    };
1265    let join = tokio::task::spawn_blocking(move || -> std::io::Result<()> {
1266        let bytes = serde_json::to_vec(&snapshot)
1267            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?;
1268        store.save(&bytes)
1269    })
1270    .await;
1271    match join {
1272        Ok(Ok(())) => {}
1273        Ok(Err(err)) => tracing::error!(%err, "failed to write ec2 snapshot"),
1274        Err(err) => tracing::error!(%err, "ec2 snapshot task panicked"),
1275    }
1276}
1277
1278/// True if a concurrent Terminate (code 48) or Stop (code 80) has already
1279/// claimed an instance during the restart recovery window, so
1280/// `recover_persisted_containers` must NOT overwrite that terminal state with a
1281/// recovered `running`/`stopped` row. Mirrors the both-terminal guard in
1282/// [`instance::reconcile_started`]; applies to BOTH the boot-success and
1283/// boot-failure arms (a boot failure previously clobbered a concurrent
1284/// Terminate to `stopped`; a boot success clobbered a concurrent Stop back to
1285/// `running` with a fresh container). bug-hunt restart-dataloss.
1286fn recovery_terminal_wins(state_code: i64) -> bool {
1287    state_code == 48 || state_code == 80
1288}
1289
1290#[async_trait]
1291impl AwsService for Ec2Service {
1292    fn service_name(&self) -> &str {
1293        "ec2"
1294    }
1295
1296    fn supported_actions(&self) -> &[&str] {
1297        SUPPORTED_ACTIONS
1298    }
1299
1300    async fn handle(&self, request: AwsRequest) -> Result<AwsResponse, AwsServiceError> {
1301        let mutates = is_mutating_action(&request.action);
1302        let result = match request.action.as_str() {
1303            "CreateTags" => tags::create_tags(self, &request),
1304            "DeleteTags" => tags::delete_tags(self, &request),
1305            "DescribeTags" => tags::describe_tags(self, &request),
1306            "DescribeRegions" => meta::describe_regions(self, &request),
1307            "DescribeAvailabilityZones" => meta::describe_availability_zones(self, &request),
1308            "DescribeAccountAttributes" => meta::describe_account_attributes(self, &request),
1309            "CreateVpc" => vpc::create_vpc(self, &request),
1310            "CreateDefaultVpc" => vpc::create_default_vpc(self, &request),
1311            "DeleteVpc" => vpc::delete_vpc(self, &request),
1312            "DescribeVpcs" => vpc::describe_vpcs(self, &request),
1313            "ModifyVpcAttribute" => vpc::modify_vpc_attribute(self, &request),
1314            "DescribeVpcAttribute" => vpc::describe_vpc_attribute(self, &request),
1315            "ModifyVpcTenancy" => vpc::modify_vpc_tenancy(self, &request),
1316            "AssociateVpcCidrBlock" => vpc::associate_vpc_cidr_block(self, &request),
1317            "DisassociateVpcCidrBlock" => vpc::disassociate_vpc_cidr_block(self, &request),
1318            "CreateDhcpOptions" => dhcp::create_dhcp_options(self, &request),
1319            "DeleteDhcpOptions" => dhcp::delete_dhcp_options(self, &request),
1320            "DescribeDhcpOptions" => dhcp::describe_dhcp_options(self, &request),
1321            "AssociateDhcpOptions" => dhcp::associate_dhcp_options(self, &request),
1322            "CreateSubnet" => subnet::create_subnet(self, &request),
1323            "CreateDefaultSubnet" => subnet::create_default_subnet(self, &request),
1324            "CreateSecondarySubnet" => subnet::create_secondary_subnet(self, &request),
1325            "DeleteSubnet" => subnet::delete_subnet(self, &request),
1326            "DeleteSecondarySubnet" => subnet::delete_secondary_subnet(self, &request),
1327            "DescribeSubnets" => subnet::describe_subnets(self, &request),
1328            "DescribeSecondarySubnets" => subnet::describe_secondary_subnets(self, &request),
1329            "ModifySubnetAttribute" => subnet::modify_subnet_attribute(self, &request),
1330            "AssociateSubnetCidrBlock" => subnet::associate_subnet_cidr_block(self, &request),
1331            "DisassociateSubnetCidrBlock" => subnet::disassociate_subnet_cidr_block(self, &request),
1332            "CreateSubnetCidrReservation" => subnet::create_subnet_cidr_reservation(self, &request),
1333            "DeleteSubnetCidrReservation" => subnet::delete_subnet_cidr_reservation(self, &request),
1334            "GetSubnetCidrReservations" => subnet::get_subnet_cidr_reservations(self, &request),
1335            "CreateSecurityGroup" => sg::create_security_group(self, &request),
1336            "DeleteSecurityGroup" => sg::delete_security_group(self, &request),
1337            "DescribeSecurityGroups" => sg::describe_security_groups(self, &request),
1338            "AuthorizeSecurityGroupIngress" => sg::authorize_security_group_ingress(self, &request),
1339            "AuthorizeSecurityGroupEgress" => sg::authorize_security_group_egress(self, &request),
1340            "RevokeSecurityGroupIngress" => sg::revoke_security_group_ingress(self, &request),
1341            "RevokeSecurityGroupEgress" => sg::revoke_security_group_egress(self, &request),
1342            "DescribeSecurityGroupRules" => sg::describe_security_group_rules(self, &request),
1343            "ModifySecurityGroupRules" => sg::modify_security_group_rules(self, &request),
1344            "UpdateSecurityGroupRuleDescriptionsIngress" => {
1345                sg::update_rule_descriptions_ingress(self, &request)
1346            }
1347            "UpdateSecurityGroupRuleDescriptionsEgress" => {
1348                sg::update_rule_descriptions_egress(self, &request)
1349            }
1350            "AssociateSecurityGroupVpc" => sg::associate_security_group_vpc(self, &request),
1351            "DisassociateSecurityGroupVpc" => sg::disassociate_security_group_vpc(self, &request),
1352            "DescribeSecurityGroupVpcAssociations" => {
1353                sg::describe_security_group_vpc_associations(self, &request)
1354            }
1355            "GetSecurityGroupsForVpc" => sg::get_security_groups_for_vpc(self, &request),
1356            "DescribeStaleSecurityGroups" => sg::describe_stale_security_groups(self, &request),
1357            "DescribeSecurityGroupReferences" => {
1358                sg::describe_security_group_references(self, &request)
1359            }
1360            "CreateRouteTable" => routing::create_route_table(self, &request),
1361            "DeleteRouteTable" => routing::delete_route_table(self, &request),
1362            "DescribeRouteTables" => routing::describe_route_tables(self, &request),
1363            "CreateRoute" => routing::create_route(self, &request),
1364            "DeleteRoute" => routing::delete_route(self, &request),
1365            "ReplaceRoute" => routing::replace_route(self, &request),
1366            "AssociateRouteTable" => routing::associate_route_table(self, &request),
1367            "DisassociateRouteTable" => routing::disassociate_route_table(self, &request),
1368            "ReplaceRouteTableAssociation" => {
1369                routing::replace_route_table_association(self, &request)
1370            }
1371            "CreateInternetGateway" => routing::create_internet_gateway(self, &request),
1372            "DeleteInternetGateway" => routing::delete_internet_gateway(self, &request),
1373            "DescribeInternetGateways" => routing::describe_internet_gateways(self, &request),
1374            "AttachInternetGateway" => routing::attach_internet_gateway(self, &request),
1375            "DetachInternetGateway" => routing::detach_internet_gateway(self, &request),
1376            "CreateEgressOnlyInternetGateway" => routing::create_egress_only_igw(self, &request),
1377            "DeleteEgressOnlyInternetGateway" => routing::delete_egress_only_igw(self, &request),
1378            "DescribeEgressOnlyInternetGateways" => {
1379                routing::describe_egress_only_igws(self, &request)
1380            }
1381            "CreateNatGateway" => routing::create_nat_gateway(self, &request),
1382            "DeleteNatGateway" => routing::delete_nat_gateway(self, &request),
1383            "DescribeNatGateways" => routing::describe_nat_gateways(self, &request),
1384            "AssignPrivateNatGatewayAddress" => {
1385                routing::assign_private_nat_gateway_address(self, &request)
1386            }
1387            "AssociateNatGatewayAddress" => routing::associate_nat_gateway_address(self, &request),
1388            "DisassociateNatGatewayAddress" => {
1389                routing::disassociate_nat_gateway_address(self, &request)
1390            }
1391            "UnassignPrivateNatGatewayAddress" => {
1392                routing::unassign_private_nat_gateway_address(self, &request)
1393            }
1394            "AllocateAddress" => eip::allocate_address(self, &request),
1395            "ReleaseAddress" => eip::release_address(self, &request),
1396            "DescribeAddresses" => eip::describe_addresses(self, &request),
1397            "AssociateAddress" => eip::associate_address(self, &request),
1398            "DisassociateAddress" => eip::disassociate_address(self, &request),
1399            "DescribeAddressesAttribute" => eip::describe_addresses_attribute(self, &request),
1400            "ModifyAddressAttribute" => eip::modify_address_attribute(self, &request),
1401            "ResetAddressAttribute" => eip::reset_address_attribute(self, &request),
1402            "MoveAddressToVpc" => eip::move_address_to_vpc(self, &request),
1403            "RestoreAddressToClassic" => eip::restore_address_to_classic(self, &request),
1404            "AcceptAddressTransfer" => eip::accept_address_transfer(self, &request),
1405            "EnableAddressTransfer" => eip::enable_address_transfer(self, &request),
1406            "DisableAddressTransfer" => eip::disable_address_transfer(self, &request),
1407            "DescribeAddressTransfers" => eip::describe_address_transfers(self, &request),
1408            "DescribeMovingAddresses" => eip::describe_moving_addresses(self, &request),
1409            "CreateKeyPair" => eip::create_key_pair(self, &request),
1410            "ImportKeyPair" => eip::import_key_pair(self, &request),
1411            "DeleteKeyPair" => eip::delete_key_pair(self, &request),
1412            "DescribeKeyPairs" => eip::describe_key_pairs(self, &request),
1413            "CreatePlacementGroup" => eip::create_placement_group(self, &request),
1414            "DeletePlacementGroup" => eip::delete_placement_group(self, &request),
1415            "DescribePlacementGroups" => eip::describe_placement_groups(self, &request),
1416            "GetGroupsForCapacityReservation" => {
1417                eip::get_groups_for_capacity_reservation(self, &request)
1418            }
1419            "CreateNetworkInterface" => eni::create_network_interface(self, &request),
1420            "DeleteNetworkInterface" => eni::delete_network_interface(self, &request),
1421            "DescribeNetworkInterfaces" => eni::describe_network_interfaces(self, &request),
1422            "AttachNetworkInterface" => eni::attach_network_interface(self, &request),
1423            "DetachNetworkInterface" => eni::detach_network_interface(self, &request),
1424            "ModifyNetworkInterfaceAttribute" => {
1425                eni::modify_network_interface_attribute(self, &request)
1426            }
1427            "ResetNetworkInterfaceAttribute" => {
1428                eni::reset_network_interface_attribute(self, &request)
1429            }
1430            "DescribeNetworkInterfaceAttribute" => {
1431                eni::describe_network_interface_attribute(self, &request)
1432            }
1433            "CreateNetworkInterfacePermission" => {
1434                eni::create_network_interface_permission(self, &request)
1435            }
1436            "DeleteNetworkInterfacePermission" => {
1437                eni::delete_network_interface_permission(self, &request)
1438            }
1439            "DescribeNetworkInterfacePermissions" => {
1440                eni::describe_network_interface_permissions(self, &request)
1441            }
1442            "AssignPrivateIpAddresses" => eni::assign_private_ip_addresses(self, &request),
1443            "UnassignPrivateIpAddresses" => eni::unassign_private_ip_addresses(self, &request),
1444            "AssignIpv6Addresses" => eni::assign_ipv6_addresses(self, &request),
1445            "UnassignIpv6Addresses" => eni::unassign_ipv6_addresses(self, &request),
1446            "RunInstances" => instance::run_instances(self, &request).await,
1447            "StartInstances" => instance::start_instances(self, &request).await,
1448            "StopInstances" => instance::stop_instances(self, &request).await,
1449            "RebootInstances" => instance::reboot_instances(self, &request).await,
1450            "TerminateInstances" => instance::terminate_instances(self, &request).await,
1451            "MonitorInstances" => instance::monitor_instances(self, &request),
1452            "UnmonitorInstances" => instance::unmonitor_instances(self, &request),
1453            "DescribeInstances" => instance::describe_instances(self, &request),
1454            "DescribeInstanceStatus" => instance::describe_instance_status(self, &request),
1455            "DescribeInstanceTypes" => instance::describe_instance_types(self, &request),
1456            "GetInstanceTypesFromInstanceRequirements" => {
1457                instance::get_instance_types_from_requirements(self, &request)
1458            }
1459            "DescribeInstanceAttribute" => instance::describe_instance_attribute(self, &request),
1460            "ModifyInstanceAttribute" => instance::modify_instance_attribute(self, &request),
1461            "ResetInstanceAttribute" => instance::reset_instance_attribute(self, &request),
1462            "ModifyInstancePlacement" => instance::modify_instance_placement(self, &request),
1463            "ModifyInstanceMetadataOptions" => {
1464                instance::modify_instance_metadata_options(self, &request)
1465            }
1466            "ModifyInstanceMaintenanceOptions" => {
1467                instance::modify_instance_maintenance_options(self, &request)
1468            }
1469            "ModifyInstanceCpuOptions" => instance::modify_instance_cpu_options(self, &request),
1470            "ModifyInstanceNetworkPerformanceOptions" => {
1471                instance::modify_instance_network_performance_options(self, &request)
1472            }
1473            "ModifyInstanceEventStartTime" => {
1474                instance::modify_instance_event_start_time(self, &request)
1475            }
1476            "DescribeInstanceCreditSpecifications" => {
1477                instance::describe_instance_credit_specifications(self, &request)
1478            }
1479            "ModifyInstanceCreditSpecification" => {
1480                instance::modify_instance_credit_specification(self, &request)
1481            }
1482            "GetInstanceMetadataDefaults" => {
1483                instance::get_instance_metadata_defaults(self, &request)
1484            }
1485            "ModifyInstanceMetadataDefaults" => {
1486                instance::modify_instance_metadata_defaults(self, &request)
1487            }
1488            "RegisterInstanceEventNotificationAttributes" => {
1489                instance::register_event_notification_attributes(self, &request)
1490            }
1491            "DeregisterInstanceEventNotificationAttributes" => {
1492                instance::deregister_event_notification_attributes(self, &request)
1493            }
1494            "DescribeInstanceEventNotificationAttributes" => {
1495                instance::describe_event_notification_attributes(self, &request)
1496            }
1497            "ReportInstanceStatus" => instance::report_instance_status(self, &request),
1498            "DescribeInstanceTopology" => instance::describe_instance_topology(self, &request),
1499            "CreateVolume" => volume::create_volume(self, &request),
1500            "DeleteVolume" => volume::delete_volume(self, &request),
1501            "DescribeVolumes" => volume::describe_volumes(self, &request),
1502            "AttachVolume" => volume::attach_volume(self, &request),
1503            "DetachVolume" => volume::detach_volume(self, &request),
1504            "ModifyVolume" => volume::modify_volume(self, &request),
1505            "DescribeVolumesModifications" => {
1506                volume::describe_volumes_modifications(self, &request)
1507            }
1508            "DescribeVolumeStatus" => volume::describe_volume_status(self, &request),
1509            "DescribeVolumeAttribute" => volume::describe_volume_attribute(self, &request),
1510            "ModifyVolumeAttribute" => volume::modify_volume_attribute(self, &request),
1511            "EnableVolumeIO" => volume::enable_volume_io(self, &request),
1512            "ListVolumesInRecycleBin" => volume::list_volumes_in_recycle_bin(self, &request),
1513            "RestoreVolumeFromRecycleBin" => {
1514                volume::restore_volume_from_recycle_bin(self, &request)
1515            }
1516            "GetEbsEncryptionByDefault" => volume::get_ebs_encryption_by_default(self, &request),
1517            "EnableEbsEncryptionByDefault" => {
1518                volume::enable_ebs_encryption_by_default(self, &request)
1519            }
1520            "DisableEbsEncryptionByDefault" => {
1521                volume::disable_ebs_encryption_by_default(self, &request)
1522            }
1523            "GetEbsDefaultKmsKeyId" => volume::get_ebs_default_kms_key_id(self, &request),
1524            "ModifyEbsDefaultKmsKeyId" => volume::modify_ebs_default_kms_key_id(self, &request),
1525            "ResetEbsDefaultKmsKeyId" => volume::reset_ebs_default_kms_key_id(self, &request),
1526            "CreateSnapshot" => snapshot::create_snapshot(self, &request),
1527            "CreateSnapshots" => snapshot::create_snapshots(self, &request),
1528            "DeleteSnapshot" => snapshot::delete_snapshot(self, &request),
1529            "DescribeSnapshots" => snapshot::describe_snapshots(self, &request),
1530            "CopySnapshot" => snapshot::copy_snapshot(self, &request),
1531            "DescribeSnapshotAttribute" => snapshot::describe_snapshot_attribute(self, &request),
1532            "ModifySnapshotAttribute" => snapshot::modify_snapshot_attribute(self, &request),
1533            "ResetSnapshotAttribute" => snapshot::reset_snapshot_attribute(self, &request),
1534            "ModifySnapshotTier" => snapshot::modify_snapshot_tier(self, &request),
1535            "DescribeSnapshotTierStatus" => snapshot::describe_snapshot_tier_status(self, &request),
1536            "RestoreSnapshotTier" => snapshot::restore_snapshot_tier(self, &request),
1537            "ListSnapshotsInRecycleBin" => snapshot::list_snapshots_in_recycle_bin(self, &request),
1538            "RestoreSnapshotFromRecycleBin" => {
1539                snapshot::restore_snapshot_from_recycle_bin(self, &request)
1540            }
1541            "LockSnapshot" => snapshot::lock_snapshot(self, &request),
1542            "UnlockSnapshot" => snapshot::unlock_snapshot(self, &request),
1543            "DescribeLockedSnapshots" => snapshot::describe_locked_snapshots(self, &request),
1544            "GetSnapshotBlockPublicAccessState" => {
1545                snapshot::get_snapshot_block_public_access_state(self, &request)
1546            }
1547            "EnableSnapshotBlockPublicAccess" => {
1548                snapshot::enable_snapshot_block_public_access(self, &request)
1549            }
1550            "DisableSnapshotBlockPublicAccess" => {
1551                snapshot::disable_snapshot_block_public_access(self, &request)
1552            }
1553            "EnableFastSnapshotRestores" => snapshot::enable_fast_snapshot_restores(self, &request),
1554            "DisableFastSnapshotRestores" => {
1555                snapshot::disable_fast_snapshot_restores(self, &request)
1556            }
1557            "DescribeFastSnapshotRestores" => {
1558                snapshot::describe_fast_snapshot_restores(self, &request)
1559            }
1560            "CreateImage" => image::create_image(self, &request),
1561            "RegisterImage" => image::register_image(self, &request),
1562            "DeregisterImage" => image::deregister_image(self, &request),
1563            "DescribeImages" => image::describe_images(self, &request),
1564            "CopyImage" => image::copy_image(self, &request),
1565            "DescribeImageAttribute" => image::describe_image_attribute(self, &request),
1566            "ModifyImageAttribute" => image::modify_image_attribute(self, &request),
1567            "ResetImageAttribute" => image::reset_image_attribute(self, &request),
1568            "EnableImage" => image::enable_image(self, &request),
1569            "DisableImage" => image::disable_image(self, &request),
1570            "AttachImageWatermark" => image::attach_image_watermark(self, &request),
1571            "DetachImageWatermark" => image::detach_image_watermark(self, &request),
1572            "EnableImageDeprecation" => image::enable_image_deprecation(self, &request),
1573            "DisableImageDeprecation" => image::disable_image_deprecation(self, &request),
1574            "EnableImageDeregistrationProtection" => {
1575                image::enable_image_deregistration_protection(self, &request)
1576            }
1577            "DisableImageDeregistrationProtection" => {
1578                image::disable_image_deregistration_protection(self, &request)
1579            }
1580            "CancelImageLaunchPermission" => image::cancel_image_launch_permission(self, &request),
1581            "RestoreImageFromRecycleBin" => image::restore_image_from_recycle_bin(self, &request),
1582            "ListImagesInRecycleBin" => image::list_images_in_recycle_bin(self, &request),
1583            "EnableImageBlockPublicAccess" => {
1584                image::enable_image_block_public_access(self, &request)
1585            }
1586            "DisableImageBlockPublicAccess" => {
1587                image::disable_image_block_public_access(self, &request)
1588            }
1589            "GetImageBlockPublicAccessState" => {
1590                image::get_image_block_public_access_state(self, &request)
1591            }
1592            "EnableAllowedImagesSettings" => image::enable_allowed_images_settings(self, &request),
1593            "DisableAllowedImagesSettings" => {
1594                image::disable_allowed_images_settings(self, &request)
1595            }
1596            "GetAllowedImagesSettings" => image::get_allowed_images_settings(self, &request),
1597            "ReplaceImageCriteriaInAllowedImagesSettings" => {
1598                image::replace_image_criteria_in_allowed_images_settings(self, &request)
1599            }
1600            "CreateStoreImageTask" => image::create_store_image_task(self, &request),
1601            "DescribeStoreImageTasks" => image::describe_store_image_tasks(self, &request),
1602            "CreateRestoreImageTask" => image::create_restore_image_task(self, &request),
1603            "DescribeFastLaunchImages" => image::describe_fast_launch_images(self, &request),
1604            "CreateNetworkAcl" => nacl::create_network_acl(self, &request),
1605            "DeleteNetworkAcl" => nacl::delete_network_acl(self, &request),
1606            "DescribeNetworkAcls" => nacl::describe_network_acls(self, &request),
1607            "CreateNetworkAclEntry" => nacl::create_network_acl_entry(self, &request),
1608            "DeleteNetworkAclEntry" => nacl::delete_network_acl_entry(self, &request),
1609            "ReplaceNetworkAclEntry" => nacl::replace_network_acl_entry(self, &request),
1610            "ReplaceNetworkAclAssociation" => nacl::replace_network_acl_association(self, &request),
1611            "CreateVpcPeeringConnection" => nacl::create_vpc_peering_connection(self, &request),
1612            "DeleteVpcPeeringConnection" => nacl::delete_vpc_peering_connection(self, &request),
1613            "DescribeVpcPeeringConnections" => {
1614                nacl::describe_vpc_peering_connections(self, &request)
1615            }
1616            "AcceptVpcPeeringConnection" => nacl::accept_vpc_peering_connection(self, &request),
1617            "RejectVpcPeeringConnection" => nacl::reject_vpc_peering_connection(self, &request),
1618            "ModifyVpcPeeringConnectionOptions" => {
1619                nacl::modify_vpc_peering_connection_options(self, &request)
1620            }
1621            "CreateVpcEndpoint" => endpoint::create_vpc_endpoint(self, &request),
1622            "DeleteVpcEndpoints" => endpoint::delete_vpc_endpoints(self, &request),
1623            "DescribeVpcEndpoints" => endpoint::describe_vpc_endpoints(self, &request),
1624            "ModifyVpcEndpoint" => endpoint::modify_vpc_endpoint(self, &request),
1625            "DescribeVpcEndpointServices" => {
1626                endpoint::describe_vpc_endpoint_services(self, &request)
1627            }
1628            "DescribeVpcEndpointConnections" => {
1629                endpoint::describe_vpc_endpoint_connections(self, &request)
1630            }
1631            "AcceptVpcEndpointConnections" => {
1632                endpoint::accept_vpc_endpoint_connections(self, &request)
1633            }
1634            "RejectVpcEndpointConnections" => {
1635                endpoint::reject_vpc_endpoint_connections(self, &request)
1636            }
1637            "CreateVpcEndpointServiceConfiguration" => {
1638                endpoint::create_vpc_endpoint_service_configuration(self, &request)
1639            }
1640            "DeleteVpcEndpointServiceConfigurations" => {
1641                endpoint::delete_vpc_endpoint_service_configurations(self, &request)
1642            }
1643            "DescribeVpcEndpointServiceConfigurations" => {
1644                endpoint::describe_vpc_endpoint_service_configurations(self, &request)
1645            }
1646            "ModifyVpcEndpointServiceConfiguration" => {
1647                endpoint::modify_vpc_endpoint_service_configuration(self, &request)
1648            }
1649            "DescribeVpcEndpointServicePermissions" => {
1650                endpoint::describe_vpc_endpoint_service_permissions(self, &request)
1651            }
1652            "ModifyVpcEndpointServicePermissions" => {
1653                endpoint::modify_vpc_endpoint_service_permissions(self, &request)
1654            }
1655            "ModifyVpcEndpointServicePayerResponsibility" => {
1656                endpoint::modify_vpc_endpoint_service_payer_responsibility(self, &request)
1657            }
1658            "StartVpcEndpointServicePrivateDnsVerification" => {
1659                endpoint::start_vpc_endpoint_service_private_dns_verification(self, &request)
1660            }
1661            "CreateVpcEndpointConnectionNotification" => {
1662                endpoint::create_vpc_endpoint_connection_notification(self, &request)
1663            }
1664            "DeleteVpcEndpointConnectionNotifications" => {
1665                endpoint::delete_vpc_endpoint_connection_notifications(self, &request)
1666            }
1667            "DescribeVpcEndpointConnectionNotifications" => {
1668                endpoint::describe_vpc_endpoint_connection_notifications(self, &request)
1669            }
1670            "ModifyVpcEndpointConnectionNotification" => {
1671                endpoint::modify_vpc_endpoint_connection_notification(self, &request)
1672            }
1673            "DescribeVpcEndpointAssociations" => {
1674                endpoint::describe_vpc_endpoint_associations(self, &request)
1675            }
1676            "CreateFlowLogs" => endpoint::create_flow_logs(self, &request),
1677            "DeleteFlowLogs" => endpoint::delete_flow_logs(self, &request),
1678            "DescribeFlowLogs" => endpoint::describe_flow_logs(self, &request),
1679            "GetFlowLogsIntegrationTemplate" => {
1680                endpoint::get_flow_logs_integration_template(self, &request)
1681            }
1682            "CreateLaunchTemplate" => fleet::create_launch_template(self, &request),
1683            "CreateLaunchTemplateVersion" => fleet::create_launch_template_version(self, &request),
1684            "DeleteLaunchTemplate" => fleet::delete_launch_template(self, &request),
1685            "DeleteLaunchTemplateVersions" => {
1686                fleet::delete_launch_template_versions(self, &request)
1687            }
1688            "DescribeLaunchTemplates" => fleet::describe_launch_templates(self, &request),
1689            "DescribeLaunchTemplateVersions" => {
1690                fleet::describe_launch_template_versions(self, &request)
1691            }
1692            "GetLaunchTemplateData" => fleet::get_launch_template_data(self, &request),
1693            "ModifyLaunchTemplate" => fleet::modify_launch_template(self, &request),
1694            "RequestSpotInstances" => fleet::request_spot_instances(self, &request),
1695            "DescribeSpotInstanceRequests" => {
1696                fleet::describe_spot_instance_requests(self, &request)
1697            }
1698            "CancelSpotInstanceRequests" => fleet::cancel_spot_instance_requests(self, &request),
1699            "RequestSpotFleet" => fleet::request_spot_fleet(self, &request),
1700            "DescribeSpotFleetRequests" => fleet::describe_spot_fleet_requests(self, &request),
1701            "CancelSpotFleetRequests" => fleet::cancel_spot_fleet_requests(self, &request),
1702            "ModifySpotFleetRequest" => fleet::modify_spot_fleet_request(self, &request),
1703            "DescribeSpotFleetInstances" => fleet::describe_spot_fleet_instances(self, &request),
1704            "DescribeSpotFleetRequestHistory" => {
1705                fleet::describe_spot_fleet_request_history(self, &request)
1706            }
1707            "DescribeSpotPriceHistory" => fleet::describe_spot_price_history(self, &request),
1708            "GetSpotPlacementScores" => fleet::get_spot_placement_scores(self, &request),
1709            "CreateSpotDatafeedSubscription" => {
1710                fleet::create_spot_datafeed_subscription(self, &request)
1711            }
1712            "DeleteSpotDatafeedSubscription" => {
1713                fleet::delete_spot_datafeed_subscription(self, &request)
1714            }
1715            "DescribeSpotDatafeedSubscription" => {
1716                fleet::describe_spot_datafeed_subscription(self, &request)
1717            }
1718            "CreateFleet" => fleet::create_fleet(self, &request),
1719            "DeleteFleets" => fleet::delete_fleets(self, &request),
1720            "DescribeFleets" => fleet::describe_fleets(self, &request),
1721            "ModifyFleet" => fleet::modify_fleet(self, &request),
1722            "DescribeFleetHistory" => fleet::describe_fleet_history(self, &request),
1723            "DescribeFleetInstances" => fleet::describe_fleet_instances(self, &request),
1724            "CreateCapacityReservation" => capacity::create_capacity_reservation(self, &request),
1725            "CancelCapacityReservation" => capacity::cancel_capacity_reservation(self, &request),
1726            "DescribeCapacityReservations" => {
1727                capacity::describe_capacity_reservations(self, &request)
1728            }
1729            "ModifyCapacityReservation" => capacity::modify_capacity_reservation(self, &request),
1730            "GetCapacityReservationUsage" => {
1731                capacity::get_capacity_reservation_usage(self, &request)
1732            }
1733            "CreateCapacityReservationFleet" => {
1734                capacity::create_capacity_reservation_fleet(self, &request)
1735            }
1736            "CancelCapacityReservationFleets" => {
1737                capacity::cancel_capacity_reservation_fleets(self, &request)
1738            }
1739            "DescribeCapacityReservationFleets" => {
1740                capacity::describe_capacity_reservation_fleets(self, &request)
1741            }
1742            "ModifyCapacityReservationFleet" => {
1743                capacity::modify_capacity_reservation_fleet(self, &request)
1744            }
1745            "ModifyInstanceCapacityReservationAttributes" => {
1746                capacity::modify_instance_capacity_reservation_attributes(self, &request)
1747            }
1748            "CreateCapacityReservationBySplitting" => {
1749                capacity::create_capacity_reservation_by_splitting(self, &request)
1750            }
1751            "MoveCapacityReservationInstances" => {
1752                capacity::move_capacity_reservation_instances(self, &request)
1753            }
1754            "DescribeCapacityReservationBillingRequests" => {
1755                capacity::describe_capacity_reservation_billing_requests(self, &request)
1756            }
1757            "AssociateCapacityReservationBillingOwner" => {
1758                capacity::associate_capacity_reservation_billing_owner(self, &request)
1759            }
1760            "DisassociateCapacityReservationBillingOwner" => {
1761                capacity::disassociate_capacity_reservation_billing_owner(self, &request)
1762            }
1763            "AcceptCapacityReservationBillingOwnership" => {
1764                capacity::accept_capacity_reservation_billing_ownership(self, &request)
1765            }
1766            "RejectCapacityReservationBillingOwnership" => {
1767                capacity::reject_capacity_reservation_billing_ownership(self, &request)
1768            }
1769            "DescribeCapacityBlockOfferings" => {
1770                capacity::describe_capacity_block_offerings(self, &request)
1771            }
1772            "DescribeCapacityBlocks" => capacity::describe_capacity_blocks(self, &request),
1773            "PurchaseCapacityBlock" => capacity::purchase_capacity_block(self, &request),
1774            "DescribeCapacityBlockStatus" => {
1775                capacity::describe_capacity_block_status(self, &request)
1776            }
1777            "DescribeCapacityBlockExtensionHistory" => {
1778                capacity::describe_capacity_block_extension_history(self, &request)
1779            }
1780            "DescribeCapacityBlockExtensionOfferings" => {
1781                capacity::describe_capacity_block_extension_offerings(self, &request)
1782            }
1783            "PurchaseCapacityBlockExtension" => {
1784                capacity::purchase_capacity_block_extension(self, &request)
1785            }
1786            "DescribeCapacityReservationTopology" => {
1787                capacity::describe_capacity_reservation_topology(self, &request)
1788            }
1789            "CreateInterruptibleCapacityReservationAllocation" => {
1790                capacity::create_interruptible_capacity_reservation_allocation(self, &request)
1791            }
1792            "UpdateInterruptibleCapacityReservationAllocation" => {
1793                capacity::update_interruptible_capacity_reservation_allocation(self, &request)
1794            }
1795            "DescribeReservedInstances" => reserved::describe_reserved_instances(self, &request),
1796            "DescribeReservedInstancesOfferings" => {
1797                reserved::describe_reserved_instances_offerings(self, &request)
1798            }
1799            "PurchaseReservedInstancesOffering" => {
1800                reserved::purchase_reserved_instances_offering(self, &request)
1801            }
1802            "DescribeReservedInstancesListings" => {
1803                reserved::describe_reserved_instances_listings(self, &request)
1804            }
1805            "CreateReservedInstancesListing" => {
1806                reserved::create_reserved_instances_listing(self, &request)
1807            }
1808            "CancelReservedInstancesListing" => {
1809                reserved::cancel_reserved_instances_listing(self, &request)
1810            }
1811            "DescribeReservedInstancesModifications" => {
1812                reserved::describe_reserved_instances_modifications(self, &request)
1813            }
1814            "ModifyReservedInstances" => reserved::modify_reserved_instances(self, &request),
1815            "GetReservedInstancesExchangeQuote" => {
1816                reserved::get_reserved_instances_exchange_quote(self, &request)
1817            }
1818            "AcceptReservedInstancesExchangeQuote" => {
1819                reserved::accept_reserved_instances_exchange_quote(self, &request)
1820            }
1821            "DeleteQueuedReservedInstances" => {
1822                reserved::delete_queued_reserved_instances(self, &request)
1823            }
1824            "AllocateHosts" => reserved::allocate_hosts(self, &request),
1825            "DescribeHosts" => reserved::describe_hosts(self, &request),
1826            "ModifyHosts" => reserved::modify_hosts(self, &request),
1827            "ReleaseHosts" => reserved::release_hosts(self, &request),
1828            "DescribeMacHosts" => reserved::describe_mac_hosts(self, &request),
1829            "CreateTransitGateway" => tgw::create_transit_gateway(self, &request),
1830            "DeleteTransitGateway" => tgw::delete_transit_gateway(self, &request),
1831            "DescribeTransitGateways" => tgw::describe_transit_gateways(self, &request),
1832            "ModifyTransitGateway" => tgw::modify_transit_gateway(self, &request),
1833            "CreateTransitGatewayVpcAttachment" => {
1834                tgw::create_transit_gateway_vpc_attachment(self, &request)
1835            }
1836            "DeleteTransitGatewayVpcAttachment" => {
1837                tgw::delete_transit_gateway_vpc_attachment(self, &request)
1838            }
1839            "DescribeTransitGatewayVpcAttachments" => {
1840                tgw::describe_transit_gateway_vpc_attachments(self, &request)
1841            }
1842            "ModifyTransitGatewayVpcAttachment" => {
1843                tgw::modify_transit_gateway_vpc_attachment(self, &request)
1844            }
1845            "AcceptTransitGatewayVpcAttachment" => {
1846                tgw::accept_transit_gateway_vpc_attachment(self, &request)
1847            }
1848            "RejectTransitGatewayVpcAttachment" => {
1849                tgw::reject_transit_gateway_vpc_attachment(self, &request)
1850            }
1851            "DescribeTransitGatewayAttachments" => {
1852                tgw::describe_transit_gateway_attachments(self, &request)
1853            }
1854            "CreateTransitGatewayRouteTable" => {
1855                tgw::create_transit_gateway_route_table(self, &request)
1856            }
1857            "DeleteTransitGatewayRouteTable" => {
1858                tgw::delete_transit_gateway_route_table(self, &request)
1859            }
1860            "DescribeTransitGatewayRouteTables" => {
1861                tgw::describe_transit_gateway_route_tables(self, &request)
1862            }
1863            "AssociateTransitGatewayRouteTable" => {
1864                tgw::associate_transit_gateway_route_table(self, &request)
1865            }
1866            "DisassociateTransitGatewayRouteTable" => {
1867                tgw::disassociate_transit_gateway_route_table(self, &request)
1868            }
1869            "EnableTransitGatewayRouteTablePropagation" => {
1870                tgw::enable_transit_gateway_route_table_propagation(self, &request)
1871            }
1872            "DisableTransitGatewayRouteTablePropagation" => {
1873                tgw::disable_transit_gateway_route_table_propagation(self, &request)
1874            }
1875            "CreateTransitGatewayRoute" => tgw::create_transit_gateway_route(self, &request),
1876            "DeleteTransitGatewayRoute" => tgw::delete_transit_gateway_route(self, &request),
1877            "ReplaceTransitGatewayRoute" => tgw::replace_transit_gateway_route(self, &request),
1878            "SearchTransitGatewayRoutes" => tgw::search_transit_gateway_routes(self, &request),
1879            "ExportTransitGatewayRoutes" => tgw::export_transit_gateway_routes(self, &request),
1880            "GetTransitGatewayRouteTableAssociations" => {
1881                tgw::get_transit_gateway_route_table_associations(self, &request)
1882            }
1883            "GetTransitGatewayRouteTablePropagations" => {
1884                tgw::get_transit_gateway_route_table_propagations(self, &request)
1885            }
1886            "GetTransitGatewayAttachmentPropagations" => {
1887                tgw::get_transit_gateway_attachment_propagations(self, &request)
1888            }
1889            "CreateTransitGatewayPrefixListReference" => {
1890                tgw::create_transit_gateway_prefix_list_reference(self, &request)
1891            }
1892            "DeleteTransitGatewayPrefixListReference" => {
1893                tgw::delete_transit_gateway_prefix_list_reference(self, &request)
1894            }
1895            "ModifyTransitGatewayPrefixListReference" => {
1896                tgw::modify_transit_gateway_prefix_list_reference(self, &request)
1897            }
1898            "GetTransitGatewayPrefixListReferences" => {
1899                tgw::get_transit_gateway_prefix_list_references(self, &request)
1900            }
1901            "CreateTransitGatewayPeeringAttachment" => {
1902                tgw_peering::create_transit_gateway_peering_attachment(self, &request)
1903            }
1904            "DeleteTransitGatewayPeeringAttachment" => {
1905                tgw_peering::delete_transit_gateway_peering_attachment(self, &request)
1906            }
1907            "DescribeTransitGatewayPeeringAttachments" => {
1908                tgw_peering::describe_transit_gateway_peering_attachments(self, &request)
1909            }
1910            "AcceptTransitGatewayPeeringAttachment" => {
1911                tgw_peering::accept_transit_gateway_peering_attachment(self, &request)
1912            }
1913            "RejectTransitGatewayPeeringAttachment" => {
1914                tgw_peering::reject_transit_gateway_peering_attachment(self, &request)
1915            }
1916            "CreateTransitGatewayConnect" => {
1917                tgw_peering::create_transit_gateway_connect(self, &request)
1918            }
1919            "DeleteTransitGatewayConnect" => {
1920                tgw_peering::delete_transit_gateway_connect(self, &request)
1921            }
1922            "DescribeTransitGatewayConnects" => {
1923                tgw_peering::describe_transit_gateway_connects(self, &request)
1924            }
1925            "CreateTransitGatewayConnectPeer" => {
1926                tgw_peering::create_transit_gateway_connect_peer(self, &request)
1927            }
1928            "DeleteTransitGatewayConnectPeer" => {
1929                tgw_peering::delete_transit_gateway_connect_peer(self, &request)
1930            }
1931            "DescribeTransitGatewayConnectPeers" => {
1932                tgw_peering::describe_transit_gateway_connect_peers(self, &request)
1933            }
1934            "CreateTransitGatewayPolicyTable" => {
1935                tgw_peering::create_transit_gateway_policy_table(self, &request)
1936            }
1937            "DeleteTransitGatewayPolicyTable" => {
1938                tgw_peering::delete_transit_gateway_policy_table(self, &request)
1939            }
1940            "DescribeTransitGatewayPolicyTables" => {
1941                tgw_peering::describe_transit_gateway_policy_tables(self, &request)
1942            }
1943            "AssociateTransitGatewayPolicyTable" => {
1944                tgw_peering::associate_transit_gateway_policy_table(self, &request)
1945            }
1946            "DisassociateTransitGatewayPolicyTable" => {
1947                tgw_peering::disassociate_transit_gateway_policy_table(self, &request)
1948            }
1949            "GetTransitGatewayPolicyTableAssociations" => {
1950                tgw_peering::get_transit_gateway_policy_table_associations(self, &request)
1951            }
1952            "GetTransitGatewayPolicyTableEntries" => {
1953                tgw_peering::get_transit_gateway_policy_table_entries(self, &request)
1954            }
1955            "CreateTransitGatewayRouteTableAnnouncement" => {
1956                tgw_peering::create_transit_gateway_route_table_announcement(self, &request)
1957            }
1958            "DeleteTransitGatewayRouteTableAnnouncement" => {
1959                tgw_peering::delete_transit_gateway_route_table_announcement(self, &request)
1960            }
1961            "DescribeTransitGatewayRouteTableAnnouncements" => {
1962                tgw_peering::describe_transit_gateway_route_table_announcements(self, &request)
1963            }
1964            "CreateTransitGatewayMulticastDomain" => {
1965                tgw_mcast::create_transit_gateway_multicast_domain(self, &request)
1966            }
1967            "DeleteTransitGatewayMulticastDomain" => {
1968                tgw_mcast::delete_transit_gateway_multicast_domain(self, &request)
1969            }
1970            "DescribeTransitGatewayMulticastDomains" => {
1971                tgw_mcast::describe_transit_gateway_multicast_domains(self, &request)
1972            }
1973            "AssociateTransitGatewayMulticastDomain" => {
1974                tgw_mcast::associate_transit_gateway_multicast_domain(self, &request)
1975            }
1976            "DisassociateTransitGatewayMulticastDomain" => {
1977                tgw_mcast::disassociate_transit_gateway_multicast_domain(self, &request)
1978            }
1979            "AcceptTransitGatewayMulticastDomainAssociations" => {
1980                tgw_mcast::accept_transit_gateway_multicast_domain_associations(self, &request)
1981            }
1982            "RejectTransitGatewayMulticastDomainAssociations" => {
1983                tgw_mcast::reject_transit_gateway_multicast_domain_associations(self, &request)
1984            }
1985            "GetTransitGatewayMulticastDomainAssociations" => {
1986                tgw_mcast::get_transit_gateway_multicast_domain_associations(self, &request)
1987            }
1988            "RegisterTransitGatewayMulticastGroupMembers" => {
1989                tgw_mcast::register_transit_gateway_multicast_group_members(self, &request)
1990            }
1991            "RegisterTransitGatewayMulticastGroupSources" => {
1992                tgw_mcast::register_transit_gateway_multicast_group_sources(self, &request)
1993            }
1994            "DeregisterTransitGatewayMulticastGroupMembers" => {
1995                tgw_mcast::deregister_transit_gateway_multicast_group_members(self, &request)
1996            }
1997            "DeregisterTransitGatewayMulticastGroupSources" => {
1998                tgw_mcast::deregister_transit_gateway_multicast_group_sources(self, &request)
1999            }
2000            "SearchTransitGatewayMulticastGroups" => {
2001                tgw_mcast::search_transit_gateway_multicast_groups(self, &request)
2002            }
2003            "CreateTransitGatewayMeteringPolicy" => {
2004                tgw_mcast::create_transit_gateway_metering_policy(self, &request)
2005            }
2006            "DeleteTransitGatewayMeteringPolicy" => {
2007                tgw_mcast::delete_transit_gateway_metering_policy(self, &request)
2008            }
2009            "DescribeTransitGatewayMeteringPolicies" => {
2010                tgw_mcast::describe_transit_gateway_metering_policies(self, &request)
2011            }
2012            "ModifyTransitGatewayMeteringPolicy" => {
2013                tgw_mcast::modify_transit_gateway_metering_policy(self, &request)
2014            }
2015            "CreateTransitGatewayMeteringPolicyEntry" => {
2016                tgw_mcast::create_transit_gateway_metering_policy_entry(self, &request)
2017            }
2018            "DeleteTransitGatewayMeteringPolicyEntry" => {
2019                tgw_mcast::delete_transit_gateway_metering_policy_entry(self, &request)
2020            }
2021            "GetTransitGatewayMeteringPolicyEntries" => {
2022                tgw_mcast::get_transit_gateway_metering_policy_entries(self, &request)
2023            }
2024            "AcceptTransitGatewayClientVpnAttachment" => {
2025                tgw_mcast::accept_transit_gateway_client_vpn_attachment(self, &request)
2026            }
2027            "DeleteTransitGatewayClientVpnAttachment" => {
2028                tgw_mcast::delete_transit_gateway_client_vpn_attachment(self, &request)
2029            }
2030            "RejectTransitGatewayClientVpnAttachment" => {
2031                tgw_mcast::reject_transit_gateway_client_vpn_attachment(self, &request)
2032            }
2033            "CreateCustomerGateway" => vpn::create_customer_gateway(self, &request),
2034            "DeleteCustomerGateway" => vpn::delete_customer_gateway(self, &request),
2035            "DescribeCustomerGateways" => vpn::describe_customer_gateways(self, &request),
2036            "CreateVpnGateway" => vpn::create_vpn_gateway(self, &request),
2037            "DeleteVpnGateway" => vpn::delete_vpn_gateway(self, &request),
2038            "DescribeVpnGateways" => vpn::describe_vpn_gateways(self, &request),
2039            "AttachVpnGateway" => vpn::attach_vpn_gateway(self, &request),
2040            "DetachVpnGateway" => vpn::detach_vpn_gateway(self, &request),
2041            "CreateVpnConnection" => vpn::create_vpn_connection(self, &request),
2042            "DeleteVpnConnection" => vpn::delete_vpn_connection(self, &request),
2043            "DescribeVpnConnections" => vpn::describe_vpn_connections(self, &request),
2044            "ModifyVpnConnection" => vpn::modify_vpn_connection(self, &request),
2045            "ModifyVpnConnectionOptions" => vpn::modify_vpn_connection_options(self, &request),
2046            "CreateVpnConnectionRoute" => vpn::create_vpn_connection_route(self, &request),
2047            "DeleteVpnConnectionRoute" => vpn::delete_vpn_connection_route(self, &request),
2048            "ModifyVpnTunnelOptions" => vpn::modify_vpn_tunnel_options(self, &request),
2049            "ModifyVpnTunnelCertificate" => vpn::modify_vpn_tunnel_certificate(self, &request),
2050            "ReplaceVpnTunnel" => vpn::replace_vpn_tunnel(self, &request),
2051            "GetActiveVpnTunnelStatus" => vpn::get_active_vpn_tunnel_status(self, &request),
2052            "GetVpnTunnelReplacementStatus" => {
2053                vpn::get_vpn_tunnel_replacement_status(self, &request)
2054            }
2055            "GetVpnConnectionDeviceTypes" => vpn::get_vpn_connection_device_types(self, &request),
2056            "GetVpnConnectionDeviceSampleConfiguration" => {
2057                vpn::get_vpn_connection_device_sample_configuration(self, &request)
2058            }
2059            "CreateVpnConcentrator" => vpn::create_vpn_concentrator(self, &request),
2060            "DeleteVpnConcentrator" => vpn::delete_vpn_concentrator(self, &request),
2061            "DescribeVpnConcentrators" => vpn::describe_vpn_concentrators(self, &request),
2062            "CreateClientVpnEndpoint" => cvpn::create_client_vpn_endpoint(self, &request),
2063            "DeleteClientVpnEndpoint" => cvpn::delete_client_vpn_endpoint(self, &request),
2064            "DescribeClientVpnEndpoints" => cvpn::describe_client_vpn_endpoints(self, &request),
2065            "ModifyClientVpnEndpoint" => cvpn::modify_client_vpn_endpoint(self, &request),
2066            "CreateClientVpnRoute" => cvpn::create_client_vpn_route(self, &request),
2067            "DeleteClientVpnRoute" => cvpn::delete_client_vpn_route(self, &request),
2068            "DescribeClientVpnRoutes" => cvpn::describe_client_vpn_routes(self, &request),
2069            "AuthorizeClientVpnIngress" => cvpn::authorize_client_vpn_ingress(self, &request),
2070            "RevokeClientVpnIngress" => cvpn::revoke_client_vpn_ingress(self, &request),
2071            "DescribeClientVpnAuthorizationRules" => {
2072                cvpn::describe_client_vpn_authorization_rules(self, &request)
2073            }
2074            "AssociateClientVpnTargetNetwork" => {
2075                cvpn::associate_client_vpn_target_network(self, &request)
2076            }
2077            "DisassociateClientVpnTargetNetwork" => {
2078                cvpn::disassociate_client_vpn_target_network(self, &request)
2079            }
2080            "DescribeClientVpnTargetNetworks" => {
2081                cvpn::describe_client_vpn_target_networks(self, &request)
2082            }
2083            "ApplySecurityGroupsToClientVpnTargetNetwork" => {
2084                cvpn::apply_security_groups_to_client_vpn_target_network(self, &request)
2085            }
2086            "DescribeClientVpnConnections" => cvpn::describe_client_vpn_connections(self, &request),
2087            "TerminateClientVpnConnections" => {
2088                cvpn::terminate_client_vpn_connections(self, &request)
2089            }
2090            "ExportClientVpnClientCertificateRevocationList" => {
2091                cvpn::export_client_vpn_client_certificate_revocation_list(self, &request)
2092            }
2093            "ExportClientVpnClientConfiguration" => {
2094                cvpn::export_client_vpn_client_configuration(self, &request)
2095            }
2096            "ImportClientVpnClientCertificateRevocationList" => {
2097                cvpn::import_client_vpn_client_certificate_revocation_list(self, &request)
2098            }
2099            "CreateIpam" => ipam::create_ipam(self, &request),
2100            "DeleteIpam" => ipam::delete_ipam(self, &request),
2101            "DescribeIpams" => ipam::describe_ipams(self, &request),
2102            "ModifyIpam" => ipam::modify_ipam(self, &request),
2103            "CreateIpamScope" => ipam::create_ipam_scope(self, &request),
2104            "DeleteIpamScope" => ipam::delete_ipam_scope(self, &request),
2105            "DescribeIpamScopes" => ipam::describe_ipam_scopes(self, &request),
2106            "ModifyIpamScope" => ipam::modify_ipam_scope(self, &request),
2107            "CreateIpamPool" => ipam::create_ipam_pool(self, &request),
2108            "DeleteIpamPool" => ipam::delete_ipam_pool(self, &request),
2109            "DescribeIpamPools" => ipam::describe_ipam_pools(self, &request),
2110            "ModifyIpamPool" => ipam::modify_ipam_pool(self, &request),
2111            "ProvisionIpamPoolCidr" => ipam::provision_ipam_pool_cidr(self, &request),
2112            "DeprovisionIpamPoolCidr" => ipam::deprovision_ipam_pool_cidr(self, &request),
2113            "GetIpamPoolCidrs" => ipam::get_ipam_pool_cidrs(self, &request),
2114            "AllocateIpamPoolCidr" => ipam::allocate_ipam_pool_cidr(self, &request),
2115            "ReleaseIpamPoolAllocation" => ipam::release_ipam_pool_allocation(self, &request),
2116            "GetIpamPoolAllocations" => ipam::get_ipam_pool_allocations(self, &request),
2117            "GetIpamResourceCidrs" => ipam::get_ipam_resource_cidrs(self, &request),
2118            "ModifyIpamResourceCidr" => ipam::modify_ipam_resource_cidr(self, &request),
2119            "GetIpamAddressHistory" => ipam::get_ipam_address_history(self, &request),
2120            "EnableIpamOrganizationAdminAccount" => {
2121                ipam::enable_ipam_organization_admin_account(self, &request)
2122            }
2123            "DisableIpamOrganizationAdminAccount" => {
2124                ipam::disable_ipam_organization_admin_account(self, &request)
2125            }
2126            "CreateIpamResourceDiscovery" => {
2127                ipam_discovery::create_ipam_resource_discovery(self, &request)
2128            }
2129            "DeleteIpamResourceDiscovery" => {
2130                ipam_discovery::delete_ipam_resource_discovery(self, &request)
2131            }
2132            "DescribeIpamResourceDiscoveries" => {
2133                ipam_discovery::describe_ipam_resource_discoveries(self, &request)
2134            }
2135            "ModifyIpamResourceDiscovery" => {
2136                ipam_discovery::modify_ipam_resource_discovery(self, &request)
2137            }
2138            "AssociateIpamResourceDiscovery" => {
2139                ipam_discovery::associate_ipam_resource_discovery(self, &request)
2140            }
2141            "DisassociateIpamResourceDiscovery" => {
2142                ipam_discovery::disassociate_ipam_resource_discovery(self, &request)
2143            }
2144            "DescribeIpamResourceDiscoveryAssociations" => {
2145                ipam_discovery::describe_ipam_resource_discovery_associations(self, &request)
2146            }
2147            "GetIpamDiscoveredAccounts" => {
2148                ipam_discovery::get_ipam_discovered_accounts(self, &request)
2149            }
2150            "GetIpamDiscoveredPublicAddresses" => {
2151                ipam_discovery::get_ipam_discovered_public_addresses(self, &request)
2152            }
2153            "GetIpamDiscoveredResourceCidrs" => {
2154                ipam_discovery::get_ipam_discovered_resource_cidrs(self, &request)
2155            }
2156            "AssociateIpamByoasn" => ipam_discovery::associate_ipam_byoasn(self, &request),
2157            "DisassociateIpamByoasn" => ipam_discovery::disassociate_ipam_byoasn(self, &request),
2158            "ProvisionIpamByoasn" => ipam_discovery::provision_ipam_byoasn(self, &request),
2159            "DeprovisionIpamByoasn" => ipam_discovery::deprovision_ipam_byoasn(self, &request),
2160            "DescribeIpamByoasn" => ipam_discovery::describe_ipam_byoasn(self, &request),
2161            "MoveByoipCidrToIpam" => ipam_discovery::move_byoip_cidr_to_ipam(self, &request),
2162            "CreateIpamExternalResourceVerificationToken" => {
2163                ipam_discovery::create_ipam_external_resource_verification_token(self, &request)
2164            }
2165            "DeleteIpamExternalResourceVerificationToken" => {
2166                ipam_discovery::delete_ipam_external_resource_verification_token(self, &request)
2167            }
2168            "DescribeIpamExternalResourceVerificationTokens" => {
2169                ipam_discovery::describe_ipam_external_resource_verification_tokens(self, &request)
2170            }
2171            "CreateIpamPolicy" => ipam_policy::create_ipam_policy(self, &request),
2172            "DeleteIpamPolicy" => ipam_policy::delete_ipam_policy(self, &request),
2173            "DescribeIpamPolicies" => ipam_policy::describe_ipam_policies(self, &request),
2174            "EnableIpamPolicy" => ipam_policy::enable_ipam_policy(self, &request),
2175            "DisableIpamPolicy" => ipam_policy::disable_ipam_policy(self, &request),
2176            "GetEnabledIpamPolicy" => ipam_policy::get_enabled_ipam_policy(self, &request),
2177            "GetIpamPolicyAllocationRules" => {
2178                ipam_policy::get_ipam_policy_allocation_rules(self, &request)
2179            }
2180            "ModifyIpamPolicyAllocationRules" => {
2181                ipam_policy::modify_ipam_policy_allocation_rules(self, &request)
2182            }
2183            "GetIpamPolicyOrganizationTargets" => {
2184                ipam_policy::get_ipam_policy_organization_targets(self, &request)
2185            }
2186            "CreateIpamPrefixListResolver" => {
2187                ipam_policy::create_ipam_prefix_list_resolver(self, &request)
2188            }
2189            "DeleteIpamPrefixListResolver" => {
2190                ipam_policy::delete_ipam_prefix_list_resolver(self, &request)
2191            }
2192            "DescribeIpamPrefixListResolvers" => {
2193                ipam_policy::describe_ipam_prefix_list_resolvers(self, &request)
2194            }
2195            "ModifyIpamPrefixListResolver" => {
2196                ipam_policy::modify_ipam_prefix_list_resolver(self, &request)
2197            }
2198            "CreateIpamPrefixListResolverTarget" => {
2199                ipam_policy::create_ipam_prefix_list_resolver_target(self, &request)
2200            }
2201            "DeleteIpamPrefixListResolverTarget" => {
2202                ipam_policy::delete_ipam_prefix_list_resolver_target(self, &request)
2203            }
2204            "DescribeIpamPrefixListResolverTargets" => {
2205                ipam_policy::describe_ipam_prefix_list_resolver_targets(self, &request)
2206            }
2207            "ModifyIpamPrefixListResolverTarget" => {
2208                ipam_policy::modify_ipam_prefix_list_resolver_target(self, &request)
2209            }
2210            "GetIpamPrefixListResolverRules" => {
2211                ipam_policy::get_ipam_prefix_list_resolver_rules(self, &request)
2212            }
2213            "GetIpamPrefixListResolverVersions" => {
2214                ipam_policy::get_ipam_prefix_list_resolver_versions(self, &request)
2215            }
2216            "GetIpamPrefixListResolverVersionEntries" => {
2217                ipam_policy::get_ipam_prefix_list_resolver_version_entries(self, &request)
2218            }
2219            "CreateVerifiedAccessInstance" => va::create_verified_access_instance(self, &request),
2220            "DeleteVerifiedAccessInstance" => va::delete_verified_access_instance(self, &request),
2221            "DescribeVerifiedAccessInstances" => {
2222                va::describe_verified_access_instances(self, &request)
2223            }
2224            "ModifyVerifiedAccessInstance" => va::modify_verified_access_instance(self, &request),
2225            "CreateVerifiedAccessTrustProvider" => {
2226                va::create_verified_access_trust_provider(self, &request)
2227            }
2228            "DeleteVerifiedAccessTrustProvider" => {
2229                va::delete_verified_access_trust_provider(self, &request)
2230            }
2231            "DescribeVerifiedAccessTrustProviders" => {
2232                va::describe_verified_access_trust_providers(self, &request)
2233            }
2234            "ModifyVerifiedAccessTrustProvider" => {
2235                va::modify_verified_access_trust_provider(self, &request)
2236            }
2237            "AttachVerifiedAccessTrustProvider" => {
2238                va::attach_verified_access_trust_provider(self, &request)
2239            }
2240            "DetachVerifiedAccessTrustProvider" => {
2241                va::detach_verified_access_trust_provider(self, &request)
2242            }
2243            "CreateVerifiedAccessGroup" => va::create_verified_access_group(self, &request),
2244            "DeleteVerifiedAccessGroup" => va::delete_verified_access_group(self, &request),
2245            "DescribeVerifiedAccessGroups" => va::describe_verified_access_groups(self, &request),
2246            "ModifyVerifiedAccessGroup" => va::modify_verified_access_group(self, &request),
2247            "GetVerifiedAccessGroupPolicy" => va::get_verified_access_group_policy(self, &request),
2248            "ModifyVerifiedAccessGroupPolicy" => {
2249                va::modify_verified_access_group_policy(self, &request)
2250            }
2251            "CreateVerifiedAccessEndpoint" => va::create_verified_access_endpoint(self, &request),
2252            "DeleteVerifiedAccessEndpoint" => va::delete_verified_access_endpoint(self, &request),
2253            "DescribeVerifiedAccessEndpoints" => {
2254                va::describe_verified_access_endpoints(self, &request)
2255            }
2256            "ModifyVerifiedAccessEndpoint" => va::modify_verified_access_endpoint(self, &request),
2257            "GetVerifiedAccessEndpointPolicy" => {
2258                va::get_verified_access_endpoint_policy(self, &request)
2259            }
2260            "ModifyVerifiedAccessEndpointPolicy" => {
2261                va::modify_verified_access_endpoint_policy(self, &request)
2262            }
2263            "GetVerifiedAccessEndpointTargets" => {
2264                va::get_verified_access_endpoint_targets(self, &request)
2265            }
2266            "DescribeVerifiedAccessInstanceLoggingConfigurations" => {
2267                va::describe_verified_access_instance_logging_configurations(self, &request)
2268            }
2269            "ModifyVerifiedAccessInstanceLoggingConfiguration" => {
2270                va::modify_verified_access_instance_logging_configuration(self, &request)
2271            }
2272            "ExportVerifiedAccessInstanceClientConfiguration" => {
2273                va::export_verified_access_instance_client_configuration(self, &request)
2274            }
2275            "CreateNetworkInsightsPath" => ni::create_network_insights_path(self, &request),
2276            "DeleteNetworkInsightsPath" => ni::delete_network_insights_path(self, &request),
2277            "DescribeNetworkInsightsPaths" => ni::describe_network_insights_paths(self, &request),
2278            "StartNetworkInsightsAnalysis" => ni::start_network_insights_analysis(self, &request),
2279            "DeleteNetworkInsightsAnalysis" => ni::delete_network_insights_analysis(self, &request),
2280            "DescribeNetworkInsightsAnalyses" => {
2281                ni::describe_network_insights_analyses(self, &request)
2282            }
2283            "CreateNetworkInsightsAccessScope" => {
2284                ni::create_network_insights_access_scope(self, &request)
2285            }
2286            "DeleteNetworkInsightsAccessScope" => {
2287                ni::delete_network_insights_access_scope(self, &request)
2288            }
2289            "DescribeNetworkInsightsAccessScopes" => {
2290                ni::describe_network_insights_access_scopes(self, &request)
2291            }
2292            "GetNetworkInsightsAccessScopeContent" => {
2293                ni::get_network_insights_access_scope_content(self, &request)
2294            }
2295            "StartNetworkInsightsAccessScopeAnalysis" => {
2296                ni::start_network_insights_access_scope_analysis(self, &request)
2297            }
2298            "DeleteNetworkInsightsAccessScopeAnalysis" => {
2299                ni::delete_network_insights_access_scope_analysis(self, &request)
2300            }
2301            "DescribeNetworkInsightsAccessScopeAnalyses" => {
2302                ni::describe_network_insights_access_scope_analyses(self, &request)
2303            }
2304            "GetNetworkInsightsAccessScopeAnalysisFindings" => {
2305                ni::get_network_insights_access_scope_analysis_findings(self, &request)
2306            }
2307            "CreateCarrierGateway" => lgw::create_carrier_gateway(self, &request),
2308            "DeleteCarrierGateway" => lgw::delete_carrier_gateway(self, &request),
2309            "DescribeCarrierGateways" => lgw::describe_carrier_gateways(self, &request),
2310            "CreateCoipPool" => lgw::create_coip_pool(self, &request),
2311            "DeleteCoipPool" => lgw::delete_coip_pool(self, &request),
2312            "DescribeCoipPools" => lgw::describe_coip_pools(self, &request),
2313            "CreateCoipCidr" => lgw::create_coip_cidr(self, &request),
2314            "DeleteCoipCidr" => lgw::delete_coip_cidr(self, &request),
2315            "GetCoipPoolUsage" => lgw::get_coip_pool_usage(self, &request),
2316            "CreateLocalGatewayRouteTable" => lgw::create_local_gateway_route_table(self, &request),
2317            "DeleteLocalGatewayRouteTable" => lgw::delete_local_gateway_route_table(self, &request),
2318            "DescribeLocalGatewayRouteTables" => {
2319                lgw::describe_local_gateway_route_tables(self, &request)
2320            }
2321            "CreateLocalGatewayRoute" => lgw::create_local_gateway_route(self, &request),
2322            "DeleteLocalGatewayRoute" => lgw::delete_local_gateway_route(self, &request),
2323            "ModifyLocalGatewayRoute" => lgw::modify_local_gateway_route(self, &request),
2324            "SearchLocalGatewayRoutes" => lgw::search_local_gateway_routes(self, &request),
2325            "CreateLocalGatewayRouteTableVpcAssociation" => {
2326                lgw::create_local_gateway_route_table_vpc_association(self, &request)
2327            }
2328            "DeleteLocalGatewayRouteTableVpcAssociation" => {
2329                lgw::delete_local_gateway_route_table_vpc_association(self, &request)
2330            }
2331            "DescribeLocalGatewayRouteTableVpcAssociations" => {
2332                lgw::describe_local_gateway_route_table_vpc_associations(self, &request)
2333            }
2334            "CreateLocalGatewayVirtualInterface" => {
2335                lgw::create_local_gateway_virtual_interface(self, &request)
2336            }
2337            "DeleteLocalGatewayVirtualInterface" => {
2338                lgw::delete_local_gateway_virtual_interface(self, &request)
2339            }
2340            "DescribeLocalGatewayVirtualInterfaces" => {
2341                lgw::describe_local_gateway_virtual_interfaces(self, &request)
2342            }
2343            "CreateLocalGatewayVirtualInterfaceGroup" => {
2344                lgw::create_local_gateway_virtual_interface_group(self, &request)
2345            }
2346            "DeleteLocalGatewayVirtualInterfaceGroup" => {
2347                lgw::delete_local_gateway_virtual_interface_group(self, &request)
2348            }
2349            "DescribeLocalGatewayVirtualInterfaceGroups" => {
2350                lgw::describe_local_gateway_virtual_interface_groups(self, &request)
2351            }
2352            "CreateLocalGatewayRouteTableVirtualInterfaceGroupAssociation" => {
2353                lgw::create_local_gateway_route_table_virtual_interface_group_association(
2354                    self, &request,
2355                )
2356            }
2357            "DeleteLocalGatewayRouteTableVirtualInterfaceGroupAssociation" => {
2358                lgw::delete_local_gateway_route_table_virtual_interface_group_association(
2359                    self, &request,
2360                )
2361            }
2362            "DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociations" => {
2363                lgw::describe_local_gateway_route_table_virtual_interface_group_associations(
2364                    self, &request,
2365                )
2366            }
2367            "DescribeLocalGateways" => lgw::describe_local_gateways(self, &request),
2368            "CreateInstanceConnectEndpoint" => {
2369                ice::create_instance_connect_endpoint(self, &request)
2370            }
2371            "DeleteInstanceConnectEndpoint" => {
2372                ice::delete_instance_connect_endpoint(self, &request)
2373            }
2374            "DescribeInstanceConnectEndpoints" => {
2375                ice::describe_instance_connect_endpoints(self, &request)
2376            }
2377            "ModifyInstanceConnectEndpoint" => {
2378                ice::modify_instance_connect_endpoint(self, &request)
2379            }
2380            "EnableFastLaunch" => ice::enable_fast_launch(self, &request),
2381            "DisableFastLaunch" => ice::disable_fast_launch(self, &request),
2382            "EnableSerialConsoleAccess" => ice::enable_serial_console_access(self, &request),
2383            "DisableSerialConsoleAccess" => ice::disable_serial_console_access(self, &request),
2384            "GetSerialConsoleAccessStatus" => ice::get_serial_console_access_status(self, &request),
2385            "GetConsoleOutput" => ice::get_console_output(self, &request).await,
2386            "GetConsoleScreenshot" => ice::get_console_screenshot(self, &request),
2387            "GetPasswordData" => ice::get_password_data(self, &request),
2388            "AdvertiseByoipCidr" => rest::advertise_byoip_cidr(self, &request),
2389            "AssociateEnclaveCertificateIamRole" => {
2390                rest::associate_enclave_certificate_iam_role(self, &request)
2391            }
2392            "AssociateIamInstanceProfile" => rest::associate_iam_instance_profile(self, &request),
2393            "AssociateInstanceEventWindow" => rest::associate_instance_event_window(self, &request),
2394            "AssociateRouteServer" => rest::associate_route_server(self, &request),
2395            "AssociateTrunkInterface" => rest::associate_trunk_interface(self, &request),
2396            "AttachClassicLinkVpc" => rest::attach_classic_link_vpc(self, &request),
2397            "BundleInstance" => rest::bundle_instance(self, &request),
2398            "CancelBundleTask" => rest::cancel_bundle_task(self, &request),
2399            "CancelConversionTask" => rest::cancel_conversion_task(self, &request),
2400            "CancelDeclarativePoliciesReport" => {
2401                rest::cancel_declarative_policies_report(self, &request)
2402            }
2403            "CancelExportTask" => rest::cancel_export_task(self, &request),
2404            "CancelImportTask" => rest::cancel_import_task(self, &request),
2405            "ConfirmProductInstance" => rest::confirm_product_instance(self, &request),
2406            "CopyFpgaImage" => rest::copy_fpga_image(self, &request),
2407            "CopyVolumes" => rest::copy_volumes(self, &request),
2408            "CreateCapacityManagerDataExport" => {
2409                rest::create_capacity_manager_data_export(self, &request)
2410            }
2411            "CreateDelegateMacVolumeOwnershipTask" => {
2412                rest::create_delegate_mac_volume_ownership_task(self, &request)
2413            }
2414            "CreateFpgaImage" => rest::create_fpga_image(self, &request),
2415            "CreateImageUsageReport" => rest::create_image_usage_report(self, &request),
2416            "CreateInstanceEventWindow" => rest::create_instance_event_window(self, &request),
2417            "CreateInstanceExportTask" => rest::create_instance_export_task(self, &request),
2418            "CreateMacSystemIntegrityProtectionModificationTask" => {
2419                rest::create_mac_system_integrity_protection_modification_task(self, &request)
2420            }
2421            "CreateManagedPrefixList" => rest::create_managed_prefix_list(self, &request),
2422            "CreatePublicIpv4Pool" => rest::create_public_ipv4_pool(self, &request),
2423            "CreateReplaceRootVolumeTask" => rest::create_replace_root_volume_task(self, &request),
2424            "CreateRouteServer" => rest::create_route_server(self, &request),
2425            "CreateRouteServerEndpoint" => rest::create_route_server_endpoint(self, &request),
2426            "CreateRouteServerPeer" => rest::create_route_server_peer(self, &request),
2427            "CreateSecondaryNetwork" => rest::create_secondary_network(self, &request),
2428            "CreateTrafficMirrorFilter" => rest::create_traffic_mirror_filter(self, &request),
2429            "CreateTrafficMirrorFilterRule" => {
2430                rest::create_traffic_mirror_filter_rule(self, &request)
2431            }
2432            "CreateTrafficMirrorSession" => rest::create_traffic_mirror_session(self, &request),
2433            "CreateTrafficMirrorTarget" => rest::create_traffic_mirror_target(self, &request),
2434            "CreateVpcBlockPublicAccessExclusion" => {
2435                rest::create_vpc_block_public_access_exclusion(self, &request)
2436            }
2437            "CreateVpcEncryptionControl" => rest::create_vpc_encryption_control(self, &request),
2438            "DeleteCapacityManagerDataExport" => {
2439                rest::delete_capacity_manager_data_export(self, &request)
2440            }
2441            "DeleteFpgaImage" => rest::delete_fpga_image(self, &request),
2442            "DeleteImageUsageReport" => rest::delete_image_usage_report(self, &request),
2443            "DeleteInstanceEventWindow" => rest::delete_instance_event_window(self, &request),
2444            "DeleteManagedPrefixList" => rest::delete_managed_prefix_list(self, &request),
2445            "DeletePublicIpv4Pool" => rest::delete_public_ipv4_pool(self, &request),
2446            "DeleteRouteServer" => rest::delete_route_server(self, &request),
2447            "DeleteRouteServerEndpoint" => rest::delete_route_server_endpoint(self, &request),
2448            "DeleteRouteServerPeer" => rest::delete_route_server_peer(self, &request),
2449            "DeleteSecondaryNetwork" => rest::delete_secondary_network(self, &request),
2450            "DeleteTrafficMirrorFilter" => rest::delete_traffic_mirror_filter(self, &request),
2451            "DeleteTrafficMirrorFilterRule" => {
2452                rest::delete_traffic_mirror_filter_rule(self, &request)
2453            }
2454            "DeleteTrafficMirrorSession" => rest::delete_traffic_mirror_session(self, &request),
2455            "DeleteTrafficMirrorTarget" => rest::delete_traffic_mirror_target(self, &request),
2456            "DeleteVpcBlockPublicAccessExclusion" => {
2457                rest::delete_vpc_block_public_access_exclusion(self, &request)
2458            }
2459            "DeleteVpcEncryptionControl" => rest::delete_vpc_encryption_control(self, &request),
2460            "DeprovisionByoipCidr" => rest::deprovision_byoip_cidr(self, &request),
2461            "DeprovisionPublicIpv4PoolCidr" => {
2462                rest::deprovision_public_ipv4_pool_cidr(self, &request)
2463            }
2464            "DescribeAggregateIdFormat" => rest::describe_aggregate_id_format(self, &request),
2465            "DescribeAwsNetworkPerformanceMetricSubscriptions" => {
2466                rest::describe_aws_network_performance_metric_subscriptions(self, &request)
2467            }
2468            "DescribeBundleTasks" => rest::describe_bundle_tasks(self, &request),
2469            "DescribeByoipCidrs" => rest::describe_byoip_cidrs(self, &request),
2470            "DescribeCapacityManagerDataExports" => {
2471                rest::describe_capacity_manager_data_exports(self, &request)
2472            }
2473            "DescribeClassicLinkInstances" => rest::describe_classic_link_instances(self, &request),
2474            "DescribeConversionTasks" => rest::describe_conversion_tasks(self, &request),
2475            "DescribeDeclarativePoliciesReports" => {
2476                rest::describe_declarative_policies_reports(self, &request)
2477            }
2478            "DescribeElasticGpus" => rest::describe_elastic_gpus(self, &request),
2479            "DescribeExportImageTasks" => rest::describe_export_image_tasks(self, &request),
2480            "DescribeExportTasks" => rest::describe_export_tasks(self, &request),
2481            "DescribeFpgaImageAttribute" => rest::describe_fpga_image_attribute(self, &request),
2482            "DescribeFpgaImages" => rest::describe_fpga_images(self, &request),
2483            "DescribeHostReservationOfferings" => {
2484                rest::describe_host_reservation_offerings(self, &request)
2485            }
2486            "DescribeHostReservations" => rest::describe_host_reservations(self, &request),
2487            "DescribeIamInstanceProfileAssociations" => {
2488                rest::describe_iam_instance_profile_associations(self, &request)
2489            }
2490            "DescribeIdFormat" => rest::describe_id_format(self, &request),
2491            "DescribeIdentityIdFormat" => rest::describe_identity_id_format(self, &request),
2492            "DescribeImageReferences" => rest::describe_image_references(self, &request),
2493            "DescribeImageUsageReportEntries" => {
2494                rest::describe_image_usage_report_entries(self, &request)
2495            }
2496            "DescribeImageUsageReports" => rest::describe_image_usage_reports(self, &request),
2497            "DescribeImportImageTasks" => rest::describe_import_image_tasks(self, &request),
2498            "DescribeImportSnapshotTasks" => rest::describe_import_snapshot_tasks(self, &request),
2499            "DescribeInstanceEventWindows" => rest::describe_instance_event_windows(self, &request),
2500            "DescribeInstanceImageMetadata" => {
2501                rest::describe_instance_image_metadata(self, &request)
2502            }
2503            "DescribeInstanceSqlHaHistoryStates" => {
2504                rest::describe_instance_sql_ha_history_states(self, &request)
2505            }
2506            "DescribeInstanceSqlHaStates" => rest::describe_instance_sql_ha_states(self, &request),
2507            "DescribeInstanceTypeOfferings" => {
2508                rest::describe_instance_type_offerings(self, &request)
2509            }
2510            "DescribeIpv6Pools" => rest::describe_ipv6_pools(self, &request),
2511            "DescribeMacModificationTasks" => rest::describe_mac_modification_tasks(self, &request),
2512            "DescribeManagedPrefixLists" => rest::describe_managed_prefix_lists(self, &request),
2513            "DescribeOutpostLags" => rest::describe_outpost_lags(self, &request),
2514            "DescribePrefixLists" => rest::describe_prefix_lists(self, &request),
2515            "DescribePrincipalIdFormat" => rest::describe_principal_id_format(self, &request),
2516            "DescribePublicIpv4Pools" => rest::describe_public_ipv4_pools(self, &request),
2517            "DescribeReplaceRootVolumeTasks" => {
2518                rest::describe_replace_root_volume_tasks(self, &request)
2519            }
2520            "DescribeRouteServerEndpoints" => rest::describe_route_server_endpoints(self, &request),
2521            "DescribeRouteServerPeers" => rest::describe_route_server_peers(self, &request),
2522            "DescribeRouteServers" => rest::describe_route_servers(self, &request),
2523            "DescribeScheduledInstanceAvailability" => {
2524                rest::describe_scheduled_instance_availability(self, &request)
2525            }
2526            "DescribeScheduledInstances" => rest::describe_scheduled_instances(self, &request),
2527            "DescribeSecondaryInterfaces" => rest::describe_secondary_interfaces(self, &request),
2528            "DescribeSecondaryNetworks" => rest::describe_secondary_networks(self, &request),
2529            "DescribeServiceLinkVirtualInterfaces" => {
2530                rest::describe_service_link_virtual_interfaces(self, &request)
2531            }
2532            "DescribeTrafficMirrorFilterRules" => {
2533                rest::describe_traffic_mirror_filter_rules(self, &request)
2534            }
2535            "DescribeTrafficMirrorFilters" => rest::describe_traffic_mirror_filters(self, &request),
2536            "DescribeTrafficMirrorSessions" => {
2537                rest::describe_traffic_mirror_sessions(self, &request)
2538            }
2539            "DescribeTrafficMirrorTargets" => rest::describe_traffic_mirror_targets(self, &request),
2540            "DescribeTrunkInterfaceAssociations" => {
2541                rest::describe_trunk_interface_associations(self, &request)
2542            }
2543            "DescribeVpcBlockPublicAccessExclusions" => {
2544                rest::describe_vpc_block_public_access_exclusions(self, &request)
2545            }
2546            "DescribeVpcBlockPublicAccessOptions" => {
2547                rest::describe_vpc_block_public_access_options(self, &request)
2548            }
2549            "DescribeVpcClassicLink" => rest::describe_vpc_classic_link(self, &request),
2550            "DescribeVpcClassicLinkDnsSupport" => {
2551                rest::describe_vpc_classic_link_dns_support(self, &request)
2552            }
2553            "DescribeVpcEncryptionControls" => {
2554                rest::describe_vpc_encryption_controls(self, &request)
2555            }
2556            "DetachClassicLinkVpc" => rest::detach_classic_link_vpc(self, &request),
2557            "DisableAwsNetworkPerformanceMetricSubscription" => {
2558                rest::disable_aws_network_performance_metric_subscription(self, &request)
2559            }
2560            "DisableCapacityManager" => rest::disable_capacity_manager(self, &request),
2561            "DisableInstanceSqlHaStandbyDetections" => {
2562                rest::disable_instance_sql_ha_standby_detections(self, &request)
2563            }
2564            "DisableRouteServerPropagation" => {
2565                rest::disable_route_server_propagation(self, &request)
2566            }
2567            "DisableVgwRoutePropagation" => rest::disable_vgw_route_propagation(self, &request),
2568            "DisableVpcClassicLink" => rest::disable_vpc_classic_link(self, &request),
2569            "DisableVpcClassicLinkDnsSupport" => {
2570                rest::disable_vpc_classic_link_dns_support(self, &request)
2571            }
2572            "DisassociateEnclaveCertificateIamRole" => {
2573                rest::disassociate_enclave_certificate_iam_role(self, &request)
2574            }
2575            "DisassociateIamInstanceProfile" => {
2576                rest::disassociate_iam_instance_profile(self, &request)
2577            }
2578            "DisassociateInstanceEventWindow" => {
2579                rest::disassociate_instance_event_window(self, &request)
2580            }
2581            "DisassociateRouteServer" => rest::disassociate_route_server(self, &request),
2582            "DisassociateTrunkInterface" => rest::disassociate_trunk_interface(self, &request),
2583            "EnableAwsNetworkPerformanceMetricSubscription" => {
2584                rest::enable_aws_network_performance_metric_subscription(self, &request)
2585            }
2586            "EnableCapacityManager" => rest::enable_capacity_manager(self, &request),
2587            "EnableInstanceSqlHaStandbyDetections" => {
2588                rest::enable_instance_sql_ha_standby_detections(self, &request)
2589            }
2590            "EnableReachabilityAnalyzerOrganizationSharing" => {
2591                rest::enable_reachability_analyzer_organization_sharing(self, &request)
2592            }
2593            "EnableRouteServerPropagation" => rest::enable_route_server_propagation(self, &request),
2594            "EnableVgwRoutePropagation" => rest::enable_vgw_route_propagation(self, &request),
2595            "EnableVpcClassicLink" => rest::enable_vpc_classic_link(self, &request),
2596            "EnableVpcClassicLinkDnsSupport" => {
2597                rest::enable_vpc_classic_link_dns_support(self, &request)
2598            }
2599            "ExportImage" => rest::export_image(self, &request),
2600            "GetAssociatedEnclaveCertificateIamRoles" => {
2601                rest::get_associated_enclave_certificate_iam_roles(self, &request)
2602            }
2603            "GetAssociatedIpv6PoolCidrs" => rest::get_associated_ipv6_pool_cidrs(self, &request),
2604            "GetAwsNetworkPerformanceData" => {
2605                rest::get_aws_network_performance_data(self, &request)
2606            }
2607            "GetCapacityManagerAttributes" => rest::get_capacity_manager_attributes(self, &request),
2608            "GetCapacityManagerMetricData" => {
2609                rest::get_capacity_manager_metric_data(self, &request)
2610            }
2611            "GetCapacityManagerMetricDimensions" => {
2612                rest::get_capacity_manager_metric_dimensions(self, &request)
2613            }
2614            "GetCapacityManagerMonitoredTagKeys" => {
2615                rest::get_capacity_manager_monitored_tag_keys(self, &request)
2616            }
2617            "GetDeclarativePoliciesReportSummary" => {
2618                rest::get_declarative_policies_report_summary(self, &request)
2619            }
2620            "GetDefaultCreditSpecification" => {
2621                rest::get_default_credit_specification(self, &request)
2622            }
2623            "GetHostReservationPurchasePreview" => {
2624                rest::get_host_reservation_purchase_preview(self, &request)
2625            }
2626            "GetImageAncestry" => rest::get_image_ancestry(self, &request),
2627            "GetInstanceTpmEkPub" => rest::get_instance_tpm_ek_pub(self, &request),
2628            "GetInstanceUefiData" => rest::get_instance_uefi_data(self, &request),
2629            "GetManagedPrefixListAssociations" => {
2630                rest::get_managed_prefix_list_associations(self, &request)
2631            }
2632            "GetManagedPrefixListEntries" => rest::get_managed_prefix_list_entries(self, &request),
2633            "GetManagedResourceVisibility" => rest::get_managed_resource_visibility(self, &request),
2634            "GetRouteServerAssociations" => rest::get_route_server_associations(self, &request),
2635            "GetRouteServerPropagations" => rest::get_route_server_propagations(self, &request),
2636            "GetRouteServerRoutingDatabase" => {
2637                rest::get_route_server_routing_database(self, &request)
2638            }
2639            "GetVpcResourcesBlockingEncryptionEnforcement" => {
2640                rest::get_vpc_resources_blocking_encryption_enforcement(self, &request)
2641            }
2642            "ImportImage" => rest::import_image(self, &request),
2643            "ImportInstance" => rest::import_instance(self, &request),
2644            "ImportSnapshot" => rest::import_snapshot(self, &request),
2645            "ImportVolume" => rest::import_volume(self, &request),
2646            "ModifyAvailabilityZoneGroup" => rest::modify_availability_zone_group(self, &request),
2647            "ModifyDefaultCreditSpecification" => {
2648                rest::modify_default_credit_specification(self, &request)
2649            }
2650            "ModifyFpgaImageAttribute" => rest::modify_fpga_image_attribute(self, &request),
2651            "ModifyIdFormat" => rest::modify_id_format(self, &request),
2652            "ModifyIdentityIdFormat" => rest::modify_identity_id_format(self, &request),
2653            "ModifyInstanceEventWindow" => rest::modify_instance_event_window(self, &request),
2654            "ModifyManagedPrefixList" => rest::modify_managed_prefix_list(self, &request),
2655            "ModifyManagedResourceVisibility" => {
2656                rest::modify_managed_resource_visibility(self, &request)
2657            }
2658            "ModifyPrivateDnsNameOptions" => rest::modify_private_dns_name_options(self, &request),
2659            "ModifyPublicIpDnsNameOptions" => {
2660                rest::modify_public_ip_dns_name_options(self, &request)
2661            }
2662            "ModifyRouteServer" => rest::modify_route_server(self, &request),
2663            "ModifyTrafficMirrorFilterNetworkServices" => {
2664                rest::modify_traffic_mirror_filter_network_services(self, &request)
2665            }
2666            "ModifyTrafficMirrorFilterRule" => {
2667                rest::modify_traffic_mirror_filter_rule(self, &request)
2668            }
2669            "ModifyTrafficMirrorSession" => rest::modify_traffic_mirror_session(self, &request),
2670            "ModifyVpcBlockPublicAccessExclusion" => {
2671                rest::modify_vpc_block_public_access_exclusion(self, &request)
2672            }
2673            "ModifyVpcBlockPublicAccessOptions" => {
2674                rest::modify_vpc_block_public_access_options(self, &request)
2675            }
2676            "ModifyVpcEncryptionControl" => rest::modify_vpc_encryption_control(self, &request),
2677            "ProvisionByoipCidr" => rest::provision_byoip_cidr(self, &request),
2678            "ProvisionPublicIpv4PoolCidr" => rest::provision_public_ipv4_pool_cidr(self, &request),
2679            "PurchaseHostReservation" => rest::purchase_host_reservation(self, &request),
2680            "PurchaseScheduledInstances" => rest::purchase_scheduled_instances(self, &request),
2681            "ReplaceIamInstanceProfileAssociation" => {
2682                rest::replace_iam_instance_profile_association(self, &request)
2683            }
2684            "ResetFpgaImageAttribute" => rest::reset_fpga_image_attribute(self, &request),
2685            "RestoreManagedPrefixListVersion" => {
2686                rest::restore_managed_prefix_list_version(self, &request)
2687            }
2688            "RunScheduledInstances" => rest::run_scheduled_instances(self, &request),
2689            "SendDiagnosticInterrupt" => rest::send_diagnostic_interrupt(self, &request),
2690            "StartDeclarativePoliciesReport" => {
2691                rest::start_declarative_policies_report(self, &request)
2692            }
2693            "UpdateCapacityManagerMonitoredTagKeys" => {
2694                rest::update_capacity_manager_monitored_tag_keys(self, &request)
2695            }
2696            "UpdateCapacityManagerOrganizationsAccess" => {
2697                rest::update_capacity_manager_organizations_access(self, &request)
2698            }
2699            "WithdrawByoipCidr" => rest::withdraw_byoip_cidr(self, &request),
2700            // Model ops absent from the vendored SDK client; tested via raw query.
2701            "CreateCapacityReservationCancellationQuote" => {
2702                rest::create_capacity_reservation_cancellation_quote(self, &request)
2703            }
2704            "DescribeCapacityReservationCancellationQuotes" => {
2705                rest::describe_capacity_reservation_cancellation_quotes(self, &request)
2706            }
2707            "DescribeIpamPoolAllocations" => rest::describe_ipam_pool_allocations(self, &request),
2708            "ModifyIpamPoolAllocation" => rest::modify_ipam_pool_allocation(self, &request),
2709            "DescribeAccountVpcEncryptionControl" => {
2710                rest::describe_account_vpc_encryption_control(self, &request)
2711            }
2712            "ModifyAccountVpcEncryptionControl" => {
2713                rest::modify_account_vpc_encryption_control(self, &request)
2714            }
2715            "ModifyVpcEndpointPayerResponsibility" => {
2716                endpoint::modify_vpc_endpoint_payer_responsibility(self, &request)
2717            }
2718            other => Err(AwsServiceError::aws_error(
2719                StatusCode::BAD_REQUEST,
2720                "InvalidAction",
2721                format!("The action {other} is not valid for this web service."),
2722            )),
2723        };
2724        if mutates && matches!(result.as_ref(), Ok(resp) if resp.status.is_success()) {
2725            self.save_snapshot().await;
2726        }
2727        result
2728    }
2729}
2730
2731impl Ec2Service {
2732    /// Render an `ec2Query` response for `action` with `body` as the inner XML.
2733    pub(crate) fn respond(action: &str, request_id: &str, body: &str) -> AwsResponse {
2734        AwsResponse::xml(
2735            StatusCode::OK,
2736            fakecloud_aws::ec2query::ec2_response(action, request_id, body),
2737        )
2738    }
2739}
2740
2741#[cfg(test)]
2742mod recover_guard_tests {
2743    use super::recovery_terminal_wins;
2744
2745    // A minimal stand-in for the `state_code`/`state_name` fields the recovery
2746    // closure mutates. Kept independent of the full `Instance` struct so this
2747    // regression stays pinned to the guard behavior, not to unrelated field
2748    // churn (the struct-field repo-wide-ctor hazard).
2749    struct Row {
2750        state_code: i64,
2751        state_name: &'static str,
2752    }
2753
2754    // Boot-success arm of `recover_persisted_containers`, driven by the guard.
2755    // Returns whether the just-started container must be reaped.
2756    fn apply_boot_success(row: &mut Row) -> bool {
2757        if recovery_terminal_wins(row.state_code) {
2758            true
2759        } else {
2760            row.state_code = 16;
2761            row.state_name = "running";
2762            false
2763        }
2764    }
2765
2766    // Boot-failure arm of `recover_persisted_containers`, driven by the guard.
2767    fn apply_boot_failure(row: &mut Row) -> bool {
2768        if recovery_terminal_wins(row.state_code) {
2769            false
2770        } else {
2771            row.state_code = 80;
2772            row.state_name = "stopped";
2773            false
2774        }
2775    }
2776
2777    // Instance state codes: 0 pending, 16 running, 48 terminated, 80 stopped.
2778    #[test]
2779    fn terminal_states_win_over_recovery() {
2780        assert!(recovery_terminal_wins(48), "terminated wins");
2781        assert!(recovery_terminal_wins(80), "stopped wins");
2782        assert!(!recovery_terminal_wins(16), "running is recoverable");
2783        assert!(!recovery_terminal_wins(0), "pending is recoverable");
2784    }
2785
2786    #[test]
2787    fn boot_success_does_not_resurrect_concurrent_stop() {
2788        // Concurrent StopInstances set code 80 during the recovery window.
2789        let mut row = Row {
2790            state_code: 80,
2791            state_name: "stopped",
2792        };
2793        let reap = apply_boot_success(&mut row);
2794        assert!(reap, "the just-started container must be reaped");
2795        assert_eq!(row.state_code, 80, "stop must not be clobbered to running");
2796        assert_eq!(row.state_name, "stopped");
2797    }
2798
2799    #[test]
2800    fn boot_failure_does_not_clobber_concurrent_terminate() {
2801        // Concurrent TerminateInstances set code 48 during the recovery window,
2802        // and the backing container failed to boot.
2803        let mut row = Row {
2804            state_code: 48,
2805            state_name: "terminated",
2806        };
2807        let reap = apply_boot_failure(&mut row);
2808        assert!(!reap, "boot failed: nothing to reap");
2809        assert_eq!(
2810            row.state_code, 48,
2811            "terminate must not be overwritten to stopped"
2812        );
2813        assert_eq!(row.state_name, "terminated");
2814    }
2815
2816    #[test]
2817    fn boot_success_recovers_a_still_pending_instance() {
2818        // No concurrent op: a persisted pending row recovers to running.
2819        let mut row = Row {
2820            state_code: 0,
2821            state_name: "pending",
2822        };
2823        let reap = apply_boot_success(&mut row);
2824        assert!(!reap);
2825        assert_eq!(row.state_code, 16, "pending recovers to running");
2826        assert_eq!(row.state_name, "running");
2827    }
2828
2829    #[test]
2830    fn boot_failure_stops_a_still_pending_instance() {
2831        // No concurrent op, boot failed: a pending row is marked stopped.
2832        let mut row = Row {
2833            state_code: 0,
2834            state_name: "pending",
2835        };
2836        let reap = apply_boot_failure(&mut row);
2837        assert!(!reap);
2838        assert_eq!(row.state_code, 80, "failed boot marks stopped");
2839    }
2840}