diff --git a/Cargo.lock b/Cargo.lock index dbac1592cf..f16e785b6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5454,6 +5454,7 @@ dependencies = [ "expectorate", "libc", "omicron-common", + "omicron-uuid-kinds", "omicron-workspace-hack", "schemars", "serde", diff --git a/clients/sled-agent-client/src/lib.rs b/clients/sled-agent-client/src/lib.rs index 36bf516130..894a30daf5 100644 --- a/clients/sled-agent-client/src/lib.rs +++ b/clients/sled-agent-client/src/lib.rs @@ -72,6 +72,7 @@ progenitor::generate_api!( SwitchLocation = omicron_common::api::external::SwitchLocation, TypedUuidForDatasetKind = omicron_uuid_kinds::DatasetUuid, TypedUuidForInstanceKind = omicron_uuid_kinds::InstanceUuid, + TypedUuidForOmicronZoneKind = omicron_uuid_kinds::OmicronZoneUuid, TypedUuidForPropolisKind = omicron_uuid_kinds::PropolisUuid, TypedUuidForZpoolKind = omicron_uuid_kinds::ZpoolUuid, Vni = omicron_common::api::external::Vni, diff --git a/nexus-config/Cargo.toml b/nexus-config/Cargo.toml index 9d23be302f..be451cbc5e 100644 --- a/nexus-config/Cargo.toml +++ b/nexus-config/Cargo.toml @@ -11,6 +11,7 @@ anyhow.workspace = true camino.workspace = true dropshot.workspace = true omicron-common.workspace = true +omicron-uuid-kinds.workspace = true omicron-workspace-hack.workspace = true schemars.workspace = true serde.workspace = true diff --git a/nexus-config/src/nexus_config.rs b/nexus-config/src/nexus_config.rs index 7f2726cc59..93b223c506 100644 --- a/nexus-config/src/nexus_config.rs +++ b/nexus-config/src/nexus_config.rs @@ -14,6 +14,7 @@ use omicron_common::address::Ipv6Subnet; use omicron_common::address::NEXUS_TECHPORT_EXTERNAL_PORT; use omicron_common::address::RACK_PREFIX; use omicron_common::api::internal::shared::SwitchLocation; +use omicron_uuid_kinds::OmicronZoneUuid; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::serde_as; @@ -150,7 +151,7 @@ pub enum InternalDns { #[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] pub struct DeploymentConfig { /// Uuid of the Nexus instance - pub id: Uuid, + pub id: OmicronZoneUuid, /// Uuid of the Rack where Nexus is executing. pub rack_id: Uuid, /// Port on which the "techport external" dropshot server should listen. diff --git a/nexus-sled-agent-shared/src/inventory.rs b/nexus-sled-agent-shared/src/inventory.rs index d695f3a14b..eda237a741 100644 --- a/nexus-sled-agent-shared/src/inventory.rs +++ b/nexus-sled-agent-shared/src/inventory.rs @@ -14,8 +14,8 @@ use omicron_common::{ disk::DiskVariant, zpool_name::ZpoolName, }; -use omicron_uuid_kinds::DatasetUuid; use omicron_uuid_kinds::ZpoolUuid; +use omicron_uuid_kinds::{DatasetUuid, OmicronZoneUuid}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; // Export this type for convenience -- this way, dependents don't have to @@ -142,7 +142,7 @@ impl OmicronZonesConfig { Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] pub struct OmicronZoneConfig { - pub id: Uuid, + pub id: OmicronZoneUuid, pub underlay_address: Ipv6Addr, /// The pool on which we'll place this zone's root filesystem. diff --git a/nexus/db-model/src/deployment.rs b/nexus/db-model/src/deployment.rs index 168c118ea2..b9046519c8 100644 --- a/nexus/db-model/src/deployment.rs +++ b/nexus/db-model/src/deployment.rs @@ -40,10 +40,10 @@ use nexus_types::deployment::{ use omicron_common::api::internal::shared::NetworkInterface; use omicron_common::disk::DiskIdentity; use omicron_common::zpool_name::ZpoolName; -use omicron_uuid_kinds::ZpoolUuid; -use omicron_uuid_kinds::{ExternalIpKind, SledKind, ZpoolKind}; -use omicron_uuid_kinds::{ExternalIpUuid, GenericUuid, OmicronZoneUuid}; -use omicron_uuid_kinds::{OmicronZoneKind, SledUuid}; +use omicron_uuid_kinds::{ + ExternalIpKind, ExternalIpUuid, GenericUuid, OmicronZoneKind, + OmicronZoneUuid, SledKind, SledUuid, ZpoolKind, ZpoolUuid, +}; use std::net::{IpAddr, SocketAddrV6}; use uuid::Uuid; @@ -238,7 +238,7 @@ impl BpSledOmicronZones { pub struct BpOmicronZone { pub blueprint_id: Uuid, pub sled_id: DbTypedUuid, - pub id: Uuid, + pub id: DbTypedUuid, pub underlay_address: ipv6::Ipv6Addr, pub zone_type: ZoneType, pub primary_service_ip: ipv6::Ipv6Addr, @@ -281,7 +281,7 @@ impl BpOmicronZone { // `blueprint_zone.zone_type` blueprint_id, sled_id: sled_id.into(), - id: blueprint_zone.id.into_untyped_uuid(), + id: blueprint_zone.id.into(), underlay_address: blueprint_zone.underlay_address.into(), external_ip_id, filesystem_pool: blueprint_zone @@ -526,7 +526,7 @@ impl BpOmicronZone { // Result) we immediately return. We check the inner result later, but // only if some code path tries to use `nic` and it's not present. let nic = omicron_zone_config::nic_row_to_network_interface( - self.id, + self.id.into(), self.bp_nic_id, nic_row.map(Into::into), )?; @@ -691,7 +691,7 @@ impl BpOmicronZone { Ok(BlueprintZoneConfig { disposition: self.disposition.into(), - id: OmicronZoneUuid::from_untyped_uuid(self.id), + id: self.id.into(), underlay_address: self.underlay_address.into(), filesystem_pool: self .filesystem_pool @@ -768,7 +768,7 @@ impl BpOmicronZoneNic { let Some((_, nic)) = zone.zone_type.external_networking() else { return Ok(None); }; - let nic = OmicronZoneNic::new(zone.id.into_untyped_uuid(), nic)?; + let nic = OmicronZoneNic::new(zone.id, nic)?; Ok(Some(Self { blueprint_id, id: nic.id, @@ -784,7 +784,7 @@ impl BpOmicronZoneNic { pub fn into_network_interface_for_zone( self, - zone_id: Uuid, + zone_id: OmicronZoneUuid, ) -> Result { let zone_nic = OmicronZoneNic::from(self); zone_nic.into_network_interface_for_zone(zone_id) diff --git a/nexus/db-model/src/inventory.rs b/nexus/db-model/src/inventory.rs index d5754965f2..a57ca64b7c 100644 --- a/nexus/db-model/src/inventory.rs +++ b/nexus/db-model/src/inventory.rs @@ -37,14 +37,14 @@ use nexus_types::inventory::{ }; use omicron_common::api::internal::shared::NetworkInterface; use omicron_common::zpool_name::ZpoolName; -use omicron_uuid_kinds::CollectionKind; -use omicron_uuid_kinds::CollectionUuid; use omicron_uuid_kinds::DatasetKind; use omicron_uuid_kinds::GenericUuid; use omicron_uuid_kinds::SledKind; use omicron_uuid_kinds::SledUuid; use omicron_uuid_kinds::ZpoolKind; use omicron_uuid_kinds::ZpoolUuid; +use omicron_uuid_kinds::{CollectionKind, OmicronZoneKind}; +use omicron_uuid_kinds::{CollectionUuid, OmicronZoneUuid}; use std::net::{IpAddr, SocketAddrV6}; use uuid::Uuid; @@ -1116,7 +1116,7 @@ impl From for ZoneType { pub struct InvOmicronZone { pub inv_collection_id: DbTypedUuid, pub sled_id: DbTypedUuid, - pub id: Uuid, + pub id: DbTypedUuid, pub underlay_address: ipv6::Ipv6Addr, pub zone_type: ZoneType, pub primary_service_ip: ipv6::Ipv6Addr, @@ -1151,7 +1151,7 @@ impl InvOmicronZone { // `zone.zone_type` inv_collection_id: inv_collection_id.into(), sled_id: sled_id.into(), - id: zone.id, + id: zone.id.into(), underlay_address: zone.underlay_address.into(), filesystem_pool: zone .filesystem_pool @@ -1362,7 +1362,7 @@ impl InvOmicronZone { // Result) we immediately return. We check the inner result later, but // only if some code path tries to use `nic` and it's not present. let nic = omicron_zone_config::nic_row_to_network_interface( - self.id, + self.id.into(), self.nic_id, nic_row.map(Into::into), )?; @@ -1482,7 +1482,7 @@ impl InvOmicronZone { }; Ok(OmicronZoneConfig { - id: self.id, + id: self.id.into(), underlay_address: self.underlay_address.into(), filesystem_pool: self .filesystem_pool @@ -1545,7 +1545,7 @@ impl InvOmicronZoneNic { pub fn into_network_interface_for_zone( self, - zone_id: Uuid, + zone_id: OmicronZoneUuid, ) -> Result { let zone_nic = OmicronZoneNic::from(self); zone_nic.into_network_interface_for_zone(zone_id) diff --git a/nexus/db-model/src/omicron_zone_config.rs b/nexus/db-model/src/omicron_zone_config.rs index 0abc2bb4ec..44396d7a2a 100644 --- a/nexus/db-model/src/omicron_zone_config.rs +++ b/nexus/db-model/src/omicron_zone_config.rs @@ -18,6 +18,7 @@ use ipnetwork::IpNetwork; use nexus_sled_agent_shared::inventory::OmicronZoneDataset; use nexus_types::inventory::NetworkInterface; use omicron_common::api::internal::shared::NetworkInterfaceKind; +use omicron_uuid_kinds::{GenericUuid, OmicronZoneUuid}; use std::net::{IpAddr, SocketAddr, SocketAddrV6}; use uuid::Uuid; @@ -55,7 +56,7 @@ pub fn ntp_dns_servers_to_omicron_internal( /// immediately. The inner result represents an operational error and should /// only be unwrapped when the nic is used. pub fn nic_row_to_network_interface( - zone_id: Uuid, + zone_id: OmicronZoneUuid, nic_id: Option, nic_row: Option, ) -> anyhow::Result> { @@ -133,7 +134,7 @@ pub(crate) struct OmicronZoneNic { impl OmicronZoneNic { pub(crate) fn new( - zone_id: Uuid, + zone_id: OmicronZoneUuid, nic: &nexus_types::inventory::NetworkInterface, ) -> anyhow::Result { // We do not bother storing the NIC's kind and associated id @@ -142,7 +143,7 @@ impl OmicronZoneNic { ensure!( matches!( nic.kind, - NetworkInterfaceKind::Service{ id } if id == zone_id + NetworkInterfaceKind::Service { id } if id == zone_id.into_untyped_uuid() ), "expected zone's NIC kind to be \"service\" and the \ id to match the zone's id ({zone_id})", @@ -162,12 +163,14 @@ impl OmicronZoneNic { pub(crate) fn into_network_interface_for_zone( self, - zone_id: Uuid, + zone_id: OmicronZoneUuid, ) -> anyhow::Result { Ok(NetworkInterface { id: self.id, ip: self.ip.ip(), - kind: NetworkInterfaceKind::Service { id: zone_id }, + kind: NetworkInterfaceKind::Service { + id: zone_id.into_untyped_uuid(), + }, mac: *self.mac, name: self.name.into(), primary: self.is_primary, diff --git a/nexus/db-model/src/saga_types.rs b/nexus/db-model/src/saga_types.rs index 010c717356..1ffd78bc94 100644 --- a/nexus/db-model/src/saga_types.rs +++ b/nexus/db-model/src/saga_types.rs @@ -20,6 +20,7 @@ use diesel::serialize::{self, ToSql}; use diesel::sql_types; use omicron_common::api::external::Error; use omicron_common::api::external::Generation; +use omicron_uuid_kinds::{GenericUuid, OmicronZoneUuid}; use std::convert::TryFrom; use std::io::Write; use std::sync::Arc; @@ -64,6 +65,12 @@ NewtypeDebug! { () pub struct SecId(Uuid); } NewtypeDisplay! { () pub struct SecId(Uuid); } NewtypeFrom! { () pub struct SecId(Uuid); } +impl From for SecId { + fn from(g: OmicronZoneUuid) -> Self { + g.into_untyped_uuid().into() + } +} + impl From<&SecId> for Uuid { fn from(g: &SecId) -> Self { g.0 diff --git a/nexus/inventory/src/collector.rs b/nexus/inventory/src/collector.rs index 25f8ffded6..d363a9b31c 100644 --- a/nexus/inventory/src/collector.rs +++ b/nexus/inventory/src/collector.rs @@ -384,6 +384,7 @@ mod test { use omicron_common::api::external::Generation; use omicron_common::zpool_name::ZpoolName; use omicron_sled_agent::sim; + use omicron_uuid_kinds::OmicronZoneUuid; use omicron_uuid_kinds::ZpoolUuid; use std::fmt::Write; use std::net::Ipv6Addr; @@ -532,7 +533,7 @@ mod test { async fn sim_sled_agent( log: slog::Logger, sled_id: Uuid, - zone_id: Uuid, + zone_id: OmicronZoneUuid, ) -> sim::Server { // Start a simulated sled agent. let config = sim::Config::for_testing( diff --git a/nexus/reconfigurator/execution/src/dns.rs b/nexus/reconfigurator/execution/src/dns.rs index aab3839bd0..9b0b95a0e0 100644 --- a/nexus/reconfigurator/execution/src/dns.rs +++ b/nexus/reconfigurator/execution/src/dns.rs @@ -467,7 +467,6 @@ mod test { use internal_dns::resolver::Resolver; use internal_dns::ServiceName; use internal_dns::DNS_ZONE; - use newtype_uuid::GenericUuid; use nexus_db_model::DnsGroup; use nexus_db_model::Silo; use nexus_db_queries::authn; @@ -745,7 +744,7 @@ mod test { }; Ok(BlueprintZoneConfig { disposition, - id: OmicronZoneUuid::from_untyped_uuid(config.id), + id: config.id, underlay_address: config.underlay_address, filesystem_pool: config.filesystem_pool, zone_type, diff --git a/nexus/reconfigurator/execution/src/lib.rs b/nexus/reconfigurator/execution/src/lib.rs index 45738d7985..bd0c23fcf5 100644 --- a/nexus/reconfigurator/execution/src/lib.rs +++ b/nexus/reconfigurator/execution/src/lib.rs @@ -20,6 +20,7 @@ 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; @@ -29,7 +30,6 @@ use std::net::SocketAddrV6; use std::sync::Arc; use tokio::sync::mpsc; use update_engine::merge_anyhow_list; -use uuid::Uuid; mod cockroachdb; mod datasets; @@ -96,7 +96,7 @@ pub async fn realize_blueprint( datastore: &DataStore, resolver: &Resolver, blueprint: &Blueprint, - nexus_id: Uuid, + nexus_id: OmicronZoneUuid, sender: mpsc::Sender, ) -> Result { realize_blueprint_with_overrides( @@ -116,7 +116,7 @@ pub async fn realize_blueprint_with_overrides( datastore: &DataStore, resolver: &Resolver, blueprint: &Blueprint, - nexus_id: Uuid, + nexus_id: OmicronZoneUuid, overrides: &Overridables, sender: mpsc::Sender, ) -> Result { @@ -406,7 +406,7 @@ fn register_dns_records_step<'a>( opctx: &'a OpContext, datastore: &'a DataStore, blueprint: &'a Blueprint, - nexus_id: Uuid, + nexus_id: OmicronZoneUuid, overrides: &'a Overridables, sleds: SharedStepHandle>>, ) { @@ -530,7 +530,7 @@ fn register_reassign_sagas_step<'a>( opctx: &'a OpContext, datastore: &'a DataStore, blueprint: &'a Blueprint, - nexus_id: Uuid, + nexus_id: OmicronZoneUuid, ) -> StepHandle { // For this and subsequent steps, we'll assume that any errors that we // encounter do *not* require stopping execution. We'll just accumulate @@ -545,7 +545,7 @@ fn register_reassign_sagas_step<'a>( // For any expunged Nexus zones, re-assign in-progress sagas to // some other Nexus. If this fails for some reason, it doesn't // affect anything else. - let sec_id = nexus_db_model::SecId(nexus_id); + let sec_id = nexus_db_model::SecId::from(nexus_id); let reassigned = sagas::reassign_sagas_from_expunged( &opctx, datastore, blueprint, sec_id, ) diff --git a/nexus/reconfigurator/execution/src/test_utils.rs b/nexus/reconfigurator/execution/src/test_utils.rs index 0e16b570c1..3f623af6c4 100644 --- a/nexus/reconfigurator/execution/src/test_utils.rs +++ b/nexus/reconfigurator/execution/src/test_utils.rs @@ -7,8 +7,8 @@ use internal_dns::resolver::Resolver; use nexus_db_queries::{context::OpContext, db::DataStore}; use nexus_types::deployment::{execution::EventBuffer, Blueprint}; +use omicron_uuid_kinds::OmicronZoneUuid; use update_engine::TerminalKind; -use uuid::Uuid; use crate::{overridables::Overridables, RealizeBlueprintOutput}; @@ -34,7 +34,7 @@ pub(crate) async fn realize_blueprint_and_expect( datastore, resolver, blueprint, - Uuid::new_v4(), + OmicronZoneUuid::new_v4(), overrides, sender, ) diff --git a/nexus/src/app/background/init.rs b/nexus/src/app/background/init.rs index b839af2bb3..dc2cb8fbfe 100644 --- a/nexus/src/app/background/init.rs +++ b/nexus/src/app/background/init.rs @@ -128,6 +128,7 @@ use nexus_config::DnsTasksConfig; use nexus_db_model::DnsGroup; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; +use omicron_uuid_kinds::OmicronZoneUuid; use oximeter::types::ProducerRegistry; use std::collections::BTreeMap; use std::sync::Arc; @@ -719,7 +720,7 @@ impl BackgroundTasksInitializer { { let task_impl = Box::new(saga_recovery::SagaRecovery::new( datastore.clone(), - nexus_db_model::SecId(args.nexus_id), + nexus_db_model::SecId::from(args.nexus_id), args.saga_recovery, )); @@ -820,7 +821,7 @@ pub struct BackgroundTasksData { /// rack identifier pub rack_id: Uuid, /// nexus identifier - pub nexus_id: Uuid, + pub nexus_id: OmicronZoneUuid, /// internal DNS DNS resolver, used when tasks need to contact other /// internal services pub resolver: internal_dns::resolver::Resolver, diff --git a/nexus/src/app/background/tasks/blueprint_execution.rs b/nexus/src/app/background/tasks/blueprint_execution.rs index 0a138b8757..c4fd916d5f 100644 --- a/nexus/src/app/background/tasks/blueprint_execution.rs +++ b/nexus/src/app/background/tasks/blueprint_execution.rs @@ -14,11 +14,11 @@ use nexus_reconfigurator_execution::RealizeBlueprintOutput; use nexus_types::deployment::{ execution::EventBuffer, Blueprint, BlueprintTarget, }; +use omicron_uuid_kinds::OmicronZoneUuid; use serde_json::json; use std::sync::Arc; use tokio::sync::watch; use update_engine::NestedError; -use uuid::Uuid; /// Background task that takes a [`Blueprint`] and realizes the change to /// the state of the system based on the `Blueprint`. @@ -26,7 +26,7 @@ pub struct BlueprintExecutor { datastore: Arc, resolver: Resolver, rx_blueprint: watch::Receiver>>, - nexus_id: Uuid, + nexus_id: OmicronZoneUuid, tx: watch::Sender, saga_recovery: Activator, } @@ -38,7 +38,7 @@ impl BlueprintExecutor { rx_blueprint: watch::Receiver< Option>, >, - nexus_id: Uuid, + nexus_id: OmicronZoneUuid, saga_recovery: Activator, ) -> BlueprintExecutor { let (tx, _) = watch::channel(0); @@ -318,7 +318,7 @@ mod test { datastore.clone(), resolver.clone(), blueprint_rx, - Uuid::new_v4(), + OmicronZoneUuid::new_v4(), Activator::new(), ); diff --git a/nexus/src/app/background/tasks/instance_watcher.rs b/nexus/src/app/background/tasks/instance_watcher.rs index 6bad1d7406..1232e7e19a 100644 --- a/nexus/src/app/background/tasks/instance_watcher.rs +++ b/nexus/src/app/background/tasks/instance_watcher.rs @@ -23,6 +23,7 @@ use omicron_common::api::external::InstanceState; use omicron_common::api::internal::nexus; use omicron_common::api::internal::nexus::SledVmmState; use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::OmicronZoneUuid; use omicron_uuid_kinds::PropolisUuid; use oximeter::types::ProducerRegistry; use sled_agent_client::Client as SledAgentClient; @@ -286,7 +287,7 @@ impl InstanceWatcher { /// (rather than positional arguments) and can't be swapped accidentally. #[derive(Copy, Clone)] pub struct WatcherIdentity { - pub nexus_id: Uuid, + pub nexus_id: OmicronZoneUuid, pub rack_id: Uuid, } @@ -301,7 +302,7 @@ impl VirtualMachine { let addr = sled.address(); Self { rack_id, - nexus_id, + nexus_id: nexus_id.into_untyped_uuid(), instance_id: instance.id(), silo_id: project.silo_id, project_id: project.id(), diff --git a/nexus/src/app/mod.rs b/nexus/src/app/mod.rs index 5cfacd0c9c..c004a14c7d 100644 --- a/nexus/src/app/mod.rs +++ b/nexus/src/app/mod.rs @@ -30,6 +30,7 @@ use omicron_common::address::MGD_PORT; use omicron_common::address::MGS_PORT; use omicron_common::api::external::Error; use omicron_common::api::internal::shared::SwitchLocation; +use omicron_uuid_kinds::OmicronZoneUuid; use oximeter_producer::Server as ProducerServer; use slog::Logger; use std::collections::HashMap; @@ -120,7 +121,7 @@ pub const MAX_SSH_KEYS_PER_INSTANCE: u32 = 100; /// Manages an Oxide fleet -- the heart of the control plane pub struct Nexus { /// uuid for this nexus instance. - id: Uuid, + id: OmicronZoneUuid, /// uuid for this rack rack_id: Uuid, @@ -552,8 +553,8 @@ impl Nexus { } /// Return the ID for this Nexus instance. - pub fn id(&self) -> &Uuid { - &self.id + pub fn id(&self) -> OmicronZoneUuid { + self.id } /// Return the rack ID for this Nexus instance. diff --git a/nexus/src/context.rs b/nexus/src/context.rs index 9620a3937a..a2a50958e4 100644 --- a/nexus/src/context.rs +++ b/nexus/src/context.rs @@ -19,6 +19,7 @@ use nexus_db_queries::context::{OpContext, OpKind}; use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::{authn, authz, db}; use omicron_common::address::{Ipv6Subnet, AZ_PREFIX}; +use omicron_uuid_kinds::GenericUuid; use oximeter::types::ProducerRegistry; use oximeter_instruments::http::{HttpService, LatencyTracker}; use slog::Logger; @@ -144,7 +145,7 @@ impl ServerContext { let create_tracker = |name: &str| { let target = HttpService { name: name.to_string().into(), - id: config.deployment.id, + id: config.deployment.id.into_untyped_uuid(), }; // Start at 1 microsecond == 1e3 nanoseconds. const LATENCY_START_POWER: u16 = 3; @@ -159,7 +160,8 @@ impl ServerContext { }; let internal_latencies = create_tracker("nexus-internal"); let external_latencies = create_tracker("nexus-external"); - let producer_registry = ProducerRegistry::with_id(config.deployment.id); + let producer_registry = + ProducerRegistry::with_id(config.deployment.id.into_untyped_uuid()); producer_registry .register_producer(internal_latencies.clone()) .unwrap(); diff --git a/nexus/test-utils/src/lib.rs b/nexus/test-utils/src/lib.rs index 180ca3c743..35ddff5f5f 100644 --- a/nexus/test-utils/src/lib.rs +++ b/nexus/test-utils/src/lib.rs @@ -184,7 +184,7 @@ pub fn load_test_config() -> NexusConfig { let config_file_path = Utf8Path::new("tests/config.test.toml"); let mut config = NexusConfig::from_file(config_file_path) .expect("failed to load config.test.toml"); - config.deployment.id = Uuid::new_v4(); + config.deployment.id = OmicronZoneUuid::new_v4(); config } @@ -663,8 +663,7 @@ impl<'a, N: NexusServer> ControlPlaneTestContextBuilder<'a, N> { .expect("ran out of MAC addresses"); let external_address = self.config.deployment.dropshot_external.dropshot.bind_address.ip(); - let nexus_id = - OmicronZoneUuid::from_untyped_uuid(self.config.deployment.id); + let nexus_id = self.config.deployment.id; self.rack_init_builder.add_service_to_dns( nexus_id, address, diff --git a/nexus/tests/integration_tests/metrics.rs b/nexus/tests/integration_tests/metrics.rs index f51f57d414..3b8cd707fc 100644 --- a/nexus/tests/integration_tests/metrics.rs +++ b/nexus/tests/integration_tests/metrics.rs @@ -725,7 +725,7 @@ async fn test_mgs_metrics( } // Wait until the MGS registers as a producer with Oximeter. - wait_for_producer(&cptestctx.oximeter, &mgs.gateway_id).await; + wait_for_producer(&cptestctx.oximeter, mgs.gateway_id).await; check_all_timeseries_present(&cptestctx, "temperature", temp_sensors).await; check_all_timeseries_present(&cptestctx, "voltage", voltage_sensors).await; @@ -755,9 +755,18 @@ async fn test_mgs_metrics( /// /// This blocks until the producer is registered, for up to 60s. It panics if /// the retry loop hits a permanent error. -pub async fn wait_for_producer( +pub async fn wait_for_producer( oximeter: &oximeter_collector::Oximeter, - producer_id: &Uuid, + producer_id: G, +) { + wait_for_producer_impl(oximeter, producer_id.into_untyped_uuid()).await; +} + +// This function is outlined from wait_for_producer to avoid unnecessary +// monomorphization. +async fn wait_for_producer_impl( + oximeter: &oximeter_collector::Oximeter, + producer_id: Uuid, ) { wait_for_condition( || async { @@ -765,7 +774,7 @@ pub async fn wait_for_producer( .list_producers(None, usize::MAX) .await .iter() - .any(|p| &p.id == producer_id) + .any(|p| p.id == producer_id) { Ok(()) } else { diff --git a/nexus/tests/integration_tests/oximeter.rs b/nexus/tests/integration_tests/oximeter.rs index 3b48351ac8..6a63799790 100644 --- a/nexus/tests/integration_tests/oximeter.rs +++ b/nexus/tests/integration_tests/oximeter.rs @@ -42,7 +42,7 @@ async fn test_oximeter_database_records(context: &ControlPlaneTestContext) { // Kind of silly, but let's wait until the producer is actually registered // with Oximeter. let producer_id = nexus_test_utils::PRODUCER_UUID.parse().unwrap(); - wait_for_producer(&context.oximeter, &producer_id).await; + wait_for_producer(&context.oximeter, producer_id).await; // Verify that the producer lives in the DB. let results = conn diff --git a/nexus/types/src/deployment.rs b/nexus/types/src/deployment.rs index 7da2860420..ad62ec1d50 100644 --- a/nexus/types/src/deployment.rs +++ b/nexus/types/src/deployment.rs @@ -18,7 +18,6 @@ use crate::inventory::Collection; pub use crate::inventory::SourceNatConfig; pub use crate::inventory::ZpoolName; use derive_more::From; -use newtype_uuid::GenericUuid; use nexus_sled_agent_shared::inventory::OmicronZoneConfig; use nexus_sled_agent_shared::inventory::OmicronZoneType; use nexus_sled_agent_shared::inventory::OmicronZonesConfig; @@ -612,7 +611,7 @@ impl ZoneSortKey for OmicronZoneConfig { } fn id(&self) -> OmicronZoneUuid { - OmicronZoneUuid::from_untyped_uuid(self.id) + self.id } } @@ -650,7 +649,7 @@ pub struct BlueprintZoneConfig { impl From for OmicronZoneConfig { fn from(z: BlueprintZoneConfig) -> Self { Self { - id: z.id.into_untyped_uuid(), + id: z.id, underlay_address: z.underlay_address, filesystem_pool: z.filesystem_pool, zone_type: z.zone_type.into(), diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index 39fe9dd3e0..415f6a5d23 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -3899,8 +3899,7 @@ ] }, "id": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForOmicronZoneKind" }, "underlay_address": { "type": "string", @@ -5083,6 +5082,10 @@ "type": "string", "format": "uuid" }, + "TypedUuidForOmicronZoneKind": { + "type": "string", + "format": "uuid" + }, "TypedUuidForZpoolKind": { "type": "string", "format": "uuid" diff --git a/schema/all-zones-requests.json b/schema/all-zones-requests.json index c504474589..9aad75a895 100644 --- a/schema/all-zones-requests.json +++ b/schema/all-zones-requests.json @@ -252,8 +252,7 @@ ] }, "id": { - "type": "string", - "format": "uuid" + "$ref": "#/definitions/TypedUuidForOmicronZoneKind" }, "underlay_address": { "type": "string", @@ -694,6 +693,10 @@ } } }, + "TypedUuidForOmicronZoneKind": { + "type": "string", + "format": "uuid" + }, "Vni": { "description": "A Geneve Virtual Network Identifier", "type": "integer", diff --git a/schema/deployment-config.json b/schema/deployment-config.json index 7b737c52b2..2beb0ea4fb 100644 --- a/schema/deployment-config.json +++ b/schema/deployment-config.json @@ -28,8 +28,11 @@ }, "id": { "description": "Uuid of the Nexus instance", - "type": "string", - "format": "uuid" + "allOf": [ + { + "$ref": "#/definitions/TypedUuidForOmicronZoneKind" + } + ] }, "internal_dns": { "description": "Describes how Nexus should find internal DNS servers for bootstrapping.", @@ -150,6 +153,10 @@ "$ref": "#/definitions/Ipv6Net" } } + }, + "TypedUuidForOmicronZoneKind": { + "type": "string", + "format": "uuid" } } } \ No newline at end of file diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index de0b086752..f9c0f117ba 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -4,6 +4,7 @@ use nexus_sled_agent_shared::inventory::{OmicronZoneConfig, OmicronZoneType}; use omicron_common::disk::{DatasetKind, DatasetName}; +use omicron_uuid_kinds::GenericUuid; pub use sled_hardware::DendriteAsic; use std::net::SocketAddrV6; @@ -19,7 +20,7 @@ impl OmicronZoneConfigExt for OmicronZoneConfig { fn zone_name(&self) -> String { illumos_utils::running_zone::InstalledZone::get_zone_name( self.zone_type.kind().zone_prefix(), - Some(self.id), + Some(self.id.into_untyped_uuid()), ) } } diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 2c83fc5ea3..bce3c35ba3 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -93,6 +93,7 @@ use omicron_common::backoff::{ use omicron_common::disk::{DatasetKind, DatasetName}; use omicron_common::ledger::{self, Ledger, Ledgerable}; use omicron_ddm_admin_client::{Client as DdmAdminClient, DdmError}; +use omicron_uuid_kinds::GenericUuid; use once_cell::sync::OnceCell; use rand::prelude::SliceRandom; use sled_agent_types::{ @@ -1522,7 +1523,8 @@ impl ServiceManager { Some(dir) => ZoneBuilderFactory::fake(Some(dir)).builder(), }; if let Some(uuid) = unique_name { - zone_builder = zone_builder.with_unique_name(uuid); + zone_builder = + zone_builder.with_unique_name(uuid.into_untyped_uuid()); } if let Some(vnic) = bootstrap_vnic { zone_builder = zone_builder.with_bootstrap_vnic(vnic); @@ -4611,6 +4613,7 @@ mod test { zone::MockZones, }; + use omicron_uuid_kinds::OmicronZoneUuid; use sled_storage::manager_test_harness::StorageManagerTestHarness; use std::os::unix::process::ExitStatusExt; use std::{ @@ -4812,7 +4815,7 @@ mod test { // Prepare to call "ensure" for a new service, then actually call "ensure". async fn ensure_new_service( mgr: &ServiceManager, - id: Uuid, + id: OmicronZoneUuid, generation: Generation, tmp_dir: String, ) { @@ -4836,7 +4839,7 @@ mod test { async fn try_new_service_of_type( mgr: &ServiceManager, - id: Uuid, + id: OmicronZoneUuid, generation: Generation, zone_type: OmicronZoneType, tmp_dir: String, @@ -4865,7 +4868,7 @@ mod test { // return the service without actually installing a new zone. async fn ensure_existing_service( mgr: &ServiceManager, - id: Uuid, + id: OmicronZoneUuid, generation: Generation, tmp_dir: String, ) { @@ -5072,7 +5075,7 @@ mod test { assert!(found.zones.is_empty()); let v2 = v1.next(); - let id = Uuid::new_v4(); + let id = OmicronZoneUuid::new_v4(); ensure_new_service( &mgr, id, @@ -5151,7 +5154,7 @@ mod test { assert!(found.zones.is_empty()); let v2 = v1.next(); - let id = Uuid::new_v4(); + let id = OmicronZoneUuid::new_v4(); // Should fail: time has not yet synchronized. let address = @@ -5229,7 +5232,7 @@ mod test { .await; let v2 = Generation::new().next(); - let id = Uuid::new_v4(); + let id = OmicronZoneUuid::new_v4(); let dir = String::from(test_config.config_dir.path().as_str()); ensure_new_service(&mgr, id, v2, dir.clone()).await; let v3 = v2.next(); @@ -5301,7 +5304,7 @@ mod test { .await; let v2 = Generation::new().next(); - let id = Uuid::new_v4(); + let id = OmicronZoneUuid::new_v4(); ensure_new_service( &mgr, id, @@ -5405,7 +5408,7 @@ mod test { let v1 = Generation::new(); let v2 = v1.next(); - let id = Uuid::new_v4(); + let id = OmicronZoneUuid::new_v4(); ensure_new_service( &mgr, id, @@ -5465,7 +5468,7 @@ mod test { // Like the normal tests, set up a generation with one zone in it. let v1 = Generation::new(); let v2 = v1.next(); - let id1 = Uuid::new_v4(); + let id1 = OmicronZoneUuid::new_v4(); let _expectations = expect_new_services(); let address = @@ -5498,7 +5501,7 @@ mod test { // Make a new list of zones that we're going to try with a bunch of // different generation numbers. - let id2 = Uuid::new_v4(); + let id2 = OmicronZoneUuid::new_v4(); zones.push(OmicronZoneConfig { id: id2, underlay_address: Ipv6Addr::LOCALHOST, diff --git a/sled-agent/src/sled_agent.rs b/sled-agent/src/sled_agent.rs index e7fcdfc327..d2f192afc0 100644 --- a/sled-agent/src/sled_agent.rs +++ b/sled-agent/src/sled_agent.rs @@ -56,7 +56,7 @@ use omicron_common::disk::{ OmicronPhysicalDisksConfig, }; use omicron_ddm_admin_client::Client as DdmAdminClient; -use omicron_uuid_kinds::PropolisUuid; +use omicron_uuid_kinds::{GenericUuid, PropolisUuid}; use sled_agent_api::Zpool; use sled_agent_types::disk::DiskStateRequested; use sled_agent_types::early_networking::EarlyNetworkConfig; @@ -934,7 +934,7 @@ impl SledAgent { }; // First, ensure the dataset exists - let dataset_id = zone.id; + let dataset_id = zone.id.into_untyped_uuid(); self.inner .storage .upsert_filesystem(dataset_id, dataset_name)