Skip to content

Commit

Permalink
plumb transit_ips through instance NIC create
Browse files Browse the repository at this point in the history
  • Loading branch information
david-crespo committed Oct 14, 2024
1 parent 8669fe1 commit 3784aea
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 5 deletions.
7 changes: 7 additions & 0 deletions nexus/db-model/src/network_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ pub struct IncompleteNetworkInterface {
pub kind: NetworkInterfaceKind,
pub parent_id: Uuid,
pub subnet: VpcSubnet,
pub transit_ips: Vec<IpNetwork>,
pub ip: Option<std::net::IpAddr>,
pub mac: Option<external::MacAddr>,
pub slot: Option<u8>,
Expand All @@ -332,6 +333,7 @@ impl IncompleteNetworkInterface {
parent_id: Uuid,
subnet: VpcSubnet,
identity: external::IdentityMetadataCreateParams,
transit_ips: Vec<oxnet::IpNet>,
ip: Option<std::net::IpAddr>,
mac: Option<external::MacAddr>,
slot: Option<u8>,
Expand Down Expand Up @@ -378,6 +380,7 @@ impl IncompleteNetworkInterface {
kind,
parent_id,
subnet,
transit_ips: transit_ips.into_iter().map(Into::into).collect(),
ip,
mac,
slot,
Expand All @@ -389,6 +392,7 @@ impl IncompleteNetworkInterface {
instance_id: InstanceUuid,
subnet: VpcSubnet,
identity: external::IdentityMetadataCreateParams,
transit_ips: Vec<oxnet::IpNet>,
ip: Option<std::net::IpAddr>,
) -> Result<Self, external::Error> {
Self::new(
Expand All @@ -397,6 +401,7 @@ impl IncompleteNetworkInterface {
instance_id.into_untyped_uuid(),
subnet,
identity,
transit_ips,
ip,
None,
None,
Expand All @@ -418,6 +423,7 @@ impl IncompleteNetworkInterface {
service_id,
subnet,
identity,
vec![],
Some(ip),
Some(mac),
Some(slot),
Expand All @@ -438,6 +444,7 @@ impl IncompleteNetworkInterface {
probe_id,
subnet,
identity,
vec![],
ip,
mac,
None,
Expand Down
1 change: 1 addition & 0 deletions nexus/db-queries/src/db/datastore/vpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3752,6 +3752,7 @@ mod tests {
name: "nic".parse().unwrap(),
description: "A NIC...".into(),
},
vec![],
None,
)
.unwrap(),
Expand Down
35 changes: 31 additions & 4 deletions nexus/db-queries/src/db/queries/network_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,13 @@ impl QueryFragment<Pg> for InsertQuery {
out.push_identifier(dsl::parent_id::NAME)?;
out.push_sql(", ");

out.push_bind_param::<sql_types::Array<sql_types::Inet>, Vec<IpNetwork>>(
&self.interface.transit_ips,
)?;
out.push_sql(" AS ");
out.push_identifier(dsl::transit_ips::NAME)?;
out.push_sql(", ");

// Helper function to push a subquery selecting something from the CTE.
fn select_from_cte(
mut out: AstPass<Pg>,
Expand Down Expand Up @@ -1231,6 +1238,8 @@ impl QueryFragment<Pg> for InsertQueryValues {
out.push_sql(", ");
out.push_identifier(dsl::parent_id::NAME)?;
out.push_sql(", ");
out.push_identifier(dsl::transit_ips::NAME)?;
out.push_sql(", ");
out.push_identifier(dsl::vpc_id::NAME)?;
out.push_sql(", ");
out.push_identifier(dsl::subnet_id::NAME)?;
Expand Down Expand Up @@ -2144,6 +2153,7 @@ mod tests {
name: "interface-a".parse().unwrap(),
description: String::from("description"),
},
vec![],
Some(requested_ip),
)
.unwrap();
Expand Down Expand Up @@ -2173,6 +2183,7 @@ mod tests {
name: "interface-a".parse().unwrap(),
description: String::from("description"),
},
vec![],
Some(requested_ip),
)
.unwrap();
Expand All @@ -2186,10 +2197,10 @@ mod tests {
.expect("Failed to insert interface with known-good IP address");
assert_interfaces_eq(&interface, &inserted_interface.clone().into());
assert_eq!(
inserted_interface.ip.ip(),
requested_ip,
"The requested IP address should be available when no interfaces exist in the table"
);
inserted_interface.ip.ip(),
requested_ip,
"The requested IP address should be available when no interfaces exist in the table"
);
context.success().await;
}

Expand All @@ -2205,6 +2216,7 @@ mod tests {
name: "interface-b".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2243,6 +2255,7 @@ mod tests {
name: format!("interface-{}", i).parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2287,6 +2300,7 @@ mod tests {
name: "interface-c".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand All @@ -2306,6 +2320,7 @@ mod tests {
name: "interface-c".parse().unwrap(),
description: String::from("description"),
},
vec![],
Some(inserted_interface.ip.ip()),
)
.unwrap();
Expand Down Expand Up @@ -2545,6 +2560,7 @@ mod tests {
name: "interface-c".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand All @@ -2564,6 +2580,7 @@ mod tests {
name: "interface-c".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2595,6 +2612,7 @@ mod tests {
name: "interface-c".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand All @@ -2611,6 +2629,7 @@ mod tests {
name: "interface-d".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2639,6 +2658,7 @@ mod tests {
name: "interface-c".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2681,6 +2701,7 @@ mod tests {
name: "interface-c".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand All @@ -2699,6 +2720,7 @@ mod tests {
name: "interface-a".parse().unwrap(),
description: String::from("description"),
},
vec![],
addr,
)
.unwrap();
Expand Down Expand Up @@ -2735,6 +2757,7 @@ mod tests {
name: "interface-c".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2764,6 +2787,7 @@ mod tests {
name: "interface-d".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2797,6 +2821,7 @@ mod tests {
name: format!("if{}", i).parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2865,6 +2890,7 @@ mod tests {
name: format!("interface-{}", slot).parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down Expand Up @@ -2900,6 +2926,7 @@ mod tests {
name: "interface-8".parse().unwrap(),
description: String::from("description"),
},
vec![],
None,
)
.unwrap();
Expand Down
1 change: 1 addition & 0 deletions nexus/src/app/network_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl super::Nexus {
InstanceUuid::from_untyped_uuid(authz_instance.id()),
db_subnet,
params.identity.clone(),
params.transit_ips.clone(),
params.ip,
)?;
self.db_datastore
Expand Down
2 changes: 2 additions & 0 deletions nexus/src/app/sagas/instance_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ async fn create_custom_network_interface(
instance_id,
db_subnet.clone(),
interface_params.identity.clone(),
interface_params.transit_ips.clone(),
interface_params.ip,
)
.map_err(ActionError::action_failed)?;
Expand Down Expand Up @@ -621,6 +622,7 @@ async fn create_default_primary_network_interface(
instance_id,
db_subnet.clone(),
interface_params.identity.clone(),
interface_params.transit_ips.clone(),
interface_params.ip,
)
.map_err(ActionError::action_failed)?;
Expand Down
12 changes: 11 additions & 1 deletion nexus/tests/integration_tests/instances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2609,7 +2609,7 @@ async fn test_instance_create_delete_network_interface(
vpc_name: "default".parse().unwrap(),
subnet_name: secondary_subnet.identity.name.clone(),
ip: Some("172.31.0.11".parse().unwrap()),
transit_ips: vec![],
transit_ips: vec!["10.0.0.0/24".parse().unwrap()],
},
];

Expand Down Expand Up @@ -2663,6 +2663,15 @@ async fn test_instance_create_delete_network_interface(
i == 0,
"Only the first interface should be primary"
);
if i == 1 {
assert!(
iface.transit_ips.len() == 1
&& iface.transit_ips[0].to_string() == "10.0.0.0/24",
"Only the second interface has a transit IP"
);
} else {
assert!(iface.transit_ips.is_empty())
}
interfaces.push(iface);
}

Expand All @@ -2683,6 +2692,7 @@ async fn test_instance_create_delete_network_interface(
assert_eq!(iface0.subnet_id, iface1.subnet_id);
assert_eq!(iface0.ip, iface1.ip);
assert_eq!(iface0.primary, iface1.primary);
assert_eq!(iface0.transit_ips, iface1.transit_ips);
}

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

0 comments on commit 3784aea

Please sign in to comment.