Skip to content

Commit d15d74e

Browse files
authored
fix(ec2): persist SG rule descriptions + IAM-profile/SG-VPC/TGW-multicast/route-server/BYOIP/NAT associations (bug-hunt) (#2305)
2 parents ac8f1e6 + e9fc543 commit d15d74e

12 files changed

Lines changed: 1937 additions & 210 deletions

File tree

crates/fakecloud-ec2/src/defaults.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ pub(crate) fn bootstrap_default_network(state: &mut Ec2State) {
380380
cidr_ipv6: None,
381381
prefix_list_id: None,
382382
referenced_group_id: Some(sg_id.clone()),
383+
referenced_group_name: None,
384+
referenced_user_id: None,
383385
description: String::new(),
384386
},
385387
SecurityGroupRule {
@@ -393,6 +395,8 @@ pub(crate) fn bootstrap_default_network(state: &mut Ec2State) {
393395
cidr_ipv6: None,
394396
prefix_list_id: None,
395397
referenced_group_id: None,
398+
referenced_group_name: None,
399+
referenced_user_id: None,
396400
description: String::new(),
397401
},
398402
],
@@ -476,6 +480,8 @@ pub(crate) fn create_vpc_default_resources(state: &mut Ec2State, vpc_id: &str, c
476480
cidr_ipv6: None,
477481
prefix_list_id: None,
478482
referenced_group_id: Some(sg_id.clone()),
483+
referenced_group_name: None,
484+
referenced_user_id: None,
479485
description: String::new(),
480486
},
481487
SecurityGroupRule {
@@ -489,6 +495,8 @@ pub(crate) fn create_vpc_default_resources(state: &mut Ec2State, vpc_id: &str, c
489495
cidr_ipv6: None,
490496
prefix_list_id: None,
491497
referenced_group_id: None,
498+
referenced_group_name: None,
499+
referenced_user_id: None,
492500
description: String::new(),
493501
},
494502
],

crates/fakecloud-ec2/src/service/firewall_model.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ mod tests {
263263
cidr_ipv6: None,
264264
prefix_list_id: None,
265265
referenced_group_id: refg.map(str::to_string),
266+
referenced_group_name: None,
267+
referenced_user_id: None,
266268
description: String::new(),
267269
}
268270
}

crates/fakecloud-ec2/src/service/rest/byoip.rs

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,63 +4,121 @@
44

55
use super::*;
66

7+
fn byoip_cidr_xml(c: &ByoipCidr) -> String {
8+
format!(
9+
"{}{}{}",
10+
ec2_elem("cidr", &c.cidr),
11+
ec2_elem("description", &c.description),
12+
ec2_elem("state", &c.state),
13+
)
14+
}
15+
16+
/// Update the persisted BYOIP CIDR's state (inserting it when unknown), then
17+
/// render it. Shared by advertise/withdraw so each op round-trips.
18+
fn set_byoip_state(svc: &Ec2Service, req: &AwsRequest, cidr: &str, state: &str) -> ByoipCidr {
19+
let mut accounts = svc.state.write();
20+
let account = accounts.get_or_create(&req.account_id);
21+
let entry = account
22+
.byoip_cidrs
23+
.entry(cidr.to_string())
24+
.or_insert_with(|| ByoipCidr {
25+
cidr: cidr.to_string(),
26+
description: String::new(),
27+
state: state.to_string(),
28+
});
29+
entry.state = state.to_string();
30+
entry.clone()
31+
}
32+
733
pub(crate) fn advertise_byoip_cidr(
8-
_svc: &Ec2Service,
34+
svc: &Ec2Service,
935
req: &AwsRequest,
1036
) -> Result<AwsResponse, AwsServiceError> {
11-
require(&req.query_params, "Cidr")?;
37+
let cidr = require(&req.query_params, "Cidr")?;
38+
let c = set_byoip_state(svc, req, &cidr, "advertised");
1239
Ok(Ec2Service::respond(
1340
"AdvertiseByoipCidr",
1441
&req.request_id,
15-
"",
42+
&format!("<byoipCidr>{}</byoipCidr>", byoip_cidr_xml(&c)),
1643
))
1744
}
1845

