1use std::collections::HashMap;
9use std::sync::Arc;
10
11use parking_lot::RwLock;
12use serde::{Deserialize, Serialize};
13
14pub type SharedEc2State = Arc<RwLock<fakecloud_core::multi_account::MultiAccountState<Ec2State>>>;
16
17impl fakecloud_core::multi_account::AccountState for Ec2State {
18 fn new_for_account(account_id: &str, region: &str, _endpoint: &str) -> Self {
19 Self::new(account_id, region)
20 }
21}
22
23#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
25pub struct Tag {
26 pub key: String,
27 pub value: String,
28}
29
30#[derive(Clone, Debug, Serialize, Deserialize)]
32pub struct VpcCidrAssoc {
33 pub association_id: String,
34 pub cidr_block: String,
35 pub state: String,
37}
38
39#[derive(Clone, Debug, Serialize, Deserialize)]
41pub struct Vpc {
42 pub vpc_id: String,
43 pub cidr_block: String,
44 pub state: String,
46 pub dhcp_options_id: String,
47 pub instance_tenancy: String,
49 pub is_default: bool,
50 pub enable_dns_support: bool,
51 pub enable_dns_hostnames: bool,
52 #[serde(default)]
53 pub cidr_associations: Vec<VpcCidrAssoc>,
54}
55
56#[derive(Clone, Debug, Serialize, Deserialize)]
58pub struct DhcpConfig {
59 pub key: String,
60 pub values: Vec<String>,
61}
62
63#[derive(Clone, Debug, Serialize, Deserialize)]
65pub struct DhcpOptions {
66 pub dhcp_options_id: String,
67 pub configurations: Vec<DhcpConfig>,
68}
69
70#[derive(Clone, Debug, Serialize, Deserialize)]
72pub struct Subnet {
73 pub subnet_id: String,
74 pub vpc_id: String,
75 pub cidr_block: String,
76 pub availability_zone: String,
77 pub availability_zone_id: String,
78 pub state: String,
80 pub available_ip_address_count: i32,
81 pub default_for_az: bool,
82 pub map_public_ip_on_launch: bool,
83 pub assign_ipv6_address_on_creation: bool,
84 pub map_customer_owned_ip_on_launch: bool,
85 pub enable_dns64: bool,
86 pub private_dns_hostname_type: String,
88}
89
90#[derive(Clone, Debug, Serialize, Deserialize)]
92pub struct SubnetCidrReservation {
93 pub subnet_cidr_reservation_id: String,
94 pub subnet_id: String,
95 pub cidr: String,
96 pub reservation_type: String,
98 pub description: String,
99}
100
101#[derive(Clone, Debug, Serialize, Deserialize)]
103pub struct SecurityGroupRule {
104 pub rule_id: String,
105 pub group_id: String,
106 pub is_egress: bool,
107 pub ip_protocol: String,
108 pub from_port: i64,
109 pub to_port: i64,
110 pub cidr_ipv4: Option<String>,
111 pub cidr_ipv6: Option<String>,
112 pub prefix_list_id: Option<String>,
113 pub referenced_group_id: Option<String>,
114 pub description: String,
115}
116
117#[derive(Clone, Debug, Serialize, Deserialize)]
119pub struct SecurityGroup {
120 pub group_id: String,
121 pub group_name: String,
122 pub description: String,
123 pub vpc_id: String,
124 #[serde(default)]
125 pub rules: Vec<SecurityGroupRule>,
126}
127
128#[derive(Clone, Debug, Default, Serialize, Deserialize)]
130pub struct Route {
131 pub destination_cidr_block: Option<String>,
132 pub destination_ipv6_cidr_block: Option<String>,
133 pub destination_prefix_list_id: Option<String>,
134 pub gateway_id: Option<String>,
135 pub nat_gateway_id: Option<String>,
136 pub network_interface_id: Option<String>,
137 pub instance_id: Option<String>,
138 pub vpc_peering_connection_id: Option<String>,
139 pub transit_gateway_id: Option<String>,
140 pub egress_only_internet_gateway_id: Option<String>,
141 pub state: String,
143 pub origin: String,
145}
146
147#[derive(Clone, Debug, Serialize, Deserialize)]
149pub struct RouteTableAssociation {
150 pub association_id: String,
151 pub route_table_id: String,
152 pub subnet_id: Option<String>,
153 pub gateway_id: Option<String>,
154 pub main: bool,
155}
156
157#[derive(Clone, Debug, Serialize, Deserialize)]
159pub struct RouteTable {
160 pub route_table_id: String,
161 pub vpc_id: String,
162 #[serde(default)]
163 pub routes: Vec<Route>,
164 #[serde(default)]
165 pub associations: Vec<RouteTableAssociation>,
166}
167
168#[derive(Clone, Debug, Serialize, Deserialize)]
170pub struct InternetGateway {
171 pub internet_gateway_id: String,
172 #[serde(default)]
174 pub attachments: Vec<(String, String)>,
175}
176
177#[derive(Clone, Debug, Serialize, Deserialize)]
179pub struct NatGateway {
180 pub nat_gateway_id: String,
181 pub subnet_id: String,
182 pub vpc_id: String,
183 pub state: String,
185 pub connectivity_type: String,
187 pub allocation_id: Option<String>,
188}
189
190#[derive(Clone, Debug, Serialize, Deserialize)]
192pub struct ElasticIp {
193 pub allocation_id: String,
194 pub public_ip: String,
195 pub domain: String,
197 pub association_id: Option<String>,
198 pub instance_id: Option<String>,
199 pub network_interface_id: Option<String>,
200 pub private_ip_address: Option<String>,
201}
202
203#[derive(Clone, Debug, Serialize, Deserialize)]
205pub struct KeyPair {
206 pub key_pair_id: String,
207 pub key_name: String,
208 pub key_type: String,
210 pub key_fingerprint: String,
211}
212
213#[derive(Clone, Debug, Serialize, Deserialize)]
215pub struct PlacementGroup {
216 pub group_id: String,
217 pub group_name: String,
218 pub strategy: String,
220 pub state: String,
222 pub partition_count: Option<i64>,
223 pub spread_level: Option<String>,
224}
225
226#[derive(Clone, Debug, Serialize, Deserialize)]
228pub struct EniAttachment {
229 pub attachment_id: String,
230 pub instance_id: String,
231 pub device_index: i64,
232 pub status: String,
234}
235
236#[derive(Clone, Debug, Serialize, Deserialize)]
238pub struct NetworkInterface {
239 pub network_interface_id: String,
240 pub subnet_id: String,
241 pub vpc_id: String,
242 pub availability_zone: String,
243 pub description: String,
244 pub mac_address: String,
245 pub private_ip_address: String,
246 pub status: String,
248 pub interface_type: String,
249 pub source_dest_check: bool,
250 #[serde(default)]
251 pub group_ids: Vec<String>,
252 #[serde(default)]
253 pub private_ips: Vec<String>,
254 #[serde(default)]
255 pub ipv6_addresses: Vec<String>,
256 pub attachment: Option<EniAttachment>,
257}
258
259#[derive(Clone, Debug, Serialize, Deserialize)]
261pub struct NetworkInterfacePermission {
262 pub permission_id: String,
263 pub network_interface_id: String,
264 pub aws_account_id: String,
265 pub permission: String,
267}
268
269#[derive(Clone, Debug, Serialize, Deserialize)]
271pub struct Instance {
272 pub instance_id: String,
273 pub image_id: String,
274 pub instance_type: String,
275 pub state_code: i64,
278 pub state_name: String,
279 pub private_ip: String,
280 pub public_ip: Option<String>,
281 pub subnet_id: Option<String>,
282 pub vpc_id: Option<String>,
283 pub key_name: Option<String>,
284 #[serde(default)]
285 pub security_group_ids: Vec<String>,
286 pub reservation_id: String,
287 pub ami_launch_index: i64,
288 pub monitoring: bool,
289 pub az: String,
290 pub launch_time: String,
291}
292
293#[derive(Clone, Debug, Serialize, Deserialize)]
295pub struct VolumeAttachment {
296 pub volume_id: String,
297 pub instance_id: String,
298 pub device: String,
299 pub status: String,
301 pub delete_on_termination: bool,
302}
303
304#[derive(Clone, Debug, Serialize, Deserialize)]
306pub struct Volume {
307 pub volume_id: String,
308 pub size: i64,
309 pub snapshot_id: Option<String>,
310 pub availability_zone: String,
311 pub state: String,
313 pub volume_type: String,
314 pub iops: Option<i64>,
315 pub throughput: Option<i64>,
316 pub encrypted: bool,
317 pub kms_key_id: Option<String>,
318 pub multi_attach_enabled: bool,
319 pub auto_enable_io: bool,
320 #[serde(default)]
321 pub attachments: Vec<VolumeAttachment>,
322 #[serde(default)]
323 pub in_recycle_bin: bool,
324}
325
326#[derive(Clone, Debug, Serialize, Deserialize)]
328pub struct Snapshot {
329 pub snapshot_id: String,
330 pub volume_id: String,
331 pub state: String,
333 pub volume_size: i64,
334 pub description: String,
335 pub encrypted: bool,
336 pub storage_tier: String,
338 #[serde(default)]
339 pub in_recycle_bin: bool,
340 #[serde(default)]
341 pub locked: bool,
342 pub lock_mode: Option<String>,
343}
344
345#[derive(Clone, Debug, Serialize, Deserialize)]
347pub struct Image {
348 pub image_id: String,
349 pub name: String,
350 pub description: String,
351 pub state: String,
353 pub architecture: String,
354 pub public: bool,
355 pub source_instance_id: Option<String>,
356 #[serde(default)]
357 pub in_recycle_bin: bool,
358 pub deprecation_time: Option<String>,
359 #[serde(default)]
360 pub deregistration_protection: bool,
361 #[serde(default)]
364 pub launch_permission_users: Vec<String>,
365 #[serde(default)]
367 pub launch_permission_groups: Vec<String>,
368 #[serde(default)]
371 pub boot_mode: Option<String>,
372}
373
374#[derive(Clone, Debug, Serialize, Deserialize)]
376pub struct NetworkAclEntry {
377 pub rule_number: i64,
378 pub protocol: String,
379 pub rule_action: String,
381 pub egress: bool,
382 pub cidr_block: Option<String>,
383 pub ipv6_cidr_block: Option<String>,
384 pub port_range: Option<(i64, i64)>,
386 pub icmp_type_code: Option<(i64, i64)>,
388}
389
390#[derive(Clone, Debug, Serialize, Deserialize)]
392pub struct NetworkAclAssoc {
393 pub association_id: String,
394 pub subnet_id: String,
395}
396
397#[derive(Clone, Debug, Serialize, Deserialize)]
399pub struct NetworkAcl {
400 pub network_acl_id: String,
401 pub vpc_id: String,
402 pub is_default: bool,
403 #[serde(default)]
404 pub entries: Vec<NetworkAclEntry>,
405 #[serde(default)]
406 pub associations: Vec<NetworkAclAssoc>,
407}
408
409#[derive(Clone, Debug, Serialize, Deserialize)]
411pub struct VpcPeering {
412 pub id: String,
413 pub requester_vpc_id: String,
414 pub accepter_vpc_id: String,
415 pub status: String,
417 #[serde(default)]
419 pub requester_allow_dns: bool,
420 #[serde(default)]
422 pub accepter_allow_dns: bool,
423}
424
425#[derive(Clone, Debug, Serialize, Deserialize)]
427pub struct VpcEndpoint {
428 pub id: String,
429 pub endpoint_type: String,
431 pub vpc_id: String,
432 pub service_name: String,
433 pub state: String,
434 #[serde(default)]
435 pub subnet_ids: Vec<String>,
436 #[serde(default)]
437 pub route_table_ids: Vec<String>,
438 #[serde(default)]
439 pub private_dns_enabled: bool,
440}
441
442#[derive(Clone, Debug, Serialize, Deserialize)]
444pub struct EndpointService {
445 pub service_id: String,
446 pub service_name: String,
447 pub state: String,
448 pub acceptance_required: bool,
449 pub payer_responsibility: String,
450 #[serde(default)]
451 pub nlb_arns: Vec<String>,
452}
453
454#[derive(Clone, Debug, Serialize, Deserialize)]
456pub struct ConnectionNotification {
457 pub id: String,
458 pub arn: String,
459 pub service_id: Option<String>,
460 #[serde(default)]
461 pub events: Vec<String>,
462}
463
464#[derive(Clone, Debug, Serialize, Deserialize)]
466pub struct FlowLog {
467 pub id: String,
468 pub resource_id: String,
469 pub traffic_type: String,
470 pub log_destination_type: String,
471 pub log_group_name: Option<String>,
472 pub log_destination: Option<String>,
474}
475
476#[derive(Clone, Debug, Serialize, Deserialize)]
478pub struct LaunchTemplate {
479 pub id: String,
480 pub name: String,
481 pub default_version: i64,
482 pub latest_version: i64,
483}
484
485#[derive(Clone, Debug, Serialize, Deserialize)]
487pub struct SpotRequest {
488 pub id: String,
489 pub state: String,
491 pub request_type: String,
492 pub spot_price: String,
493}
494
495#[derive(Clone, Debug, Serialize, Deserialize)]
497pub struct SpotFleet {
498 pub id: String,
499 pub state: String,
500}
501
502#[derive(Clone, Debug, Serialize, Deserialize)]
504pub struct Fleet {
505 pub id: String,
506 pub state: String,
507 pub fleet_type: String,
508}
509
510#[derive(Clone, Debug, Serialize, Deserialize)]
512pub struct CapacityReservation {
513 pub id: String,
514 pub instance_type: String,
515 pub instance_platform: String,
516 pub availability_zone: String,
517 pub tenancy: String,
518 pub total_instance_count: i64,
519 pub available_instance_count: i64,
520 pub state: String,
522 pub end_date_type: String,
523 pub instance_match_criteria: String,
524}
525
526#[derive(Clone, Debug, Serialize, Deserialize)]
528pub struct ReservedInstances {
529 pub id: String,
530 pub instance_type: String,
531 pub availability_zone: String,
532 pub instance_count: i64,
533 pub product_description: String,
534 pub state: String,
535 pub duration: i64,
536 pub fixed_price: String,
537 pub usage_price: String,
538}
539
540#[derive(Clone, Debug, Serialize, Deserialize)]
542pub struct ReservedInstancesListing {
543 pub listing_id: String,
544 pub reserved_instances_id: String,
545 pub instance_count: i64,
546 pub client_token: String,
547 pub status: String,
549 pub status_message: String,
550}
551
552#[derive(Clone, Debug, Serialize, Deserialize)]
554pub struct ReservedInstancesModification {
555 pub modification_id: String,
556 pub reserved_instances_ids: Vec<String>,
557 pub status: String,
559 pub client_token: String,
560}
561
562#[derive(Clone, Debug, Serialize, Deserialize)]
564pub struct DedicatedHost {
565 pub id: String,
566 pub auto_placement: String,
567 pub availability_zone: String,
568 pub instance_type: String,
569 pub state: String,
570 pub host_recovery: String,
571 pub host_maintenance: String,
572}
573
574#[derive(Clone, Debug, Serialize, Deserialize)]
576pub struct TransitGateway {
577 pub id: String,
578 pub description: String,
579 #[serde(default = "tgw_default_state")]
581 pub state: String,
582}
583
584fn tgw_default_state() -> String {
585 "available".to_string()
586}
587
588#[derive(Clone, Debug, Serialize, Deserialize)]
590pub struct TgwAttachment {
591 pub id: String,
592 pub tgw_id: String,
593 pub resource_id: String,
594 pub resource_type: String,
595 #[serde(default)]
596 pub subnet_ids: Vec<String>,
597 pub state: String,
598}
599
600#[derive(Clone, Debug, Serialize, Deserialize)]
602pub struct TgwRouteTable {
603 pub id: String,
604 pub tgw_id: String,
605}
606
607#[derive(Clone, Debug, Serialize, Deserialize)]
609pub struct TgwRoute {
610 pub cidr: String,
611 pub attachment_id: String,
612 pub state: String,
613}
614
615#[derive(Clone, Debug, Serialize, Deserialize)]
617pub struct TgwMulticastDomain {
618 pub id: String,
619 pub tgw_id: String,
620}
621
622#[derive(Clone, Debug, Serialize, Deserialize)]
624pub struct TgwMeteringPolicy {
625 pub id: String,
626 pub tgw_id: String,
627}
628
629#[derive(Clone, Debug, Serialize, Deserialize)]
631pub struct CustomerGateway {
632 pub id: String,
633 pub state: String,
634 pub ip_address: String,
635 pub bgp_asn: String,
636}
637
638#[derive(Clone, Debug, Serialize, Deserialize)]
640pub struct VpnGateway {
641 pub id: String,
642 pub state: String,
643 #[serde(default)]
644 pub attachments: Vec<String>,
645}
646
647#[derive(Clone, Debug, Serialize, Deserialize)]
649pub struct VpnConnection {
650 pub id: String,
651 pub state: String,
652 pub customer_gateway_id: String,
653 pub vpn_gateway_id: Option<String>,
654 #[serde(default)]
655 pub routes: Vec<String>,
656}
657
658#[derive(Clone, Debug, Serialize, Deserialize)]
660pub struct VpnConcentrator {
661 pub id: String,
662 pub state: String,
663}
664
665#[derive(Clone, Debug, Serialize, Deserialize)]
667pub struct Ipam {
668 pub id: String,
669 pub public_scope_id: String,
670 pub private_scope_id: String,
671 pub tier: String,
672 #[serde(default)]
673 pub description: String,
674}
675
676#[derive(Clone, Debug, Serialize, Deserialize)]
678pub struct IpamScope {
679 pub id: String,
680 pub ipam_id: String,
681 #[serde(default)]
683 pub scope_type: String,
684 #[serde(default)]
685 pub description: String,
686}
687
688#[derive(Clone, Debug, Serialize, Deserialize)]
690pub struct IpamPool {
691 pub id: String,
692 pub scope_id: String,
693 pub address_family: String,
694 #[serde(default)]
695 pub description: String,
696}
697
698#[derive(Clone, Debug, Serialize, Deserialize)]
700pub struct IpamResourceDiscovery {
701 pub id: String,
702 #[serde(default)]
703 pub description: String,
704}
705
706#[derive(Clone, Debug, Serialize, Deserialize)]
708pub struct IpamPolicy {
709 pub id: String,
710 pub ipam_id: String,
711}
712
713#[derive(Clone, Debug, Serialize, Deserialize)]
715pub struct IpamPrefixListResolver {
716 pub id: String,
717 pub ipam_id: String,
718 pub address_family: String,
719 #[serde(default)]
720 pub description: String,
721}
722
723#[derive(Clone, Debug, Serialize, Deserialize)]
725pub struct IpamPrefixListResolverTarget {
726 pub id: String,
727 pub resolver_id: String,
728 pub prefix_list_id: String,
729 pub prefix_list_region: String,
730 #[serde(default)]
731 pub track_latest_version: bool,
732}
733
734#[derive(Clone, Debug, Serialize, Deserialize)]
736pub struct VerifiedAccessInstance {
737 pub id: String,
738 pub description: String,
739 #[serde(default)]
740 pub trust_providers: Vec<String>,
741}
742
743#[derive(Clone, Debug, Serialize, Deserialize)]
745pub struct VerifiedAccessTrustProvider {
746 pub id: String,
747 pub trust_provider_type: String,
748 pub policy_reference_name: String,
749 pub description: String,
750}
751
752#[derive(Clone, Debug, Serialize, Deserialize)]
754pub struct VerifiedAccessGroup {
755 pub id: String,
756 pub instance_id: String,
757 pub description: String,
758}
759
760#[derive(Clone, Debug, Serialize, Deserialize)]
762pub struct VerifiedAccessEndpoint {
763 pub id: String,
764 pub group_id: String,
765 pub instance_id: String,
766 pub endpoint_type: String,
767 pub attachment_type: String,
768}
769
770#[derive(Clone, Debug, Serialize, Deserialize)]
772pub struct NetworkInsightsPath {
773 pub id: String,
774 pub source: String,
775 pub destination: String,
776 pub protocol: String,
777}
778
779#[derive(Clone, Debug, Serialize, Deserialize)]
781pub struct NetworkInsightsAnalysis {
782 pub id: String,
783 pub path_id: String,
784}
785
786#[derive(Clone, Debug, Serialize, Deserialize)]
788pub struct NetworkInsightsAccessScope {
789 pub id: String,
790}
791
792#[derive(Clone, Debug, Serialize, Deserialize)]
794pub struct NetworkInsightsAccessScopeAnalysis {
795 pub id: String,
796 pub scope_id: String,
797}
798
799#[derive(Clone, Debug, Serialize, Deserialize)]
801pub struct CarrierGateway {
802 pub id: String,
803 pub vpc_id: String,
804}
805
806#[derive(Clone, Debug, Serialize, Deserialize)]
808pub struct InstanceConnectEndpoint {
809 pub id: String,
810 pub subnet_id: String,
811}
812
813#[derive(Clone, Debug, Serialize, Deserialize)]
815pub struct CoipPool {
816 pub id: String,
817 pub route_table_id: String,
818}
819
820#[derive(Clone, Debug, Serialize, Deserialize)]
822pub struct LocalGatewayRouteTable {
823 pub id: String,
824 pub local_gateway_id: String,
825 pub mode: String,
826}
827
828#[derive(Clone, Debug, Serialize, Deserialize)]
830pub struct LocalGatewayRouteTableVpcAssoc {
831 pub id: String,
832 pub route_table_id: String,
833 pub vpc_id: String,
834}
835
836#[derive(Clone, Debug, Serialize, Deserialize)]
838pub struct LocalGatewayVif {
839 pub id: String,
840 pub group_id: String,
841 pub vlan: String,
842 pub local_address: String,
843 pub peer_address: String,
844}
845
846#[derive(Clone, Debug, Serialize, Deserialize)]
848pub struct LocalGatewayVifGroup {
849 pub id: String,
850 pub local_gateway_id: String,
851}
852
853#[derive(Clone, Debug, Serialize, Deserialize)]
855pub struct LocalGatewayRouteTableVifgAssoc {
856 pub id: String,
857 pub route_table_id: String,
858 pub vif_group_id: String,
859}
860
861#[derive(Clone, Debug, Serialize, Deserialize)]
863pub struct ClientVpnEndpoint {
864 pub id: String,
865 pub description: String,
866 pub status: String,
867 pub server_cert_arn: String,
868 pub transport_protocol: String,
869 pub client_cidr: String,
870 #[serde(default)]
871 pub routes: Vec<String>,
872 #[serde(default)]
874 pub target_networks: Vec<(String, String)>,
875 #[serde(default)]
877 pub auth_rules: Vec<String>,
878}
879
880#[derive(Clone, Debug, Serialize, Deserialize)]
882pub struct TgwPeering {
883 pub id: String,
884 pub tgw_id: String,
885 pub peer_tgw_id: String,
886 pub peer_account: String,
887 pub peer_region: String,
888 pub state: String,
889}
890
891#[derive(Clone, Debug, Default, Serialize, Deserialize)]
894pub struct Ec2State {
895 pub account_id: String,
896 pub region: String,
897 #[serde(default)]
899 pub tags: HashMap<String, Vec<Tag>>,
900 #[serde(default)]
901 pub vpcs: HashMap<String, Vpc>,
902 #[serde(default)]
903 pub dhcp_options: HashMap<String, DhcpOptions>,
904 #[serde(default)]
905 pub subnets: HashMap<String, Subnet>,
906 #[serde(default)]
907 pub subnet_cidr_reservations: HashMap<String, SubnetCidrReservation>,
908 #[serde(default)]
909 pub security_groups: HashMap<String, SecurityGroup>,
910 #[serde(default)]
911 pub route_tables: HashMap<String, RouteTable>,
912 #[serde(default)]
913 pub internet_gateways: HashMap<String, InternetGateway>,
914 #[serde(default)]
915 pub egress_only_igws: HashMap<String, InternetGateway>,
916 #[serde(default)]
917 pub nat_gateways: HashMap<String, NatGateway>,
918 #[serde(default)]
920 pub elastic_ips: HashMap<String, ElasticIp>,
921 #[serde(default)]
923 pub key_pairs: HashMap<String, KeyPair>,
924 #[serde(default)]
926 pub placement_groups: HashMap<String, PlacementGroup>,
927 #[serde(default)]
928 pub network_interfaces: HashMap<String, NetworkInterface>,
929 #[serde(default)]
931 pub eni_permissions: HashMap<String, NetworkInterfacePermission>,
932 #[serde(default)]
933 pub instances: HashMap<String, Instance>,
934 #[serde(default)]
935 pub volumes: HashMap<String, Volume>,
936 #[serde(default)]
938 pub ebs_encryption_default: bool,
939 #[serde(default)]
941 pub ebs_default_kms_key_id: Option<String>,
942 #[serde(default)]
943 pub snapshots: HashMap<String, Snapshot>,
944 #[serde(default)]
946 pub snapshot_block_public_access: String,
947 #[serde(default)]
948 pub images: HashMap<String, Image>,
949 #[serde(default)]
951 pub image_block_public_access: String,
952 #[serde(default)]
954 pub allowed_images_settings: String,
955 #[serde(default)]
956 pub network_acls: HashMap<String, NetworkAcl>,
957 #[serde(default)]
958 pub vpc_peerings: HashMap<String, VpcPeering>,
959 #[serde(default)]
960 pub vpc_endpoints: HashMap<String, VpcEndpoint>,
961 #[serde(default)]
962 pub endpoint_services: HashMap<String, EndpointService>,
963 #[serde(default)]
964 pub connection_notifications: HashMap<String, ConnectionNotification>,
965 #[serde(default)]
966 pub flow_logs: HashMap<String, FlowLog>,
967 #[serde(default)]
968 pub launch_templates: HashMap<String, LaunchTemplate>,
969 #[serde(default)]
970 pub spot_requests: HashMap<String, SpotRequest>,
971 #[serde(default)]
972 pub spot_fleets: HashMap<String, SpotFleet>,
973 #[serde(default)]
974 pub fleets: HashMap<String, Fleet>,
975 #[serde(default)]
977 pub spot_datafeed: Option<(String, String)>,
978 #[serde(default)]
979 pub capacity_reservations: HashMap<String, CapacityReservation>,
980 #[serde(default)]
982 pub capacity_reservation_fleets: HashMap<String, String>,
983 #[serde(default)]
984 pub reserved_instances: HashMap<String, ReservedInstances>,
985 #[serde(default)]
986 pub reserved_instances_listings: HashMap<String, ReservedInstancesListing>,
987 #[serde(default)]
988 pub reserved_instances_modifications: HashMap<String, ReservedInstancesModification>,
989 #[serde(default)]
990 pub dedicated_hosts: HashMap<String, DedicatedHost>,
991 #[serde(default)]
992 pub transit_gateways: HashMap<String, TransitGateway>,
993 #[serde(default)]
994 pub tgw_attachments: HashMap<String, TgwAttachment>,
995 #[serde(default)]
996 pub tgw_route_tables: HashMap<String, TgwRouteTable>,
997 #[serde(default)]
999 pub tgw_routes: HashMap<String, Vec<TgwRoute>>,
1000 #[serde(default)]
1002 pub tgw_rt_associations: HashMap<String, Vec<String>>,
1003 #[serde(default)]
1005 pub tgw_rt_propagations: HashMap<String, Vec<String>>,
1006 #[serde(default)]
1008 pub tgw_prefix_list_refs: HashMap<String, Vec<String>>,
1009 #[serde(default)]
1010 pub tgw_peerings: HashMap<String, TgwPeering>,
1011 #[serde(default)]
1013 pub tgw_connects: HashMap<String, (String, String)>,
1014 #[serde(default)]
1016 pub tgw_connect_peers: HashMap<String, String>,
1017 #[serde(default)]
1019 pub tgw_policy_tables: HashMap<String, String>,
1020 #[serde(default)]
1022 pub tgw_policy_table_associations: HashMap<String, Vec<String>>,
1023 #[serde(default)]
1025 pub tgw_announcements: HashMap<String, (String, String)>,
1026 #[serde(default)]
1027 pub tgw_multicast_domains: HashMap<String, TgwMulticastDomain>,
1028 #[serde(default)]
1029 pub tgw_metering_policies: HashMap<String, TgwMeteringPolicy>,
1030 #[serde(default)]
1031 pub customer_gateways: HashMap<String, CustomerGateway>,
1032 #[serde(default)]
1033 pub vpn_gateways: HashMap<String, VpnGateway>,
1034 #[serde(default)]
1035 pub vpn_connections: HashMap<String, VpnConnection>,
1036 #[serde(default)]
1037 pub vpn_concentrators: HashMap<String, VpnConcentrator>,
1038 #[serde(default)]
1039 pub client_vpn_endpoints: HashMap<String, ClientVpnEndpoint>,
1040 #[serde(default)]
1041 pub ipams: HashMap<String, Ipam>,
1042 #[serde(default)]
1043 pub ipam_scopes: HashMap<String, IpamScope>,
1044 #[serde(default)]
1045 pub ipam_pools: HashMap<String, IpamPool>,
1046 #[serde(default)]
1048 pub ipam_pool_cidrs: HashMap<String, Vec<(String, String)>>,
1049 #[serde(default)]
1051 pub ipam_pool_allocations: HashMap<String, Vec<(String, String)>>,
1052 #[serde(default)]
1053 pub ipam_resource_discoveries: HashMap<String, IpamResourceDiscovery>,
1054 #[serde(default)]
1056 pub ipam_rd_associations: HashMap<String, (String, String)>,
1057 #[serde(default)]
1059 pub ipam_byoasns: HashMap<String, String>,
1060 #[serde(default)]
1062 pub ipam_ext_tokens: HashMap<String, String>,
1063 #[serde(default)]
1064 pub ipam_policies: HashMap<String, IpamPolicy>,
1065 #[serde(default)]
1066 pub ipam_pl_resolvers: HashMap<String, IpamPrefixListResolver>,
1067 #[serde(default)]
1068 pub ipam_pl_resolver_targets: HashMap<String, IpamPrefixListResolverTarget>,
1069 #[serde(default)]
1071 pub ipam_policy_alloc_rules: HashMap<String, Vec<(String, String)>>,
1072 #[serde(default)]
1074 pub ipam_enabled_policy: Option<String>,
1075 #[serde(default)]
1076 pub va_instances: HashMap<String, VerifiedAccessInstance>,
1077 #[serde(default)]
1078 pub va_trust_providers: HashMap<String, VerifiedAccessTrustProvider>,
1079 #[serde(default)]
1080 pub va_groups: HashMap<String, VerifiedAccessGroup>,
1081 #[serde(default)]
1082 pub va_endpoints: HashMap<String, VerifiedAccessEndpoint>,
1083 #[serde(default)]
1085 pub va_group_policies: HashMap<String, String>,
1086 #[serde(default)]
1088 pub va_endpoint_policies: HashMap<String, String>,
1089 #[serde(default)]
1090 pub ni_paths: HashMap<String, NetworkInsightsPath>,
1091 #[serde(default)]
1092 pub ni_analyses: HashMap<String, NetworkInsightsAnalysis>,
1093 #[serde(default)]
1094 pub ni_access_scopes: HashMap<String, NetworkInsightsAccessScope>,
1095 #[serde(default)]
1096 pub ni_scope_analyses: HashMap<String, NetworkInsightsAccessScopeAnalysis>,
1097 #[serde(default)]
1098 pub carrier_gateways: HashMap<String, CarrierGateway>,
1099 #[serde(default)]
1100 pub coip_pools: HashMap<String, CoipPool>,
1101 #[serde(default)]
1103 pub coip_pool_cidrs: HashMap<String, Vec<String>>,
1104 #[serde(default)]
1105 pub lg_route_tables: HashMap<String, LocalGatewayRouteTable>,
1106 #[serde(default)]
1108 pub lg_routes: HashMap<String, Vec<String>>,
1109 #[serde(default)]
1110 pub lg_rt_vpc_assocs: HashMap<String, LocalGatewayRouteTableVpcAssoc>,
1111 #[serde(default)]
1112 pub lg_virtual_interfaces: HashMap<String, LocalGatewayVif>,
1113 #[serde(default)]
1114 pub lg_vif_groups: HashMap<String, LocalGatewayVifGroup>,
1115 #[serde(default)]
1116 pub lg_rt_vifg_assocs: HashMap<String, LocalGatewayRouteTableVifgAssoc>,
1117 #[serde(default)]
1118 pub instance_connect_endpoints: HashMap<String, InstanceConnectEndpoint>,
1119 #[serde(default)]
1121 pub fast_launch_images: std::collections::HashSet<String>,
1122 #[serde(default)]
1123 pub serial_console_access: bool,
1124}
1125
1126impl Ec2State {
1127 pub fn new(account_id: &str, region: &str) -> Self {
1128 Self {
1129 account_id: account_id.to_string(),
1130 region: region.to_string(),
1131 ..Default::default()
1132 }
1133 }
1134
1135 pub fn upsert_tags(&mut self, resource_id: &str, new_tags: &[Tag]) {
1138 let entry = self.tags.entry(resource_id.to_string()).or_default();
1139 for t in new_tags {
1140 if let Some(existing) = entry.iter_mut().find(|e| e.key == t.key) {
1141 existing.value = t.value.clone();
1142 } else {
1143 entry.push(t.clone());
1144 }
1145 }
1146 }
1147
1148 pub fn remove_tags(&mut self, resource_id: &str, to_remove: &[(String, Option<String>)]) {
1152 if let Some(entry) = self.tags.get_mut(resource_id) {
1153 for (key, value) in to_remove {
1154 entry.retain(|e| {
1155 if &e.key != key {
1156 return true;
1157 }
1158 match value {
1159 Some(v) => &e.value != v,
1160 None => false,
1161 }
1162 });
1163 }
1164 if entry.is_empty() {
1165 self.tags.remove(resource_id);
1166 }
1167 }
1168 }
1169
1170 pub fn tags_for(&self, resource_id: &str) -> &[Tag] {
1172 self.tags.get(resource_id).map(Vec::as_slice).unwrap_or(&[])
1173 }
1174}
1175
1176#[cfg(test)]
1177mod tests {
1178 use super::*;
1179
1180 fn tag(k: &str, v: &str) -> Tag {
1181 Tag {
1182 key: k.to_string(),
1183 value: v.to_string(),
1184 }
1185 }
1186
1187 #[test]
1188 fn upsert_tags_inserts_then_overwrites_by_key() {
1189 let mut s = Ec2State::new("123456789012", "us-east-1");
1190 s.upsert_tags("vpc-1", &[tag("Name", "a"), tag("env", "dev")]);
1191 s.upsert_tags("vpc-1", &[tag("Name", "b")]);
1192 let tags = s.tags_for("vpc-1");
1193 assert_eq!(tags.len(), 2);
1194 assert_eq!(tags.iter().find(|t| t.key == "Name").unwrap().value, "b");
1195 }
1196
1197 #[test]
1198 fn remove_tags_by_key_and_by_key_value() {
1199 let mut s = Ec2State::new("123456789012", "us-east-1");
1200 s.upsert_tags(
1201 "i-1",
1202 &[tag("Name", "x"), tag("env", "prod"), tag("team", "a")],
1203 );
1204 s.remove_tags("i-1", &[("Name".to_string(), None)]);
1206 s.remove_tags("i-1", &[("env".to_string(), Some("dev".to_string()))]);
1208 s.remove_tags("i-1", &[("team".to_string(), Some("a".to_string()))]);
1210 let tags = s.tags_for("i-1");
1211 assert_eq!(tags.len(), 1);
1212 assert_eq!(tags[0].key, "env");
1213 }
1214
1215 #[test]
1216 fn empty_tag_set_drops_resource_entry() {
1217 let mut s = Ec2State::new("123456789012", "us-east-1");
1218 s.upsert_tags("sg-1", &[tag("Name", "x")]);
1219 s.remove_tags("sg-1", &[("Name".to_string(), None)]);
1220 assert!(!s.tags.contains_key("sg-1"));
1221 }
1222}