Skip to content
15 changes: 14 additions & 1 deletion dev-tools/reconfigurator-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use nexus_inventory::CollectionBuilder;
use nexus_reconfigurator_blippy::Blippy;
use nexus_reconfigurator_blippy::BlippyReportSortKey;
use nexus_reconfigurator_planning::blueprint_builder::BlueprintBuilder;
use nexus_reconfigurator_planning::blueprint_editor::ExternalNetworkingAllocator;
use nexus_reconfigurator_planning::example::{
ExampleSystemBuilder, extract_tuf_repo_description, tuf_assemble,
};
Expand Down Expand Up @@ -2248,8 +2249,20 @@ fn cmd_blueprint_edit(
&planning_input,
ZoneKind::Nexus,
)?;
let external_ip = ExternalNetworkingAllocator::from_current_zones(
&builder,
planning_input.external_ip_policy(),
)
.context("failed to construct external networking allocator")?
.for_new_nexus()
.context("failed to pick an external IP for Nexus")?;
builder
.sled_add_zone_nexus(sled_id, image_source, nexus_generation)
.sled_add_zone_nexus(
sled_id,
image_source,
external_ip,
nexus_generation,
)
.context("failed to add Nexus zone")?;
format!("added Nexus zone to sled {}", sled_id)
}
Expand Down
15 changes: 14 additions & 1 deletion live-tests/tests/test_nexus_add_remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use nexus_lockstep_client::types::QuiesceState;
use nexus_lockstep_client::types::Saga;
use nexus_lockstep_client::types::SagaState;
use nexus_reconfigurator_planning::blueprint_builder::BlueprintBuilder;
use nexus_reconfigurator_planning::blueprint_editor::ExternalNetworkingAllocator;
use nexus_reconfigurator_planning::planner::Planner;
use nexus_reconfigurator_planning::planner::PlannerRng;
use nexus_reconfigurator_preparation::PlanningInputFromDb;
Expand Down Expand Up @@ -115,8 +116,20 @@ async fn test_nexus_add_remove(lc: &LiveTestContext) {
"could not find in-service Nexus in parent blueprint",
)?;

let external_ip = ExternalNetworkingAllocator::from_current_zones(
builder,
planning_input.external_ip_policy(),
)
.context("failed to construct external networking allocator")?
.for_new_nexus()
.context("failed to pick an external IP for Nexus")?;
builder
.sled_add_zone_nexus(sled_id, image_source, *nexus_generation)
.sled_add_zone_nexus(
sled_id,
image_source,
external_ip,
*nexus_generation,
)
.context("adding Nexus zone")?;