1946
pub(crate) fn deprovision_byoip_cidr(
20-
_svc: &Ec2Service,
47+
svc: &Ec2Service,
2148
req: &AwsRequest,
2249
) -> Result<AwsResponse, AwsServiceError> {
23-
require(&req.query_params, "Cidr")?;
50+
let cidr = require(&req.query_params, "Cidr")?;
51+
// Deprovision removes the CIDR from the pool; report the transitional state.
52+
let mut c = set_byoip_state(svc, req, &cidr, "pending-deprovision");
53+
{
54+
let mut accounts = svc.state.write();
55+
accounts
56+
.get_or_create(&req.account_id)
57+
.byoip_cidrs
58+
.remove(&cidr);
59+
}
60+
c.state = "pending-deprovision".to_string();
2461
Ok(Ec2Service::respond(
2562
"DeprovisionByoipCidr",
2663
&req.request_id,
27-
"",
64+
&format!("<byoipCidr>{}</byoipCidr>", byoip_cidr_xml(&c)),
2865
))
2966
}
3067

3168
pub(crate) fn describe_byoip_cidrs(
32-
_svc: &Ec2Service,
69+
svc: &Ec2Service,
3370
req: &AwsRequest,
3471
) -> Result<AwsResponse, AwsServiceError> {
3572
require(&req.query_params, "MaxResults")?;
3673
validate_max_results(&req.query_params, 1, 100)?;
74+
let accounts = svc.state.read();
75+
let empty = Ec2State::new(&req.account_id, &req.region);
76+
let state = accounts.get(&req.account_id).unwrap_or(&empty);
77+
let items: Vec<String> = state.byoip_cidrs.values().map(byoip_cidr_xml).collect();
3778
Ok(Ec2Service::respond(
3879
"DescribeByoipCidrs",
3980
&req.request_id,
40-
"",
81+
&ec2_list("byoipCidrSet", &items),
4182
))
4283
}
4384

4485
pub(crate) fn provision_byoip_cidr(
45-
_svc: &Ec2Service,
86+
svc: &Ec2Service,
4687
req: &AwsRequest,
4788
) -> Result<AwsResponse, AwsServiceError> {
48-
require(&req.query_params, "Cidr")?;
89+
let cidr = require(&req.query_params, "Cidr")?;
90+
let c = ByoipCidr {
91+
cidr: cidr.clone(),
92+
description: req
93+
.query_params
94+
.get("Description")
95+
.cloned()
96+
.unwrap_or_default(),
97+
state: "provisioned".to_string(),
98+
};
99+
{
100+
let mut accounts = svc.state.write();
101+
accounts
102+
.get_or_create(&req.account_id)
103+
.byoip_cidrs
104+
.insert(cidr, c.clone());
105+
}
49106
Ok(Ec2Service::respond(
50107
"ProvisionByoipCidr",
51108
&req.request_id,
52-
"",
109+
&format!("<byoipCidr>{}</byoipCidr>", byoip_cidr_xml(&c)),
53110
))
54111
}
55112

56113
pub(crate) fn withdraw_byoip_cidr(
57-
_svc: &Ec2Service,
114+
svc: &Ec2Service,
58115
req: &AwsRequest,
59116
) -> Result<AwsResponse, AwsServiceError> {
60-
require(&req.query_params, "Cidr")?;
117+
let cidr = require(&req.query_params, "Cidr")?;
118+
let c = set_byoip_state(svc, req, &cidr, "provisioned");
61119
Ok(Ec2Service::respond(
62120
"WithdrawByoipCidr",
63121
&req.request_id,
64-
"",
122+
&format!("<byoipCidr>{}</byoipCidr>", byoip_cidr_xml(&c)),
65123
))
66124
}

0 commit comments

Comments
 (0)