Skip to content

Commit 3784aea

Browse files
committed
plumb transit_ips through instance NIC create
1 parent 8669fe1 commit 3784aea

File tree

6 files changed

+53
-5
lines changed

6 files changed

+53
-5
lines changed

nexus/db-model/src/network_interface.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ pub struct IncompleteNetworkInterface {
319319
pub kind: NetworkInterfaceKind,
320320
pub parent_id: Uuid,
321321
pub subnet: VpcSubnet,
322+
pub transit_ips: Vec<IpNetwork>,
322323
pub ip: Option<std::net::IpAddr>,
323324
pub mac: Option<external::MacAddr>,
324325
pub slot: Option<u8>,
@@ -332,6 +333,7 @@ impl IncompleteNetworkInterface {
332333
parent_id: Uuid,
333334
subnet: VpcSubnet,
334335
identity: external::IdentityMetadataCreateParams,
336+
transit_ips: Vec<oxnet::IpNet>,
335337
ip: Option<std::net::IpAddr>,
336338
mac: Option<external::MacAddr>,
337339
slot: Option<u8>,
@@ -378,6 +380,7 @@ impl IncompleteNetworkInterface {
378380
kind,
379381
parent_id,
380382
subnet,
383+
transit_ips: transit_ips.into_iter().map(Into::into).collect(),
381384
ip,
382385
mac,
383386
slot,
@@ -389,6 +392,7 @@ impl IncompleteNetworkInterface {
389392
instance_id: InstanceUuid,
390393
subnet: VpcSubnet,
391394
identity: external::IdentityMetadataCreateParams,
395+
transit_ips: Vec<oxnet::IpNet>,
392396
ip: Option<std::net::IpAddr>,
393397
) -> Result<Self, external::Error> {
394398
Self::new(
@@ -397,6 +401,7 @@ impl IncompleteNetworkInterface {
397401
instance_id.into_untyped_uuid(),
398402
subnet,
399403
identity,
404+
transit_ips,
400405
ip,
401406
None,
402407
None,
@@ -418,6 +423,7 @@ impl IncompleteNetworkInterface {
418423
service_id,
419424
subnet,
420425
identity,
426+
vec![],
421427
Some(ip),
422428
Some(mac),
423429
Some(slot),
@@ -438,6 +444,7 @@ impl IncompleteNetworkInterface {
438444
probe_id,
439445
subnet,
440446
identity,
447+
vec![],
441448
ip,
442449
mac,
443450
None,

nexus/db-queries/src/db/datastore/vpc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3752,6 +3752,7 @@ mod tests {
37523752
name: "nic".parse().unwrap(),
37533753
description: "A NIC...".into(),
37543754
},
3755+
vec![],
37553756
None,
37563757
)
37573758
.unwrap(),

nexus/db-queries/src/db/queries/network_interface.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,13 @@ impl QueryFragment<Pg> for InsertQuery {
11381138
out.push_identifier(dsl::parent_id::NAME)?;
11391139
out.push_sql(", ");
11401140

1141+
out.push_bind_param::<sql_types::Array<sql_types::Inet>, Vec<IpNetwork>>(
1142+
&self.interface.transit_ips,
1143+
)?;
1144+
out.push_sql(" AS ");
1145+
out.push_identifier(dsl::transit_ips::NAME)?;
1146+
out.push_sql(", ");
1147+
11411148
// Helper function to push a subquery selecting something from the CTE.
11421149
fn select_from_cte(
11431150
mut out: AstPass<Pg>,
@@ -1231,6 +1238,8 @@ impl QueryFragment<Pg> for InsertQueryValues {
12311238
out.push_sql(", ");
12321239
out.push_identifier(dsl::parent_id::NAME)?;
12331240
out.push_sql(", ");
1241+
out.push_identifier(dsl::transit_ips::NAME)?;
1242+
out.push_sql(", ");
12341243
out.push_identifier(dsl::vpc_id::NAME)?;
12351244
out.push_sql(", ");
12361245
out.push_identifier(dsl::subnet_id::NAME)?;
@@ -2144,6 +2153,7 @@ mod tests {
21442153
name: "interface-a".parse().unwrap(),
21452154
description: String::from("description"),
21462155
},
2156+
vec![],
21472157
Some(requested_ip),
21482158
)
21492159
.unwrap();
@@ -2173,6 +2183,7 @@ mod tests {
21732183
name: "interface-a".parse().unwrap(),
21742184
description: String::from("description"),
21752185
},
2186+
vec![],
21762187
Some(requested_ip),
21772188
)
21782189
.unwrap();
@@ -2186,10 +2197,10 @@ mod tests {
21862197
.expect("Failed to insert interface with known-good IP address");
21872198
assert_interfaces_eq(&interface, &inserted_interface.clone().into());
21882199
assert_eq!(
2189-
inserted_interface.ip.ip(),
2190-
requested_ip,
2191-
"The requested IP address should be available when no interfaces exist in the table"
2192-
);
2200+
inserted_interface.ip.ip(),
2201+
requested_ip,
2202+
"The requested IP address should be available when no interfaces exist in the table"
2203+
);
21932204
context.success().await;
21942205
}
21952206

@@ -2205,6 +2216,7 @@ mod tests {
22052216
name: "interface-b".parse().unwrap(),
22062217
description: String::from("description"),
22072218
},
2219+
vec![],
22082220
None,
22092221
)
22102222
.unwrap();
@@ -2243,6 +2255,7 @@ mod tests {
22432255
name: format!("interface-{}", i).parse().unwrap(),
22442256
description: String::from("description"),
22452257
},
2258+
vec![],
22462259
None,
22472260
)
22482261
.unwrap();
@@ -2287,6 +2300,7 @@ mod tests {
22872300
name: "interface-c".parse().unwrap(),
22882301
description: String::from("description"),
22892302
},
2303+
vec![],
22902304
None,
22912305
)
22922306
.unwrap();
@@ -2306,6 +2320,7 @@ mod tests {
23062320
name: "interface-c".parse().unwrap(),
23072321
description: String::from("description"),
23082322
},
2323+
vec![],
23092324
Some(inserted_interface.ip.ip()),
23102325
)
23112326
.unwrap();
@@ -2545,6 +2560,7 @@ mod tests {
25452560
name: "interface-c".parse().unwrap(),
25462561
description: String::from("description"),
25472562
},
2563+
vec![],
25482564
None,
25492565
)
25502566
.unwrap();
@@ -2564,6 +2580,7 @@ mod tests {
25642580
name: "interface-c".parse().unwrap(),
25652581
description: String::from("description"),
25662582
},
2583+
vec![],
25672584
None,
25682585
)
25692586
.unwrap();
@@ -2595,6 +2612,7 @@ mod tests {
25952612
name: "interface-c".parse().unwrap(),
25962613
description: String::from("description"),
25972614
},
2615+
vec![],
25982616
None,
25992617
)
26002618
.unwrap();
@@ -2611,6 +2629,7 @@ mod tests {
26112629
name: "interface-d".parse().unwrap(),
26122630
description: String::from("description"),
26132631
},
2632+
vec![],
26142633
None,
26152634
)
26162635
.unwrap();
@@ -2639,6 +2658,7 @@ mod tests {
26392658
name: "interface-c".parse().unwrap(),
26402659
description: String::from("description"),
26412660
},
2661+
vec![],
26422662
None,
26432663
)
26442664
.unwrap();
@@ -2681,6 +2701,7 @@ mod tests {
26812701
name: "interface-c".parse().unwrap(),
26822702
description: String::from("description"),
26832703
},
2704+
vec![],
26842705
None,
26852706
)
26862707
.unwrap();
@@ -2699,6 +2720,7 @@ mod tests {
26992720
name: "interface-a".parse().unwrap(),
27002721
description: String::from("description"),
27012722
},
2723+
vec![],
27022724
addr,
27032725
)
27042726
.unwrap();
@@ -2735,6 +2757,7 @@ mod tests {
27352757
name: "interface-c".parse().unwrap(),
27362758
description: String::from("description"),
27372759
},
2760+
vec![],
27382761
None,
27392762
)
27402763
.unwrap();
@@ -2764,6 +2787,7 @@ mod tests {
27642787
name: "interface-d".parse().unwrap(),
27652788
description: String::from("description"),
27662789
},
2790+
vec![],
27672791
None,
27682792
)
27692793
.unwrap();
@@ -2797,6 +2821,7 @@ mod tests {
27972821
name: format!("if{}", i).parse().unwrap(),
27982822
description: String::from("description"),
27992823
},
2824+
vec![],
28002825
None,
28012826
)
28022827
.unwrap();
@@ -2865,6 +2890,7 @@ mod tests {
28652890
name: format!("interface-{}", slot).parse().unwrap(),
28662891
description: String::from("description"),
28672892
},
2893+
vec![],
28682894
None,
28692895
)
28702896
.unwrap();
@@ -2900,6 +2926,7 @@ mod tests {
29002926
name: "interface-8".parse().unwrap(),
29012927
description: String::from("description"),
29022928
},
2929+
vec![],
29032930
None,
29042931
)
29052932
.unwrap();

nexus/src/app/network_interface.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ impl super::Nexus {
9292
InstanceUuid::from_untyped_uuid(authz_instance.id()),
9393
db_subnet,
9494
params.identity.clone(),
95+
params.transit_ips.clone(),
9596
params.ip,
9697
)?;
9798
self.db_datastore

nexus/src/app/sagas/instance_create.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ async fn create_custom_network_interface(
526526
instance_id,
527527
db_subnet.clone(),
528528
interface_params.identity.clone(),
529+
interface_params.transit_ips.clone(),
529530
interface_params.ip,
530531
)
531532
.map_err(ActionError::action_failed)?;
@@ -621,6 +622,7 @@ async fn create_default_primary_network_interface(
621622
instance_id,
622623
db_subnet.clone(),
623624
interface_params.identity.clone(),
625+
interface_params.transit_ips.clone(),
624626
interface_params.ip,
625627
)
626628
.map_err(ActionError::action_failed)?;

nexus/tests/integration_tests/instances.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2609,7 +2609,7 @@ async fn test_instance_create_delete_network_interface(
26092609
vpc_name: "default".parse().unwrap(),
26102610
subnet_name: secondary_subnet.identity.name.clone(),
26112611
ip: Some("172.31.0.11".parse().unwrap()),
2612-
transit_ips: vec![],
2612+
transit_ips: vec!["10.0.0.0/24".parse().unwrap()],
26132613
},
26142614
];
26152615

@@ -2663,6 +2663,15 @@ async fn test_instance_create_delete_network_interface(
26632663
i == 0,
26642664
"Only the first interface should be primary"
26652665
);
2666+
if i == 1 {
2667+
assert!(
2668+
iface.transit_ips.len() == 1
2669+
&& iface.transit_ips[0].to_string() == "10.0.0.0/24",
2670+
"Only the second interface has a transit IP"
2671+
);
2672+
} else {
2673+
assert!(iface.transit_ips.is_empty())
2674+
}
26662675
interfaces.push(iface);
26672676
}
26682677

@@ -2683,6 +2692,7 @@ async fn test_instance_create_delete_network_interface(
26832692
assert_eq!(iface0.subnet_id, iface1.subnet_id);
26842693
assert_eq!(iface0.ip, iface1.ip);
26852694
assert_eq!(iface0.primary, iface1.primary);
2695+
assert_eq!(iface0.transit_ips, iface1.transit_ips);
26862696
}
26872697

26882698
// Verify we cannot delete either interface while the instance is running

0 commit comments

Comments
 (0)