Ok(())
Expand Down
13 changes: 13 additions & 0 deletions live-tests/tests/test_nexus_handoff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use live_tests_macros::live_test;
use nexus_db_model::DbMetadataNexusState;
use nexus_lockstep_client::types::QuiesceState;
use nexus_reconfigurator_planning::blueprint_builder::BlueprintBuilder;
use nexus_reconfigurator_planning::blueprint_editor::ExternalNetworkingAllocator;
use nexus_reconfigurator_preparation::PlanningInputFromDb;
use nexus_types::deployment::Blueprint;
use nexus_types::deployment::BlueprintZoneDisposition;
Expand Down Expand Up @@ -173,11 +174,23 @@ async fn test_nexus_handoff(lc: &LiveTestContext) {
&collection,
&nexus,
&|builder: &mut BlueprintBuilder| {
let mut external_networking_alloc =
ExternalNetworkingAllocator::from_current_zones(
builder,
planning_input.external_ip_policy(),
)
.context(
"failed to construct external networking allocator",
)?;
for current_nexus in current_nexus_zones.values() {
let external_ip = external_networking_alloc
.for_new_nexus()
.context("failed to pick an external IP for Nexus")?;
builder
.sled_add_zone_nexus(
current_nexus.sled_id,
current_nexus.image_source.clone(),
external_ip,
next_generation,
)
.context("adding Nexus zone")?;
Expand Down
19 changes: 19 additions & 0 deletions nexus/db-queries/src/db/datastore/vpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2979,6 +2979,7 @@ mod tests {
use nexus_db_model::IncompleteNetworkInterface;
use nexus_db_model::IpConfig;
use nexus_reconfigurator_planning::blueprint_builder::BlueprintBuilder;
use nexus_reconfigurator_planning::blueprint_editor::ExternalNetworkingAllocator;
use nexus_reconfigurator_planning::planner::PlannerRng;
use nexus_reconfigurator_planning::system::SledBuilder;
use nexus_reconfigurator_planning::system::SystemDescription;
Expand Down Expand Up @@ -3347,12 +3348,20 @@ mod tests {
)
.expect("ensured disks");
}
let external_ip = ExternalNetworkingAllocator::from_current_zones(
&builder,
planning_input.external_ip_policy(),
)
.expect("constructed ExternalNetworkingAllocator")
.for_new_nexus()
.expect("found external IP for Nexus");
builder
.sled_add_zone_nexus_with_config(
sled_ids[2],
false,
Vec::new(),
BlueprintZoneImageSource::InstallDataset,
external_ip,
bp0.nexus_generation,
)
.expect("added nexus to third sled");
Expand Down Expand Up @@ -3422,13 +3431,23 @@ mod tests {
PlannerRng::from_entropy(),
)
.expect("created blueprint builder");
let mut external_networking_alloc =
ExternalNetworkingAllocator::from_current_zones(
&builder,
planning_input.external_ip_policy(),
)
.expect("constructed ExternalNetworkingAllocator");
for &sled_id in &sled_ids {
let external_ip = external_networking_alloc
.for_new_nexus()
.expect("found external IP for Nexus");
builder
.sled_add_zone_nexus_with_config(
sled_id,
false,
Vec::new(),
BlueprintZoneImageSource::InstallDataset,
external_ip,
bp2.nexus_generation,
)
.expect("added nexus to third sled");
Expand Down
16 changes: 13 additions & 3 deletions nexus/reconfigurator/execution/src/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ mod test {
use nexus_inventory::CollectionBuilder;
use nexus_inventory::now_db_precision;
use nexus_reconfigurator_planning::blueprint_builder::BlueprintBuilder;
use nexus_reconfigurator_planning::blueprint_editor::ExternalNetworkingAllocator;
use nexus_reconfigurator_planning::example::ExampleSystemBuilder;
use nexus_reconfigurator_planning::planner::PlannerRng;
use nexus_reconfigurator_preparation::PlanningInputFromDb;
Expand Down Expand Up @@ -1584,13 +1585,22 @@ mod test {
// * 127.0.0.1 (Nexus)
// * ::1 (external DNS)
//
// However, when the builder compiles its list of "IPs already in use",
// it _ignores_ loopback addresses, meaning we still have two external
// IPs available for new zones (127.0.0.1 and ::1).
// However, when the allocator compiles its list of "IPs already in
// use", it _ignores_ loopback addresses, meaning we still have two
// external IPs available for new zones (127.0.0.1 and ::1).
let new_nexus_external_ip =
ExternalNetworkingAllocator::from_current_zones(
&builder,
planning_input.external_ip_policy(),
)
.expect("constructed ExternalNetworkingAllocator")
.for_new_nexus()
.expect("found external IP for Nexus");
builder
.sled_add_zone_nexus(
sled_id,
BlueprintZoneImageSource::InstallDataset,
new_nexus_external_ip,
blueprint.nexus_generation,
)
.unwrap();
Expand Down
17 changes: 16 additions & 1 deletion nexus/reconfigurator/execution/src/sagas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ fn find_expunged_same_generation(
mod test {
use super::*;
use nexus_reconfigurator_planning::blueprint_builder::BlueprintBuilder;
use nexus_reconfigurator_planning::blueprint_editor::ExternalNetworkingAllocator;
use nexus_reconfigurator_planning::example::ExampleSystemBuilder;
use nexus_reconfigurator_planning::planner::PlannerRng;
use nexus_types::deployment::BlueprintSource;
Expand Down Expand Up @@ -160,9 +161,23 @@ mod test {
// Create the same number of Nexus zones in the next generation.
// We'll use the same images.
let g2 = g1.next();
let mut external_networking_alloc =
ExternalNetworkingAllocator::from_current_zones(
&builder,
example.input.external_ip_policy(),
)
.expect("constructed ExternalNetworkingAllocator");
for (sled_id, _zone_id, image_source) in &g1_nexus_ids {
let external_ip = external_networking_alloc
.for_new_nexus()
.expect("found external IP for Nexus");
builder
.sled_add_zone_nexus(*sled_id, image_source.clone(), g2)
.sled_add_zone_nexus(
*sled_id,
image_source.clone(),
external_ip,
g2,
)
.expect("add Nexus zone");
}

Expand Down
Loading
Loading