From 91703c7e178fc4c9ca77610870055d6fc99de213 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 5 Oct 2024 17:45:48 -0700 Subject: [PATCH 1/4] [spr] changes to main this commit is based on Created using spr 1.3.6-beta.1 [skip ci] --- Cargo.lock | 2 +- dev-tools/omdb/tests/test_all_output.rs | 33 +-- dev-tools/reconfigurator-cli/Cargo.toml | 1 - dev-tools/reconfigurator-cli/src/main.rs | 15 +- .../reconfigurator-cli/tests/test_basic.rs | 4 +- nexus/db-fixed-data/src/project.rs | 4 +- nexus/db-fixed-data/src/silo.rs | 29 +- nexus/db-fixed-data/src/silo_user.rs | 8 +- nexus/db-model/src/sled.rs | 16 + nexus/db-queries/src/db/datastore/instance.rs | 3 +- .../db-queries/src/db/datastore/migration.rs | 3 +- nexus/db-queries/src/db/datastore/mod.rs | 16 +- nexus/db-queries/src/db/datastore/project.rs | 4 +- nexus/db-queries/src/db/datastore/rack.rs | 4 +- .../virtual_provisioning_collection.rs | 3 +- .../execution/src/cockroachdb.rs | 4 +- nexus/reconfigurator/execution/src/dns.rs | 232 ++------------- nexus/reconfigurator/execution/src/lib.rs | 42 +-- .../execution/src/omicron_physical_disks.rs | 9 +- .../execution/src/omicron_zones.rs | 10 +- .../execution/src/test_utils.rs | 43 ++- .../planning/src/blueprint_builder/builder.rs | 3 +- .../blueprint_builder/external_networking.rs | 3 +- nexus/reconfigurator/planning/src/example.rs | 277 +++++++++++++++++- nexus/reconfigurator/planning/src/planner.rs | 76 +---- nexus/reconfigurator/planning/src/system.rs | 16 + .../example_builder_zone_counts_blueprint.txt | 211 +++++++++++++ nexus/src/app/external_endpoints.rs | 6 +- nexus/src/app/rack.rs | 2 +- nexus/src/app/silo.rs | 4 +- nexus/tests/integration_tests/authn_http.rs | 4 +- nexus/tests/integration_tests/disks.rs | 11 +- nexus/tests/integration_tests/instances.rs | 4 +- nexus/tests/integration_tests/ip_pools.rs | 6 +- nexus/tests/integration_tests/metrics.rs | 13 +- nexus/tests/integration_tests/silo_users.rs | 6 +- nexus/tests/integration_tests/silos.rs | 13 +- nexus/types/Cargo.toml | 1 + nexus/types/src/deployment/execution/mod.rs | 11 + .../src/deployment/execution}/overridables.rs | 57 +--- .../{execution.rs => execution/spec.rs} | 0 nexus/types/src/deployment/execution/utils.rs | 228 ++++++++++++++ nexus/types/src/lib.rs | 1 + nexus/types/src/silo.rs | 44 +++ test-utils/src/dev/test_cmds.rs | 98 ++++--- 45 files changed, 1048 insertions(+), 532 deletions(-) create mode 100644 nexus/reconfigurator/planning/tests/output/example_builder_zone_counts_blueprint.txt create mode 100644 nexus/types/src/deployment/execution/mod.rs rename nexus/{reconfigurator/execution/src => types/src/deployment/execution}/overridables.rs (59%) rename nexus/types/src/deployment/{execution.rs => execution/spec.rs} (100%) create mode 100644 nexus/types/src/deployment/execution/utils.rs create mode 100644 nexus/types/src/silo.rs diff --git a/Cargo.lock b/Cargo.lock index b427d779ea..6162d5b0e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5898,6 +5898,7 @@ dependencies = [ "gateway-client", "http 1.1.0", "humantime", + "internal-dns", "ipnetwork", "newtype-uuid", "newtype_derive", @@ -8877,7 +8878,6 @@ dependencies = [ "nexus-client", "nexus-db-queries", "nexus-inventory", - "nexus-reconfigurator-execution", "nexus-reconfigurator-planning", "nexus-reconfigurator-preparation", "nexus-sled-agent-shared", diff --git a/dev-tools/omdb/tests/test_all_output.rs b/dev-tools/omdb/tests/test_all_output.rs index be14d07765..282248de80 100644 --- a/dev-tools/omdb/tests/test_all_output.rs +++ b/dev-tools/omdb/tests/test_all_output.rs @@ -16,9 +16,9 @@ use nexus_types::deployment::Blueprint; use nexus_types::deployment::SledFilter; use nexus_types::deployment::UnstableReconfiguratorState; use omicron_test_utils::dev::test_cmds::path_to_executable; -use omicron_test_utils::dev::test_cmds::redact_extra; use omicron_test_utils::dev::test_cmds::run_command; use omicron_test_utils::dev::test_cmds::ExtraRedactions; +use omicron_test_utils::dev::test_cmds::Redactor; use slog_error_chain::InlineErrorChain; use std::fmt::Write; use std::net::IpAddr; @@ -211,11 +211,16 @@ async fn test_omdb_success_cases(cptestctx: &ControlPlaneTestContext) { "cockroachdb_fingerprint", &initial_blueprint.cockroachdb_fingerprint, ); + let crdb_version = initial_blueprint.cockroachdb_setting_preserve_downgrade.to_string(); if initial_blueprint.cockroachdb_setting_preserve_downgrade.is_set() { redactions.variable_length("cockroachdb_version", &crdb_version); } + + let mut redactor = Redactor::new(); + redactor.extra(redactions); + for args in invocations { println!("running commands with args: {:?}", args); let p = postgres_url.to_string(); @@ -234,7 +239,7 @@ async fn test_omdb_success_cases(cptestctx: &ControlPlaneTestContext) { }, &cmd_path, args, - Some(&redactions), + Some(&redactor), ) .await; } @@ -444,14 +449,7 @@ async fn do_run( ) where F: FnOnce(Exec) -> Exec + Send + 'static, { - do_run_extra( - output, - modexec, - cmd_path, - args, - Some(&ExtraRedactions::new()), - ) - .await; + do_run_extra(output, modexec, cmd_path, args, Some(&Redactor::new())).await; } async fn do_run_no_redactions( @@ -470,7 +468,8 @@ async fn do_run_extra( modexec: F, cmd_path: &Path, args: &[&str], - extra_redactions: Option<&ExtraRedactions<'_>>, + // None means no redactions are performed. + redactor: Option<&Redactor<'_>>, ) where F: FnOnce(Exec) -> Exec + Send + 'static, { @@ -480,9 +479,9 @@ async fn do_run_extra( cmd_path.file_name().expect("missing command").to_string_lossy(), args.iter() .map(|r| { - extra_redactions.map_or_else( + redactor.map_or_else( || r.to_string(), - |redactions| redact_extra(r, redactions), + |redactor| redactor.do_redact(r), ) }) .collect::>() @@ -522,8 +521,8 @@ async fn do_run_extra( write!(output, "---------------------------------------------\n").unwrap(); write!(output, "stdout:\n").unwrap(); - if let Some(extra_redactions) = extra_redactions { - output.push_str(&redact_extra(&stdout_text, extra_redactions)); + if let Some(redactor) = redactor { + output.push_str(&redactor.do_redact(&stdout_text)); } else { output.push_str(&stdout_text); } @@ -531,8 +530,8 @@ async fn do_run_extra( write!(output, "---------------------------------------------\n").unwrap(); write!(output, "stderr:\n").unwrap(); - if let Some(extra_redactions) = extra_redactions { - output.push_str(&redact_extra(&stderr_text, extra_redactions)); + if let Some(redactor) = redactor { + output.push_str(&redactor.do_redact(&stderr_text)); } else { output.push_str(&stderr_text); } diff --git a/dev-tools/reconfigurator-cli/Cargo.toml b/dev-tools/reconfigurator-cli/Cargo.toml index b24c0eef36..e3dcff6769 100644 --- a/dev-tools/reconfigurator-cli/Cargo.toml +++ b/dev-tools/reconfigurator-cli/Cargo.toml @@ -21,7 +21,6 @@ humantime.workspace = true indexmap.workspace = true nexus-inventory.workspace = true nexus-reconfigurator-planning.workspace = true -nexus-reconfigurator-execution.workspace = true nexus-sled-agent-shared.workspace = true nexus-types.workspace = true omicron-common.workspace = true diff --git a/dev-tools/reconfigurator-cli/src/main.rs b/dev-tools/reconfigurator-cli/src/main.rs index 188319b665..783891610e 100644 --- a/dev-tools/reconfigurator-cli/src/main.rs +++ b/dev-tools/reconfigurator-cli/src/main.rs @@ -13,8 +13,6 @@ use clap::{Args, Parser, Subcommand}; use dns_service_client::DnsDiff; use indexmap::IndexMap; use nexus_inventory::CollectionBuilder; -use nexus_reconfigurator_execution::blueprint_external_dns_config; -use nexus_reconfigurator_execution::blueprint_internal_dns_config; use nexus_reconfigurator_planning::blueprint_builder::BlueprintBuilder; use nexus_reconfigurator_planning::blueprint_builder::EnsureMultiple; use nexus_reconfigurator_planning::planner::Planner; @@ -22,8 +20,10 @@ use nexus_reconfigurator_planning::system::{ SledBuilder, SledHwInventory, SystemDescription, }; use nexus_sled_agent_shared::inventory::OmicronZonesConfig; -use nexus_sled_agent_shared::inventory::SledRole; use nexus_sled_agent_shared::inventory::ZoneKind; +use nexus_types::deployment::execution; +use nexus_types::deployment::execution::blueprint_external_dns_config; +use nexus_types::deployment::execution::blueprint_internal_dns_config; use nexus_types::deployment::BlueprintZoneFilter; use nexus_types::deployment::OmicronZoneNic; use nexus_types::deployment::PlanningInput; @@ -882,10 +882,7 @@ fn cmd_blueprint_diff( fn make_sleds_by_id( sim: &ReconfiguratorSim, -) -> Result< - BTreeMap, - anyhow::Error, -> { +) -> Result, anyhow::Error> { let collection = sim .system .to_collection_builder() @@ -897,10 +894,10 @@ fn make_sleds_by_id( .sled_agents .iter() .map(|(sled_id, sled_agent_info)| { - let sled = nexus_reconfigurator_execution::Sled::new( + let sled = execution::Sled::new( *sled_id, sled_agent_info.sled_agent_address, - sled_agent_info.sled_role == SledRole::Scrimlet, + sled_agent_info.sled_role, ); (*sled_id, sled) }) diff --git a/dev-tools/reconfigurator-cli/tests/test_basic.rs b/dev-tools/reconfigurator-cli/tests/test_basic.rs index 2f45158d30..a847c2593f 100644 --- a/dev-tools/reconfigurator-cli/tests/test_basic.rs +++ b/dev-tools/reconfigurator-cli/tests/test_basic.rs @@ -19,8 +19,8 @@ use omicron_test_utils::dev::poll::wait_for_condition; use omicron_test_utils::dev::poll::CondCheckError; use omicron_test_utils::dev::test_cmds::assert_exit_code; use omicron_test_utils::dev::test_cmds::path_to_executable; -use omicron_test_utils::dev::test_cmds::redact_variable; use omicron_test_utils::dev::test_cmds::run_command; +use omicron_test_utils::dev::test_cmds::Redactor; use omicron_test_utils::dev::test_cmds::EXIT_SUCCESS; use omicron_uuid_kinds::SledUuid; use slog::debug; @@ -43,7 +43,7 @@ fn test_basic() { let exec = Exec::cmd(path_to_cli()).arg("tests/input/cmds.txt"); let (exit_status, stdout_text, stderr_text) = run_command(exec); assert_exit_code(exit_status, EXIT_SUCCESS, &stderr_text); - let stdout_text = redact_variable(&stdout_text); + let stdout_text = Redactor::new().do_redact(&stdout_text); assert_contents("tests/output/cmd-stdout", &stdout_text); assert_contents("tests/output/cmd-stderr", &stderr_text); } diff --git a/nexus/db-fixed-data/src/project.rs b/nexus/db-fixed-data/src/project.rs index 6b9f005916..7784390820 100644 --- a/nexus/db-fixed-data/src/project.rs +++ b/nexus/db-fixed-data/src/project.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use nexus_db_model as model; -use nexus_types::external_api::params; +use nexus_types::{external_api::params, silo::INTERNAL_SILO_ID}; use omicron_common::api::external::IdentityMetadataCreateParams; use once_cell::sync::Lazy; @@ -21,7 +21,7 @@ pub static SERVICES_PROJECT_ID: Lazy = Lazy::new(|| { pub static SERVICES_PROJECT: Lazy = Lazy::new(|| { model::Project::new_with_id( *SERVICES_PROJECT_ID, - *super::silo::INTERNAL_SILO_ID, + INTERNAL_SILO_ID, params::ProjectCreate { identity: IdentityMetadataCreateParams { name: SERVICES_DB_NAME.parse().unwrap(), diff --git a/nexus/db-fixed-data/src/silo.rs b/nexus/db-fixed-data/src/silo.rs index ebc6776923..10c624e30e 100644 --- a/nexus/db-fixed-data/src/silo.rs +++ b/nexus/db-fixed-data/src/silo.rs @@ -3,26 +3,26 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use nexus_db_model as model; -use nexus_types::external_api::{params, shared}; +use nexus_types::{ + external_api::{params, shared}, + silo::{ + default_silo_name, internal_silo_name, DEFAULT_SILO_ID, + INTERNAL_SILO_ID, + }, +}; use omicron_common::api::external::IdentityMetadataCreateParams; use once_cell::sync::Lazy; -pub static DEFAULT_SILO_ID: Lazy = Lazy::new(|| { - "001de000-5110-4000-8000-000000000000" - .parse() - .expect("invalid uuid for builtin silo id") -}); - /// "Default" Silo /// /// This was historically used for demos and the unit tests. The plan is to /// remove it per omicron#2305. pub static DEFAULT_SILO: Lazy = Lazy::new(|| { model::Silo::new_with_id( - *DEFAULT_SILO_ID, + DEFAULT_SILO_ID, params::SiloCreate { identity: IdentityMetadataCreateParams { - name: "default-silo".parse().unwrap(), + name: default_silo_name().clone(), description: "default silo".to_string(), }, // This quota is actually _unused_ because the default silo @@ -38,21 +38,14 @@ pub static DEFAULT_SILO: Lazy = Lazy::new(|| { .unwrap() }); -/// UUID of built-in internal silo. -pub static INTERNAL_SILO_ID: Lazy = Lazy::new(|| { - "001de000-5110-4000-8000-000000000001" - .parse() - .expect("invalid uuid for builtin silo id") -}); - /// Built-in Silo to house internal resources. It contains no users and /// can't be logged into. pub static INTERNAL_SILO: Lazy = Lazy::new(|| { model::Silo::new_with_id( - *INTERNAL_SILO_ID, + INTERNAL_SILO_ID, params::SiloCreate { identity: IdentityMetadataCreateParams { - name: "oxide-internal".parse().unwrap(), + name: internal_silo_name().clone(), description: "Built-in internal Silo.".to_string(), }, // The internal silo contains no virtual resources, so it has no allotted capacity. diff --git a/nexus/db-fixed-data/src/silo_user.rs b/nexus/db-fixed-data/src/silo_user.rs index defaa9bd52..e6e6d7d0e5 100644 --- a/nexus/db-fixed-data/src/silo_user.rs +++ b/nexus/db-fixed-data/src/silo_user.rs @@ -5,7 +5,7 @@ use super::role_builtin; use nexus_db_model as model; -use nexus_types::identity::Asset; +use nexus_types::{identity::Asset, silo::DEFAULT_SILO_ID}; use once_cell::sync::Lazy; /// Test user that's granted all privileges, used for automated testing and @@ -15,7 +15,7 @@ use once_cell::sync::Lazy; // not automatically at Nexus startup. See omicron#2305. pub static USER_TEST_PRIVILEGED: Lazy = Lazy::new(|| { model::SiloUser::new( - *crate::silo::DEFAULT_SILO_ID, + DEFAULT_SILO_ID, // "4007" looks a bit like "root". "001de000-05e4-4000-8000-000000004007".parse().unwrap(), "privileged".into(), @@ -39,7 +39,7 @@ pub static ROLE_ASSIGNMENTS_PRIVILEGED: Lazy> = model::IdentityType::SiloUser, USER_TEST_PRIVILEGED.id(), role_builtin::SILO_ADMIN.resource_type, - *crate::silo::DEFAULT_SILO_ID, + DEFAULT_SILO_ID, role_builtin::SILO_ADMIN.role_name, ), ] @@ -51,7 +51,7 @@ pub static ROLE_ASSIGNMENTS_PRIVILEGED: Lazy> = // not automatically at Nexus startup. See omicron#2305. pub static USER_TEST_UNPRIVILEGED: Lazy = Lazy::new(|| { model::SiloUser::new( - *crate::silo::DEFAULT_SILO_ID, + DEFAULT_SILO_ID, // 60001 is the decimal uid for "nobody" on Helios. "001de000-05e4-4000-8000-000000060001".parse().unwrap(), "unprivileged".into(), diff --git a/nexus/db-model/src/sled.rs b/nexus/db-model/src/sled.rs index ca2b292711..b586ad0fc5 100644 --- a/nexus/db-model/src/sled.rs +++ b/nexus/db-model/src/sled.rs @@ -11,11 +11,13 @@ use crate::sled_policy::DbSledPolicy; use chrono::{DateTime, Utc}; use db_macros::Asset; use nexus_sled_agent_shared::inventory::SledRole; +use nexus_types::deployment::execution; use nexus_types::{ external_api::{shared, views}, identity::Asset, internal_api::params, }; +use omicron_uuid_kinds::{GenericUuid, SledUuid}; use std::net::Ipv6Addr; use std::net::SocketAddrV6; use uuid::Uuid; @@ -140,6 +142,20 @@ impl From for views::Sled { } } +impl From for execution::Sled { + fn from(sled: Sled) -> Self { + Self::new( + SledUuid::from_untyped_uuid(sled.id()), + sled.address(), + if sled.is_scrimlet { + SledRole::Scrimlet + } else { + SledRole::Gimlet + }, + ) + } +} + impl From for params::SledAgentInfo { fn from(sled: Sled) -> Self { let role = if sled.is_scrimlet { diff --git a/nexus/db-queries/src/db/datastore/instance.rs b/nexus/db-queries/src/db/datastore/instance.rs index 1662504865..8fdb16b2f3 100644 --- a/nexus/db-queries/src/db/datastore/instance.rs +++ b/nexus/db-queries/src/db/datastore/instance.rs @@ -1954,6 +1954,7 @@ mod tests { use nexus_test_utils::db::test_setup_database; use nexus_types::external_api::params; use nexus_types::identity::Asset; + use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::api::external; use omicron_common::api::external::ByteCount; use omicron_common::api::external::IdentityMetadataCreateParams; @@ -1963,7 +1964,7 @@ mod tests { datastore: &DataStore, opctx: &OpContext, ) -> (authz::Project, Project) { - let silo_id = *nexus_db_fixed_data::silo::DEFAULT_SILO_ID; + let silo_id = DEFAULT_SILO_ID; let project_id = Uuid::new_v4(); datastore .project_create( diff --git a/nexus/db-queries/src/db/datastore/migration.rs b/nexus/db-queries/src/db/datastore/migration.rs index 584f00f084..0866226d69 100644 --- a/nexus/db-queries/src/db/datastore/migration.rs +++ b/nexus/db-queries/src/db/datastore/migration.rs @@ -184,6 +184,7 @@ mod tests { use nexus_db_model::Project; use nexus_test_utils::db::test_setup_database; use nexus_types::external_api::params; + use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::api::external::ByteCount; use omicron_common::api::external::IdentityMetadataCreateParams; use omicron_test_utils::dev; @@ -194,7 +195,7 @@ mod tests { datastore: &DataStore, opctx: &OpContext, ) -> authz::Instance { - let silo_id = *nexus_db_fixed_data::silo::DEFAULT_SILO_ID; + let silo_id = DEFAULT_SILO_ID; let project_id = Uuid::new_v4(); let instance_id = InstanceUuid::new_v4(); diff --git a/nexus/db-queries/src/db/datastore/mod.rs b/nexus/db-queries/src/db/datastore/mod.rs index ec317c184f..258e43f18c 100644 --- a/nexus/db-queries/src/db/datastore/mod.rs +++ b/nexus/db-queries/src/db/datastore/mod.rs @@ -444,11 +444,11 @@ mod test { use futures::StreamExt; use nexus_config::RegionAllocationStrategy; use nexus_db_fixed_data::silo::DEFAULT_SILO; - use nexus_db_fixed_data::silo::DEFAULT_SILO_ID; use nexus_db_model::IpAttachState; use nexus_db_model::{to_db_typed_uuid, Generation}; use nexus_test_utils::db::test_setup_database; use nexus_types::external_api::params; + use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::api::external::{ ByteCount, Error, IdentityMetadataCreateParams, LookupType, Name, }; @@ -552,8 +552,8 @@ mod test { // Associate silo with user let authz_silo = authz::Silo::new( authz::FLEET, - *DEFAULT_SILO_ID, - LookupType::ById(*DEFAULT_SILO_ID), + DEFAULT_SILO_ID, + LookupType::ById(DEFAULT_SILO_ID), ); datastore .silo_user_create( @@ -572,7 +572,7 @@ mod test { .fetch() .await .unwrap(); - assert_eq!(*DEFAULT_SILO_ID, db_silo_user.silo_id); + assert_eq!(DEFAULT_SILO_ID, db_silo_user.silo_id); // fetch the one we just created let (.., fetched) = LookupPath::new(&opctx, &datastore) @@ -630,7 +630,7 @@ mod test { Arc::new(authz::Authz::new(&logctx.log)), authn::Context::for_test_user( silo_user_id, - *DEFAULT_SILO_ID, + DEFAULT_SILO_ID, SiloAuthnPolicy::try_from(&*DEFAULT_SILO).unwrap(), ), Arc::clone(&datastore) as Arc, @@ -1726,8 +1726,8 @@ mod test { // Create a new Silo user so that we can lookup their keys. let authz_silo = authz::Silo::new( authz::FLEET, - *DEFAULT_SILO_ID, - LookupType::ById(*DEFAULT_SILO_ID), + DEFAULT_SILO_ID, + LookupType::ById(DEFAULT_SILO_ID), ); let silo_user_id = Uuid::new_v4(); datastore @@ -1777,7 +1777,7 @@ mod test { .fetch() .await .unwrap(); - assert_eq!(authz_silo.id(), *DEFAULT_SILO_ID); + assert_eq!(authz_silo.id(), DEFAULT_SILO_ID); assert_eq!(authz_silo_user.id(), silo_user_id); assert_eq!(found.silo_user_id, ssh_key.silo_user_id); assert_eq!(found.public_key, ssh_key.public_key); diff --git a/nexus/db-queries/src/db/datastore/project.rs b/nexus/db-queries/src/db/datastore/project.rs index 42ccca4ed6..58b7b315c1 100644 --- a/nexus/db-queries/src/db/datastore/project.rs +++ b/nexus/db-queries/src/db/datastore/project.rs @@ -26,7 +26,7 @@ use async_bb8_diesel::AsyncRunQueryDsl; use chrono::Utc; use diesel::prelude::*; use nexus_db_fixed_data::project::SERVICES_PROJECT; -use nexus_db_fixed_data::silo::INTERNAL_SILO_ID; +use nexus_types::silo::INTERNAL_SILO_ID; use omicron_common::api::external::http_pagination::PaginatedBy; use omicron_common::api::external::CreateResult; use omicron_common::api::external::DeleteResult; @@ -103,7 +103,7 @@ impl DataStore { debug!(opctx.log, "attempting to create built-in projects"); let (authz_silo,) = db::lookup::LookupPath::new(&opctx, self) - .silo_id(*INTERNAL_SILO_ID) + .silo_id(INTERNAL_SILO_ID) .lookup_for(authz::Action::CreateChild) .await?; diff --git a/nexus/db-queries/src/db/datastore/rack.rs b/nexus/db-queries/src/db/datastore/rack.rs index ce93891406..7f1e252a06 100644 --- a/nexus/db-queries/src/db/datastore/rack.rs +++ b/nexus/db-queries/src/db/datastore/rack.rs @@ -33,7 +33,6 @@ use diesel::prelude::*; use diesel::result::Error as DieselError; use diesel::upsert::excluded; use ipnetwork::IpNetwork; -use nexus_db_fixed_data::silo::INTERNAL_SILO_ID; use nexus_db_fixed_data::vpc_subnet::DNS_VPC_SUBNET; use nexus_db_fixed_data::vpc_subnet::NEXUS_VPC_SUBNET; use nexus_db_fixed_data::vpc_subnet::NTP_VPC_SUBNET; @@ -57,6 +56,7 @@ use nexus_types::external_api::shared::IdentityType; use nexus_types::external_api::shared::IpRange; use nexus_types::external_api::shared::SiloRole; use nexus_types::identity::Resource; +use nexus_types::silo::INTERNAL_SILO_ID; use omicron_common::api::external::AllowedSourceIps; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::Error; @@ -983,7 +983,7 @@ impl DataStore { db::model::IpPoolResource { ip_pool_id: internal_pool_id, resource_type: db::model::IpPoolResourceType::Silo, - resource_id: *INTERNAL_SILO_ID, + resource_id: INTERNAL_SILO_ID, is_default: true, }, ) diff --git a/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs b/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs index 0e200f47bb..e838d38d37 100644 --- a/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs +++ b/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs @@ -333,6 +333,7 @@ mod test { use nexus_db_model::SiloQuotasUpdate; use nexus_test_utils::db::test_setup_database; use nexus_types::external_api::params; + use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::api::external::IdentityMetadataCreateParams; use omicron_test_utils::dev; use uuid::Uuid; @@ -380,7 +381,7 @@ mod test { opctx: &OpContext, ) -> TestData { let fleet_id = *nexus_db_fixed_data::FLEET_ID; - let silo_id = *nexus_db_fixed_data::silo::DEFAULT_SILO_ID; + let silo_id = DEFAULT_SILO_ID; let project_id = Uuid::new_v4(); let (authz_project, _project) = datastore diff --git a/nexus/reconfigurator/execution/src/cockroachdb.rs b/nexus/reconfigurator/execution/src/cockroachdb.rs index 33b8176df6..9656428c2d 100644 --- a/nexus/reconfigurator/execution/src/cockroachdb.rs +++ b/nexus/reconfigurator/execution/src/cockroachdb.rs @@ -33,7 +33,7 @@ pub(crate) async fn ensure_settings( #[cfg(test)] mod test { use super::*; - use crate::overridables::Overridables; + use crate::test_utils::overridables_for_test; use crate::test_utils::realize_blueprint_and_expect; use nexus_db_queries::authn; use nexus_db_queries::authz; @@ -98,7 +98,7 @@ mod test { ) .await; // Execute the initial blueprint. - let overrides = Overridables::for_test(cptestctx); + let overrides = overridables_for_test(cptestctx); _ = realize_blueprint_and_expect( &opctx, datastore, resolver, &blueprint, &overrides, ) diff --git a/nexus/reconfigurator/execution/src/dns.rs b/nexus/reconfigurator/execution/src/dns.rs index 52c593a8e6..1aba020339 100644 --- a/nexus/reconfigurator/execution/src/dns.rs +++ b/nexus/reconfigurator/execution/src/dns.rs @@ -4,35 +4,27 @@ //! Propagates DNS changes in a given blueprint -use crate::overridables::Overridables; use crate::Sled; use dns_service_client::DnsDiff; -use internal_dns::DnsConfigBuilder; -use internal_dns::ServiceName; use nexus_db_model::DnsGroup; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::datastore::Discoverability; use nexus_db_queries::db::datastore::DnsVersionUpdateBuilder; -use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO; use nexus_db_queries::db::DataStore; -use nexus_types::deployment::blueprint_zone_type; +use nexus_types::deployment::execution::blueprint_external_dns_config; +use nexus_types::deployment::execution::blueprint_internal_dns_config; +use nexus_types::deployment::execution::Overridables; use nexus_types::deployment::Blueprint; -use nexus_types::deployment::BlueprintZoneFilter; -use nexus_types::deployment::BlueprintZoneType; use nexus_types::identity::Resource; use nexus_types::internal_api::params::DnsConfigParams; use nexus_types::internal_api::params::DnsConfigZone; -use nexus_types::internal_api::params::DnsRecord; use omicron_common::api::external::Error; use omicron_common::api::external::Generation; use omicron_common::api::external::InternalContext; -use omicron_common::api::external::Name; use omicron_common::bail_unless; use omicron_uuid_kinds::SledUuid; use slog::{debug, info, o}; use std::collections::BTreeMap; -use std::collections::HashMap; -use std::net::IpAddr; pub(crate) async fn deploy_dns( opctx: &OpContext, @@ -60,7 +52,10 @@ pub(crate) async fn deploy_dns( // Next, construct the DNS config represented by the blueprint. let internal_dns_zone_blueprint = - blueprint_internal_dns_config(blueprint, sleds_by_id, overrides)?; + blueprint_internal_dns_config(blueprint, sleds_by_id, overrides) + .map_err(|e| Error::InternalError { + internal_message: e.to_string(), + })?; let silos = datastore .silo_list_all_batched(opctx, Discoverability::All) .await @@ -245,171 +240,6 @@ pub(crate) async fn deploy_dns_one( datastore.dns_update_from_version(opctx, update, generation).await } -/// Returns the expected contents of internal DNS based on the given blueprint -pub fn blueprint_internal_dns_config( - blueprint: &Blueprint, - sleds_by_id: &BTreeMap, - overrides: &Overridables, -) -> Result { - // The DNS names configured here should match what RSS configures for the - // same zones. It's tricky to have RSS share the same code because it uses - // Sled Agent's _internal_ `OmicronZoneConfig` (and friends), whereas we're - // using `sled-agent-client`'s version of that type. However, the - // DnsConfigBuilder's interface is high-level enough that it handles most of - // the details. - let mut dns_builder = DnsConfigBuilder::new(); - - 'all_zones: for (_, zone) in - blueprint.all_omicron_zones(BlueprintZoneFilter::ShouldBeInInternalDns) - { - let (service_name, port) = match &zone.zone_type { - BlueprintZoneType::BoundaryNtp( - blueprint_zone_type::BoundaryNtp { address, .. }, - ) => (ServiceName::BoundaryNtp, address.port()), - BlueprintZoneType::InternalNtp( - blueprint_zone_type::InternalNtp { address, .. }, - ) => (ServiceName::InternalNtp, address.port()), - BlueprintZoneType::Clickhouse( - blueprint_zone_type::Clickhouse { address, .. }, - ) - | BlueprintZoneType::ClickhouseServer( - blueprint_zone_type::ClickhouseServer { address, .. }, - ) => { - // Add the HTTP and native TCP interfaces for ClickHouse data - // replicas. This adds the zone itself, so we need to continue - // back up to the loop over all the Omicron zones, rather than - // falling through to call `host_zone_with_one_backend()`. - let http_service = if matches!( - &zone.zone_type, - BlueprintZoneType::Clickhouse(_) - ) { - ServiceName::Clickhouse - } else { - ServiceName::ClickhouseServer - }; - dns_builder - .host_zone_clickhouse( - zone.id, - zone.underlay_address, - http_service, - address.port(), - ) - .map_err(|e| Error::InternalError { - internal_message: e.to_string(), - })?; - continue 'all_zones; - } - BlueprintZoneType::ClickhouseKeeper( - blueprint_zone_type::ClickhouseKeeper { address, .. }, - ) => { - // Add the Clickhouse keeper service and `clickhouse-admin` - // service used for managing the keeper. We continue below so we - // don't fall through and call `host_zone_with_one_backend`. - dns_builder - .host_zone_clickhouse_keeper( - zone.id, - zone.underlay_address, - ServiceName::ClickhouseKeeper, - address.port(), - ) - .map_err(|e| Error::InternalError { - internal_message: e.to_string(), - })?; - continue 'all_zones; - } - BlueprintZoneType::CockroachDb( - blueprint_zone_type::CockroachDb { address, .. }, - ) => (ServiceName::Cockroach, address.port()), - BlueprintZoneType::Nexus(blueprint_zone_type::Nexus { - internal_address, - .. - }) => (ServiceName::Nexus, internal_address.port()), - BlueprintZoneType::Crucible(blueprint_zone_type::Crucible { - address, - .. - }) => (ServiceName::Crucible(zone.id), address.port()), - BlueprintZoneType::CruciblePantry( - blueprint_zone_type::CruciblePantry { address }, - ) => (ServiceName::CruciblePantry, address.port()), - BlueprintZoneType::Oximeter(blueprint_zone_type::Oximeter { - address, - }) => (ServiceName::Oximeter, address.port()), - BlueprintZoneType::ExternalDns( - blueprint_zone_type::ExternalDns { http_address, .. }, - ) => (ServiceName::ExternalDns, http_address.port()), - BlueprintZoneType::InternalDns( - blueprint_zone_type::InternalDns { http_address, .. }, - ) => (ServiceName::InternalDns, http_address.port()), - }; - dns_builder - .host_zone_with_one_backend( - zone.id, - zone.underlay_address, - service_name, - port, - ) - .map_err(|e| Error::InternalError { - internal_message: e.to_string(), - })?; - } - - let scrimlets = sleds_by_id.values().filter(|sled| sled.is_scrimlet); - for scrimlet in scrimlets { - let sled_subnet = scrimlet.subnet(); - let switch_zone_ip = overrides.switch_zone_ip(scrimlet.id, sled_subnet); - dns_builder - .host_zone_switch( - scrimlet.id, - switch_zone_ip, - overrides.dendrite_port(scrimlet.id), - overrides.mgs_port(scrimlet.id), - overrides.mgd_port(scrimlet.id), - ) - .map_err(|e| Error::InternalError { - internal_message: e.to_string(), - })?; - } - - Ok(dns_builder.build_zone()) -} - -pub fn blueprint_external_dns_config( - blueprint: &Blueprint, - silos: &[Name], - external_dns_zone_name: String, -) -> DnsConfigZone { - let nexus_external_ips = blueprint_nexus_external_ips(blueprint); - - let dns_records: Vec = nexus_external_ips - .into_iter() - .map(|addr| match addr { - IpAddr::V4(addr) => DnsRecord::A(addr), - IpAddr::V6(addr) => DnsRecord::Aaaa(addr), - }) - .collect(); - - let records = silos - .into_iter() - // We do not generate a DNS name for the "default" Silo. - // - // We use the name here rather than the id. It shouldn't really matter - // since every system will have this silo and so no other Silo could - // have this name. But callers (particularly the test suite and - // reconfigurator-cli) specify silos by name, not id, so if we used the - // id here then they'd have to apply this filter themselves (and this - // abstraction, such as it is, would be leakier). - .filter_map(|silo_name| { - (silo_name != DEFAULT_SILO.name()) - .then(|| (silo_dns_name(&silo_name), dns_records.clone())) - }) - .collect::>>(); - - DnsConfigZone { - zone_name: external_dns_zone_name, - records: records.clone(), - } -} - fn dns_compute_update( log: &slog::Logger, dns_group: DnsGroup, @@ -468,35 +298,10 @@ fn dns_compute_update( Ok(Some(update)) } -/// Returns the (relative) DNS name for this Silo's API and console endpoints -/// _within_ the external DNS zone (i.e., without that zone's suffix) -/// -/// This specific naming scheme is determined under RFD 357. -pub fn silo_dns_name(name: &omicron_common::api::external::Name) -> String { - // RFD 4 constrains resource names (including Silo names) to DNS-safe - // strings, which is why it's safe to directly put the name of the - // resource into the DNS name rather than doing any kind of escaping. - format!("{}.sys", name) -} - -/// Return the Nexus external addresses according to the given blueprint -pub fn blueprint_nexus_external_ips(blueprint: &Blueprint) -> Vec { - blueprint - .all_omicron_zones(BlueprintZoneFilter::ShouldBeExternallyReachable) - .filter_map(|(_, z)| match z.zone_type { - BlueprintZoneType::Nexus(blueprint_zone_type::Nexus { - external_ip, - .. - }) => Some(external_ip.ip), - _ => None, - }) - .collect() -} - #[cfg(test)] mod test { use super::*; - use crate::overridables::Overridables; + use crate::test_utils::overridables_for_test; use crate::test_utils::realize_blueprint_and_expect; use crate::Sled; use dns_service_client::DnsDiff; @@ -520,14 +325,18 @@ mod test { use nexus_reconfigurator_preparation::PlanningInputFromDb; use nexus_sled_agent_shared::inventory::OmicronZoneConfig; use nexus_sled_agent_shared::inventory::OmicronZoneType; + use nexus_sled_agent_shared::inventory::SledRole; use nexus_sled_agent_shared::inventory::ZoneKind; use nexus_test_utils::resource_helpers::create_silo; use nexus_test_utils::resource_helpers::DiskTestBuilder; use nexus_test_utils_macros::nexus_test; + use nexus_types::deployment::blueprint_zone_type; use nexus_types::deployment::Blueprint; use nexus_types::deployment::BlueprintTarget; use nexus_types::deployment::BlueprintZoneConfig; use nexus_types::deployment::BlueprintZoneDisposition; + use nexus_types::deployment::BlueprintZoneFilter; + use nexus_types::deployment::BlueprintZoneType; use nexus_types::deployment::BlueprintZonesConfig; use nexus_types::deployment::CockroachDbClusterVersion; use nexus_types::deployment::CockroachDbPreserveDowngrade; @@ -544,6 +353,7 @@ mod test { use nexus_types::internal_api::params::DnsConfigZone; use nexus_types::internal_api::params::DnsRecord; use nexus_types::internal_api::params::Srv; + use nexus_types::silo::silo_dns_name; use omicron_common::address::get_sled_address; use omicron_common::address::get_switch_zone_address; use omicron_common::address::IpRange; @@ -904,15 +714,13 @@ mod test { .zip(possible_sled_subnets) .enumerate() .map(|(i, (sled_id, subnet))| { - let sled_info = Sled { - id: *sled_id, - sled_agent_address: get_sled_address(Ipv6Subnet::new( - subnet.network(), - )), + let sled_info = Sled::new( + *sled_id, + get_sled_address(Ipv6Subnet::new(subnet.network())), // The first two of these (arbitrarily) will be marked // Scrimlets. - is_scrimlet: i < 2, - }; + if i < 2 { SledRole::Scrimlet } else { SledRole::Gimlet }, + ); (*sled_id, sled_info) }) .collect(); @@ -969,7 +777,7 @@ mod test { let mut switch_sleds_by_ip: BTreeMap<_, _> = sleds_by_id .iter() .filter_map(|(sled_id, sled)| { - if sled.is_scrimlet { + if sled.is_scrimlet() { let sled_subnet = sleds_by_id.get(sled_id).unwrap().subnet(); let switch_zone_ip = get_switch_zone_address(sled_subnet); @@ -1495,7 +1303,7 @@ mod test { .await; // Now, execute the initial blueprint. - let overrides = Overridables::for_test(cptestctx); + let overrides = overridables_for_test(cptestctx); _ = realize_blueprint_and_expect( &opctx, datastore, resolver, &blueprint, &overrides, ) diff --git a/nexus/reconfigurator/execution/src/lib.rs b/nexus/reconfigurator/execution/src/lib.rs index ad2d2cc7cc..e46eda470f 100644 --- a/nexus/reconfigurator/execution/src/lib.rs +++ b/nexus/reconfigurator/execution/src/lib.rs @@ -16,17 +16,13 @@ use nexus_types::deployment::BlueprintZoneFilter; use nexus_types::deployment::SledFilter; use nexus_types::external_api::views::SledState; use nexus_types::identity::Asset; -use omicron_common::address::Ipv6Subnet; -use omicron_common::address::SLED_PREFIX; use omicron_physical_disks::DeployDisksDone; use omicron_uuid_kinds::GenericUuid; use omicron_uuid_kinds::OmicronZoneUuid; use omicron_uuid_kinds::SledUuid; -use overridables::Overridables; use slog::info; use slog_error_chain::InlineErrorChain; use std::collections::BTreeMap; -use std::net::SocketAddrV6; use std::sync::Arc; use tokio::sync::mpsc; use update_engine::merge_anyhow_list; @@ -37,47 +33,11 @@ mod datasets; mod dns; mod omicron_physical_disks; mod omicron_zones; -mod overridables; mod sagas; mod sled_state; #[cfg(test)] mod test_utils; -pub use dns::blueprint_external_dns_config; -pub use dns::blueprint_internal_dns_config; -pub use dns::blueprint_nexus_external_ips; -pub use dns::silo_dns_name; - -pub struct Sled { - id: SledUuid, - sled_agent_address: SocketAddrV6, - is_scrimlet: bool, -} - -impl Sled { - pub fn new( - id: SledUuid, - sled_agent_address: SocketAddrV6, - is_scrimlet: bool, - ) -> Sled { - Sled { id, sled_agent_address, is_scrimlet } - } - - pub(crate) fn subnet(&self) -> Ipv6Subnet { - Ipv6Subnet::::new(*self.sled_agent_address.ip()) - } -} - -impl From for Sled { - fn from(value: nexus_db_model::Sled) -> Self { - Sled { - id: SledUuid::from_untyped_uuid(value.id()), - sled_agent_address: value.address(), - is_scrimlet: value.is_scrimlet(), - } - } -} - /// The result of calling [`realize_blueprint`] or /// [`realize_blueprint_with_overrides`]. #[derive(Debug)] @@ -286,7 +246,7 @@ fn register_sled_list_step<'a>( .map(|db_sled| { ( SledUuid::from_untyped_uuid(db_sled.id()), - Sled::from(db_sled), + db_sled.into(), ) }) .collect(); diff --git a/nexus/reconfigurator/execution/src/omicron_physical_disks.rs b/nexus/reconfigurator/execution/src/omicron_physical_disks.rs index 14af55fee6..895b7a2d9d 100644 --- a/nexus/reconfigurator/execution/src/omicron_physical_disks.rs +++ b/nexus/reconfigurator/execution/src/omicron_physical_disks.rs @@ -44,7 +44,7 @@ pub(crate) async fn deploy_disks( let client = nexus_networking::sled_client_from_address( sled_id.into_untyped_uuid(), - db_sled.sled_agent_address, + db_sled.sled_agent_address(), &log, ); let result = @@ -143,6 +143,7 @@ mod test { use nexus_db_model::Zpool; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; + use nexus_sled_agent_shared::inventory::SledRole; use nexus_test_utils::SLED_AGENT_UUID; use nexus_test_utils_macros::nexus_test; use nexus_types::deployment::{ @@ -217,11 +218,7 @@ mod test { let SocketAddr::V6(addr) = server.addr() else { panic!("Expected Ipv6 address. Got {}", server.addr()); }; - let sled = Sled { - id: sled_id, - sled_agent_address: addr, - is_scrimlet: false, - }; + let sled = Sled::new(sled_id, addr, SledRole::Gimlet); (sled_id, sled) }) .collect(); diff --git a/nexus/reconfigurator/execution/src/omicron_zones.rs b/nexus/reconfigurator/execution/src/omicron_zones.rs index 78934a96af..b42ce32f76 100644 --- a/nexus/reconfigurator/execution/src/omicron_zones.rs +++ b/nexus/reconfigurator/execution/src/omicron_zones.rs @@ -62,7 +62,7 @@ pub(crate) async fn deploy_zones( let client = nexus_networking::sled_client_from_address( sled_id.into_untyped_uuid(), - db_sled.sled_agent_address, + db_sled.sled_agent_address(), &opctx.log, ); let omicron_zones = config @@ -350,7 +350,7 @@ mod test { use httptest::responders::{json_encoded, status_code}; use httptest::Expectation; use nexus_sled_agent_shared::inventory::{ - OmicronZoneDataset, OmicronZonesConfig, + OmicronZoneDataset, OmicronZonesConfig, SledRole, }; use nexus_test_utils_macros::nexus_test; use nexus_types::deployment::{ @@ -420,11 +420,7 @@ mod test { let SocketAddr::V6(addr) = server.addr() else { panic!("Expected Ipv6 address. Got {}", server.addr()); }; - let sled = Sled { - id: sled_id, - sled_agent_address: addr, - is_scrimlet: false, - }; + let sled = Sled::new(sled_id, addr, SledRole::Gimlet); (sled_id, sled) }) .collect(); diff --git a/nexus/reconfigurator/execution/src/test_utils.rs b/nexus/reconfigurator/execution/src/test_utils.rs index 3f623af6c4..9d48d52049 100644 --- a/nexus/reconfigurator/execution/src/test_utils.rs +++ b/nexus/reconfigurator/execution/src/test_utils.rs @@ -4,13 +4,18 @@ //! Test utilities for reconfigurator execution. +use std::net::Ipv6Addr; + use internal_dns::resolver::Resolver; use nexus_db_queries::{context::OpContext, db::DataStore}; -use nexus_types::deployment::{execution::EventBuffer, Blueprint}; +use nexus_types::deployment::{ + execution::{EventBuffer, Overridables}, + Blueprint, +}; use omicron_uuid_kinds::OmicronZoneUuid; use update_engine::TerminalKind; -use crate::{overridables::Overridables, RealizeBlueprintOutput}; +use crate::RealizeBlueprintOutput; pub(crate) async fn realize_blueprint_and_expect( opctx: &OpContext, @@ -63,3 +68,37 @@ pub(crate) async fn realize_blueprint_and_expect( (output, buffer) } + +/// Generates a set of overrides describing the simulated test environment. +pub fn overridables_for_test( + cptestctx: &nexus_test_utils::ControlPlaneTestContext< + omicron_nexus::Server, + >, +) -> Overridables { + use omicron_common::api::external::SwitchLocation; + + let mut overrides = Overridables::default(); + let scrimlets = [ + (nexus_test_utils::SLED_AGENT_UUID, SwitchLocation::Switch0), + (nexus_test_utils::SLED_AGENT2_UUID, SwitchLocation::Switch1), + ]; + for (id_str, switch_location) in scrimlets { + let sled_id = id_str.parse().unwrap(); + let ip = Ipv6Addr::LOCALHOST; + let mgs_port = cptestctx + .gateway + .get(&switch_location) + .unwrap() + .client + .bind_address + .port(); + let dendrite_port = + cptestctx.dendrite.get(&switch_location).unwrap().port; + let mgd_port = cptestctx.mgd.get(&switch_location).unwrap().port; + overrides.override_switch_zone_ip(sled_id, ip); + overrides.override_dendrite_port(sled_id, dendrite_port); + overrides.override_mgs_port(sled_id, mgs_port); + overrides.override_mgd_port(sled_id, mgd_port); + } + overrides +} diff --git a/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs b/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs index bf9decc373..7bd2142b5d 100644 --- a/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs +++ b/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs @@ -1646,9 +1646,8 @@ impl<'a> BlueprintBuilder<'a> { /// ordinarily only come from RSS. /// /// TODO-cleanup: Remove when external DNS addresses are in the policy. - #[cfg(test)] #[track_caller] - pub fn add_external_dns_ip(&mut self, addr: IpAddr) { + pub(crate) fn add_external_dns_ip(&mut self, addr: IpAddr) { self.external_networking() .expect("failed to initialize external networking allocator") .add_external_dns_ip(addr); diff --git a/nexus/reconfigurator/planning/src/blueprint_builder/external_networking.rs b/nexus/reconfigurator/planning/src/blueprint_builder/external_networking.rs index 9cab099fcb..2b6c564275 100644 --- a/nexus/reconfigurator/planning/src/blueprint_builder/external_networking.rs +++ b/nexus/reconfigurator/planning/src/blueprint_builder/external_networking.rs @@ -371,8 +371,7 @@ impl<'a> BuilderExternalNetworking<'a> { /// which could otherwise only be added via RSS. /// /// TODO-cleanup: Remove when external DNS addresses are in the policy. - #[cfg(test)] - pub fn add_external_dns_ip(&mut self, addr: IpAddr) { + pub(crate) fn add_external_dns_ip(&mut self, addr: IpAddr) { assert!( self.available_external_dns_ips.insert(addr), "duplicate external DNS IP address" diff --git a/nexus/reconfigurator/planning/src/example.rs b/nexus/reconfigurator/planning/src/example.rs index e0081c844d..c5ad4bf791 100644 --- a/nexus/reconfigurator/planning/src/example.rs +++ b/nexus/reconfigurator/planning/src/example.rs @@ -4,6 +4,9 @@ //! Example blueprints +use std::net::IpAddr; +use std::net::Ipv4Addr; + use crate::blueprint_builder::BlueprintBuilder; use crate::system::SledBuilder; use crate::system::SystemDescription; @@ -53,6 +56,10 @@ pub struct ExampleSystemBuilder { test_name: String, nsleds: usize, ndisks_per_sled: u8, + // None means nsleds + nexus_count: Option, + internal_dns_count: ZoneCount, + external_dns_count: ZoneCount, create_zones: bool, create_disks_in_blueprint: bool, } @@ -61,12 +68,21 @@ impl ExampleSystemBuilder { /// The default number of sleds in the example system. pub const DEFAULT_N_SLEDS: usize = 3; + /// The default number of external DNS instances in the example system. + /// + /// The default value is picked for backwards compatibility -- we may wish + /// to revisit it in the future. + pub const DEFAULT_EXTERNAL_DNS_COUNT: usize = 0; + pub fn new(log: &slog::Logger, test_name: &str) -> Self { Self { log: log.new(slog::o!("component" => "ExampleSystem", "test_name" => test_name.to_string())), test_name: test_name.to_string(), nsleds: Self::DEFAULT_N_SLEDS, ndisks_per_sled: SledBuilder::DEFAULT_NPOOLS, + nexus_count: None, + internal_dns_count: ZoneCount(INTERNAL_DNS_REDUNDANCY), + external_dns_count: ZoneCount(Self::DEFAULT_EXTERNAL_DNS_COUNT), create_zones: true, create_disks_in_blueprint: true, } @@ -85,11 +101,66 @@ impl ExampleSystemBuilder { /// /// The default value is [`SledBuilder::DEFAULT_NPOOLS`]. A value of 0 is /// permitted. + /// + /// If [`Self::create_zones`] is set to `false`, this is ignored. pub fn ndisks_per_sled(mut self, ndisks_per_sled: u8) -> Self { self.ndisks_per_sled = ndisks_per_sled; self } + /// Set the number of Nexus instances in the example system. + /// + /// The default value is the same as the number of sleds (i.e. one Nexus + /// instance per sled). A value of 0 is permitted. + /// + /// If [`Self::create_zones`] is set to `false`, this is ignored. + pub fn nexus_count(mut self, nexus_count: usize) -> Self { + self.nexus_count = Some(ZoneCount(nexus_count)); + self + } + + /// Set the number of internal DNS instances in the example system. + /// + /// The default value is [`INTERNAL_DNS_REDUNDANCY`]. A value anywhere + /// between 0 and [`INTERNAL_DNS_REDUNDANCY`], inclusive, is permitted. + /// + /// If [`Self::create_zones`] is set to `false`, this is ignored. + pub fn internal_dns_count( + mut self, + internal_dns_count: usize, + ) -> anyhow::Result { + if internal_dns_count > INTERNAL_DNS_REDUNDANCY { + anyhow::bail!( + "internal_dns_count {} is greater than INTERNAL_DNS_REDUNDANCY {}", + internal_dns_count, + INTERNAL_DNS_REDUNDANCY, + ); + } + self.internal_dns_count = ZoneCount(internal_dns_count); + Ok(self) + } + + /// Set the number of external DNS instances in the example system. + /// + /// The default value is [`Self::DEFAULT_EXTERNAL_DNS_COUNT`]. A value + /// anywhere between 0 and 30, inclusive, is permitted. (The limit of 30 is + /// primarily to simplify the implementation.) + /// + /// Each DNS server is assigned an address in the 10.x.x.x range. + pub fn external_dns_count( + mut self, + external_dns_count: usize, + ) -> anyhow::Result { + if external_dns_count > 30 { + anyhow::bail!( + "external_dns_count {} is greater than 30", + external_dns_count, + ); + } + self.external_dns_count = ZoneCount(external_dns_count); + Ok(self) + } + /// Create zones in the example system. /// /// The default is `true`. @@ -109,20 +180,34 @@ impl ExampleSystemBuilder { self } + fn get_nexus_zones(&self) -> ZoneCount { + self.nexus_count.unwrap_or(ZoneCount(self.nsleds)) + } + /// Create a new example system with the given modifications. /// /// Return the system, and the initial blueprint that matches it. pub fn build(&self) -> (ExampleSystem, Blueprint) { + let nexus_count = self.get_nexus_zones(); + slog::info!( &self.log, "Creating example system"; "nsleds" => self.nsleds, "ndisks_per_sled" => self.ndisks_per_sled, + "nexus_count" => nexus_count.0, + "internal_dns_count" => self.internal_dns_count.0, + "external_dns_count" => self.external_dns_count.0, "create_zones" => self.create_zones, "create_disks_in_blueprint" => self.create_disks_in_blueprint, ); let mut system = SystemDescription::new(); + // Update the system's target counts with the counts. (Note that + // there's no external DNS count.) + system + .target_nexus_zone_count(nexus_count.0) + .target_internal_dns_zone_count(self.internal_dns_count.0); let mut sled_rng = TypedUuidRng::from_seed(&self.test_name, "ExampleSystem"); let sled_ids: Vec<_> = @@ -166,6 +251,18 @@ impl ExampleSystemBuilder { ) .unwrap(); builder.set_rng_seed((&self.test_name, "ExampleSystem make_zones")); + + // Add as many external IPs as is necessary for external DNS zones. We + // pick a start address arbitrarily in the 10.x.x.x range. + for i in 0..self.external_dns_count.0 { + builder.add_external_dns_ip(IpAddr::V4(Ipv4Addr::new( + 10, + 49, + 0, + (i + 1).try_into().expect("external_dns_count is always <= 30"), + ))); + } + for (i, (sled_id, sled_resources)) in base_input.all_sled_resources(SledFilter::Commissioned).enumerate() { @@ -174,16 +271,23 @@ impl ExampleSystemBuilder { let _ = builder .sled_ensure_zone_multiple_nexus_with_config( sled_id, - 1, + nexus_count.on(i, self.nsleds), false, vec![], ) .unwrap(); - if i < INTERNAL_DNS_REDUNDANCY { - let _ = builder - .sled_ensure_zone_multiple_internal_dns(sled_id, 1) - .unwrap(); - } + let _ = builder + .sled_ensure_zone_multiple_internal_dns( + sled_id, + self.internal_dns_count.on(i, self.nsleds), + ) + .unwrap(); + let _ = builder + .sled_ensure_zone_multiple_external_dns( + sled_id, + self.external_dns_count.on(i, self.nsleds), + ) + .unwrap(); } if self.create_disks_in_blueprint { let _ = @@ -255,3 +359,164 @@ impl ExampleSystemBuilder { (example, blueprint) } } + +// A little wrapper to try and avoid having an `on` function which takes 3 +// usize parameters. +#[derive(Clone, Copy, Debug)] +struct ZoneCount(usize); + +impl ZoneCount { + fn on(self, sled_id: usize, total_sleds: usize) -> usize { + // Spread instances out as evenly as possible. If there are 5 sleds and 3 + // instances, we want to spread them out as 2, 2, 1. + let div = self.0 / total_sleds; + let rem = self.0 % total_sleds; + div + if sled_id < rem { 1 } else { 0 } + } +} + +#[cfg(test)] +mod tests { + use chrono::{NaiveDateTime, TimeZone, Utc}; + use nexus_sled_agent_shared::inventory::{OmicronZoneConfig, ZoneKind}; + use nexus_types::deployment::BlueprintZoneConfig; + use omicron_test_utils::dev::test_setup_log; + + use super::*; + + #[test] + fn instances_on_examples() { + assert_eq!(ZoneCount(3).on(0, 5), 1); + assert_eq!(ZoneCount(3).on(1, 5), 1); + assert_eq!(ZoneCount(3).on(2, 5), 1); + assert_eq!(ZoneCount(3).on(3, 5), 0); + assert_eq!(ZoneCount(3).on(4, 5), 0); + + assert_eq!(ZoneCount(5).on(0, 5), 1); + assert_eq!(ZoneCount(5).on(1, 5), 1); + assert_eq!(ZoneCount(5).on(2, 5), 1); + assert_eq!(ZoneCount(5).on(3, 5), 1); + assert_eq!(ZoneCount(5).on(4, 5), 1); + + assert_eq!(ZoneCount(7).on(0, 5), 2); + assert_eq!(ZoneCount(7).on(1, 5), 2); + assert_eq!(ZoneCount(7).on(2, 5), 1); + assert_eq!(ZoneCount(6).on(3, 5), 1); + assert_eq!(ZoneCount(6).on(4, 5), 1); + } + + #[test] + fn builder_zone_counts() { + static TEST_NAME: &str = "example_builder_zone_counts"; + let logctx = test_setup_log(TEST_NAME); + + let (example, mut blueprint) = + ExampleSystemBuilder::new(&logctx.log, TEST_NAME) + .nsleds(5) + .nexus_count(6) + .internal_dns_count(2) + .unwrap() + .external_dns_count(10) + .unwrap() + .build(); + + // Define a time_created for consistent output across runs. + blueprint.time_created = + Utc.from_utc_datetime(&NaiveDateTime::UNIX_EPOCH); + + expectorate::assert_contents( + "tests/output/example_builder_zone_counts_blueprint.txt", + &blueprint.display().to_string(), + ); + + // Check that the system's target counts are set correctly. + assert_eq!(example.system.get_target_nexus_zone_count(), 6); + assert_eq!(example.system.get_target_internal_dns_zone_count(), 2); + + // Check that the right number of internal and external DNS zones are + // present in both the blueprint and in the collection. + let nexus_zones = blueprint_zones_of_kind(&blueprint, ZoneKind::Nexus); + assert_eq!( + nexus_zones.len(), + 6, + "expected 6 Nexus zones in blueprint, got {}: {:#?}", + nexus_zones.len(), + nexus_zones, + ); + let nexus_zones = + collection_zones_of_kind(&example.collection, ZoneKind::Nexus); + assert_eq!( + nexus_zones.len(), + 6, + "expected 6 Nexus zones in collection, got {}: {:#?}", + nexus_zones.len(), + nexus_zones, + ); + + let internal_dns_zones = + blueprint_zones_of_kind(&blueprint, ZoneKind::InternalDns); + assert_eq!( + internal_dns_zones.len(), + 2, + "expected 2 internal DNS zones in blueprint, got {}: {:#?}", + internal_dns_zones.len(), + internal_dns_zones, + ); + let internal_dns_zones = collection_zones_of_kind( + &example.collection, + ZoneKind::InternalDns, + ); + assert_eq!( + internal_dns_zones.len(), + 2, + "expected 2 internal DNS zones in collection, got {}: {:#?}", + internal_dns_zones.len(), + internal_dns_zones, + ); + + let external_dns_zones = + blueprint_zones_of_kind(&blueprint, ZoneKind::ExternalDns); + assert_eq!( + external_dns_zones.len(), + 10, + "expected 10 external DNS zones in blueprint, got {}: {:#?}", + external_dns_zones.len(), + external_dns_zones, + ); + let external_dns_zones = collection_zones_of_kind( + &example.collection, + ZoneKind::ExternalDns, + ); + assert_eq!( + external_dns_zones.len(), + 10, + "expected 10 external DNS zones in collection, got {}: {:#?}", + external_dns_zones.len(), + external_dns_zones, + ); + + logctx.cleanup_successful(); + } + + fn blueprint_zones_of_kind( + blueprint: &Blueprint, + kind: ZoneKind, + ) -> Vec<&BlueprintZoneConfig> { + blueprint + .all_omicron_zones(BlueprintZoneFilter::All) + .filter_map(|(_, zone)| { + (zone.zone_type.kind() == kind).then_some(zone) + }) + .collect() + } + + fn collection_zones_of_kind( + collection: &Collection, + kind: ZoneKind, + ) -> Vec<&OmicronZoneConfig> { + collection + .all_omicron_zones() + .filter(|zone| zone.zone_type.kind() == kind) + .collect() + } +} diff --git a/nexus/reconfigurator/planning/src/planner.rs b/nexus/reconfigurator/planning/src/planner.rs index 426b779789..22a53f8e74 100644 --- a/nexus/reconfigurator/planning/src/planner.rs +++ b/nexus/reconfigurator/planning/src/planner.rs @@ -802,7 +802,6 @@ mod test { use nexus_types::deployment::CockroachDbClusterVersion; use nexus_types::deployment::CockroachDbPreserveDowngrade; use nexus_types::deployment::CockroachDbSettings; - use nexus_types::deployment::OmicronZoneNetworkResources; use nexus_types::deployment::SledDisk; use nexus_types::external_api::views::PhysicalDiskPolicy; use nexus_types::external_api::views::PhysicalDiskState; @@ -813,13 +812,11 @@ mod test { use omicron_common::api::external::Generation; use omicron_common::disk::DiskIdentity; use omicron_test_utils::dev::test_setup_log; - use omicron_uuid_kinds::GenericUuid; use omicron_uuid_kinds::PhysicalDiskUuid; use omicron_uuid_kinds::SledUuid; use omicron_uuid_kinds::ZpoolUuid; use std::collections::BTreeSet; use std::collections::HashMap; - use std::mem; use std::net::IpAddr; use typed_rng::TypedUuidRng; @@ -1008,69 +1005,16 @@ mod test { static TEST_NAME: &str = "planner_add_multiple_nexus_to_one_sled"; let logctx = test_setup_log(TEST_NAME); - // Use our example system as a starting point, but strip it down to - // just one sled. - // - // An alternative here would be to pass in nsleds = 1 rather than - // DEFAULT_N_SLEDS, but that would cause multiple Nexuses to be added - // to the one sled within the example system. Instead, we want there to - // be _one_ Nexus on the one sled, and then add more Nexuses to that - // within this test. - let (sled_id, blueprint1, collection, input) = { - let (mut collection, input, mut blueprint) = - example(&logctx.log, TEST_NAME); - - // Pick one sled ID to keep and remove the rest. - let mut builder = input.into_builder(); - let keep_sled_id = - builder.sleds().keys().next().copied().expect("no sleds"); - builder.sleds_mut().retain(|&k, _v| keep_sled_id == k); - collection.sled_agents.retain(|&k, _v| keep_sled_id == k); - collection.omicron_zones.retain(|&k, _v| keep_sled_id == k); - - assert_eq!(collection.sled_agents.len(), 1); - assert_eq!(collection.omicron_zones.len(), 1); - blueprint.blueprint_zones.retain(|k, _v| keep_sled_id == *k); - blueprint.blueprint_disks.retain(|k, _v| keep_sled_id == *k); - - // Also remove all the networking resources for the zones we just - // stripped out; i.e., only keep those for `keep_sled_id`. - let mut new_network_resources = OmicronZoneNetworkResources::new(); - let old_network_resources = builder.network_resources_mut(); - for old_ip in old_network_resources.omicron_zone_external_ips() { - if blueprint.all_omicron_zones(BlueprintZoneFilter::All).any( - |(_, zone)| { - zone.zone_type - .external_networking() - .map(|(ip, _nic)| ip.id() == old_ip.ip.id()) - .unwrap_or(false) - }, - ) { - new_network_resources - .add_external_ip(old_ip.zone_id, old_ip.ip) - .expect("copied IP to new input"); - } - } - for old_nic in old_network_resources.omicron_zone_nics() { - if blueprint.all_omicron_zones(BlueprintZoneFilter::All).any( - |(_, zone)| { - zone.zone_type - .external_networking() - .map(|(_ip, nic)| { - nic.id == old_nic.nic.id.into_untyped_uuid() - }) - .unwrap_or(false) - }, - ) { - new_network_resources - .add_nic(old_nic.zone_id, old_nic.nic) - .expect("copied NIC to new input"); - } - } - mem::swap(old_network_resources, &mut &mut new_network_resources); - - (keep_sled_id, blueprint, collection, builder.build()) - }; + // Use our example system with one sled and one Nexus instance as a + // starting point. + let (example, blueprint1) = + ExampleSystemBuilder::new(&logctx.log, TEST_NAME) + .nsleds(1) + .nexus_count(1) + .build(); + let sled_id = *example.collection.sled_agents.keys().next().unwrap(); + let input = example.input; + let collection = example.collection; // This blueprint should only have 1 Nexus instance on the one sled we // kept. diff --git a/nexus/reconfigurator/planning/src/system.rs b/nexus/reconfigurator/planning/src/system.rs index d0d10bbe3e..f3ee40a00e 100644 --- a/nexus/reconfigurator/planning/src/system.rs +++ b/nexus/reconfigurator/planning/src/system.rs @@ -207,6 +207,22 @@ impl SystemDescription { self } + pub fn get_target_nexus_zone_count(&self) -> usize { + self.target_nexus_zone_count + } + + pub fn target_internal_dns_zone_count( + &mut self, + count: usize, + ) -> &mut Self { + self.target_internal_dns_zone_count = count; + self + } + + pub fn get_target_internal_dns_zone_count(&self) -> usize { + self.target_internal_dns_zone_count + } + pub fn service_ip_pool_ranges( &mut self, ranges: Vec, diff --git a/nexus/reconfigurator/planning/tests/output/example_builder_zone_counts_blueprint.txt b/nexus/reconfigurator/planning/tests/output/example_builder_zone_counts_blueprint.txt new file mode 100644 index 0000000000..e43c5e1d20 --- /dev/null +++ b/nexus/reconfigurator/planning/tests/output/example_builder_zone_counts_blueprint.txt @@ -0,0 +1,211 @@ +blueprint 4a0b8410-b14f-41e7-85e7-3c0fe7050ccc +parent: e35b2fdd-354d-48d9-acb5-703b2c269a54 + + sled: 0dbf1e39-e265-4071-a8df-6d1225b46694 (active) + + physical disks at generation 1: + ---------------------------------------------------------------------- + vendor model serial + ---------------------------------------------------------------------- + fake-vendor fake-model serial-2b9c7004-fa39-4cf0-ae41-c299d3191f26 + fake-vendor fake-model serial-3ad934d9-90ee-4805-881c-20108827773f + fake-vendor fake-model serial-69db5dd6-795e-4e04-bfb3-f51962c49853 + fake-vendor fake-model serial-8557a3fb-cc12-497f-86d2-9f1a463b3685 + fake-vendor fake-model serial-9bd3cc34-4891-4c28-a4de-c4fcf01b6215 + fake-vendor fake-model serial-9dafffa2-31b7-43c0-b673-0c946be799f0 + fake-vendor fake-model serial-9e626a52-b5f1-4776-9cb8-271848b9c651 + fake-vendor fake-model serial-a645a1ac-4c49-4c7e-ba53-3dc60b737f06 + fake-vendor fake-model serial-b5ae209c-9226-44a0-8a6b-03b44f93d456 + fake-vendor fake-model serial-cd783b74-e400-41e0-9bb7-1d1d2f8958ce + + + omicron zones at generation 2: + ------------------------------------------------------------------------------------------ + zone type zone id disposition underlay IP + ------------------------------------------------------------------------------------------ + crucible 4f673614-7a9d-4860-859c-9627de33e03b in service fd00:1122:3344:105::2b + crucible 5002e44e-eef1-4f3c-81fc-78b62134400e in service fd00:1122:3344:105::26 + crucible 6422c22d-00bf-4826-9aeb-cf4e4dcae1c7 in service fd00:1122:3344:105::2d + crucible 85631c30-4b81-4a22-a0e5-e110034cc980 in service fd00:1122:3344:105::29 + crucible 9334f86c-6555-499a-9ad7-5acc987e2b87 in service fd00:1122:3344:105::2f + crucible a0624221-da2b-4f45-862e-effec567dcd1 in service fd00:1122:3344:105::2a + crucible a9980763-1f8c-452d-a542-551d1001131e in service fd00:1122:3344:105::27 + crucible c863bdbb-f270-47e1-bf7b-2220cf129266 in service fd00:1122:3344:105::28 + crucible d42c15ed-d303-43d4-b9e9-c5772505c2d7 in service fd00:1122:3344:105::2c + crucible d660e9f0-2f8f-4540-bd59-a32845d002ce in service fd00:1122:3344:105::2e + external_dns 82db7bcc-9e4c-418f-a46a-eb8ff561de7b in service fd00:1122:3344:105::25 + external_dns faac06c4-9aea-44a3-a94f-3da1adddb7b9 in service fd00:1122:3344:105::24 + internal_dns fadaa1c6-81a2-46ed-a10f-c42c29b85de9 in service fd00:1122:3344:1::1 + internal_ntp a3a3fccb-1127-4e61-9bdf-13eb58365a8a in service fd00:1122:3344:105::21 + nexus 1a741601-83b2-40b7-b59b-1a9b2c853411 in service fd00:1122:3344:105::23 + nexus a7743bca-5056-479f-9151-6f2288c0ae28 in service fd00:1122:3344:105::22 + + + + sled: 15cf73a6-445b-4d36-9232-5ed364019bc6 (active) + + physical disks at generation 1: + ---------------------------------------------------------------------- + vendor model serial + ---------------------------------------------------------------------- + fake-vendor fake-model serial-3cba16f1-1a3d-44e5-ba1d-e68cd2188615 + fake-vendor fake-model serial-3fc3ec87-1c39-4df8-99bf-30ca97ec5fac + fake-vendor fake-model serial-4c18c1af-dc1c-4de5-92a1-1b2923ea6a87 + fake-vendor fake-model serial-6f3a85db-de97-40d9-bf66-e6643ac1c114 + fake-vendor fake-model serial-96f39cf4-b2ac-413d-8f94-ba66b127cddd + fake-vendor fake-model serial-99c392f3-77b8-4f60-9efa-4efae0c92721 + fake-vendor fake-model serial-bc3195df-61ca-4111-863b-08b5cc243eab + fake-vendor fake-model serial-c787b52c-2cb8-4da2-a17a-128feb5eea0c + fake-vendor fake-model serial-d59d419e-c4d3-41ef-ab6d-0df3620dc84b + fake-vendor fake-model serial-dfaae221-11a9-4db0-b861-41fe5648f185 + + + omicron zones at generation 2: + ------------------------------------------------------------------------------------------ + zone type zone id disposition underlay IP + ------------------------------------------------------------------------------------------ + crucible 0dba037d-0b14-4e10-b430-c271f87d8e9a in service fd00:1122:3344:104::29 + crucible 10f24d62-dec3-4f6f-9f42-722763e1fcbd in service fd00:1122:3344:104::2d + crucible 313bb913-2e8b-4c27-89e6-79c92db8c03c in service fd00:1122:3344:104::28 + crucible 362b181b-452e-4f54-a42f-04bef00fa272 in service fd00:1122:3344:104::27 + crucible 60a0051f-d530-49e6-ab11-e2098856afba in service fd00:1122:3344:104::25 + crucible 69b59e77-9da3-49d3-bf83-a464570aea97 in service fd00:1122:3344:104::2a + crucible 7943dee3-d4ad-4ffb-93c7-2c1079e708a1 in service fd00:1122:3344:104::2e + crucible 8343556a-7827-4fdd-90df-a4b603b177cc in service fd00:1122:3344:104::26 + crucible b2f90d4d-34ff-4aae-8cfd-4773a30c372f in service fd00:1122:3344:104::2b + crucible f3c76e5a-779a-4c3c-87ce-dad309f612c4 in service fd00:1122:3344:104::2c + external_dns 1c0614f1-b653-43c2-b278-5372036a87c8 in service fd00:1122:3344:104::24 + external_dns 58d88005-e182-4463-96ed-9220e59facb7 in service fd00:1122:3344:104::23 + internal_dns 35a629e9-5140-48bf-975d-ce66d9c3be59 in service fd00:1122:3344:2::1 + internal_ntp c33f069b-e412-4309-a62b-e1cbef3ec234 in service fd00:1122:3344:104::21 + nexus 76edbb5e-7038-4160-833b-131abc2b2a12 in service fd00:1122:3344:104::22 + + + + sled: 50e6c1c0-43b2-4abc-9041-41165597f639 (active) + + physical disks at generation 1: + ---------------------------------------------------------------------- + vendor model serial + ---------------------------------------------------------------------- + fake-vendor fake-model serial-00fb9aa9-0bbf-49ab-a712-6e8feaf719e2 + fake-vendor fake-model serial-37f466d7-510b-40e4-b9a4-c5c092a6a5f6 + fake-vendor fake-model serial-734b7b3a-86af-48a7-bd00-8d79fa2690c3 + fake-vendor fake-model serial-747d2504-36a4-4acc-ad73-22291b5bbedb + fake-vendor fake-model serial-7dd422ab-4839-4a7a-8109-ba1941357c70 + fake-vendor fake-model serial-8b020037-bc77-48b2-9280-a622f571908b + fake-vendor fake-model serial-96753d7f-de6b-4ce6-a9dc-004f6a0ba0cf + fake-vendor fake-model serial-a0bd8e79-1113-4c40-8705-ed00e66f0c35 + fake-vendor fake-model serial-b30e150e-c83e-4c1e-b3bf-91a330d42135 + fake-vendor fake-model serial-ff911b9b-57a8-4318-a253-e2363b70083d + + + omicron zones at generation 2: + ------------------------------------------------------------------------------------------ + zone type zone id disposition underlay IP + ------------------------------------------------------------------------------------------ + crucible 234514a8-7a70-4dc5-905b-a29d1cfdee99 in service fd00:1122:3344:102::2c + crucible 29400193-6c20-4c41-8c9a-5259803c7bfd in service fd00:1122:3344:102::2b + crucible 31fdc4e5-25f2-42c5-8c2c-7f8bf3a0b89e in service fd00:1122:3344:102::26 + crucible 5895eb4f-7132-4530-8fc1-f9b719981856 in service fd00:1122:3344:102::25 + crucible a1a32afe-10db-4dbf-ac2d-6745f6f55417 in service fd00:1122:3344:102::2e + crucible a3333bac-4989-4d9a-8257-8c7a0614cef0 in service fd00:1122:3344:102::28 + crucible bec70cc9-82f9-42d3-935b-4f141c3c3503 in service fd00:1122:3344:102::2d + crucible de2023c8-6976-40fa-80d7-a8b0ea9546a1 in service fd00:1122:3344:102::2a + crucible e4aeecc2-f9ae-4b4f-963c-9c017e9df189 in service fd00:1122:3344:102::27 + crucible ed528efc-4d32-43cc-a0a2-b412693a7eca in service fd00:1122:3344:102::29 + external_dns 3c900bee-7455-4a41-8175-fe952484753c in service fd00:1122:3344:102::23 + external_dns cb4a2547-7798-48d2-839d-29f7d33d1486 in service fd00:1122:3344:102::24 + internal_ntp caf0bd1b-1da6-46b0-bb64-d6b780ad7a4c in service fd00:1122:3344:102::21 + nexus 68ff33cc-852b-4f2c-bc5c-9f7bdc32110e in service fd00:1122:3344:102::22 + + + + sled: 969ff976-df34-402c-a362-53db03a6b97f (active) + + physical disks at generation 1: + ---------------------------------------------------------------------- + vendor model serial + ---------------------------------------------------------------------- + fake-vendor fake-model serial-07444848-952b-4333-aa72-401c7bf5d724 + fake-vendor fake-model serial-242f8f98-fdc2-4ea9-ab69-e57b993df0df + fake-vendor fake-model serial-26cc7ce1-dc59-4398-8083-a4e1db957a46 + fake-vendor fake-model serial-3b757772-8c62-4543-a276-7c0051280687 + fake-vendor fake-model serial-981430ec-a43e-4418-bd2c-28db344c8b06 + fake-vendor fake-model serial-9dbfe441-887c-45d0-a3ed-7d8e1a63327f + fake-vendor fake-model serial-b37f5663-bedb-42a3-9b1a-5e417ee6c3d2 + fake-vendor fake-model serial-b48a178d-f7fd-4b50-811d-f7d195752710 + fake-vendor fake-model serial-be1784b0-017a-436f-8a6a-1884cddc5fa1 + fake-vendor fake-model serial-f9415bcf-5757-442a-a400-5a9ccfb5d80a + + + omicron zones at generation 2: + ------------------------------------------------------------------------------------------ + zone type zone id disposition underlay IP + ------------------------------------------------------------------------------------------ + crucible 0a6c78bb-f778-4b6d-9d20-370ae7c89135 in service fd00:1122:3344:103::2d + crucible 590907c2-e61e-4c2f-8a36-e705a24600c8 in service fd00:1122:3344:103::2b + crucible 983ed36f-baed-4dd1-bec7-4780f070eeee in service fd00:1122:3344:103::28 + crucible 9ff080b2-7bf9-4fe3-8d5f-367adb3525c8 in service fd00:1122:3344:103::29 + crucible c3b6651b-6a62-4292-972c-481390f4a044 in service fd00:1122:3344:103::2a + crucible e8bb3c35-b1ee-4171-b8ff-924e6a560fbf in service fd00:1122:3344:103::27 + crucible e8d99319-3796-4605-bd96-e17011d77016 in service fd00:1122:3344:103::25 + crucible ea723ef1-b23e-433d-bef5-90142476225d in service fd00:1122:3344:103::2c + crucible efa54182-a3e6-4600-9e88-044a6a8ae350 in service fd00:1122:3344:103::26 + crucible fbc67c83-773a-48ff-857c-61ddbf1ebf52 in service fd00:1122:3344:103::2e + external_dns 7cbc95ce-ab55-4b70-851d-33a0164ca362 in service fd00:1122:3344:103::23 + external_dns 7e6fa426-5200-47b4-b791-393dd17b09d9 in service fd00:1122:3344:103::24 + internal_ntp 0d5f20e4-fdca-4611-ac07-053bc28c5088 in service fd00:1122:3344:103::21 + nexus a16b5904-5ba8-42db-940c-8b852b052995 in service fd00:1122:3344:103::22 + + + + sled: ec5c0b37-b651-4c45-ac1c-24541ef9c44b (active) + + physical disks at generation 1: + ---------------------------------------------------------------------- + vendor model serial + ---------------------------------------------------------------------- + fake-vendor fake-model serial-148436fe-d3e9-4371-8d2e-ec950cc8a84c + fake-vendor fake-model serial-7dd076f1-9d62-49a8-bc0c-5ff5d045c917 + fake-vendor fake-model serial-a50f4bb9-d19a-4be8-ad49-b9a552a21062 + fake-vendor fake-model serial-b4ee33bb-03f1-4085-9830-9da92002a969 + fake-vendor fake-model serial-b50bec8b-a8d3-4ba6-ba3d-12c2a0da911c + fake-vendor fake-model serial-b64f79f6-188f-4e98-9eac-d8111673a130 + fake-vendor fake-model serial-c144a26e-f859-42a0-adca-00d9091d98e4 + fake-vendor fake-model serial-c45c08e4-aade-4333-9dad-935ccf4e8352 + fake-vendor fake-model serial-df62d5da-7da0-468b-b328-0fefbf57568b + fake-vendor fake-model serial-e6433ded-7c90-46a9-8bda-648bcc9fbf07 + + + omicron zones at generation 2: + ------------------------------------------------------------------------------------------ + zone type zone id disposition underlay IP + ------------------------------------------------------------------------------------------ + crucible 19faa2c3-b077-470a-a424-6821dd49bd11 in service fd00:1122:3344:101::25 + crucible 1b122e0d-8b22-464f-b1af-589246d636dc in service fd00:1122:3344:101::29 + crucible 25fb011b-ea9d-462c-a89e-5f7782858a4f in service fd00:1122:3344:101::2a + crucible 808e6761-6ddc-42f0-a82f-fd2049c751dc in service fd00:1122:3344:101::28 + crucible a1e77a19-9302-416a-afe9-cfdded5054d5 in service fd00:1122:3344:101::26 + crucible be3b1ad8-3de2-4ad7-89b8-d279558121ae in service fd00:1122:3344:101::2d + crucible c6192cad-a9c5-4b4d-bc8f-ce0fb066a0ed in service fd00:1122:3344:101::2c + crucible d39f526b-9799-42a6-a610-f0f5605dac44 in service fd00:1122:3344:101::27 + crucible e8dea18b-1697-4349-ae54-47f95cb3d907 in service fd00:1122:3344:101::2b + crucible f4053fb9-ce8c-4dcf-8dd3-bf6d305c29fc in service fd00:1122:3344:101::2e + external_dns dd9050e5-77ae-4dd0-98aa-d34fc2be78d4 in service fd00:1122:3344:101::23 + external_dns e8ac4104-9789-4ba1-90c5-aded124cc079 in service fd00:1122:3344:101::24 + internal_ntp 77511292-f3aa-4a07-970a-1159e2c38ec9 in service fd00:1122:3344:101::21 + nexus 236e5a84-cebe-40b8-8832-56a8e06b08b0 in service fd00:1122:3344:101::22 + + + COCKROACHDB SETTINGS: + state fingerprint::::::::::::::::: (none) + cluster.preserve_downgrade_option: (do not modify) + + METADATA: + created by::::::::::: test suite + created at::::::::::: 1970-01-01T00:00:00.000Z + comment:::::::::::::: (none) + internal DNS version: 1 + external DNS version: 1 + diff --git a/nexus/src/app/external_endpoints.rs b/nexus/src/app/external_endpoints.rs index 18d2399eb5..9d56dad61f 100644 --- a/nexus/src/app/external_endpoints.rs +++ b/nexus/src/app/external_endpoints.rs @@ -35,11 +35,11 @@ use nexus_db_model::Certificate; use nexus_db_model::DnsGroup; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::datastore::Discoverability; -use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO_ID; use nexus_db_queries::db::model::ServiceKind; use nexus_db_queries::db::DataStore; -use nexus_reconfigurator_execution::silo_dns_name; use nexus_types::identity::Resource; +use nexus_types::silo::silo_dns_name; +use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::api::external::http_pagination::PaginatedBy; use omicron_common::api::external::DataPageParams; use omicron_common::api::external::Error; @@ -225,7 +225,7 @@ impl ExternalEndpoints { .filter(|s| { // Ignore the built-in Silo, which people are not supposed to // log into. - s.id() != *DEFAULT_SILO_ID + s.id() != DEFAULT_SILO_ID }) .find(|s| s.authentication_mode == AuthenticationMode::Local) .and_then(|s| { diff --git a/nexus/src/app/rack.rs b/nexus/src/app/rack.rs index bc980bb543..1bfa22dad8 100644 --- a/nexus/src/app/rack.rs +++ b/nexus/src/app/rack.rs @@ -20,7 +20,6 @@ use nexus_db_queries::db::datastore::DnsVersionUpdateBuilder; use nexus_db_queries::db::datastore::RackInit; use nexus_db_queries::db::datastore::SledUnderlayAllocationResult; use nexus_db_queries::db::lookup::LookupPath; -use nexus_reconfigurator_execution::silo_dns_name; use nexus_types::deployment::blueprint_zone_type; use nexus_types::deployment::BlueprintZoneFilter; use nexus_types::deployment::BlueprintZoneType; @@ -48,6 +47,7 @@ use nexus_types::external_api::shared::SiloRole; use nexus_types::external_api::shared::UninitializedSled; use nexus_types::external_api::views; use nexus_types::internal_api::params::DnsRecord; +use nexus_types::silo::silo_dns_name; use omicron_common::address::{get_64_subnet, Ipv6Subnet, RACK_PREFIX}; use omicron_common::api::external::AddressLotKind; use omicron_common::api::external::BgpPeer; diff --git a/nexus/src/app/silo.rs b/nexus/src/app/silo.rs index efde55cbd1..b8e3de8866 100644 --- a/nexus/src/app/silo.rs +++ b/nexus/src/app/silo.rs @@ -16,9 +16,9 @@ use nexus_db_queries::db::identity::{Asset, Resource}; use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::{self, lookup}; use nexus_db_queries::{authn, authz}; -use nexus_reconfigurator_execution::blueprint_nexus_external_ips; -use nexus_reconfigurator_execution::silo_dns_name; +use nexus_types::deployment::execution::blueprint_nexus_external_ips; use nexus_types::internal_api::params::DnsRecord; +use nexus_types::silo::silo_dns_name; use omicron_common::api::external::http_pagination::PaginatedBy; use omicron_common::api::external::ListResultVec; use omicron_common::api::external::LookupResult; diff --git a/nexus/tests/integration_tests/authn_http.rs b/nexus/tests/integration_tests/authn_http.rs index 73066220c4..cb98b45878 100644 --- a/nexus/tests/integration_tests/authn_http.rs +++ b/nexus/tests/integration_tests/authn_http.rs @@ -26,7 +26,7 @@ use nexus_db_queries::authn::external::spoof::SPOOF_SCHEME_NAME; use nexus_db_queries::authn::external::AuthenticatorContext; use nexus_db_queries::authn::external::HttpAuthnScheme; use nexus_db_queries::authn::external::SiloUserSilo; -use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO_ID; +use nexus_types::silo::DEFAULT_SILO_ID; use std::collections::HashMap; use std::sync::Mutex; use uuid::Uuid; @@ -342,7 +342,7 @@ impl SiloUserSilo for WhoamiServerState { silo_user_id.to_string(), "7f927c86-3371-4295-c34a-e3246a4b9c02" ); - Ok(*DEFAULT_SILO_ID) + Ok(DEFAULT_SILO_ID) } } diff --git a/nexus/tests/integration_tests/disks.rs b/nexus/tests/integration_tests/disks.rs index c9659d6bb8..d6d7cb58ea 100644 --- a/nexus/tests/integration_tests/disks.rs +++ b/nexus/tests/integration_tests/disks.rs @@ -17,7 +17,7 @@ use nexus_db_queries::context::OpContext; use nexus_db_queries::db::datastore::RegionAllocationFor; use nexus_db_queries::db::datastore::RegionAllocationParameters; use nexus_db_queries::db::datastore::REGION_REDUNDANCY_THRESHOLD; -use nexus_db_queries::db::fixed_data::{silo::DEFAULT_SILO_ID, FLEET_ID}; +use nexus_db_queries::db::fixed_data::FLEET_ID; use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::http_testing::AuthnMode; use nexus_test_utils::http_testing::Collection; @@ -33,6 +33,7 @@ use nexus_test_utils::resource_helpers::objects_list_page_authz; use nexus_test_utils::SLED_AGENT_UUID; use nexus_test_utils_macros::nexus_test; use nexus_types::external_api::params; +use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::api::external::ByteCount; use omicron_common::api::external::Disk; use omicron_common::api::external::DiskState; @@ -1108,7 +1109,7 @@ async fn test_disk_virtual_provisioning_collection( 0 ); let virtual_provisioning_collection = datastore - .virtual_provisioning_collection_get(&opctx, *DEFAULT_SILO_ID) + .virtual_provisioning_collection_get(&opctx, DEFAULT_SILO_ID) .await .unwrap(); assert_eq!( @@ -1172,7 +1173,7 @@ async fn test_disk_virtual_provisioning_collection( 0 ); let virtual_provisioning_collection = datastore - .virtual_provisioning_collection_get(&opctx, *DEFAULT_SILO_ID) + .virtual_provisioning_collection_get(&opctx, DEFAULT_SILO_ID) .await .unwrap(); assert_eq!( @@ -1229,7 +1230,7 @@ async fn test_disk_virtual_provisioning_collection( disk_size ); let virtual_provisioning_collection = datastore - .virtual_provisioning_collection_get(&opctx, *DEFAULT_SILO_ID) + .virtual_provisioning_collection_get(&opctx, DEFAULT_SILO_ID) .await .unwrap(); assert_eq!( @@ -1267,7 +1268,7 @@ async fn test_disk_virtual_provisioning_collection( 0 ); let virtual_provisioning_collection = datastore - .virtual_provisioning_collection_get(&opctx, *DEFAULT_SILO_ID) + .virtual_provisioning_collection_get(&opctx, DEFAULT_SILO_ID) .await .unwrap(); assert_eq!( diff --git a/nexus/tests/integration_tests/instances.rs b/nexus/tests/integration_tests/instances.rs index d5f37d62be..a01b95ebb8 100644 --- a/nexus/tests/integration_tests/instances.rs +++ b/nexus/tests/integration_tests/instances.rs @@ -16,7 +16,6 @@ use http::StatusCode; use itertools::Itertools; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO; -use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO_ID; use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::db::DataStore; use nexus_test_interface::NexusServer; @@ -49,6 +48,7 @@ use nexus_types::external_api::views::SshKey; use nexus_types::external_api::{params, views}; use nexus_types::identity::Resource; use nexus_types::internal_api::params::InstanceMigrateRequest; +use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::api::external::ByteCount; use omicron_common::api::external::Disk; use omicron_common::api::external::DiskState; @@ -1641,7 +1641,7 @@ async fn assert_metrics( ram ); } - for id in &[None, Some(*DEFAULT_SILO_ID)] { + for id in &[None, Some(DEFAULT_SILO_ID)] { assert_eq!( get_latest_system_metric( cptestctx, diff --git a/nexus/tests/integration_tests/ip_pools.rs b/nexus/tests/integration_tests/ip_pools.rs index f56755d85c..bb2fba8be6 100644 --- a/nexus/tests/integration_tests/ip_pools.rs +++ b/nexus/tests/integration_tests/ip_pools.rs @@ -16,7 +16,6 @@ use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::datastore::SERVICE_IP_POOL_NAME; use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO; -use nexus_db_queries::db::fixed_data::silo::INTERNAL_SILO_ID; use nexus_test_utils::http_testing::AuthnMode; use nexus_test_utils::http_testing::NexusRequest; use nexus_test_utils::http_testing::RequestBuilder; @@ -53,6 +52,7 @@ use nexus_types::external_api::views::IpPoolSiloLink; use nexus_types::external_api::views::Silo; use nexus_types::external_api::views::SiloIpPool; use nexus_types::identity::Resource; +use nexus_types::silo::INTERNAL_SILO_ID; use omicron_common::address::Ipv6Range; use omicron_common::api::external::IdentityMetadataUpdateParams; use omicron_common::api::external::InstanceState; @@ -431,11 +431,11 @@ async fn test_ip_pool_service_no_cud(cptestctx: &ControlPlaneTestContext) { assert_eq!(error.message, not_found_id); // unlink not allowed by name or ID - let url = format!("{}/silos/{}", internal_pool_id_url, *INTERNAL_SILO_ID); + let url = format!("{}/silos/{}", internal_pool_id_url, INTERNAL_SILO_ID); let error = object_delete_error(client, &url, StatusCode::NOT_FOUND).await; assert_eq!(error.message, not_found_id); - let url = format!("{}/silos/{}", internal_pool_name_url, *INTERNAL_SILO_ID); + let url = format!("{}/silos/{}", internal_pool_name_url, INTERNAL_SILO_ID); let error = object_delete_error(client, &url, StatusCode::NOT_FOUND).await; assert_eq!(error.message, not_found_name); } diff --git a/nexus/tests/integration_tests/metrics.rs b/nexus/tests/integration_tests/metrics.rs index 700568fe96..c6c014db69 100644 --- a/nexus/tests/integration_tests/metrics.rs +++ b/nexus/tests/integration_tests/metrics.rs @@ -11,7 +11,6 @@ use chrono::Utc; use dropshot::test_util::ClientTestContext; use dropshot::ResultsPage; use http::{Method, StatusCode}; -use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO_ID; use nexus_test_utils::http_testing::{AuthnMode, NexusRequest, RequestBuilder}; use nexus_test_utils::resource_helpers::{ create_default_ip_pool, create_disk, create_instance, create_project, @@ -20,6 +19,7 @@ use nexus_test_utils::resource_helpers::{ use nexus_test_utils::ControlPlaneTestContext; use nexus_test_utils_macros::nexus_test; use nexus_types::external_api::views::OxqlQueryResult; +use nexus_types::silo::DEFAULT_SILO_ID; use omicron_test_utils::dev::poll::{wait_for_condition, CondCheckError}; use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; use oximeter::types::Datum; @@ -190,7 +190,7 @@ async fn test_metrics( // silo metrics start out zero assert_system_metrics(&cptestctx, None, 0, 0, 0).await; - assert_system_metrics(&cptestctx, Some(*DEFAULT_SILO_ID), 0, 0, 0).await; + assert_system_metrics(&cptestctx, Some(DEFAULT_SILO_ID), 0, 0, 0).await; assert_silo_metrics(&cptestctx, None, 0, 0, 0).await; let project1_id = create_project(&client, "p-1").await.identity.id; @@ -206,7 +206,7 @@ async fn test_metrics( "/v1/metrics/cpus_provisioned?start_time={:?}&end_time={:?}&order=descending&limit=1&project={}", cptestctx.start_time, Utc::now(), - *DEFAULT_SILO_ID, + DEFAULT_SILO_ID, ); assert_404(&cptestctx, &bad_silo_metrics_url).await; let bad_system_metrics_url = format!( @@ -222,15 +222,14 @@ async fn test_metrics( assert_silo_metrics(&cptestctx, Some(project1_id), 0, 4, GIB).await; assert_silo_metrics(&cptestctx, None, 0, 4, GIB).await; assert_system_metrics(&cptestctx, None, 0, 4, GIB).await; - assert_system_metrics(&cptestctx, Some(*DEFAULT_SILO_ID), 0, 4, GIB).await; + assert_system_metrics(&cptestctx, Some(DEFAULT_SILO_ID), 0, 4, GIB).await; // create disk in project 1 create_disk(&client, "p-1", "d-1").await; assert_silo_metrics(&cptestctx, Some(project1_id), GIB, 4, GIB).await; assert_silo_metrics(&cptestctx, None, GIB, 4, GIB).await; assert_system_metrics(&cptestctx, None, GIB, 4, GIB).await; - assert_system_metrics(&cptestctx, Some(*DEFAULT_SILO_ID), GIB, 4, GIB) - .await; + assert_system_metrics(&cptestctx, Some(DEFAULT_SILO_ID), GIB, 4, GIB).await; // project 2 metrics still empty assert_silo_metrics(&cptestctx, Some(project2_id), 0, 0, 0).await; @@ -245,7 +244,7 @@ async fn test_metrics( assert_system_metrics(&cptestctx, None, 2 * GIB, 8, 2 * GIB).await; assert_system_metrics( &cptestctx, - Some(*DEFAULT_SILO_ID), + Some(DEFAULT_SILO_ID), 2 * GIB, 8, 2 * GIB, diff --git a/nexus/tests/integration_tests/silo_users.rs b/nexus/tests/integration_tests/silo_users.rs index 598d2a28a4..ca3039f19b 100644 --- a/nexus/tests/integration_tests/silo_users.rs +++ b/nexus/tests/integration_tests/silo_users.rs @@ -7,13 +7,13 @@ use http::{method::Method, StatusCode}; use nexus_db_queries::authn::USER_TEST_UNPRIVILEGED; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; -use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO_ID; use nexus_test_utils::assert_same_items; use nexus_test_utils::http_testing::{AuthnMode, NexusRequest}; use nexus_test_utils::resource_helpers::objects_list_page_authz; use nexus_test_utils_macros::nexus_test; use nexus_types::external_api::views; use nexus_types::identity::Asset; +use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::api::external::LookupType; use uuid::Uuid; @@ -46,8 +46,8 @@ async fn test_silo_group_users(cptestctx: &ControlPlaneTestContext) { let authz_silo = authz::Silo::new( authz::FLEET, - *DEFAULT_SILO_ID, - LookupType::ById(*DEFAULT_SILO_ID), + DEFAULT_SILO_ID, + LookupType::ById(DEFAULT_SILO_ID), ); // create a group diff --git a/nexus/tests/integration_tests/silos.rs b/nexus/tests/integration_tests/silos.rs index 0de4d31395..111a5eb122 100644 --- a/nexus/tests/integration_tests/silos.rs +++ b/nexus/tests/integration_tests/silos.rs @@ -9,7 +9,7 @@ use nexus_db_queries::authn::{USER_TEST_PRIVILEGED, USER_TEST_UNPRIVILEGED}; use nexus_db_queries::authz::{self}; use nexus_db_queries::context::OpContext; use nexus_db_queries::db; -use nexus_db_queries::db::fixed_data::silo::{DEFAULT_SILO, DEFAULT_SILO_ID}; +use nexus_db_queries::db::fixed_data::silo::DEFAULT_SILO; use nexus_db_queries::db::identity::Asset; use nexus_db_queries::db::lookup::LookupPath; use nexus_test_utils::http_testing::{AuthnMode, NexusRequest, RequestBuilder}; @@ -24,6 +24,7 @@ use nexus_types::external_api::views::{ self, IdentityProvider, Project, SamlIdentityProvider, Silo, }; use nexus_types::external_api::{params, shared}; +use nexus_types::silo::DEFAULT_SILO_ID; use omicron_common::address::{IpRange, Ipv4Range}; use omicron_common::api::external::{ IdentityMetadataCreateParams, LookupType, Name, @@ -919,12 +920,12 @@ async fn test_silo_users_list(cptestctx: &ControlPlaneTestContext) { views::User { id: USER_TEST_PRIVILEGED.id(), display_name: USER_TEST_PRIVILEGED.external_id.clone(), - silo_id: *DEFAULT_SILO_ID, + silo_id: DEFAULT_SILO_ID, }, views::User { id: USER_TEST_UNPRIVILEGED.id(), display_name: USER_TEST_UNPRIVILEGED.external_id.clone(), - silo_id: *DEFAULT_SILO_ID, + silo_id: DEFAULT_SILO_ID, }, ] ); @@ -953,17 +954,17 @@ async fn test_silo_users_list(cptestctx: &ControlPlaneTestContext) { views::User { id: new_silo_user_id, display_name: new_silo_user_external_id.into(), - silo_id: *DEFAULT_SILO_ID, + silo_id: DEFAULT_SILO_ID, }, views::User { id: USER_TEST_PRIVILEGED.id(), display_name: USER_TEST_PRIVILEGED.external_id.clone(), - silo_id: *DEFAULT_SILO_ID, + silo_id: DEFAULT_SILO_ID, }, views::User { id: USER_TEST_UNPRIVILEGED.id(), display_name: USER_TEST_UNPRIVILEGED.external_id.clone(), - silo_id: *DEFAULT_SILO_ID, + silo_id: DEFAULT_SILO_ID, }, ] ); diff --git a/nexus/types/Cargo.toml b/nexus/types/Cargo.toml index fdb53aaaae..f85cdd41ac 100644 --- a/nexus/types/Cargo.toml +++ b/nexus/types/Cargo.toml @@ -44,6 +44,7 @@ uuid.workspace = true api_identity.workspace = true dns-service-client.workspace = true gateway-client.workspace = true +internal-dns.workspace = true nexus-sled-agent-shared.workspace = true omicron-common.workspace = true omicron-passwords.workspace = true diff --git a/nexus/types/src/deployment/execution/mod.rs b/nexus/types/src/deployment/execution/mod.rs new file mode 100644 index 0000000000..ce38c02d23 --- /dev/null +++ b/nexus/types/src/deployment/execution/mod.rs @@ -0,0 +1,11 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +mod overridables; +mod spec; +mod utils; + +pub use overridables::*; +pub use spec::*; +pub use utils::*; diff --git a/nexus/reconfigurator/execution/src/overridables.rs b/nexus/types/src/deployment/execution/overridables.rs similarity index 59% rename from nexus/reconfigurator/execution/src/overridables.rs rename to nexus/types/src/deployment/execution/overridables.rs index f59e3228f4..bc7b28a63a 100644 --- a/nexus/reconfigurator/execution/src/overridables.rs +++ b/nexus/types/src/deployment/execution/overridables.rs @@ -16,9 +16,9 @@ use std::net::Ipv6Addr; /// /// Blueprint execution assumes certain values about production systems that /// differ in the simulated testing environment and cannot be easily derived -/// from anything else in the environment. To accommodate this, this structure -/// provides access to these values. Everywhere except the test suite, this -/// structure is empty and returns the default (production) values. The test +/// from anything else in the environment. To accommodate this, this structure +/// provides access to these values. Everywhere except the test suite, this +/// structure is empty and returns the default (production) values. The test /// suite overrides these values. #[derive(Debug, Default)] pub struct Overridables { @@ -34,8 +34,7 @@ pub struct Overridables { impl Overridables { /// Specify the TCP port on which this sled's Dendrite is listening - #[cfg(test)] - fn override_dendrite_port(&mut self, sled_id: SledUuid, port: u16) { + pub fn override_dendrite_port(&mut self, sled_id: SledUuid, port: u16) { self.dendrite_ports.insert(sled_id, port); } @@ -45,8 +44,7 @@ impl Overridables { } /// Specify the TCP port on which this sled's MGS is listening - #[cfg(test)] - fn override_mgs_port(&mut self, sled_id: SledUuid, port: u16) { + pub fn override_mgs_port(&mut self, sled_id: SledUuid, port: u16) { self.mgs_ports.insert(sled_id, port); } @@ -56,8 +54,7 @@ impl Overridables { } /// Specify the TCP port on which this sled's MGD is listening - #[cfg(test)] - fn override_mgd_port(&mut self, sled_id: SledUuid, port: u16) { + pub fn override_mgd_port(&mut self, sled_id: SledUuid, port: u16) { self.mgd_ports.insert(sled_id, port); } @@ -67,8 +64,11 @@ impl Overridables { } /// Specify the IP address of this switch zone - #[cfg(test)] - fn override_switch_zone_ip(&mut self, sled_id: SledUuid, addr: Ipv6Addr) { + pub fn override_switch_zone_ip( + &mut self, + sled_id: SledUuid, + addr: Ipv6Addr, + ) { self.switch_zone_ips.insert(sled_id, addr); } @@ -83,39 +83,4 @@ impl Overridables { .copied() .unwrap_or_else(|| get_switch_zone_address(sled_subnet)) } - - /// Generates a set of overrides describing the simulated test environment. - #[cfg(test)] - pub fn for_test( - cptestctx: &nexus_test_utils::ControlPlaneTestContext< - omicron_nexus::Server, - >, - ) -> Overridables { - use omicron_common::api::external::SwitchLocation; - - let mut overrides = Overridables::default(); - let scrimlets = [ - (nexus_test_utils::SLED_AGENT_UUID, SwitchLocation::Switch0), - (nexus_test_utils::SLED_AGENT2_UUID, SwitchLocation::Switch1), - ]; - for (id_str, switch_location) in scrimlets { - let sled_id = id_str.parse().unwrap(); - let ip = Ipv6Addr::LOCALHOST; - let mgs_port = cptestctx - .gateway - .get(&switch_location) - .unwrap() - .client - .bind_address - .port(); - let dendrite_port = - cptestctx.dendrite.get(&switch_location).unwrap().port; - let mgd_port = cptestctx.mgd.get(&switch_location).unwrap().port; - overrides.override_switch_zone_ip(sled_id, ip); - overrides.override_dendrite_port(sled_id, dendrite_port); - overrides.override_mgs_port(sled_id, mgs_port); - overrides.override_mgd_port(sled_id, mgd_port); - } - overrides - } } diff --git a/nexus/types/src/deployment/execution.rs b/nexus/types/src/deployment/execution/spec.rs similarity index 100% rename from nexus/types/src/deployment/execution.rs rename to nexus/types/src/deployment/execution/spec.rs diff --git a/nexus/types/src/deployment/execution/utils.rs b/nexus/types/src/deployment/execution/utils.rs new file mode 100644 index 0000000000..337a529c18 --- /dev/null +++ b/nexus/types/src/deployment/execution/utils.rs @@ -0,0 +1,228 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use std::{ + collections::{BTreeMap, HashMap}, + net::{IpAddr, SocketAddrV6}, +}; + +use internal_dns::{DnsConfigBuilder, ServiceName}; +use nexus_sled_agent_shared::inventory::SledRole; +use omicron_common::{ + address::{Ipv6Subnet, SLED_PREFIX}, + api::external::Name, +}; +use omicron_uuid_kinds::SledUuid; + +use crate::{ + deployment::{ + blueprint_zone_type, Blueprint, BlueprintZoneFilter, BlueprintZoneType, + }, + internal_api::params::{DnsConfigZone, DnsRecord}, + silo::{default_silo_name, silo_dns_name}, +}; + +use super::Overridables; + +/// The minimal information needed to represent a sled in the context of +/// blueprint execution. +#[derive(Debug, Clone)] +pub struct Sled { + id: SledUuid, + sled_agent_address: SocketAddrV6, + role: SledRole, +} + +impl Sled { + pub fn new( + id: SledUuid, + sled_agent_address: SocketAddrV6, + role: SledRole, + ) -> Sled { + Sled { id, sled_agent_address, role } + } + + pub fn id(&self) -> SledUuid { + self.id + } + + pub fn sled_agent_address(&self) -> SocketAddrV6 { + self.sled_agent_address + } + + pub fn subnet(&self) -> Ipv6Subnet { + Ipv6Subnet::::new(*self.sled_agent_address.ip()) + } + + pub fn role(&self) -> SledRole { + self.role + } + + pub fn is_scrimlet(&self) -> bool { + self.role == SledRole::Scrimlet + } +} + +/// Returns the expected contents of internal DNS based on the given blueprint +pub fn blueprint_internal_dns_config( + blueprint: &Blueprint, + sleds_by_id: &BTreeMap, + overrides: &Overridables, +) -> anyhow::Result { + // The DNS names configured here should match what RSS configures for the + // same zones. It's tricky to have RSS share the same code because it uses + // Sled Agent's _internal_ `OmicronZoneConfig` (and friends), whereas we're + // using `sled-agent-client`'s version of that type. However, the + // DnsConfigBuilder's interface is high-level enough that it handles most of + // the details. + let mut dns_builder = DnsConfigBuilder::new(); + + 'all_zones: for (_, zone) in + blueprint.all_omicron_zones(BlueprintZoneFilter::ShouldBeInInternalDns) + { + let (service_name, port) = match &zone.zone_type { + BlueprintZoneType::BoundaryNtp( + blueprint_zone_type::BoundaryNtp { address, .. }, + ) => (ServiceName::BoundaryNtp, address.port()), + BlueprintZoneType::InternalNtp( + blueprint_zone_type::InternalNtp { address, .. }, + ) => (ServiceName::InternalNtp, address.port()), + BlueprintZoneType::Clickhouse( + blueprint_zone_type::Clickhouse { address, .. }, + ) + | BlueprintZoneType::ClickhouseServer( + blueprint_zone_type::ClickhouseServer { address, .. }, + ) => { + // Add the HTTP and native TCP interfaces for ClickHouse data + // replicas. This adds the zone itself, so we need to continue + // back up to the loop over all the Omicron zones, rather than + // falling through to call `host_zone_with_one_backend()`. + let http_service = if matches!( + &zone.zone_type, + BlueprintZoneType::Clickhouse(_) + ) { + ServiceName::Clickhouse + } else { + ServiceName::ClickhouseServer + }; + dns_builder.host_zone_clickhouse( + zone.id, + zone.underlay_address, + http_service, + address.port(), + )?; + continue 'all_zones; + } + BlueprintZoneType::ClickhouseKeeper( + blueprint_zone_type::ClickhouseKeeper { address, .. }, + ) => { + // Add the Clickhouse keeper service and `clickhouse-admin` + // service used for managing the keeper. We continue below so we + // don't fall through and call `host_zone_with_one_backend`. + dns_builder.host_zone_clickhouse_keeper( + zone.id, + zone.underlay_address, + ServiceName::ClickhouseKeeper, + address.port(), + )?; + continue 'all_zones; + } + BlueprintZoneType::CockroachDb( + blueprint_zone_type::CockroachDb { address, .. }, + ) => (ServiceName::Cockroach, address.port()), + BlueprintZoneType::Nexus(blueprint_zone_type::Nexus { + internal_address, + .. + }) => (ServiceName::Nexus, internal_address.port()), + BlueprintZoneType::Crucible(blueprint_zone_type::Crucible { + address, + .. + }) => (ServiceName::Crucible(zone.id), address.port()), + BlueprintZoneType::CruciblePantry( + blueprint_zone_type::CruciblePantry { address }, + ) => (ServiceName::CruciblePantry, address.port()), + BlueprintZoneType::Oximeter(blueprint_zone_type::Oximeter { + address, + }) => (ServiceName::Oximeter, address.port()), + BlueprintZoneType::ExternalDns( + blueprint_zone_type::ExternalDns { http_address, .. }, + ) => (ServiceName::ExternalDns, http_address.port()), + BlueprintZoneType::InternalDns( + blueprint_zone_type::InternalDns { http_address, .. }, + ) => (ServiceName::InternalDns, http_address.port()), + }; + dns_builder.host_zone_with_one_backend( + zone.id, + zone.underlay_address, + service_name, + port, + )?; + } + + let scrimlets = sleds_by_id.values().filter(|sled| sled.is_scrimlet()); + for scrimlet in scrimlets { + let sled_subnet = scrimlet.subnet(); + let switch_zone_ip = overrides.switch_zone_ip(scrimlet.id, sled_subnet); + dns_builder.host_zone_switch( + scrimlet.id, + switch_zone_ip, + overrides.dendrite_port(scrimlet.id), + overrides.mgs_port(scrimlet.id), + overrides.mgd_port(scrimlet.id), + )?; + } + + Ok(dns_builder.build_zone()) +} + +pub fn blueprint_external_dns_config( + blueprint: &Blueprint, + silos: &[Name], + external_dns_zone_name: String, +) -> DnsConfigZone { + let nexus_external_ips = blueprint_nexus_external_ips(blueprint); + + let dns_records: Vec = nexus_external_ips + .into_iter() + .map(|addr| match addr { + IpAddr::V4(addr) => DnsRecord::A(addr), + IpAddr::V6(addr) => DnsRecord::Aaaa(addr), + }) + .collect(); + + let records = silos + .into_iter() + // We do not generate a DNS name for the "default" Silo. + // + // We use the name here rather than the id. It shouldn't really matter + // since every system will have this silo and so no other Silo could + // have this name. But callers (particularly the test suite and + // reconfigurator-cli) specify silos by name, not id, so if we used the + // id here then they'd have to apply this filter themselves (and this + // abstraction, such as it is, would be leakier). + .filter_map(|silo_name| { + (silo_name != default_silo_name()) + .then(|| (silo_dns_name(&silo_name), dns_records.clone())) + }) + .collect::>>(); + + DnsConfigZone { + zone_name: external_dns_zone_name, + records: records.clone(), + } +} + +/// Return the Nexus external addresses according to the given blueprint +pub fn blueprint_nexus_external_ips(blueprint: &Blueprint) -> Vec { + blueprint + .all_omicron_zones(BlueprintZoneFilter::ShouldBeExternallyReachable) + .filter_map(|(_, z)| match z.zone_type { + BlueprintZoneType::Nexus(blueprint_zone_type::Nexus { + external_ip, + .. + }) => Some(external_ip.ip), + _ => None, + }) + .collect() +} diff --git a/nexus/types/src/lib.rs b/nexus/types/src/lib.rs index 8a0a3ec80e..4b9c8836a4 100644 --- a/nexus/types/src/lib.rs +++ b/nexus/types/src/lib.rs @@ -35,3 +35,4 @@ pub mod external_api; pub mod identity; pub mod internal_api; pub mod inventory; +pub mod silo; diff --git a/nexus/types/src/silo.rs b/nexus/types/src/silo.rs new file mode 100644 index 0000000000..1b34c95fb8 --- /dev/null +++ b/nexus/types/src/silo.rs @@ -0,0 +1,44 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +//! Silo-related utilities and fixed data. + +use std::sync::LazyLock; + +use omicron_common::api::external::Name; + +/// The ID of the "default" silo. +pub static DEFAULT_SILO_ID: uuid::Uuid = + uuid::Uuid::from_u128(0x001de000_5110_4000_8000_000000000000); + +/// Return the name of the default silo. +pub fn default_silo_name() -> &'static Name { + static DEFAULT_SILO_NAME: LazyLock = + LazyLock::new(|| "default-silo".parse().unwrap()); + + &DEFAULT_SILO_NAME +} + +/// The ID of the built-in internal silo. +pub static INTERNAL_SILO_ID: uuid::Uuid = + uuid::Uuid::from_u128(0x001de000_5110_4000_8000_000000000001); + +/// Return the name of the internal silo. +pub fn internal_silo_name() -> &'static Name { + static INTERNAL_SILO_NAME: LazyLock = + LazyLock::new(|| "oxide-internal".parse().unwrap()); + + &INTERNAL_SILO_NAME +} + +/// Returns the (relative) DNS name for this Silo's API and console endpoints +/// _within_ the external DNS zone (i.e., without that zone's suffix) +/// +/// This specific naming scheme is determined under RFD 357. +pub fn silo_dns_name(name: &omicron_common::api::external::Name) -> String { + // RFD 4 constrains resource names (including Silo names) to DNS-safe + // strings, which is why it's safe to directly put the name of the + // resource into the DNS name rather than doing any kind of escaping. + format!("{}.sys", name) +} diff --git a/test-utils/src/dev/test_cmds.rs b/test-utils/src/dev/test_cmds.rs index 94c558d82e..5d5e15aa91 100644 --- a/test-utils/src/dev/test_cmds.rs +++ b/test-utils/src/dev/test_cmds.rs @@ -125,7 +125,51 @@ pub fn error_for_enoent() -> String { /// invocation to invocation (e.g., assigned TCP port numbers, timestamps) /// /// This allows use to use expectorate to verify the shape of the CLI output. -pub fn redact_variable(input: &str) -> String { +#[derive(Clone, Debug)] +pub struct Redactor<'a> { + redact_uuids: bool, + extra: ExtraRedactions<'a>, +} + +impl<'a> Redactor<'a> { + pub fn new() -> Self { + Self { redact_uuids: true, extra: ExtraRedactions::new() } + } + + pub fn redact_uuids(&mut self, redact_uuids: bool) -> &mut Self { + self.redact_uuids = redact_uuids; + self + } + + pub fn extra( + &mut self, + extra_redactions: ExtraRedactions<'a>, + ) -> &mut Self { + self.extra = extra_redactions; + self + } + + pub fn do_redact(&self, input: &str) -> String { + // Perform extra redactions at the beginning, not the end. This is because + // some of the built-in redactions in redact_variable might match a + // substring of something that should be handled by extra_redactions (e.g. + // a temporary path). + let mut s = input.to_owned(); + for (name, replacement) in &self.extra.redactions { + s = s.replace(name, replacement); + } + + s = redact_basic(&s); + + if self.redact_uuids { + s = redact_uuids(&s); + } + + s + } +} + +fn redact_basic(input: &str) -> String { // Replace TCP port numbers. We include the localhost // characters to avoid catching any random sequence of numbers. let s = regex::Regex::new(r"\[::1\]:\d{4,5}") @@ -141,19 +185,6 @@ pub fn redact_variable(input: &str) -> String { .replace_all(&s, "127.0.0.1:REDACTED_PORT") .to_string(); - // Replace uuids. - // - // The length of a UUID is 32 nibbles for the hex encoding of a u128 + 4 - // dashes = 36. - const UUID_LEN: usize = 36; - let s = regex::Regex::new( - "[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-\ - [a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}", - ) - .unwrap() - .replace_all(&s, fill_redaction_text("uuid", UUID_LEN)) - .to_string(); - // Replace timestamps. // // Format: RFC 3339 (ISO 8601) @@ -213,23 +244,17 @@ pub fn redact_variable(input: &str) -> String { s } -/// Redact text from a string, allowing for extra redactions to be specified. -pub fn redact_extra( - input: &str, - extra_redactions: &ExtraRedactions<'_>, -) -> String { - // Perform extra redactions at the beginning, not the end. This is because - // some of the built-in redactions in redact_variable might match a - // substring of something that should be handled by extra_redactions (e.g. - // a temporary path). - let mut s = input.to_owned(); - for (name, replacement) in &extra_redactions.redactions { - s = s.replace(name, replacement); - } - redact_variable(&s) +fn redact_uuids(input: &str) -> String { + // The length of a UUID is 32 nibbles for the hex encoding of a u128 + 4 + // dashes = 36. + const UUID_LEN: usize = 36; + regex::Regex::new(r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}") + .unwrap() + .replace_all(&input, fill_redaction_text("uuid", UUID_LEN)) + .to_string() } -/// Represents a list of extra redactions for [`redact_variable`]. +/// Represents a list of extra redactions for [`Redactor`]. /// /// Extra redactions are applied in-order, before any builtin redactions. #[derive(Clone, Debug, Default)] @@ -309,13 +334,12 @@ mod tests { let input = "time: 123ms, path: /var/tmp/tmp.456ms123s, \ path2: /short, \ path3: /variable-length/path"; - let actual = redact_extra( - input, - ExtraRedactions::new() - .fixed_length("tp", "/var/tmp/tmp.456ms123s") - .fixed_length("short_redact", "/short") - .variable_length("variable", "/variable-length/path"), - ); + let mut extra = ExtraRedactions::new(); + extra + .fixed_length("tp", "/var/tmp/tmp.456ms123s") + .fixed_length("short_redact", "/short") + .variable_length("variable", "/variable-length/path"); + let actual = Redactor::new().extra(extra).do_redact(input); assert_eq!( actual, "time: ms, path: ........., \ @@ -347,7 +371,7 @@ mod tests { for time in times { let input = format!("{:?}", time); assert_eq!( - redact_variable(&input), + Redactor::new().do_redact(&input), "", "Failed to redact {:?}", time From 886a209f1b1d2ed6dba991cfe5b9e53d61821051 Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 11 Oct 2024 11:22:09 -0700 Subject: [PATCH 2/4] fix tests Created using spr 1.3.6-beta.1 --- .../tests/output/cmd-example-stdout | 175 +++++++++--------- .../reconfigurator-cli/tests/test_basic.rs | 3 +- 2 files changed, 90 insertions(+), 88 deletions(-) diff --git a/dev-tools/reconfigurator-cli/tests/output/cmd-example-stdout b/dev-tools/reconfigurator-cli/tests/output/cmd-example-stdout index 183192b834..3b8b8a45a4 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmd-example-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmd-example-stdout @@ -4,13 +4,13 @@ loaded example system with: - blueprint: ade5749d-bdf3-4fab-a8ae-00bea01b3a5a > load-example --seed test-basic -error: system is not empty; call 'reset' before loading an example +error: changes made to simulated system: run `wipe system` before loading an example system > > show configured external DNS zone name: oxide.example -configured silo names: default-silo +configured silo names: example-silo internal DNS generations: 1 external DNS generations: 1 target number of Nexus instances: default @@ -86,17 +86,18 @@ parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ + clickhouse fe79023f-c5d5-4be5-ad2c-da4e9e9237e4 in service fd00:1122:3344:102::23 crucible 054f64a5-182c-4c28-8994-d2e082550201 in service fd00:1122:3344:102::26 crucible 3b5bffea-e5ed-44df-8468-fd4fa69757d8 in service fd00:1122:3344:102::27 crucible 53dd7fa4-899e-49ed-9fc2-48222db3e20d in service fd00:1122:3344:102::2a crucible 7db307d4-a6ed-4c47-bddf-6759161bf64a in service fd00:1122:3344:102::2c - crucible 8b8f7c02-7a18-4268-b045-2e286b464c5d in service fd00:1122:3344:102::23 crucible 95ad9a1d-4063-4874-974c-2fc92830be27 in service fd00:1122:3344:102::29 crucible bc095417-e2f0-4e95-b390-9cc3fc6e3c6d in service fd00:1122:3344:102::28 crucible d90401f1-fbc2-42cb-bf17-309ee0f922fe in service fd00:1122:3344:102::2b + crucible e8f994c0-0a1b-40e6-8db1-40a8ca89e503 in service fd00:1122:3344:102::2d crucible eaec16c0-0d44-4847-b2d6-31a5151bae52 in service fd00:1122:3344:102::24 crucible f97aa057-6485-45d0-9cb4-4af5b0831d48 in service fd00:1122:3344:102::25 - internal_dns fe79023f-c5d5-4be5-ad2c-da4e9e9237e4 in service fd00:1122:3344:1::1 + internal_dns 8b8f7c02-7a18-4268-b045-2e286b464c5d in service fd00:1122:3344:1::1 internal_ntp c67dd9a4-0d6c-4e9f-b28d-20003f211f7d in service fd00:1122:3344:102::21 nexus 94b45ce9-d3d8-413a-a76b-865da1f67930 in service fd00:1122:3344:102::22 @@ -124,19 +125,19 @@ parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ - crucible 728db429-8621-4e1e-9915-282aadfa27d1 in service fd00:1122:3344:103::25 - crucible a999e5fa-3edc-4dac-919a-d7b554cdae58 in service fd00:1122:3344:103::28 - crucible b416f299-c23c-46c8-9820-be2b66ffea0a in service fd00:1122:3344:103::29 - crucible c8aa84a5-a802-46c9-adcd-d61e9c8393c9 in service fd00:1122:3344:103::23 - crucible cc1dc86d-bd6f-4929-aa4a-9619012e9393 in service fd00:1122:3344:103::26 - crucible cd3bb540-e605-465f-8c62-177ac482d850 in service fd00:1122:3344:103::2b - crucible e7dd3e98-7fe7-4827-be7f-395ff9a5f542 in service fd00:1122:3344:103::24 - crucible e8971ab3-fb7d-4ad8-aae3-7f2fe87c51f3 in service fd00:1122:3344:103::27 - crucible f52aa245-7e1b-46c0-8a31-e09725f02caf in service fd00:1122:3344:103::2c - crucible fae49024-6cec-444d-a6c4-83658ab015a4 in service fd00:1122:3344:103::2a - internal_dns 4f2eb088-7d28-4c4e-a27c-746400ec65ba in service fd00:1122:3344:2::1 - internal_ntp e8f994c0-0a1b-40e6-8db1-40a8ca89e503 in service fd00:1122:3344:103::21 - nexus e9bf481e-323e-466e-842f-8107078c7137 in service fd00:1122:3344:103::22 + crucible 728db429-8621-4e1e-9915-282aadfa27d1 in service fd00:1122:3344:103::24 + crucible a999e5fa-3edc-4dac-919a-d7b554cdae58 in service fd00:1122:3344:103::27 + crucible b416f299-c23c-46c8-9820-be2b66ffea0a in service fd00:1122:3344:103::28 + crucible b5d5491d-b3aa-4727-8b55-f66e0581ea4f in service fd00:1122:3344:103::2c + crucible cc1dc86d-bd6f-4929-aa4a-9619012e9393 in service fd00:1122:3344:103::25 + crucible cd3bb540-e605-465f-8c62-177ac482d850 in service fd00:1122:3344:103::2a + crucible e7dd3e98-7fe7-4827-be7f-395ff9a5f542 in service fd00:1122:3344:103::23 + crucible e8971ab3-fb7d-4ad8-aae3-7f2fe87c51f3 in service fd00:1122:3344:103::26 + crucible f52aa245-7e1b-46c0-8a31-e09725f02caf in service fd00:1122:3344:103::2b + crucible fae49024-6cec-444d-a6c4-83658ab015a4 in service fd00:1122:3344:103::29 + internal_dns c8aa84a5-a802-46c9-adcd-d61e9c8393c9 in service fd00:1122:3344:2::1 + internal_ntp e9bf481e-323e-466e-842f-8107078c7137 in service fd00:1122:3344:103::21 + nexus 4f2eb088-7d28-4c4e-a27c-746400ec65ba in service fd00:1122:3344:103::22 @@ -162,19 +163,19 @@ parent: 02697f74-b14a-4418-90f0-c28b2a3a6aa9 ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ - crucible 315a3670-d019-425c-b7a6-c9429428b671 in service fd00:1122:3344:101::26 - crucible 413d3e02-e19f-400a-9718-a662347538f0 in service fd00:1122:3344:101::27 - crucible 6cb330f9-4609-4d6c-98ad-b5cc34245813 in service fd00:1122:3344:101::2c - crucible 6d725df0-0189-4429-b270-3eeb891d39c8 in service fd00:1122:3344:101::2b - crucible 8b47e1e8-0396-4e44-a4a5-ea891405c9f2 in service fd00:1122:3344:101::25 - crucible b43ce109-90d6-46f9-9df0-8c68bfe6d4a0 in service fd00:1122:3344:101::24 - crucible b5443ebd-1f5b-448c-8edc-b4ca25c25db1 in service fd00:1122:3344:101::28 - crucible bb55534c-1042-4af4-ad2f-9590803695ac in service fd00:1122:3344:101::2a - crucible cbe91cdc-cbb6-4760-aece-6ce08b67e85a in service fd00:1122:3344:101::23 - crucible e135441d-637e-4de9-8023-5ea0096347f3 in service fd00:1122:3344:101::29 - internal_dns f3628f0a-2301-4fc8-bcbf-961199771731 in service fd00:1122:3344:3::1 - internal_ntp b5d5491d-b3aa-4727-8b55-f66e0581ea4f in service fd00:1122:3344:101::21 - nexus 09937ebb-bb6a-495b-bc97-b58076b70a78 in service fd00:1122:3344:101::22 + crucible 315a3670-d019-425c-b7a6-c9429428b671 in service fd00:1122:3344:101::25 + crucible 413d3e02-e19f-400a-9718-a662347538f0 in service fd00:1122:3344:101::26 + crucible 6cb330f9-4609-4d6c-98ad-b5cc34245813 in service fd00:1122:3344:101::2b + crucible 6d725df0-0189-4429-b270-3eeb891d39c8 in service fd00:1122:3344:101::2a + crucible 8b47e1e8-0396-4e44-a4a5-ea891405c9f2 in service fd00:1122:3344:101::24 + crucible b43ce109-90d6-46f9-9df0-8c68bfe6d4a0 in service fd00:1122:3344:101::23 + crucible b5443ebd-1f5b-448c-8edc-b4ca25c25db1 in service fd00:1122:3344:101::27 + crucible bb55534c-1042-4af4-ad2f-9590803695ac in service fd00:1122:3344:101::29 + crucible e135441d-637e-4de9-8023-5ea0096347f3 in service fd00:1122:3344:101::28 + crucible fee71ee6-da42-4a7f-a00e-f56b6a3327ce in service fd00:1122:3344:101::2c + internal_dns cbe91cdc-cbb6-4760-aece-6ce08b67e85a in service fd00:1122:3344:3::1 + internal_ntp 09937ebb-bb6a-495b-bc97-b58076b70a78 in service fd00:1122:3344:101::21 + nexus f3628f0a-2301-4fc8-bcbf-961199771731 in service fd00:1122:3344:101::22 COCKROACHDB SETTINGS: @@ -219,17 +220,18 @@ to: blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ + clickhouse fe79023f-c5d5-4be5-ad2c-da4e9e9237e4 in service fd00:1122:3344:102::23 crucible 054f64a5-182c-4c28-8994-d2e082550201 in service fd00:1122:3344:102::26 crucible 3b5bffea-e5ed-44df-8468-fd4fa69757d8 in service fd00:1122:3344:102::27 crucible 53dd7fa4-899e-49ed-9fc2-48222db3e20d in service fd00:1122:3344:102::2a crucible 7db307d4-a6ed-4c47-bddf-6759161bf64a in service fd00:1122:3344:102::2c - crucible 8b8f7c02-7a18-4268-b045-2e286b464c5d in service fd00:1122:3344:102::23 crucible 95ad9a1d-4063-4874-974c-2fc92830be27 in service fd00:1122:3344:102::29 crucible bc095417-e2f0-4e95-b390-9cc3fc6e3c6d in service fd00:1122:3344:102::28 crucible d90401f1-fbc2-42cb-bf17-309ee0f922fe in service fd00:1122:3344:102::2b + crucible e8f994c0-0a1b-40e6-8db1-40a8ca89e503 in service fd00:1122:3344:102::2d crucible eaec16c0-0d44-4847-b2d6-31a5151bae52 in service fd00:1122:3344:102::24 crucible f97aa057-6485-45d0-9cb4-4af5b0831d48 in service fd00:1122:3344:102::25 - internal_dns fe79023f-c5d5-4be5-ad2c-da4e9e9237e4 in service fd00:1122:3344:1::1 + internal_dns 8b8f7c02-7a18-4268-b045-2e286b464c5d in service fd00:1122:3344:1::1 internal_ntp c67dd9a4-0d6c-4e9f-b28d-20003f211f7d in service fd00:1122:3344:102::21 nexus 94b45ce9-d3d8-413a-a76b-865da1f67930 in service fd00:1122:3344:102::22 @@ -256,19 +258,19 @@ to: blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ - crucible 728db429-8621-4e1e-9915-282aadfa27d1 in service fd00:1122:3344:103::25 - crucible a999e5fa-3edc-4dac-919a-d7b554cdae58 in service fd00:1122:3344:103::28 - crucible b416f299-c23c-46c8-9820-be2b66ffea0a in service fd00:1122:3344:103::29 - crucible c8aa84a5-a802-46c9-adcd-d61e9c8393c9 in service fd00:1122:3344:103::23 - crucible cc1dc86d-bd6f-4929-aa4a-9619012e9393 in service fd00:1122:3344:103::26 - crucible cd3bb540-e605-465f-8c62-177ac482d850 in service fd00:1122:3344:103::2b - crucible e7dd3e98-7fe7-4827-be7f-395ff9a5f542 in service fd00:1122:3344:103::24 - crucible e8971ab3-fb7d-4ad8-aae3-7f2fe87c51f3 in service fd00:1122:3344:103::27 - crucible f52aa245-7e1b-46c0-8a31-e09725f02caf in service fd00:1122:3344:103::2c - crucible fae49024-6cec-444d-a6c4-83658ab015a4 in service fd00:1122:3344:103::2a - internal_dns 4f2eb088-7d28-4c4e-a27c-746400ec65ba in service fd00:1122:3344:2::1 - internal_ntp e8f994c0-0a1b-40e6-8db1-40a8ca89e503 in service fd00:1122:3344:103::21 - nexus e9bf481e-323e-466e-842f-8107078c7137 in service fd00:1122:3344:103::22 + crucible 728db429-8621-4e1e-9915-282aadfa27d1 in service fd00:1122:3344:103::24 + crucible a999e5fa-3edc-4dac-919a-d7b554cdae58 in service fd00:1122:3344:103::27 + crucible b416f299-c23c-46c8-9820-be2b66ffea0a in service fd00:1122:3344:103::28 + crucible b5d5491d-b3aa-4727-8b55-f66e0581ea4f in service fd00:1122:3344:103::2c + crucible cc1dc86d-bd6f-4929-aa4a-9619012e9393 in service fd00:1122:3344:103::25 + crucible cd3bb540-e605-465f-8c62-177ac482d850 in service fd00:1122:3344:103::2a + crucible e7dd3e98-7fe7-4827-be7f-395ff9a5f542 in service fd00:1122:3344:103::23 + crucible e8971ab3-fb7d-4ad8-aae3-7f2fe87c51f3 in service fd00:1122:3344:103::26 + crucible f52aa245-7e1b-46c0-8a31-e09725f02caf in service fd00:1122:3344:103::2b + crucible fae49024-6cec-444d-a6c4-83658ab015a4 in service fd00:1122:3344:103::29 + internal_dns c8aa84a5-a802-46c9-adcd-d61e9c8393c9 in service fd00:1122:3344:2::1 + internal_ntp e9bf481e-323e-466e-842f-8107078c7137 in service fd00:1122:3344:103::21 + nexus 4f2eb088-7d28-4c4e-a27c-746400ec65ba in service fd00:1122:3344:103::22 sled 89d02b1b-478c-401a-8e28-7a26f74fa41b (active): @@ -293,19 +295,19 @@ to: blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ - crucible 315a3670-d019-425c-b7a6-c9429428b671 in service fd00:1122:3344:101::26 - crucible 413d3e02-e19f-400a-9718-a662347538f0 in service fd00:1122:3344:101::27 - crucible 6cb330f9-4609-4d6c-98ad-b5cc34245813 in service fd00:1122:3344:101::2c - crucible 6d725df0-0189-4429-b270-3eeb891d39c8 in service fd00:1122:3344:101::2b - crucible 8b47e1e8-0396-4e44-a4a5-ea891405c9f2 in service fd00:1122:3344:101::25 - crucible b43ce109-90d6-46f9-9df0-8c68bfe6d4a0 in service fd00:1122:3344:101::24 - crucible b5443ebd-1f5b-448c-8edc-b4ca25c25db1 in service fd00:1122:3344:101::28 - crucible bb55534c-1042-4af4-ad2f-9590803695ac in service fd00:1122:3344:101::2a - crucible cbe91cdc-cbb6-4760-aece-6ce08b67e85a in service fd00:1122:3344:101::23 - crucible e135441d-637e-4de9-8023-5ea0096347f3 in service fd00:1122:3344:101::29 - internal_dns f3628f0a-2301-4fc8-bcbf-961199771731 in service fd00:1122:3344:3::1 - internal_ntp b5d5491d-b3aa-4727-8b55-f66e0581ea4f in service fd00:1122:3344:101::21 - nexus 09937ebb-bb6a-495b-bc97-b58076b70a78 in service fd00:1122:3344:101::22 + crucible 315a3670-d019-425c-b7a6-c9429428b671 in service fd00:1122:3344:101::25 + crucible 413d3e02-e19f-400a-9718-a662347538f0 in service fd00:1122:3344:101::26 + crucible 6cb330f9-4609-4d6c-98ad-b5cc34245813 in service fd00:1122:3344:101::2b + crucible 6d725df0-0189-4429-b270-3eeb891d39c8 in service fd00:1122:3344:101::2a + crucible 8b47e1e8-0396-4e44-a4a5-ea891405c9f2 in service fd00:1122:3344:101::24 + crucible b43ce109-90d6-46f9-9df0-8c68bfe6d4a0 in service fd00:1122:3344:101::23 + crucible b5443ebd-1f5b-448c-8edc-b4ca25c25db1 in service fd00:1122:3344:101::27 + crucible bb55534c-1042-4af4-ad2f-9590803695ac in service fd00:1122:3344:101::29 + crucible e135441d-637e-4de9-8023-5ea0096347f3 in service fd00:1122:3344:101::28 + crucible fee71ee6-da42-4a7f-a00e-f56b6a3327ce in service fd00:1122:3344:101::2c + internal_dns cbe91cdc-cbb6-4760-aece-6ce08b67e85a in service fd00:1122:3344:3::1 + internal_ntp 09937ebb-bb6a-495b-bc97-b58076b70a78 in service fd00:1122:3344:101::21 + nexus f3628f0a-2301-4fc8-bcbf-961199771731 in service fd00:1122:3344:101::22 COCKROACHDB SETTINGS: @@ -350,17 +352,18 @@ to: blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ ++ clickhouse fe79023f-c5d5-4be5-ad2c-da4e9e9237e4 in service fd00:1122:3344:102::23 + crucible 054f64a5-182c-4c28-8994-d2e082550201 in service fd00:1122:3344:102::26 + crucible 3b5bffea-e5ed-44df-8468-fd4fa69757d8 in service fd00:1122:3344:102::27 + crucible 53dd7fa4-899e-49ed-9fc2-48222db3e20d in service fd00:1122:3344:102::2a + crucible 7db307d4-a6ed-4c47-bddf-6759161bf64a in service fd00:1122:3344:102::2c -+ crucible 8b8f7c02-7a18-4268-b045-2e286b464c5d in service fd00:1122:3344:102::23 + crucible 95ad9a1d-4063-4874-974c-2fc92830be27 in service fd00:1122:3344:102::29 + crucible bc095417-e2f0-4e95-b390-9cc3fc6e3c6d in service fd00:1122:3344:102::28 + crucible d90401f1-fbc2-42cb-bf17-309ee0f922fe in service fd00:1122:3344:102::2b ++ crucible e8f994c0-0a1b-40e6-8db1-40a8ca89e503 in service fd00:1122:3344:102::2d + crucible eaec16c0-0d44-4847-b2d6-31a5151bae52 in service fd00:1122:3344:102::24 + crucible f97aa057-6485-45d0-9cb4-4af5b0831d48 in service fd00:1122:3344:102::25 -+ internal_dns fe79023f-c5d5-4be5-ad2c-da4e9e9237e4 in service fd00:1122:3344:1::1 ++ internal_dns 8b8f7c02-7a18-4268-b045-2e286b464c5d in service fd00:1122:3344:1::1 + internal_ntp c67dd9a4-0d6c-4e9f-b28d-20003f211f7d in service fd00:1122:3344:102::21 + nexus 94b45ce9-d3d8-413a-a76b-865da1f67930 in service fd00:1122:3344:102::22 @@ -387,19 +390,19 @@ to: blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ -+ crucible 728db429-8621-4e1e-9915-282aadfa27d1 in service fd00:1122:3344:103::25 -+ crucible a999e5fa-3edc-4dac-919a-d7b554cdae58 in service fd00:1122:3344:103::28 -+ crucible b416f299-c23c-46c8-9820-be2b66ffea0a in service fd00:1122:3344:103::29 -+ crucible c8aa84a5-a802-46c9-adcd-d61e9c8393c9 in service fd00:1122:3344:103::23 -+ crucible cc1dc86d-bd6f-4929-aa4a-9619012e9393 in service fd00:1122:3344:103::26 -+ crucible cd3bb540-e605-465f-8c62-177ac482d850 in service fd00:1122:3344:103::2b -+ crucible e7dd3e98-7fe7-4827-be7f-395ff9a5f542 in service fd00:1122:3344:103::24 -+ crucible e8971ab3-fb7d-4ad8-aae3-7f2fe87c51f3 in service fd00:1122:3344:103::27 -+ crucible f52aa245-7e1b-46c0-8a31-e09725f02caf in service fd00:1122:3344:103::2c -+ crucible fae49024-6cec-444d-a6c4-83658ab015a4 in service fd00:1122:3344:103::2a -+ internal_dns 4f2eb088-7d28-4c4e-a27c-746400ec65ba in service fd00:1122:3344:2::1 -+ internal_ntp e8f994c0-0a1b-40e6-8db1-40a8ca89e503 in service fd00:1122:3344:103::21 -+ nexus e9bf481e-323e-466e-842f-8107078c7137 in service fd00:1122:3344:103::22 ++ crucible 728db429-8621-4e1e-9915-282aadfa27d1 in service fd00:1122:3344:103::24 ++ crucible a999e5fa-3edc-4dac-919a-d7b554cdae58 in service fd00:1122:3344:103::27 ++ crucible b416f299-c23c-46c8-9820-be2b66ffea0a in service fd00:1122:3344:103::28 ++ crucible b5d5491d-b3aa-4727-8b55-f66e0581ea4f in service fd00:1122:3344:103::2c ++ crucible cc1dc86d-bd6f-4929-aa4a-9619012e9393 in service fd00:1122:3344:103::25 ++ crucible cd3bb540-e605-465f-8c62-177ac482d850 in service fd00:1122:3344:103::2a ++ crucible e7dd3e98-7fe7-4827-be7f-395ff9a5f542 in service fd00:1122:3344:103::23 ++ crucible e8971ab3-fb7d-4ad8-aae3-7f2fe87c51f3 in service fd00:1122:3344:103::26 ++ crucible f52aa245-7e1b-46c0-8a31-e09725f02caf in service fd00:1122:3344:103::2b ++ crucible fae49024-6cec-444d-a6c4-83658ab015a4 in service fd00:1122:3344:103::29 ++ internal_dns c8aa84a5-a802-46c9-adcd-d61e9c8393c9 in service fd00:1122:3344:2::1 ++ internal_ntp e9bf481e-323e-466e-842f-8107078c7137 in service fd00:1122:3344:103::21 ++ nexus 4f2eb088-7d28-4c4e-a27c-746400ec65ba in service fd00:1122:3344:103::22 sled 89d02b1b-478c-401a-8e28-7a26f74fa41b (active): @@ -424,19 +427,19 @@ to: blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a ------------------------------------------------------------------------------------------ zone type zone id disposition underlay IP ------------------------------------------------------------------------------------------ -+ crucible 315a3670-d019-425c-b7a6-c9429428b671 in service fd00:1122:3344:101::26 -+ crucible 413d3e02-e19f-400a-9718-a662347538f0 in service fd00:1122:3344:101::27 -+ crucible 6cb330f9-4609-4d6c-98ad-b5cc34245813 in service fd00:1122:3344:101::2c -+ crucible 6d725df0-0189-4429-b270-3eeb891d39c8 in service fd00:1122:3344:101::2b -+ crucible 8b47e1e8-0396-4e44-a4a5-ea891405c9f2 in service fd00:1122:3344:101::25 -+ crucible b43ce109-90d6-46f9-9df0-8c68bfe6d4a0 in service fd00:1122:3344:101::24 -+ crucible b5443ebd-1f5b-448c-8edc-b4ca25c25db1 in service fd00:1122:3344:101::28 -+ crucible bb55534c-1042-4af4-ad2f-9590803695ac in service fd00:1122:3344:101::2a -+ crucible cbe91cdc-cbb6-4760-aece-6ce08b67e85a in service fd00:1122:3344:101::23 -+ crucible e135441d-637e-4de9-8023-5ea0096347f3 in service fd00:1122:3344:101::29 -+ internal_dns f3628f0a-2301-4fc8-bcbf-961199771731 in service fd00:1122:3344:3::1 -+ internal_ntp b5d5491d-b3aa-4727-8b55-f66e0581ea4f in service fd00:1122:3344:101::21 -+ nexus 09937ebb-bb6a-495b-bc97-b58076b70a78 in service fd00:1122:3344:101::22 ++ crucible 315a3670-d019-425c-b7a6-c9429428b671 in service fd00:1122:3344:101::25 ++ crucible 413d3e02-e19f-400a-9718-a662347538f0 in service fd00:1122:3344:101::26 ++ crucible 6cb330f9-4609-4d6c-98ad-b5cc34245813 in service fd00:1122:3344:101::2b ++ crucible 6d725df0-0189-4429-b270-3eeb891d39c8 in service fd00:1122:3344:101::2a ++ crucible 8b47e1e8-0396-4e44-a4a5-ea891405c9f2 in service fd00:1122:3344:101::24 ++ crucible b43ce109-90d6-46f9-9df0-8c68bfe6d4a0 in service fd00:1122:3344:101::23 ++ crucible b5443ebd-1f5b-448c-8edc-b4ca25c25db1 in service fd00:1122:3344:101::27 ++ crucible bb55534c-1042-4af4-ad2f-9590803695ac in service fd00:1122:3344:101::29 ++ crucible e135441d-637e-4de9-8023-5ea0096347f3 in service fd00:1122:3344:101::28 ++ crucible fee71ee6-da42-4a7f-a00e-f56b6a3327ce in service fd00:1122:3344:101::2c ++ internal_dns cbe91cdc-cbb6-4760-aece-6ce08b67e85a in service fd00:1122:3344:3::1 ++ internal_ntp 09937ebb-bb6a-495b-bc97-b58076b70a78 in service fd00:1122:3344:101::21 ++ nexus f3628f0a-2301-4fc8-bcbf-961199771731 in service fd00:1122:3344:101::22 COCKROACHDB SETTINGS: diff --git a/dev-tools/reconfigurator-cli/tests/test_basic.rs b/dev-tools/reconfigurator-cli/tests/test_basic.rs index 84af656924..d451996e0b 100644 --- a/dev-tools/reconfigurator-cli/tests/test_basic.rs +++ b/dev-tools/reconfigurator-cli/tests/test_basic.rs @@ -58,8 +58,7 @@ fn test_example() { // The example system uses a fixed seed, which means that UUIDs are // deterministic. Some of the test commands also use those UUIDs, and it's // convenient for everyone if they aren't redacted. - let stdout_text = - Redactor::new().redact_uuids(false).do_redact(&stdout_text); + let stdout_text = Redactor::default().uuids(false).do_redact(&stdout_text); assert_contents("tests/output/cmd-example-stdout", &stdout_text); assert_contents("tests/output/cmd-example-stderr", &stderr_text); } From 3555e6b843645c032f1a8c4f7a392fc0dc500c63 Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 11 Oct 2024 11:24:08 -0700 Subject: [PATCH 3/4] slog debug Created using spr 1.3.6-beta.1 --- nexus/reconfigurator/planning/src/example.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/reconfigurator/planning/src/example.rs b/nexus/reconfigurator/planning/src/example.rs index 8db0e14e65..df6c4d0e52 100644 --- a/nexus/reconfigurator/planning/src/example.rs +++ b/nexus/reconfigurator/planning/src/example.rs @@ -192,7 +192,7 @@ impl ExampleSystemBuilder { pub fn build(&self) -> (ExampleSystem, Blueprint) { let nexus_count = self.get_nexus_zones(); - slog::trace!( + slog::debug!( &self.log, "Creating example system"; "nsleds" => self.nsleds, From a2065fcd5ec639c0175b9851b472462e6bb2f63a Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 11 Oct 2024 11:27:27 -0700 Subject: [PATCH 4/4] use wipe Created using spr 1.3.6-beta.1 --- dev-tools/reconfigurator-cli/src/main.rs | 12 ++++++------ .../reconfigurator-cli/tests/input/cmds-example.txt | 2 +- .../tests/output/cmd-example-stdout | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dev-tools/reconfigurator-cli/src/main.rs b/dev-tools/reconfigurator-cli/src/main.rs index f046cc7008..4cc7eafcde 100644 --- a/dev-tools/reconfigurator-cli/src/main.rs +++ b/dev-tools/reconfigurator-cli/src/main.rs @@ -138,7 +138,7 @@ impl ReconfiguratorSim { } // Reset the state of the REPL. - fn reset(&mut self) { + fn wipe(&mut self) { *self = Self::new(self.log.clone()); } @@ -362,7 +362,7 @@ fn process_entry(sim: &mut ReconfiguratorSim, entry: String) -> LoopResult { Commands::LoadExample(args) => cmd_load_example(sim, args), Commands::FileContents(args) => cmd_file_contents(args), Commands::Save(args) => cmd_save(sim, args), - Commands::Reset => cmd_reset(sim), + Commands::Wipe => cmd_wipe(sim), }; match cmd_result { @@ -436,7 +436,7 @@ enum Commands { /// show information about what's in a saved file FileContents(FileContentsArgs), /// reset the state of the REPL - Reset, + Wipe, } #[derive(Debug, Args)] @@ -1089,9 +1089,9 @@ fn cmd_save( ))) } -fn cmd_reset(sim: &mut ReconfiguratorSim) -> anyhow::Result> { - sim.reset(); - Ok(Some("reset reconfigurator-sim state".to_string())) +fn cmd_wipe(sim: &mut ReconfiguratorSim) -> anyhow::Result> { + sim.wipe(); + Ok(Some("wiped reconfigurator-sim state".to_string())) } fn cmd_show(sim: &mut ReconfiguratorSim) -> anyhow::Result> { diff --git a/dev-tools/reconfigurator-cli/tests/input/cmds-example.txt b/dev-tools/reconfigurator-cli/tests/input/cmds-example.txt index 57eef26b79..b3143ac016 100644 --- a/dev-tools/reconfigurator-cli/tests/input/cmds-example.txt +++ b/dev-tools/reconfigurator-cli/tests/input/cmds-example.txt @@ -15,7 +15,7 @@ blueprint-diff-inventory 9e187896-7809-46d0-9210-d75be1b3c4d4 ade5749d-bdf3-4fab inventory-generate blueprint-diff-inventory b32394d8-7d79-486f-8657-fd5219508181 ade5749d-bdf3-4fab-a8ae-00bea01b3a5a -reset +wipe load-example --seed test-basic --nsleds 1 --ndisks-per-sled 4 --no-zones sled-list diff --git a/dev-tools/reconfigurator-cli/tests/output/cmd-example-stdout b/dev-tools/reconfigurator-cli/tests/output/cmd-example-stdout index 3b8b8a45a4..a228c13d3e 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmd-example-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmd-example-stdout @@ -454,8 +454,8 @@ to: blueprint ade5749d-bdf3-4fab-a8ae-00bea01b3a5a > -> reset -reset reconfigurator-sim state +> wipe +wiped reconfigurator-sim state > load-example --seed test-basic --nsleds 1 --ndisks-per-sled 4 --no-zones loaded example system with: