From 7d8cb151a20f57c8ef187011fea865c9f6bf3a6b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Mon, 17 Jun 2024 11:43:52 -0700 Subject: [PATCH 01/26] Remove updater lock from instance runtime state (#5890) --- nexus/db-model/src/instance.rs | 43 +++++++++---------- nexus/db-model/src/schema.rs | 2 +- nexus/db-queries/src/db/datastore/instance.rs | 10 ++--- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/nexus/db-model/src/instance.rs b/nexus/db-model/src/instance.rs index 99c0126174..14f79aea39 100644 --- a/nexus/db-model/src/instance.rs +++ b/nexus/db-model/src/instance.rs @@ -58,6 +58,24 @@ pub struct Instance { #[diesel(embed)] pub runtime_state: InstanceRuntimeState, + + /// A UUID identifying the saga currently holding the update lock on this + /// instance. If this is [`None`] the instance is not locked. Otherwise, if + /// this is [`Some`], the instance is locked by the saga owning this UUID. + /// Note that this is not (presently) the UUID *of* the locking saga, but + /// rather, a UUID *generated by* that saga. Therefore, it may not be + /// useable to look up which saga holds the lock. + /// + /// This field is guarded by the instance's `updater_gen` + #[diesel(column_name = updater_id)] + pub updater_id: Option, + + /// The generation number for the updater lock. This is updated whenever the + /// lock is acquired or released, and is used in attempts to set the + /// `updater_id` field to ensure that the snapshot which indicated that the + /// lock was not held is still valid when setting the lock ID. + #[diesel(column_name = updater_gen)] + pub updater_gen: Generation, } impl Instance { @@ -85,6 +103,9 @@ impl Instance { hostname: params.hostname.to_string(), boot_on_fault: false, runtime_state, + + updater_gen: Generation::new(), + updater_id: None, } } @@ -171,24 +192,6 @@ pub struct InstanceRuntimeState { #[diesel(column_name = migration_id)] pub migration_id: Option, - /// A UUID identifying the saga currently holding the update lock on this - /// instance. If this is [`None`] the instance is not locked. Otherwise, if - /// this is [`Some`], the instance is locked by the saga owning this UUID. - /// Note that this is not (presently) the UUID *of* the locking saga, but - /// rather, a UUID *generated by* that saga. Therefore, it may not be - /// useable to look up which saga holds the lock. - /// - /// This field is guarded by the instance's `updater_gen` - #[diesel(column_name = updater_id)] - pub updater_id: Option, - - /// The generation number for the updater lock. This is updated whenever the - /// lock is acquired or released, and is used in attempts to set the - /// `updater_id` field to ensure that the snapshot which indicated that the - /// lock was not held is still valid when setting the lock ID. - #[diesel(column_name = updater_gen)] - pub updater_gen: Generation, - /// The "internal" state of this instance. The instance's externally-visible /// state may be delegated to the instance's active VMM, if it has one. /// @@ -206,8 +209,6 @@ impl InstanceRuntimeState { dst_propolis_id: None, migration_id: None, gen: Generation::new(), - updater_gen: Generation::new(), - updater_id: None, } } } @@ -231,8 +232,6 @@ impl From propolis_id: state.propolis_id, dst_propolis_id: state.dst_propolis_id, migration_id: state.migration_id, - updater_gen: Generation::new(), - updater_id: None, } } } diff --git a/nexus/db-model/src/schema.rs b/nexus/db-model/src/schema.rs index 0587e10ad5..b1fabcf976 100644 --- a/nexus/db-model/src/schema.rs +++ b/nexus/db-model/src/schema.rs @@ -430,9 +430,9 @@ table! { active_propolis_id -> Nullable, target_propolis_id -> Nullable, migration_id -> Nullable, + state -> crate::InstanceStateEnum, updater_id -> Nullable, updater_gen-> Int8, - state -> crate::InstanceStateEnum, } } diff --git a/nexus/db-queries/src/db/datastore/instance.rs b/nexus/db-queries/src/db/datastore/instance.rs index 9fc6c54da7..6542b03fd1 100644 --- a/nexus/db-queries/src/db/datastore/instance.rs +++ b/nexus/db-queries/src/db/datastore/instance.rs @@ -753,7 +753,7 @@ impl DataStore { // important than handling that extremely unlikely edge case. let mut did_lock = false; loop { - match instance.runtime_state.updater_id { + match instance.updater_id { // If the `updater_id` field is not null and the ID equals this // saga's ID, we already have the lock. We're done here! Some(lock_id) if lock_id == saga_lock_id => { @@ -766,7 +766,7 @@ impl DataStore { ); return Ok(UpdaterLock { saga_lock_id, - locked_gen: instance.runtime_state.updater_gen, + locked_gen: instance.updater_gen, }); } // The `updater_id` field is set, but it's not our ID. The instance @@ -787,7 +787,7 @@ impl DataStore { } // Okay, now attempt to acquire the lock - let current_gen = instance.runtime_state.updater_gen; + let current_gen = instance.updater_gen; slog::debug!( &opctx.log, "attempting to acquire instance updater lock"; @@ -902,12 +902,12 @@ impl DataStore { UpdateAndQueryResult { status: UpdateStatus::NotUpdatedButExists, ref found, - } if found.runtime_state.updater_gen > locked_gen => Ok(false), + } if found.updater_gen > locked_gen => Ok(false), // The instance exists, but the lock ID doesn't match our lock ID. // This means we were trying to release a lock we never held, whcih // is almost certainly a programmer error. UpdateAndQueryResult { ref found, .. } => { - match found.runtime_state.updater_id { + match found.updater_id { Some(lock_holder) => { debug_assert_ne!(lock_holder, saga_lock_id); Err(Error::internal_error( From 50e353fb0eca7bf648b314f999393a7a1db23974 Mon Sep 17 00:00:00 2001 From: Greg Colombo Date: Mon, 17 Jun 2024 12:05:19 -0700 Subject: [PATCH 02/26] Begin using typed instance and Propolis UUIDs in sled agent and Nexus (#5896) One goal of the ongoing Great Instance State Rework of 2024 is to clarify that, in broad strokes, Nexus manages instances and sled agents manage VMMs. Nexus decides whether and when an instance is connected to a VMM and how to convert VMM states to instance states; sled agents manage individual Propolis processes and send their state changes to Nexus so that it has the relevant VMM states available. Today, sled agent's instance manager tracks VMMs in a map with type `BTreeMap`, where the keys are instance IDs and the values contain Propolis IDs. In our proposed brave new world, sled agent can use Propolis IDs as keys and may not need instance IDs at all--i.e., its map type should be `BTreeMap`, where the `Vmm` may or may not contain an `InstanceUuid`. To support this future change, change sled agent's instance map to a `BTreeMap` and work through all the compiler-error fallout. This causes the difference between instance and Propolis UUIDs to filter all the way up through Nexus's instance management routines and sagas. This should make it much easier to refactor sled agent's APIs to take Propolis IDs, since the compiler can then help catch instance and Propolis ID transpositions. Nexus's instance management code often deals with instance IDs, Propolis IDs, and sled IDs together, so also start using `SledUuid` in some of these paths. This change draws an arbitrary line at using typed UUIDs in database model types and in the generated resource objects in the authz layer; calls into/out of these layers use `GenericUuid` and `from_untyped_uuid`/`into_untyped_uuid` as needed.(This is not because these changes are necessarily impossible, merely because the line had to go somewhere.) Tests: `cargo nextest`; while this change is large, it should by and large be a rote refactoring exercise. --- clients/nexus-client/src/lib.rs | 1 + clients/sled-agent-client/src/lib.rs | 2 + common/src/api/internal/nexus.rs | 7 +- dev-tools/omdb/src/bin/omdb/db.rs | 19 +- nexus/db-model/src/instance.rs | 21 +- nexus/db-model/src/network_interface.rs | 5 +- nexus/db-model/src/vmm.rs | 13 +- .../src/db/datastore/external_ip.rs | 46 +++-- nexus/db-queries/src/db/datastore/instance.rs | 36 ++-- nexus/db-queries/src/db/datastore/mod.rs | 12 +- nexus/db-queries/src/db/datastore/ssh_key.rs | 12 +- .../virtual_provisioning_collection.rs | 11 +- nexus/db-queries/src/db/datastore/vmm.rs | 28 +-- nexus/db-queries/src/db/datastore/volume.rs | 12 +- .../db-queries/src/db/queries/external_ip.rs | 17 +- nexus/db-queries/src/db/queries/instance.rs | 21 +- .../src/db/queries/network_interface.rs | 57 ++++-- .../virtual_provisioning_collection_update.rs | 18 +- .../app/background/abandoned_vmm_reaper.rs | 31 ++- nexus/src/app/background/instance_watcher.rs | 10 +- nexus/src/app/external_ip.rs | 7 +- nexus/src/app/instance.rs | 92 +++++---- nexus/src/app/instance_network.rs | 19 +- nexus/src/app/network_interface.rs | 4 +- nexus/src/app/sagas/instance_common.rs | 43 ++-- nexus/src/app/sagas/instance_create.rs | 33 +-- nexus/src/app/sagas/instance_ip_attach.rs | 33 ++- nexus/src/app/sagas/instance_ip_detach.rs | 40 ++-- nexus/src/app/sagas/instance_migrate.rs | 149 +++++++------- nexus/src/app/sagas/instance_start.rs | 153 +++++++------- nexus/src/app/sagas/test_helpers.rs | 20 +- nexus/src/app/sled.rs | 5 +- nexus/src/app/test_interfaces.rs | 35 ++-- nexus/src/internal_api/http_entrypoints.rs | 8 +- nexus/test-utils/src/lib.rs | 7 +- nexus/tests/integration_tests/disks.rs | 52 +++-- nexus/tests/integration_tests/external_ips.rs | 19 +- nexus/tests/integration_tests/instances.rs | 191 ++++++++++-------- nexus/tests/integration_tests/ip_pools.rs | 5 +- nexus/tests/integration_tests/metrics.rs | 9 +- nexus/tests/integration_tests/pantry.rs | 12 +- nexus/tests/integration_tests/sleds.rs | 3 +- nexus/tests/integration_tests/snapshots.rs | 5 +- nexus/tests/integration_tests/vpc_subnets.rs | 7 +- openapi/nexus-internal.json | 25 ++- openapi/sled-agent.json | 60 +++--- sled-agent/src/common/instance.rs | 21 +- sled-agent/src/http_entrypoints.rs | 5 +- sled-agent/src/instance.rs | 44 ++-- sled-agent/src/instance_manager.rs | 70 +++---- sled-agent/src/params.rs | 5 +- sled-agent/src/sim/collection.rs | 4 +- sled-agent/src/sim/http_entrypoints.rs | 5 +- sled-agent/src/sim/sled_agent.rs | 132 +++++++----- sled-agent/src/sim/storage.rs | 3 +- sled-agent/src/sled_agent.rs | 19 +- uuid-kinds/src/lib.rs | 1 + 57 files changed, 992 insertions(+), 732 deletions(-) diff --git a/clients/nexus-client/src/lib.rs b/clients/nexus-client/src/lib.rs index 767d8f53d5..9043592414 100644 --- a/clients/nexus-client/src/lib.rs +++ b/clients/nexus-client/src/lib.rs @@ -38,6 +38,7 @@ progenitor::generate_api!( NewPasswordHash = omicron_passwords::NewPasswordHash, TypedUuidForCollectionKind = omicron_uuid_kinds::CollectionUuid, TypedUuidForDownstairsKind = omicron_uuid_kinds::TypedUuid, + TypedUuidForPropolisKind = omicron_uuid_kinds::TypedUuid, TypedUuidForSledKind = omicron_uuid_kinds::TypedUuid, TypedUuidForUpstairsKind = omicron_uuid_kinds::TypedUuid, TypedUuidForUpstairsRepairKind = omicron_uuid_kinds::TypedUuid, diff --git a/clients/sled-agent-client/src/lib.rs b/clients/sled-agent-client/src/lib.rs index aa42429089..e4a407ef3d 100644 --- a/clients/sled-agent-client/src/lib.rs +++ b/clients/sled-agent-client/src/lib.rs @@ -53,6 +53,8 @@ progenitor::generate_api!( PortSpeed = omicron_common::api::internal::shared::PortSpeed, SourceNatConfig = omicron_common::api::internal::shared::SourceNatConfig, SwitchLocation = omicron_common::api::external::SwitchLocation, + TypedUuidForInstanceKind = omicron_uuid_kinds::InstanceUuid, + TypedUuidForPropolisKind = omicron_uuid_kinds::PropolisUuid, TypedUuidForZpoolKind = omicron_uuid_kinds::ZpoolUuid, Vni = omicron_common::api::external::Vni, ZpoolKind = omicron_common::zpool_name::ZpoolKind, diff --git a/common/src/api/internal/nexus.rs b/common/src/api/internal/nexus.rs index 4f990c56e1..b4a73f4168 100644 --- a/common/src/api/internal/nexus.rs +++ b/common/src/api/internal/nexus.rs @@ -10,6 +10,7 @@ use crate::api::external::{ }; use chrono::{DateTime, Utc}; use omicron_uuid_kinds::DownstairsRegionKind; +use omicron_uuid_kinds::PropolisUuid; use omicron_uuid_kinds::TypedUuid; use omicron_uuid_kinds::UpstairsRepairKind; use omicron_uuid_kinds::UpstairsSessionKind; @@ -50,9 +51,9 @@ pub struct InstanceProperties { #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] pub struct InstanceRuntimeState { /// The instance's currently active VMM ID. - pub propolis_id: Option, + pub propolis_id: Option, /// If a migration is active, the ID of the target VMM. - pub dst_propolis_id: Option, + pub dst_propolis_id: Option, /// If a migration is active, the ID of that migration. pub migration_id: Option, /// Generation number for this state. @@ -105,7 +106,7 @@ pub struct SledInstanceState { pub instance_state: InstanceRuntimeState, /// The ID of the VMM whose state is being reported. - pub propolis_id: Uuid, + pub propolis_id: PropolisUuid, /// The most recent state of the sled's VMM process. pub vmm_state: VmmRuntimeState, diff --git a/dev-tools/omdb/src/bin/omdb/db.rs b/dev-tools/omdb/src/bin/omdb/db.rs index be4e1e8696..7df457b247 100644 --- a/dev-tools/omdb/src/bin/omdb/db.rs +++ b/dev-tools/omdb/src/bin/omdb/db.rs @@ -111,6 +111,7 @@ use omicron_common::api::external::InstanceState; use omicron_common::api::external::MacAddr; use omicron_uuid_kinds::CollectionUuid; use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::PropolisUuid; use omicron_uuid_kinds::SledUuid; use sled_agent_client::types::VolumeConstructionRequest; use std::borrow::Cow; @@ -129,12 +130,18 @@ use uuid::Uuid; const NO_ACTIVE_PROPOLIS_MSG: &str = ""; const NOT_ON_SLED_MSG: &str = ""; -struct MaybePropolisId(Option); -struct MaybeSledId(Option); +struct MaybePropolisId(Option); +struct MaybeSledId(Option); impl From<&InstanceAndActiveVmm> for MaybePropolisId { fn from(value: &InstanceAndActiveVmm) -> Self { - Self(value.instance().runtime().propolis_id) + Self( + value + .instance() + .runtime() + .propolis_id + .map(PropolisUuid::from_untyped_uuid), + ) } } @@ -1040,7 +1047,7 @@ async fn cmd_db_disk_info( let my_sled_id = instance.sled_id().unwrap(); let (_, my_sled) = LookupPath::new(opctx, datastore) - .sled_id(my_sled_id) + .sled_id(my_sled_id.into_untyped_uuid()) .fetch() .await .context("failed to look up sled")?; @@ -1948,7 +1955,7 @@ async fn cmd_db_instances( check_limit(&instances, limit, ctx); let mut rows = Vec::new(); - let mut h_to_s: HashMap = HashMap::new(); + let mut h_to_s: HashMap = HashMap::new(); for i in instances { let host_serial = if i.vmm().is_some() { @@ -1956,7 +1963,7 @@ async fn cmd_db_instances( h_to_s.entry(i.sled_id().unwrap()) { let (_, my_sled) = LookupPath::new(opctx, datastore) - .sled_id(i.sled_id().unwrap()) + .sled_id(i.sled_id().unwrap().into_untyped_uuid()) .fetch() .await .context("failed to look up sled")?; diff --git a/nexus/db-model/src/instance.rs b/nexus/db-model/src/instance.rs index 14f79aea39..dadf4e89ae 100644 --- a/nexus/db-model/src/instance.rs +++ b/nexus/db-model/src/instance.rs @@ -10,6 +10,7 @@ use crate::schema::{disk, external_ip, instance}; use chrono::{DateTime, Utc}; use db_macros::Resource; use nexus_types::external_api::params; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid}; use serde::Deserialize; use serde::Serialize; use uuid::Uuid; @@ -82,12 +83,14 @@ impl Instance { /// Constructs a new instance record with no VMM that will initially appear /// to be in the Creating state. pub fn new( - instance_id: Uuid, + instance_id: InstanceUuid, project_id: Uuid, params: ¶ms::InstanceCreate, ) -> Self { - let identity = - InstanceIdentity::new(instance_id, params.identity.clone()); + let identity = InstanceIdentity::new( + instance_id.into_untyped_uuid(), + params.identity.clone(), + ); let runtime_state = InstanceRuntimeState::new( InstanceState::Creating, @@ -229,8 +232,10 @@ impl From nexus_state, time_updated: state.time_updated, gen: state.gen.into(), - propolis_id: state.propolis_id, - dst_propolis_id: state.dst_propolis_id, + propolis_id: state.propolis_id.map(|id| id.into_untyped_uuid()), + dst_propolis_id: state + .dst_propolis_id + .map(|id| id.into_untyped_uuid()), migration_id: state.migration_id, } } @@ -241,10 +246,12 @@ impl From { fn from(state: InstanceRuntimeState) -> Self { Self { - dst_propolis_id: state.dst_propolis_id, + dst_propolis_id: state + .dst_propolis_id + .map(PropolisUuid::from_untyped_uuid), gen: state.gen.into(), migration_id: state.migration_id, - propolis_id: state.propolis_id, + propolis_id: state.propolis_id.map(PropolisUuid::from_untyped_uuid), time_updated: state.time_updated, } } diff --git a/nexus/db-model/src/network_interface.rs b/nexus/db-model/src/network_interface.rs index 95bb8bb7f2..6d347ecd37 100644 --- a/nexus/db-model/src/network_interface.rs +++ b/nexus/db-model/src/network_interface.rs @@ -18,6 +18,7 @@ use nexus_types::external_api::params; use nexus_types::identity::Resource; use omicron_common::api::{external, internal}; use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use omicron_uuid_kinds::OmicronZoneUuid; use omicron_uuid_kinds::VnicUuid; use sled_agent_client::ZoneKind; @@ -391,7 +392,7 @@ impl IncompleteNetworkInterface { pub fn new_instance( interface_id: Uuid, - instance_id: Uuid, + instance_id: InstanceUuid, subnet: VpcSubnet, identity: external::IdentityMetadataCreateParams, ip: Option, @@ -399,7 +400,7 @@ impl IncompleteNetworkInterface { Self::new( interface_id, NetworkInterfaceKind::Instance, - instance_id, + instance_id.into_untyped_uuid(), subnet, identity, ip, diff --git a/nexus/db-model/src/vmm.rs b/nexus/db-model/src/vmm.rs index ceaef2e709..4cc6235e1d 100644 --- a/nexus/db-model/src/vmm.rs +++ b/nexus/db-model/src/vmm.rs @@ -16,6 +16,7 @@ use super::{Generation, VmmState}; use crate::schema::vmm; use crate::SqlU16; use chrono::{DateTime, Utc}; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid, SledUuid}; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -68,9 +69,9 @@ pub enum VmmInitialState { impl Vmm { /// Creates a new VMM record. pub fn new( - id: Uuid, - instance_id: Uuid, - sled_id: Uuid, + id: PropolisUuid, + instance_id: InstanceUuid, + sled_id: SledUuid, propolis_ip: ipnetwork::IpNetwork, propolis_port: u16, initial_state: VmmInitialState, @@ -82,11 +83,11 @@ impl Vmm { }; Self { - id, + id: id.into_untyped_uuid(), time_created: now, time_deleted: None, - instance_id, - sled_id, + instance_id: instance_id.into_untyped_uuid(), + sled_id: sled_id.into_untyped_uuid(), propolis_ip, propolis_port: SqlU16(propolis_port), runtime: VmmRuntimeState { diff --git a/nexus/db-queries/src/db/datastore/external_ip.rs b/nexus/db-queries/src/db/datastore/external_ip.rs index 8dda8041fa..0614cd0d9f 100644 --- a/nexus/db-queries/src/db/datastore/external_ip.rs +++ b/nexus/db-queries/src/db/datastore/external_ip.rs @@ -51,6 +51,8 @@ use omicron_common::api::external::ListResultVec; use omicron_common::api::external::LookupResult; use omicron_common::api::external::ResourceType; use omicron_common::api::external::UpdateResult; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use omicron_uuid_kinds::OmicronZoneUuid; use ref_cast::RefCast; use sled_agent_client::ZoneKind; @@ -65,12 +67,12 @@ impl DataStore { &self, opctx: &OpContext, ip_id: Uuid, - instance_id: Uuid, + instance_id: InstanceUuid, pool_id: Uuid, ) -> CreateResult { let data = IncompleteExternalIp::for_instance_source_nat( ip_id, - instance_id, + instance_id.into_untyped_uuid(), pool_id, ); self.allocate_external_ip(opctx, data).await @@ -109,7 +111,7 @@ impl DataStore { &self, opctx: &OpContext, ip_id: Uuid, - instance_id: Uuid, + instance_id: InstanceUuid, pool: Option, creating_instance: bool, ) -> CreateResult<(ExternalIp, bool)> { @@ -385,7 +387,7 @@ impl DataStore { &self, opctx: &OpContext, ip_id: Uuid, - instance_id: Uuid, + instance_id: InstanceUuid, kind: IpKind, creating_instance: bool, ) -> Result, Error> { @@ -403,7 +405,7 @@ impl DataStore { }; let query = Instance::attach_resource( - instance_id, + instance_id.into_untyped_uuid(), ip_id, inst_table .into_boxed() @@ -416,7 +418,7 @@ impl DataStore { .filter(dsl::parent_id.is_null()), MAX_EXTERNAL_IPS_PLUS_SNAT, diesel::update(dsl::external_ip).set(( - dsl::parent_id.eq(Some(instance_id)), + dsl::parent_id.eq(Some(instance_id.into_untyped_uuid())), dsl::time_modified.eq(Utc::now()), dsl::state.eq(IpAttachState::Attaching), )), @@ -430,7 +432,7 @@ impl DataStore { AttachError::CollectionNotFound => { Err(Error::not_found_by_id( ResourceType::Instance, - &instance_id, + &instance_id.into_untyped_uuid(), )) }, AttachError::ResourceNotFound => { @@ -446,9 +448,9 @@ impl DataStore { AttachError::NoUpdate { attached_count, resource, collection } => { match resource.state { // Idempotent errors: is in progress or complete for same resource pair -- this is fine. - IpAttachState::Attaching if resource.parent_id == Some(instance_id) => + IpAttachState::Attaching if resource.parent_id == Some(instance_id.into_untyped_uuid()) => return Ok(Some(resource)), - IpAttachState::Attached if resource.parent_id == Some(instance_id) => { + IpAttachState::Attached if resource.parent_id == Some(instance_id.into_untyped_uuid()) => { do_saga = false; return Ok(Some(resource)) }, @@ -518,7 +520,7 @@ impl DataStore { &self, opctx: &OpContext, ip_id: Uuid, - instance_id: Uuid, + instance_id: InstanceUuid, kind: IpKind, creating_instance: bool, ) -> UpdateResult> { @@ -534,7 +536,7 @@ impl DataStore { }; let query = Instance::detach_resource( - instance_id, + instance_id.into_untyped_uuid(), ip_id, inst_table .into_boxed() @@ -558,7 +560,7 @@ impl DataStore { DetachError::CollectionNotFound => { Error::not_found_by_id( ResourceType::Instance, - &instance_id, + &instance_id.into_untyped_uuid(), ) }, DetachError::ResourceNotFound => { @@ -572,7 +574,7 @@ impl DataStore { } }, DetachError::NoUpdate { resource, collection } => { - let parent_match = resource.parent_id == Some(instance_id); + let parent_match = resource.parent_id == Some(instance_id.into_untyped_uuid()); match resource.state { // Idempotent cases: already detached OR detaching from same instance. IpAttachState::Detached => { @@ -660,10 +662,10 @@ impl DataStore { &self, opctx: &OpContext, ip_id: Uuid, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result, Error> { let _ = LookupPath::new(&opctx, self) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await?; @@ -763,13 +765,13 @@ impl DataStore { pub async fn instance_lookup_external_ips( &self, opctx: &OpContext, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> LookupResult> { use db::schema::external_ip::dsl; dsl::external_ip .filter(dsl::is_service.eq(false)) .filter(dsl::is_probe.eq(false)) - .filter(dsl::parent_id.eq(instance_id)) + .filter(dsl::parent_id.eq(instance_id.into_untyped_uuid())) .filter(dsl::time_deleted.is_null()) .select(ExternalIp::as_select()) .get_results_async(&*self.pool_connection_authorized(opctx).await?) @@ -782,7 +784,7 @@ impl DataStore { pub async fn instance_lookup_ephemeral_ip( &self, opctx: &OpContext, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> LookupResult> { Ok(self .instance_lookup_external_ips(opctx, instance_id) @@ -915,11 +917,11 @@ impl DataStore { &self, opctx: &OpContext, authz_fip: &authz::FloatingIp, - instance_id: Uuid, + instance_id: InstanceUuid, creating_instance: bool, ) -> UpdateResult<(ExternalIp, bool)> { let (.., authz_instance) = LookupPath::new(&opctx, self) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await?; @@ -957,11 +959,11 @@ impl DataStore { &self, opctx: &OpContext, authz_fip: &authz::FloatingIp, - instance_id: Uuid, + instance_id: InstanceUuid, creating_instance: bool, ) -> UpdateResult<(ExternalIp, bool)> { let (.., authz_instance) = LookupPath::new(&opctx, self) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await?; diff --git a/nexus/db-queries/src/db/datastore/instance.rs b/nexus/db-queries/src/db/datastore/instance.rs index 6542b03fd1..f4b31b24ff 100644 --- a/nexus/db-queries/src/db/datastore/instance.rs +++ b/nexus/db-queries/src/db/datastore/instance.rs @@ -49,6 +49,10 @@ use omicron_common::api::external::LookupType; use omicron_common::api::external::ResourceType; use omicron_common::api::internal::nexus::MigrationRuntimeState; use omicron_common::bail_unless; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; +use omicron_uuid_kinds::PropolisUuid; +use omicron_uuid_kinds::SledUuid; use ref_cast::RefCast; use uuid::Uuid; @@ -68,8 +72,8 @@ impl InstanceAndActiveVmm { &self.vmm } - pub fn sled_id(&self) -> Option { - self.vmm.as_ref().map(|v| v.sled_id) + pub fn sled_id(&self) -> Option { + self.vmm.as_ref().map(|v| SledUuid::from_untyped_uuid(v.sled_id)) } pub fn effective_state( @@ -446,21 +450,21 @@ impl DataStore { // to explicitly fetch the state if they want that. pub async fn instance_update_runtime( &self, - instance_id: &Uuid, + instance_id: &InstanceUuid, new_runtime: &InstanceRuntimeState, ) -> Result { use db::schema::instance::dsl; let updated = diesel::update(dsl::instance) .filter(dsl::time_deleted.is_null()) - .filter(dsl::id.eq(*instance_id)) + .filter(dsl::id.eq(instance_id.into_untyped_uuid())) // Runtime state updates are allowed if either: // - the active Propolis ID will not change, the state generation // increased, and the Propolis generation will not change, or // - the Propolis generation increased. .filter(dsl::state_generation.lt(new_runtime.gen)) .set(new_runtime.clone()) - .check_if_exists::(*instance_id) + .check_if_exists::(instance_id.into_untyped_uuid()) .execute_and_check(&*self.pool_connection_unauthorized().await?) .await .map(|r| match r.status { @@ -472,7 +476,7 @@ impl DataStore { e, ErrorHandler::NotFoundByLookup( ResourceType::Instance, - LookupType::ById(*instance_id), + LookupType::ById(instance_id.into_untyped_uuid()), ), ) })?; @@ -507,9 +511,9 @@ impl DataStore { /// - `Err` if another error occurred while accessing the database. pub async fn instance_and_vmm_update_runtime( &self, - instance_id: &Uuid, + instance_id: &InstanceUuid, new_instance: &InstanceRuntimeState, - vmm_id: &Uuid, + vmm_id: &PropolisUuid, new_vmm: &VmmRuntimeState, migration: &Option, ) -> Result { @@ -694,7 +698,11 @@ impl DataStore { } })?; - self.instance_ssh_keys_delete(opctx, authz_instance.id()).await?; + self.instance_ssh_keys_delete( + opctx, + InstanceUuid::from_untyped_uuid(authz_instance.id()), + ) + .await?; Ok(()) } @@ -943,7 +951,7 @@ mod tests { ) -> authz::Instance { let silo_id = *nexus_db_fixed_data::silo::DEFAULT_SILO_ID; let project_id = Uuid::new_v4(); - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let (authz_project, _project) = datastore .project_create( @@ -990,7 +998,7 @@ mod tests { .expect("instance must be created successfully"); let (.., authz_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await .expect("instance must exist"); @@ -1270,9 +1278,11 @@ mod tests { ) .await .expect("active VMM should be inserted successfully!"); + + let instance_id = InstanceUuid::from_untyped_uuid(authz_instance.id()); datastore .instance_update_runtime( - &authz_instance.id(), + &instance_id, &InstanceRuntimeState { time_updated: Utc::now(), gen: Generation( @@ -1339,7 +1349,7 @@ mod tests { .expect("migration should be inserted successfully!"); datastore .instance_update_runtime( - &authz_instance.id(), + &instance_id, &InstanceRuntimeState { time_updated: Utc::now(), gen: Generation( diff --git a/nexus/db-queries/src/db/datastore/mod.rs b/nexus/db-queries/src/db/datastore/mod.rs index 0a48f33ebd..ca7c76c0ae 100644 --- a/nexus/db-queries/src/db/datastore/mod.rs +++ b/nexus/db-queries/src/db/datastore/mod.rs @@ -41,11 +41,11 @@ use omicron_common::api::external::SemverVersion; use omicron_common::backoff::{ retry_notify, retry_policy_internal_service, BackoffError, }; +use omicron_uuid_kinds::{GenericUuid, SledUuid}; use slog::Logger; use std::net::Ipv6Addr; use std::num::NonZeroU32; use std::sync::Arc; -use uuid::Uuid; mod address_lot; mod allow_list; @@ -307,11 +307,13 @@ impl DataStore { pub async fn next_ipv6_address( &self, opctx: &OpContext, - sled_id: Uuid, + sled_id: SledUuid, ) -> Result { use db::schema::sled::dsl; let net = diesel::update( - dsl::sled.find(sled_id).filter(dsl::time_deleted.is_null()), + dsl::sled + .find(sled_id.into_untyped_uuid()) + .filter(dsl::time_deleted.is_null()), ) .set(dsl::last_used_address.eq(dsl::last_used_address + 1)) .returning(dsl::last_used_address) @@ -322,7 +324,7 @@ impl DataStore { e, ErrorHandler::NotFoundByLookup( ResourceType::Sled, - LookupType::ById(sled_id), + LookupType::ById(sled_id.into_untyped_uuid()), ), ) })?; @@ -1656,6 +1658,8 @@ mod test { ); datastore.sled_upsert(sled2).await.unwrap(); + let sled1_id = SledUuid::from_untyped_uuid(sled1_id); + let sled2_id = SledUuid::from_untyped_uuid(sled2_id); let ip = datastore.next_ipv6_address(&opctx, sled1_id).await.unwrap(); let expected_ip = Ipv6Addr::new(0xfd00, 0x1de, 0, 0, 0, 0, 1, 0); assert_eq!(ip, expected_ip); diff --git a/nexus/db-queries/src/db/datastore/ssh_key.rs b/nexus/db-queries/src/db/datastore/ssh_key.rs index a5f7427267..9e9b6230b7 100644 --- a/nexus/db-queries/src/db/datastore/ssh_key.rs +++ b/nexus/db-queries/src/db/datastore/ssh_key.rs @@ -27,6 +27,8 @@ use omicron_common::api::external::LookupType; use omicron_common::api::external::NameOrId; use omicron_common::api::external::ResourceType; use omicron_common::api::external::UpdateResult; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use ref_cast::RefCast; use uuid::Uuid; @@ -120,7 +122,7 @@ impl DataStore { &self, opctx: &OpContext, authz_user: &authz::SiloUser, - instance_id: Uuid, + instance_id: InstanceUuid, keys: &Option>, ) -> UpdateResult<()> { opctx.authorize(authz::Action::ListChildren, authz_user).await?; @@ -142,7 +144,7 @@ impl DataStore { })? .iter() .map(|key| db::model::InstanceSshKey { - instance_id, + instance_id: instance_id.into_untyped_uuid(), ssh_key_id: *key, }) .collect() @@ -153,7 +155,7 @@ impl DataStore { Some(vec) => vec .iter() .map(|key| db::model::InstanceSshKey { - instance_id, + instance_id: instance_id.into_untyped_uuid(), ssh_key_id: *key, }) .collect(), @@ -203,11 +205,11 @@ impl DataStore { pub async fn instance_ssh_keys_delete( &self, opctx: &OpContext, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> DeleteResult { use db::schema::instance_ssh_key::dsl; diesel::delete(dsl::instance_ssh_key) - .filter(dsl::instance_id.eq(instance_id)) + .filter(dsl::instance_id.eq(instance_id.into_untyped_uuid())) .execute_async(&*self.pool_connection_authorized(opctx).await?) .await .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))?; 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 9738f05ff6..247eefd3d5 100644 --- a/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs +++ b/nexus/db-queries/src/db/datastore/virtual_provisioning_collection.rs @@ -17,6 +17,7 @@ use async_bb8_diesel::AsyncRunQueryDsl; use diesel::prelude::*; use diesel::result::Error as DieselError; use omicron_common::api::external::{DeleteResult, Error}; +use omicron_uuid_kinds::InstanceUuid; use uuid::Uuid; /// The types of resources which can consume storage space. @@ -261,7 +262,7 @@ impl DataStore { pub async fn virtual_provisioning_collection_insert_instance( &self, opctx: &OpContext, - id: Uuid, + id: InstanceUuid, project_id: Uuid, cpus_diff: i64, ram_diff: ByteCount, @@ -286,7 +287,7 @@ impl DataStore { pub async fn virtual_provisioning_collection_delete_instance( &self, opctx: &OpContext, - id: Uuid, + id: InstanceUuid, project_id: Uuid, cpus_diff: i64, ram_diff: ByteCount, @@ -433,7 +434,7 @@ mod test { datastore: &DataStore, opctx: &OpContext, authz_project: &crate::authz::Project, - instance_id: Uuid, + instance_id: InstanceUuid, project_id: Uuid, cpus: i64, memory: ByteCount, @@ -480,7 +481,7 @@ mod test { // Actually provision the instance - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let cpus = 12; let ram = ByteCount::try_from(1 << 30).unwrap(); @@ -553,7 +554,7 @@ mod test { // Actually provision the instance - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let cpus = 12; let ram = ByteCount::try_from(1 << 30).unwrap(); diff --git a/nexus/db-queries/src/db/datastore/vmm.rs b/nexus/db-queries/src/db/datastore/vmm.rs index bcb615411e..7ce8c1551e 100644 --- a/nexus/db-queries/src/db/datastore/vmm.rs +++ b/nexus/db-queries/src/db/datastore/vmm.rs @@ -27,6 +27,8 @@ use omicron_common::api::external::LookupResult; use omicron_common::api::external::LookupType; use omicron_common::api::external::ResourceType; use omicron_common::api::external::UpdateResult; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::PropolisUuid; use std::net::SocketAddr; use uuid::Uuid; @@ -52,16 +54,16 @@ impl DataStore { pub async fn vmm_mark_deleted( &self, opctx: &OpContext, - vmm_id: &Uuid, + vmm_id: &PropolisUuid, ) -> UpdateResult { let valid_states = vec![DbVmmState::Destroyed, DbVmmState::Failed]; let updated = diesel::update(dsl::vmm) - .filter(dsl::id.eq(*vmm_id)) + .filter(dsl::id.eq(vmm_id.into_untyped_uuid())) .filter(dsl::state.eq_any(valid_states)) .filter(dsl::time_deleted.is_null()) .set(dsl::time_deleted.eq(Utc::now())) - .check_if_exists::(*vmm_id) + .check_if_exists::(vmm_id.into_untyped_uuid()) .execute_and_check(&*self.pool_connection_authorized(opctx).await?) .await .map(|r| match r.status { @@ -73,7 +75,7 @@ impl DataStore { e, ErrorHandler::NotFoundByLookup( ResourceType::Vmm, - LookupType::ById(*vmm_id), + LookupType::ById(vmm_id.into_untyped_uuid()), ), ) })?; @@ -85,12 +87,12 @@ impl DataStore { &self, opctx: &OpContext, authz_instance: &authz::Instance, - vmm_id: &Uuid, + vmm_id: &PropolisUuid, ) -> LookupResult { opctx.authorize(authz::Action::Read, authz_instance).await?; let vmm = dsl::vmm - .filter(dsl::id.eq(*vmm_id)) + .filter(dsl::id.eq(vmm_id.into_untyped_uuid())) .filter(dsl::instance_id.eq(authz_instance.id())) .filter(dsl::time_deleted.is_null()) .select(Vmm::as_select()) @@ -101,7 +103,7 @@ impl DataStore { e, ErrorHandler::NotFoundByLookup( ResourceType::Vmm, - LookupType::ById(*vmm_id), + LookupType::ById(vmm_id.into_untyped_uuid()), ), ) })?; @@ -111,15 +113,15 @@ impl DataStore { pub async fn vmm_update_runtime( &self, - vmm_id: &Uuid, + vmm_id: &PropolisUuid, new_runtime: &VmmRuntimeState, ) -> Result { let updated = diesel::update(dsl::vmm) .filter(dsl::time_deleted.is_null()) - .filter(dsl::id.eq(*vmm_id)) + .filter(dsl::id.eq(vmm_id.into_untyped_uuid())) .filter(dsl::state_generation.lt(new_runtime.gen)) .set(new_runtime.clone()) - .check_if_exists::(*vmm_id) + .check_if_exists::(vmm_id.into_untyped_uuid()) .execute_and_check(&*self.pool_connection_unauthorized().await?) .await .map(|r| match r.status { @@ -131,7 +133,7 @@ impl DataStore { e, ErrorHandler::NotFoundByLookup( ResourceType::Vmm, - LookupType::ById(*vmm_id), + LookupType::ById(vmm_id.into_untyped_uuid()), ), ) })?; @@ -150,13 +152,13 @@ impl DataStore { pub async fn vmm_overwrite_addr_for_test( &self, opctx: &OpContext, - vmm_id: &Uuid, + vmm_id: &PropolisUuid, new_addr: SocketAddr, ) -> UpdateResult { let new_ip = ipnetwork::IpNetwork::from(new_addr.ip()); let new_port = new_addr.port(); let vmm = diesel::update(dsl::vmm) - .filter(dsl::id.eq(*vmm_id)) + .filter(dsl::id.eq(vmm_id.into_untyped_uuid())) .set(( dsl::propolis_ip.eq(new_ip), dsl::propolis_port.eq(i32::from(new_port)), diff --git a/nexus/db-queries/src/db/datastore/volume.rs b/nexus/db-queries/src/db/datastore/volume.rs index 9e2c2f55e9..f8cfd4789c 100644 --- a/nexus/db-queries/src/db/datastore/volume.rs +++ b/nexus/db-queries/src/db/datastore/volume.rs @@ -38,6 +38,8 @@ use omicron_common::api::internal::nexus::DownstairsClientStopRequest; use omicron_common::api::internal::nexus::DownstairsClientStopped; use omicron_common::api::internal::nexus::RepairProgress; use omicron_uuid_kinds::DownstairsKind; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::PropolisUuid; use omicron_uuid_kinds::TypedUuid; use omicron_uuid_kinds::UpstairsKind; use omicron_uuid_kinds::UpstairsRepairKind; @@ -58,10 +60,10 @@ pub enum VolumeCheckoutReason { CopyAndModify, /// Check out a Volume to send to Propolis to start an instance. - InstanceStart { vmm_id: Uuid }, + InstanceStart { vmm_id: PropolisUuid }, /// Check out a Volume to send to a migration destination Propolis. - InstanceMigrate { vmm_id: Uuid, target_vmm_id: Uuid }, + InstanceMigrate { vmm_id: PropolisUuid, target_vmm_id: PropolisUuid }, /// Check out a Volume to send to a Pantry (for background maintenance /// operations). @@ -312,7 +314,7 @@ impl DataStore { } (Some(propolis_id), None) => { - if propolis_id != *vmm_id { + if propolis_id != vmm_id.into_untyped_uuid() { return Err(VolumeGetError::CheckoutConditionFailed( format!( "InstanceStart {}: instance {} propolis id {} mismatch", @@ -356,7 +358,7 @@ impl DataStore { let runtime = instance.runtime(); match (runtime.propolis_id, runtime.dst_propolis_id) { (Some(propolis_id), Some(dst_propolis_id)) => { - if propolis_id != *vmm_id || dst_propolis_id != *target_vmm_id { + if propolis_id != vmm_id.into_untyped_uuid() || dst_propolis_id != target_vmm_id.into_untyped_uuid() { return Err(VolumeGetError::CheckoutConditionFailed( format!( "InstanceMigrate {} {}: instance {} propolis id mismatches {} {}", @@ -385,7 +387,7 @@ impl DataStore { (Some(propolis_id), None) => { // XXX is this right? - if propolis_id != *vmm_id { + if propolis_id != vmm_id.into_untyped_uuid() { return Err(VolumeGetError::CheckoutConditionFailed( format!( "InstanceMigrate {} {}: instance {} propolis id {} mismatch", diff --git a/nexus/db-queries/src/db/queries/external_ip.rs b/nexus/db-queries/src/db/queries/external_ip.rs index 9bb6a44ea7..b48196bde8 100644 --- a/nexus/db-queries/src/db/queries/external_ip.rs +++ b/nexus/db-queries/src/db/queries/external_ip.rs @@ -895,6 +895,7 @@ mod tests { use omicron_test_utils::dev::db::CockroachInstance; use omicron_uuid_kinds::ExternalIpUuid; use omicron_uuid_kinds::GenericUuid; + use omicron_uuid_kinds::InstanceUuid; use omicron_uuid_kinds::OmicronZoneUuid; use sled_agent_client::ZoneKind; use std::net::IpAddr; @@ -1000,8 +1001,8 @@ mod tests { .expect("Failed to create IP Pool range"); } - async fn create_instance(&self, name: &str) -> Uuid { - let instance_id = Uuid::new_v4(); + async fn create_instance(&self, name: &str) -> InstanceUuid { + let instance_id = InstanceUuid::new_v4(); let project_id = Uuid::new_v4(); let instance = Instance::new(instance_id, project_id, &InstanceCreate { identity: IdentityMetadataCreateParams { name: String::from(name).parse().unwrap(), description: format!("instance {}", name) }, @@ -1062,7 +1063,7 @@ mod tests { (0..super::MAX_PORT).step_by(NUM_SOURCE_NAT_PORTS.into()) { let id = Uuid::new_v4(); - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let ip = context .db_datastore .allocate_instance_snat_ip( @@ -1079,7 +1080,7 @@ mod tests { } // The next allocation should fail, due to IP exhaustion - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let err = context .db_datastore .allocate_instance_snat_ip( @@ -1212,7 +1213,7 @@ mod tests { // Allocate two addresses let mut ips = Vec::with_capacity(2); for (expected_ip, expected_first_port) in external_ips.clone().take(2) { - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let ip = context .db_datastore .allocate_instance_snat_ip( @@ -1240,7 +1241,7 @@ mod tests { // Allocate a new one, ensure it's the same as the first one we // released. - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let ip = context .db_datastore .allocate_instance_snat_ip( @@ -1267,7 +1268,7 @@ mod tests { // Allocate one more, ensure it's the next chunk after the second one // from the original loop. - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let ip = context .db_datastore .allocate_instance_snat_ip( @@ -1579,7 +1580,7 @@ mod tests { context.create_ip_pool("default", range, true).await; // Create one SNAT IP address. - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); let id = Uuid::new_v4(); let ip = context .db_datastore diff --git a/nexus/db-queries/src/db/queries/instance.rs b/nexus/db-queries/src/db/queries/instance.rs index ed584c6ce6..fded585b67 100644 --- a/nexus/db-queries/src/db/queries/instance.rs +++ b/nexus/db-queries/src/db/queries/instance.rs @@ -21,6 +21,7 @@ use nexus_db_model::{ use omicron_common::api::internal::nexus::{ MigrationRole, MigrationRuntimeState, }; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid}; use uuid::Uuid; use crate::db::pool::DbConnection; @@ -154,26 +155,28 @@ where impl InstanceAndVmmUpdate { pub fn new( - instance_id: Uuid, + instance_id: InstanceUuid, new_instance_runtime_state: InstanceRuntimeState, - vmm_id: Uuid, + vmm_id: PropolisUuid, new_vmm_runtime_state: VmmRuntimeState, migration: Option, ) -> Self { let instance_find = Box::new( instance_dsl::instance - .filter(instance_dsl::id.eq(instance_id)) + .filter(instance_dsl::id.eq(instance_id.into_untyped_uuid())) .select(instance_dsl::id), ); let vmm_find = Box::new( - vmm_dsl::vmm.filter(vmm_dsl::id.eq(vmm_id)).select(vmm_dsl::id), + vmm_dsl::vmm + .filter(vmm_dsl::id.eq(vmm_id.into_untyped_uuid())) + .select(vmm_dsl::id), ); let instance_update = Box::new( diesel::update(instance_dsl::instance) .filter(instance_dsl::time_deleted.is_null()) - .filter(instance_dsl::id.eq(instance_id)) + .filter(instance_dsl::id.eq(instance_id.into_untyped_uuid())) .filter( instance_dsl::state_generation .lt(new_instance_runtime_state.gen), @@ -184,7 +187,7 @@ impl InstanceAndVmmUpdate { let vmm_update = Box::new( diesel::update(vmm_dsl::vmm) .filter(vmm_dsl::time_deleted.is_null()) - .filter(vmm_dsl::id.eq(vmm_id)) + .filter(vmm_dsl::id.eq(vmm_id.into_untyped_uuid())) .filter(vmm_dsl::state_generation.lt(new_vmm_runtime_state.gen)) .set(new_vmm_runtime_state), ); @@ -210,7 +213,8 @@ impl InstanceAndVmmUpdate { diesel::update(migration_dsl::migration) .filter(migration_dsl::id.eq(migration_id)) .filter( - migration_dsl::target_propolis_id.eq(vmm_id), + migration_dsl::target_propolis_id + .eq(vmm_id.into_untyped_uuid()), ) .filter(migration_dsl::target_gen.lt(gen)) .set(( @@ -223,7 +227,8 @@ impl InstanceAndVmmUpdate { diesel::update(migration_dsl::migration) .filter(migration_dsl::id.eq(migration_id)) .filter( - migration_dsl::source_propolis_id.eq(vmm_id), + migration_dsl::source_propolis_id + .eq(vmm_id.into_untyped_uuid()), ) .filter(migration_dsl::source_gen.lt(gen)) .set(( diff --git a/nexus/db-queries/src/db/queries/network_interface.rs b/nexus/db-queries/src/db/queries/network_interface.rs index e7ce4ca61a..3a5648cd86 100644 --- a/nexus/db-queries/src/db/queries/network_interface.rs +++ b/nexus/db-queries/src/db/queries/network_interface.rs @@ -1873,6 +1873,8 @@ mod tests { use omicron_common::api::external::MacAddr; use omicron_test_utils::dev; use omicron_test_utils::dev::db::CockroachInstance; + use omicron_uuid_kinds::GenericUuid; + use omicron_uuid_kinds::InstanceUuid; use oxnet::Ipv4Net; use oxnet::Ipv6Net; use std::collections::HashSet; @@ -1890,7 +1892,7 @@ mod tests { project_id: Uuid, db_datastore: &DataStore, ) -> Instance { - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); // Use the first chunk of the UUID as the name, to avoid conflicts. // Start with a lower ascii character to satisfy the name constraints. let name = format!("a{}", instance_id)[..9].parse().unwrap(); @@ -1950,7 +1952,10 @@ mod tests { ..instance.runtime_state.clone() }; let res = db_datastore - .instance_update_runtime(&instance.id(), &new_runtime) + .instance_update_runtime( + &InstanceUuid::from_untyped_uuid(instance.id()), + &new_runtime, + ) .await; assert!(matches!(res, Ok(true)), "Failed to change instance state"); instance.runtime_state = new_runtime; @@ -2177,7 +2182,7 @@ mod tests { let context = TestContext::new("test_insert_running_instance_fails", 2).await; let instance = context.create_running_instance().await; - let instance_id = instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let requested_ip = "172.30.0.5".parse().unwrap(); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), @@ -2206,7 +2211,7 @@ mod tests { async fn test_insert_request_exact_ip() { let context = TestContext::new("test_insert_request_exact_ip", 2).await; let instance = context.create_stopped_instance().await; - let instance_id = instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let requested_ip = "172.30.0.5".parse().unwrap(); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), @@ -2242,7 +2247,7 @@ mod tests { TestContext::new("test_insert_no_instance_fails", 2).await; let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - Uuid::new_v4(), + InstanceUuid::new_v4(), context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-b".parse().unwrap(), @@ -2277,9 +2282,10 @@ mod tests { for (i, expected_address) in addresses.take(2).enumerate() { let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: format!("interface-{}", i).parse().unwrap(), @@ -2315,12 +2321,15 @@ mod tests { TestContext::new("test_insert_request_same_ip_fails", 2).await; let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let new_instance = context.create_stopped_instance().await; + let new_instance_id = + InstanceUuid::from_untyped_uuid(new_instance.id()); // Insert an interface on the first instance. let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-c".parse().unwrap(), @@ -2339,7 +2348,7 @@ mod tests { // other parameters are valid. let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - new_instance.id(), + new_instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-c".parse().unwrap(), @@ -2575,9 +2584,10 @@ mod tests { let context = TestContext::new("test_insert_with_duplicate_name_fails", 2).await; let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-c".parse().unwrap(), @@ -2596,7 +2606,7 @@ mod tests { .expect("Failed to insert interface"); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[1].clone(), IdentityMetadataCreateParams { name: "interface-c".parse().unwrap(), @@ -2624,9 +2634,10 @@ mod tests { let context = TestContext::new("test_insert_same_vpc_subnet_fails", 2).await; let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-c".parse().unwrap(), @@ -2642,7 +2653,7 @@ mod tests { .expect("Failed to insert interface"); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-d".parse().unwrap(), @@ -2667,9 +2678,10 @@ mod tests { let context = TestContext::new("test_insert_same_interface_fails", 2).await; let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-c".parse().unwrap(), @@ -2708,9 +2720,10 @@ mod tests { let context = TestContext::new("test_insert_multiple_vpcs_fails", 2).await; let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-c".parse().unwrap(), @@ -2728,7 +2741,7 @@ mod tests { for addr in [Some(expected_address), None] { let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net2.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-a".parse().unwrap(), @@ -2761,9 +2774,10 @@ mod tests { let n_interfaces = context.net1.available_ipv4_addresses()[0]; for _ in 0..n_interfaces { let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-c".parse().unwrap(), @@ -2789,9 +2803,10 @@ mod tests { &context.db_datastore, ) .await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets[0].clone(), IdentityMetadataCreateParams { name: "interface-d".parse().unwrap(), @@ -2819,10 +2834,11 @@ mod tests { TestContext::new("test_insert_multiple_vpc_subnets_succeeds", 2) .await; let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); for (i, subnet) in context.net1.subnets.iter().enumerate() { let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, subnet.clone(), IdentityMetadataCreateParams { name: format!("if{}", i).parse().unwrap(), @@ -2885,11 +2901,12 @@ mod tests { ) .await; let instance = context.create_stopped_instance().await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); for slot in 0..MAX_NICS_PER_INSTANCE { let subnet = &context.net1.subnets[slot]; let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, subnet.clone(), IdentityMetadataCreateParams { name: format!("interface-{}", slot).parse().unwrap(), @@ -2924,7 +2941,7 @@ mod tests { // The next one should fail let interface = IncompleteNetworkInterface::new_instance( Uuid::new_v4(), - instance.id(), + instance_id, context.net1.subnets.last().unwrap().clone(), IdentityMetadataCreateParams { name: "interface-8".parse().unwrap(), diff --git a/nexus/db-queries/src/db/queries/virtual_provisioning_collection_update.rs b/nexus/db-queries/src/db/queries/virtual_provisioning_collection_update.rs index b3c1a569b0..fd86912107 100644 --- a/nexus/db-queries/src/db/queries/virtual_provisioning_collection_update.rs +++ b/nexus/db-queries/src/db/queries/virtual_provisioning_collection_update.rs @@ -19,6 +19,8 @@ use diesel::result::Error as DieselError; use diesel::sql_types; use omicron_common::api::external; use omicron_common::api::external::MessagePair; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; type AllColumnsOfVirtualResource = AllColumnsOf; @@ -458,13 +460,13 @@ FROM } pub fn new_insert_instance( - id: uuid::Uuid, + id: InstanceUuid, cpus_diff: i64, ram_diff: ByteCount, project_id: uuid::Uuid, ) -> TypedSqlQuery> { let mut provision = VirtualProvisioningResource::new( - id, + id.into_untyped_uuid(), ResourceTypeProvisioned::Instance, ); provision.cpus_provisioned = cpus_diff; @@ -474,7 +476,7 @@ FROM } pub fn new_delete_instance( - id: uuid::Uuid, + id: InstanceUuid, max_instance_gen: i64, cpus_diff: i64, ram_diff: ByteCount, @@ -482,7 +484,7 @@ FROM ) -> TypedSqlQuery> { Self::apply_update( UpdateKind::DeleteInstance { - id, + id: id.into_untyped_uuid(), max_instance_gen, cpus_diff, ram_diff, @@ -544,7 +546,7 @@ mod test { #[tokio::test] async fn expectorate_query_insert_instance() { - let id = Uuid::nil(); + let id = InstanceUuid::nil(); let project_id = Uuid::nil(); let cpus_diff = 4; let ram_diff = 2048.try_into().unwrap(); @@ -561,7 +563,7 @@ mod test { #[tokio::test] async fn expectorate_query_delete_instance() { - let id = Uuid::nil(); + let id = InstanceUuid::nil(); let project_id = Uuid::nil(); let cpus_diff = 4; let ram_diff = 2048.try_into().unwrap(); @@ -649,7 +651,7 @@ mod test { let pool = crate::db::Pool::new(&logctx.log, &cfg); let conn = pool.pool().get().await.unwrap(); - let id = Uuid::nil(); + let id = InstanceUuid::nil(); let project_id = Uuid::nil(); let cpus_diff = 16.try_into().unwrap(); let ram_diff = 2048.try_into().unwrap(); @@ -675,7 +677,7 @@ mod test { let pool = crate::db::Pool::new(&logctx.log, &cfg); let conn = pool.pool().get().await.unwrap(); - let id = Uuid::nil(); + let id = InstanceUuid::nil(); let max_instance_gen = 0; let project_id = Uuid::nil(); let cpus_diff = 16.try_into().unwrap(); diff --git a/nexus/src/app/background/abandoned_vmm_reaper.rs b/nexus/src/app/background/abandoned_vmm_reaper.rs index 4685012e28..3883185d9f 100644 --- a/nexus/src/app/background/abandoned_vmm_reaper.rs +++ b/nexus/src/app/background/abandoned_vmm_reaper.rs @@ -39,6 +39,7 @@ use nexus_db_model::Vmm; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::pagination::Paginator; use nexus_db_queries::db::DataStore; +use omicron_uuid_kinds::{GenericUuid, PropolisUuid}; use std::num::NonZeroU32; use std::sync::Arc; @@ -108,10 +109,14 @@ impl AbandonedVmmReaper { slog::debug!(opctx.log, "Found abandoned VMMs"; "count" => vmms.len()); for vmm in vmms { - let vmm_id = vmm.id; + let vmm_id = PropolisUuid::from_untyped_uuid(vmm.id); slog::trace!(opctx.log, "Deleting abandoned VMM"; "vmm" => %vmm_id); // Attempt to remove the abandoned VMM's sled resource reservation. - match self.datastore.sled_reservation_delete(opctx, vmm_id).await { + match self + .datastore + .sled_reservation_delete(opctx, vmm_id.into_untyped_uuid()) + .await + { Ok(_) => { slog::trace!( opctx.log, @@ -235,7 +240,7 @@ mod tests { const PROJECT_NAME: &str = "carcosa"; struct TestFixture { - destroyed_vmm_id: Uuid, + destroyed_vmm_id: PropolisUuid, } impl TestFixture { @@ -255,12 +260,12 @@ mod tests { ) .await; - let destroyed_vmm_id = Uuid::new_v4(); + let destroyed_vmm_id = PropolisUuid::new_v4(); datastore .vmm_insert( &opctx, dbg!(Vmm { - id: destroyed_vmm_id, + id: destroyed_vmm_id.into_untyped_uuid(), time_created: Utc::now(), time_deleted: None, instance_id: instance.identity.id, @@ -287,7 +292,7 @@ mod tests { dbg!(datastore .sled_reservation_create( &opctx, - destroyed_vmm_id, + destroyed_vmm_id.into_untyped_uuid(), SledResourceKind::Instance, resources.clone(), constraints, @@ -308,7 +313,9 @@ mod tests { let conn = datastore.pool_connection_for_tests().await.unwrap(); let fetched_vmm = vmm_dsl::vmm - .filter(vmm_dsl::id.eq(self.destroyed_vmm_id)) + .filter( + vmm_dsl::id.eq(self.destroyed_vmm_id.into_untyped_uuid()), + ) .filter(vmm_dsl::time_deleted.is_null()) .select(Vmm::as_select()) .first_async::(&*conn) @@ -321,7 +328,10 @@ mod tests { ); let fetched_sled_resource = sled_resource_dsl::sled_resource - .filter(sled_resource_dsl::id.eq(self.destroyed_vmm_id)) + .filter( + sled_resource_dsl::id + .eq(self.destroyed_vmm_id.into_untyped_uuid()), + ) .select(SledResource::as_select()) .first_async::(&*conn) .await @@ -439,7 +449,10 @@ mod tests { assert!(!abandoned_vmms.is_empty()); datastore - .sled_reservation_delete(&opctx, fixture.destroyed_vmm_id) + .sled_reservation_delete( + &opctx, + fixture.destroyed_vmm_id.into_untyped_uuid(), + ) .await .expect( "simulate another nexus marking the sled reservation deleted", diff --git a/nexus/src/app/background/instance_watcher.rs b/nexus/src/app/background/instance_watcher.rs index c4eda68594..1b10605c5e 100644 --- a/nexus/src/app/background/instance_watcher.rs +++ b/nexus/src/app/background/instance_watcher.rs @@ -18,6 +18,8 @@ use nexus_types::identity::Asset; use nexus_types::identity::Resource; use omicron_common::api::external::InstanceState; use omicron_common::api::internal::nexus::SledInstanceState; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use oximeter::types::ProducerRegistry; use sled_agent_client::Client as SledAgentClient; use std::borrow::Cow; @@ -79,7 +81,11 @@ impl InstanceWatcher { async move { slog::trace!(opctx.log, "checking on instance..."); - let rsp = client.instance_get_state(&target.instance_id).await; + let rsp = client + .instance_get_state(&InstanceUuid::from_untyped_uuid( + target.instance_id, + )) + .await; let mut check = Check { target, outcome: Default::default(), result: Ok(()) }; let state = match rsp { @@ -154,7 +160,7 @@ impl InstanceWatcher { &opctx, &opctx, &opctx.log, - &target.instance_id, + &InstanceUuid::from_untyped_uuid(target.instance_id), &new_runtime_state, v2p_notification_tx, ) diff --git a/nexus/src/app/external_ip.rs b/nexus/src/app/external_ip.rs index 62b8c4cbd6..06dfc7732f 100644 --- a/nexus/src/app/external_ip.rs +++ b/nexus/src/app/external_ip.rs @@ -24,6 +24,8 @@ use omicron_common::api::external::ListResultVec; use omicron_common::api::external::LookupResult; use omicron_common::api::external::NameOrId; use omicron_common::api::external::UpdateResult; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; impl super::Nexus { pub(crate) async fn instance_list_external_ips( @@ -35,7 +37,10 @@ impl super::Nexus { instance_lookup.lookup_for(authz::Action::Read).await?; Ok(self .db_datastore - .instance_lookup_external_ips(opctx, authz_instance.id()) + .instance_lookup_external_ips( + opctx, + InstanceUuid::from_untyped_uuid(authz_instance.id()), + ) .await? .into_iter() .filter_map(|ip| { diff --git a/nexus/src/app/instance.rs b/nexus/src/app/instance.rs index 943665cab3..517fbf218a 100644 --- a/nexus/src/app/instance.rs +++ b/nexus/src/app/instance.rs @@ -47,6 +47,10 @@ use omicron_common::api::external::UpdateResult; use omicron_common::api::internal::nexus; use omicron_common::api::internal::nexus::VmmState; use omicron_common::api::internal::shared::SourceNatConfig; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; +use omicron_uuid_kinds::PropolisUuid; +use omicron_uuid_kinds::SledUuid; use propolis_client::support::tungstenite::protocol::frame::coding::CloseCode; use propolis_client::support::tungstenite::protocol::CloseFrame; use propolis_client::support::tungstenite::Message as WebSocketMessage; @@ -174,14 +178,14 @@ enum InstanceStateChangeRequestAction { /// Request the appropriate state change from the sled with the specified /// UUID. - SendToSled(Uuid), + SendToSled(SledUuid), } /// What is the higher level operation that is calling /// `instance_ensure_registered`? pub(crate) enum InstanceRegisterReason { - Start { vmm_id: Uuid }, - Migrate { vmm_id: Uuid, target_vmm_id: Uuid }, + Start { vmm_id: PropolisUuid }, + Migrate { vmm_id: PropolisUuid, target_vmm_id: PropolisUuid }, } impl super::Nexus { @@ -534,8 +538,8 @@ impl super::Nexus { pub(crate) async fn instance_set_migration_ids( &self, opctx: &OpContext, - instance_id: Uuid, - sled_id: Uuid, + instance_id: InstanceUuid, + sled_id: SledUuid, prev_instance_runtime: &db::model::InstanceRuntimeState, migration_params: InstanceMigrationSourceParams, ) -> UpdateResult { @@ -543,7 +547,7 @@ impl super::Nexus { assert!(prev_instance_runtime.dst_propolis_id.is_none()); let (.., authz_instance) = LookupPath::new(opctx, &self.db_datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await?; @@ -613,8 +617,8 @@ impl super::Nexus { /// ID set. pub(crate) async fn instance_clear_migration_ids( &self, - instance_id: Uuid, - sled_id: Uuid, + instance_id: InstanceUuid, + sled_id: SledUuid, prev_instance_runtime: &db::model::InstanceRuntimeState, ) -> Result<(), Error> { assert!(prev_instance_runtime.migration_id.is_some()); @@ -682,7 +686,9 @@ impl super::Nexus { if inner.instance_unhealthy() { let _ = self .mark_instance_failed( - &authz_instance.id(), + &InstanceUuid::from_untyped_uuid( + authz_instance.id(), + ), state.instance().runtime(), inner, ) @@ -786,7 +792,9 @@ impl super::Nexus { if inner.instance_unhealthy() { let _ = self .mark_instance_failed( - &authz_instance.id(), + &InstanceUuid::from_untyped_uuid( + authz_instance.id(), + ), state.instance().runtime(), inner, ) @@ -807,19 +815,19 @@ impl super::Nexus { &self, opctx: &OpContext, authz_instance: &authz::Instance, - sled_id: &Uuid, + sled_id: &SledUuid, ) -> Result, InstanceStateChangeError> { opctx.authorize(authz::Action::Modify, authz_instance).await?; let sa = self.sled_client(&sled_id).await?; - sa.instance_unregister(&authz_instance.id()) - .await - .map(|res| res.into_inner().updated_runtime.map(Into::into)) - .map_err(|e| { - InstanceStateChangeError::SledAgent(SledAgentInstancePutError( - e, - )) - }) + sa.instance_unregister(&InstanceUuid::from_untyped_uuid( + authz_instance.id(), + )) + .await + .map(|res| res.into_inner().updated_runtime.map(Into::into)) + .map_err(|e| { + InstanceStateChangeError::SledAgent(SledAgentInstancePutError(e)) + }) } /// Determines the action to take on an instance's active VMM given a @@ -855,7 +863,7 @@ impl super::Nexus { // instance's current sled agent. If there is none, the request needs to // be handled specially based on its type. let sled_id = if let Some(vmm) = vmm_state { - vmm.sled_id + SledUuid::from_untyped_uuid(vmm.sled_id) } else { match effective_state { // If there's no active sled because the instance is stopped, @@ -974,7 +982,7 @@ impl super::Nexus { requested: InstanceStateChangeRequest, ) -> Result<(), InstanceStateChangeError> { opctx.authorize(authz::Action::Modify, authz_instance).await?; - let instance_id = authz_instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(authz_instance.id()); match self.select_runtime_change_action( prev_instance_state, @@ -1021,7 +1029,7 @@ impl super::Nexus { opctx: &OpContext, authz_instance: &authz::Instance, db_instance: &db::model::Instance, - propolis_id: &Uuid, + propolis_id: &PropolisUuid, initial_vmm: &db::model::Vmm, operation: InstanceRegisterReason, ) -> Result<(), Error> { @@ -1111,7 +1119,10 @@ impl super::Nexus { // Collect the external IPs for the instance. let (snat_ip, external_ips): (Vec<_>, Vec<_>) = self .db_datastore - .instance_lookup_external_ips(&opctx, authz_instance.id()) + .instance_lookup_external_ips( + &opctx, + InstanceUuid::from_untyped_uuid(authz_instance.id()), + ) .await? .into_iter() .partition(|ip| ip.kind == IpKind::SNat); @@ -1264,10 +1275,13 @@ impl super::Nexus { )), }; - let sa = self.sled_client(&initial_vmm.sled_id).await?; + let instance_id = InstanceUuid::from_untyped_uuid(db_instance.id()); + let sa = self + .sled_client(&SledUuid::from_untyped_uuid(initial_vmm.sled_id)) + .await?; let instance_register_result = sa .instance_register( - &db_instance.id(), + &instance_id, &sled_agent_client::types::InstanceEnsureBody { hardware: instance_hardware, instance_runtime: db_instance.runtime().clone().into(), @@ -1287,14 +1301,13 @@ impl super::Nexus { match instance_register_result { Ok(state) => { - self.write_returned_instance_state(&db_instance.id(), state) - .await?; + self.write_returned_instance_state(&instance_id, state).await?; } Err(e) => { if e.instance_unhealthy() { let _ = self .mark_instance_failed( - &db_instance.id(), + &instance_id, db_instance.runtime(), &e, ) @@ -1322,7 +1335,7 @@ impl super::Nexus { /// owing to an outdated generation number) will return `Ok`. async fn write_returned_instance_state( &self, - instance_id: &Uuid, + instance_id: &InstanceUuid, state: Option, ) -> Result { slog::debug!(&self.log, @@ -1365,7 +1378,7 @@ impl super::Nexus { /// agent instance API, supplied in `reason`. pub(crate) async fn mark_instance_failed( &self, - instance_id: &Uuid, + instance_id: &InstanceUuid, prev_instance_runtime: &db::model::InstanceRuntimeState, reason: &SledAgentInstancePutError, ) -> Result<(), Error> { @@ -1523,7 +1536,7 @@ impl super::Nexus { pub(crate) async fn notify_instance_updated( &self, opctx: &OpContext, - instance_id: &Uuid, + instance_id: &InstanceUuid, new_runtime_state: &nexus::SledInstanceState, ) -> Result<(), Error> { notify_instance_updated( @@ -1973,7 +1986,7 @@ pub(crate) async fn notify_instance_updated( opctx_alloc: &OpContext, opctx: &OpContext, log: &slog::Logger, - instance_id: &Uuid, + instance_id: &InstanceUuid, new_runtime_state: &nexus::SledInstanceState, v2p_notification_tx: tokio::sync::watch::Sender<()>, ) -> Result, Error> { @@ -1989,7 +2002,7 @@ pub(crate) async fn notify_instance_updated( // Grab the current state of the instance in the DB to reason about // whether this update is stale or not. let (.., authz_instance, db_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(*instance_id) + .instance_id(instance_id.into_untyped_uuid()) .fetch() .await?; @@ -2054,8 +2067,13 @@ pub(crate) async fn notify_instance_updated( // an instance's state changes. // // Tracked in https://github.com/oxidecomputer/omicron/issues/3742. - super::oximeter::unassign_producer(datastore, log, opctx, instance_id) - .await?; + super::oximeter::unassign_producer( + datastore, + log, + opctx, + &instance_id.into_untyped_uuid(), + ) + .await?; } // Write the new instance and VMM states back to CRDB. This needs to be @@ -2136,7 +2154,9 @@ pub(crate) async fn notify_instance_updated( "instance_id" => %instance_id, "propolis_id" => %propolis_id); - datastore.sled_reservation_delete(opctx, propolis_id).await?; + datastore + .sled_reservation_delete(opctx, propolis_id.into_untyped_uuid()) + .await?; if !datastore.vmm_mark_deleted(opctx, &propolis_id).await? { warn!(log, "failed to mark vmm record as deleted"; diff --git a/nexus/src/app/instance_network.rs b/nexus/src/app/instance_network.rs index 3c607bae78..b1ad2bb6fc 100644 --- a/nexus/src/app/instance_network.rs +++ b/nexus/src/app/instance_network.rs @@ -20,6 +20,8 @@ use omicron_common::api::external::Error; use omicron_common::api::internal::nexus; use omicron_common::api::internal::shared::NetworkInterface; use omicron_common::api::internal::shared::SwitchLocation; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use oxnet::Ipv4Net; use oxnet::Ipv6Net; use std::collections::HashSet; @@ -63,7 +65,7 @@ impl super::Nexus { pub(crate) async fn instance_ensure_dpd_config( &self, opctx: &OpContext, - instance_id: Uuid, + instance_id: InstanceUuid, sled_ip_address: &std::net::SocketAddrV6, ip_filter: Option, ) -> Result, Error> { @@ -266,7 +268,7 @@ pub(crate) async fn ensure_updated_instance_network_config( new_instance_state: &nexus::InstanceRuntimeState, v2p_notification_tx: tokio::sync::watch::Sender<()>, ) -> Result<(), Error> { - let instance_id = authz_instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(authz_instance.id()); // If this instance update is stale, do nothing, since the superseding // update may have allowed the instance's location to change further. @@ -335,7 +337,8 @@ pub(crate) async fn ensure_updated_instance_network_config( let migration_retired = prev_instance_state.migration_id.is_some() && new_instance_state.migration_id.is_none(); - if (prev_instance_state.propolis_id == new_instance_state.propolis_id) + if (prev_instance_state.propolis_id + == new_instance_state.propolis_id.map(GenericUuid::into_untyped_uuid)) && !migration_retired { debug!(log, "instance didn't move, won't touch network config"; @@ -438,7 +441,7 @@ pub(crate) async fn instance_ensure_dpd_config( resolver: &internal_dns::resolver::Resolver, opctx: &OpContext, opctx_alloc: &OpContext, - instance_id: Uuid, + instance_id: InstanceUuid, sled_ip_address: &std::net::SocketAddrV6, ip_filter: Option, ) -> Result, Error> { @@ -446,7 +449,7 @@ pub(crate) async fn instance_ensure_dpd_config( "instance_id" => %instance_id); let (.., authz_instance) = LookupPath::new(opctx, datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::ListChildren) .await?; @@ -724,7 +727,7 @@ async fn clear_instance_networking_state( log, resolver, opctx_alloc, - Some(authz_instance.id()), + Some(InstanceUuid::from_untyped_uuid(authz_instance.id())), true, ) .await @@ -760,7 +763,7 @@ pub(crate) async fn instance_delete_dpd_config( opctx_alloc: &OpContext, authz_instance: &authz::Instance, ) -> Result<(), Error> { - let instance_id = authz_instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(authz_instance.id()); info!(log, "deleting instance dpd configuration"; "instance_id" => %instance_id); @@ -949,7 +952,7 @@ async fn notify_dendrite_nat_state( log: &slog::Logger, resolver: &internal_dns::resolver::Resolver, opctx_alloc: &OpContext, - instance_id: Option, + instance_id: Option, fail_fast: bool, ) -> Result<(), Error> { // Querying boundary switches also requires fleet access and the use of the diff --git a/nexus/src/app/network_interface.rs b/nexus/src/app/network_interface.rs index d1fa87073e..fef8e9d1ac 100644 --- a/nexus/src/app/network_interface.rs +++ b/nexus/src/app/network_interface.rs @@ -11,6 +11,8 @@ use omicron_common::api::external::NameOrId; use omicron_common::api::external::http_pagination::PaginatedBy; use omicron_common::api::external::UpdateResult; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use uuid::Uuid; use nexus_db_queries::authz; @@ -87,7 +89,7 @@ impl super::Nexus { let interface_id = Uuid::new_v4(); let interface = db::model::IncompleteNetworkInterface::new_instance( interface_id, - authz_instance.id(), + InstanceUuid::from_untyped_uuid(authz_instance.id()), db_subnet, params.identity.clone(), params.ip, diff --git a/nexus/src/app/sagas/instance_common.rs b/nexus/src/app/sagas/instance_common.rs index 14263df0ff..6e431aaca7 100644 --- a/nexus/src/app/sagas/instance_common.rs +++ b/nexus/src/app/sagas/instance_common.rs @@ -16,9 +16,9 @@ use nexus_db_queries::authz; use nexus_db_queries::db::lookup::LookupPath; use nexus_db_queries::{authn, context::OpContext, db, db::DataStore}; use omicron_common::api::external::{Error, NameOrId}; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid, SledUuid}; use serde::{Deserialize, Serialize}; use steno::ActionError; -use uuid::Uuid; use super::NexusActionContext; @@ -33,7 +33,7 @@ const DEFAULT_PROPOLIS_PORT: u16 = 12400; /// `propolis_id`. pub async fn reserve_vmm_resources( nexus: &Nexus, - propolis_id: Uuid, + propolis_id: PropolisUuid, ncpus: u32, guest_memory: ByteCount, constraints: SledReservationConstraints, @@ -68,7 +68,7 @@ pub async fn reserve_vmm_resources( let resource = nexus .reserve_on_random_sled( - propolis_id, + propolis_id.into_untyped_uuid(), nexus_db_model::SledResourceKind::Instance, resources, constraints, @@ -88,9 +88,9 @@ pub async fn reserve_vmm_resources( pub async fn create_and_insert_vmm_record( datastore: &DataStore, opctx: &OpContext, - instance_id: Uuid, - propolis_id: Uuid, - sled_id: Uuid, + instance_id: InstanceUuid, + propolis_id: PropolisUuid, + sled_id: SledUuid, propolis_ip: Ipv6Addr, initial_state: nexus_db_model::VmmInitialState, ) -> Result { @@ -131,8 +131,9 @@ pub async fn unwind_vmm_record( gen: prev_record.runtime.gen.next().into(), }; - datastore.vmm_update_runtime(&prev_record.id, &new_runtime).await?; - datastore.vmm_mark_deleted(&opctx, &prev_record.id).await?; + let prev_id = PropolisUuid::from_untyped_uuid(prev_record.id); + datastore.vmm_update_runtime(&prev_id, &new_runtime).await?; + datastore.vmm_mark_deleted(&opctx, &prev_id).await?; Ok(()) } @@ -141,7 +142,7 @@ pub async fn unwind_vmm_record( pub(super) async fn allocate_vmm_ipv6( opctx: &OpContext, datastore: &DataStore, - sled_uuid: Uuid, + sled_uuid: SledUuid, ) -> Result { datastore .next_ipv6_address(opctx, sled_uuid) @@ -217,7 +218,7 @@ pub async fn instance_ip_get_instance_state( serialized_authn: &authn::saga::Serialized, authz_instance: &authz::Instance, verb: &str, -) -> Result, ActionError> { +) -> Result, ActionError> { // XXX: we can get instance state (but not sled ID) in same transaction // as attach (but not detach) wth current design. We need to re-query // for sled ID anyhow, so keep consistent between attach/detach. @@ -351,7 +352,7 @@ pub async fn instance_ip_add_nat( sagactx: &NexusActionContext, serialized_authn: &authn::saga::Serialized, authz_instance: &authz::Instance, - sled_uuid: Option, + sled_uuid: Option, target_ip: ModifyStateForExternalIp, ) -> Result, ActionError> { let osagactx = sagactx.user_data(); @@ -376,7 +377,7 @@ pub async fn instance_ip_add_nat( // Querying sleds requires fleet access; use the instance allocator context // for this. let (.., sled) = LookupPath::new(&osagactx.nexus().opctx_alloc, &datastore) - .sled_id(sled_uuid) + .sled_id(sled_uuid.into_untyped_uuid()) .fetch() .await .map_err(ActionError::action_failed)?; @@ -385,7 +386,7 @@ pub async fn instance_ip_add_nat( .nexus() .instance_ensure_dpd_config( &opctx, - authz_instance.id(), + InstanceUuid::from_untyped_uuid(authz_instance.id()), &sled.address(), Some(target_ip.id), ) @@ -407,7 +408,7 @@ pub async fn instance_ip_add_nat( pub async fn instance_ip_remove_nat( sagactx: &NexusActionContext, serialized_authn: &authn::saga::Serialized, - sled_uuid: Option, + sled_uuid: Option, target_ip: ModifyStateForExternalIp, ) -> Result<(), ActionError> { let osagactx = sagactx.user_data(); @@ -445,7 +446,7 @@ pub async fn instance_ip_remove_nat( pub async fn instance_ip_add_opte( sagactx: &NexusActionContext, authz_instance: &authz::Instance, - sled_uuid: Option, + sled_uuid: Option, target_ip: ModifyStateForExternalIp, ) -> Result<(), ActionError> { let osagactx = sagactx.user_data(); @@ -476,7 +477,10 @@ pub async fn instance_ip_add_opte( "sled agent client went away mid-attach/detach", )) })? - .instance_put_external_ip(&authz_instance.id(), &sled_agent_body) + .instance_put_external_ip( + &InstanceUuid::from_untyped_uuid(authz_instance.id()), + &sled_agent_body, + ) .await .map_err(|e| { ActionError::action_failed(match e { @@ -500,7 +504,7 @@ pub async fn instance_ip_add_opte( pub async fn instance_ip_remove_opte( sagactx: &NexusActionContext, authz_instance: &authz::Instance, - sled_uuid: Option, + sled_uuid: Option, target_ip: ModifyStateForExternalIp, ) -> Result<(), ActionError> { let osagactx = sagactx.user_data(); @@ -531,7 +535,10 @@ pub async fn instance_ip_remove_opte( "sled agent client went away mid-attach/detach", )) })? - .instance_delete_external_ip(&authz_instance.id(), &sled_agent_body) + .instance_delete_external_ip( + &InstanceUuid::from_untyped_uuid(authz_instance.id()), + &sled_agent_body, + ) .await .map_err(|e| { ActionError::action_failed(match e { diff --git a/nexus/src/app/sagas/instance_create.rs b/nexus/src/app/sagas/instance_create.rs index f336a01f0c..ffbd5ff2f5 100644 --- a/nexus/src/app/sagas/instance_create.rs +++ b/nexus/src/app/sagas/instance_create.rs @@ -22,6 +22,7 @@ use omicron_common::api::external::Name; use omicron_common::api::external::NameOrId; use omicron_common::api::external::{Error, InternalContext}; use omicron_common::api::internal::shared::SwitchLocation; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; use ref_cast::RefCast; use serde::Deserialize; use serde::Serialize; @@ -51,14 +52,14 @@ pub(crate) struct Params { struct NetParams { saga_params: Params, which: usize, - instance_id: Uuid, + instance_id: InstanceUuid, new_id: Uuid, } #[derive(Debug, Deserialize, Serialize)] struct NetworkConfigParams { saga_params: Params, - instance_id: Uuid, + instance_id: InstanceUuid, which: usize, switch_location: SwitchLocation, } @@ -67,7 +68,7 @@ struct NetworkConfigParams { struct DiskAttachParams { serialized_authn: authn::saga::Serialized, project_id: Uuid, - instance_id: Uuid, + instance_id: InstanceUuid, attach_params: InstanceDiskAttachment, } @@ -122,7 +123,7 @@ impl NexusSaga for SagaInstanceCreate { ) -> Result { // Pre-create the instance ID so that it can be supplied as a constant // parameter to the subsagas that create and attach devices. - let instance_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); builder.append(Node::constant( "instance_id", @@ -307,7 +308,7 @@ async fn sic_associate_ssh_keys( &sagactx, &saga_params.serialized_authn, ); - let instance_id = sagactx.lookup::("instance_id")?; + let instance_id = sagactx.lookup::("instance_id")?; // Gather the SSH public keys of the actor making the request so // that they may be injected into the new image via cloud-init. @@ -359,7 +360,7 @@ async fn sic_associate_ssh_keys_undo( &sagactx, &saga_params.serialized_authn, ); - let instance_id = sagactx.lookup::("instance_id")?; + let instance_id = sagactx.lookup::("instance_id")?; datastore .instance_ssh_keys_delete(&opctx, instance_id) .await @@ -423,7 +424,7 @@ async fn sic_create_network_interface_undo( ); let interface_id = repeat_saga_params.new_id; let (.., authz_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await .map_err(ActionError::action_failed)?; @@ -469,7 +470,7 @@ async fn sic_create_network_interface_undo( async fn create_custom_network_interface( sagactx: &NexusActionContext, saga_params: &Params, - instance_id: Uuid, + instance_id: InstanceUuid, interface_id: Uuid, interface_params: ¶ms::InstanceNetworkInterfaceCreate, ) -> Result<(), ActionError> { @@ -482,7 +483,7 @@ async fn create_custom_network_interface( // Lookup authz objects, used in the call to create the NIC itself. let (.., authz_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::CreateChild) .await .map_err(ActionError::action_failed)?; @@ -544,7 +545,7 @@ async fn create_default_primary_network_interface( sagactx: &NexusActionContext, saga_params: &Params, nic_index: usize, - instance_id: Uuid, + instance_id: InstanceUuid, interface_id: Uuid, ) -> Result<(), ActionError> { // We're statically creating up to MAX_NICS_PER_INSTANCE saga nodes, but @@ -588,7 +589,7 @@ async fn create_default_primary_network_interface( // Lookup authz objects, used in the call to actually create the NIC. let (.., authz_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::CreateChild) .await .map_err(ActionError::action_failed)?; @@ -643,7 +644,7 @@ async fn sic_allocate_instance_snat_ip( &sagactx, &saga_params.serialized_authn, ); - let instance_id = sagactx.lookup::("instance_id")?; + let instance_id = sagactx.lookup::("instance_id")?; let ip_id = sagactx.lookup::("snat_ip_id")?; let (.., pool) = datastore @@ -886,7 +887,7 @@ async fn ensure_instance_disk_attach_state( let (.., authz_instance, _db_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .fetch() .await .map_err(ActionError::action_failed)?; @@ -929,7 +930,7 @@ async fn sic_create_instance_record( &sagactx, ¶ms.serialized_authn, ); - let instance_id = sagactx.lookup::("instance_id")?; + let instance_id = sagactx.lookup::("instance_id")?; let new_instance = db::model::Instance::new( instance_id, @@ -962,7 +963,7 @@ async fn sic_delete_instance_record( &sagactx, ¶ms.serialized_authn, ); - let instance_id = sagactx.lookup::("instance_id")?; + let instance_id = sagactx.lookup::("instance_id")?; let instance_name = sagactx .lookup::("instance_record")? .name() @@ -1024,7 +1025,7 @@ async fn sic_move_to_stopped( sagactx: NexusActionContext, ) -> Result<(), ActionError> { let osagactx = sagactx.user_data(); - let instance_id = sagactx.lookup::("instance_id")?; + let instance_id = sagactx.lookup::("instance_id")?; let instance_record = sagactx.lookup::("instance_record")?; diff --git a/nexus/src/app/sagas/instance_ip_attach.rs b/nexus/src/app/sagas/instance_ip_attach.rs index f8edf37dc4..c4e209dccd 100644 --- a/nexus/src/app/sagas/instance_ip_attach.rs +++ b/nexus/src/app/sagas/instance_ip_attach.rs @@ -13,6 +13,7 @@ use crate::app::{authn, authz}; use nexus_db_model::{IpAttachState, Ipv4NatEntry}; use nexus_types::external_api::views; use omicron_common::api::external::Error; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, SledUuid}; use serde::Deserialize; use serde::Serialize; use steno::ActionError; @@ -89,6 +90,8 @@ async fn siia_begin_attach_ip( ¶ms.serialized_authn, ); + let instance_id = + InstanceUuid::from_untyped_uuid(params.authz_instance.id()); match ¶ms.create_params { // Allocate a new IP address from the target, possibly default, pool ExternalIpAttach::Ephemeral { pool } => { @@ -111,7 +114,7 @@ async fn siia_begin_attach_ip( .allocate_instance_ephemeral_ip( &opctx, Uuid::new_v4(), - params.authz_instance.id(), + instance_id, pool, false, ) @@ -124,12 +127,7 @@ async fn siia_begin_attach_ip( } // Set the parent of an existing floating IP to the new instance's ID. ExternalIpAttach::Floating { floating_ip } => datastore - .floating_ip_begin_attach( - &opctx, - &floating_ip, - params.authz_instance.id(), - false, - ) + .floating_ip_begin_attach(&opctx, &floating_ip, instance_id, false) .await .map_err(ActionError::action_failed) .map(|(external_ip, do_saga)| ModifyStateForExternalIp { @@ -163,7 +161,7 @@ async fn siia_begin_attach_ip_undo( async fn siia_get_instance_state( sagactx: NexusActionContext, -) -> Result, ActionError> { +) -> Result, ActionError> { let params = sagactx.saga_params::()?; instance_ip_get_instance_state( &sagactx, @@ -179,7 +177,7 @@ async fn siia_nat( sagactx: NexusActionContext, ) -> Result, ActionError> { let params = sagactx.saga_params::()?; - let sled_id = sagactx.lookup::>("instance_state")?; + let sled_id = sagactx.lookup::>("instance_state")?; let target_ip = sagactx.lookup::("target_ip")?; instance_ip_add_nat( &sagactx, @@ -248,7 +246,7 @@ async fn siia_update_opte( sagactx: NexusActionContext, ) -> Result<(), ActionError> { let params = sagactx.saga_params::()?; - let sled_id = sagactx.lookup::>("instance_state")?; + let sled_id = sagactx.lookup::>("instance_state")?; let target_ip = sagactx.lookup::("target_ip")?; instance_ip_add_opte(&sagactx, ¶ms.authz_instance, sled_id, target_ip) .await @@ -259,7 +257,7 @@ async fn siia_update_opte_undo( ) -> Result<(), anyhow::Error> { let log = sagactx.user_data().log(); let params = sagactx.saga_params::()?; - let sled_id = sagactx.lookup::>("instance_state")?; + let sled_id = sagactx.lookup::>("instance_state")?; let target_ip = sagactx.lookup::("target_ip")?; if let Err(e) = instance_ip_remove_opte( &sagactx, @@ -420,9 +418,10 @@ pub(crate) mod test { let instance = create_instance(client, PROJECT_NAME, INSTANCE_NAME).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); crate::app::sagas::test_helpers::instance_simulate( cptestctx, - &instance.identity.id, + &instance_id, ) .await; @@ -434,11 +433,9 @@ pub(crate) mod test { nexus.run_saga(saga).await.expect("Attach saga should succeed"); } - let instance_id = instance.id(); - // Sled agent has a record of the new external IPs. let mut eips = sled_agent.external_ips.lock().await; - let my_eips = eips.entry(instance_id).or_default(); + let my_eips = eips.entry(instance_id.into_untyped_uuid()).or_default(); assert!(my_eips.iter().any(|v| matches!( v, omicron_sled_agent::params::InstanceExternalIpBody::Floating(_) @@ -517,7 +514,7 @@ pub(crate) mod test { crate::app::sagas::test_helpers::instance_simulate( cptestctx, - &instance.identity.id, + &InstanceUuid::from_untyped_uuid(instance.identity.id), ) .await; @@ -549,7 +546,7 @@ pub(crate) mod test { crate::app::sagas::test_helpers::instance_simulate( cptestctx, - &instance.identity.id, + &InstanceUuid::from_untyped_uuid(instance.identity.id), ) .await; @@ -584,7 +581,7 @@ pub(crate) mod test { crate::app::sagas::test_helpers::instance_simulate( cptestctx, - &instance.identity.id, + &InstanceUuid::from_untyped_uuid(instance.identity.id), ) .await; diff --git a/nexus/src/app/sagas/instance_ip_detach.rs b/nexus/src/app/sagas/instance_ip_detach.rs index 9625d77bf9..474cfb18a6 100644 --- a/nexus/src/app/sagas/instance_ip_detach.rs +++ b/nexus/src/app/sagas/instance_ip_detach.rs @@ -15,6 +15,7 @@ use nexus_db_model::IpAttachState; use nexus_db_queries::db::lookup::LookupPath; use nexus_types::external_api::views; use omicron_common::api::external::NameOrId; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, SledUuid}; use ref_cast::RefCast; use serde::Deserialize; use serde::Serialize; @@ -71,13 +72,12 @@ async fn siid_begin_detach_ip( ¶ms.serialized_authn, ); + let instance_id = + InstanceUuid::from_untyped_uuid(params.authz_instance.id()); match ¶ms.delete_params { params::ExternalIpDetach::Ephemeral => { let eip = datastore - .instance_lookup_ephemeral_ip( - &opctx, - params.authz_instance.id(), - ) + .instance_lookup_ephemeral_ip(&opctx, instance_id) .await .map_err(ActionError::action_failed)?; @@ -86,7 +86,7 @@ async fn siid_begin_detach_ip( .begin_deallocate_ephemeral_ip( &opctx, eph_ip.id, - params.authz_instance.id(), + instance_id, ) .await .map_err(ActionError::action_failed) @@ -118,7 +118,7 @@ async fn siid_begin_detach_ip( .floating_ip_begin_detach( &opctx, &authz_fip, - params.authz_instance.id(), + instance_id, false, ) .await @@ -155,7 +155,7 @@ async fn siid_begin_detach_ip_undo( async fn siid_get_instance_state( sagactx: NexusActionContext, -) -> Result, ActionError> { +) -> Result, ActionError> { let params = sagactx.saga_params::()?; instance_ip_get_instance_state( &sagactx, @@ -168,7 +168,7 @@ async fn siid_get_instance_state( async fn siid_nat(sagactx: NexusActionContext) -> Result<(), ActionError> { let params = sagactx.saga_params::()?; - let sled_id = sagactx.lookup::>("instance_state")?; + let sled_id = sagactx.lookup::>("instance_state")?; let target_ip = sagactx.lookup::("target_ip")?; instance_ip_remove_nat( &sagactx, @@ -184,7 +184,7 @@ async fn siid_nat_undo( ) -> Result<(), anyhow::Error> { let log = sagactx.user_data().log(); let params = sagactx.saga_params::()?; - let sled_id = sagactx.lookup::>("instance_state")?; + let sled_id = sagactx.lookup::>("instance_state")?; let target_ip = sagactx.lookup::("target_ip")?; if let Err(e) = instance_ip_add_nat( &sagactx, @@ -205,7 +205,7 @@ async fn siid_update_opte( sagactx: NexusActionContext, ) -> Result<(), ActionError> { let params = sagactx.saga_params::()?; - let sled_id = sagactx.lookup::>("instance_state")?; + let sled_id = sagactx.lookup::>("instance_state")?; let target_ip = sagactx.lookup::("target_ip")?; instance_ip_remove_opte( &sagactx, @@ -221,7 +221,7 @@ async fn siid_update_opte_undo( ) -> Result<(), anyhow::Error> { let log = sagactx.user_data().log(); let params = sagactx.saga_params::()?; - let sled_id = sagactx.lookup::>("instance_state")?; + let sled_id = sagactx.lookup::>("instance_state")?; let target_ip = sagactx.lookup::("target_ip")?; if let Err(e) = instance_ip_add_opte( &sagactx, @@ -390,10 +390,11 @@ pub(crate) mod test { let _ = ip_manip_test_setup(&client).await; let instance = create_instance(client, PROJECT_NAME, INSTANCE_NAME).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.id()); crate::app::sagas::test_helpers::instance_simulate( cptestctx, - &instance.identity.id, + &instance_id, ) .await; @@ -407,11 +408,9 @@ pub(crate) mod test { nexus.run_saga(saga).await.expect("Detach saga should succeed"); } - let instance_id = instance.id(); - // Sled agent has removed its records of the external IPs. let mut eips = sled_agent.external_ips.lock().await; - let my_eips = eips.entry(instance_id).or_default(); + let my_eips = eips.entry(instance_id.into_untyped_uuid()).or_default(); assert!(my_eips.is_empty()); // DB only has record for SNAT. @@ -460,7 +459,10 @@ pub(crate) mod test { // Instance still has one Ephemeral IP, and one Floating IP. let db_eips = datastore - .instance_lookup_external_ips(&opctx, instance_id) + .instance_lookup_external_ips( + &opctx, + InstanceUuid::from_untyped_uuid(instance_id), + ) .await .unwrap(); assert_eq!(db_eips.len(), 3); @@ -492,7 +494,7 @@ pub(crate) mod test { crate::app::sagas::test_helpers::instance_simulate( cptestctx, - &instance.identity.id, + &InstanceUuid::from_untyped_uuid(instance.identity.id), ) .await; @@ -526,7 +528,7 @@ pub(crate) mod test { crate::app::sagas::test_helpers::instance_simulate( cptestctx, - &instance.identity.id, + &InstanceUuid::from_untyped_uuid(instance.identity.id), ) .await; @@ -563,7 +565,7 @@ pub(crate) mod test { crate::app::sagas::test_helpers::instance_simulate( cptestctx, - &instance.identity.id, + &InstanceUuid::from_untyped_uuid(instance.identity.id), ) .await; diff --git a/nexus/src/app/sagas/instance_migrate.rs b/nexus/src/app/sagas/instance_migrate.rs index cbcad41a4f..3546642bbb 100644 --- a/nexus/src/app/sagas/instance_migrate.rs +++ b/nexus/src/app/sagas/instance_migrate.rs @@ -13,6 +13,7 @@ use crate::app::sagas::{ use crate::external_api::params; use nexus_db_queries::db::{identity::Resource, lookup::LookupPath}; use nexus_db_queries::{authn, authz, db}; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid, SledUuid}; use serde::Deserialize; use serde::Serialize; use sled_agent_client::types::{ @@ -41,6 +42,10 @@ pub struct Params { declare_saga_actions! { instance_migrate; + GENERATE_PROPOLIS_ID -> "dst_propolis_id" { + + sim_generate_propolis_id + } + // In order to set up migration, the saga needs to construct the following: // // - A migration ID and destination Propolis ID (added to the DAG inline as @@ -125,12 +130,7 @@ impl NexusSaga for SagaInstanceMigrate { ACTION_GENERATE_ID.as_ref(), )); - builder.append(Node::action( - "dst_propolis_id", - "GeneratePropolisId", - ACTION_GENERATE_ID.as_ref(), - )); - + builder.append(generate_propolis_id_action()); builder.append(reserve_resources_action()); builder.append(allocate_propolis_ip_action()); builder.append(create_vmm_record_action()); @@ -143,13 +143,19 @@ impl NexusSaga for SagaInstanceMigrate { } } +async fn sim_generate_propolis_id( + _sagactx: NexusActionContext, +) -> Result { + Ok(PropolisUuid::new_v4()) +} + /// Reserves resources for the destination on the specified target sled. async fn sim_reserve_sled_resources( sagactx: NexusActionContext, -) -> Result { +) -> Result { let osagactx = sagactx.user_data(); let params = sagactx.saga_params::()?; - let propolis_id = sagactx.lookup::("dst_propolis_id")?; + let propolis_id = sagactx.lookup::("dst_propolis_id")?; // Add a constraint that requires the allocator to reserve on the // migration's destination sled instead of a random sled. @@ -166,16 +172,19 @@ async fn sim_reserve_sled_resources( ) .await?; - Ok(resource.sled_id) + Ok(SledUuid::from_untyped_uuid(resource.sled_id)) } async fn sim_release_sled_resources( sagactx: NexusActionContext, ) -> Result<(), anyhow::Error> { let osagactx = sagactx.user_data(); - let propolis_id = sagactx.lookup::("dst_propolis_id")?; + let propolis_id = sagactx.lookup::("dst_propolis_id")?; - osagactx.nexus().delete_sled_reservation(propolis_id).await?; + osagactx + .nexus() + .delete_sled_reservation(propolis_id.into_untyped_uuid()) + .await?; Ok(()) } @@ -191,7 +200,7 @@ async fn sim_allocate_propolis_ip( allocate_vmm_ipv6( &opctx, sagactx.user_data().datastore(), - params.migrate_params.dst_sled_id, + SledUuid::from_untyped_uuid(params.migrate_params.dst_sled_id), ) .await } @@ -258,8 +267,8 @@ async fn sim_create_vmm_record( ); let instance_id = params.instance.id(); - let propolis_id = sagactx.lookup::("dst_propolis_id")?; - let sled_id = sagactx.lookup::("dst_sled_id")?; + let propolis_id = sagactx.lookup::("dst_propolis_id")?; + let sled_id = sagactx.lookup::("dst_sled_id")?; let propolis_ip = sagactx.lookup::("dst_propolis_ip")?; info!(osagactx.log(), "creating vmm record for migration destination"; @@ -270,7 +279,7 @@ async fn sim_create_vmm_record( super::instance_common::create_and_insert_vmm_record( osagactx.datastore(), &opctx, - instance_id, + InstanceUuid::from_untyped_uuid(instance_id), propolis_id, sled_id, propolis_ip, @@ -312,9 +321,10 @@ async fn sim_set_migration_ids( ); let db_instance = ¶ms.instance; - let src_sled_id = params.src_vmm.sled_id; + let instance_id = InstanceUuid::from_untyped_uuid(db_instance.id()); + let src_sled_id = SledUuid::from_untyped_uuid(params.src_vmm.sled_id); let migration_id = sagactx.lookup::("migrate_id")?; - let dst_propolis_id = sagactx.lookup::("dst_propolis_id")?; + let dst_propolis_id = sagactx.lookup::("dst_propolis_id")?; info!(osagactx.log(), "setting migration IDs on migration source sled"; "instance_id" => %db_instance.id(), @@ -327,7 +337,7 @@ async fn sim_set_migration_ids( .nexus() .instance_set_migration_ids( &opctx, - db_instance.id(), + instance_id, src_sled_id, db_instance.runtime(), InstanceMigrationSourceParams { dst_propolis_id, migration_id }, @@ -343,9 +353,10 @@ async fn sim_clear_migration_ids( ) -> Result<(), anyhow::Error> { let osagactx = sagactx.user_data(); let params = sagactx.saga_params::()?; - let src_sled_id = params.src_vmm.sled_id; + let src_sled_id = SledUuid::from_untyped_uuid(params.src_vmm.sled_id); let db_instance = sagactx.lookup::("set_migration_ids")?; + let instance_id = InstanceUuid::from_untyped_uuid(db_instance.id()); info!(osagactx.log(), "clearing migration IDs for saga unwind"; "instance_id" => %db_instance.id(), @@ -367,7 +378,7 @@ async fn sim_clear_migration_ids( if let Err(e) = osagactx .nexus() .instance_clear_migration_ids( - db_instance.id(), + instance_id, src_sled_id, db_instance.runtime(), ) @@ -375,7 +386,7 @@ async fn sim_clear_migration_ids( { warn!(osagactx.log(), "Error clearing migration IDs during rollback"; - "instance_id" => %db_instance.id(), + "instance_id" => %instance_id, "error" => ?e); } @@ -407,17 +418,19 @@ async fn sim_ensure_destination_propolis( .await .map_err(ActionError::action_failed)?; + let src_propolis_id = PropolisUuid::from_untyped_uuid(params.src_vmm.id); + let dst_propolis_id = PropolisUuid::from_untyped_uuid(vmm.id); osagactx .nexus() .instance_ensure_registered( &opctx, &authz_instance, &db_instance, - &vmm.id, + &dst_propolis_id, &vmm, InstanceRegisterReason::Migrate { - vmm_id: params.src_vmm.id, - target_vmm_id: vmm.id, + vmm_id: src_propolis_id, + target_vmm_id: dst_propolis_id, }, ) .await @@ -436,7 +449,7 @@ async fn sim_ensure_destination_propolis_undo( ¶ms.serialized_authn, ); - let dst_sled_id = sagactx.lookup::("dst_sled_id")?; + let dst_sled_id = sagactx.lookup::("dst_sled_id")?; let db_instance = sagactx.lookup::("set_migration_ids")?; let (.., authz_instance) = LookupPath::new(&opctx, &osagactx.datastore()) @@ -592,10 +605,10 @@ mod tests { async fn add_sleds( cptestctx: &ControlPlaneTestContext, num_sleds: usize, - ) -> Vec<(Uuid, Server)> { + ) -> Vec<(SledUuid, Server)> { let mut sas = Vec::with_capacity(num_sleds); for _ in 0..num_sleds { - let sa_id = Uuid::new_v4(); + let sa_id = SledUuid::new_v4(); let log = cptestctx.logctx.log.new(o!("sled_id" => sa_id.to_string())); let addr = @@ -647,10 +660,10 @@ mod tests { fn select_first_alternate_sled( db_vmm: &db::model::Vmm, - other_sleds: &[(Uuid, Server)], - ) -> Uuid { - let default_sled_uuid = - Uuid::parse_str(nexus_test_utils::SLED_AGENT_UUID).unwrap(); + other_sleds: &[(SledUuid, Server)], + ) -> SledUuid { + let default_sled_uuid: SledUuid = + nexus_test_utils::SLED_AGENT_UUID.parse().unwrap(); if other_sleds.is_empty() { panic!("need at least one other sled"); } @@ -659,7 +672,7 @@ mod tests { panic!("default test sled agent was in other_sleds"); } - if db_vmm.sled_id == default_sled_uuid { + if db_vmm.sled_id == default_sled_uuid.into_untyped_uuid() { other_sleds[0].0 } else { default_sled_uuid @@ -677,19 +690,21 @@ mod tests { let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // Poke the instance to get it into the Running state. - test_helpers::instance_simulate(cptestctx, &instance.identity.id).await; + test_helpers::instance_simulate(cptestctx, &instance_id).await; - let state = - test_helpers::instance_fetch(cptestctx, instance.identity.id).await; + let state = test_helpers::instance_fetch(cptestctx, instance_id).await; let vmm = state.vmm().as_ref().unwrap(); let dst_sled_id = select_first_alternate_sled(vmm, &other_sleds); let params = Params { serialized_authn: authn::saga::Serialized::for_opctx(&opctx), instance: state.instance().clone(), src_vmm: vmm.clone(), - migrate_params: params::InstanceMigrate { dst_sled_id }, + migrate_params: params::InstanceMigrate { + dst_sled_id: dst_sled_id.into_untyped_uuid(), + }, }; let dag = create_saga_dag::(params).unwrap(); @@ -700,8 +715,7 @@ mod tests { // steps in the simulated agents) should not change where the instance // is running. let new_state = - test_helpers::instance_fetch(cptestctx, state.instance().id()) - .await; + test_helpers::instance_fetch(cptestctx, instance_id).await; assert_eq!( new_state.instance().runtime().propolis_id, @@ -721,18 +735,17 @@ mod tests { let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // Poke the instance to get it into the Running state. - test_helpers::instance_simulate(cptestctx, &instance.identity.id).await; + test_helpers::instance_simulate(cptestctx, &instance_id).await; let make_params = || -> futures::future::BoxFuture<'_, Params> { Box::pin({ async { - let old_state = test_helpers::instance_fetch( - cptestctx, - instance.identity.id, - ) - .await; + let old_state = + test_helpers::instance_fetch(cptestctx, instance_id) + .await; let old_instance = old_state.instance(); let old_vmm = old_state @@ -754,7 +767,9 @@ mod tests { ), instance: old_instance.clone(), src_vmm: old_vmm.clone(), - migrate_params: params::InstanceMigrate { dst_sled_id }, + migrate_params: params::InstanceMigrate { + dst_sled_id: dst_sled_id.into_untyped_uuid(), + }, } } }) @@ -766,11 +781,9 @@ mod tests { // Unwinding at any step should clear the migration IDs from // the instance record and leave the instance's location // otherwise untouched. - let new_state = test_helpers::instance_fetch( - cptestctx, - instance.identity.id, - ) - .await; + let new_state = + test_helpers::instance_fetch(cptestctx, instance_id) + .await; let new_instance = new_state.instance(); let new_vmm = @@ -793,22 +806,13 @@ mod tests { // destroying the migration destination (if one was ensured) // doesn't advance the Propolis ID generation in a way that // prevents the source from issuing further state updates. - test_helpers::instance_stop( - cptestctx, - &instance.identity.id, - ) - .await; - test_helpers::instance_simulate( - cptestctx, - &instance.identity.id, - ) - .await; - - let new_state = test_helpers::instance_fetch( - cptestctx, - instance.identity.id, - ) - .await; + test_helpers::instance_stop(cptestctx, &instance_id).await; + test_helpers::instance_simulate(cptestctx, &instance_id) + .await; + + let new_state = + test_helpers::instance_fetch(cptestctx, instance_id) + .await; let new_instance = new_state.instance(); let new_vmm = new_state.vmm().as_ref(); @@ -825,16 +829,9 @@ mod tests { "migration saga unwind: restarting instance after \ failed saga" ); - test_helpers::instance_start( - cptestctx, - &instance.identity.id, - ) - .await; - test_helpers::instance_simulate( - cptestctx, - &instance.identity.id, - ) - .await; + test_helpers::instance_start(cptestctx, &instance_id).await; + test_helpers::instance_simulate(cptestctx, &instance_id) + .await; } }) }; diff --git a/nexus/src/app/sagas/instance_start.rs b/nexus/src/app/sagas/instance_start.rs index 0013a63d1a..9730025099 100644 --- a/nexus/src/app/sagas/instance_start.rs +++ b/nexus/src/app/sagas/instance_start.rs @@ -8,7 +8,7 @@ use std::net::Ipv6Addr; use super::{ instance_common::allocate_vmm_ipv6, NexusActionContext, NexusSaga, - SagaInitError, ACTION_GENERATE_ID, + SagaInitError, }; use crate::app::instance::InstanceRegisterReason; use crate::app::instance::InstanceStateChangeError; @@ -17,10 +17,10 @@ use chrono::Utc; use nexus_db_queries::db::{identity::Resource, lookup::LookupPath}; use nexus_db_queries::{authn, authz, db}; use omicron_common::api::external::Error; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid, SledUuid}; use serde::{Deserialize, Serialize}; use slog::info; -use steno::{ActionError, Node}; -use uuid::Uuid; +use steno::ActionError; /// Parameters to the instance start saga. #[derive(Debug, Deserialize, Serialize)] @@ -35,6 +35,10 @@ pub(crate) struct Params { declare_saga_actions! { instance_start; + GENERATE_PROPOLIS_ID -> "propolis_id" { + + sis_generate_propolis_id + } + ALLOC_SERVER -> "sled_id" { + sis_alloc_server - sis_alloc_server_undo @@ -101,12 +105,7 @@ impl NexusSaga for SagaInstanceStart { _params: &Self::Params, mut builder: steno::DagBuilder, ) -> Result { - builder.append(Node::action( - "propolis_id", - "GeneratePropolisId", - ACTION_GENERATE_ID.as_ref(), - )); - + builder.append(generate_propolis_id_action()); builder.append(alloc_server_action()); builder.append(alloc_propolis_ip_action()); builder.append(create_vmm_record_action()); @@ -120,14 +119,20 @@ impl NexusSaga for SagaInstanceStart { } } +async fn sis_generate_propolis_id( + _sagactx: NexusActionContext, +) -> Result { + Ok(PropolisUuid::new_v4()) +} + async fn sis_alloc_server( sagactx: NexusActionContext, -) -> Result { +) -> Result { let osagactx = sagactx.user_data(); let params = sagactx.saga_params::()?; let hardware_threads = params.db_instance.ncpus.0; let reservoir_ram = params.db_instance.memory; - let propolis_id = sagactx.lookup::("propolis_id")?; + let propolis_id = sagactx.lookup::("propolis_id")?; let resource = super::instance_common::reserve_vmm_resources( osagactx.nexus(), @@ -138,16 +143,19 @@ async fn sis_alloc_server( ) .await?; - Ok(resource.sled_id) + Ok(SledUuid::from_untyped_uuid(resource.sled_id)) } async fn sis_alloc_server_undo( sagactx: NexusActionContext, ) -> Result<(), anyhow::Error> { let osagactx = sagactx.user_data(); - let propolis_id = sagactx.lookup::("propolis_id")?; + let propolis_id = sagactx.lookup::("propolis_id")?; - osagactx.nexus().delete_sled_reservation(propolis_id).await?; + osagactx + .nexus() + .delete_sled_reservation(propolis_id.into_untyped_uuid()) + .await?; Ok(()) } @@ -159,7 +167,7 @@ async fn sis_alloc_propolis_ip( &sagactx, ¶ms.serialized_authn, ); - let sled_uuid = sagactx.lookup::("sled_id")?; + let sled_uuid = sagactx.lookup::("sled_id")?; allocate_vmm_ipv6(&opctx, sagactx.user_data().datastore(), sled_uuid).await } @@ -172,9 +180,9 @@ async fn sis_create_vmm_record( &sagactx, ¶ms.serialized_authn, ); - let instance_id = params.db_instance.id(); - let propolis_id = sagactx.lookup::("propolis_id")?; - let sled_id = sagactx.lookup::("sled_id")?; + let instance_id = InstanceUuid::from_untyped_uuid(params.db_instance.id()); + let propolis_id = sagactx.lookup::("propolis_id")?; + let sled_id = sagactx.lookup::("sled_id")?; let propolis_ip = sagactx.lookup::("propolis_ip")?; super::instance_common::create_and_insert_vmm_record( @@ -214,8 +222,8 @@ async fn sis_move_to_starting( let params = sagactx.saga_params::()?; let osagactx = sagactx.user_data(); let datastore = osagactx.datastore(); - let instance_id = params.db_instance.id(); - let propolis_id = sagactx.lookup::("propolis_id")?; + let instance_id = InstanceUuid::from_untyped_uuid(params.db_instance.id()); + let propolis_id = sagactx.lookup::("propolis_id")?; info!(osagactx.log(), "moving instance to Starting state via saga"; "instance_id" => %instance_id, "propolis_id" => %propolis_id); @@ -228,7 +236,7 @@ async fn sis_move_to_starting( // For idempotency, refetch the instance to see if this step already applied // its desired update. let (.., db_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .fetch_for(authz::Action::Modify) .await .map_err(ActionError::action_failed)?; @@ -237,7 +245,7 @@ async fn sis_move_to_starting( // If this saga's Propolis ID is already written to the record, then // this step must have completed already and is being retried, so // proceed. - Some(db_id) if db_id == propolis_id => { + Some(db_id) if db_id == propolis_id.into_untyped_uuid() => { info!(osagactx.log(), "start saga: Propolis ID already set"; "instance_id" => %instance_id); @@ -261,7 +269,7 @@ async fn sis_move_to_starting( None => { let new_runtime = db::model::InstanceRuntimeState { nexus_state: db::model::InstanceState::Vmm, - propolis_id: Some(propolis_id), + propolis_id: Some(propolis_id.into_untyped_uuid()), time_updated: Utc::now(), gen: db_instance.runtime().gen.next().into(), ..db_instance.runtime_state @@ -293,7 +301,7 @@ async fn sis_move_to_starting_undo( let osagactx = sagactx.user_data(); let db_instance = sagactx.lookup::("started_record")?; - let instance_id = db_instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(db_instance.id()); info!(osagactx.log(), "start saga failed; returning instance to Stopped"; "instance_id" => %instance_id); @@ -322,7 +330,7 @@ async fn sis_account_virtual_resources( ) -> Result<(), ActionError> { let osagactx = sagactx.user_data(); let params = sagactx.saga_params::()?; - let instance_id = params.db_instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(params.db_instance.id()); let opctx = crate::context::op_context_for_saga_action( &sagactx, @@ -348,7 +356,7 @@ async fn sis_account_virtual_resources_undo( ) -> Result<(), anyhow::Error> { let osagactx = sagactx.user_data(); let params = sagactx.saga_params::()?; - let instance_id = params.db_instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(params.db_instance.id()); let opctx = crate::context::op_context_for_saga_action( &sagactx, @@ -384,7 +392,7 @@ async fn sis_dpd_ensure( let osagactx = sagactx.user_data(); let db_instance = sagactx.lookup::("started_record")?; - let instance_id = db_instance.id(); + let instance_id = InstanceUuid::from_untyped_uuid(db_instance.id()); info!(osagactx.log(), "start saga: ensuring instance dpd configuration"; "instance_id" => %instance_id); @@ -397,9 +405,9 @@ async fn sis_dpd_ensure( // Querying sleds requires fleet access; use the instance allocator context // for this. - let sled_uuid = sagactx.lookup::("sled_id")?; + let sled_uuid = sagactx.lookup::("sled_id")?; let (.., sled) = LookupPath::new(&osagactx.nexus().opctx_alloc, &datastore) - .sled_id(sled_uuid) + .sled_id(sled_uuid.into_untyped_uuid()) .fetch() .await .map_err(ActionError::action_failed)?; @@ -472,9 +480,9 @@ async fn sis_ensure_registered( let db_instance = sagactx.lookup::("started_record")?; let instance_id = db_instance.id(); - let sled_id = sagactx.lookup::("sled_id")?; + let sled_id = sagactx.lookup::("sled_id")?; let vmm_record = sagactx.lookup::("vmm_record")?; - let propolis_id = sagactx.lookup::("propolis_id")?; + let propolis_id = sagactx.lookup::("propolis_id")?; info!(osagactx.log(), "start saga: ensuring instance is registered on sled"; "instance_id" => %instance_id, @@ -508,8 +516,8 @@ async fn sis_ensure_registered_undo( let osagactx = sagactx.user_data(); let params = sagactx.saga_params::()?; let datastore = osagactx.datastore(); - let instance_id = params.db_instance.id(); - let sled_id = sagactx.lookup::("sled_id")?; + let instance_id = InstanceUuid::from_untyped_uuid(params.db_instance.id()); + let sled_id = sagactx.lookup::("sled_id")?; let opctx = crate::context::op_context_for_saga_action( &sagactx, ¶ms.serialized_authn, @@ -522,7 +530,7 @@ async fn sis_ensure_registered_undo( // Fetch the latest record so that this callee can drive the instance into // a Failed state if the unregister call fails. let (.., authz_instance, db_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .fetch() .await .map_err(ActionError::action_failed)?; @@ -624,14 +632,14 @@ async fn sis_ensure_running( let db_instance = sagactx.lookup::("started_record")?; let db_vmm = sagactx.lookup::("vmm_record")?; - let instance_id = params.db_instance.id(); - let sled_id = sagactx.lookup::("sled_id")?; + let instance_id = InstanceUuid::from_untyped_uuid(params.db_instance.id()); + let sled_id = sagactx.lookup::("sled_id")?; info!(osagactx.log(), "start saga: ensuring instance is running"; "instance_id" => %instance_id, "sled_id" => %sled_id); let (.., authz_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Modify) .await .map_err(ActionError::action_failed)?; @@ -737,11 +745,11 @@ mod test { let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; - let db_instance = - test_helpers::instance_fetch(cptestctx, instance.identity.id) - .await - .instance() - .clone(); + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + let db_instance = test_helpers::instance_fetch(cptestctx, instance_id) + .await + .instance() + .clone(); let params = Params { serialized_authn: authn::saga::Serialized::for_opctx(&opctx), @@ -752,15 +760,14 @@ mod test { let saga = nexus.create_runnable_saga(dag).await.unwrap(); nexus.run_saga(saga).await.expect("Start saga should succeed"); - test_helpers::instance_simulate(cptestctx, &instance.identity.id).await; - let vmm_state = - test_helpers::instance_fetch(cptestctx, instance.identity.id) - .await - .vmm() - .as_ref() - .expect("running instance should have a vmm") - .runtime - .state; + test_helpers::instance_simulate(cptestctx, &instance_id).await; + let vmm_state = test_helpers::instance_fetch(cptestctx, instance_id) + .await + .vmm() + .as_ref() + .expect("running instance should have a vmm") + .runtime + .state; assert_eq!(vmm_state, nexus_db_model::VmmState::Running); } @@ -775,6 +782,7 @@ mod test { let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); test_helpers::action_failure_can_unwind::< SagaInstanceStart, @@ -787,7 +795,7 @@ mod test { async { let db_instance = test_helpers::instance_fetch( cptestctx, - instance.identity.id, + instance_id, ) .await.instance().clone(); @@ -804,7 +812,7 @@ mod test { async { let new_db_instance = test_helpers::instance_fetch( cptestctx, - instance.identity.id, + instance_id, ) .await.instance().clone(); @@ -837,11 +845,11 @@ mod test { let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; - let db_instance = - test_helpers::instance_fetch(cptestctx, instance.identity.id) - .await - .instance() - .clone(); + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + let db_instance = test_helpers::instance_fetch(cptestctx, instance_id) + .await + .instance() + .clone(); let params = Params { serialized_authn: authn::saga::Serialized::for_opctx(&opctx), @@ -850,15 +858,14 @@ mod test { let dag = create_saga_dag::(params).unwrap(); test_helpers::actions_succeed_idempotently(nexus, dag).await; - test_helpers::instance_simulate(cptestctx, &instance.identity.id).await; - let vmm_state = - test_helpers::instance_fetch(cptestctx, instance.identity.id) - .await - .vmm() - .as_ref() - .expect("running instance should have a vmm") - .runtime - .state; + test_helpers::instance_simulate(cptestctx, &instance_id).await; + let vmm_state = test_helpers::instance_fetch(cptestctx, instance_id) + .await + .vmm() + .as_ref() + .expect("running instance should have a vmm") + .runtime + .state; assert_eq!(vmm_state, nexus_db_model::VmmState::Running); } @@ -878,11 +885,11 @@ mod test { let _project_id = setup_test_project(&client).await; let opctx = test_helpers::test_opctx(cptestctx); let instance = create_instance(client).await; - let db_instance = - test_helpers::instance_fetch(cptestctx, instance.identity.id) - .await - .instance() - .clone(); + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + let db_instance = test_helpers::instance_fetch(cptestctx, instance_id) + .await + .instance() + .clone(); let params = Params { serialized_authn: authn::saga::Serialized::for_opctx(&opctx), @@ -922,7 +929,7 @@ mod test { assert_eq!(saga_error.error_node_name, last_node_name); let db_instance = - test_helpers::instance_fetch(cptestctx, instance.identity.id).await; + test_helpers::instance_fetch(cptestctx, instance_id).await; assert_eq!( db_instance.instance().runtime_state.nexus_state, diff --git a/nexus/src/app/sagas/test_helpers.rs b/nexus/src/app/sagas/test_helpers.rs index bacd0f1c9d..684b84dd07 100644 --- a/nexus/src/app/sagas/test_helpers.rs +++ b/nexus/src/app/sagas/test_helpers.rs @@ -22,11 +22,11 @@ use nexus_db_queries::{ }; use nexus_types::identity::Resource; use omicron_common::api::external::NameOrId; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; use sled_agent_client::TestInterfaces as _; use slog::{info, warn, Logger}; use std::{num::NonZeroU32, sync::Arc}; use steno::SagaDag; -use uuid::Uuid; type ControlPlaneTestContext = nexus_test_utils::ControlPlaneTestContext; @@ -40,14 +40,14 @@ pub fn test_opctx(cptestctx: &ControlPlaneTestContext) -> OpContext { pub(crate) async fn instance_start( cptestctx: &ControlPlaneTestContext, - id: &Uuid, + id: &InstanceUuid, ) { let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let instance_selector = nexus_types::external_api::params::InstanceSelector { project: None, - instance: NameOrId::from(*id), + instance: NameOrId::from(id.into_untyped_uuid()), }; let instance_lookup = @@ -60,14 +60,14 @@ pub(crate) async fn instance_start( pub(crate) async fn instance_stop( cptestctx: &ControlPlaneTestContext, - id: &Uuid, + id: &InstanceUuid, ) { let nexus = &cptestctx.server.server_context().nexus; let opctx = test_opctx(&cptestctx); let instance_selector = nexus_types::external_api::params::InstanceSelector { project: None, - instance: NameOrId::from(*id), + instance: NameOrId::from(id.into_untyped_uuid()), }; let instance_lookup = @@ -122,7 +122,7 @@ pub(crate) async fn instance_delete_by_name( pub(crate) async fn instance_simulate( cptestctx: &ControlPlaneTestContext, - instance_id: &Uuid, + instance_id: &InstanceUuid, ) { info!(&cptestctx.logctx.log, "Poking simulated instance"; "instance_id" => %instance_id); @@ -133,7 +133,7 @@ pub(crate) async fn instance_simulate( .unwrap() .expect("instance must be on a sled to simulate a state change"); - sa.instance_finish_transition(*instance_id).await; + sa.instance_finish_transition(instance_id.into_untyped_uuid()).await; } pub(crate) async fn instance_simulate_by_name( @@ -157,7 +157,7 @@ pub(crate) async fn instance_simulate_by_name( nexus.instance_lookup(&opctx, instance_selector).unwrap(); let (.., instance) = instance_lookup.fetch().await.unwrap(); let sa = nexus - .instance_sled_by_id(&instance.id()) + .instance_sled_by_id(&InstanceUuid::from_untyped_uuid(instance.id())) .await .unwrap() .expect("instance must be on a sled to simulate a state change"); @@ -166,12 +166,12 @@ pub(crate) async fn instance_simulate_by_name( pub async fn instance_fetch( cptestctx: &ControlPlaneTestContext, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> InstanceAndActiveVmm { let datastore = cptestctx.server.server_context().nexus.datastore().clone(); let opctx = test_opctx(&cptestctx); let (.., authz_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(authz::Action::Read) .await .expect("test instance should be present in datastore"); diff --git a/nexus/src/app/sled.rs b/nexus/src/app/sled.rs index c7fc651823..fd5341ae80 100644 --- a/nexus/src/app/sled.rs +++ b/nexus/src/app/sled.rs @@ -20,6 +20,7 @@ use omicron_common::api::external::DataPageParams; use omicron_common::api::external::Error; use omicron_common::api::external::ListResultVec; use omicron_common::api::external::LookupResult; +use omicron_uuid_kinds::{GenericUuid, SledUuid}; use sled_agent_client::Client as SledAgentClient; use std::net::SocketAddrV6; use std::sync::Arc; @@ -123,7 +124,7 @@ impl super::Nexus { pub async fn sled_client( &self, - id: &Uuid, + id: &SledUuid, ) -> Result, Error> { // TODO: We should consider injecting connection pooling here, // but for now, connections to sled agents are constructed @@ -135,7 +136,7 @@ impl super::Nexus { let client = nexus_networking::sled_client( &self.db_datastore, &self.opctx_alloc, - *id, + id.into_untyped_uuid(), &self.log, ) .await?; diff --git a/nexus/src/app/test_interfaces.rs b/nexus/src/app/test_interfaces.rs index 9e7bd1582f..adfafa523d 100644 --- a/nexus/src/app/test_interfaces.rs +++ b/nexus/src/app/test_interfaces.rs @@ -6,6 +6,8 @@ use async_trait::async_trait; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::lookup::LookupPath; use omicron_common::api::external::Error; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::{InstanceUuid, SledUuid}; use sled_agent_client::Client as SledAgentClient; use std::sync::Arc; use uuid::Uuid; @@ -28,12 +30,12 @@ pub trait TestInterfaces { /// but after all it's a test suite special to begin with. async fn instance_sled_by_id( &self, - id: &Uuid, + id: &InstanceUuid, ) -> Result>, Error>; async fn instance_sled_by_id_with_opctx( &self, - id: &Uuid, + id: &InstanceUuid, opctx: &OpContext, ) -> Result>, Error>; @@ -47,14 +49,14 @@ pub trait TestInterfaces { /// Returns the supplied instance's current active sled ID. async fn instance_sled_id( &self, - instance_id: &Uuid, - ) -> Result, Error>; + instance_id: &InstanceUuid, + ) -> Result, Error>; async fn instance_sled_id_with_opctx( &self, - instance_id: &Uuid, + instance_id: &InstanceUuid, opctx: &OpContext, - ) -> Result, Error>; + ) -> Result, Error>; async fn set_disk_as_faulted(&self, disk_id: &Uuid) -> Result; @@ -69,7 +71,7 @@ impl TestInterfaces for super::Nexus { async fn instance_sled_by_id( &self, - id: &Uuid, + id: &InstanceUuid, ) -> Result>, Error> { let opctx = OpContext::for_tests( self.log.new(o!()), @@ -82,7 +84,7 @@ impl TestInterfaces for super::Nexus { async fn instance_sled_by_id_with_opctx( &self, - id: &Uuid, + id: &InstanceUuid, opctx: &OpContext, ) -> Result>, Error> { let sled_id = self.instance_sled_id_with_opctx(id, opctx).await?; @@ -107,11 +109,16 @@ impl TestInterfaces for super::Nexus { .fetch() .await?; - self.instance_sled_by_id(&db_disk.runtime().attach_instance_id.unwrap()) - .await + let instance_id = InstanceUuid::from_untyped_uuid( + db_disk.runtime().attach_instance_id.unwrap(), + ); + self.instance_sled_by_id(&instance_id).await } - async fn instance_sled_id(&self, id: &Uuid) -> Result, Error> { + async fn instance_sled_id( + &self, + id: &InstanceUuid, + ) -> Result, Error> { let opctx = OpContext::for_tests( self.log.new(o!()), Arc::clone(&self.db_datastore) @@ -123,11 +130,11 @@ impl TestInterfaces for super::Nexus { async fn instance_sled_id_with_opctx( &self, - id: &Uuid, + id: &InstanceUuid, opctx: &OpContext, - ) -> Result, Error> { + ) -> Result, Error> { let (.., authz_instance) = LookupPath::new(&opctx, &self.db_datastore) - .instance_id(*id) + .instance_id(id.into_untyped_uuid()) .lookup_for(nexus_db_queries::authz::Action::Read) .await?; diff --git a/nexus/src/internal_api/http_entrypoints.rs b/nexus/src/internal_api/http_entrypoints.rs index ceafe7f103..582f7cb608 100644 --- a/nexus/src/internal_api/http_entrypoints.rs +++ b/nexus/src/internal_api/http_entrypoints.rs @@ -51,6 +51,8 @@ use omicron_common::api::internal::nexus::RepairStartInfo; use omicron_common::api::internal::nexus::SledInstanceState; use omicron_common::update::ArtifactId; use omicron_uuid_kinds::DownstairsKind; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use omicron_uuid_kinds::SledUuid; use omicron_uuid_kinds::TypedUuid; use omicron_uuid_kinds::UpstairsKind; @@ -274,7 +276,11 @@ async fn cpapi_instances_put( let opctx = crate::context::op_context_for_internal_api(&rqctx).await; let handler = async { nexus - .notify_instance_updated(&opctx, &path.instance_id, &new_state) + .notify_instance_updated( + &opctx, + &InstanceUuid::from_untyped_uuid(path.instance_id), + &new_state, + ) .await?; Ok(HttpResponseUpdatedNoContent()) }; diff --git a/nexus/test-utils/src/lib.rs b/nexus/test-utils/src/lib.rs index de00290616..97fd66f949 100644 --- a/nexus/test-utils/src/lib.rs +++ b/nexus/test-utils/src/lib.rs @@ -880,13 +880,14 @@ impl<'a, N: NexusServer> ControlPlaneTestContextBuilder<'a, N> { self.nexus_internal_addr.expect("Must launch Nexus first"); // Set up a single sled agent. - let sa_id: Uuid = if switch_location == SwitchLocation::Switch0 { + let sa_id: SledUuid = if switch_location == SwitchLocation::Switch0 { SLED_AGENT_UUID } else { SLED_AGENT2_UUID } .parse() .unwrap(); + let tempdir = camino_tempfile::tempdir().unwrap(); let sled_agent = start_sled_agent( self.logctx.log.new(o!( @@ -1382,12 +1383,12 @@ async fn setup_with_config_impl( pub async fn start_sled_agent( log: Logger, nexus_address: SocketAddr, - id: Uuid, + id: SledUuid, update_directory: &Utf8Path, sim_mode: sim::SimMode, ) -> Result { let config = sim::Config::for_testing( - id, + id.into_untyped_uuid(), sim_mode, Some(nexus_address), Some(update_directory), diff --git a/nexus/tests/integration_tests/disks.rs b/nexus/tests/integration_tests/disks.rs index a707f8240d..4c707ba0fa 100644 --- a/nexus/tests/integration_tests/disks.rs +++ b/nexus/tests/integration_tests/disks.rs @@ -43,7 +43,7 @@ use omicron_common::api::external::NameOrId; use omicron_nexus::app::{MAX_DISK_SIZE_BYTES, MIN_DISK_SIZE_BYTES}; use omicron_nexus::Nexus; use omicron_nexus::TestInterfaces as _; -use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; use oximeter::types::Datum; use oximeter::types::Measurement; use sled_agent_client::TestInterfaces as _; @@ -180,13 +180,13 @@ async fn set_instance_state( .unwrap() } -async fn instance_simulate(nexus: &Arc, id: &Uuid) { +async fn instance_simulate(nexus: &Arc, id: &InstanceUuid) { let sa = nexus .instance_sled_by_id(id) .await .unwrap() .expect("instance must be on a sled to simulate a state change"); - sa.instance_finish_transition(*id).await; + sa.instance_finish_transition(id.into_untyped_uuid()).await; } #[nexus_test] @@ -238,7 +238,11 @@ async fn test_disk_create_attach_detach_delete( // is an artificial limitation without hotplug support. let instance_next = set_instance_state(&client, INSTANCE_NAME, "stop").await; - instance_simulate(nexus, &instance_next.identity.id).await; + instance_simulate( + nexus, + &InstanceUuid::from_untyped_uuid(instance_next.identity.id), + ) + .await; // Verify that there are no disks attached to the instance, and specifically // that our disk is not attached to this instance. @@ -383,10 +387,9 @@ async fn test_disk_slot_assignment(cptestctx: &ControlPlaneTestContext) { // to allow disks to be attached. There should be no disks attached // initially. let instance = create_instance(&client, PROJECT_NAME, INSTANCE_NAME).await; - let instance_id = &instance.identity.id; - let instance_next = - set_instance_state(&client, INSTANCE_NAME, "stop").await; - instance_simulate(nexus, &instance_next.identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + set_instance_state(&client, INSTANCE_NAME, "stop").await; + instance_simulate(nexus, &instance_id).await; let url_instance_disks = get_instance_disks_url(instance.identity.name.as_str()); let listed_disks = disks_list(&client, &url_instance_disks).await; @@ -422,7 +425,10 @@ async fn test_disk_slot_assignment(cptestctx: &ControlPlaneTestContext) { assert_eq!(attached_disk.identity.name, disk.identity.name); assert_eq!(attached_disk.identity.id, disk.identity.id); - assert_eq!(attached_disk.state, DiskState::Attached(*instance_id)); + assert_eq!( + attached_disk.state, + DiskState::Attached(instance_id.into_untyped_uuid()) + ); assert_eq!( get_disk_slot(cptestctx, attached_disk.identity.id).await, @@ -485,13 +491,14 @@ async fn test_disk_move_between_instances(cptestctx: &ControlPlaneTestContext) { // Create an instance to attach the disk. let instance = create_instance(&client, PROJECT_NAME, INSTANCE_NAME).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + // TODO(https://github.com/oxidecomputer/omicron/issues/811): // // Instances must be stopped before disks can be attached - this // is an artificial limitation without hotplug support. - let instance_next = - set_instance_state(&client, INSTANCE_NAME, "stop").await; - instance_simulate(nexus, &instance_next.identity.id).await; + set_instance_state(&client, INSTANCE_NAME, "stop").await; + instance_simulate(nexus, &instance_id).await; // Verify that there are no disks attached to the instance, and specifically // that our disk is not attached to this instance. @@ -526,8 +533,9 @@ async fn test_disk_move_between_instances(cptestctx: &ControlPlaneTestContext) { // Create a second instance and try to attach the disk to that. This should // fail and the disk should remain attached to the first instance. let instance2 = create_instance(&client, PROJECT_NAME, "instance2").await; - let instance_next = set_instance_state(&client, "instance2", "stop").await; - instance_simulate(nexus, &instance_next.identity.id).await; + let instance2_id = InstanceUuid::from_untyped_uuid(instance2.identity.id); + set_instance_state(&client, "instance2", "stop").await; + instance_simulate(nexus, &instance2_id).await; let url_instance2_attach_disk = get_disk_attach_url(&instance2.identity.id.into()); @@ -556,7 +564,10 @@ async fn test_disk_move_between_instances(cptestctx: &ControlPlaneTestContext) { ); let attached_disk = disk_get(&client, &disk_url).await; - assert_eq!(attached_disk.state, DiskState::Attached(*instance_id)); + assert_eq!( + attached_disk.state, + DiskState::Attached(instance_id.into_untyped_uuid()) + ); // Begin detaching the disk. let disk = @@ -583,10 +594,12 @@ async fn test_disk_move_between_instances(cptestctx: &ControlPlaneTestContext) { disk.identity.name.clone(), ) .await; - let instance2_id = &instance2.identity.id; assert_eq!(attached_disk.identity.name, disk.identity.name); assert_eq!(attached_disk.identity.id, disk.identity.id); - assert_eq!(attached_disk.state, DiskState::Attached(*instance2_id)); + assert_eq!( + attached_disk.state, + DiskState::Attached(instance2_id.into_untyped_uuid()) + ); // At this point, it's not legal to attempt to attach it to a different // instance (the first one). @@ -618,7 +631,10 @@ async fn test_disk_move_between_instances(cptestctx: &ControlPlaneTestContext) { disk.identity.name.clone(), ) .await; - assert_eq!(disk.state, DiskState::Attached(*instance2_id)); + assert_eq!( + disk.state, + DiskState::Attached(instance2_id.into_untyped_uuid()) + ); // It's not allowed to delete a disk that's attached. let error = NexusRequest::expect_failure( diff --git a/nexus/tests/integration_tests/external_ips.rs b/nexus/tests/integration_tests/external_ips.rs index 396edddc41..2789318855 100644 --- a/nexus/tests/integration_tests/external_ips.rs +++ b/nexus/tests/integration_tests/external_ips.rs @@ -49,6 +49,8 @@ use omicron_common::api::external::Instance; use omicron_common::api::external::InstanceCpuCount; use omicron_common::api::external::Name; use omicron_common::api::external::NameOrId; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use uuid::Uuid; type ControlPlaneTestContext = @@ -653,6 +655,7 @@ async fn test_floating_ip_create_attachment( &FIP_NAMES[..1], ) .await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // Reacquire FIP: parent ID must have updated to match instance. let fetched_fip = @@ -673,8 +676,8 @@ async fn test_floating_ip_create_attachment( ); // Stop and delete the instance. - instance_simulate(nexus, &instance.identity.id).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; + instance_simulate(nexus, &instance_id).await; let _: Instance = NexusRequest::new( RequestBuilder::new( @@ -692,7 +695,7 @@ async fn test_floating_ip_create_attachment( .parsed_body() .unwrap(); - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; NexusRequest::object_delete( &client, @@ -762,10 +765,11 @@ async fn test_external_ip_live_attach_detach( &[], ) .await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); if *start { - instance_simulate(nexus, &instance.identity.id).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; + instance_simulate(nexus, &instance_id).await; } // Verify that each instance has no external IPs. @@ -1035,9 +1039,10 @@ async fn test_external_ip_attach_fail_if_in_use_by_other( &[FIP_NAMES[i]], ) .await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); - instance_simulate(nexus, &instance.identity.id).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; + instance_simulate(nexus, &instance_id).await; instances.push(instance); fips.push(fip); diff --git a/nexus/tests/integration_tests/instances.rs b/nexus/tests/integration_tests/instances.rs index 948f8a18f3..4f7a1d1b77 100644 --- a/nexus/tests/integration_tests/instances.rs +++ b/nexus/tests/integration_tests/instances.rs @@ -66,6 +66,9 @@ use omicron_nexus::Nexus; use omicron_nexus::TestInterfaces as _; use omicron_sled_agent::sim::SledAgent; use omicron_test_utils::dev::poll::wait_for_condition; +use omicron_uuid_kinds::PropolisUuid; +use omicron_uuid_kinds::SledUuid; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; use sled_agent_client::TestInterfaces as _; use std::convert::TryFrom; use std::net::Ipv4Addr; @@ -363,7 +366,8 @@ async fn test_instances_create_reboot_halt( ); // Now, simulate completion of instance boot and check the state reported. - instance_simulate(nexus, &instance.identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; identity_eq(&instance.identity, &instance_next.identity); assert_eq!(instance_next.runtime.run_state, InstanceState::Running); @@ -392,7 +396,7 @@ async fn test_instances_create_reboot_halt( ); let instance = instance_next; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; assert_eq!(instance_next.runtime.run_state, InstanceState::Running); assert!( @@ -411,7 +415,7 @@ async fn test_instances_create_reboot_halt( ); let instance = instance_next; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; assert_eq!(instance_next.runtime.run_state, InstanceState::Stopped); assert!( @@ -472,7 +476,7 @@ async fn test_instances_create_reboot_halt( ); let instance = instance_next; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; assert_eq!(instance_next.runtime.run_state, InstanceState::Running); assert!( @@ -506,7 +510,7 @@ async fn test_instances_create_reboot_halt( .unwrap(); // assert_eq!(error.message, "cannot reboot instance in state \"stopping\""); let instance = instance_next; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; assert_eq!(instance_next.runtime.run_state, InstanceState::Stopped); assert!( @@ -593,7 +597,7 @@ async fn test_instance_start_creates_networking_state( let nsleds = 3; let mut additional_sleds = Vec::with_capacity(nsleds); for _ in 0..nsleds { - let sa_id = Uuid::new_v4(); + let sa_id = SledUuid::new_v4(); let log = cptestctx.logctx.log.new(o!( "sled_id" => sa_id.to_string() )); let addr = cptestctx.server.get_http_server_internal_address().await; @@ -614,12 +618,12 @@ async fn test_instance_start_creates_networking_state( create_project_and_pool(&client).await; let instance_url = get_instance_url(instance_name); let instance = create_instance(client, PROJECT_NAME, instance_name).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // Drive the instance to Running, then stop it. - instance_simulate(nexus, &instance.identity.id).await; - let instance = - instance_post(&client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; + instance_post(&client, instance_name, InstanceOp::Stop).await; + instance_simulate(nexus, &instance_id).await; let instance = instance_get(&client, &instance_url).await; assert_eq!(instance.runtime.run_state, InstanceState::Stopped); @@ -634,9 +638,8 @@ async fn test_instance_start_creates_networking_state( } // Start the instance and make sure that it gets to Running. - let instance = - instance_post(&client, instance_name, InstanceOp::Start).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(&client, instance_name, InstanceOp::Start).await; + instance_simulate(nexus, &instance_id).await; let instance = instance_get(&client, &instance_url).await; assert_eq!(instance.runtime.run_state, InstanceState::Running); @@ -709,10 +712,10 @@ async fn test_instance_migrate(cptestctx: &ControlPlaneTestContext) { let instance_name = "bird-ecology"; // Create a second sled to migrate to/from. - let default_sled_id: Uuid = + let default_sled_id: SledUuid = nexus_test_utils::SLED_AGENT_UUID.parse().unwrap(); let update_dir = Utf8Path::new("/should/be/unused"); - let other_sled_id = Uuid::new_v4(); + let other_sled_id = SledUuid::new_v4(); let _other_sa = nexus_test_utils::start_sled_agent( cptestctx.logctx.log.new(o!("sled_id" => other_sled_id.to_string())), cptestctx.server.get_http_server_internal_address().await, @@ -738,7 +741,7 @@ async fn test_instance_migrate(cptestctx: &ControlPlaneTestContext) { true, ) .await; - let instance_id = instance.identity.id; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // Poke the instance into an active state. instance_simulate(nexus, &instance_id).await; @@ -761,7 +764,9 @@ async fn test_instance_migrate(cptestctx: &ControlPlaneTestContext) { format!("/v1/instances/{}/migrate", &instance_id.to_string()); let instance = NexusRequest::new( RequestBuilder::new(client, Method::POST, &migrate_url) - .body(Some(¶ms::InstanceMigrate { dst_sled_id })) + .body(Some(¶ms::InstanceMigrate { + dst_sled_id: dst_sled_id.into_untyped_uuid(), + })) .expect_status(Some(StatusCode::OK)), ) .authn_as(AuthnMode::PrivilegedUser) @@ -844,7 +849,7 @@ async fn test_instance_migrate_v2p(cptestctx: &ControlPlaneTestContext) { let nsleds = 3; let mut other_sleds = Vec::with_capacity(nsleds); for _ in 0..nsleds { - let sa_id = Uuid::new_v4(); + let sa_id = SledUuid::new_v4(); let log = cptestctx.logctx.log.new(o!("sled_id" => sa_id.to_string())); let update_dir = Utf8Path::new("/should/be/unused"); let sa = nexus_test_utils::start_sled_agent( @@ -875,7 +880,7 @@ async fn test_instance_migrate_v2p(cptestctx: &ControlPlaneTestContext) { true, ) .await; - let instance_id = instance.identity.id; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // The default configuration gives one NIC. let nics_url = format!("/v1/network-interfaces?instance={}", instance_id); @@ -893,7 +898,7 @@ async fn test_instance_migrate_v2p(cptestctx: &ControlPlaneTestContext) { // Ensure that all of the V2P information is correct. let (.., authz_instance) = LookupPath::new(&opctx, &datastore) - .instance_id(instance_id) + .instance_id(instance_id.into_untyped_uuid()) .lookup_for(nexus_db_queries::authz::Action::Read) .await .unwrap(); @@ -913,11 +918,12 @@ async fn test_instance_migrate_v2p(cptestctx: &ControlPlaneTestContext) { assert_sled_v2p_mappings(sled_agent, &nics[0], guest_nics[0].vni).await; } - let dst_sled_id = if original_sled_id == cptestctx.sled_agent.sled_agent.id - { + let testctx_sled_id = + SledUuid::from_untyped_uuid(cptestctx.sled_agent.sled_agent.id); + let dst_sled_id = if original_sled_id == testctx_sled_id { other_sleds[0].0 } else { - cptestctx.sled_agent.sled_agent.id + testctx_sled_id }; // Kick off migration and simulate its completion on the target. @@ -925,7 +931,9 @@ async fn test_instance_migrate_v2p(cptestctx: &ControlPlaneTestContext) { format!("/v1/instances/{}/migrate", &instance_id.to_string()); let _ = NexusRequest::new( RequestBuilder::new(client, Method::POST, &migrate_url) - .body(Some(¶ms::InstanceMigrate { dst_sled_id })) + .body(Some(¶ms::InstanceMigrate { + dst_sled_id: dst_sled_id.into_untyped_uuid(), + })) .expect_status(Some(StatusCode::OK)), ) .authn_as(AuthnMode::PrivilegedUser) @@ -954,7 +962,7 @@ async fn test_instance_migrate_v2p(cptestctx: &ControlPlaneTestContext) { // updated here because Nexus presumes that the instance's new sled // agent will have updated any mappings there. Remove this bifurcation // when Nexus programs all mappings explicitly. - if sled_agent.id != dst_sled_id { + if sled_agent.id != dst_sled_id.into_untyped_uuid() { assert_sled_v2p_mappings(sled_agent, &nics[0], guest_nics[0].vni) .await; } @@ -976,7 +984,8 @@ async fn test_instance_failed_after_sled_agent_error( create_project_and_pool(&client).await; let instance_url = get_instance_url(instance_name); let instance = create_instance(client, PROJECT_NAME, instance_name).await; - instance_simulate(nexus, &instance.identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; assert_eq!(instance_next.runtime.run_state, InstanceState::Running); @@ -1013,7 +1022,8 @@ async fn test_instance_failed_after_sled_agent_error( sled_agent.set_instance_ensure_state_error(None).await; let instance = create_instance(client, PROJECT_NAME, instance_name).await; - instance_simulate(nexus, &instance.identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; assert_eq!(instance_next.runtime.run_state, InstanceState::Running); @@ -1135,7 +1145,8 @@ async fn test_instance_metrics(cptestctx: &ControlPlaneTestContext) { // deprovisioned. let instance = instance_post(&client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + instance_simulate(nexus, &instance_id).await; let instance = instance_get(&client, &get_instance_url(&instance_name)).await; assert_eq!(instance.runtime.run_state, InstanceState::Stopped); @@ -1187,10 +1198,10 @@ async fn test_instance_metrics_with_migration( .await; // Create a second sled to migrate to/from. - let default_sled_id: Uuid = + let default_sled_id: SledUuid = nexus_test_utils::SLED_AGENT_UUID.parse().unwrap(); let update_dir = Utf8Path::new("/should/be/unused"); - let other_sled_id = Uuid::new_v4(); + let other_sled_id = SledUuid::new_v4(); let _other_sa = nexus_test_utils::start_sled_agent( cptestctx.logctx.log.new(o!("sled_id" => other_sled_id.to_string())), cptestctx.server.get_http_server_internal_address().await, @@ -1217,7 +1228,7 @@ async fn test_instance_metrics_with_migration( true, ) .await; - let instance_id = instance.identity.id; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // Poke the instance into an active state. instance_simulate(nexus, &instance_id).await; @@ -1266,7 +1277,9 @@ async fn test_instance_metrics_with_migration( format!("/v1/instances/{}/migrate", &instance_id.to_string()); let _ = NexusRequest::new( RequestBuilder::new(client, Method::POST, &migrate_url) - .body(Some(¶ms::InstanceMigrate { dst_sled_id })) + .body(Some(¶ms::InstanceMigrate { + dst_sled_id: dst_sled_id.into_untyped_uuid(), + })) .expect_status(Some(StatusCode::OK)), ) .authn_as(AuthnMode::PrivilegedUser) @@ -1293,9 +1306,8 @@ async fn test_instance_metrics_with_migration( // instance (whose demise wasn't simulated here), but this is intentionally // not reflected in the virtual provisioning counters (which reflect the // logical states of instances ignoring migration). - let instance = - instance_post(&client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(&client, instance_name, InstanceOp::Stop).await; + instance_simulate(nexus, &instance_id).await; let instance = instance_get(&client, &get_instance_url(&instance_name)).await; assert_eq!(instance.runtime.run_state, InstanceState::Stopped); @@ -1342,9 +1354,10 @@ async fn test_instances_create_stopped_start( let instance_url = get_instance_url(instance_name); let instance = instance_post(&client, instance_name, InstanceOp::Start).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // Now, simulate completion of instance boot and check the state reported. - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; identity_eq(&instance.identity, &instance_next.identity); assert_eq!(instance_next.runtime.run_state, InstanceState::Running); @@ -1368,9 +1381,10 @@ async fn test_instances_delete_fails_when_running_succeeds_when_stopped( // Create an instance. let instance_url = get_instance_url(instance_name); let instance = create_instance(client, PROJECT_NAME, instance_name).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // Simulate the instance booting. - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; identity_eq(&instance.identity, &instance_next.identity); assert_eq!(instance_next.runtime.run_state, InstanceState::Running); @@ -1394,9 +1408,8 @@ async fn test_instances_delete_fails_when_running_succeeds_when_stopped( ); // Stop the instance - let instance = - instance_post(&client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(&client, instance_name, InstanceOp::Stop).await; + instance_simulate(nexus, &instance_id).await; let instance = instance_get(&client, &instance_url).await; assert_eq!(instance.runtime.run_state, InstanceState::Stopped); @@ -1995,7 +2008,8 @@ async fn test_instance_create_delete_network_interface( // Stop the instance let instance = instance_post(client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + instance_simulate(nexus, &instance_id).await; // Verify we can now make the requests again let mut interfaces = Vec::with_capacity(2); @@ -2021,9 +2035,8 @@ async fn test_instance_create_delete_network_interface( } // Restart the instance, verify the interfaces are still correct. - let instance = - instance_post(client, instance_name, InstanceOp::Start).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(client, instance_name, InstanceOp::Start).await; + instance_simulate(nexus, &instance_id).await; // Get all interfaces in one request. let other_interfaces = objects_list_page_authz::( @@ -2064,8 +2077,8 @@ async fn test_instance_create_delete_network_interface( } // Stop the instance and verify we can delete the interface - let instance = instance_post(client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(client, instance_name, InstanceOp::Stop).await; + instance_simulate(nexus, &instance_id).await; // We should not be able to delete the primary interface, while the // secondary still exists @@ -2201,7 +2214,8 @@ async fn test_instance_update_network_interfaces( // Stop the instance let instance = instance_post(client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + instance_simulate(nexus, &instance_id).await; // Create the first interface on the instance. let primary_iface = NexusRequest::objects_post( @@ -2221,9 +2235,8 @@ async fn test_instance_update_network_interfaces( // Restart the instance, to ensure we can only modify things when it's // stopped. - let instance = - instance_post(client, instance_name, InstanceOp::Start).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(client, instance_name, InstanceOp::Start).await; + instance_simulate(nexus, &instance_id).await; // We'll change the interface's name and description let new_name = Name::try_from(String::from("new-if0")).unwrap(); @@ -2260,8 +2273,8 @@ async fn test_instance_update_network_interfaces( ); // Stop the instance again, and now verify that the update works. - let instance = instance_post(client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(client, instance_name, InstanceOp::Stop).await; + instance_simulate(nexus, &instance_id).await; let updated_primary_iface = NexusRequest::object_put( client, &format!("/v1/network-interfaces/{}", primary_iface.identity.id), @@ -2363,9 +2376,8 @@ async fn test_instance_update_network_interfaces( ); // Restart the instance, and verify that we can't update either interface. - let instance = - instance_post(client, instance_name, InstanceOp::Start).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(client, instance_name, InstanceOp::Start).await; + instance_simulate(nexus, &instance_id).await; for if_id in [&updated_primary_iface.identity.id, &secondary_iface.identity.id] @@ -2393,8 +2405,8 @@ async fn test_instance_update_network_interfaces( } // Stop the instance again. - let instance = instance_post(client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_post(client, instance_name, InstanceOp::Stop).await; + instance_simulate(nexus, &instance_id).await; // Verify that we can set the secondary as the new primary, and that nothing // else changes about the NICs. @@ -3161,19 +3173,19 @@ async fn test_disks_detached_when_instance_destroyed( // sled. let instance_url = format!("/v1/instances/nfs?project={}", PROJECT_NAME); let instance = instance_get(&client, &instance_url).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); let apictx = &cptestctx.server.server_context(); let nexus = &apictx.nexus; let sa = nexus - .instance_sled_by_id(&instance.identity.id) + .instance_sled_by_id(&instance_id) .await .unwrap() .expect("instance should be on a sled while it's running"); // Stop and delete instance - let instance = - instance_post(&client, instance_name, InstanceOp::Stop).await; + instance_post(&client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance = instance_get(&client, &instance_url).await; assert_eq!(instance.runtime.run_state, InstanceState::Stopped); @@ -3689,9 +3701,10 @@ async fn test_cannot_provision_instance_beyond_cpu_capacity( // Make the started instance transition to Running, shut it down, and verify // that the other reasonably-sized instance can now start. let nexus = &cptestctx.server.server_context().nexus; - instance_simulate(nexus, &instances[1].identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instances[1].identity.id); + instance_simulate(nexus, &instance_id).await; instances[1] = instance_post(client, configs[1].0, InstanceOp::Stop).await; - instance_simulate(nexus, &instances[1].identity.id).await; + instance_simulate(nexus, &instance_id).await; expect_instance_start_ok(client, configs[2].0).await; } @@ -3795,9 +3808,10 @@ async fn test_cannot_provision_instance_beyond_ram_capacity( // Make the started instance transition to Running, shut it down, and verify // that the other reasonably-sized instance can now start. let nexus = &cptestctx.server.server_context().nexus; - instance_simulate(nexus, &instances[1].identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instances[1].identity.id); + instance_simulate(nexus, &instance_id).await; instances[1] = instance_post(client, configs[1].0, InstanceOp::Stop).await; - instance_simulate(nexus, &instances[1].identity.id).await; + instance_simulate(nexus, &instance_id).await; expect_instance_start_ok(client, configs[2].0).await; } @@ -3840,9 +3854,10 @@ async fn test_instance_serial(cptestctx: &ControlPlaneTestContext) { // Create an instance and poke it to ensure it's running. let instance = create_instance(client, PROJECT_NAME, instance_name).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); let instance_next = poll::wait_for_condition( || async { - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; if instance_next.runtime.run_state == InstanceState::Running { Ok(instance_next) @@ -3873,10 +3888,12 @@ async fn test_instance_serial(cptestctx: &ControlPlaneTestContext) { .fetch() .await .unwrap(); - let propolis_id = db_instance - .runtime() - .propolis_id - .expect("running instance should have vmm"); + let propolis_id = PropolisUuid::from_untyped_uuid( + db_instance + .runtime() + .propolis_id + .expect("running instance should have vmm"), + ); let updated_vmm = datastore .vmm_overwrite_addr_for_test(&opctx, &propolis_id, propolis_addr) .await @@ -3916,7 +3933,7 @@ async fn test_instance_serial(cptestctx: &ControlPlaneTestContext) { ); let instance = instance_next; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_next = instance_get(&client, &instance_url).await; assert_eq!(instance_next.runtime.run_state, InstanceState::Stopped); assert!( @@ -4085,7 +4102,11 @@ async fn stop_and_delete_instance( let instance = instance_post(&client, instance_name, InstanceOp::Stop).await; let nexus = &cptestctx.server.server_context().nexus; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate( + nexus, + &InstanceUuid::from_untyped_uuid(instance.identity.id), + ) + .await; let url = format!("/v1/instances/{}?project={}", instance_name, PROJECT_NAME); object_delete(client, &url).await; @@ -4473,6 +4494,7 @@ async fn test_instance_create_in_silo(cptestctx: &ControlPlaneTestContext) { let authn = AuthnMode::SiloUser(user_id); let instance_url = get_instance_url(instance_name); let instance = instance_get_as(&client, &instance_url, authn.clone()).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); info!(&cptestctx.logctx.log, "test got instance"; "instance" => ?instance); assert_eq!(instance.runtime.run_state, InstanceState::Starting); @@ -4490,7 +4512,7 @@ async fn test_instance_create_in_silo(cptestctx: &ControlPlaneTestContext) { ), nexus.datastore().clone(), ); - instance_simulate_with_opctx(nexus, &instance.identity.id, &opctx).await; + instance_simulate_with_opctx(nexus, &instance_id, &opctx).await; let instance = instance_get_as(&client, &instance_url, authn).await; assert_eq!(instance.runtime.run_state, InstanceState::Running); @@ -4509,7 +4531,7 @@ async fn test_instance_create_in_silo(cptestctx: &ControlPlaneTestContext) { .await .expect("Failed to stop the instance"); - instance_simulate_with_opctx(nexus, &instance.identity.id, &opctx).await; + instance_simulate_with_opctx(nexus, &instance_id, &opctx).await; // Delete the instance NexusRequest::object_delete(client, &instance_url) @@ -4530,7 +4552,7 @@ async fn test_instance_v2p_mappings(cptestctx: &ControlPlaneTestContext) { let nsleds = 3; let mut additional_sleds = Vec::with_capacity(nsleds); for _ in 0..nsleds { - let sa_id = Uuid::new_v4(); + let sa_id = SledUuid::new_v4(); let log = cptestctx.logctx.log.new(o!( "sled_id" => sa_id.to_string() )); let addr = cptestctx.server.get_http_server_internal_address().await; @@ -4551,6 +4573,7 @@ async fn test_instance_v2p_mappings(cptestctx: &ControlPlaneTestContext) { // Create an instance. let instance_name = "test-instance"; let instance = create_instance(client, PROJECT_NAME, instance_name).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); let nics_url = format!("/v1/network-interfaces?instance={}", instance.identity.id,); @@ -4593,9 +4616,9 @@ async fn test_instance_v2p_mappings(cptestctx: &ControlPlaneTestContext) { } // Delete the instance - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; instance_post(&client, instance_name, InstanceOp::Stop).await; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; let instance_url = get_instance_url(instance_name); NexusRequest::object_delete(client, &instance_url) @@ -4745,18 +4768,18 @@ async fn assert_sled_v2p_mappings( /// have to look up the instance, then get the sled agent associated with that /// instance, and then tell it to finish simulating whatever async transition is /// going on. -pub async fn instance_simulate(nexus: &Arc, id: &Uuid) { +pub async fn instance_simulate(nexus: &Arc, id: &InstanceUuid) { let sa = nexus .instance_sled_by_id(id) .await .unwrap() .expect("instance must be on a sled to simulate a state change"); - sa.instance_finish_transition(*id).await; + sa.instance_finish_transition(id.into_untyped_uuid()).await; } pub async fn instance_simulate_with_opctx( nexus: &Arc, - id: &Uuid, + id: &InstanceUuid, opctx: &OpContext, ) { let sa = nexus @@ -4764,7 +4787,7 @@ pub async fn instance_simulate_with_opctx( .await .unwrap() .expect("instance must be on a sled to simulate a state change"); - sa.instance_finish_transition(*id).await; + sa.instance_finish_transition(id.into_untyped_uuid()).await; } /// Simulates state transitions for the incarnation of the instance on the @@ -4773,11 +4796,11 @@ pub async fn instance_simulate_with_opctx( async fn instance_simulate_on_sled( cptestctx: &ControlPlaneTestContext, nexus: &Arc, - sled_id: Uuid, - instance_id: Uuid, + sled_id: SledUuid, + instance_id: InstanceUuid, ) { info!(&cptestctx.logctx.log, "Poking simulated instance on sled"; "instance_id" => %instance_id, "sled_id" => %sled_id); let sa = nexus.sled_client(&sled_id).await.unwrap(); - sa.instance_finish_transition(instance_id).await; + sa.instance_finish_transition(instance_id.into_untyped_uuid()).await; } diff --git a/nexus/tests/integration_tests/ip_pools.rs b/nexus/tests/integration_tests/ip_pools.rs index e3ddc98029..df3aa93c5f 100644 --- a/nexus/tests/integration_tests/ip_pools.rs +++ b/nexus/tests/integration_tests/ip_pools.rs @@ -54,6 +54,8 @@ use omicron_common::api::external::NameOrId; use omicron_common::api::external::SimpleIdentity; use omicron_common::api::external::{IdentityMetadataCreateParams, Name}; use omicron_nexus::TestInterfaces; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use sled_agent_client::TestInterfaces as SledTestInterfaces; use uuid::Uuid; @@ -1254,6 +1256,7 @@ async fn test_ip_range_delete_with_allocated_external_ip_fails( const INSTANCE_NAME: &str = "myinst"; create_project(client, PROJECT_NAME).await; let instance = create_instance(client, PROJECT_NAME, INSTANCE_NAME).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // We should not be able to delete the range, since there's an external IP // address in use out of it. @@ -1293,7 +1296,7 @@ async fn test_ip_range_delete_with_allocated_external_ip_fails( // Simulate the transition, wait until it is in fact stopped. let sa = nexus - .instance_sled_by_id(&instance.identity.id) + .instance_sled_by_id(&instance_id) .await .unwrap() .expect("running instance should be on a sled"); diff --git a/nexus/tests/integration_tests/metrics.rs b/nexus/tests/integration_tests/metrics.rs index 5fbff216d9..9cfa0350e8 100644 --- a/nexus/tests/integration_tests/metrics.rs +++ b/nexus/tests/integration_tests/metrics.rs @@ -20,6 +20,7 @@ use nexus_test_utils::resource_helpers::{ use nexus_test_utils::ControlPlaneTestContext; use nexus_test_utils_macros::nexus_test; use omicron_test_utils::dev::poll::{wait_for_condition, CondCheckError}; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; use oximeter::types::Datum; use oximeter::types::Measurement; use oximeter::TimeseriesSchema; @@ -429,11 +430,11 @@ async fn test_instance_watcher_metrics( #[track_caller] fn count_state( table: &oximeter_db::oxql::Table, - instance_id: Uuid, + instance_id: InstanceUuid, state: &'static str, ) -> i64 { use oximeter_db::oxql::point::ValueArray; - let uuid = FieldValue::Uuid(instance_id); + let uuid = FieldValue::Uuid(instance_id.into_untyped_uuid()); let state = FieldValue::String(state.into()); let mut timeserieses = table.timeseries().filter(|ts| { ts.fields.get(INSTANCE_ID_FIELD) == Some(&uuid) @@ -473,7 +474,7 @@ async fn test_instance_watcher_metrics( eprintln!("--- creating instance 1 ---"); let instance1 = create_instance(&client, project_name, "i-1").await; - let instance1_uuid = instance1.identity.id; + let instance1_uuid = InstanceUuid::from_untyped_uuid(instance1.identity.id); // activate the instance watcher background task. activate_instance_watcher().await; @@ -489,7 +490,7 @@ async fn test_instance_watcher_metrics( // okay, make another instance eprintln!("--- creating instance 2 ---"); let instance2 = create_instance(&client, project_name, "i-2").await; - let instance2_uuid = instance2.identity.id; + let instance2_uuid = InstanceUuid::from_untyped_uuid(instance2.identity.id); // activate the instance watcher background task. activate_instance_watcher().await; diff --git a/nexus/tests/integration_tests/pantry.rs b/nexus/tests/integration_tests/pantry.rs index c5d98709ac..29e590b1a9 100644 --- a/nexus/tests/integration_tests/pantry.rs +++ b/nexus/tests/integration_tests/pantry.rs @@ -26,6 +26,8 @@ use omicron_common::api::external::IdentityMetadataCreateParams; use omicron_common::api::external::Instance; use omicron_nexus::Nexus; use omicron_nexus::TestInterfaces as _; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use sled_agent_client::TestInterfaces as _; use std::sync::Arc; use uuid::Uuid; @@ -83,13 +85,13 @@ async fn set_instance_state( .unwrap() } -async fn instance_simulate(nexus: &Arc, id: &Uuid) { +async fn instance_simulate(nexus: &Arc, id: &InstanceUuid) { let sa = nexus .instance_sled_by_id(id) .await .unwrap() .expect("instance must be on a sled to simulate a state change"); - sa.instance_finish_transition(*id).await; + sa.instance_finish_transition(id.into_untyped_uuid()).await; } async fn disk_get(client: &ClientTestContext, disk_url: &str) -> Disk { @@ -147,14 +149,14 @@ async fn create_instance_and_attach_disk( ) { // Create an instance to attach the disk. let instance = create_instance(&client, PROJECT_NAME, INSTANCE_NAME).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // TODO(https://github.com/oxidecomputer/omicron/issues/811): // // Instances must be stopped before disks can be attached - this // is an artificial limitation without hotplug support. - let instance_next = - set_instance_state(&client, INSTANCE_NAME, "stop").await; - instance_simulate(nexus, &instance_next.identity.id).await; + set_instance_state(&client, INSTANCE_NAME, "stop").await; + instance_simulate(nexus, &instance_id).await; let url_instance_attach_disk = get_disk_attach_url(instance.identity.name.as_str()); diff --git a/nexus/tests/integration_tests/sleds.rs b/nexus/tests/integration_tests/sleds.rs index 97dbb39bc6..bd8a8877fc 100644 --- a/nexus/tests/integration_tests/sleds.rs +++ b/nexus/tests/integration_tests/sleds.rs @@ -20,6 +20,7 @@ use nexus_test_utils_macros::nexus_test; use nexus_types::external_api::views::SledInstance; use nexus_types::external_api::views::{PhysicalDisk, Sled}; use omicron_sled_agent::sim; +use omicron_uuid_kinds::SledUuid; use std::str::FromStr; use uuid::Uuid; @@ -56,7 +57,7 @@ async fn test_sleds_list(cptestctx: &ControlPlaneTestContext) { let nsleds = 3; let mut sas = Vec::with_capacity(nsleds); for _ in 0..nsleds { - let sa_id = Uuid::new_v4(); + let sa_id = SledUuid::new_v4(); let log = cptestctx.logctx.log.new(o!( "sled_id" => sa_id.to_string() )); let addr = cptestctx.server.get_http_server_internal_address().await; diff --git a/nexus/tests/integration_tests/snapshots.rs b/nexus/tests/integration_tests/snapshots.rs index f0ce2cca72..b4b8ad3090 100644 --- a/nexus/tests/integration_tests/snapshots.rs +++ b/nexus/tests/integration_tests/snapshots.rs @@ -38,6 +38,8 @@ use omicron_common::api::external::Instance; use omicron_common::api::external::InstanceCpuCount; use omicron_common::api::external::Name; use omicron_nexus::app::MIN_DISK_SIZE_BYTES; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use uuid::Uuid; type ControlPlaneTestContext = @@ -139,10 +141,11 @@ async fn test_snapshot_basic(cptestctx: &ControlPlaneTestContext) { }, ) .await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); // cannot snapshot attached disk for instance in state starting let nexus = &cptestctx.server.server_context().nexus; - instance_simulate(nexus, &instance.identity.id).await; + instance_simulate(nexus, &instance_id).await; // Issue snapshot request let snapshots_url = format!("/v1/snapshots?project={}", PROJECT_NAME); diff --git a/nexus/tests/integration_tests/vpc_subnets.rs b/nexus/tests/integration_tests/vpc_subnets.rs index dcc96d08bf..81e7156e8e 100644 --- a/nexus/tests/integration_tests/vpc_subnets.rs +++ b/nexus/tests/integration_tests/vpc_subnets.rs @@ -21,6 +21,8 @@ use nexus_types::external_api::{params, views::VpcSubnet}; use omicron_common::api::external::IdentityMetadataCreateParams; use omicron_common::api::external::IdentityMetadataUpdateParams; use omicron_common::api::external::Ipv6NetExt; +use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use oxnet::Ipv6Net; type ControlPlaneTestContext = @@ -55,7 +57,8 @@ async fn test_delete_vpc_subnet_with_interfaces_fails( let instance_url = format!("/v1/instances/{instance_name}?project={project_name}"); let instance = create_instance(client, &project_name, instance_name).await; - instance_simulate(nexus, &instance.identity.id).await; + let instance_id = InstanceUuid::from_untyped_uuid(instance.identity.id); + instance_simulate(nexus, &instance_id).await; let err: HttpErrorResponseBody = NexusRequest::expect_failure( &client, StatusCode::BAD_REQUEST, @@ -76,7 +79,7 @@ async fn test_delete_vpc_subnet_with_interfaces_fails( // Stop and then delete the instance instance_post(client, instance_name, InstanceOp::Stop).await; - instance_simulate(&nexus, &instance.identity.id).await; + instance_simulate(&nexus, &instance_id).await; NexusRequest::object_delete(&client, &instance_url) .authn_as(AuthnMode::PrivilegedUser) .execute() diff --git a/openapi/nexus-internal.json b/openapi/nexus-internal.json index b27dc6ce00..c3cc3c059d 100644 --- a/openapi/nexus-internal.json +++ b/openapi/nexus-internal.json @@ -3145,8 +3145,11 @@ "dst_propolis_id": { "nullable": true, "description": "If a migration is active, the ID of the target VMM.", - "type": "string", - "format": "uuid" + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForPropolisKind" + } + ] }, "gen": { "description": "Generation number for this state.", @@ -3165,8 +3168,11 @@ "propolis_id": { "nullable": true, "description": "The instance's currently active VMM ID.", - "type": "string", - "format": "uuid" + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForPropolisKind" + } + ] }, "time_updated": { "description": "Timestamp for this information.", @@ -4665,8 +4671,11 @@ }, "propolis_id": { "description": "The ID of the VMM whose state is being reported.", - "type": "string", - "format": "uuid" + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForPropolisKind" + } + ] }, "vmm_state": { "description": "The most recent state of the sled's VMM process.", @@ -4905,6 +4914,10 @@ "type": "string", "format": "uuid" }, + "TypedUuidForPropolisKind": { + "type": "string", + "format": "uuid" + }, "TypedUuidForSledKind": { "type": "string", "format": "uuid" diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index 25e8d1c5da..e1349c2b59 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -230,8 +230,7 @@ "name": "instance_id", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForInstanceKind" } } ], @@ -272,8 +271,7 @@ "name": "instance_id", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForInstanceKind" } } ], @@ -360,8 +358,7 @@ "name": "instance_id", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForInstanceKind" } } ], @@ -395,8 +392,7 @@ "name": "instance_id", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForInstanceKind" } } ], @@ -432,8 +428,7 @@ "name": "instance_id", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForInstanceKind" } } ], @@ -476,8 +471,7 @@ "name": "instance_id", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForInstanceKind" } } ], @@ -508,8 +502,7 @@ "name": "instance_id", "required": true, "schema": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForInstanceKind" } } ], @@ -2812,8 +2805,11 @@ }, "propolis_id": { "description": "The ID of the VMM being registered. This may not be the active VMM ID in the instance runtime state (e.g. if the new VMM is going to be a migration target).", - "type": "string", - "format": "uuid" + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForPropolisKind" + } + ] }, "vmm_runtime": { "description": "The initial VMM runtime state for the VMM being registered.", @@ -2982,8 +2978,7 @@ "type": "object", "properties": { "dst_propolis_id": { - "type": "string", - "format": "uuid" + "$ref": "#/components/schemas/TypedUuidForPropolisKind" }, "migration_id": { "type": "string", @@ -3104,8 +3099,11 @@ "dst_propolis_id": { "nullable": true, "description": "If a migration is active, the ID of the target VMM.", - "type": "string", - "format": "uuid" + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForPropolisKind" + } + ] }, "gen": { "description": "Generation number for this state.", @@ -3124,8 +3122,11 @@ "propolis_id": { "nullable": true, "description": "The instance's currently active VMM ID.", - "type": "string", - "format": "uuid" + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForPropolisKind" + } + ] }, "time_updated": { "description": "Timestamp for this information.", @@ -4280,8 +4281,11 @@ }, "propolis_id": { "description": "The ID of the VMM whose state is being reported.", - "type": "string", - "format": "uuid" + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForPropolisKind" + } + ] }, "vmm_state": { "description": "The most recent state of the sled's VMM process.", @@ -4499,6 +4503,10 @@ "sync" ] }, + "TypedUuidForPropolisKind": { + "type": "string", + "format": "uuid" + }, "TypedUuidForZpoolKind": { "type": "string", "format": "uuid" @@ -5044,6 +5052,10 @@ "A", "B" ] + }, + "TypedUuidForInstanceKind": { + "type": "string", + "format": "uuid" } }, "responses": { diff --git a/sled-agent/src/common/instance.rs b/sled-agent/src/common/instance.rs index b2c135fcf8..02623455f4 100644 --- a/sled-agent/src/common/instance.rs +++ b/sled-agent/src/common/instance.rs @@ -11,18 +11,18 @@ use omicron_common::api::internal::nexus::{ InstanceRuntimeState, MigrationRole, MigrationRuntimeState, MigrationState, SledInstanceState, VmmRuntimeState, VmmState, }; +use omicron_uuid_kinds::PropolisUuid; use propolis_client::types::{ InstanceState as PropolisApiState, InstanceStateMonitorResponse, MigrationState as PropolisMigrationState, }; -use uuid::Uuid; /// The instance and VMM state that sled agent maintains on a per-VMM basis. #[derive(Clone, Debug)] pub struct InstanceStates { instance: InstanceRuntimeState, vmm: VmmRuntimeState, - propolis_id: Uuid, + propolis_id: PropolisUuid, migration: Option, } @@ -209,7 +209,7 @@ impl InstanceStates { pub fn new( instance: InstanceRuntimeState, vmm: VmmRuntimeState, - propolis_id: Uuid, + propolis_id: PropolisUuid, ) -> Self { let migration = instance.migration_id.map(|migration_id| { let dst_propolis_id = instance.dst_propolis_id.expect("if an instance has a migration ID, it should also have a target VMM ID"); @@ -237,7 +237,7 @@ impl InstanceStates { &self.vmm } - pub fn propolis_id(&self) -> Uuid { + pub fn propolis_id(&self) -> PropolisUuid { self.propolis_id } @@ -602,7 +602,7 @@ mod test { use uuid::Uuid; fn make_instance() -> InstanceStates { - let propolis_id = Uuid::new_v4(); + let propolis_id = PropolisUuid::new_v4(); let now = Utc::now(); let instance = InstanceRuntimeState { propolis_id: Some(propolis_id), @@ -626,7 +626,7 @@ mod test { state.vmm.state = VmmState::Migrating; let migration_id = Uuid::new_v4(); state.instance.migration_id = Some(migration_id); - state.instance.dst_propolis_id = Some(Uuid::new_v4()); + state.instance.dst_propolis_id = Some(PropolisUuid::new_v4()); state.migration = Some(MigrationRuntimeState { migration_id, state: MigrationState::InProgress, @@ -636,6 +636,7 @@ mod test { gen: Generation::new().next(), time_updated: Utc::now(), }); + state } @@ -644,7 +645,7 @@ mod test { state.vmm.state = VmmState::Migrating; let migration_id = Uuid::new_v4(); state.instance.migration_id = Some(migration_id); - state.propolis_id = Uuid::new_v4(); + state.propolis_id = PropolisUuid::new_v4(); state.instance.dst_propolis_id = Some(state.propolis_id); state.migration = Some(MigrationRuntimeState { migration_id, @@ -935,7 +936,7 @@ mod test { state.set_migration_ids( &Some(InstanceMigrationSourceParams { migration_id, - dst_propolis_id: Uuid::new_v4(), + dst_propolis_id: PropolisUuid::new_v4(), }), Utc::now(), ); @@ -1020,7 +1021,7 @@ mod test { // new IDs are present should indicate that they are indeed present. let migration_ids = InstanceMigrationSourceParams { migration_id: Uuid::new_v4(), - dst_propolis_id: Uuid::new_v4(), + dst_propolis_id: PropolisUuid::new_v4(), }; new_instance.set_migration_ids(&Some(migration_ids), Utc::now()); @@ -1056,7 +1057,7 @@ mod test { )); new_instance.instance.migration_id = Some(migration_ids.migration_id); - new_instance.instance.dst_propolis_id = Some(Uuid::new_v4()); + new_instance.instance.dst_propolis_id = Some(PropolisUuid::new_v4()); assert!(!new_instance.migration_ids_already_set( old_instance.instance(), &Some(migration_ids) diff --git a/sled-agent/src/http_entrypoints.rs b/sled-agent/src/http_entrypoints.rs index c5cd88619f..6defd18a95 100644 --- a/sled-agent/src/http_entrypoints.rs +++ b/sled-agent/src/http_entrypoints.rs @@ -32,6 +32,7 @@ use omicron_common::api::internal::nexus::{ DiskRuntimeState, SledInstanceState, UpdateArtifactId, }; use omicron_common::api::internal::shared::SwitchPorts; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use sled_hardware::DiskVariant; @@ -414,7 +415,7 @@ async fn cockroachdb_init( /// Path parameters for Instance requests (sled agent API) #[derive(Deserialize, JsonSchema)] struct InstancePathParam { - instance_id: Uuid, + instance_id: InstanceUuid, } #[endpoint { @@ -614,7 +615,7 @@ async fn instance_issue_disk_snapshot_request( let body = body.into_inner(); sa.instance_issue_disk_snapshot_request( - path_params.instance_id, + InstanceUuid::from_untyped_uuid(path_params.instance_id), path_params.disk_id, body.snapshot_id, ) diff --git a/sled-agent/src/instance.rs b/sled-agent/src/instance.rs index c6c567595d..04b68ef752 100644 --- a/sled-agent/src/instance.rs +++ b/sled-agent/src/instance.rs @@ -39,6 +39,7 @@ use omicron_common::api::internal::shared::{ NetworkInterface, SourceNatConfig, }; use omicron_common::backoff; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid}; use propolis_client::Client as PropolisClient; use rand::prelude::SliceRandom; use rand::SeedableRng; @@ -108,10 +109,10 @@ pub enum Error { ResolveError(#[from] internal_dns::resolver::ResolveError), #[error("Instance {0} not running!")] - InstanceNotRunning(Uuid), + InstanceNotRunning(InstanceUuid), #[error("Instance already registered with Propolis ID {0}")] - InstanceAlreadyRegistered(Uuid), + InstanceAlreadyRegistered(PropolisUuid), #[error("No U.2 devices found")] U2NotFound, @@ -182,7 +183,7 @@ fn fmri_name() -> String { /// Return the expected name of a Propolis zone managing an instance with the /// provided ID. -pub fn propolis_zone_name(id: &Uuid) -> String { +pub fn propolis_zone_name(id: &PropolisUuid) -> String { format!("{}{}", PROPOLIS_ZONE_PREFIX, id) } @@ -316,7 +317,7 @@ struct InstanceRunner { properties: propolis_client::types::InstanceProperties, // The ID of the Propolis server (and zone) running this instance - propolis_id: Uuid, + propolis_id: PropolisUuid, // The socket address of the Propolis server running this instance propolis_addr: SocketAddr, @@ -470,12 +471,12 @@ impl InstanceRunner { } /// Yields this instance's ID. - fn id(&self) -> &Uuid { - &self.properties.id + fn id(&self) -> InstanceUuid { + InstanceUuid::from_untyped_uuid(self.properties.id) } /// Yields this instance's Propolis's ID. - fn propolis_id(&self) -> &Uuid { + fn propolis_id(&self) -> &PropolisUuid { &self.propolis_id } @@ -495,7 +496,10 @@ impl InstanceRunner { self.nexus_client .client() - .cpapi_instances_put(self.id(), &state.into()) + .cpapi_instances_put( + &self.id().into_untyped_uuid(), + &state.into(), + ) .await .map_err(|err| -> backoff::BackoffError { match &err { @@ -928,8 +932,8 @@ impl Instance { /// * `metadata`: Instance-related metadata used to track statistics. pub(crate) fn new( log: Logger, - id: Uuid, - propolis_id: Uuid, + id: InstanceUuid, + propolis_id: PropolisUuid, ticket: InstanceTicket, state: InstanceInitialState, services: InstanceManagerServices, @@ -1000,7 +1004,7 @@ impl Instance { monitor_handle: None, // NOTE: Mostly lies. properties: propolis_client::types::InstanceProperties { - id, + id: id.into_untyped_uuid(), name: hardware.properties.hostname.to_string(), description: "Test description".to_string(), image_id: Uuid::nil(), @@ -1262,7 +1266,7 @@ impl InstanceRunner { } InstanceStateRequested::Reboot => { if self.running_state.is_none() { - return Err(Error::InstanceNotRunning(*self.id())); + return Err(Error::InstanceNotRunning(self.id())); } ( Some(PropolisRequest::Reboot), @@ -1354,7 +1358,7 @@ impl InstanceRunner { .with_zone_root_path(&root) .with_zone_image_paths(&["/opt/oxide".into()]) .with_zone_type("propolis-server") - .with_unique_name(*self.propolis_id()) + .with_unique_name(self.propolis_id().into_untyped_uuid()) .with_datasets(&[]) .with_filesystems(&[]) .with_data_links(&[]) @@ -1473,7 +1477,9 @@ impl InstanceRunner { Ok(()) } else { - Err(Error::InstanceNotRunning(self.properties.id)) + Err(Error::InstanceNotRunning(InstanceUuid::from_untyped_uuid( + self.properties.id, + ))) } } @@ -1710,8 +1716,8 @@ mod tests { storage_handle: StorageHandle, temp_dir: &String, ) -> Instance { - let id = Uuid::new_v4(); - let propolis_id = Uuid::new_v4(); + let id = InstanceUuid::new_v4(); + let propolis_id = PropolisUuid::new_v4(); let ticket = InstanceTicket::new_without_manager_for_test(id); @@ -1743,7 +1749,7 @@ mod tests { } fn fake_instance_initial_state( - propolis_id: Uuid, + propolis_id: PropolisUuid, propolis_addr: SocketAddr, ) -> InstanceInitialState { let hardware = InstanceHardware { @@ -2104,8 +2110,8 @@ mod tests { propolis_mock_server(&logctx.log); let propolis_addr = propolis_server.local_addr(); - let instance_id = Uuid::new_v4(); - let propolis_id = Uuid::new_v4(); + let instance_id = InstanceUuid::new_v4(); + let propolis_id = PropolisUuid::new_v4(); let InstanceInitialState { hardware, instance_runtime, diff --git a/sled-agent/src/instance_manager.rs b/sled-agent/src/instance_manager.rs index ee1425f0d7..beeb8377d2 100644 --- a/sled-agent/src/instance_manager.rs +++ b/sled-agent/src/instance_manager.rs @@ -27,6 +27,8 @@ use illumos_utils::running_zone::ZoneBuilderFactory; use omicron_common::api::internal::nexus::InstanceRuntimeState; use omicron_common::api::internal::nexus::SledInstanceState; use omicron_common::api::internal::nexus::VmmRuntimeState; +use omicron_uuid_kinds::InstanceUuid; +use omicron_uuid_kinds::PropolisUuid; use sled_storage::manager::StorageHandle; use slog::Logger; use std::collections::BTreeMap; @@ -44,7 +46,7 @@ pub enum Error { Instance(#[from] crate::instance::Error), #[error("No such instance ID: {0}")] - NoSuchInstance(Uuid), + NoSuchInstance(InstanceUuid), #[error("OPTE port management error: {0}")] Opte(#[from] illumos_utils::opte::Error), @@ -137,8 +139,8 @@ impl InstanceManager { #[allow(clippy::too_many_arguments)] pub async fn ensure_registered( &self, - instance_id: Uuid, - propolis_id: Uuid, + instance_id: InstanceUuid, + propolis_id: PropolisUuid, hardware: InstanceHardware, instance_runtime: InstanceRuntimeState, vmm_runtime: VmmRuntimeState, @@ -165,7 +167,7 @@ impl InstanceManager { pub async fn ensure_unregistered( &self, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result { let (tx, rx) = oneshot::channel(); self.inner @@ -181,7 +183,7 @@ impl InstanceManager { pub async fn ensure_state( &self, - instance_id: Uuid, + instance_id: InstanceUuid, target: InstanceStateRequested, ) -> Result { let (tx, rx) = oneshot::channel(); @@ -215,7 +217,7 @@ impl InstanceManager { pub async fn put_migration_ids( &self, - instance_id: Uuid, + instance_id: InstanceUuid, old_runtime: &InstanceRuntimeState, migration_ids: &Option, ) -> Result { @@ -235,7 +237,7 @@ impl InstanceManager { pub async fn instance_issue_disk_snapshot_request( &self, - instance_id: Uuid, + instance_id: InstanceUuid, disk_id: Uuid, snapshot_id: Uuid, ) -> Result<(), Error> { @@ -272,7 +274,7 @@ impl InstanceManager { pub async fn add_external_ip( &self, - instance_id: Uuid, + instance_id: InstanceUuid, ip: &InstanceExternalIpBody, ) -> Result<(), Error> { let (tx, rx) = oneshot::channel(); @@ -290,7 +292,7 @@ impl InstanceManager { pub async fn delete_external_ip( &self, - instance_id: Uuid, + instance_id: InstanceUuid, ip: &InstanceExternalIpBody, ) -> Result<(), Error> { let (tx, rx) = oneshot::channel(); @@ -313,7 +315,7 @@ impl InstanceManager { pub async fn get_instance_state( &self, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result { let (tx, rx) = oneshot::channel(); self.inner @@ -334,8 +336,8 @@ impl InstanceManager { #[derive(strum::Display)] enum InstanceManagerRequest { EnsureRegistered { - instance_id: Uuid, - propolis_id: Uuid, + instance_id: InstanceUuid, + propolis_id: PropolisUuid, hardware: InstanceHardware, instance_runtime: InstanceRuntimeState, vmm_runtime: VmmRuntimeState, @@ -344,22 +346,22 @@ enum InstanceManagerRequest { tx: oneshot::Sender>, }, EnsureUnregistered { - instance_id: Uuid, + instance_id: InstanceUuid, tx: oneshot::Sender>, }, EnsureState { - instance_id: Uuid, + instance_id: InstanceUuid, target: InstanceStateRequested, tx: oneshot::Sender>, }, PutMigrationIds { - instance_id: Uuid, + instance_id: InstanceUuid, old_runtime: InstanceRuntimeState, migration_ids: Option, tx: oneshot::Sender>, }, InstanceIssueDiskSnapshot { - instance_id: Uuid, + instance_id: InstanceUuid, disk_id: Uuid, snapshot_id: Uuid, tx: oneshot::Sender>, @@ -369,17 +371,17 @@ enum InstanceManagerRequest { tx: oneshot::Sender>, }, InstanceAddExternalIp { - instance_id: Uuid, + instance_id: InstanceUuid, ip: InstanceExternalIpBody, tx: oneshot::Sender>, }, InstanceDeleteExternalIp { - instance_id: Uuid, + instance_id: InstanceUuid, ip: InstanceExternalIpBody, tx: oneshot::Sender>, }, GetState { - instance_id: Uuid, + instance_id: InstanceUuid, tx: oneshot::Sender>, }, } @@ -387,7 +389,7 @@ enum InstanceManagerRequest { // Requests that the instance manager stop processing information about a // particular instance. struct InstanceDeregisterRequest { - id: Uuid, + id: InstanceUuid, } struct InstanceManagerRunner { @@ -414,7 +416,7 @@ struct InstanceManagerRunner { // instance, we could avoid the methods within "instance.rs" that panic // if the Propolis client hasn't been initialized. /// A mapping from a Sled Agent "Instance ID" to ("Propolis ID", [Instance]). - instances: BTreeMap, + instances: BTreeMap, vnic_allocator: VnicAllocator, port_manager: PortManager, @@ -511,7 +513,7 @@ impl InstanceManagerRunner { } } - fn get_instance(&self, instance_id: Uuid) -> Option<&Instance> { + fn get_instance(&self, instance_id: InstanceUuid) -> Option<&Instance> { self.instances.get(&instance_id).map(|(_id, v)| v) } @@ -535,8 +537,8 @@ impl InstanceManagerRunner { #[allow(clippy::too_many_arguments)] pub async fn ensure_registered( &mut self, - instance_id: Uuid, - propolis_id: Uuid, + instance_id: InstanceUuid, + propolis_id: PropolisUuid, hardware: InstanceHardware, instance_runtime: InstanceRuntimeState, vmm_runtime: VmmRuntimeState, @@ -625,7 +627,7 @@ impl InstanceManagerRunner { async fn ensure_unregistered( &mut self, tx: oneshot::Sender>, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result<(), Error> { // If the instance does not exist, we response immediately. let Some(instance) = self.get_instance(instance_id) else { @@ -645,7 +647,7 @@ impl InstanceManagerRunner { async fn ensure_state( &mut self, tx: oneshot::Sender>, - instance_id: Uuid, + instance_id: InstanceUuid, target: InstanceStateRequested, ) -> Result<(), Error> { let Some(instance) = self.get_instance(instance_id) else { @@ -680,7 +682,7 @@ impl InstanceManagerRunner { async fn put_migration_ids( &mut self, tx: oneshot::Sender>, - instance_id: Uuid, + instance_id: InstanceUuid, old_runtime: &InstanceRuntimeState, migration_ids: &Option, ) -> Result<(), Error> { @@ -697,7 +699,7 @@ impl InstanceManagerRunner { async fn instance_issue_disk_snapshot_request( &self, tx: oneshot::Sender>, - instance_id: Uuid, + instance_id: InstanceUuid, disk_id: Uuid, snapshot_id: Uuid, ) -> Result<(), Error> { @@ -734,7 +736,7 @@ impl InstanceManagerRunner { async fn add_external_ip( &self, tx: oneshot::Sender>, - instance_id: Uuid, + instance_id: InstanceUuid, ip: &InstanceExternalIpBody, ) -> Result<(), Error> { let Some(instance) = self.get_instance(instance_id) else { @@ -747,7 +749,7 @@ impl InstanceManagerRunner { async fn delete_external_ip( &self, tx: oneshot::Sender>, - instance_id: Uuid, + instance_id: InstanceUuid, ip: &InstanceExternalIpBody, ) -> Result<(), Error> { let Some(instance) = self.get_instance(instance_id) else { @@ -761,7 +763,7 @@ impl InstanceManagerRunner { async fn get_instance_state( &self, tx: oneshot::Sender>, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result<(), Error> { let Some(instance) = self.get_instance(instance_id) else { return tx @@ -777,7 +779,7 @@ impl InstanceManagerRunner { /// Represents membership of an instance in the [`InstanceManager`]. pub struct InstanceTicket { - id: Uuid, + id: InstanceUuid, terminate_tx: Option>, } @@ -785,14 +787,14 @@ impl InstanceTicket { // Creates a new instance ticket for instance "id" to be removed // from the manger on destruction. fn new( - id: Uuid, + id: InstanceUuid, terminate_tx: mpsc::UnboundedSender, ) -> Self { InstanceTicket { id, terminate_tx: Some(terminate_tx) } } #[cfg(all(test, target_os = "illumos"))] - pub(crate) fn new_without_manager_for_test(id: Uuid) -> Self { + pub(crate) fn new_without_manager_for_test(id: InstanceUuid) -> Self { Self { id, terminate_tx: None } } diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 2ed7ca5528..9575e08c17 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -19,6 +19,7 @@ use omicron_common::api::internal::nexus::{ use omicron_common::api::internal::shared::{ NetworkInterface, SourceNatConfig, }; +use omicron_uuid_kinds::PropolisUuid; use omicron_uuid_kinds::ZpoolUuid; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -117,7 +118,7 @@ pub struct InstanceEnsureBody { /// The ID of the VMM being registered. This may not be the active VMM ID in /// the instance runtime state (e.g. if the new VMM is going to be a /// migration target). - pub propolis_id: Uuid, + pub propolis_id: PropolisUuid, /// The address at which this VMM should serve a Propolis server API. pub propolis_addr: SocketAddr, @@ -214,7 +215,7 @@ impl InstanceStateRequested { #[derive(Copy, Clone, Debug, Deserialize, Serialize, JsonSchema)] pub struct InstanceMigrationSourceParams { pub migration_id: Uuid, - pub dst_propolis_id: Uuid, + pub dst_propolis_id: PropolisUuid, } /// The body of a request to set or clear the migration identifiers from a diff --git a/sled-agent/src/sim/collection.rs b/sled-agent/src/sim/collection.rs index 12e17cc3de..8af71ac026 100644 --- a/sled-agent/src/sim/collection.rs +++ b/sled-agent/src/sim/collection.rs @@ -427,12 +427,12 @@ mod test { use omicron_common::api::internal::nexus::VmmRuntimeState; use omicron_common::api::internal::nexus::VmmState; use omicron_test_utils::dev::test_setup_log; - use uuid::Uuid; + use omicron_uuid_kinds::PropolisUuid; fn make_instance( logctx: &LogContext, ) -> (SimObject, Receiver<()>) { - let propolis_id = Uuid::new_v4(); + let propolis_id = PropolisUuid::new_v4(); let instance_vmm = InstanceRuntimeState { propolis_id: Some(propolis_id), dst_propolis_id: None, diff --git a/sled-agent/src/sim/http_entrypoints.rs b/sled-agent/src/sim/http_entrypoints.rs index ae1318a8b1..012889c664 100644 --- a/sled-agent/src/sim/http_entrypoints.rs +++ b/sled-agent/src/sim/http_entrypoints.rs @@ -25,6 +25,7 @@ use omicron_common::api::internal::nexus::DiskRuntimeState; use omicron_common::api::internal::nexus::SledInstanceState; use omicron_common::api::internal::nexus::UpdateArtifactId; use omicron_common::api::internal::shared::SwitchPorts; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use sled_storage::resources::DisksManagementResult; @@ -77,7 +78,7 @@ pub fn api() -> SledApiDescription { /// Path parameters for Instance requests (sled agent API) #[derive(Deserialize, JsonSchema)] struct InstancePathParam { - instance_id: Uuid, + instance_id: InstanceUuid, } #[endpoint { @@ -309,7 +310,7 @@ async fn instance_issue_disk_snapshot_request( let body = body.into_inner(); sa.instance_issue_disk_snapshot_request( - path_params.instance_id, + InstanceUuid::from_untyped_uuid(path_params.instance_id), path_params.disk_id, body.snapshot_id, ) diff --git a/sled-agent/src/sim/sled_agent.rs b/sled-agent/src/sim/sled_agent.rs index 7f07dc199a..f47d8a9100 100644 --- a/sled-agent/src/sim/sled_agent.rs +++ b/sled-agent/src/sim/sled_agent.rs @@ -38,7 +38,7 @@ use omicron_common::api::internal::nexus::{ }; use omicron_common::api::internal::shared::RackNetworkConfig; use omicron_common::disk::DiskIdentity; -use omicron_uuid_kinds::ZpoolUuid; +use omicron_uuid_kinds::{GenericUuid, InstanceUuid, PropolisUuid, ZpoolUuid}; use oxnet::Ipv6Net; use propolis_client::{ types::VolumeConstructionRequest, Client as PropolisClient, @@ -253,8 +253,8 @@ impl SledAgent { /// (described by `target`). pub async fn instance_register( self: &Arc, - instance_id: Uuid, - propolis_id: Uuid, + instance_id: InstanceUuid, + propolis_id: PropolisUuid, hardware: InstanceHardware, instance_runtime: InstanceRuntimeState, vmm_runtime: VmmRuntimeState, @@ -271,7 +271,9 @@ impl SledAgent { for disk in &hardware.disks { let initial_state = DiskRuntimeState { - disk_state: DiskState::Attached(instance_id), + disk_state: DiskState::Attached( + instance_id.into_untyped_uuid(), + ), gen: omicron_common::api::external::Generation::new(), time_updated: chrono::Utc::now(), }; @@ -286,7 +288,9 @@ impl SledAgent { .sim_ensure( &id, initial_state, - Some(DiskStateRequested::Attached(instance_id)), + Some(DiskStateRequested::Attached( + instance_id.into_untyped_uuid(), + )), ) .await?; self.disks @@ -303,9 +307,13 @@ impl SledAgent { // point to the correct address. let mock_lock = self.mock_propolis.lock().await; if let Some((_srv, client)) = mock_lock.as_ref() { - if !self.instances.contains_key(&instance_id).await { + if !self + .instances + .contains_key(&instance_id.into_untyped_uuid()) + .await + { let properties = propolis_client::types::InstanceProperties { - id: propolis_id, + id: propolis_id.into_untyped_uuid(), name: hardware.properties.hostname.to_string(), description: "sled-agent-sim created instance".to_string(), image_id: Uuid::default(), @@ -336,7 +344,7 @@ impl SledAgent { let instance_run_time_state = self .instances .sim_ensure( - &instance_id, + &instance_id.into_untyped_uuid(), SledInstanceState { instance_state: instance_runtime, vmm_state: vmm_runtime, @@ -360,32 +368,33 @@ impl SledAgent { /// not notified. pub async fn instance_unregister( self: &Arc, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result { - let instance = - match self.instances.sim_get_cloned_object(&instance_id).await { - Ok(instance) => instance, - Err(Error::ObjectNotFound { .. }) => { - return Ok(InstanceUnregisterResponse { - updated_runtime: None, - }) - } - Err(e) => return Err(e), - }; + let instance = match self + .instances + .sim_get_cloned_object(&instance_id.into_untyped_uuid()) + .await + { + Ok(instance) => instance, + Err(Error::ObjectNotFound { .. }) => { + return Ok(InstanceUnregisterResponse { updated_runtime: None }) + } + Err(e) => return Err(e), + }; self.detach_disks_from_instance(instance_id).await?; let response = InstanceUnregisterResponse { updated_runtime: Some(instance.terminate()), }; - self.instances.sim_force_remove(instance_id).await; + self.instances.sim_force_remove(instance_id.into_untyped_uuid()).await; Ok(response) } /// Asks the supplied instance to transition to the requested state. pub async fn instance_ensure_state( self: &Arc, - instance_id: Uuid, + instance_id: InstanceUuid, state: InstanceStateRequested, ) -> Result { if let Some(e) = self.instance_ensure_state_error.lock().await.as_ref() @@ -393,23 +402,26 @@ impl SledAgent { return Err(e.clone()); } - let current = - match self.instances.sim_get_cloned_object(&instance_id).await { - Ok(i) => i.current().clone(), - Err(_) => match state { - InstanceStateRequested::Stopped => { - return Ok(InstancePutStateResponse { - updated_runtime: None, - }); - } - _ => { - return Err(Error::invalid_request(&format!( - "instance {} not registered on sled", - instance_id, - ))); - } - }, - }; + let current = match self + .instances + .sim_get_cloned_object(&instance_id.into_untyped_uuid()) + .await + { + Ok(i) => i.current().clone(), + Err(_) => match state { + InstanceStateRequested::Stopped => { + return Ok(InstancePutStateResponse { + updated_runtime: None, + }); + } + _ => { + return Err(Error::invalid_request(&format!( + "instance {} not registered on sled", + instance_id, + ))); + } + }, + }; let mock_lock = self.mock_propolis.lock().await; if let Some((_srv, client)) = mock_lock.as_ref() { @@ -427,7 +439,11 @@ impl SledAgent { tokio::spawn(async move { tokio::time::sleep(Duration::from_secs(10)).await; match instances - .sim_ensure(&instance_id, current, Some(state)) + .sim_ensure( + &instance_id.into_untyped_uuid(), + current, + Some(state), + ) .await { Ok(state) => { @@ -457,7 +473,7 @@ impl SledAgent { let new_state = self .instances - .sim_ensure(&instance_id, current, Some(state)) + .sim_ensure(&instance_id.into_untyped_uuid(), current, Some(state)) .await?; // If this request will shut down the simulated instance, look for any @@ -471,11 +487,11 @@ impl SledAgent { pub async fn instance_get_state( &self, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result { let instance = self .instances - .sim_get_cloned_object(&instance_id) + .sim_get_cloned_object(&instance_id.into_untyped_uuid()) .await .map_err(|_| { crate::sled_agent::Error::Instance( @@ -491,13 +507,13 @@ impl SledAgent { async fn detach_disks_from_instance( &self, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result<(), Error> { self.disks .sim_ensure_for_each_where( |disk| match disk.current().disk_state { DiskState::Attached(id) | DiskState::Attaching(id) => { - id == instance_id + id == instance_id.into_untyped_uuid() } _ => false, }, @@ -510,12 +526,14 @@ impl SledAgent { pub async fn instance_put_migration_ids( self: &Arc, - instance_id: Uuid, + instance_id: InstanceUuid, old_runtime: &InstanceRuntimeState, migration_ids: &Option, ) -> Result { - let instance = - self.instances.sim_get_cloned_object(&instance_id).await?; + let instance = self + .instances + .sim_get_cloned_object(&instance_id.into_untyped_uuid()) + .await?; instance.put_migration_ids(old_runtime, migration_ids).await } @@ -544,8 +562,8 @@ impl SledAgent { self.disks.size().await } - pub async fn instance_poke(&self, id: Uuid) { - self.instances.sim_poke(id, PokeMode::Drain).await; + pub async fn instance_poke(&self, id: InstanceUuid) { + self.instances.sim_poke(id.into_untyped_uuid(), PokeMode::Drain).await; } pub async fn disk_poke(&self, id: Uuid) { @@ -628,7 +646,7 @@ impl SledAgent { /// snapshot here. pub async fn instance_issue_disk_snapshot_request( &self, - _instance_id: Uuid, + _instance_id: InstanceUuid, disk_id: Uuid, snapshot_id: Uuid, ) -> Result<(), Error> { @@ -689,17 +707,18 @@ impl SledAgent { pub async fn instance_put_external_ip( &self, - instance_id: Uuid, + instance_id: InstanceUuid, body_args: &InstanceExternalIpBody, ) -> Result<(), Error> { - if !self.instances.contains_key(&instance_id).await { + if !self.instances.contains_key(&instance_id.into_untyped_uuid()).await + { return Err(Error::internal_error( "can't alter IP state for nonexistent instance", )); } let mut eips = self.external_ips.lock().await; - let my_eips = eips.entry(instance_id).or_default(); + let my_eips = eips.entry(instance_id.into_untyped_uuid()).or_default(); // High-level behaviour: this should always succeed UNLESS // trying to add a double ephemeral. @@ -722,17 +741,18 @@ impl SledAgent { pub async fn instance_delete_external_ip( &self, - instance_id: Uuid, + instance_id: InstanceUuid, body_args: &InstanceExternalIpBody, ) -> Result<(), Error> { - if !self.instances.contains_key(&instance_id).await { + if !self.instances.contains_key(&instance_id.into_untyped_uuid()).await + { return Err(Error::internal_error( "can't alter IP state for nonexistent instance", )); } let mut eips = self.external_ips.lock().await; - let my_eips = eips.entry(instance_id).or_default(); + let my_eips = eips.entry(instance_id.into_untyped_uuid()).or_default(); my_eips.remove(&body_args); diff --git a/sled-agent/src/sim/storage.rs b/sled-agent/src/sim/storage.rs index dac2a4cb48..5077120fdd 100644 --- a/sled-agent/src/sim/storage.rs +++ b/sled-agent/src/sim/storage.rs @@ -21,6 +21,7 @@ use dropshot::HttpError; use futures::lock::Mutex; use omicron_common::disk::DiskIdentity; use omicron_uuid_kinds::GenericUuid; +use omicron_uuid_kinds::InstanceUuid; use omicron_uuid_kinds::OmicronZoneUuid; use omicron_uuid_kinds::ZpoolUuid; use propolis_client::types::VolumeConstructionRequest; @@ -868,7 +869,7 @@ impl Pantry { self.sled_agent .instance_issue_disk_snapshot_request( - Uuid::new_v4(), // instance id, not used by function + InstanceUuid::new_v4(), // instance id, not used by function volume_id.parse().unwrap(), snapshot_id.parse().unwrap(), ) diff --git a/sled-agent/src/sled_agent.rs b/sled-agent/src/sled_agent.rs index 670d486686..993e5f6a94 100644 --- a/sled-agent/src/sled_agent.rs +++ b/sled-agent/src/sled_agent.rs @@ -59,6 +59,7 @@ use omicron_common::backoff::{ retry_notify, retry_policy_internal_service_aggressive, BackoffError, }; use omicron_ddm_admin_client::Client as DdmAdminClient; +use omicron_uuid_kinds::{InstanceUuid, PropolisUuid}; use oximeter::types::ProducerRegistry; use sled_hardware::{underlay, HardwareManager}; use sled_hardware_types::underlay::BootstrapInterface; @@ -882,8 +883,8 @@ impl SledAgent { #[allow(clippy::too_many_arguments)] pub async fn instance_ensure_registered( &self, - instance_id: Uuid, - propolis_id: Uuid, + instance_id: InstanceUuid, + propolis_id: PropolisUuid, hardware: InstanceHardware, instance_runtime: InstanceRuntimeState, vmm_runtime: VmmRuntimeState, @@ -912,7 +913,7 @@ impl SledAgent { /// rudely terminates the instance. pub async fn instance_ensure_unregistered( &self, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result { self.inner .instances @@ -925,7 +926,7 @@ impl SledAgent { /// state. pub async fn instance_ensure_state( &self, - instance_id: Uuid, + instance_id: InstanceUuid, target: InstanceStateRequested, ) -> Result { self.inner @@ -941,7 +942,7 @@ impl SledAgent { /// [`crate::params::InstancePutMigrationIdsBody`]. pub async fn instance_put_migration_ids( &self, - instance_id: Uuid, + instance_id: InstanceUuid, old_runtime: &InstanceRuntimeState, migration_ids: &Option, ) -> Result { @@ -959,7 +960,7 @@ impl SledAgent { /// does not match the current ephemeral IP. pub async fn instance_put_external_ip( &self, - instance_id: Uuid, + instance_id: InstanceUuid, external_ip: &InstanceExternalIpBody, ) -> Result<(), Error> { self.inner @@ -973,7 +974,7 @@ impl SledAgent { /// specified external IP address in either its ephemeral or floating IP set. pub async fn instance_delete_external_ip( &self, - instance_id: Uuid, + instance_id: InstanceUuid, external_ip: &InstanceExternalIpBody, ) -> Result<(), Error> { self.inner @@ -986,7 +987,7 @@ impl SledAgent { /// Returns the state of the instance with the provided ID. pub async fn instance_get_state( &self, - instance_id: Uuid, + instance_id: InstanceUuid, ) -> Result { self.inner .instances @@ -1023,7 +1024,7 @@ impl SledAgent { /// Issue a snapshot request for a Crucible disk attached to an instance pub async fn instance_issue_disk_snapshot_request( &self, - instance_id: Uuid, + instance_id: InstanceUuid, disk_id: Uuid, snapshot_id: Uuid, ) -> Result<(), Error> { diff --git a/uuid-kinds/src/lib.rs b/uuid-kinds/src/lib.rs index 2fc08972a6..430b3f7f9f 100644 --- a/uuid-kinds/src/lib.rs +++ b/uuid-kinds/src/lib.rs @@ -57,6 +57,7 @@ impl_typed_uuid_kind! { LoopbackAddress => "loopback_address", OmicronZone => "service", PhysicalDisk => "physical_disk", + Propolis => "propolis", Sled => "sled", TufRepo => "tuf_repo", Upstairs => "upstairs", From 064d9ea9aa50ce153aa048a24aaa045c828f2994 Mon Sep 17 00:00:00 2001 From: David Crespo Date: Mon, 17 Jun 2024 17:29:14 -0500 Subject: [PATCH 03/26] Fix "project" (silo) IP pool view perms for non-admins (#5887) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #5883 Authz for IP pools is undercooked. Every user has `CreateChild` on them so they can allocate IPs, but they generally don't have `Read` on them unless they're a fleet viewer. Ideally, we'd be able to say "you have `Read` on an IP pool if it is linked to your silo", but I don't know how to express that relationship with polar (plus it requires a join to the silo-pool links table to tell). Update: after [discussing](https://matrix.to/#/!YNYPOVxjAUeXksTcRj:oxide.computer/$XTbZiYkEFRKWHwe6XSVivBrqiWWl_z25u2_TcjwRohE?via=oxide.computer&via=unix.house&via=matrix.org) this with @davepacheco in chat, we agreed on a direction but also agreed it might be fairly complicated. Based on that, I think it would be most expedient to 1. Merge this fix as-is (with a link to https://github.com/oxidecomputer/omicron/issues/3995, which I forgot I had made 10 months ago 😢) 2. Update #3995 with more details from the chat --- nexus/src/app/ip_pool.rs | 16 ++- nexus/tests/integration_tests/ip_pools.rs | 113 +++++++++++++++------- 2 files changed, 94 insertions(+), 35 deletions(-) diff --git a/nexus/src/app/ip_pool.rs b/nexus/src/app/ip_pool.rs index fd73a18355..d3179f9299 100644 --- a/nexus/src/app/ip_pool.rs +++ b/nexus/src/app/ip_pool.rs @@ -99,8 +99,20 @@ impl super::Nexus { opctx: &'a OpContext, pool: &'a NameOrId, ) -> LookupResult<(db::model::IpPool, db::model::IpPoolResource)> { - let (authz_pool, pool) = - self.ip_pool_lookup(opctx, pool)?.fetch().await?; + let (authz_pool, pool) = self + .ip_pool_lookup(opctx, pool)? + // TODO-robustness: https://github.com/oxidecomputer/omicron/issues/3995 + // Checking CreateChild works because it is the permission for + // allocating IPs from a pool, which any authenticated user has. + // But what we really want to say is that any authenticated user + // has actual Read permission on any IP pool linked to their silo. + // Instead we are backing into this with the next line: never fail + // this auth check as long as you're authed, then 404 if unlinked. + // This is not a correctness issue per se because the logic as-is is + // correct. The main problem is that it is fiddly to get right and + // has to be done manually each time. + .fetch_for(authz::Action::CreateChild) + .await?; // 404 if no link is found in the current silo let link = self.db_datastore.ip_pool_fetch_link(opctx, pool.id()).await; diff --git a/nexus/tests/integration_tests/ip_pools.rs b/nexus/tests/integration_tests/ip_pools.rs index df3aa93c5f..d044eb735c 100644 --- a/nexus/tests/integration_tests/ip_pools.rs +++ b/nexus/tests/integration_tests/ip_pools.rs @@ -4,6 +4,8 @@ //! Integration tests for operating on IP Pools +use std::net::Ipv4Addr; + use dropshot::test_util::ClientTestContext; use dropshot::HttpErrorResponseBody; use dropshot::ResultsPage; @@ -20,8 +22,10 @@ use nexus_test_utils::http_testing::RequestBuilder; use nexus_test_utils::resource_helpers::assert_ip_pool_utilization; use nexus_test_utils::resource_helpers::create_instance; use nexus_test_utils::resource_helpers::create_ip_pool; +use nexus_test_utils::resource_helpers::create_local_user; use nexus_test_utils::resource_helpers::create_project; use nexus_test_utils::resource_helpers::create_silo; +use nexus_test_utils::resource_helpers::grant_iam; use nexus_test_utils::resource_helpers::link_ip_pool; use nexus_test_utils::resource_helpers::object_create; use nexus_test_utils::resource_helpers::object_create_error; @@ -41,6 +45,7 @@ use nexus_types::external_api::params::IpPoolUpdate; use nexus_types::external_api::shared::IpRange; use nexus_types::external_api::shared::Ipv4Range; use nexus_types::external_api::shared::SiloIdentityMode; +use nexus_types::external_api::shared::SiloRole; use nexus_types::external_api::views::IpPool; use nexus_types::external_api::views::IpPoolRange; use nexus_types::external_api::views::IpPoolSiloLink; @@ -1144,52 +1149,94 @@ async fn test_ip_pool_range_pagination(cptestctx: &ControlPlaneTestContext) { #[nexus_test] async fn test_ip_pool_list_in_silo(cptestctx: &ControlPlaneTestContext) { let client = &cptestctx.external_client; - let mypool_name = "mypool"; - const PROJECT_NAME: &str = "myproj"; - create_project(client, PROJECT_NAME).await; + let silo_url = format!("/v1/system/silos/{}", cptestctx.silo_name); + let silo: Silo = object_get(client, &silo_url).await; - // create pool with range and link (as default pool) to default silo, which - // is the privileged user's silo - let mypool_range = IpRange::V4( - Ipv4Range::new( - std::net::Ipv4Addr::new(10, 0, 0, 51), - std::net::Ipv4Addr::new(10, 0, 0, 52), - ) - .unwrap(), + // manually create default pool and link to test silo, as opposed to default + // silo, which is what the helper would do + let _ = create_ip_pool(&client, "default", None).await; + let default_name = "default"; + link_ip_pool(&client, default_name, &silo.identity.id, true).await; + + // create other pool and link to silo + let other_pool_range = IpRange::V4( + Ipv4Range::new(Ipv4Addr::new(10, 1, 0, 1), Ipv4Addr::new(10, 1, 0, 5)) + .unwrap(), ); - create_ip_pool(client, mypool_name, Some(mypool_range)).await; - link_ip_pool(client, mypool_name, &DEFAULT_SILO.id(), true).await; + let other_name = "other-pool"; + create_ip_pool(&client, other_name, Some(other_pool_range)).await; + link_ip_pool(&client, other_name, &silo.identity.id, false).await; - // create another pool and don't link it to anything - let otherpool_name = "other-pool"; - let otherpool_range = IpRange::V4( - Ipv4Range::new( - std::net::Ipv4Addr::new(10, 0, 0, 53), - std::net::Ipv4Addr::new(10, 0, 0, 54), - ) - .unwrap(), + // create third pool and don't link to silo + let unlinked_pool_range = IpRange::V4( + Ipv4Range::new(Ipv4Addr::new(10, 2, 0, 1), Ipv4Addr::new(10, 2, 0, 5)) + .unwrap(), ); - create_ip_pool(client, otherpool_name, Some(otherpool_range)).await; + let unlinked_name = "unlinked-pool"; + create_ip_pool(&client, unlinked_name, Some(unlinked_pool_range)).await; + + // Create a silo user + let user = create_local_user( + client, + &silo, + &"user".parse().unwrap(), + params::UserPassword::LoginDisallowed, + ) + .await; - let list = objects_list_page_authz::(client, "/v1/ip-pools") + // Make silo collaborator + grant_iam( + client, + &silo_url, + SiloRole::Collaborator, + user.id, + AuthnMode::PrivilegedUser, + ) + .await; + + let list = NexusRequest::object_get(client, "/v1/ip-pools") + .authn_as(AuthnMode::SiloUser(user.id)) + .execute_and_parse_unwrap::>() .await .items; - // only mypool shows up because it's linked to my silo - assert_eq!(list.len(), 1); - assert_eq!(list[0].identity.name.to_string(), mypool_name); + assert_eq!(list.len(), 2); + assert_eq!(list[0].identity.name.to_string(), default_name); assert!(list[0].is_default); - - // fetch the pool directly too - let url = format!("/v1/ip-pools/{}", mypool_name); - let pool = object_get::(client, &url).await; - assert_eq!(pool.identity.name.as_str(), mypool_name); + assert_eq!(list[1].identity.name.to_string(), other_name); + assert!(!list[1].is_default); + + // fetch the pools directly too + let url = format!("/v1/ip-pools/{}", default_name); + let pool = NexusRequest::object_get(client, &url) + .authn_as(AuthnMode::SiloUser(user.id)) + .execute_and_parse_unwrap::() + .await; + assert_eq!(pool.identity.name.as_str(), default_name); assert!(pool.is_default); + let url = format!("/v1/ip-pools/{}", other_name); + let pool = NexusRequest::object_get(client, &url) + .authn_as(AuthnMode::SiloUser(user.id)) + .execute_and_parse_unwrap::() + .await; + assert_eq!(pool.identity.name.as_str(), other_name); + assert!(!pool.is_default); + // fetching the other pool directly 404s - let url = format!("/v1/ip-pools/{}", otherpool_name); - object_get_error(client, &url, StatusCode::NOT_FOUND).await; + let url = format!("/v1/ip-pools/{}", unlinked_name); + let _error = NexusRequest::new( + RequestBuilder::new(client, Method::GET, &url) + .expect_status(Some(StatusCode::NOT_FOUND)), + ) + .authn_as(AuthnMode::PrivilegedUser) + .execute() + .await + .unwrap() + .parsed_body::() + .unwrap(); + dbg!(_error); } #[nexus_test] From 13f51377a5e41b66a7b6c1c72d42f43cd582c30a Mon Sep 17 00:00:00 2001 From: Nils Nieuwejaar Date: Mon, 17 Jun 2024 20:57:33 -0400 Subject: [PATCH 04/26] UplinkAddress change broke deserialization of old test data (#5905) Use "use as" to avoid BgpPeer name collision with maghemite --- sled-agent/src/bootstrap/early_networking.rs | 533 ++++++++++-------- sled-agent/src/bootstrap/params.rs | 152 ++++- sled-agent/src/config.rs | 7 +- sled-agent/src/rack_setup/config.rs | 6 +- sled-agent/src/rack_setup/plan/sled.rs | 44 +- sled-agent/tests/data/early_network_blobs.txt | 4 +- .../tests/integration_tests/early_network.rs | 7 +- .../madrid-rss-sled-plan.json | 2 +- 8 files changed, 482 insertions(+), 273 deletions(-) diff --git a/sled-agent/src/bootstrap/early_networking.rs b/sled-agent/src/bootstrap/early_networking.rs index 61cfd8485d..664e3242ab 100644 --- a/sled-agent/src/bootstrap/early_networking.rs +++ b/sled-agent/src/bootstrap/early_networking.rs @@ -14,9 +14,11 @@ use futures::future; use gateway_client::Client as MgsClient; use internal_dns::resolver::{ResolveError, Resolver as DnsResolver}; use internal_dns::ServiceName; +use mg_admin_client::types::BfdPeerConfig as MgBfdPeerConfig; +use mg_admin_client::types::BgpPeerConfig as MgBgpPeerConfig; +use mg_admin_client::types::ImportExportPolicy as MgImportExportPolicy; use mg_admin_client::types::{ - AddStaticRoute4Request, ApplyRequest, BfdPeerConfig, BgpPeerConfig, - CheckerSource, ImportExportPolicy as MgImportExportPolicy, Prefix, Prefix4, + AddStaticRoute4Request, ApplyRequest, CheckerSource, Prefix, Prefix4, Prefix6, ShaperSource, StaticRoute4, StaticRoute4List, }; use mg_admin_client::Client as MgdClient; @@ -24,8 +26,9 @@ use omicron_common::address::DENDRITE_PORT; use omicron_common::address::{MGD_PORT, MGS_PORT}; use omicron_common::api::external::{BfdMode, ImportExportPolicy}; use omicron_common::api::internal::shared::{ - BgpConfig, PortConfig, PortConfigV2, PortFec, PortSpeed, RackNetworkConfig, - RackNetworkConfigV2, RouteConfig, SwitchLocation, UplinkAddressConfig, + BfdPeerConfig, BgpConfig, BgpPeerConfig, PortConfig, PortConfigV2, PortFec, + PortSpeed, RackNetworkConfig, RackNetworkConfigV2, RouteConfig, + SwitchLocation, UplinkAddressConfig, }; use omicron_common::backoff::{ retry_notify, retry_policy_local, BackoffError, ExponentialBackoff, @@ -39,6 +42,7 @@ use serde::{Deserialize, Serialize}; use slog::Logger; use std::collections::{HashMap, HashSet}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV6}; +use std::str::FromStr; use std::time::{Duration, Instant}; use thiserror::Error; @@ -459,7 +463,8 @@ impl<'a> EarlyNetworkSetup<'a> { ); let mut config: Option = None; - let mut bgp_peer_configs = HashMap::>::new(); + let mut bgp_peer_configs = + HashMap::>::new(); // Iterate through ports and apply BGP config. for port in &our_ports { @@ -488,7 +493,7 @@ impl<'a> EarlyNetworkSetup<'a> { ); } - let bpc = BgpPeerConfig { + let bpc = MgBgpPeerConfig { name: format!("{}", peer.addr), host: format!("{}:179", peer.addr), hold_time: peer.hold_time.unwrap_or(6), @@ -622,7 +627,7 @@ impl<'a> EarlyNetworkSetup<'a> { if spec.switch != switch_location { continue; } - let cfg = BfdPeerConfig { + let cfg = MgBfdPeerConfig { detection_threshold: spec.detection_threshold, listen: spec.local.unwrap_or(Ipv4Addr::UNSPECIFIED.into()), mode: match spec.mode { @@ -723,54 +728,6 @@ fn retry_policy_switch_mapping() -> ExponentialBackoff { .build() } -// The first production version of the `EarlyNetworkConfig`. -// -// If this version is in the bootstore than we need to convert it to -// `EarlyNetworkConfigV2`. -// -// Once we do this for all customers that have initialized racks with the -// old version we can go ahead and remove this type and its conversion code -// altogether. -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -struct EarlyNetworkConfigV0 { - // The current generation number of data as stored in CRDB. - // The initial generation is set during RSS time and then only mutated - // by Nexus. - pub generation: u64, - - pub rack_subnet: Ipv6Addr, - - /// The external NTP server addresses. - pub ntp_servers: Vec, - - // Rack network configuration as delivered from RSS and only existing at - // generation 1 - pub rack_network_config: Option, -} - -// The second production version of the `EarlyNetworkConfig`. -// -// If this version is in the bootstore than we need to convert it to -// `EarlyNetworkConfigV2`. -// -// Once we do this for all customers that have initialized racks with the -// old version we can go ahead and remove this type and its conversion code -// altogether. -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -struct EarlyNetworkConfigV1 { - // The current generation number of data as stored in CRDB. - // The initial generation is set during RSS time and then only mutated - // by Nexus. - pub generation: u64, - - // Which version of the data structure do we have. This is to help with - // deserialization and conversion in future updates. - pub schema_version: u32, - - // The actual configuration details - pub body: EarlyNetworkConfigBodyV1, -} - /// Network configuration required to bring up the control plane /// /// The fields in this structure are those from @@ -792,7 +749,44 @@ pub struct EarlyNetworkConfig { pub body: EarlyNetworkConfigBody, } +impl FromStr for EarlyNetworkConfig { + type Err = String; + + fn from_str(value: &str) -> Result { + #[derive(Deserialize)] + struct ShadowConfig { + generation: u64, + schema_version: u32, + body: EarlyNetworkConfigBody, + } + + let v2_err = match serde_json::from_str::(&value) { + Ok(cfg) => { + return Ok(EarlyNetworkConfig { + generation: cfg.generation, + schema_version: cfg.schema_version, + body: cfg.body, + }) + } + Err(e) => format!("unable to parse EarlyNetworkConfig: {e:?}"), + }; + // If we fail to parse the config as any known version, we return the + // error corresponding to the parse failure of the newest schema. + serde_json::from_str::(&value) + .map(|v1| EarlyNetworkConfig { + generation: v1.generation, + schema_version: Self::schema_version(), + body: v1.body.into(), + }) + .map_err(|_| v2_err) + } +} + impl EarlyNetworkConfig { + pub fn schema_version() -> u32 { + 2 + } + // Note: This currently only converts between v0 and v1 or deserializes v1 of // `EarlyNetworkConfig`. pub fn deserialize_bootstore_config( @@ -817,18 +811,15 @@ impl EarlyNetworkConfig { } }; - match serde_json::from_slice::(&config.blob) { - Ok(val) => { + match serde_json::from_slice::( + &config.blob, + ) { + Ok(v1) => { // Convert from v1 to v2 return Ok(EarlyNetworkConfig { - generation: val.generation, - schema_version: 2, - body: EarlyNetworkConfigBody { - ntp_servers: val.body.ntp_servers, - rack_network_config: val.body.rack_network_config.map( - |v1_config| RackNetworkConfigV1::to_v2(v1_config), - ), - }, + generation: v1.generation, + schema_version: EarlyNetworkConfig::schema_version(), + body: v1.body.into(), }); } Err(error) => { @@ -842,7 +833,9 @@ impl EarlyNetworkConfig { } }; - match serde_json::from_slice::(&config.blob) { + match serde_json::from_slice::( + &config.blob, + ) { Ok(val) => { // Convert from v0 to v2 return Ok(EarlyNetworkConfig { @@ -852,7 +845,7 @@ impl EarlyNetworkConfig { ntp_servers: val.ntp_servers, rack_network_config: val.rack_network_config.map( |v0_config| { - RackNetworkConfigV0::to_v2( + back_compat::RackNetworkConfigV0::to_v2( val.rack_subnet, v0_config, ) @@ -870,8 +863,8 @@ impl EarlyNetworkConfig { } }; - // Return the v2 error preferentially over subsequent errors as it's - // more likely to be useful. + // If we fail to parse the config as any known version, we return the + // error corresponding to the parse failure of the newest schema. Err(v2_error) } } @@ -905,186 +898,246 @@ impl From for bootstore::NetworkConfig { } } -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -struct EarlyNetworkConfigBodyV1 { - /// The external NTP server addresses. - pub ntp_servers: Vec, +/// Structures and routines used to maintain backwards compatibility. The +/// contents of this module should only be used to convert older data into the +/// current format, and not for any ongoing run-time operations. +pub mod back_compat { + use super::*; - // Rack network configuration as delivered from RSS or Nexus - pub rack_network_config: Option, -} + #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] + pub struct EarlyNetworkConfigBodyV1 { + /// The external NTP server addresses. + pub ntp_servers: Vec, -/// Deprecated, use `RackNetworkConfig` instead. Cannot actually deprecate due to -/// -/// -/// Our first version of `RackNetworkConfig`. If this exists in the bootstore, we -/// upgrade out of it into `RackNetworkConfigV1` or later versions if possible. -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] -struct RackNetworkConfigV0 { - // TODO: #3591 Consider making infra-ip ranges implicit for uplinks - /// First ip address to be used for configuring network infrastructure - pub infra_ip_first: Ipv4Addr, - /// Last ip address to be used for configuring network infrastructure - pub infra_ip_last: Ipv4Addr, - /// Uplinks for connecting the rack to external networks - pub uplinks: Vec, -} + // Rack network configuration as delivered from RSS or Nexus + pub rack_network_config: Option, + } -impl RackNetworkConfigV0 { - /// Convert from `RackNetworkConfigV0` to `RackNetworkConfigV1` - /// - /// We cannot use `From for `RackNetworkConfigV2` - /// because the `rack_subnet` field does not exist in `RackNetworkConfigV0` - /// and must be passed in from the `EarlyNetworkConfigV0` struct which - /// contains the `RackNetworkConfigV0` struct. - pub fn to_v2( - rack_subnet: Ipv6Addr, - v0: RackNetworkConfigV0, - ) -> RackNetworkConfigV2 { - RackNetworkConfigV2 { - rack_subnet: Ipv6Net::new(rack_subnet, 56).unwrap(), - infra_ip_first: v0.infra_ip_first, - infra_ip_last: v0.infra_ip_last, - ports: v0 - .uplinks - .into_iter() - .map(|uplink| PortConfigV2::from(uplink)) - .collect(), - bgp: vec![], - bfd: vec![], + impl From for EarlyNetworkConfigBody { + fn from(v1: EarlyNetworkConfigBodyV1) -> Self { + EarlyNetworkConfigBody { + ntp_servers: v1.ntp_servers, + rack_network_config: v1 + .rack_network_config + .map(|v1_config| v1_config.into()), + } } } -} -/// Deprecated, use PortConfigV2 instead. Cannot actually deprecate due to -/// -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -struct PortConfigV1 { - /// The set of routes associated with this port. - pub routes: Vec, - /// This port's addresses and optional vlan IDs - pub addresses: Vec, - /// Switch the port belongs to. - pub switch: SwitchLocation, - /// Nmae of the port this config applies to. - pub port: String, - /// Port speed. - pub uplink_port_speed: PortSpeed, - /// Port forward error correction type. - pub uplink_port_fec: PortFec, - /// BGP peers on this port - pub bgp_peers: Vec, - /// Whether or not to set autonegotiation - #[serde(default)] - pub autoneg: bool, -} + /// Deprecated, use `RackNetworkConfig` instead. Cannot actually deprecate due to + /// + /// + /// Our first version of `RackNetworkConfig`. If this exists in the bootstore, we + /// upgrade out of it into `RackNetworkConfigV1` or later versions if possible. + #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] + pub(crate) struct RackNetworkConfigV0 { + // TODO: #3591 Consider making infra-ip ranges implicit for uplinks + /// First ip address to be used for configuring network infrastructure + pub infra_ip_first: Ipv4Addr, + /// Last ip address to be used for configuring network infrastructure + pub infra_ip_last: Ipv4Addr, + /// Uplinks for connecting the rack to external networks + pub uplinks: Vec, + } -impl From for PortConfigV2 { - fn from(value: PortConfigV1) -> Self { - PortConfigV2 { - routes: value.routes.clone(), - addresses: value - .addresses - .iter() - .map(|a| UplinkAddressConfig { address: *a, vlan_id: None }) - .collect(), - switch: value.switch, - port: value.port, - uplink_port_speed: value.uplink_port_speed, - uplink_port_fec: value.uplink_port_fec, - bgp_peers: vec![], - autoneg: false, + impl RackNetworkConfigV0 { + /// Convert from `RackNetworkConfigV0` to `RackNetworkConfigV1` + /// + /// We cannot use `From for `RackNetworkConfigV2` + /// because the `rack_subnet` field does not exist in `RackNetworkConfigV0` + /// and must be passed in from the `EarlyNetworkConfigV0` struct which + /// contains the `RackNetworkConfigV0` struct. + pub fn to_v2( + rack_subnet: Ipv6Addr, + v0: RackNetworkConfigV0, + ) -> RackNetworkConfigV2 { + RackNetworkConfigV2 { + rack_subnet: Ipv6Net::new(rack_subnet, 56).unwrap(), + infra_ip_first: v0.infra_ip_first, + infra_ip_last: v0.infra_ip_last, + ports: v0 + .uplinks + .into_iter() + .map(|uplink| PortConfigV2::from(uplink)) + .collect(), + bgp: vec![], + bfd: vec![], + } } } -} -/// Deprecated, use PortConfigV2 instead. Cannot actually deprecate due to -/// -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] -struct UplinkConfig { - /// Gateway address - pub gateway_ip: Ipv4Addr, - /// Switch to use for uplink - pub switch: SwitchLocation, - /// Switchport to use for external connectivity - pub uplink_port: String, - /// Speed for the Switchport - pub uplink_port_speed: PortSpeed, - /// Forward Error Correction setting for the uplink port - pub uplink_port_fec: PortFec, - /// IP Address and prefix (e.g., `192.168.0.1/16`) to apply to switchport - /// (must be in infra_ip pool) - pub uplink_cidr: Ipv4Net, - /// VLAN id to use for uplink - pub uplink_vid: Option, -} + /// Deprecated, use PortConfigV2 instead. Cannot actually deprecate due to + /// + #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)] + pub struct PortConfigV1 { + /// The set of routes associated with this port. + pub routes: Vec, + /// This port's addresses and optional vlan IDs + pub addresses: Vec, + /// Switch the port belongs to. + pub switch: SwitchLocation, + /// Nmae of the port this config applies to. + pub port: String, + /// Port speed. + pub uplink_port_speed: PortSpeed, + /// Port forward error correction type. + pub uplink_port_fec: PortFec, + /// BGP peers on this port + pub bgp_peers: Vec, + /// Whether or not to set autonegotiation + #[serde(default)] + pub autoneg: bool, + } -impl From for PortConfigV2 { - fn from(value: UplinkConfig) -> Self { - PortConfigV2 { - routes: vec![RouteConfig { - destination: "0.0.0.0/0".parse().unwrap(), - nexthop: value.gateway_ip.into(), - vlan_id: value.uplink_vid, - }], - addresses: vec![UplinkAddressConfig { - address: value.uplink_cidr.into(), - vlan_id: value.uplink_vid, - }], - switch: value.switch, - port: value.uplink_port, - uplink_port_speed: value.uplink_port_speed, - uplink_port_fec: value.uplink_port_fec, - bgp_peers: vec![], - autoneg: false, + impl From for PortConfigV2 { + fn from(v1: PortConfigV1) -> Self { + PortConfigV2 { + routes: v1.routes.clone(), + addresses: v1 + .addresses + .iter() + .map(|a| UplinkAddressConfig { address: *a, vlan_id: None }) + .collect(), + switch: v1.switch, + port: v1.port, + uplink_port_speed: v1.uplink_port_speed, + uplink_port_fec: v1.uplink_port_fec, + bgp_peers: v1.bgp_peers.clone(), + autoneg: v1.autoneg, + } } } -} -/// Deprecated, use `RackNetworkConfig` instead. Cannot actually deprecate due to -/// -/// -/// Our second version of `RackNetworkConfig`. If this exists in the bootstore, -/// we upgrade out of it into `RackNetworkConfigV1` or later versions if -/// possible. -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -struct RackNetworkConfigV1 { - pub rack_subnet: Ipv6Net, - // TODO: #3591 Consider making infra-ip ranges implicit for uplinks - /// First ip address to be used for configuring network infrastructure - pub infra_ip_first: Ipv4Addr, - /// Last ip address to be used for configuring network infrastructure - pub infra_ip_last: Ipv4Addr, - /// Uplinks for connecting the rack to external networks - pub ports: Vec, - /// BGP configurations for connecting the rack to external networks - pub bgp: Vec, - /// BFD configuration for connecting the rack to external networks - #[serde(default)] - pub bfd: Vec, -} + /// Deprecated, use PortConfigV2 instead. Cannot actually deprecate due to + /// + #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] + pub(crate) struct UplinkConfig { + /// Gateway address + pub gateway_ip: Ipv4Addr, + /// Switch to use for uplink + pub switch: SwitchLocation, + /// Switchport to use for external connectivity + pub uplink_port: String, + /// Speed for the Switchport + pub uplink_port_speed: PortSpeed, + /// Forward Error Correction setting for the uplink port + pub uplink_port_fec: PortFec, + /// IP Address and prefix (e.g., `192.168.0.1/16`) to apply to switchport + /// (must be in infra_ip pool) + pub uplink_cidr: Ipv4Net, + /// VLAN id to use for uplink + pub uplink_vid: Option, + } -impl RackNetworkConfigV1 { - /// Convert from `RackNetworkConfigV1` to `RackNetworkConfigV2` + impl From for PortConfigV2 { + fn from(value: UplinkConfig) -> Self { + PortConfigV2 { + routes: vec![RouteConfig { + destination: "0.0.0.0/0".parse().unwrap(), + nexthop: value.gateway_ip.into(), + vlan_id: value.uplink_vid, + }], + addresses: vec![UplinkAddressConfig { + address: value.uplink_cidr.into(), + vlan_id: value.uplink_vid, + }], + switch: value.switch, + port: value.uplink_port, + uplink_port_speed: value.uplink_port_speed, + uplink_port_fec: value.uplink_port_fec, + bgp_peers: vec![], + autoneg: false, + } + } + } + + /// Deprecated, use `RackNetworkConfig` instead. Cannot actually deprecate due to + /// /// - /// We cannot use `From for `RackNetworkConfigV1` - /// because the `rack_subnet` field does not exist in `RackNetworkConfigV0` - /// and must be passed in from the `EarlyNetworkConfigV0` struct which - /// contains the `RackNetworkConfivV0` struct. - pub fn to_v2(v1: RackNetworkConfigV1) -> RackNetworkConfigV2 { - RackNetworkConfigV2 { - rack_subnet: v1.rack_subnet, - infra_ip_first: v1.infra_ip_first, - infra_ip_last: v1.infra_ip_last, - ports: v1 - .ports - .into_iter() - .map(|ports| PortConfigV2::from(ports)) - .collect(), - bgp: v1.bgp.clone(), - bfd: v1.bfd.clone(), + /// Our second version of `RackNetworkConfig`. If this exists in the bootstore, + /// we upgrade out of it into `RackNetworkConfigV1` or later versions if + /// possible. + #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)] + pub struct RackNetworkConfigV1 { + pub rack_subnet: Ipv6Net, + // TODO: #3591 Consider making infra-ip ranges implicit for uplinks + /// First ip address to be used for configuring network infrastructure + pub infra_ip_first: Ipv4Addr, + /// Last ip address to be used for configuring network infrastructure + pub infra_ip_last: Ipv4Addr, + /// Uplinks for connecting the rack to external networks + pub ports: Vec, + /// BGP configurations for connecting the rack to external networks + pub bgp: Vec, + /// BFD configuration for connecting the rack to external networks + #[serde(default)] + pub bfd: Vec, + } + + impl From for RackNetworkConfigV2 { + fn from(v1: RackNetworkConfigV1) -> Self { + RackNetworkConfigV2 { + rack_subnet: v1.rack_subnet, + infra_ip_first: v1.infra_ip_first, + infra_ip_last: v1.infra_ip_last, + ports: v1 + .ports + .into_iter() + .map(|ports| PortConfigV2::from(ports)) + .collect(), + bgp: v1.bgp.clone(), + bfd: v1.bfd.clone(), + } } } + + // The second production version of the `EarlyNetworkConfig`. + // + // If this version is in the bootstore than we need to convert it to + // `EarlyNetworkConfigV2`. + // + // Once we do this for all customers that have initialized racks with the + // old version we can go ahead and remove this type and its conversion code + // altogether. + #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] + pub struct EarlyNetworkConfigV1 { + // The current generation number of data as stored in CRDB. + // The initial generation is set during RSS time and then only mutated + // by Nexus. + pub generation: u64, + + // Which version of the data structure do we have. This is to help with + // deserialization and conversion in future updates. + pub schema_version: u32, + + // The actual configuration details + pub body: EarlyNetworkConfigBodyV1, + } + + // The first production version of the `EarlyNetworkConfig`. + // + // If this version is in the bootstore than we need to convert it to + // `EarlyNetworkConfigV2`. + // + // Once we do this for all customers that have initialized racks with the + // old version we can go ahead and remove this type and its conversion code + // altogether. + #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] + pub(crate) struct EarlyNetworkConfigV0 { + // The current generation number of data as stored in CRDB. + // The initial generation is set during RSS time and then only mutated + // by Nexus. + pub generation: u64, + + pub rack_subnet: Ipv6Addr, + + /// The external NTP server addresses. + pub ntp_servers: Vec, + + // Rack network configuration as delivered from RSS and only existing at + // generation 1 + pub rack_network_config: Option, + } } // The following two conversion functions translate the speed and fec types used @@ -1125,14 +1178,14 @@ mod tests { let logctx = test_setup_log( "serialized_early_network_config_v0_to_v2_conversion", ); - let v0 = EarlyNetworkConfigV0 { + let v0 = back_compat::EarlyNetworkConfigV0 { generation: 1, rack_subnet: Ipv6Addr::UNSPECIFIED, ntp_servers: Vec::new(), - rack_network_config: Some(RackNetworkConfigV0 { + rack_network_config: Some(back_compat::RackNetworkConfigV0 { infra_ip_first: Ipv4Addr::UNSPECIFIED, infra_ip_last: Ipv4Addr::UNSPECIFIED, - uplinks: vec![UplinkConfig { + uplinks: vec![back_compat::UplinkConfig { gateway_ip: Ipv4Addr::UNSPECIFIED, switch: SwitchLocation::Switch0, uplink_port: "Port0".to_string(), @@ -1157,7 +1210,7 @@ mod tests { let uplink = v0_rack_network_config.uplinks[0].clone(); let expected = EarlyNetworkConfig { generation: 1, - schema_version: 2, + schema_version: EarlyNetworkConfig::schema_version(), body: EarlyNetworkConfigBody { ntp_servers: v0.ntp_servers.clone(), rack_network_config: Some(RackNetworkConfigV2 { @@ -1198,17 +1251,17 @@ mod tests { "serialized_early_network_config_v1_to_v2_conversion", ); - let v1 = EarlyNetworkConfigV1 { + let v1 = back_compat::EarlyNetworkConfigV1 { generation: 1, schema_version: 1, - body: EarlyNetworkConfigBodyV1 { + body: back_compat::EarlyNetworkConfigBodyV1 { ntp_servers: Vec::new(), - rack_network_config: Some(RackNetworkConfigV1 { + rack_network_config: Some(back_compat::RackNetworkConfigV1 { rack_subnet: Ipv6Net::new(Ipv6Addr::UNSPECIFIED, 56) .unwrap(), infra_ip_first: Ipv4Addr::UNSPECIFIED, infra_ip_last: Ipv4Addr::UNSPECIFIED, - ports: vec![PortConfigV1 { + ports: vec![back_compat::PortConfigV1 { routes: vec![RouteConfig { destination: "0.0.0.0/0".parse().unwrap(), nexthop: "192.168.0.2".parse().unwrap(), @@ -1241,7 +1294,7 @@ mod tests { let port = v1_rack_network_config.ports[0].clone(); let expected = EarlyNetworkConfig { generation: 1, - schema_version: 2, + schema_version: EarlyNetworkConfig::schema_version(), body: EarlyNetworkConfigBody { ntp_servers: v1.body.ntp_servers.clone(), rack_network_config: Some(RackNetworkConfigV2 { diff --git a/sled-agent/src/bootstrap/params.rs b/sled-agent/src/bootstrap/params.rs index e458900c53..4a5b443dc3 100644 --- a/sled-agent/src/bootstrap/params.rs +++ b/sled-agent/src/bootstrap/params.rs @@ -4,6 +4,7 @@ //! Request types for the bootstrap agent +use crate::bootstrap::early_networking::back_compat::RackNetworkConfigV1; use anyhow::{bail, Result}; use async_trait::async_trait; use omicron_common::address::{self, Ipv6Subnet, SLED_PREFIX}; @@ -28,6 +29,92 @@ pub enum BootstrapAddressDiscovery { OnlyThese { addrs: BTreeSet }, } +/// Structures and routines used to maintain backwards compatibility. The +/// contents of this module should only be used to convert older data into the +/// current format, and not for any ongoing run-time operations. +pub mod back_compat { + use super::*; + + #[derive(Clone, Deserialize)] + struct UnvalidatedRackInitializeRequestV1 { + trust_quorum_peers: Option>, + bootstrap_discovery: BootstrapAddressDiscovery, + ntp_servers: Vec, + dns_servers: Vec, + internal_services_ip_pool_ranges: Vec, + external_dns_ips: Vec, + external_dns_zone_name: String, + external_certificates: Vec, + recovery_silo: RecoverySiloConfig, + rack_network_config: RackNetworkConfigV1, + #[serde(default = "default_allowed_source_ips")] + allowed_source_ips: AllowedSourceIps, + } + + /// This is a deprecated format, maintained to allow importing from older + /// versions. + #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)] + #[serde(try_from = "UnvalidatedRackInitializeRequestV1")] + pub struct RackInitializeRequestV1 { + pub trust_quorum_peers: Option>, + pub bootstrap_discovery: BootstrapAddressDiscovery, + pub ntp_servers: Vec, + pub dns_servers: Vec, + pub internal_services_ip_pool_ranges: Vec, + pub external_dns_ips: Vec, + pub external_dns_zone_name: String, + pub external_certificates: Vec, + pub recovery_silo: RecoverySiloConfig, + pub rack_network_config: RackNetworkConfigV1, + #[serde(default = "default_allowed_source_ips")] + pub allowed_source_ips: AllowedSourceIps, + } + + impl TryFrom for RackInitializeRequestV1 { + type Error = anyhow::Error; + + fn try_from(value: UnvalidatedRackInitializeRequestV1) -> Result { + validate_external_dns( + &value.external_dns_ips, + &value.internal_services_ip_pool_ranges, + )?; + + Ok(RackInitializeRequestV1 { + trust_quorum_peers: value.trust_quorum_peers, + bootstrap_discovery: value.bootstrap_discovery, + ntp_servers: value.ntp_servers, + dns_servers: value.dns_servers, + internal_services_ip_pool_ranges: value + .internal_services_ip_pool_ranges, + external_dns_ips: value.external_dns_ips, + external_dns_zone_name: value.external_dns_zone_name, + external_certificates: value.external_certificates, + recovery_silo: value.recovery_silo, + rack_network_config: value.rack_network_config, + allowed_source_ips: value.allowed_source_ips, + }) + } + } + impl From for RackInitializeRequest { + fn from(v1: RackInitializeRequestV1) -> Self { + RackInitializeRequest { + trust_quorum_peers: v1.trust_quorum_peers, + bootstrap_discovery: v1.bootstrap_discovery, + ntp_servers: v1.ntp_servers, + dns_servers: v1.dns_servers, + internal_services_ip_pool_ranges: v1 + .internal_services_ip_pool_ranges, + external_dns_ips: v1.external_dns_ips, + external_dns_zone_name: v1.external_dns_zone_name, + external_certificates: v1.external_certificates, + recovery_silo: v1.recovery_silo, + rack_network_config: v1.rack_network_config.into(), + allowed_source_ips: v1.allowed_source_ips, + } + } + } +} + // "Shadow" copy of `RackInitializeRequest` that does no validation on its // fields. #[derive(Clone, Deserialize)] @@ -96,6 +183,26 @@ pub struct RackInitializeRequest { pub allowed_source_ips: AllowedSourceIps, } +impl RackInitializeRequest { + pub fn from_toml_with_fallback( + data: &str, + ) -> Result { + let v2_err = match toml::from_str::(&data) { + Ok(req) => return Ok(req), + Err(e) => e, + }; + if let Ok(v1) = + toml::from_str::(&data) + { + return Ok(v1.into()); + } + + // If we fail to parse the request as any known version, we return the + // error corresponding to the parse failure of the newest schema. + Err(v2_err.into()) + } +} + /// This field was added after several racks were already deployed. RSS plans /// for those racks should default to allowing any source IP, since that is /// effectively what they did. @@ -141,29 +248,36 @@ impl std::fmt::Debug for RackInitializeRequest { } } +fn validate_external_dns( + dns_ips: &Vec, + internal_ranges: &Vec, +) -> Result<()> { + if dns_ips.is_empty() { + bail!("At least one external DNS IP is required"); + } + + // Every external DNS IP should also be present in one of the internal + // services IP pool ranges. This check is O(N*M), but we expect both N + // and M to be small (~5 DNS servers, and a small number of pools). + for &dns_ip in dns_ips { + if !internal_ranges.iter().any(|range| range.contains(dns_ip)) { + bail!( + "External DNS IP {dns_ip} is not contained in \ + `internal_services_ip_pool_ranges`" + ); + } + } + Ok(()) +} + impl TryFrom for RackInitializeRequest { type Error = anyhow::Error; fn try_from(value: UnvalidatedRackInitializeRequest) -> Result { - if value.external_dns_ips.is_empty() { - bail!("At least one external DNS IP is required"); - } - - // Every external DNS IP should also be present in one of the internal - // services IP pool ranges. This check is O(N*M), but we expect both N - // and M to be small (~5 DNS servers, and a small number of pools). - for &dns_ip in &value.external_dns_ips { - if !value - .internal_services_ip_pool_ranges - .iter() - .any(|range| range.contains(dns_ip)) - { - bail!( - "External DNS IP {dns_ip} is not contained in \ - `internal_services_ip_pool_ranges`" - ); - } - } + validate_external_dns( + &value.external_dns_ips, + &value.internal_services_ip_pool_ranges, + )?; Ok(RackInitializeRequest { trust_quorum_peers: value.trust_quorum_peers, diff --git a/sled-agent/src/config.rs b/sled-agent/src/config.rs index c4ce421497..ac9b61f3bb 100644 --- a/sled-agent/src/config.rs +++ b/sled-agent/src/config.rs @@ -115,7 +115,7 @@ pub enum ConfigError { Parse { path: Utf8PathBuf, #[source] - err: toml::de::Error, + err: anyhow::Error, }, #[error("Loading certificate: {0}")] Certificate(#[source] anyhow::Error), @@ -130,8 +130,9 @@ impl Config { let path = path.as_ref(); let contents = std::fs::read_to_string(&path) .map_err(|err| ConfigError::Io { path: path.into(), err })?; - let config = toml::from_str(&contents) - .map_err(|err| ConfigError::Parse { path: path.into(), err })?; + let config = toml::from_str(&contents).map_err(|err| { + ConfigError::Parse { path: path.into(), err: err.into() } + })?; Ok(config) } diff --git a/sled-agent/src/rack_setup/config.rs b/sled-agent/src/rack_setup/config.rs index e52ed14304..43664cfd04 100644 --- a/sled-agent/src/rack_setup/config.rs +++ b/sled-agent/src/rack_setup/config.rs @@ -10,6 +10,7 @@ use omicron_common::address::{ get_64_subnet, Ipv6Subnet, AZ_PREFIX, RACK_PREFIX, SLED_PREFIX, }; +pub use crate::bootstrap::params::back_compat::RackInitializeRequestV1 as SetupServiceConfigV1; use crate::bootstrap::params::Certificate; pub use crate::bootstrap::params::RackInitializeRequest as SetupServiceConfig; @@ -18,8 +19,9 @@ impl SetupServiceConfig { let path = path.as_ref(); let contents = std::fs::read_to_string(&path) .map_err(|err| ConfigError::Io { path: path.into(), err })?; - let mut raw_config: SetupServiceConfig = toml::from_str(&contents) - .map_err(|err| ConfigError::Parse { path: path.into(), err })?; + let mut raw_config = + SetupServiceConfig::from_toml_with_fallback(&contents) + .map_err(|err| ConfigError::Parse { path: path.into(), err })?; // In the same way that sled-agent itself (our caller) discovers the // optional config-rss.toml in a well-known path relative to its config diff --git a/sled-agent/src/rack_setup/plan/sled.rs b/sled-agent/src/rack_setup/plan/sled.rs index a3fd57369a..c6d2e73ccd 100644 --- a/sled-agent/src/rack_setup/plan/sled.rs +++ b/sled-agent/src/rack_setup/plan/sled.rs @@ -9,6 +9,7 @@ use crate::bootstrap::{ config::BOOTSTRAP_AGENT_RACK_INIT_PORT, params::StartSledAgentRequest, }; use crate::rack_setup::config::SetupServiceConfig as Config; +use crate::rack_setup::config::SetupServiceConfigV1 as ConfigV1; use camino::Utf8PathBuf; use omicron_common::ledger::{self, Ledger, Ledgerable}; use schemars::JsonSchema; @@ -18,6 +19,7 @@ use sled_storage::manager::StorageHandle; use slog::Logger; use std::collections::{BTreeMap, BTreeSet}; use std::net::{Ipv6Addr, SocketAddrV6}; +use std::str::FromStr; use thiserror::Error; use uuid::Uuid; @@ -43,7 +45,7 @@ impl Ledgerable for Plan { } const RSS_SLED_PLAN_FILENAME: &str = "rss-sled-plan.json"; -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] pub struct Plan { pub rack_id: Uuid, pub sleds: BTreeMap, @@ -53,6 +55,42 @@ pub struct Plan { pub config: Config, } +impl FromStr for Plan { + type Err = String; + + fn from_str(value: &str) -> Result { + #[derive(Deserialize)] + struct ShadowPlan { + pub rack_id: Uuid, + pub sleds: BTreeMap, + pub config: Config, + } + #[derive(Deserialize)] + struct ShadowPlanV1 { + pub rack_id: Uuid, + pub sleds: BTreeMap, + pub config: ConfigV1, + } + let v2_err = match serde_json::from_str::(&value) { + Ok(plan) => { + return Ok(Plan { + rack_id: plan.rack_id, + sleds: plan.sleds, + config: plan.config, + }) + } + Err(e) => format!("unable to parse Plan: {e:?}"), + }; + serde_json::from_str::(&value) + .map(|v1| Plan { + rack_id: v1.rack_id, + sleds: v1.sleds, + config: v1.config.into(), + }) + .map_err(|_| v2_err) + } +} + impl Plan { pub async fn load( log: &Logger, @@ -164,8 +202,8 @@ mod tests { let contents = std::fs::read_to_string(path.join(sled_plan_basename)) .expect("failed to read file"); - let parsed: Plan = - serde_json::from_str(&contents).expect("failed to parse file"); + let parsed = + Plan::from_str(&contents).expect("failed to parse file"); expectorate::assert_contents( out_path.join(sled_plan_basename), &serde_json::to_string_pretty(&parsed).unwrap(), diff --git a/sled-agent/tests/data/early_network_blobs.txt b/sled-agent/tests/data/early_network_blobs.txt index e9b9927e86..c968d4010b 100644 --- a/sled-agent/tests/data/early_network_blobs.txt +++ b/sled-agent/tests/data/early_network_blobs.txt @@ -1,2 +1,2 @@ -2023-11-30 mupdate failing blob,{"generation":15,"schema_version":1,"body":{"ntp_servers":[],"rack_network_config":{"rack_subnet":"fd00:1122:3344:100::/56","infra_ip_first":"0.0.0.0","infra_ip_last":"0.0.0.0","ports":[{"routes":[],"addresses":[],"switch":"switch1","port":"qsfp0","uplink_port_speed":"speed100_g","uplink_port_fec":"none","bgp_peers":[]},{"routes":[],"addresses":[{"address":"172.20.15.53/29"}],"switch":"switch1","port":"qsfp18","uplink_port_speed":"speed100_g","uplink_port_fec":"rs","bgp_peers":[{"asn":65002,"port":"qsfp18","addr":"172.20.15.51","hold_time":6,"idle_hold_time":6,"delay_open":0,"connect_retry":3,"keepalive":2}]},{"routes":[],"addresses":[{"address":"172.20.15.45/29"}],"switch":"switch0","port":"qsfp18","uplink_port_speed":"speed100_g","uplink_port_fec":"rs","bgp_peers":[{"asn":65002,"port":"qsfp18","addr":"172.20.15.43","hold_time":6,"idle_hold_time":6,"delay_open":0,"connect_retry":3,"keepalive":2}]},{"routes":[],"addresses":[],"switch":"switch0","port":"qsfp0","uplink_port_speed":"speed100_g","uplink_port_fec":"none","bgp_peers":[]}],"bgp":[{"asn":65002,"originate":["172.20.26.0/24"]},{"asn":65002,"originate":["172.20.26.0/24"]}]}}} -2023-12-06 config,{"generation":20,"schema_version":1,"body":{"ntp_servers":["ntp.example.com"],"rack_network_config":{"rack_subnet":"ff01::/32","infra_ip_first":"127.0.0.1","infra_ip_last":"127.1.0.1","ports":[{"routes":[{"destination":"10.1.9.32/16","nexthop":"10.1.9.32"}],"addresses":[{"address":"2001:db8::/96"}],"switch":"switch0","port":"foo","uplink_port_speed":"speed200_g","uplink_port_fec":"firecode","bgp_peers":[{"asn":65000,"port":"bar","addr":"1.2.3.4","hold_time":20,"idle_hold_time":50,"delay_open":null,"connect_retry":30,"keepalive":10}],"autoneg":true}],"bgp":[{"asn":20000,"originate":["192.168.0.0/24"]}]}}} +2023-11-30 mupdate failing blob,{"generation":15,"schema_version":1,"body":{"ntp_servers":[],"rack_network_config":{"rack_subnet":"fd00:1122:3344:100::/56","infra_ip_first":"0.0.0.0","infra_ip_last":"0.0.0.0","ports":[{"routes":[],"addresses":[],"switch":"switch1","port":"qsfp0","uplink_port_speed":"speed100_g","uplink_port_fec":"none","bgp_peers":[]},{"routes":[],"addresses":["172.20.15.53/29"],"switch":"switch1","port":"qsfp18","uplink_port_speed":"speed100_g","uplink_port_fec":"rs","bgp_peers":[{"asn":65002,"port":"qsfp18","addr":"172.20.15.51","hold_time":6,"idle_hold_time":6,"delay_open":0,"connect_retry":3,"keepalive":2}]},{"routes":[],"addresses":["172.20.15.45/29"],"switch":"switch0","port":"qsfp18","uplink_port_speed":"speed100_g","uplink_port_fec":"rs","bgp_peers":[{"asn":65002,"port":"qsfp18","addr":"172.20.15.43","hold_time":6,"idle_hold_time":6,"delay_open":0,"connect_retry":3,"keepalive":2}]},{"routes":[],"addresses":[],"switch":"switch0","port":"qsfp0","uplink_port_speed":"speed100_g","uplink_port_fec":"none","bgp_peers":[]}],"bgp":[{"asn":65002,"originate":["172.20.26.0/24"]},{"asn":65002,"originate":["172.20.26.0/24"]}]}}} +2023-12-06 config,{"generation":20,"schema_version":1,"body":{"ntp_servers":["ntp.example.com"],"rack_network_config":{"rack_subnet":"ff01::/32","infra_ip_first":"127.0.0.1","infra_ip_last":"127.1.0.1","ports":[{"routes":[{"destination":"10.1.9.32/16","nexthop":"10.1.9.32"}],"addresses":["2001:db8::/96"],"switch":"switch0","port":"foo","uplink_port_speed":"speed200_g","uplink_port_fec":"firecode","bgp_peers":[{"asn":65000,"port":"bar","addr":"1.2.3.4","hold_time":20,"idle_hold_time":50,"delay_open":null,"connect_retry":30,"keepalive":10}],"autoneg":true}],"bgp":[{"asn":20000,"originate":["192.168.0.0/24"]}]}}} diff --git a/sled-agent/tests/integration_tests/early_network.rs b/sled-agent/tests/integration_tests/early_network.rs index b7cab53a51..28fc0fd010 100644 --- a/sled-agent/tests/integration_tests/early_network.rs +++ b/sled-agent/tests/integration_tests/early_network.rs @@ -5,6 +5,7 @@ //! Tests that EarlyNetworkConfig deserializes across versions. use std::net::Ipv4Addr; +use std::str::FromStr; use bootstore::schemes::v0 as bootstore; use omicron_common::api::{ @@ -48,8 +49,8 @@ fn early_network_blobs_deserialize() { }); // Attempt to deserialize this blob. - let config = serde_json::from_str::(blob_json) - .unwrap_or_else(|error| { + let config = + EarlyNetworkConfig::from_str(blob_json).unwrap_or_else(|error| { panic!( "error deserializing early_network_blobs.txt \ \"{blob_desc}\" (line {blob_lineno}): {error}", @@ -113,7 +114,7 @@ fn current_config_example() -> (&'static str, EarlyNetworkConfig) { let description = "2023-12-06 config"; let config = EarlyNetworkConfig { generation: 20, - schema_version: 1, + schema_version: EarlyNetworkConfig::schema_version(), body: EarlyNetworkConfigBody { ntp_servers: vec!["ntp.example.com".to_owned()], rack_network_config: Some(RackNetworkConfig { diff --git a/sled-agent/tests/old-rss-sled-plans/madrid-rss-sled-plan.json b/sled-agent/tests/old-rss-sled-plans/madrid-rss-sled-plan.json index 683e8fb833..5512247ee8 100644 --- a/sled-agent/tests/old-rss-sled-plans/madrid-rss-sled-plan.json +++ b/sled-agent/tests/old-rss-sled-plans/madrid-rss-sled-plan.json @@ -1 +1 @@ -{"rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","sleds":{"[fdb0:a840:2504:396::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"b3e78a88-0f2e-476e-a8a9-2d8c90a169d6","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:103::/64"}}},"[fdb0:a840:2504:157::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"168e1ad6-1e4b-4f7a-b894-157974bd8bb8","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:104::/64"}}},"[fdb0:a840:2504:355::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"b9877212-212b-4588-b818-9c7b53c5b143","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:102::/64"}}},"[fdb0:a840:2504:3d2::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"c3a0f8be-5b05-4ee8-8c4e-2514de6501b6","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:101::/64"}}}},"config":{"rack_subnet":"fd00:1122:3344:100::","trust_quorum_peers":[{"type":"gimlet","identifier":"BRM42220081","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM42220046","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM44220001","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM42220004","model":"913-0000019","revision":6}],"bootstrap_discovery":{"type":"only_these","addrs":["fdb0:a840:2504:3d2::1","fdb0:a840:2504:355::1","fdb0:a840:2504:396::1","fdb0:a840:2504:157::1"]},"ntp_servers":["ntp.eng.oxide.computer"],"dns_servers":["1.1.1.1","9.9.9.9"],"internal_services_ip_pool_ranges":[{"first":"172.20.28.1","last":"172.20.28.10"}],"external_dns_ips":["172.20.28.1"],"external_dns_zone_name":"madrid.eng.oxide.computer","external_certificates":[{"cert":"","key":""}],"recovery_silo":{"silo_name":"recovery","user_name":"recovery","user_password_hash":"$argon2id$v=19$m=98304,t=13,p=1$RUlWc0ZxaHo0WFdrN0N6ZQ$S8p52j85GPvMhR/ek3GL0el/oProgTwWpHJZ8lsQQoY"},"rack_network_config":{"rack_subnet":"fd00:1122:3344:1::/56","infra_ip_first":"172.20.15.37","infra_ip_last":"172.20.15.38","ports":[{"routes":[{"destination":"0.0.0.0/0","nexthop":"172.20.15.33"}],"addresses":[{"address":"172.20.15.38/29"}],"switch":"switch0","port":"qsfp0","uplink_port_speed":"speed40_g","uplink_port_fec":"none","bgp_peers":[],"autoneg":false},{"routes":[{"destination":"0.0.0.0/0","nexthop":"172.20.15.33"}],"addresses":[{"address":"172.20.15.37/29"}],"switch":"switch1","port":"qsfp0","uplink_port_speed":"speed40_g","uplink_port_fec":"none","bgp_peers":[],"autoneg":false}],"bgp":[]}}} +{"rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","sleds":{"[fdb0:a840:2504:396::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"b3e78a88-0f2e-476e-a8a9-2d8c90a169d6","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:103::/64"}}},"[fdb0:a840:2504:157::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"168e1ad6-1e4b-4f7a-b894-157974bd8bb8","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:104::/64"}}},"[fdb0:a840:2504:355::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"b9877212-212b-4588-b818-9c7b53c5b143","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:102::/64"}}},"[fdb0:a840:2504:3d2::1]:12346":{"generation":0,"schema_version":1,"body":{"id":"c3a0f8be-5b05-4ee8-8c4e-2514de6501b6","rack_id":"ed6bcf59-9620-491d-8ebd-4a4eebf2e136","use_trust_quorum":true,"is_lrtq_learner":false,"subnet":{"net":"fd00:1122:3344:101::/64"}}}},"config":{"rack_subnet":"fd00:1122:3344:100::","trust_quorum_peers":[{"type":"gimlet","identifier":"BRM42220081","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM42220046","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM44220001","model":"913-0000019","revision":6},{"type":"gimlet","identifier":"BRM42220004","model":"913-0000019","revision":6}],"bootstrap_discovery":{"type":"only_these","addrs":["fdb0:a840:2504:3d2::1","fdb0:a840:2504:355::1","fdb0:a840:2504:396::1","fdb0:a840:2504:157::1"]},"ntp_servers":["ntp.eng.oxide.computer"],"dns_servers":["1.1.1.1","9.9.9.9"],"internal_services_ip_pool_ranges":[{"first":"172.20.28.1","last":"172.20.28.10"}],"external_dns_ips":["172.20.28.1"],"external_dns_zone_name":"madrid.eng.oxide.computer","external_certificates":[{"cert":"","key":""}],"recovery_silo":{"silo_name":"recovery","user_name":"recovery","user_password_hash":"$argon2id$v=19$m=98304,t=13,p=1$RUlWc0ZxaHo0WFdrN0N6ZQ$S8p52j85GPvMhR/ek3GL0el/oProgTwWpHJZ8lsQQoY"},"rack_network_config":{"rack_subnet":"fd00:1122:3344:1::/56","infra_ip_first":"172.20.15.37","infra_ip_last":"172.20.15.38","ports":[{"routes":[{"destination":"0.0.0.0/0","nexthop":"172.20.15.33"}],"addresses":["172.20.15.38/29"],"switch":"switch0","port":"qsfp0","uplink_port_speed":"speed40_g","uplink_port_fec":"none","bgp_peers":[],"autoneg":false},{"routes":[{"destination":"0.0.0.0/0","nexthop":"172.20.15.33"}],"addresses":["172.20.15.37/29"],"switch":"switch1","port":"qsfp0","uplink_port_speed":"speed40_g","uplink_port_fec":"none","bgp_peers":[],"autoneg":false}],"bgp":[]}}} From 754fcd04f58e063373d07fc06b85def8a7fb2c0a Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 18 Jun 2024 09:22:56 -0700 Subject: [PATCH 05/26] Fix clippy::needless_update lint (#5907) This lint was introduced while merging #5980. Because the `updater_id` and `updater_gen` fields are no longer part of `InstanceRuntimeState`, the struct update syntax now doesn't provide any fields and Clippy asks us to remove it. --- nexus/db-queries/src/db/datastore/instance.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/nexus/db-queries/src/db/datastore/instance.rs b/nexus/db-queries/src/db/datastore/instance.rs index f4b31b24ff..0abe491213 100644 --- a/nexus/db-queries/src/db/datastore/instance.rs +++ b/nexus/db-queries/src/db/datastore/instance.rs @@ -1359,7 +1359,6 @@ mod tests { propolis_id: Some(active_vmm.id), dst_propolis_id: Some(target_vmm.id), migration_id: Some(migration.id), - ..snapshot.instance.runtime_state.clone() }, ) .await From 7fb6cb47c7b194b7088744ede0572d5e5be703a6 Mon Sep 17 00:00:00 2001 From: Greg Colombo Date: Tue, 18 Jun 2024 12:49:58 -0700 Subject: [PATCH 06/26] pick up Propolis 50cb28f5 (#5906) Update to Propolis commit 50cb28f5 to obtain the following updates: ``` 50cb28f server: separate statuses of inbound and outbound migrations (#661) 61e1481 Don't return None from BlockData::block_for_req when attachment is paused (#711) 79e243b Build and clippy fixes for Rust 1.79 (#712) 3c0f998 Modernize fw_cfg emulation 7a65be9 Update and prune dependencies ``` 50cb28f5 changes the Propolis instance status and migration status APIs to report both inbound and outbound migration status. Update sled agent accordingly. Tests: `cargo nextest`, smoke test on a dev cluster. --- Cargo.lock | 24 ++++----- Cargo.toml | 6 +-- package-manifest.toml | 4 +- sled-agent/src/common/instance.rs | 87 +++++++++++++++++-------------- sled-agent/src/sim/instance.rs | 64 ++++++++++++++++------- 5 files changed, 108 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5949144ab5..8e1d3ca90c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -464,9 +464,9 @@ dependencies = [ [[package]] name = "bhyve_api" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76#6d7ed9a033babc054db9eff5b59dee978d2b0d76" +source = "git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753#50cb28f586083fdb990e401bc6146e7dac9b2753" dependencies = [ - "bhyve_api_sys 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76)", + "bhyve_api_sys 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753)", "libc", "strum", ] @@ -484,7 +484,7 @@ dependencies = [ [[package]] name = "bhyve_api_sys" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76#6d7ed9a033babc054db9eff5b59dee978d2b0d76" +source = "git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753#50cb28f586083fdb990e401bc6146e7dac9b2753" dependencies = [ "libc", "strum", @@ -3471,7 +3471,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "bhyve_api 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76)", + "bhyve_api 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753)", "byteorder", "camino", "camino-tempfile", @@ -5526,7 +5526,7 @@ dependencies = [ "pq-sys", "pretty_assertions", "progenitor-client", - "propolis-client 0.1.0 (git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76)", + "propolis-client 0.1.0 (git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753)", "rand 0.8.5", "rcgen", "ref-cast", @@ -5776,7 +5776,7 @@ dependencies = [ "oximeter-producer", "oxnet", "pretty_assertions", - "propolis-client 0.1.0 (git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76)", + "propolis-client 0.1.0 (git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753)", "propolis-mock-server", "rand 0.8.5", "rcgen", @@ -7207,7 +7207,7 @@ dependencies = [ [[package]] name = "propolis-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76#6d7ed9a033babc054db9eff5b59dee978d2b0d76" +source = "git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753#50cb28f586083fdb990e401bc6146e7dac9b2753" dependencies = [ "async-trait", "base64 0.21.7", @@ -7221,7 +7221,7 @@ dependencies = [ "slog", "thiserror", "tokio", - "tokio-tungstenite 0.20.1", + "tokio-tungstenite 0.21.0", "uuid", ] @@ -7249,7 +7249,7 @@ dependencies = [ [[package]] name = "propolis-mock-server" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76#6d7ed9a033babc054db9eff5b59dee978d2b0d76" +source = "git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753#50cb28f586083fdb990e401bc6146e7dac9b2753" dependencies = [ "anyhow", "atty", @@ -7259,7 +7259,7 @@ dependencies = [ "futures", "hyper 0.14.28", "progenitor", - "propolis_types 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76)", + "propolis_types 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753)", "rand 0.8.5", "reqwest", "schemars", @@ -7272,7 +7272,7 @@ dependencies = [ "slog-term", "thiserror", "tokio", - "tokio-tungstenite 0.20.1", + "tokio-tungstenite 0.21.0", "uuid", ] @@ -7291,7 +7291,7 @@ dependencies = [ [[package]] name = "propolis_types" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis?rev=6d7ed9a033babc054db9eff5b59dee978d2b0d76#6d7ed9a033babc054db9eff5b59dee978d2b0d76" +source = "git+https://github.com/oxidecomputer/propolis?rev=50cb28f586083fdb990e401bc6146e7dac9b2753#50cb28f586083fdb990e401bc6146e7dac9b2753" dependencies = [ "schemars", "serde", diff --git a/Cargo.toml b/Cargo.toml index d461e0585a..69269a1de4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -394,9 +394,9 @@ prettyplease = { version = "0.2.20", features = ["verbatim"] } proc-macro2 = "1.0" progenitor = { git = "https://github.com/oxidecomputer/progenitor", branch = "main" } progenitor-client = { git = "https://github.com/oxidecomputer/progenitor", branch = "main" } -bhyve_api = { git = "https://github.com/oxidecomputer/propolis", rev = "6d7ed9a033babc054db9eff5b59dee978d2b0d76" } -propolis-client = { git = "https://github.com/oxidecomputer/propolis", rev = "6d7ed9a033babc054db9eff5b59dee978d2b0d76" } -propolis-mock-server = { git = "https://github.com/oxidecomputer/propolis", rev = "6d7ed9a033babc054db9eff5b59dee978d2b0d76" } +bhyve_api = { git = "https://github.com/oxidecomputer/propolis", rev = "50cb28f586083fdb990e401bc6146e7dac9b2753" } +propolis-client = { git = "https://github.com/oxidecomputer/propolis", rev = "50cb28f586083fdb990e401bc6146e7dac9b2753" } +propolis-mock-server = { git = "https://github.com/oxidecomputer/propolis", rev = "50cb28f586083fdb990e401bc6146e7dac9b2753" } proptest = "1.4.0" quote = "1.0" rand = "0.8.5" diff --git a/package-manifest.toml b/package-manifest.toml index 8e27588be3..27a5397bf1 100644 --- a/package-manifest.toml +++ b/package-manifest.toml @@ -532,10 +532,10 @@ service_name = "propolis-server" only_for_targets.image = "standard" source.type = "prebuilt" source.repo = "propolis" -source.commit = "6d7ed9a033babc054db9eff5b59dee978d2b0d76" +source.commit = "50cb28f586083fdb990e401bc6146e7dac9b2753" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/propolis/image//propolis-server.sha256.txt -source.sha256 = "f8f41b47bc00811fefe2ba75e0f6f8ab77765776c04021e0b31f09c3b21108a9" +source.sha256 = "864e74222d3e617f1bd7b7ba8d0e5cc18134dca121fc4339369620d1419c5bb0" output.type = "zone" [package.mg-ddm-gz] diff --git a/sled-agent/src/common/instance.rs b/sled-agent/src/common/instance.rs index 02623455f4..ed0aceff82 100644 --- a/sled-agent/src/common/instance.rs +++ b/sled-agent/src/common/instance.rs @@ -117,50 +117,57 @@ impl ObservedPropolisState { instance_runtime: &InstanceRuntimeState, propolis_state: &InstanceStateMonitorResponse, ) -> Self { - let migration_status = - match (instance_runtime.migration_id, &propolis_state.migration) { - // If the runtime state and Propolis state agree that there's - // a migration in progress, and they agree on its ID, the - // Propolis migration state determines the migration status. - (Some(this_id), Some(propolis_migration)) - if this_id == propolis_migration.migration_id => - { - match propolis_migration.state { - PropolisMigrationState::Finish => { - ObservedMigrationStatus::Succeeded - } - PropolisMigrationState::Error => { - ObservedMigrationStatus::Failed - } - _ => ObservedMigrationStatus::InProgress, - } - } - - // If both sides have a migration ID, but the IDs don't match, - // assume the instance's migration ID is newer. This can happen - // if Propolis was initialized via migration in and has not yet - // been told to migrate out. - (Some(_), Some(_)) => ObservedMigrationStatus::Pending, - - // If only Propolis has a migration ID, assume it was from a - // prior migration in and report that no migration is in - // progress. This could be improved with propolis#508. - (None, Some(_)) => ObservedMigrationStatus::NoMigration, - - // A migration source's migration IDs get set before its - // Propolis actually gets asked to migrate, so it's possible for - // the runtime state to contain an ID while the Propolis has - // none, in which case the migration is pending. - (Some(_), None) => ObservedMigrationStatus::Pending, - - // If neither side has a migration ID, then there's clearly no - // migration. - (None, None) => ObservedMigrationStatus::NoMigration, + // If there's no migration currently registered with this sled, report + // the current state and that no migration is currently in progress, + // even if Propolis has some migration data to share. (This case arises + // when Propolis returns state from a previous migration that sled agent + // has already retired.) + // + // N.B. This needs to be read from the instance runtime state and not + // the migration runtime state to ensure that, once a migration in + // completes, the "completed" observation is reported to + // `InstanceStates::apply_propolis_observation` exactly once. + // Otherwise that routine will try to apply the "inbound migration + // complete" instance state transition twice. + let Some(migration_id) = instance_runtime.migration_id else { + return Self { + vmm_state: PropolisInstanceState(propolis_state.state), + migration_status: ObservedMigrationStatus::NoMigration, + time: Utc::now(), }; + }; + + // Sled agent believes a live migration may be in progress. See if + // either of the Propolis migrations corresponds to it. + let propolis_migration = match ( + &propolis_state.migration.migration_in, + &propolis_state.migration.migration_out, + ) { + (Some(inbound), _) if inbound.id == migration_id => inbound, + (_, Some(outbound)) if outbound.id == migration_id => outbound, + _ => { + // Sled agent believes this instance should be migrating, but + // Propolis isn't reporting a matching migration yet, so assume + // the migration is still pending. + return Self { + vmm_state: PropolisInstanceState(propolis_state.state), + migration_status: ObservedMigrationStatus::Pending, + time: Utc::now(), + }; + } + }; Self { vmm_state: PropolisInstanceState(propolis_state.state), - migration_status, + migration_status: match propolis_migration.state { + PropolisMigrationState::Finish => { + ObservedMigrationStatus::Succeeded + } + PropolisMigrationState::Error => { + ObservedMigrationStatus::Failed + } + _ => ObservedMigrationStatus::InProgress, + }, time: Utc::now(), } } diff --git a/sled-agent/src/sim/instance.rs b/sled-agent/src/sim/instance.rs index 2ac8618399..06739df8fa 100644 --- a/sled-agent/src/sim/instance.rs +++ b/sled-agent/src/sim/instance.rs @@ -19,7 +19,8 @@ use omicron_common::api::internal::nexus::{ InstanceRuntimeState, MigrationRole, SledInstanceState, VmmState, }; use propolis_client::types::{ - InstanceMigrateStatusResponse as PropolisMigrateStatus, + InstanceMigrateStatusResponse as PropolisMigrateResponse, + InstanceMigrationStatus as PropolisMigrationStatus, InstanceState as PropolisInstanceState, InstanceStateMonitorResponse, }; use std::collections::VecDeque; @@ -32,7 +33,7 @@ use crate::common::instance::{Action as InstanceAction, InstanceStates}; #[derive(Clone, Debug)] enum MonitorChange { PropolisState(PropolisInstanceState), - MigrateStatus(PropolisMigrateStatus), + MigrateStatus(PropolisMigrateResponse), } /// A simulation of an Instance created by the external Oxide API. @@ -70,10 +71,10 @@ impl SimInstanceInner { self.queue.push_back(MonitorChange::PropolisState(propolis_state)); } - /// Pushes a Propolis migration status to the state change queue. - fn queue_migration_status( + /// Pushes a Propolis migration update to the state change queue. + fn queue_migration_update( &mut self, - migrate_status: PropolisMigrateStatus, + migrate_status: PropolisMigrateResponse, ) { self.queue.push_back(MonitorChange::MigrateStatus(migrate_status)) } @@ -92,22 +93,42 @@ impl SimInstanceInner { self ) }); - self.queue_migration_status(PropolisMigrateStatus { - migration_id, - state: propolis_client::types::MigrationState::Sync, - }); - self.queue_migration_status(PropolisMigrateStatus { - migration_id, - state: propolis_client::types::MigrationState::Finish, - }); - - // The state we transition to after the migration completes will depend - // on whether we are the source or destination. + match role { + MigrationRole::Source => { + self.queue_migration_update(PropolisMigrateResponse { + migration_in: None, + migration_out: Some(PropolisMigrationStatus { + id: migration_id, + state: propolis_client::types::MigrationState::Sync, + }), + }); + self.queue_migration_update(PropolisMigrateResponse { + migration_in: None, + migration_out: Some(PropolisMigrationStatus { + id: migration_id, + state: propolis_client::types::MigrationState::Finish, + }), + }); + self.queue_graceful_stop(); + } MigrationRole::Target => { + self.queue_migration_update(PropolisMigrateResponse { + migration_in: Some(PropolisMigrationStatus { + id: migration_id, + state: propolis_client::types::MigrationState::Sync, + }), + migration_out: None, + }); + self.queue_migration_update(PropolisMigrateResponse { + migration_in: Some(PropolisMigrationStatus { + id: migration_id, + state: propolis_client::types::MigrationState::Finish, + }), + migration_out: None, + }); self.queue_propolis_state(PropolisInstanceState::Running) } - MigrationRole::Source => self.queue_graceful_stop(), } } @@ -252,12 +273,12 @@ impl SimInstanceInner { self.last_response.state = state; } MonitorChange::MigrateStatus(status) => { - self.last_response.migration = Some(status); + self.last_response.migration = status; } } self.state.apply_propolis_observation(&ObservedPropolisState::new( - &self.state.instance(), + self.state.instance(), &self.last_response, )) } else { @@ -450,7 +471,10 @@ impl Simulatable for SimInstance { last_response: InstanceStateMonitorResponse { gen: 1, state: PropolisInstanceState::Starting, - migration: None, + migration: PropolisMigrateResponse { + migration_in: None, + migration_out: None, + }, }, queue: VecDeque::new(), destroyed: false, From 75f5b67c9974eb614d4253562e0cfbb9e79df281 Mon Sep 17 00:00:00 2001 From: David Crespo Date: Wed, 19 Jun 2024 14:45:46 -0500 Subject: [PATCH 07/26] 400 instead of 500 on duplicate firewall rule names (#5913) Closes #5725 This does the check in a helper function in the model file, which feels appropriate. I wasn't sure about raising external API validation errors from the model file, but we do that in a bunch of places: ```console $ rg 'external::Error' nexus/db-model nexus/db-model/src/allow_list.rs 17:use omicron_common::api::external::Error; nexus/db-model/src/role_assignment.rs 9:use omicron_common::api::external::Error; nexus/db-model/src/ipv6.rs 17:use omicron_common::api::external::Error; nexus/db-model/src/saga_types.rs 21:use omicron_common::api::external::Error; nexus/db-model/src/vpc_subnet.rs 76: ) -> Result<(), external::Error> { 81: .map_err(|e| external::Error::invalid_request(e.to_string())) ... there were a bunch more ``` --- nexus/db-model/src/vpc_firewall_rule.rs | 34 +++++++++- nexus/src/app/vpc.rs | 5 +- nexus/tests/integration_tests/vpc_firewall.rs | 67 +++++++++++++------ 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/nexus/db-model/src/vpc_firewall_rule.rs b/nexus/db-model/src/vpc_firewall_rule.rs index 2d19796524..120d3e1473 100644 --- a/nexus/db-model/src/vpc_firewall_rule.rs +++ b/nexus/db-model/src/vpc_firewall_rule.rs @@ -14,6 +14,7 @@ use nexus_types::identity::Resource; use omicron_common::api::external; use serde::Deserialize; use serde::Serialize; +use std::collections::HashSet; use std::io::Write; use uuid::Uuid; @@ -253,15 +254,42 @@ impl VpcFirewallRule { pub fn vec_from_params( vpc_id: Uuid, params: external::VpcFirewallRuleUpdateParams, - ) -> Vec { - params + ) -> Result, external::Error> { + ensure_no_duplicates(¶ms)?; + Ok(params .rules .iter() .map(|rule| VpcFirewallRule::new(Uuid::new_v4(), vpc_id, rule)) - .collect() + .collect()) } } +fn ensure_no_duplicates( + params: &external::VpcFirewallRuleUpdateParams, +) -> Result<(), external::Error> { + // we could do this by comparing set(names).len() to names.len(), but this + // way we can say what the duplicate names are, and that's nice! + let mut names = HashSet::new(); + let mut dupes = HashSet::new(); + for r in params.rules.iter() { + if !names.insert(r.name.clone()) { + // insert returns false if already present + dupes.insert(r.name.clone()); + } + } + + if dupes.is_empty() { + return Ok(()); + } + + let dupes_str = + dupes.iter().map(|d| format!("\"{d}\"")).collect::>().join(", "); + return Err(external::Error::invalid_value( + "rules", + format!("Rule names must be unique. Duplicates: [{}]", dupes_str), + )); +} + impl Into for VpcFirewallRule { fn into(self) -> external::VpcFirewallRule { external::VpcFirewallRule { diff --git a/nexus/src/app/vpc.rs b/nexus/src/app/vpc.rs index 0950e65b83..09d402a940 100644 --- a/nexus/src/app/vpc.rs +++ b/nexus/src/app/vpc.rs @@ -179,7 +179,8 @@ impl super::Nexus { let rules = db::model::VpcFirewallRule::vec_from_params( authz_vpc.id(), params.clone(), - ); + )?; + let rules = self .db_datastore .vpc_update_firewall_rules(opctx, &authz_vpc, rules) @@ -199,7 +200,7 @@ impl super::Nexus { let mut rules = db::model::VpcFirewallRule::vec_from_params( vpc_id, defaults::DEFAULT_FIREWALL_RULES.clone(), - ); + )?; for rule in rules.iter_mut() { for target in rule.targets.iter_mut() { match target.0 { diff --git a/nexus/tests/integration_tests/vpc_firewall.rs b/nexus/tests/integration_tests/vpc_firewall.rs index a62019288d..83379bef88 100644 --- a/nexus/tests/integration_tests/vpc_firewall.rs +++ b/nexus/tests/integration_tests/vpc_firewall.rs @@ -5,7 +5,9 @@ use http::method::Method; use http::StatusCode; use nexus_test_utils::http_testing::{AuthnMode, NexusRequest}; -use nexus_test_utils::resource_helpers::{create_project, create_vpc}; +use nexus_test_utils::resource_helpers::{ + create_project, create_vpc, object_get, object_put_error, +}; use nexus_test_utils_macros::nexus_test; use nexus_types::external_api::views::Vpc; use omicron_common::api::external::{ @@ -42,7 +44,9 @@ async fn test_vpc_firewall(cptestctx: &ControlPlaneTestContext) { let default_vpc_firewall = format!("/v1/vpc-firewall-rules?vpc=default&{}", project_selector,); - let rules = get_rules(client, &default_vpc_firewall).await; + let rules = object_get::(client, &default_vpc_firewall) + .await + .rules; assert!(rules.iter().all(|r| r.vpc_id == default_vpc.identity.id)); assert!(is_default_firewall_rules("default", &rules)); @@ -52,7 +56,8 @@ async fn test_vpc_firewall(cptestctx: &ControlPlaneTestContext) { let other_vpc_firewall = format!("/v1/vpc-firewall-rules?{}", other_vpc_selector); let vpc2 = create_vpc(&client, &project_name, &other_vpc).await; - let rules = get_rules(client, &other_vpc_firewall).await; + let rules = + object_get::(client, &other_vpc_firewall).await.rules; assert!(rules.iter().all(|r| r.vpc_id == vpc2.identity.id)); assert!(is_default_firewall_rules(other_vpc, &rules)); @@ -111,14 +116,17 @@ async fn test_vpc_firewall(cptestctx: &ControlPlaneTestContext) { assert_eq!(updated_rules[1].identity.name, "deny-all-incoming"); // Make sure the firewall is changed - let rules = get_rules(client, &default_vpc_firewall).await; + let rules = object_get::(client, &default_vpc_firewall) + .await + .rules; assert!(!is_default_firewall_rules("default", &rules)); assert_eq!(rules.len(), new_rules.len()); assert_eq!(rules[0].identity.name, "allow-icmp"); assert_eq!(rules[1].identity.name, "deny-all-incoming"); // Make sure the other firewall is unchanged - let rules = get_rules(client, &other_vpc_firewall).await; + let rules = + object_get::(client, &other_vpc_firewall).await.rules; assert!(is_default_firewall_rules(other_vpc, &rules)); // DELETE is unsupported @@ -162,20 +170,6 @@ async fn test_vpc_firewall(cptestctx: &ControlPlaneTestContext) { .unwrap(); } -async fn get_rules( - client: &dropshot::test_util::ClientTestContext, - url: &str, -) -> Vec { - NexusRequest::object_get(client, url) - .authn_as(AuthnMode::PrivilegedUser) - .execute() - .await - .unwrap() - .parsed_body::() - .unwrap() - .rules -} - fn is_default_firewall_rules( vpc_name: &str, rules: &Vec, @@ -292,3 +286,38 @@ fn is_default_firewall_rules( } true } + +#[nexus_test] +async fn test_firewall_rules_same_name(cptestctx: &ControlPlaneTestContext) { + let client = &cptestctx.external_client; + + let project_name = "my-project"; + create_project(&client, &project_name).await; + + let rule = VpcFirewallRuleUpdate { + name: "dupe".parse().unwrap(), + description: "".to_string(), + status: VpcFirewallRuleStatus::Enabled, + direction: VpcFirewallRuleDirection::Inbound, + targets: vec![], + filters: VpcFirewallRuleFilter { + hosts: None, + protocols: None, + ports: None, + }, + action: VpcFirewallRuleAction::Allow, + priority: VpcFirewallRulePriority(65534), + }; + + let error = object_put_error( + client, + &format!("/v1/vpc-firewall-rules?vpc=default&project={}", project_name), + &VpcFirewallRuleUpdateParams { + rules: vec![rule.clone(), rule.clone()], + }, + StatusCode::BAD_REQUEST, + ) + .await; + assert_eq!(error.error_code, Some("InvalidValue".to_string())); + assert_eq!(error.message, "unsupported value for \"rules\": Rule names must be unique. Duplicates: [\"dupe\"]"); +} From 76e140be8680615d83a12309d19cf7df82b348ba Mon Sep 17 00:00:00 2001 From: Augustus Mayo Date: Thu, 20 Jun 2024 10:45:29 -0500 Subject: [PATCH 08/26] Add PEM encoded certificate to external api response (#5078) * Add pem encoded certificate to certificate list and view endpoints When managing multiple silos, it quickly becomes desirable to be able to use the oxide cli and/or sdk to manage them. Handling certificate rotation currently requires storing external state about what certificate is registered with which silo as our external API only returns identity metadata about the certificate. This PR proposes adding the the public certificate to the fields returned for a certificate. This initial implementation tries to take the simplest approach to this: 1. Return the exact representation that we store in the database (PEM-encoded string) 2. Returns the certificate on both list and view endpoints An alternative approach may be to only return the full certificate as a part of the view endpoint, but I'm not sure if that is a pattern that we use. The other consideration is how this should handle the failure to construct a String from the bytes form of a certificate. Currently it is very disruptive, and hard to debug if bad data were to be stored in the database. --------- Co-authored-by: reflector[bot] <123+reflector[bot]@users.noreply.github.com> --- nexus/db-model/src/certificate.rs | 7 +++++++ nexus/types/src/external_api/views.rs | 3 +++ openapi/nexus.json | 12 +++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/nexus/db-model/src/certificate.rs b/nexus/db-model/src/certificate.rs index 2cd1bcf08a..0e221b7c46 100644 --- a/nexus/db-model/src/certificate.rs +++ b/nexus/db-model/src/certificate.rs @@ -82,6 +82,13 @@ impl TryFrom for views::Certificate { Ok(Self { identity: cert.identity(), service: cert.service.try_into()?, + // This is expected to succeed in normal circumstances. Certificates are stored in the + // database with PEM encoding which are essentially bundles of Base64 encoded text. + // The only cases in which this conversion should fail is when our internal database + // representation of the certificate is invalid. + cert: String::from_utf8(cert.cert).map_err(|_| { + Error::internal_error("Certificate is not valid UTF-8") + })?, }) } } diff --git a/nexus/types/src/external_api/views.rs b/nexus/types/src/external_api/views.rs index 2fa94b0e80..394bef5d2f 100644 --- a/nexus/types/src/external_api/views.rs +++ b/nexus/types/src/external_api/views.rs @@ -177,7 +177,10 @@ pub struct Project { pub struct Certificate { #[serde(flatten)] pub identity: IdentityMetadata, + /// The service using this certificate pub service: ServiceUsingCertificate, + /// PEM-formatted string containing public certificate chain + pub cert: String, } // IMAGES diff --git a/openapi/nexus.json b/openapi/nexus.json index 01ec9aeb56..42ccb567cf 100644 --- a/openapi/nexus.json +++ b/openapi/nexus.json @@ -11021,6 +11021,10 @@ "description": "View of a Certificate", "type": "object", "properties": { + "cert": { + "description": "PEM-formatted string containing public certificate chain", + "type": "string" + }, "description": { "description": "human-readable free-form text about a resource", "type": "string" @@ -11039,7 +11043,12 @@ ] }, "service": { - "$ref": "#/components/schemas/ServiceUsingCertificate" + "description": "The service using this certificate", + "allOf": [ + { + "$ref": "#/components/schemas/ServiceUsingCertificate" + } + ] }, "time_created": { "description": "timestamp when this resource was created", @@ -11053,6 +11062,7 @@ } }, "required": [ + "cert", "description", "id", "name", From 64610780573d0f87475b9abc77fe7c6afe7441ba Mon Sep 17 00:00:00 2001 From: Levon Tarver <11586085+internet-diglett@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:00:05 -0500 Subject: [PATCH 09/26] BUGFIX: use sled filter to apply v2p mappings (#5917) It has been reported that marking a sled as "non_provisionable" causes it to lose the instance v2p mappings. This is a regression. It was determined that the scoping of the mappings is too strict, relying on the sled_policy to be set to "in service" via the db view. The preferred option is to rely on the sled policy machinery to do the filtering for us, so the view has been removed and the querying logic updated accordingly. Also, based on a comment in a previous related PR, we are now selecting target sleds for instances using the active_propolis_id to avoid potential conflicts during live migrations. ## Related --- #5872 --- dev-tools/omdb/tests/usage_errors.out | 1 + nexus/db-model/src/schema.rs | 14 +- nexus/db-model/src/schema_versions.rs | 3 +- nexus/db-model/src/sled.rs | 2 +- nexus/db-model/src/v2p_mapping.rs | 12 +- .../src/db/datastore/v2p_mapping.rs | 124 ++++++++++++++++-- nexus/src/app/background/v2p_mappings.rs | 25 +--- nexus/types/src/deployment/planning_input.rs | 8 ++ schema/crdb/dbinit.sql | 49 +------ .../remove-view-for-v2p-mappings/up01.sql | 1 + 10 files changed, 142 insertions(+), 97 deletions(-) create mode 100644 schema/crdb/remove-view-for-v2p-mappings/up01.sql diff --git a/dev-tools/omdb/tests/usage_errors.out b/dev-tools/omdb/tests/usage_errors.out index 563d23d6f3..b7fe7bdf7f 100644 --- a/dev-tools/omdb/tests/usage_errors.out +++ b/dev-tools/omdb/tests/usage_errors.out @@ -290,6 +290,7 @@ Options: for discretionary services) - query-during-inventory: Sleds whose sled agents should be queried for inventory - reservation-create: Sleds on which reservations can be created + - v2p-mapping: Sleds which should be sent OPTE V2P mappings - vpc-firewall: Sleds which should be sent VPC firewall rules --log-level diff --git a/nexus/db-model/src/schema.rs b/nexus/db-model/src/schema.rs index b1fabcf976..d08a51edd4 100644 --- a/nexus/db-model/src/schema.rs +++ b/nexus/db-model/src/schema.rs @@ -285,17 +285,6 @@ table! { } } -table! { - v2p_mapping_view (nic_id) { - nic_id -> Uuid, - sled_id -> Uuid, - sled_ip -> Inet, - vni -> Int4, - mac -> Int8, - ip -> Inet, - } -} - table! { bgp_announce_set (id) { id -> Uuid, @@ -1842,6 +1831,7 @@ allow_tables_to_appear_in_same_query!( user_builtin, role_builtin, role_assignment, + probe, ); allow_tables_to_appear_in_same_query!(dns_zone, dns_version, dns_name); @@ -1870,3 +1860,5 @@ joinable!(instance_ssh_key -> ssh_key (ssh_key_id)); joinable!(instance_ssh_key -> instance (instance_id)); allow_tables_to_appear_in_same_query!(sled, sled_instance); + +joinable!(network_interface -> probe (parent_id)); diff --git a/nexus/db-model/src/schema_versions.rs b/nexus/db-model/src/schema_versions.rs index eed8c81421..04fafe4f93 100644 --- a/nexus/db-model/src/schema_versions.rs +++ b/nexus/db-model/src/schema_versions.rs @@ -17,7 +17,7 @@ use std::collections::BTreeMap; /// /// This must be updated when you change the database schema. Refer to /// schema/crdb/README.adoc in the root of this repository for details. -pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(76, 0, 0); +pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(77, 0, 0); /// List of all past database schema versions, in *reverse* order /// @@ -29,6 +29,7 @@ static KNOWN_VERSIONS: Lazy> = Lazy::new(|| { // | leaving the first copy as an example for the next person. // v // KnownVersion::new(next_int, "unique-dirname-with-the-sql-files"), + KnownVersion::new(77, "remove-view-for-v2p-mappings"), KnownVersion::new(76, "lookup-region-snapshot-by-snapshot-id"), KnownVersion::new(75, "add-cockroach-zone-id-to-node-id"), KnownVersion::new(74, "add-migration-table"), diff --git a/nexus/db-model/src/sled.rs b/nexus/db-model/src/sled.rs index 5019366733..c177650991 100644 --- a/nexus/db-model/src/sled.rs +++ b/nexus/db-model/src/sled.rs @@ -44,7 +44,7 @@ pub struct SledSystemHardware { #[diesel(table_name = sled)] pub struct Sled { #[diesel(embed)] - identity: SledIdentity, + pub identity: SledIdentity, time_deleted: Option>, pub rcgen: Generation, diff --git a/nexus/db-model/src/v2p_mapping.rs b/nexus/db-model/src/v2p_mapping.rs index 43831f7503..bb7c74b83f 100644 --- a/nexus/db-model/src/v2p_mapping.rs +++ b/nexus/db-model/src/v2p_mapping.rs @@ -1,15 +1,17 @@ -use crate::schema::v2p_mapping_view; -use crate::{MacAddr, Vni}; +use crate::{Ipv6Addr, MacAddr, Vni}; use ipnetwork::IpNetwork; use serde::{Deserialize, Serialize}; use uuid::Uuid; -#[derive(Queryable, Selectable, Clone, Debug, Serialize, Deserialize)] -#[diesel(table_name = v2p_mapping_view)] +/// This is not backed by an actual database view, +/// but it is still essentially a "view" in the sense +/// that it is a read-only data model derived from +/// multiple db tables +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct V2PMappingView { pub nic_id: Uuid, pub sled_id: Uuid, - pub sled_ip: IpNetwork, + pub sled_ip: Ipv6Addr, pub vni: Vni, pub mac: MacAddr, pub ip: IpNetwork, diff --git a/nexus/db-queries/src/db/datastore/v2p_mapping.rs b/nexus/db-queries/src/db/datastore/v2p_mapping.rs index 6c00957e7d..2f54dfb9be 100644 --- a/nexus/db-queries/src/db/datastore/v2p_mapping.rs +++ b/nexus/db-queries/src/db/datastore/v2p_mapping.rs @@ -7,11 +7,15 @@ use crate::context::OpContext; use crate::db; use crate::db::datastore::SQL_BATCH_SIZE; use crate::db::error::{public_error_from_diesel, ErrorHandler}; +use crate::db::model::ApplySledFilterExt; use crate::db::model::V2PMappingView; use crate::db::pagination::paginated; use crate::db::pagination::Paginator; use async_bb8_diesel::AsyncRunQueryDsl; -use diesel::{QueryDsl, SelectableHelper}; +use diesel::{ExpressionMethods, QueryDsl, SelectableHelper}; +use diesel::{JoinOnDsl, NullableExpressionMethods}; +use nexus_db_model::{NetworkInterface, NetworkInterfaceKind, Sled, Vpc}; +use nexus_types::deployment::SledFilter; use omicron_common::api::external::ListResultVec; impl DataStore { @@ -19,22 +23,120 @@ impl DataStore { &self, opctx: &OpContext, ) -> ListResultVec { - use db::schema::v2p_mapping_view::dsl; + use db::schema::instance::dsl as instance_dsl; + use db::schema::network_interface::dsl as network_interface_dsl; + use db::schema::probe::dsl as probe_dsl; + use db::schema::sled::dsl as sled_dsl; + use db::schema::vmm::dsl as vmm_dsl; + use db::schema::vpc::dsl as vpc_dsl; + use db::schema::vpc_subnet::dsl as vpc_subnet_dsl; + + use db::schema::network_interface; opctx.check_complex_operations_allowed()?; let mut mappings = Vec::new(); let mut paginator = Paginator::new(SQL_BATCH_SIZE); while let Some(p) = paginator.next() { - let batch = paginated( - dsl::v2p_mapping_view, - dsl::nic_id, - &p.current_pagparams(), - ) - .select(V2PMappingView::as_select()) - .load_async(&*self.pool_connection_authorized(opctx).await?) - .await - .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))?; + let batch: Vec<_> = + paginated( + network_interface_dsl::network_interface, + network_interface_dsl::id, + &p.current_pagparams(), + ) + .inner_join( + instance_dsl::instance + .on(network_interface_dsl::parent_id + .eq(instance_dsl::id)), + ) + .inner_join(vmm_dsl::vmm.on( + vmm_dsl::id.nullable().eq(instance_dsl::active_propolis_id), + )) + .inner_join(vpc_subnet_dsl::vpc_subnet.on( + vpc_subnet_dsl::id.eq(network_interface_dsl::subnet_id), + )) + .inner_join( + vpc_dsl::vpc + .on(vpc_dsl::id.eq(network_interface_dsl::vpc_id)), + ) + .inner_join( + sled_dsl::sled.on(sled_dsl::id.eq(vmm_dsl::sled_id)), + ) + .filter(network_interface::time_deleted.is_null()) + .filter( + network_interface::kind.eq(NetworkInterfaceKind::Instance), + ) + .sled_filter(SledFilter::V2PMapping) + .select(( + NetworkInterface::as_select(), + Sled::as_select(), + Vpc::as_select(), + )) + .load_async(&*self.pool_connection_authorized(opctx).await?) + .await + .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))? + .into_iter() + .map(|(nic, sled, vpc): (NetworkInterface, Sled, Vpc)| { + V2PMappingView { + nic_id: nic.identity.id, + sled_id: sled.identity.id, + sled_ip: sled.ip, + vni: vpc.vni, + mac: nic.mac, + ip: nic.ip, + } + }) + .collect(); + + paginator = p.found_batch(&batch, &|mapping| mapping.nic_id); + mappings.extend(batch); + } + + let mut paginator = Paginator::new(SQL_BATCH_SIZE); + while let Some(p) = paginator.next() { + let batch: Vec<_> = + paginated( + network_interface_dsl::network_interface, + network_interface_dsl::id, + &p.current_pagparams(), + ) + .inner_join( + probe_dsl::probe + .on(probe_dsl::id.eq(network_interface_dsl::parent_id)), + ) + .inner_join(vpc_subnet_dsl::vpc_subnet.on( + vpc_subnet_dsl::id.eq(network_interface_dsl::subnet_id), + )) + .inner_join( + vpc_dsl::vpc + .on(vpc_dsl::id.eq(network_interface_dsl::vpc_id)), + ) + .inner_join(sled_dsl::sled.on(sled_dsl::id.eq(probe_dsl::sled))) + .filter(network_interface::time_deleted.is_null()) + .filter( + network_interface::kind.eq(NetworkInterfaceKind::Instance), + ) + .sled_filter(SledFilter::V2PMapping) + .select(( + NetworkInterface::as_select(), + Sled::as_select(), + Vpc::as_select(), + )) + .load_async(&*self.pool_connection_authorized(opctx).await?) + .await + .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))? + .into_iter() + .map(|(nic, sled, vpc): (NetworkInterface, Sled, Vpc)| { + V2PMappingView { + nic_id: nic.identity.id, + sled_id: sled.identity.id, + sled_ip: sled.ip, + vni: vpc.vni, + mac: nic.mac, + ip: nic.ip, + } + }) + .collect(); paginator = p.found_batch(&batch, &|mapping| mapping.nic_id); mappings.extend(batch); diff --git a/nexus/src/app/background/v2p_mappings.rs b/nexus/src/app/background/v2p_mappings.rs index a53ac3442f..e2318f94d6 100644 --- a/nexus/src/app/background/v2p_mappings.rs +++ b/nexus/src/app/background/v2p_mappings.rs @@ -74,28 +74,13 @@ impl BackgroundTask for V2PManager { // create a set of updates from the v2p mappings let desired_v2p: HashSet<_> = v2p_mappings .into_iter() - .filter_map(|mapping| { - let physical_host_ip = match mapping.sled_ip.ip() { - std::net::IpAddr::V4(v) => { - // sled ip should never be ipv4 - error!( - &log, - "sled ip should be ipv6 but is ipv4: {v}" - ); - return None; - } - std::net::IpAddr::V6(v) => v, - }; - - let vni = mapping.vni.0; - - let mapping = VirtualNetworkInterfaceHost { + .map(|mapping| { + VirtualNetworkInterfaceHost { virtual_ip: mapping.ip.ip(), virtual_mac: *mapping.mac, - physical_host_ip, - vni, - }; - Some(mapping) + physical_host_ip: *mapping.sled_ip, + vni: mapping.vni.0, + } }) .collect(); diff --git a/nexus/types/src/deployment/planning_input.rs b/nexus/types/src/deployment/planning_input.rs index 10d528bbfd..028f2301ba 100644 --- a/nexus/types/src/deployment/planning_input.rs +++ b/nexus/types/src/deployment/planning_input.rs @@ -482,6 +482,9 @@ pub enum SledFilter { /// Sleds on which reservations can be created. ReservationCreate, + /// Sleds which should be sent OPTE V2P mappings. + V2PMapping, + /// Sleds which should be sent VPC firewall rules. VpcFirewall, } @@ -536,6 +539,7 @@ impl SledPolicy { SledFilter::InService => true, SledFilter::QueryDuringInventory => true, SledFilter::ReservationCreate => true, + SledFilter::V2PMapping => true, SledFilter::VpcFirewall => true, }, SledPolicy::InService { @@ -547,6 +551,7 @@ impl SledPolicy { SledFilter::InService => true, SledFilter::QueryDuringInventory => true, SledFilter::ReservationCreate => false, + SledFilter::V2PMapping => true, SledFilter::VpcFirewall => true, }, SledPolicy::Expunged => match filter { @@ -556,6 +561,7 @@ impl SledPolicy { SledFilter::InService => false, SledFilter::QueryDuringInventory => false, SledFilter::ReservationCreate => false, + SledFilter::V2PMapping => false, SledFilter::VpcFirewall => false, }, } @@ -587,6 +593,7 @@ impl SledState { SledFilter::InService => true, SledFilter::QueryDuringInventory => true, SledFilter::ReservationCreate => true, + SledFilter::V2PMapping => true, SledFilter::VpcFirewall => true, }, SledState::Decommissioned => match filter { @@ -596,6 +603,7 @@ impl SledState { SledFilter::InService => false, SledFilter::QueryDuringInventory => false, SledFilter::ReservationCreate => false, + SledFilter::V2PMapping => false, SledFilter::VpcFirewall => false, }, } diff --git a/schema/crdb/dbinit.sql b/schema/crdb/dbinit.sql index 338f52f854..905fd111c1 100644 --- a/schema/crdb/dbinit.sql +++ b/schema/crdb/dbinit.sql @@ -3891,53 +3891,6 @@ ON omicron.public.switch_port (port_settings_id, port_name) STORING (switch_loca CREATE INDEX IF NOT EXISTS switch_port_name ON omicron.public.switch_port (port_name); -COMMIT; -BEGIN; - --- view for v2p mapping rpw -CREATE VIEW IF NOT EXISTS omicron.public.v2p_mapping_view -AS -WITH VmV2pMappings AS ( - SELECT - n.id as nic_id, - s.id as sled_id, - s.ip as sled_ip, - v.vni, - n.mac, - n.ip - FROM omicron.public.network_interface n - JOIN omicron.public.vpc_subnet vs ON vs.id = n.subnet_id - JOIN omicron.public.vpc v ON v.id = n.vpc_id - JOIN omicron.public.vmm vmm ON n.parent_id = vmm.instance_id - JOIN omicron.public.sled s ON vmm.sled_id = s.id - WHERE n.time_deleted IS NULL - AND n.kind = 'instance' - AND (vmm.state = 'running' OR vmm.state = 'starting') - AND s.sled_policy = 'in_service' - AND s.sled_state = 'active' -), -ProbeV2pMapping AS ( - SELECT - n.id as nic_id, - s.id as sled_id, - s.ip as sled_ip, - v.vni, - n.mac, - n.ip - FROM omicron.public.network_interface n - JOIN omicron.public.vpc_subnet vs ON vs.id = n.subnet_id - JOIN omicron.public.vpc v ON v.id = n.vpc_id - JOIN omicron.public.probe p ON n.parent_id = p.id - JOIN omicron.public.sled s ON p.sled = s.id - WHERE n.time_deleted IS NULL - AND n.kind = 'probe' - AND s.sled_policy = 'in_service' - AND s.sled_state = 'active' -) -SELECT nic_id, sled_id, sled_ip, vni, mac, ip FROM VmV2pMappings -UNION -SELECT nic_id, sled_id, sled_ip, vni, mac, ip FROM ProbeV2pMapping; - CREATE INDEX IF NOT EXISTS network_interface_by_parent ON omicron.public.network_interface (parent_id) STORING (name, kind, vpc_id, subnet_id, mac, ip, slot); @@ -4145,7 +4098,7 @@ INSERT INTO omicron.public.db_metadata ( version, target_version ) VALUES - (TRUE, NOW(), NOW(), '76.0.0', NULL) + (TRUE, NOW(), NOW(), '77.0.0', NULL) ON CONFLICT DO NOTHING; COMMIT; diff --git a/schema/crdb/remove-view-for-v2p-mappings/up01.sql b/schema/crdb/remove-view-for-v2p-mappings/up01.sql new file mode 100644 index 0000000000..aebe0119f5 --- /dev/null +++ b/schema/crdb/remove-view-for-v2p-mappings/up01.sql @@ -0,0 +1 @@ +DROP VIEW IF EXISTS omicron.public.v2p_mapping_view; From c1d56c7475c1ce72fb152fb3db28bab5f9925876 Mon Sep 17 00:00:00 2001 From: iliana etaoin Date: Thu, 20 Jun 2024 14:19:24 -0700 Subject: [PATCH 10/26] be more consistent about workspace members (#5921) 1. We have reasons for excluding some packages from the default workspace members, but there was nothing checking that newly-added packages were added to both. I added an additional check to `cargo xtask check-workspace-deps` to ensure that `default-members` is equal to `members` minus xtask and end-to-end-tests. This had the effect that the tests in `api_identity` were not being run in CI! 2. Add `--workspace` to `cargo clippy` and `cargo doc` in CI to run checks across the entire tree. 3. Fix clippy lints / doc errors that were not being caught in the previous setup. --- .github/buildomat/jobs/clippy.sh | 2 +- .github/workflows/rust.yml | 2 +- Cargo.toml | 13 +++++++-- api_identity/src/lib.rs | 18 ++++-------- dev-tools/xtask/src/check_workspace_deps.rs | 32 ++++++++++++++++++++- dev-tools/xtask/src/clippy.rs | 1 + dev-tools/xtask/src/download.rs | 2 +- dev-tools/xtask/src/virtual_hardware.rs | 12 ++++---- end-to-end-tests/src/helpers/icmp.rs | 2 +- nexus/test-utils/src/http_testing.rs | 9 +++--- 10 files changed, 62 insertions(+), 31 deletions(-) diff --git a/.github/buildomat/jobs/clippy.sh b/.github/buildomat/jobs/clippy.sh index cff9c45a1b..7da32ec331 100755 --- a/.github/buildomat/jobs/clippy.sh +++ b/.github/buildomat/jobs/clippy.sh @@ -30,4 +30,4 @@ ptime -m bash ./tools/install_builder_prerequisites.sh -y banner clippy export CARGO_INCREMENTAL=0 ptime -m cargo xtask clippy -ptime -m cargo doc +RUSTDOCFLAGS="-Dwarnings" ptime -m cargo doc --workspace diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 724f88e7a3..1888481ba2 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -108,4 +108,4 @@ jobs: - name: Install Pre-Requisites run: ./tools/install_builder_prerequisites.sh -y - name: Test build documentation - run: RUSTDOCFLAGS="-Dwarnings" cargo doc + run: RUSTDOCFLAGS="-Dwarnings" cargo doc --workspace diff --git a/Cargo.toml b/Cargo.toml index 69269a1de4..2e6e556519 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -87,6 +87,7 @@ members = [ ] default-members = [ + "api_identity", "bootstore", "certificates", "clients/bootstrap-agent-client", @@ -113,6 +114,8 @@ default-members = [ # hakari to not work as well and build times to be longer. # See omicron#4392. "dns-server", + # Do not include end-to-end-tests in the list of default members, as its + # tests only work on a deployed control plane. "gateway-cli", "gateway-test-utils", "gateway", @@ -128,18 +131,21 @@ default-members = [ "nexus-config", "nexus/authz-macros", "nexus/auth", - "nexus/macros-common", - "nexus/metrics-producer-gc", - "nexus/networking", "nexus/db-fixed-data", "nexus/db-macros", "nexus/db-model", "nexus/db-queries", "nexus/defaults", "nexus/inventory", + "nexus/macros-common", + "nexus/metrics-producer-gc", + "nexus/networking", "nexus/reconfigurator/execution", "nexus/reconfigurator/planning", "nexus/reconfigurator/preparation", + "nexus/test-interface", + "nexus/test-utils-macros", + "nexus/test-utils", "nexus/types", "oximeter/collector", "oximeter/db", @@ -166,6 +172,7 @@ default-members = [ "wicket-dbg", "wicket", "wicketd", + "workspace-hack", "zone-setup", ] resolver = "2" diff --git a/api_identity/src/lib.rs b/api_identity/src/lib.rs index 4d933ed3c0..f90b1e3a89 100644 --- a/api_identity/src/lib.rs +++ b/api_identity/src/lib.rs @@ -60,12 +60,9 @@ mod test { #[test] fn test_identity() { - let ret = do_object_identity( - quote! { - struct Foo { identity: IdentityMetadata } - } - .into(), - ); + let ret = do_object_identity(quote! { + struct Foo { identity: IdentityMetadata } + }); let expected = quote! { impl ObjectIdentity for Foo { @@ -80,12 +77,9 @@ mod test { #[test] fn test_identity_no_field() { - let ret = do_object_identity( - quote! { - struct Foo {} - } - .into(), - ); + let ret = do_object_identity(quote! { + struct Foo {} + }); let error = ret.unwrap_err(); assert!(error.to_string().starts_with("deriving ObjectIdentity")); diff --git a/dev-tools/xtask/src/check_workspace_deps.rs b/dev-tools/xtask/src/check_workspace_deps.rs index 76e405ce1a..94de557a46 100644 --- a/dev-tools/xtask/src/check_workspace_deps.rs +++ b/dev-tools/xtask/src/check_workspace_deps.rs @@ -8,7 +8,7 @@ use anyhow::{bail, Context, Result}; use camino::Utf8Path; use cargo_toml::{Dependency, Manifest}; use fs_err as fs; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; const WORKSPACE_HACK_PACKAGE_NAME: &str = "omicron-workspace-hack"; @@ -116,6 +116,36 @@ pub fn run_cmd() -> Result<()> { nerrors += 1; } + // Check that `default-members` is configured correctly. + let non_default = workspace + .packages + .iter() + .filter_map(|package| { + [ + // Including xtask causes hakari to not work as well and build + // times to be longer (omicron#4392). + "xtask", + // The tests here should not be run by default, as they require + // a running control plane. + "end-to-end-tests", + ] + .contains(&package.name.as_str()) + .then_some(&package.id) + }) + .collect::>(); + let members = workspace.workspace_members.iter().collect::>(); + let default_members = + workspace.workspace_default_members.iter().collect::>(); + for package in members.difference(&default_members) { + if !non_default.contains(package) { + eprintln!( + "error: package {:?} not in default-members", + package.repr + ); + nerrors += 1; + } + } + eprintln!( "check-workspace-deps: errors: {}, warnings: {}", nerrors, nwarnings diff --git a/dev-tools/xtask/src/clippy.rs b/dev-tools/xtask/src/clippy.rs index 8c454fdebf..7924a05574 100644 --- a/dev-tools/xtask/src/clippy.rs +++ b/dev-tools/xtask/src/clippy.rs @@ -42,6 +42,7 @@ pub fn run_cmd(args: ClippyArgs) -> Result<()> { command // Make sure we check everything. .arg("--all-targets") + .arg("--workspace") .arg("--") // For a list of lints, see // https://rust-lang.github.io/rust-clippy/master. diff --git a/dev-tools/xtask/src/download.rs b/dev-tools/xtask/src/download.rs index ce227b7c4d..f7583d19a0 100644 --- a/dev-tools/xtask/src/download.rs +++ b/dev-tools/xtask/src/download.rs @@ -218,7 +218,7 @@ async fn get_values_from_file( .context("Failed to read {path}")?; for line in content.lines() { let line = line.trim(); - let Some((key, value)) = line.split_once("=") else { + let Some((key, value)) = line.split_once('=') else { continue; }; let value = value.trim_matches('"'); diff --git a/dev-tools/xtask/src/virtual_hardware.rs b/dev-tools/xtask/src/virtual_hardware.rs index 5384433f55..d28c3d9037 100644 --- a/dev-tools/xtask/src/virtual_hardware.rs +++ b/dev-tools/xtask/src/virtual_hardware.rs @@ -235,9 +235,7 @@ fn unload_xde_driver() -> Result<()> { .context("Invalid modinfo output")? .lines() .find_map(|line| { - let mut cols = line.trim().splitn(2, ' '); - let id = cols.next()?; - let desc = cols.next()?; + let (id, desc) = line.trim().split_once(' ')?; if !desc.contains("xde") { return None; } @@ -419,7 +417,7 @@ fn run_scadm_command(args: Vec<&str>) -> Result { for arg in &args { cmd.arg(arg); } - Ok(execute(cmd)?) + execute(cmd) } fn default_gateway_ip() -> Result { @@ -497,8 +495,8 @@ struct SledAgentConfig { impl SledAgentConfig { fn read(path: &Utf8Path) -> Result { let config = std::fs::read_to_string(path)?; - Ok(toml::from_str(&config) - .context("Could not parse sled agent config as toml")?) + toml::from_str(&config) + .context("Could not parse sled agent config as toml") } } @@ -605,7 +603,7 @@ fn swap_list() -> Result> { let mut cmd = Command::new(SWAP); cmd.arg("-l"); - let output = cmd.output().context(format!("Could not start swap"))?; + let output = cmd.output().context("Could not start swap")?; if !output.status.success() { if let Ok(stderr) = String::from_utf8(output.stderr) { // This is an exceptional case - if there are no swap devices, diff --git a/end-to-end-tests/src/helpers/icmp.rs b/end-to-end-tests/src/helpers/icmp.rs index 36b9bc5675..40256db8d9 100644 --- a/end-to-end-tests/src/helpers/icmp.rs +++ b/end-to-end-tests/src/helpers/icmp.rs @@ -150,7 +150,7 @@ impl Pinger4 { "{:.3}", (t.sum.as_micros() as f32 / 1000.0 - / t.rx_count as f32) + / f32::from(t.rx_count)) ) }, format!("{:.3}", (t.high.as_micros() as f32 / 1000.0)), diff --git a/nexus/test-utils/src/http_testing.rs b/nexus/test-utils/src/http_testing.rs index 90c7dd43bc..1a85d7094c 100644 --- a/nexus/test-utils/src/http_testing.rs +++ b/nexus/test-utils/src/http_testing.rs @@ -216,8 +216,8 @@ impl<'a> RequestBuilder<'a> { /// Add header and value to check for at execution time /// - /// Behaves like header() rather than expect_allowed_headers() in that it - /// takes one header at a time rather than a whole set. + /// Behaves like header() in that it takes one header at a time rather than + /// a whole set. pub fn expect_response_header( mut self, name: K, @@ -291,8 +291,9 @@ impl<'a> RequestBuilder<'a> { /// response, and make the response available to the caller /// /// This function checks the returned status code (if [`Self::expect_status()`] - /// was used), allowed headers (if [`Self::expect_allowed_headers()`] was used), and - /// various other properties of the response. + /// was used), allowed headers (if [`Self::expect_websocket_handshake()`] or + /// [`Self::expect_console_asset()`] was used), and various other properties + /// of the response. pub async fn execute(self) -> Result { if let Some(error) = self.error { return Err(error); From 3549436604b76aaf70459ac2561e99e9e3b2dbfa Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Thu, 20 Jun 2024 18:03:06 -0400 Subject: [PATCH 11/26] Support updating the RoT bootloader (stage0) (#5882) --- Cargo.lock | 13 +- clients/sled-agent-client/src/lib.rs | 9 + common/src/api/internal/nexus.rs | 10 +- common/src/update.rs | 17 + openapi/sled-agent.json | 5 +- openapi/wicketd.json | 42 ++ .../tests/output/self-stat-schema.json | 4 +- sp-sim/src/gimlet.rs | 40 +- tools/permslip_production | 1 + tools/permslip_staging | 1 + tufaceous-lib/src/assemble/manifest.rs | 9 +- tufaceous/manifests/fake.toml | 17 + update-common/src/artifacts/update_plan.rs | 212 ++++++- wicket-common/src/update_events.rs | 17 + wicket/README.md | 13 +- wicket/src/cli/rack_update.rs | 5 + wicket/src/runner.rs | 4 + wicket/src/state/force_update.rs | 27 +- wicket/src/state/inventory.rs | 23 + wicket/src/state/update.rs | 21 +- wicket/src/ui/panes/overview.rs | 16 +- wicket/src/ui/panes/update.rs | 116 +++- wicketd/src/http_entrypoints.rs | 11 +- wicketd/src/update_tracker.rs | 515 +++++++++++++++++- 24 files changed, 1066 insertions(+), 82 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e1d3ca90c..4592b555bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3239,9 +3239,10 @@ dependencies = [ [[package]] name = "hubtools" -version = "0.4.1" -source = "git+https://github.com/oxidecomputer/hubtools.git?branch=main#73cd5a84689d59ecce9da66ad4389c540d315168" +version = "0.4.6" +source = "git+https://github.com/oxidecomputer/hubtools.git?branch=main#943c4bbe6b50d1ab635d085d6204895fb4154e79" dependencies = [ + "hex", "lpc55_areas", "lpc55_sign", "object 0.30.4", @@ -4145,8 +4146,8 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lpc55_areas" -version = "0.2.4" -source = "git+https://github.com/oxidecomputer/lpc55_support#96f064eaae5e95930efaab6c29fd1b2e22225dac" +version = "0.2.5" +source = "git+https://github.com/oxidecomputer/lpc55_support#131520fc913ecce9b80557e854751953f743a7d2" dependencies = [ "bitfield", "clap", @@ -4156,8 +4157,8 @@ dependencies = [ [[package]] name = "lpc55_sign" -version = "0.3.3" -source = "git+https://github.com/oxidecomputer/lpc55_support#96f064eaae5e95930efaab6c29fd1b2e22225dac" +version = "0.3.4" +source = "git+https://github.com/oxidecomputer/lpc55_support#131520fc913ecce9b80557e854751953f743a7d2" dependencies = [ "byteorder", "const-oid", diff --git a/clients/sled-agent-client/src/lib.rs b/clients/sled-agent-client/src/lib.rs index e4a407ef3d..81b225b035 100644 --- a/clients/sled-agent-client/src/lib.rs +++ b/clients/sled-agent-client/src/lib.rs @@ -484,6 +484,15 @@ impl From use omicron_common::api::internal::nexus::KnownArtifactKind; match s { + KnownArtifactKind::GimletRotBootloader => { + types::KnownArtifactKind::GimletRotBootloader + } + KnownArtifactKind::PscRotBootloader => { + types::KnownArtifactKind::PscRotBootloader + } + KnownArtifactKind::SwitchRotBootloader => { + types::KnownArtifactKind::SwitchRotBootloader + } KnownArtifactKind::GimletSp => types::KnownArtifactKind::GimletSp, KnownArtifactKind::GimletRot => types::KnownArtifactKind::GimletRot, KnownArtifactKind::Host => types::KnownArtifactKind::Host, diff --git a/common/src/api/internal/nexus.rs b/common/src/api/internal/nexus.rs index b4a73f4168..d82d9a980a 100644 --- a/common/src/api/internal/nexus.rs +++ b/common/src/api/internal/nexus.rs @@ -273,16 +273,11 @@ pub struct UpdateArtifactId { // // 1. Add it here. // -// 2. Add the new kind to /{nexus-client,sled-agent-client}/lib.rs. +// 2. Add the new kind to /clients/src/lib.rs. // The mapping from `UpdateArtifactKind::*` to `types::UpdateArtifactKind::*` // must be left as a `todo!()` for now; `types::UpdateArtifactKind` will not // be updated with the new variant until step 5 below. // -// 3. Add it to the sql database schema under (CREATE TYPE -// omicron.public.update_artifact_kind). -// -// TODO: After omicron ships this would likely involve a DB migration. -// // 4. Add the new kind and the mapping to its `update_artifact_kind` to // /nexus/db-model/src/update_artifact.rs // @@ -324,6 +319,7 @@ pub enum KnownArtifactKind { // Sled Artifacts GimletSp, GimletRot, + GimletRotBootloader, Host, Trampoline, ControlPlane, @@ -331,10 +327,12 @@ pub enum KnownArtifactKind { // PSC Artifacts PscSp, PscRot, + PscRotBootloader, // Switch Artifacts SwitchSp, SwitchRot, + SwitchRotBootloader, } impl KnownArtifactKind { diff --git a/common/src/update.rs b/common/src/update.rs index 9feff1f868..fc747cf16d 100644 --- a/common/src/update.rs +++ b/common/src/update.rs @@ -177,6 +177,12 @@ impl ArtifactKind { /// These artifact kinds are not stored anywhere, but are derived from stored /// kinds and used as internal identifiers. impl ArtifactKind { + /// Gimlet root of trust bootloader slot image identifier. + /// + /// Derived from [`KnownArtifactKind::GimletRotBootloader`]. + pub const GIMLET_ROT_STAGE0: Self = + Self::from_static("gimlet_rot_bootloader"); + /// Gimlet root of trust A slot image identifier. /// /// Derived from [`KnownArtifactKind::GimletRot`]. @@ -189,6 +195,11 @@ impl ArtifactKind { pub const GIMLET_ROT_IMAGE_B: Self = Self::from_static("gimlet_rot_image_b"); + /// PSC root of trust stage0 image identifier. + /// + /// Derived from [`KnownArtifactKind::PscRotBootloader`]. + pub const PSC_ROT_STAGE0: Self = Self::from_static("psc_rot_bootloader"); + /// PSC root of trust A slot image identifier. /// /// Derived from [`KnownArtifactKind::PscRot`]. @@ -199,6 +210,12 @@ impl ArtifactKind { /// Derived from [`KnownArtifactKind::PscRot`]. pub const PSC_ROT_IMAGE_B: Self = Self::from_static("psc_rot_image_b"); + /// Switch root of trust A slot image identifier. + /// + /// Derived from [`KnownArtifactKind::SwitchRotBootloader`]. + pub const SWITCH_ROT_STAGE0: Self = + Self::from_static("switch_rot_bootloader"); + /// Switch root of trust A slot image identifier. /// /// Derived from [`KnownArtifactKind::SwitchRot`]. diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index e1349c2b59..21967f9fc3 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -3380,13 +3380,16 @@ "enum": [ "gimlet_sp", "gimlet_rot", + "gimlet_rot_bootloader", "host", "trampoline", "control_plane", "psc_sp", "psc_rot", + "psc_rot_bootloader", "switch_sp", - "switch_rot" + "switch_rot", + "switch_rot_bootloader" ] }, "L4PortRange": { diff --git a/openapi/wicketd.json b/openapi/wicketd.json index df13340334..21e8ebeedd 100644 --- a/openapi/wicketd.json +++ b/openapi/wicketd.json @@ -3274,6 +3274,10 @@ "StartUpdateOptions": { "type": "object", "properties": { + "skip_rot_bootloader_version_check": { + "description": "If true, skip the check on the current RoT version and always update it regardless of whether the update appears to be neeeded.", + "type": "boolean" + }, "skip_rot_version_check": { "description": "If true, skip the check on the current RoT version and always update it regardless of whether the update appears to be neeeded.", "type": "boolean" @@ -3291,6 +3295,15 @@ } ] }, + "test_simulate_rot_bootloader_result": { + "nullable": true, + "description": "If passed in, simulates a result for the RoT Bootloader update.\n\nThis is used for testing.", + "allOf": [ + { + "$ref": "#/components/schemas/UpdateSimulatedResult" + } + ] + }, "test_simulate_rot_result": { "nullable": true, "description": "If passed in, simulates a result for the RoT update.\n\nThis is used for testing.", @@ -3318,6 +3331,7 @@ } }, "required": [ + "skip_rot_bootloader_version_check", "skip_rot_version_check", "skip_sp_version_check" ] @@ -4734,6 +4748,20 @@ }, "UpdateComponent": { "oneOf": [ + { + "type": "object", + "properties": { + "component": { + "type": "string", + "enum": [ + "rot_bootloader" + ] + } + }, + "required": [ + "component" + ] + }, { "type": "object", "properties": { @@ -4822,6 +4850,20 @@ "state" ] }, + { + "type": "object", + "properties": { + "id": { + "type": "string", + "enum": [ + "interrogate_rot_bootloader" + ] + } + }, + "required": [ + "id" + ] + }, { "type": "object", "properties": { diff --git a/oximeter/collector/tests/output/self-stat-schema.json b/oximeter/collector/tests/output/self-stat-schema.json index 019e05b494..f5e439d40f 100644 --- a/oximeter/collector/tests/output/self-stat-schema.json +++ b/oximeter/collector/tests/output/self-stat-schema.json @@ -39,7 +39,7 @@ } ], "datum_type": "cumulative_u64", - "created": "2024-06-04T20:49:05.675711686Z" + "created": "2024-06-11T21:04:40.129429782Z" }, "oximeter_collector:failed_collections": { "timeseries_name": "oximeter_collector:failed_collections", @@ -86,6 +86,6 @@ } ], "datum_type": "cumulative_u64", - "created": "2024-06-04T20:49:05.676050088Z" + "created": "2024-06-11T21:04:40.130239084Z" } } \ No newline at end of file diff --git a/sp-sim/src/gimlet.rs b/sp-sim/src/gimlet.rs index 280248d034..4e0b264e64 100644 --- a/sp-sim/src/gimlet.rs +++ b/sp-sim/src/gimlet.rs @@ -1275,12 +1275,13 @@ impl SpHandler for Handler { "port" => ?port, "component" => ?component, ); - if component == SpComponent::ROT { - Ok(rot_slot_id_to_u16(self.rot_active_slot)) - } else { + match component { + SpComponent::ROT => Ok(rot_slot_id_to_u16(self.rot_active_slot)), + // The only active component is stage0 + SpComponent::STAGE0 => Ok(0), // The real SP returns `RequestUnsupportedForComponent` for anything // other than the RoT, including SP_ITSELF. - Err(SpError::RequestUnsupportedForComponent) + _ => Err(SpError::RequestUnsupportedForComponent), } } @@ -1300,16 +1301,27 @@ impl SpHandler for Handler { "slot" => slot, "persist" => persist, ); - if component == SpComponent::ROT { - self.rot_active_slot = rot_slot_id_from_u16(slot)?; - Ok(()) - } else if component == SpComponent::HOST_CPU_BOOT_FLASH { - self.update_state.set_active_host_slot(slot); - Ok(()) - } else { - // The real SP returns `RequestUnsupportedForComponent` for anything - // other than the RoT and host boot flash, including SP_ITSELF. - Err(SpError::RequestUnsupportedForComponent) + match component { + SpComponent::ROT => { + self.rot_active_slot = rot_slot_id_from_u16(slot)?; + Ok(()) + } + SpComponent::STAGE0 => { + if slot == 1 { + return Ok(()); + } else { + Err(SpError::RequestUnsupportedForComponent) + } + } + SpComponent::HOST_CPU_BOOT_FLASH => { + self.update_state.set_active_host_slot(slot); + Ok(()) + } + _ => { + // The real SP returns `RequestUnsupportedForComponent` for anything + // other than the RoT and host boot flash, including SP_ITSELF. + Err(SpError::RequestUnsupportedForComponent) + } } } diff --git a/tools/permslip_production b/tools/permslip_production index c384c2cd51..1b0f191d5a 100644 --- a/tools/permslip_production +++ b/tools/permslip_production @@ -1 +1,2 @@ 3feecf35522ecc07a23fbe934c752ecbf248672ce55c29102de485927edc12e6 manifest-oxide-rot-1-v1.0.11.toml +74e754e68705cf6fed4152a92bc1ee9667d1d98a21fc12993a2232dbe34bfccb manifest-bootleby-v1.3.0.toml diff --git a/tools/permslip_staging b/tools/permslip_staging index 3764a4569e..e0c4b4ad70 100644 --- a/tools/permslip_staging +++ b/tools/permslip_staging @@ -2,3 +2,4 @@ b973cc9feb20f7bba447e7f5291c4070387fa9992deab81301f67f0a3844cd0c manifest-oxide-rot-1-v1.0.11.toml ca14a77639db3b71c60234e4edebd01ff31ba5a93a842100a991dbf3ad6e94fb manifest-psc-v1.0.20.toml af0f6c7d0723db33a2972343cc42e4c2ee2ab8884c49808c9c3d8289c193f97b manifest-sidecar-v1.0.21.toml +c0fecaefac7674138337f3bd4ce4ce5b884053dead5ec27b575701471631ea2f manifest-bootleby-v1.3.0.toml diff --git a/tufaceous-lib/src/assemble/manifest.rs b/tufaceous-lib/src/assemble/manifest.rs index 1c4a676f4c..e9187ff0af 100644 --- a/tufaceous-lib/src/assemble/manifest.rs +++ b/tufaceous-lib/src/assemble/manifest.rs @@ -279,6 +279,9 @@ impl<'a> FakeDataAttributes<'a> { use hubtools::{CabooseBuilder, HubrisArchiveBuilder}; let board = match self.kind { + KnownArtifactKind::GimletRotBootloader + | KnownArtifactKind::PscRotBootloader + | KnownArtifactKind::SwitchRotBootloader => "SimRotStage0", // non-Hubris artifacts: just make fake data KnownArtifactKind::Host | KnownArtifactKind::Trampoline @@ -287,11 +290,11 @@ impl<'a> FakeDataAttributes<'a> { // hubris artifacts: build a fake archive (SimGimletSp and // SimGimletRot are used by sp-sim) KnownArtifactKind::GimletSp => "SimGimletSp", - KnownArtifactKind::GimletRot => "SimGimletRot", + KnownArtifactKind::GimletRot => "SimRot", KnownArtifactKind::PscSp => "fake-psc-sp", KnownArtifactKind::PscRot => "fake-psc-rot", - KnownArtifactKind::SwitchSp => "fake-sidecar-sp", - KnownArtifactKind::SwitchRot => "fake-sidecar-rot", + KnownArtifactKind::SwitchSp => "SimSidecarSp", + KnownArtifactKind::SwitchRot => "SimRot", }; let caboose = CabooseBuilder::default() diff --git a/tufaceous/manifests/fake.toml b/tufaceous/manifests/fake.toml index cc7ccabd74..a71a5e853f 100644 --- a/tufaceous/manifests/fake.toml +++ b/tufaceous/manifests/fake.toml @@ -68,3 +68,20 @@ version = "1.0.0" kind = "composite-rot" archive_a = { kind = "fake", size = "512KiB" } archive_b = { kind = "fake", size = "512KiB" } + +[[artifact.gimlet_rot_bootloader]] +name = "fake-gimlet-rot-bootloader" +version = "1.0.0" +source = { kind = "fake", size = "1MiB" } + +[[artifact.psc_rot_bootloader]] +name = "fake-psc-rot-bootloader" +version = "1.0.0" +source = { kind = "fake", size = "1MiB" } + +[[artifact.switch_rot_bootloader]] +name = "fake-switch-rot-bootloader" +version = "1.0.0" +source = { kind = "fake", size = "1MiB" } + + diff --git a/update-common/src/artifacts/update_plan.rs b/update-common/src/artifacts/update_plan.rs index c5b171d648..ae5a582be3 100644 --- a/update-common/src/artifacts/update_plan.rs +++ b/update-common/src/artifacts/update_plan.rs @@ -44,12 +44,15 @@ pub struct UpdatePlan { pub gimlet_sp: BTreeMap, pub gimlet_rot_a: Vec, pub gimlet_rot_b: Vec, + pub gimlet_rot_bootloader: Vec, pub psc_sp: BTreeMap, pub psc_rot_a: Vec, pub psc_rot_b: Vec, + pub psc_rot_bootloader: Vec, pub sidecar_sp: BTreeMap, pub sidecar_rot_a: Vec, pub sidecar_rot_b: Vec, + pub sidecar_rot_bootloader: Vec, // Note: The Trampoline image is broken into phase1/phase2 as part of our // update plan (because they go to different destinations), but the two @@ -84,12 +87,15 @@ pub struct UpdatePlanBuilder<'a> { gimlet_sp: BTreeMap, gimlet_rot_a: Vec, gimlet_rot_b: Vec, + gimlet_rot_bootloader: Vec, psc_sp: BTreeMap, psc_rot_a: Vec, psc_rot_b: Vec, + psc_rot_bootloader: Vec, sidecar_sp: BTreeMap, sidecar_rot_a: Vec, sidecar_rot_b: Vec, + sidecar_rot_bootloader: Vec, // We always send phase 1 images (regardless of host or trampoline) to the // SP via MGS, so we retain their data. @@ -130,12 +136,15 @@ impl<'a> UpdatePlanBuilder<'a> { gimlet_sp: BTreeMap::new(), gimlet_rot_a: Vec::new(), gimlet_rot_b: Vec::new(), + gimlet_rot_bootloader: Vec::new(), psc_sp: BTreeMap::new(), psc_rot_a: Vec::new(), psc_rot_b: Vec::new(), + psc_rot_bootloader: Vec::new(), sidecar_sp: BTreeMap::new(), sidecar_rot_a: Vec::new(), sidecar_rot_b: Vec::new(), + sidecar_rot_bootloader: Vec::new(), host_phase_1: None, trampoline_phase_1: None, trampoline_phase_2: None, @@ -187,6 +196,17 @@ impl<'a> UpdatePlanBuilder<'a> { | KnownArtifactKind::SwitchRot => { self.add_rot_artifact(artifact_id, artifact_kind, stream).await } + KnownArtifactKind::GimletRotBootloader + | KnownArtifactKind::PscRotBootloader + | KnownArtifactKind::SwitchRotBootloader => { + self.add_rot_bootloader_artifact( + artifact_id, + artifact_kind, + artifact_hash, + stream, + ) + .await + } KnownArtifactKind::Host => { self.add_host_artifact(artifact_id, stream) } @@ -221,7 +241,10 @@ impl<'a> UpdatePlanBuilder<'a> { | KnownArtifactKind::Trampoline | KnownArtifactKind::ControlPlane | KnownArtifactKind::PscRot - | KnownArtifactKind::SwitchRot => unreachable!(), + | KnownArtifactKind::SwitchRot + | KnownArtifactKind::GimletRotBootloader + | KnownArtifactKind::PscRotBootloader + | KnownArtifactKind::SwitchRotBootloader => unreachable!(), }; let mut stream = std::pin::pin!(stream); @@ -274,6 +297,74 @@ impl<'a> UpdatePlanBuilder<'a> { Ok(()) } + async fn add_rot_bootloader_artifact( + &mut self, + artifact_id: ArtifactId, + artifact_kind: KnownArtifactKind, + artifact_hash: ArtifactHash, + stream: impl Stream> + Send, + ) -> Result<(), RepositoryError> { + // We're only called with an RoT bootloader kind. + let (bootloader, bootloader_kind) = match artifact_kind { + KnownArtifactKind::GimletRotBootloader => ( + &mut self.gimlet_rot_bootloader, + ArtifactKind::GIMLET_ROT_STAGE0, + ), + KnownArtifactKind::PscRotBootloader => { + (&mut self.psc_rot_bootloader, ArtifactKind::PSC_ROT_STAGE0) + } + KnownArtifactKind::SwitchRotBootloader => ( + &mut self.sidecar_rot_bootloader, + ArtifactKind::SWITCH_ROT_STAGE0, + ), + KnownArtifactKind::GimletRot + | KnownArtifactKind::Host + | KnownArtifactKind::Trampoline + | KnownArtifactKind::ControlPlane + | KnownArtifactKind::PscRot + | KnownArtifactKind::SwitchRot + | KnownArtifactKind::GimletSp + | KnownArtifactKind::PscSp + | KnownArtifactKind::SwitchSp => unreachable!(), + }; + + let mut stream = std::pin::pin!(stream); + + // RoT images are small, and hubtools wants a `&[u8]` to parse, so we'll + // read the whole thing into memory. + let mut data = Vec::new(); + while let Some(res) = stream.next().await { + let chunk = res.map_err(|error| RepositoryError::ReadArtifact { + kind: artifact_kind.into(), + error: Box::new(error), + })?; + data.extend_from_slice(&chunk); + } + + let artifact_hash_id = + ArtifactHashId { kind: artifact_kind.into(), hash: artifact_hash }; + let data = self + .extracted_artifacts + .store( + artifact_hash_id, + futures::stream::iter([Ok(Bytes::from(data))]), + ) + .await?; + bootloader.push(ArtifactIdData { + id: artifact_id.clone(), + data: data.clone(), + }); + + self.record_extracted_artifact( + artifact_id, + data, + bootloader_kind, + self.log, + )?; + + Ok(()) + } + async fn add_rot_artifact( &mut self, artifact_id: ArtifactId, @@ -305,7 +396,10 @@ impl<'a> UpdatePlanBuilder<'a> { | KnownArtifactKind::Trampoline | KnownArtifactKind::ControlPlane | KnownArtifactKind::PscSp - | KnownArtifactKind::SwitchSp => unreachable!(), + | KnownArtifactKind::SwitchSp + | KnownArtifactKind::GimletRotBootloader + | KnownArtifactKind::SwitchRotBootloader + | KnownArtifactKind::PscRotBootloader => unreachable!(), }; let (rot_a_data, rot_b_data) = Self::extract_nested_artifact_pair( @@ -694,6 +788,18 @@ impl<'a> UpdatePlanBuilder<'a> { KnownArtifactKind::SwitchRot, self.sidecar_rot_a.is_empty() || self.sidecar_rot_b.is_empty(), ), + ( + KnownArtifactKind::GimletRotBootloader, + self.gimlet_rot_bootloader.is_empty(), + ), + ( + KnownArtifactKind::PscRotBootloader, + self.psc_rot_bootloader.is_empty(), + ), + ( + KnownArtifactKind::SwitchRotBootloader, + self.sidecar_rot_bootloader.is_empty(), + ), ] { if no_artifacts { return Err(RepositoryError::MissingArtifactKind(kind)); @@ -732,6 +838,37 @@ impl<'a> UpdatePlanBuilder<'a> { } } + // Same check for the RoT bootloader. We are explicitly treating the + // bootloader as distinct from the main A/B images here. + for (kind, mut single_board_rot_artifacts) in [ + ( + KnownArtifactKind::GimletRotBootloader, + self.gimlet_rot_bootloader.iter(), + ), + ( + KnownArtifactKind::PscRotBootloader, + self.psc_rot_bootloader.iter(), + ), + ( + KnownArtifactKind::SwitchRotBootloader, + self.sidecar_rot_bootloader.iter(), + ), + ] { + // We know each of these iterators has at least 1 element (checked + // above) so we can safely unwrap the first. + let version = + &single_board_rot_artifacts.next().unwrap().id.version; + for artifact in single_board_rot_artifacts { + if artifact.id.version != *version { + return Err(RepositoryError::MultipleVersionsPresent { + kind, + v1: version.clone(), + v2: artifact.id.version.clone(), + }); + } + } + } + // Repeat the same version check for all SP images. (This is a separate // loop because the types of the iterators don't match.) for (kind, mut single_board_sp_artifacts) in [ @@ -758,12 +895,15 @@ impl<'a> UpdatePlanBuilder<'a> { gimlet_sp: self.gimlet_sp, // checked above gimlet_rot_a: self.gimlet_rot_a, // checked above gimlet_rot_b: self.gimlet_rot_b, // checked above + gimlet_rot_bootloader: self.gimlet_rot_bootloader, // checked above psc_sp: self.psc_sp, // checked above psc_rot_a: self.psc_rot_a, // checked above psc_rot_b: self.psc_rot_b, // checked above + psc_rot_bootloader: self.psc_rot_bootloader, // checked above sidecar_sp: self.sidecar_sp, // checked above sidecar_rot_a: self.sidecar_rot_a, // checked above sidecar_rot_b: self.sidecar_rot_b, // checked above + sidecar_rot_bootloader: self.sidecar_rot_bootloader, // checked above host_phase_1: self.host_phase_1.ok_or( RepositoryError::MissingArtifactKind(KnownArtifactKind::Host), )?, @@ -941,6 +1081,22 @@ mod tests { builder.build_to_vec().unwrap() } + fn make_fake_rot_bootloader_image(board: &str, sign: &str) -> Vec { + use hubtools::{CabooseBuilder, HubrisArchiveBuilder}; + + let caboose = CabooseBuilder::default() + .git_commit("this-is-fake-data") + .board(board) + .version("0.0.0") + .name(board) + .sign(sign) + .build(); + + let mut builder = HubrisArchiveBuilder::with_fake_image(); + builder.write_caboose(caboose.as_slice()).unwrap(); + builder.build_to_vec().unwrap() + } + // See documentation for extract_nested_artifact_pair for why multi_thread // is required. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -1077,6 +1233,40 @@ mod tests { .unwrap(); } + let gimlet_rot_bootloader = + make_fake_rot_bootloader_image("test-gimlet-a", "test-gimlet-a"); + let psc_rot_bootloader = + make_fake_rot_bootloader_image("test-psc-a", "test-psc-a"); + let switch_rot_bootloader = + make_fake_rot_bootloader_image("test-sidecar-a", "test-sidecar-a"); + + for (kind, artifact) in [ + ( + KnownArtifactKind::GimletRotBootloader, + gimlet_rot_bootloader.clone(), + ), + (KnownArtifactKind::PscRotBootloader, psc_rot_bootloader.clone()), + ( + KnownArtifactKind::SwitchRotBootloader, + switch_rot_bootloader.clone(), + ), + ] { + let hash = ArtifactHash(Sha256::digest(&artifact).into()); + let id = ArtifactId { + name: format!("{kind:?}"), + version: VERSION_0, + kind: kind.into(), + }; + plan_builder + .add_artifact( + id, + hash, + futures::stream::iter([Ok(Bytes::from(artifact))]), + ) + .await + .unwrap(); + } + let UpdatePlanBuildOutput { plan, by_id, .. } = plan_builder.build().unwrap(); @@ -1142,7 +1332,10 @@ mod tests { | KnownArtifactKind::Trampoline | KnownArtifactKind::GimletRot | KnownArtifactKind::PscRot - | KnownArtifactKind::SwitchRot => {} + | KnownArtifactKind::SwitchRot + | KnownArtifactKind::SwitchRotBootloader + | KnownArtifactKind::GimletRotBootloader + | KnownArtifactKind::PscRotBootloader => {} } } @@ -1186,6 +1379,19 @@ mod tests { sidecar_rot.archive_b ); + assert_eq!( + read_to_vec(&plan.gimlet_rot_bootloader[0].data).await, + gimlet_rot_bootloader + ); + assert_eq!( + read_to_vec(&plan.sidecar_rot_bootloader[0].data).await, + switch_rot_bootloader + ); + assert_eq!( + read_to_vec(&plan.psc_rot_bootloader[0].data).await, + psc_rot_bootloader + ); + logctx.cleanup_successful(); } diff --git a/wicket-common/src/update_events.rs b/wicket-common/src/update_events.rs index fe92887646..630ad2d905 100644 --- a/wicket-common/src/update_events.rs +++ b/wicket-common/src/update_events.rs @@ -32,6 +32,7 @@ pub enum WicketdEngineSpec {} )] #[serde(tag = "component", rename_all = "snake_case")] pub enum UpdateComponent { + RotBootloader, Rot, Sp, Host, @@ -42,6 +43,7 @@ pub enum UpdateComponent { pub enum UpdateStepId { TestStep, SetHostPowerState { state: PowerState }, + InterrogateRotBootloader, InterrogateRot, InterrogateSp, SpComponentUpdate, @@ -257,6 +259,21 @@ pub enum SpComponentUpdateTerminalError { }, #[error("RoT booted into unexpected slot {active_slot}")] RotUnexpectedActiveSlot { active_slot: u16 }, + #[error("Getting RoT boot info failed")] + GetRotBootInfoFailed { + #[source] + error: anyhow::Error, + }, + #[error("Unexpected error returned from RoT bootloader update")] + RotBootloaderError { + #[source] + error: anyhow::Error, + }, + #[error("setting currently-active RoT bootloader slot failed")] + SetRotBootloaderActiveSlotFailed { + #[source] + error: anyhow::Error, + }, } impl update_engine::AsError for SpComponentUpdateTerminalError { diff --git a/wicket/README.md b/wicket/README.md index 0a24acbe8e..fc1c93fe83 100644 --- a/wicket/README.md +++ b/wicket/README.md @@ -148,7 +148,18 @@ it on an as-needed basis. ### Using a real SP -TODO +The easiest way is to change the mgs config to point to a running SP instead +of a simulated SP + +``` +[[switch.port]] +kind = "simulated" +fake-interface = "fake-sled1" +# Your SP address here +addr = "[fe80::c1d:93ff:fe20:ffe0%2]:11111" +ignition-target = 3 +location = { switch0 = ["sled", 1], switch1 = ["sled", 1] } +``` ### Running wicketd diff --git a/wicket/src/cli/rack_update.rs b/wicket/src/cli/rack_update.rs index ccacea0e38..44a2076b22 100644 --- a/wicket/src/cli/rack_update.rs +++ b/wicket/src/cli/rack_update.rs @@ -98,6 +98,10 @@ pub(crate) struct StartRackUpdateArgs { #[clap(flatten)] component_ids: ComponentIdSelector, + /// Force update the RoT Bootloader even if the version is the same. + #[clap(long, help_heading = "Update options")] + force_update_rot_bootloader: bool, + /// Force update the RoT even if the version is the same. #[clap(long, help_heading = "Update options")] force_update_rot: bool, @@ -125,6 +129,7 @@ impl StartRackUpdateArgs { let update_ids = self.component_ids.to_component_ids()?; let options = CreateStartUpdateOptions { + force_update_rot_bootloader: self.force_update_rot_bootloader, force_update_rot: self.force_update_rot, force_update_sp: self.force_update_sp, } diff --git a/wicket/src/runner.rs b/wicket/src/runner.rs index e83d321459..77fbb82df8 100644 --- a/wicket/src/runner.rs +++ b/wicket/src/runner.rs @@ -176,6 +176,10 @@ impl RunnerCore { Action::StartUpdate(component_id) => { if let Some(wicketd) = wicketd { let options = CreateStartUpdateOptions { + force_update_rot_bootloader: self + .state + .force_update_state + .force_update_rot_bootloader, force_update_rot: self .state .force_update_state diff --git a/wicket/src/state/force_update.rs b/wicket/src/state/force_update.rs index 72533f1378..feafac88a7 100644 --- a/wicket/src/state/force_update.rs +++ b/wicket/src/state/force_update.rs @@ -7,6 +7,7 @@ use wicket_common::update_events::UpdateComponent; #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct ForceUpdateState { + pub force_update_rot_bootloader: bool, pub force_update_rot: bool, pub force_update_sp: bool, selected_component: UpdateComponent, @@ -15,9 +16,10 @@ pub struct ForceUpdateState { impl Default for ForceUpdateState { fn default() -> Self { Self { + force_update_rot_bootloader: false, force_update_rot: false, force_update_sp: false, - selected_component: UpdateComponent::Rot, + selected_component: UpdateComponent::RotBootloader, } } } @@ -28,20 +30,29 @@ impl ForceUpdateState { } pub fn next_component(&mut self) { - if self.selected_component == UpdateComponent::Rot { - self.selected_component = UpdateComponent::Sp; - } else { - self.selected_component = UpdateComponent::Rot; - } + self.selected_component = match self.selected_component { + UpdateComponent::RotBootloader => UpdateComponent::Rot, + UpdateComponent::Rot => UpdateComponent::Sp, + UpdateComponent::Sp => UpdateComponent::RotBootloader, + _ => unreachable!(), + }; } pub fn prev_component(&mut self) { - // We only have 2 components; next/prev are both toggles. - self.next_component(); + self.selected_component = match self.selected_component { + UpdateComponent::RotBootloader => UpdateComponent::Sp, + UpdateComponent::Rot => UpdateComponent::RotBootloader, + UpdateComponent::Sp => UpdateComponent::Rot, + _ => unreachable!(), + }; } pub fn toggle(&mut self, component: UpdateComponent) { match component { + UpdateComponent::RotBootloader => { + self.force_update_rot_bootloader = + !self.force_update_rot_bootloader + } UpdateComponent::Rot => { self.force_update_rot = !self.force_update_rot; } diff --git a/wicket/src/state/inventory.rs b/wicket/src/state/inventory.rs index 5cfe536dfb..0ab187cc48 100644 --- a/wicket/src/state/inventory.rs +++ b/wicket/src/state/inventory.rs @@ -171,6 +171,21 @@ impl Component { self.sp().rot.as_ref().and_then(|rot| rot.caboose_b.as_ref()), ) } + + pub fn stage0_version(&self) -> String { + version_or_unknown( + self.sp().rot.as_ref().and_then(|rot| rot.caboose_stage0.as_ref()), + ) + } + + pub fn stage0next_version(&self) -> String { + version_or_unknown( + self.sp() + .rot + .as_ref() + .and_then(|rot| rot.caboose_stage0next.as_ref()), + ) + } } /// The component type and its slot. @@ -256,6 +271,14 @@ impl ComponentId { } } + pub fn rot_bootloader_known_artifact_kind(&self) -> KnownArtifactKind { + match self { + ComponentId::Sled(_) => KnownArtifactKind::GimletRotBootloader, + ComponentId::Switch(_) => KnownArtifactKind::SwitchRotBootloader, + ComponentId::Psc(_) => KnownArtifactKind::PscRotBootloader, + } + } + pub fn to_string_uppercase(&self) -> String { let mut s = self.to_string(); s.make_ascii_uppercase(); diff --git a/wicket/src/state/update.rs b/wicket/src/state/update.rs index 77bbdd83d2..31876365e2 100644 --- a/wicket/src/state/update.rs +++ b/wicket/src/state/update.rs @@ -46,6 +46,7 @@ impl RackUpdateState { *id, vec![ UpdateComponent::Rot, + UpdateComponent::RotBootloader, UpdateComponent::Sp, UpdateComponent::Host, ], @@ -55,14 +56,22 @@ impl RackUpdateState { *id, UpdateItem::new( *id, - vec![UpdateComponent::Rot, UpdateComponent::Sp], + vec![ + UpdateComponent::Rot, + UpdateComponent::RotBootloader, + UpdateComponent::Sp, + ], ), ), ComponentId::Psc(_) => ( *id, UpdateItem::new( *id, - vec![UpdateComponent::Rot, UpdateComponent::Sp], + vec![ + UpdateComponent::Rot, + UpdateComponent::RotBootloader, + UpdateComponent::Sp, + ], ), ), }) @@ -429,6 +438,7 @@ fn update_component_state( #[allow(unused)] pub fn update_component_title(component: UpdateComponent) -> &'static str { match component { + UpdateComponent::RotBootloader => "ROT_BOOTLOADER", UpdateComponent::Rot => "ROT", UpdateComponent::Sp => "SP", UpdateComponent::Host => "HOST", @@ -436,6 +446,7 @@ pub fn update_component_title(component: UpdateComponent) -> &'static str { } pub struct CreateStartUpdateOptions { + pub(crate) force_update_rot_bootloader: bool, pub(crate) force_update_rot: bool, pub(crate) force_update_sp: bool, } @@ -454,7 +465,9 @@ impl CreateStartUpdateOptions { as a u64", ) }); - + let test_simulate_rot_bootloader_result = get_update_simulated_result( + "WICKET_UPDATE_TEST_SIMULATE_ROT_BOOTLOADER_RESULT", + )?; let test_simulate_rot_result = get_update_simulated_result( "WICKET_UPDATE_TEST_SIMULATE_ROT_RESULT", )?; @@ -465,8 +478,10 @@ impl CreateStartUpdateOptions { Ok(StartUpdateOptions { test_error, test_step_seconds, + test_simulate_rot_bootloader_result, test_simulate_rot_result, test_simulate_sp_result, + skip_rot_bootloader_version_check: self.force_update_rot_bootloader, skip_rot_version_check: self.force_update_rot, skip_sp_version_check: self.force_update_sp, }) diff --git a/wicket/src/ui/panes/overview.rs b/wicket/src/ui/panes/overview.rs index 7d60c41772..45d02311aa 100644 --- a/wicket/src/ui/panes/overview.rs +++ b/wicket/src/ui/panes/overview.rs @@ -770,12 +770,12 @@ fn inventory_description(component: &Component) -> Text { .into(), ); } - if let Some(_) = slot_a_error { + if let Some(e) = slot_a_error { spans.push( vec![ nest_bullet(), Span::styled("Image status: ", label_style), - Span::styled("Error: ", bad_style), + Span::styled(format!("Error: {e:?}"), bad_style), ] .into(), ); @@ -813,12 +813,12 @@ fn inventory_description(component: &Component) -> Text { .into(), ); } - if let Some(_) = slot_b_error { + if let Some(e) = slot_b_error { spans.push( vec![ nest_bullet(), Span::styled("Image status: ", label_style), - Span::styled("Error: ", bad_style), + Span::styled(format!("Error: {e:?}"), bad_style), ] .into(), ); @@ -857,12 +857,12 @@ fn inventory_description(component: &Component) -> Text { .into(), ); } - if let Some(_) = stage0_error { + if let Some(e) = stage0_error { spans.push( vec![ nest_bullet(), Span::styled("Image status: ", label_style), - Span::styled("Error: ", bad_style), + Span::styled(format!("Error: {e:?}"), bad_style), ] .into(), ); @@ -902,12 +902,12 @@ fn inventory_description(component: &Component) -> Text { .into(), ); } - if let Some(_) = stage0next_error { + if let Some(e) = stage0next_error { spans.push( vec![ nest_bullet(), Span::styled("Image status: ", label_style), - Span::styled("Error: ", bad_style), + Span::styled(format!("Error: {e:?}"), bad_style), ] .into(), ); diff --git a/wicket/src/ui/panes/update.rs b/wicket/src/ui/panes/update.rs index 664c647eac..712ba778b5 100644 --- a/wicket/src/ui/panes/update.rs +++ b/wicket/src/ui/panes/update.rs @@ -1711,6 +1711,7 @@ struct ComponentForceUpdateSelectionState { } struct ForceUpdateSelectionState { + rot_bootloader: Option, rot: Option, sp: Option, } @@ -1722,6 +1723,7 @@ impl From<&'_ State> for ForceUpdateSelectionState { let inventory = &state.inventory; let update_item = &state.update_state.items[&component_id]; + let mut rot_bootloader = None; let mut rot = None; let mut sp = None; @@ -1737,6 +1739,22 @@ impl From<&'_ State> for ForceUpdateSelectionState { let installed_version = active_installed_version(&component_id, component, inventory); match component { + UpdateComponent::RotBootloader => { + assert!( + rot_bootloader.is_none(), + "update item contains multiple RoT bootloader entries" + ); + if artifact_version == installed_version { + rot_bootloader = + Some(ComponentForceUpdateSelectionState { + version: artifact_version, + toggled_on: state + .force_update_state + .force_update_rot_bootloader, + selected: false, // set below + }); + } + } UpdateComponent::Rot => { assert!( rot.is_none(), @@ -1773,28 +1791,63 @@ impl From<&'_ State> for ForceUpdateSelectionState { // If we only have one force-updateable component, mark it as selected; // otherwise, respect the option currently selected in `State`. - match (rot.as_mut(), sp.as_mut()) { - (Some(rot), None) => rot.selected = true, - (None, Some(sp)) => sp.selected = true, - (Some(rot), Some(sp)) => { + match (rot_bootloader.as_mut(), rot.as_mut(), sp.as_mut()) { + (Some(rot_bootloader), None, None) => { + rot_bootloader.selected = true + } + (None, Some(rot), None) => rot.selected = true, + (None, None, Some(sp)) => sp.selected = true, + // Two selected + (Some(rot_bootloader), Some(rot), None) => { + if state.force_update_state.selected_component() + == UpdateComponent::RotBootloader + { + rot_bootloader.selected = true + } else { + rot.selected = true + } + } + (None, Some(rot), Some(sp)) => { if state.force_update_state.selected_component() == UpdateComponent::Rot { - rot.selected = true; + rot.selected = true } else { - sp.selected = true; + sp.selected = true } } - (None, None) => (), + (Some(rot_bootloader), None, Some(sp)) => { + if state.force_update_state.selected_component() + == UpdateComponent::RotBootloader + { + rot_bootloader.selected = true + } else { + sp.selected = true + } + } + // All three + (Some(rot_bootloader), Some(rot), Some(sp)) => { + match state.force_update_state.selected_component() { + UpdateComponent::Rot => rot.selected = true, + UpdateComponent::Sp => sp.selected = true, + UpdateComponent::RotBootloader => { + rot_bootloader.selected = true + } + _ => (), + } + } + (None, None, None) => (), } - Self { rot, sp } + Self { rot_bootloader, rot, sp } } } impl ForceUpdateSelectionState { fn num_spans(&self) -> usize { - usize::from(self.rot.is_some()) + usize::from(self.sp.is_some()) + usize::from(self.rot.is_some()) + + usize::from(self.sp.is_some()) + + usize::from(self.rot_bootloader.is_some()) } fn next_component(&self, state: &mut State) { @@ -1826,6 +1879,13 @@ impl ForceUpdateSelectionState { state.force_update_state.toggle(UpdateComponent::Rot); } else if self.sp.as_ref().map(|sp| sp.selected).unwrap_or(false) { state.force_update_state.toggle(UpdateComponent::Sp); + } else if self + .rot_bootloader + .as_ref() + .map(|rot_bootloader| rot_bootloader.selected) + .unwrap_or(false) + { + state.force_update_state.toggle(UpdateComponent::RotBootloader); } } @@ -1850,6 +1910,9 @@ impl ForceUpdateSelectionState { } let mut spans = Vec::new(); + if let Some(rot_bootloader) = self.rot_bootloader.as_ref() { + spans.push(make_spans("RoT Bootloader", rot_bootloader)); + } if let Some(rot) = self.rot.as_ref() { spans.push(make_spans("RoT", rot)); } @@ -2201,6 +2264,10 @@ fn active_installed_version( ) -> String { let component = inventory.get_inventory(id); match update_component { + UpdateComponent::RotBootloader => component.map_or_else( + || "UNKNOWN".to_string(), + |component| component.stage0_version(), + ), UpdateComponent::Sp => component.map_or_else( || "UNKNOWN".to_string(), |component| component.sp_version_active(), @@ -2254,6 +2321,26 @@ fn all_installed_versions( ] }, ), + UpdateComponent::RotBootloader => component.map_or_else( + || { + vec![InstalledVersion { + title: base_title.into(), + version: "UNKNOWN".into(), + }] + }, + |component| { + vec![ + InstalledVersion { + title: base_title.into(), + version: component.stage0_version().into(), + }, + InstalledVersion { + title: format!("{base_title}_NEXT").into(), + version: component.stage0next_version().into(), + }, + ] + }, + ), UpdateComponent::Rot => component.map_or_else( || { vec![InstalledVersion { @@ -2301,6 +2388,9 @@ fn artifact_version( versions: &BTreeMap, ) -> String { let artifact = match (id, component) { + (ComponentId::Sled(_), UpdateComponent::RotBootloader) => { + KnownArtifactKind::GimletRotBootloader + } (ComponentId::Sled(_), UpdateComponent::Rot) => { KnownArtifactKind::GimletRot } @@ -2310,12 +2400,18 @@ fn artifact_version( (ComponentId::Sled(_), UpdateComponent::Host) => { KnownArtifactKind::Host } + (ComponentId::Switch(_), UpdateComponent::RotBootloader) => { + KnownArtifactKind::SwitchRotBootloader + } (ComponentId::Switch(_), UpdateComponent::Rot) => { KnownArtifactKind::SwitchRot } (ComponentId::Switch(_), UpdateComponent::Sp) => { KnownArtifactKind::SwitchSp } + (ComponentId::Psc(_), UpdateComponent::RotBootloader) => { + KnownArtifactKind::PscRotBootloader + } (ComponentId::Psc(_), UpdateComponent::Rot) => { KnownArtifactKind::PscRot } @@ -2363,7 +2459,7 @@ impl Control for UpdatePane { [ Constraint::Length(3), Constraint::Length(3), - Constraint::Length(6), + Constraint::Length(8), Constraint::Min(0), Constraint::Length(3), ] diff --git a/wicketd/src/http_entrypoints.rs b/wicketd/src/http_entrypoints.rs index 999428ff06..001974e085 100644 --- a/wicketd/src/http_entrypoints.rs +++ b/wicketd/src/http_entrypoints.rs @@ -697,6 +697,12 @@ pub(crate) struct StartUpdateOptions { /// This is used for testing. pub(crate) test_step_seconds: Option, + /// If passed in, simulates a result for the RoT Bootloader update. + /// + /// This is used for testing. + pub(crate) test_simulate_rot_bootloader_result: + Option, + /// If passed in, simulates a result for the RoT update. /// /// This is used for testing. @@ -709,7 +715,10 @@ pub(crate) struct StartUpdateOptions { /// If true, skip the check on the current RoT version and always update it /// regardless of whether the update appears to be neeeded. - #[allow(dead_code)] // TODO actually use this + pub(crate) skip_rot_bootloader_version_check: bool, + + /// If true, skip the check on the current RoT version and always update it + /// regardless of whether the update appears to be neeeded. pub(crate) skip_rot_version_check: bool, /// If true, skip the check on the current SP version and always update it diff --git a/wicketd/src/update_tracker.rs b/wicketd/src/update_tracker.rs index 10253bc2f7..6de7090ce4 100644 --- a/wicketd/src/update_tracker.rs +++ b/wicketd/src/update_tracker.rs @@ -23,12 +23,15 @@ use display_error_chain::DisplayErrorChain; use dropshot::HttpError; use futures::Stream; use futures::TryFutureExt; +use gateway_client::types::GetRotBootInfoParams; use gateway_client::types::HostPhase2Progress; use gateway_client::types::HostPhase2RecoveryImageId; use gateway_client::types::HostStartupOptions; use gateway_client::types::InstallinatorImageId; use gateway_client::types::PowerState; use gateway_client::types::RotCfpaSlot; +use gateway_client::types::RotImageError; +use gateway_client::types::RotState; use gateway_client::types::SpComponentFirmwareSlot; use gateway_client::types::SpIdentifier; use gateway_client::types::SpType; @@ -862,19 +865,45 @@ impl UpdateDriver { define_test_steps(&engine, secs); } - let (rot_a, rot_b, sp_artifacts) = match update_cx.sp.type_ { - SpType::Sled => { - (&plan.gimlet_rot_a, &plan.gimlet_rot_b, &plan.gimlet_sp) - } - SpType::Power => (&plan.psc_rot_a, &plan.psc_rot_b, &plan.psc_sp), - SpType::Switch => { - (&plan.sidecar_rot_a, &plan.sidecar_rot_b, &plan.sidecar_sp) - } - }; + let (rot_a, rot_b, sp_artifacts, rot_bootloader) = + match update_cx.sp.type_ { + SpType::Sled => ( + &plan.gimlet_rot_a, + &plan.gimlet_rot_b, + &plan.gimlet_sp, + &plan.gimlet_rot_bootloader, + ), + SpType::Power => ( + &plan.psc_rot_a, + &plan.psc_rot_b, + &plan.psc_sp, + &plan.psc_rot_bootloader, + ), + SpType::Switch => ( + &plan.sidecar_rot_a, + &plan.sidecar_rot_b, + &plan.sidecar_sp, + &plan.sidecar_rot_bootloader, + ), + }; + let rot_bootloader_registrar = + engine.for_component(UpdateComponent::RotBootloader); let rot_registrar = engine.for_component(UpdateComponent::Rot); let sp_registrar = engine.for_component(UpdateComponent::Sp); + // There are some extra checks and verifications needed to + // before we can update the RoT bootloader + let rot_bootloader_interrogation = rot_bootloader_registrar + .new_step( + UpdateStepId::InterrogateRot, + "Checking current RoT bootloader version", + move |_cx| async move { + update_cx.interrogate_rot_bootloader(rot_bootloader).await + }, + ) + .register(); + // To update the RoT, we have to know which slot (A or B) it is // currently executing; we must update the _other_ slot. We also want to // know its current version (so we can skip updating if we only need to @@ -946,6 +975,94 @@ impl UpdateDriver { }, ) .register(); + + // Send the bootloader update to the RoT. + let inner_cx = SpComponentUpdateContext::new( + update_cx, + UpdateComponent::RotBootloader, + ); + rot_bootloader_registrar + .new_step( + UpdateStepId::SpComponentUpdate, + "Updating RoT bootloader", + move |cx| async move { + if let Some(result) = opts.test_simulate_rot_bootloader_result { + return simulate_result(result); + } + + let rot_bootloader_interrogation = + match rot_bootloader_interrogation.into_value(cx.token()).await { + Some(v) => v, + None => return StepSkipped::new( + (), + "Skipping bootloader update, check interrogation step", + ).into(), + }; + + let bootloader_has_this_version = rot_bootloader_interrogation + .active_version_matches_artifact_to_apply(); + + let sp_can_update = rot_bootloader_interrogation.sp_can_update_bootloader(&update_cx.mgs_client).await; + + if !sp_can_update { + return StepSkipped::new( + (), + "SP version needs to be upgraded before RoT bootloader can be updated", + ) + .into(); + + } + + // If this RoT already has this version, skip the rest of + // this step, UNLESS we've been told to skip this version + // check. + if bootloader_has_this_version && !opts.skip_rot_bootloader_version_check { + return StepSkipped::new( + (), + format!( + "RoT bootloader already at version {}", + rot_bootloader_interrogation.available_artifacts_version, + ), + ) + .into(); + } + + let artifact_to_apply = rot_bootloader_interrogation + .choose_artifact_to_apply( + &update_cx.mgs_client, + &update_cx.log, + ) + .await?; + + cx.with_nested_engine(|engine| { + inner_cx.register_steps( + engine, + rot_bootloader_interrogation.slot_to_update, + artifact_to_apply, + ); + Ok(()) + }) + .await?; + + // If we updated despite the RoT already having the version + // we updated to, make this step return a warning with that + // message; otherwise, this is a normal success. + if bootloader_has_this_version { + StepWarning::new( + (), + format!( + "RoT bootloader updated despite already having version {}", + rot_bootloader_interrogation.available_artifacts_version + ), + ) + .into() + } else { + StepSuccess::new(()).into() + } + }, + ) + .register(); + // Send the update to the RoT. let inner_cx = SpComponentUpdateContext::new(update_cx, UpdateComponent::Rot); @@ -1588,6 +1705,43 @@ struct RotInterrogation { } impl RotInterrogation { + async fn sp_can_update_bootloader( + &self, + client: &gateway_client::Client, + ) -> bool { + let sp_caboose = client + .sp_component_caboose_get( + self.sp.type_, + self.sp.slot, + SpComponent::SP_ITSELF.const_as_str(), + 0, + ) + .await + .ok() + .map(|v| v.into_inner()); + + // Older versions of the SP have a bug that prevents setting + // the active slot for the RoT bootloader. Check for these + // and skip the update until the SP gets updated + const MIN_GIMLET_VERSION: SemverVersion = SemverVersion::new(1, 0, 21); + const MIN_SWITCH_VERSION: SemverVersion = SemverVersion::new(1, 0, 21); + const MIN_PSC_VERSION: SemverVersion = SemverVersion::new(1, 0, 20); + + match sp_caboose { + // If we can't get the SP caboose for whatever reason don't risk + // trying an update + None => false, + Some(caboose) => match caboose.version.parse::() { + Ok(vers) => match self.sp.type_ { + SpType::Sled => vers >= MIN_GIMLET_VERSION, + SpType::Switch => vers >= MIN_SWITCH_VERSION, + SpType::Power => vers >= MIN_PSC_VERSION, + }, + Err(_) => false, + }, + } + } + fn active_version_matches_artifact_to_apply(&self) -> bool { Some(&self.available_artifacts_version) == self.active_version.as_ref() } @@ -1599,6 +1753,9 @@ impl RotInterrogation { /// their CMPA/CFPA pages, if we fail to fetch them _and_ /// `available_artifacts` has exactly one item, we will return that one /// item. + /// + /// This is also applicable to the RoT bootloader which follows the + /// same vaildation method async fn choose_artifact_to_apply( &self, client: &gateway_client::Client, @@ -1844,6 +2001,151 @@ impl UpdateContext { }) } + async fn interrogate_rot_bootloader( + &self, + rot_bootloader: &[ArtifactIdData], + ) -> Result>, UpdateTerminalError> { + // We have a known set of bootloader FWID that don't have cabooses. + static KNOWN_MISSING_CABOOSE: [&str; 18] = [ + "1122095f4a3797db8a7d6279ae889ddde0316631f1f3bc204bdc39c2d75707af", + "1525832a663024f6421c13c0f7c7d9e9b32ebf433898565a2ad8112e7d237ead", + "29fc0d31e1739865c7f3d4bb5f5b86779db92a65a2decbd59e42f6e95dd84698", + "37aa40d0ea12e1290477a84014cd03dbc6fa9817223d1546a10847510d75c383", + "53cb91f4a3fbb69efa733a9eb326bd9f71c849782b0eea4306ebc66620158d44", + "60effb7fd6c4780138887e0d65c9e9b9c8447ce4ea3ea71e08194aec2847b185", + "77b8fc4308221dfe123d93431c21b57fa896db65c015ca82e22a337c7aa7cd77", + "77c2b94e3a83fc6b3c8924d38b0d23ac7c1e7a15defa910ee3f850b41af9ca4c", + "8c58b2272fe2da219ab0757ff27398b8d4a459eb4e75c32c782f98d684269352", + "9dd79a4e7609bd4af8e39a03f77b997b35f5050409a2ecd19de1e7d16184b1f3", + "b123a0f683f4e7b60238840139c9f3dbfe2b2c61597d9cdd4e92c718f7f98bb7", + "ba08df44e7282a1daeae2d9346b99ca741bfc2649c12aa8292f413a1c84d80b7", + "bfa9adfc127886aeaa1ac58d30c07c76e89592c29fc83dfa88062e7f3a48335e", + "c23a53858e94932a95945f28730e41ae4a2d1a8db4776283245eda143b6b2994", + "e7ec5dae7ac462cc7f7561a91ef244a2ece0894ff212995fcccb1e86438cb665", + "ee688a237a480e9fd111a7f70cc4c6f9ac837dcac65a01e7cfa29f7c28545d07", + "f31442015da37523a13ffaa173b4dfe0b069c6d890cf1c9748a898001fe4110e", + "fa73f26fb73b27b5db8f425320e206df5ebf3e137475d40be76b540ea8bd2af9", + ]; + + // We already validated at repo-upload time there is at least one RoT + // artifact available and that all available RoT artifacts are the same + // version, so we can unwrap the first artifact here and assume its + // version matches any subsequent artifacts. + // TODO this needs to be fixed for multi version to work! + let available_artifacts_version = rot_bootloader + .get(0) + .expect("no RoT artifacts available") + .id + .version + .clone(); + + let stage0_fwid = match self + .mgs_client + .sp_rot_boot_info( + self.sp.type_, + self.sp.slot, + SpComponent::ROT.const_as_str(), + &GetRotBootInfoParams { + version: + gateway_messages::RotBootInfo::HIGHEST_KNOWN_VERSION, + }, + ) + .await + { + Ok(v) => match v.into_inner() { + // the minimum we will ever return is 3 + RotState::V2 { .. } => unreachable!(), + RotState::V3 { stage0_fwid, .. } => stage0_fwid, + // ugh + RotState::CommunicationFailed { message } => { + return StepWarning::new( + None, + format!( + "Failed to communicate with the RoT: {message}. Will not proceed with update." + ), + ) + .into(); + } + }, + // If we can't run `rot_boot_info` there's a chance we can't do + // antything else with stage0 either + Err(e) => return StepWarning::new( + None, + format!("Failed to run `rot_boot_info`: {e:?}. Will not proceed with update."), + ) + .into(), + }; + + // Read the caboose of the currently running version (always 0) + // When updating from older stage0 we may not have a caboose so an error here + // need not be fatal + // TODO make this fatal at some point + let caboose = self + .mgs_client + .sp_component_caboose_get( + self.sp.type_, + self.sp.slot, + SpComponent::STAGE0.const_as_str(), + 0, + ) + .await + .map(|v| v.into_inner()) + .ok(); + + let available_artifacts = rot_bootloader.to_vec(); + let make_result = |active_version| { + Some(RotInterrogation { + // We always update slot 1 + slot_to_update: 1, + available_artifacts, + available_artifacts_version, + sp: self.sp, + active_version, + }) + }; + + match caboose { + Some(c) => { + let message = format!( + "RoT bootloader version {} (git commit {})", + c.version, c.git_commit + ); + + match c.version.parse::() { + Ok(version) => StepSuccess::new(make_result(Some(version))) + .with_message(message) + .into(), + Err(err) => StepWarning::new( + make_result(None), + format!( + "{message} (failed to parse RoT bootloader version: {err})" + ), + ) + .into(), + } + } + None => { + if KNOWN_MISSING_CABOOSE.contains(&stage0_fwid.as_str()) { + StepWarning::new( + make_result(None), + format!( + "fwid {stage0_fwid} is known to be missing a caboose." + ), + ) + .into() + } else { + StepWarning::new( + None, + format!( + "fwid {stage0_fwid} is _not_ supposed to be missing a caboose. Will not proceed with update" + ), + ) + .into() + } + } + } + } + async fn interrogate_rot( &self, rot_a: &[ArtifactIdData], @@ -1923,6 +2225,52 @@ impl UpdateContext { } } + /// Poll the RoT asking for its boot information. This is used to check + /// state after RoT bootloader updates + async fn wait_for_rot_boot_info( + &self, + timeout: Duration, + ) -> anyhow::Result<(Option, Option)> { + let mut ticker = tokio::time::interval(Duration::from_secs(1)); + + let start = Instant::now(); + loop { + ticker.tick().await; + match self.get_rot_boot_info().await { + Ok(state) => match state { + // the minimum we will ever return is 3 + RotState::V2 { .. } => unreachable!(), + RotState::V3 { stage0_error, stage0next_error, .. } => { + return Ok((stage0_error, stage0next_error)) + } + // ugh + RotState::CommunicationFailed { message } => { + if start.elapsed() < timeout { + warn!( + self.log, + "failed getting RoT boot info (will retry)"; + "error" => %message, + ); + } else { + return Err(anyhow!(message)); + } + } + }, + Err(error) => { + if start.elapsed() < timeout { + warn!( + self.log, + "failed getting RoT boot info (will retry)"; + "error" => %error, + ); + } else { + return Err(error); + } + } + } + } + } + /// Poll the RoT asking for its currently active slot, allowing failures up /// to a fixed timeout to give time for it to boot. /// @@ -1930,16 +2278,14 @@ impl UpdateContext { async fn wait_for_rot_reboot( &self, timeout: Duration, + component: &str, ) -> anyhow::Result { let mut ticker = tokio::time::interval(Duration::from_secs(1)); let start = Instant::now(); loop { ticker.tick().await; - match self - .get_component_active_slot(SpComponent::ROT.const_as_str()) - .await - { + match self.get_component_active_slot(component).await { Ok(slot) => return Ok(slot), Err(error) => { if start.elapsed() < timeout { @@ -2083,6 +2429,22 @@ impl UpdateContext { StepSuccess::new(()).into() } + async fn get_rot_boot_info(&self) -> anyhow::Result { + self.mgs_client + .sp_rot_boot_info( + self.sp.type_, + self.sp.slot, + SpComponent::ROT.const_as_str(), + &GetRotBootInfoParams { + version: + gateway_messages::RotBootInfo::HIGHEST_KNOWN_VERSION, + }, + ) + .await + .context("failed to get RoT boot info") + .map(|res| res.into_inner()) + } + async fn get_component_active_slot( &self, component: &str, @@ -2325,6 +2687,9 @@ impl<'a> SpComponentUpdateContext<'a> { let update_cx = self.update_cx; let component_name = match self.component { + UpdateComponent::RotBootloader => { + SpComponent::STAGE0.const_as_str() + } UpdateComponent::Rot => SpComponent::ROT.const_as_str(), UpdateComponent::Sp => SpComponent::SP_ITSELF.const_as_str(), UpdateComponent::Host => { @@ -2434,13 +2799,130 @@ impl<'a> SpComponentUpdateContext<'a> { // to stage updates for example, but for wicketd-driven recovery it's // fine to do this immediately.) match component { + UpdateComponent::RotBootloader => { + const WAIT_FOR_BOOT_TIMEOUT: Duration = Duration::from_secs(30); + + // We need to reset the RoT in order to check the signature on what we just + // updated + registrar + .new_step( + SpComponentUpdateStepId::Resetting, + "Resetting the RoT to check the bootloader signature", + move |_cx| async move { + update_cx + .reset_sp_component(SpComponent::ROT.const_as_str()) + .await + .map_err(|error| { + SpComponentUpdateTerminalError::RotResetFailed { + error, + } + })?; + StepSuccess::new(()).into() + }, + ) + .register(); + + registrar + .new_step( + SpComponentUpdateStepId::Resetting, + "Waiting for RoT to boot".to_string(), + move |_cx| async move { + let (_, stage0next_error) = update_cx + .wait_for_rot_boot_info(WAIT_FOR_BOOT_TIMEOUT) + .await + .map_err(|error| { + SpComponentUpdateTerminalError::GetRotBootInfoFailed { error } + })?; + + // check that stage0next is valid before we try to set the component + if let Some(error) = stage0next_error { + return Err(SpComponentUpdateTerminalError::RotBootloaderError { + error: anyhow!(format!("{error:?}")) + }); + } + StepSuccess::new(()).into() + }, + ) + .register(); + + // Actually set stage0 to use the new firmware + registrar + .new_step( + SpComponentUpdateStepId::SettingActiveBootSlot, + format!("Setting {component_name} active slot to {firmware_slot}"), + move |_cx| async move { + update_cx + .set_component_active_slot( + component_name, + firmware_slot, + true, + ) + .await + .map_err(|error| { + SpComponentUpdateTerminalError::SetRotBootloaderActiveSlotFailed { + error, + } + })?; + StepSuccess::new(()).into() + }, + ) + .register(); + + // Now reset (again) to boot into the new stage0 + registrar + .new_step( + SpComponentUpdateStepId::Resetting, + "Resetting the RoT to boot into the new bootloader", + move |_cx| async move { + update_cx + .reset_sp_component(SpComponent::ROT.const_as_str()) + .await + .map_err(|error| { + SpComponentUpdateTerminalError::RotResetFailed { + error, + } + })?; + StepSuccess::new(()).into() + }, + ) + .register(); + + registrar + .new_step( + SpComponentUpdateStepId::Resetting, + "Checking the new RoT bootloader".to_string(), + move |_cx| async move { + let (stage0_error, stage0next_error) = update_cx + .wait_for_rot_boot_info(WAIT_FOR_BOOT_TIMEOUT) + .await + .map_err(|error| { + SpComponentUpdateTerminalError::GetRotActiveSlotFailed { error } + })?; + + // Both the active and pending slots should be valid after this spot + if let Some(error) = stage0_error { + return Err(SpComponentUpdateTerminalError::RotBootloaderError { + error: anyhow!(format!("{error:?}")) + }); + } + if let Some(error) = stage0next_error { + return Err(SpComponentUpdateTerminalError::RotBootloaderError { + error: anyhow!(format!("{error:?}")) + }); + } + + StepSuccess::new(()).into() + }, + ) + .register(); + } UpdateComponent::Rot => { // Prior to rebooting the RoT, we have to tell it to boot into // the firmware slot we just updated. registrar .new_step( SpComponentUpdateStepId::SettingActiveBootSlot, - format!("Setting RoT active slot to {firmware_slot}"), + format!("Setting {component_name} active slot to {firmware_slot}"), move |_cx| async move { update_cx .set_component_active_slot( @@ -2463,7 +2945,7 @@ impl<'a> SpComponentUpdateContext<'a> { registrar .new_step( SpComponentUpdateStepId::Resetting, - "Resetting RoT", + format!("Resetting {component_name}"), move |_cx| async move { update_cx .reset_sp_component(component_name) @@ -2502,7 +2984,7 @@ impl<'a> SpComponentUpdateContext<'a> { const WAIT_FOR_BOOT_TIMEOUT: Duration = Duration::from_secs(30); let active_slot = update_cx - .wait_for_rot_reboot(WAIT_FOR_BOOT_TIMEOUT) + .wait_for_rot_reboot(WAIT_FOR_BOOT_TIMEOUT, component_name) .await .map_err(|error| { SpComponentUpdateTerminalError::GetRotActiveSlotFailed { error } @@ -2518,6 +3000,7 @@ impl<'a> SpComponentUpdateContext<'a> { } UpdateComponent::Sp => { // Nothing special to do on the SP - just reset it. + // TODO fixup the SP to also set the active slot registrar .new_step( SpComponentUpdateStepId::Resetting, From 92d65307c123ef078c42f5a86f054dfcffc267a6 Mon Sep 17 00:00:00 2001 From: iliana etaoin Date: Fri, 21 Jun 2024 08:50:19 -0700 Subject: [PATCH 12/26] fix `cargo doc` checks in CI (#5924) Fixes #5739. Also adds `--no-deps` because this is intended as a check to ensure the docs, if someone wants to generate them, are valid and build without warnings. Warnings in dependencies' docs are ignored anyway. --- .cargo/config.toml | 6 ++++++ .github/buildomat/build-and-test.sh | 2 +- .github/buildomat/jobs/clippy.sh | 2 +- .github/workflows/rust.yml | 2 +- nexus/auth/src/authz/api_resources.rs | 10 +++++----- nexus/db-queries/src/db/datastore/sled.rs | 4 ++-- nexus/db-queries/src/db/datastore/update.rs | 2 +- .../planning/src/blueprint_builder/builder.rs | 13 +++++++------ nexus/src/app/instance_network.rs | 3 ++- nexus/src/app/sagas/volume_delete.rs | 6 +++++- nexus/types/src/deployment/blueprint_diff.rs | 2 +- nexus/types/src/deployment/blueprint_display.rs | 3 +-- oximeter/db/src/oxql/ast/grammar.rs | 4 ++-- sled-agent/src/sim/instance.rs | 10 +++++----- wicket/src/ui/panes/update.rs | 2 +- 15 files changed, 41 insertions(+), 30 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index f658f146c9..c5b6fcd9d4 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -4,6 +4,12 @@ # binaries and the test suite. There's no need for typical library # documentation of public interfaces.) # +# NOTE: If you change this, also change the `RUSTDOCFLAGS` values in the various +# CI scripts: +# - .github/buildomat/build-and-test.sh +# - .github/buildomat/jobs/clippy.sh +# - .github/workflows/rust.yml +# [build] rustdocflags = "--document-private-items" diff --git a/.github/buildomat/build-and-test.sh b/.github/buildomat/build-and-test.sh index cc344522db..1e4b655cb9 100755 --- a/.github/buildomat/build-and-test.sh +++ b/.github/buildomat/build-and-test.sh @@ -54,7 +54,7 @@ ptime -m bash ./tools/install_builder_prerequisites.sh -y # banner build export RUSTFLAGS="-D warnings" -export RUSTDOCFLAGS="-D warnings" +export RUSTDOCFLAGS="--document-private-items -D warnings" # When running on illumos we need to pass an additional runpath that is # usually configured via ".cargo/config" but the `RUSTFLAGS` env variable # takes precedence. This path contains oxide specific libraries such as diff --git a/.github/buildomat/jobs/clippy.sh b/.github/buildomat/jobs/clippy.sh index 7da32ec331..71aa04c907 100755 --- a/.github/buildomat/jobs/clippy.sh +++ b/.github/buildomat/jobs/clippy.sh @@ -30,4 +30,4 @@ ptime -m bash ./tools/install_builder_prerequisites.sh -y banner clippy export CARGO_INCREMENTAL=0 ptime -m cargo xtask clippy -RUSTDOCFLAGS="-Dwarnings" ptime -m cargo doc --workspace +RUSTDOCFLAGS="--document-private-items -D warnings" ptime -m cargo doc --workspace --no-deps diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1888481ba2..2ef2783108 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -108,4 +108,4 @@ jobs: - name: Install Pre-Requisites run: ./tools/install_builder_prerequisites.sh -y - name: Test build documentation - run: RUSTDOCFLAGS="-Dwarnings" cargo doc --workspace + run: RUSTDOCFLAGS="--document-private-items -D warnings" cargo doc --workspace --no-deps diff --git a/nexus/auth/src/authz/api_resources.rs b/nexus/auth/src/authz/api_resources.rs index 98a24b68b5..f4c91dc544 100644 --- a/nexus/auth/src/authz/api_resources.rs +++ b/nexus/auth/src/authz/api_resources.rs @@ -5,11 +5,11 @@ //! Authz types for resources in the API hierarchy //! //! The general pattern in Nexus for working with an object is to look it up -//! (see [`crate::db::lookup::LookupPath`]) and get back a so-called `authz` -//! type. This type uniquely identifies the resource regardless of any other -//! changes (e.g., name change or moving it to a different parent collection). -//! The various datastore functions that modify API resources accept these -//! `authz` types. +//! (see `nexus_db_queries::db::lookup::LookupPath`) and get back a so-called +//! `authz` type. This type uniquely identifies the resource regardless of +//! any other changes (e.g., name change or moving it to a different parent +//! collection). The various datastore functions that modify API resources +//! accept these `authz` types. //! //! The `authz` types can be passed to //! [`crate::context::OpContext::authorize()`] to do an authorization check -- diff --git a/nexus/db-queries/src/db/datastore/sled.rs b/nexus/db-queries/src/db/datastore/sled.rs index bf43b9182d..381b25dc17 100644 --- a/nexus/db-queries/src/db/datastore/sled.rs +++ b/nexus/db-queries/src/db/datastore/sled.rs @@ -695,7 +695,7 @@ impl SledTransition { /// (which is always considered valid). /// /// For a more descriptive listing of valid transitions, see - /// [`test_sled_transitions`]. + /// `test_sled_transitions`. fn valid_old_policies(&self) -> Vec { use SledPolicy::*; use SledProvisionPolicy::*; @@ -731,7 +731,7 @@ impl SledTransition { /// (which is always considered valid). /// /// For a more descriptive listing of valid transitions, see - /// [`test_sled_transitions`]. + /// `test_sled_transitions`. fn valid_old_states(&self) -> Vec { use SledState::*; diff --git a/nexus/db-queries/src/db/datastore/update.rs b/nexus/db-queries/src/db/datastore/update.rs index d73a3d903f..37339beb62 100644 --- a/nexus/db-queries/src/db/datastore/update.rs +++ b/nexus/db-queries/src/db/datastore/update.rs @@ -25,7 +25,7 @@ use omicron_uuid_kinds::TufRepoKind; use omicron_uuid_kinds::TypedUuid; use swrite::{swrite, SWrite}; -/// The return value of [`DataStore::update_tuf_repo_description_insert`]. +/// The return value of [`DataStore::update_tuf_repo_insert`]. /// /// This is similar to [`external::TufRepoInsertResponse`], but uses /// nexus-db-model's types instead of external types. diff --git a/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs b/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs index 9d7c542eda..c93781a073 100644 --- a/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs +++ b/nexus/reconfigurator/planning/src/blueprint_builder/builder.rs @@ -1164,12 +1164,13 @@ impl<'a> BlueprintZonesBuilder<'a> { /// Helper for working with sets of disks on each sled /// -/// Tracking the set of disks is slightly non-trivial because we need to bump -/// the per-sled generation number iff the disks are changed. So we need to -/// keep track of whether we've changed the disks relative to the parent -/// blueprint. We do this by keeping a copy of any [`BlueprintDisksConfig`] -/// that we've changed and a _reference_ to the parent blueprint's disks. This -/// struct makes it easy for callers iterate over the right set of disks. +/// Tracking the set of disks is slightly non-trivial because we need to +/// bump the per-sled generation number iff the disks are changed. So +/// we need to keep track of whether we've changed the disks relative +/// to the parent blueprint. We do this by keeping a copy of any +/// [`BlueprintPhysicalDisksConfig`] that we've changed and a _reference_ to +/// the parent blueprint's disks. This struct makes it easy for callers iterate +/// over the right set of disks. struct BlueprintDisksBuilder<'a> { changed_disks: BTreeMap, parent_disks: &'a BTreeMap, diff --git a/nexus/src/app/instance_network.rs b/nexus/src/app/instance_network.rs index b1ad2bb6fc..c2d46c5499 100644 --- a/nexus/src/app/instance_network.rs +++ b/nexus/src/app/instance_network.rs @@ -29,8 +29,9 @@ use std::str::FromStr; use uuid::Uuid; use super::background::BackgroundTasks; +use super::Nexus; -impl super::Nexus { +impl Nexus { /// Returns the set of switches with uplinks configured and boundary /// services enabled. pub(crate) async fn boundary_switches( diff --git a/nexus/src/app/sagas/volume_delete.rs b/nexus/src/app/sagas/volume_delete.rs index bfd8e6616c..b9e02538b2 100644 --- a/nexus/src/app/sagas/volume_delete.rs +++ b/nexus/src/app/sagas/volume_delete.rs @@ -332,8 +332,9 @@ async fn svd_delete_crucible_snapshot_records( /// It's insufficient to rely on the struct of CrucibleResources to clean up /// that is returned as part of svd_decrease_crucible_resource_count. Imagine a /// disk that is composed of three regions (a subset of -/// [`VolumeConstructionRequest`] is shown here): +/// [`sled_agent_client::types::VolumeConstructionRequest`] is shown here): /// +/// ```json /// { /// "type": "volume", /// "id": "6b353c87-afac-4ee2-b71a-6fe35fcf9e46", @@ -352,9 +353,11 @@ async fn svd_delete_crucible_snapshot_records( /// ], /// "read_only_parent": null, /// } +/// ``` /// /// Taking a snapshot of this will produce the following volume: /// +/// ```json /// { /// "type": "volume", /// "id": "1ef7282e-a3fb-4222-85a8-b16d3fbfd738", <-- new UUID @@ -373,6 +376,7 @@ async fn svd_delete_crucible_snapshot_records( /// ], /// "read_only_parent": null, /// } +/// ``` /// /// The snapshot targets will use the same IP but different port: snapshots are /// initially located on the same filesystem as their region. diff --git a/nexus/types/src/deployment/blueprint_diff.rs b/nexus/types/src/deployment/blueprint_diff.rs index 17631e692d..4f2ee9ed3b 100644 --- a/nexus/types/src/deployment/blueprint_diff.rs +++ b/nexus/types/src/deployment/blueprint_diff.rs @@ -2,7 +2,7 @@ // 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/. -//! Types helpful for diffing [`Blueprints`]. +//! Types helpful for diffing blueprints. use super::blueprint_display::{ constants::*, linear_table_modified, linear_table_unchanged, BpDiffState, diff --git a/nexus/types/src/deployment/blueprint_display.rs b/nexus/types/src/deployment/blueprint_display.rs index 5d106b6ef3..2b0e4cab6c 100644 --- a/nexus/types/src/deployment/blueprint_display.rs +++ b/nexus/types/src/deployment/blueprint_display.rs @@ -2,7 +2,7 @@ // 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/. -//! Types helpful for rendering [`Blueprints`]. +//! Types helpful for rendering blueprints. use omicron_common::api::external::Generation; use std::fmt; @@ -176,7 +176,6 @@ pub trait BpSledSubtableData { } /// A table specific to a sled resource, such as a zone or disk. -/// `BpSledSubtable`s are always nested under [`BpSledTable`]s. pub struct BpSledSubtable { table_name: &'static str, column_names: &'static [&'static str], diff --git a/oximeter/db/src/oxql/ast/grammar.rs b/oximeter/db/src/oxql/ast/grammar.rs index a644dff41d..a7585402b6 100644 --- a/oximeter/db/src/oxql/ast/grammar.rs +++ b/oximeter/db/src/oxql/ast/grammar.rs @@ -257,7 +257,7 @@ peg::parser! { /// /// We support the following common escape sequences: /// - /// ```ignore + /// ```text /// \n /// \r /// \t @@ -271,7 +271,7 @@ peg::parser! { /// styles if required, by writing them as their Unicode escape /// sequences. For example, this string: /// - /// ```ignore + /// ```text /// "this string has \u{22} in it" /// ``` /// diff --git a/sled-agent/src/sim/instance.rs b/sled-agent/src/sim/instance.rs index 06739df8fa..be6c63f53a 100644 --- a/sled-agent/src/sim/instance.rs +++ b/sled-agent/src/sim/instance.rs @@ -43,11 +43,11 @@ enum MonitorChange { /// integration tests. /// /// The simulated instance contains a fake instance state stored as a -/// [`propolis_client::api::InstanceStateMonitorResponse`]. Transition requests -/// enqueue changes to either the instance state or the migration status fields -/// of this response. When poked, the simulated instance applies the next -/// transition, translates this to an observed Propolis state, and sends it -/// off for processing. +/// [`propolis_client::types::InstanceStateMonitorResponse`]. Transition +/// requests enqueue changes to either the instance state or the migration +/// status fields of this response. When poked, the simulated instance applies +/// the next transition, translates this to an observed Propolis state, and +/// sends it off for processing. #[derive(Debug)] struct SimInstanceInner { /// The current simulated instance state. diff --git a/wicket/src/ui/panes/update.rs b/wicket/src/ui/panes/update.rs index 712ba778b5..6269228bc2 100644 --- a/wicket/src/ui/panes/update.rs +++ b/wicket/src/ui/panes/update.rs @@ -150,7 +150,7 @@ pub struct UpdatePane { /// TODO: Move following state into global `State` so that recorder snapshots /// capture all state. /// - /// TODO: The generic parameter is carried over from earlier versions + /// TODO: The usize generic parameter is carried over from earlier versions /// of tui-tree-widget, but there's likely a better index type. tree_state: TreeState, items: Vec>, From 253ccecc68b8516ab6a93cc05a59c558d0accb5e Mon Sep 17 00:00:00 2001 From: iliana etaoin Date: Fri, 21 Jun 2024 09:45:52 -0700 Subject: [PATCH 13/26] only unset xtrace if env.sh set it first (#5875) I noticed that the Buildomat logs for some of our tests didn't have execution tracing, despite `set -o xtrace` at the top of their scripts! Turns out env.sh was the cause. Despite this script being Bash-specific (`$BASH_SOURCE`) I went with a POSIXy implementation here. (Also fixed quoting, in case your checkout is within a directory path containing spaces.) --- env.sh | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/env.sh b/env.sh index 74f3d1caf4..6a84c35902 100644 --- a/env.sh +++ b/env.sh @@ -4,11 +4,22 @@ # # See also: ./.envrc +OLD_SHELL_OPTS=$- set -o xtrace -OMICRON_WS="$(readlink -f $(dirname "${BASH_SOURCE[0]}"))" + +OMICRON_WS=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")") export PATH="$OMICRON_WS/out/cockroachdb/bin:$PATH" export PATH="$OMICRON_WS/out/clickhouse:$PATH" export PATH="$OMICRON_WS/out/dendrite-stub/bin:$PATH" export PATH="$OMICRON_WS/out/mgd/root/opt/oxide/mgd/bin:$PATH" -unset OMICRON_WS -set +o xtrace + +# if xtrace was set previously, do not unset it +case $OLD_SHELL_OPTS in + *x*) + unset OLD_SHELL_OPTS OMICRON_WS + ;; + *) + unset OLD_SHELL_OPTS OMICRON_WS + set +o xtrace + ;; +esac From e9c243264d7fb6190885e9501da334bcf245ce98 Mon Sep 17 00:00:00 2001 From: iliana etaoin Date: Fri, 21 Jun 2024 09:46:04 -0700 Subject: [PATCH 14/26] remove scripts from old releng CI process (#5879) I forgot to remove these in #5744. These scripts were adapted into `cargo xtask releng` and aren't referenced anywhere in this repo anymore. --- tools/build-global-zone-packages.sh | 74 ------------------- .../build-trampoline-global-zone-packages.sh | 51 ------------- 2 files changed, 125 deletions(-) delete mode 100755 tools/build-global-zone-packages.sh delete mode 100755 tools/build-trampoline-global-zone-packages.sh diff --git a/tools/build-global-zone-packages.sh b/tools/build-global-zone-packages.sh deleted file mode 100755 index fe00e53383..0000000000 --- a/tools/build-global-zone-packages.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -TOOLS_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" - -# Use the default "out" dir in omicron to find the needed packages if one isn't given -tarball_src_dir="$(readlink -f "${1:-"$TOOLS_DIR/../out"}")" -# Stash the final tgz in the given src dir if a different target isn't given -out_dir="$(readlink -f "${2:-"$tarball_src_dir"}")" - -# Make sure needed packages exist -deps=( - "$tarball_src_dir/omicron-sled-agent.tar" - "$tarball_src_dir/mg-ddm-gz.tar" - "$tarball_src_dir/pumpkind-gz.tar" - "$tarball_src_dir/propolis-server.tar.gz" - "$tarball_src_dir/overlay.tar.gz" - "$tarball_src_dir/oxlog.tar" -) -for dep in "${deps[@]}"; do - if [[ ! -e $dep ]]; then - echo "Missing Global Zone dep: $(basename "$dep")" - exit 1 - fi -done - -# Assemble global zone files in a temporary directory. -tmp_gz=$(mktemp -d) -trap 'cd /; rm -rf "$tmp_gz"' EXIT # Cleanup on exit - -# Header file, identifying this is intended to be layered in the global zone. -# Within the ramdisk, this means that all files under "root/foo" should appear -# in the global zone as "/foo". -echo '{"v":"1","t":"layer"}' > "$tmp_gz/oxide.json" - -# Extract the sled-agent tarball for re-packaging into the layered GZ archive. -pkg_dir="$tmp_gz/root/opt/oxide/sled-agent" -mkdir -p "$pkg_dir" -cd "$pkg_dir" -tar -xvfz "$tarball_src_dir/omicron-sled-agent.tar" -# Ensure that the manifest for the sled agent exists in a location where it may -# be automatically initialized. -mkdir -p "$tmp_gz/root/lib/svc/manifest/site/" -mv pkg/manifest.xml "$tmp_gz/root/lib/svc/manifest/site/sled-agent.xml" -cd - -# Extract the mg-ddm tarball for re-packaging into the layered GZ archive. -pkg_dir="$tmp_gz/root/opt/oxide/mg-ddm" -mkdir -p "$pkg_dir" -cd "$pkg_dir" -tar -xvfz "$tarball_src_dir/mg-ddm-gz.tar" -cd - -# Extract the pumpkind tarball for re-packaging into the layered GZ archive. -pkg_dir="$tmp_gz/root/opt/oxide/pumpkind" -mkdir -p "$pkg_dir" -cd "$pkg_dir" -tar -xvfz "$tarball_src_dir/pumpkind-gz.tar" -cd - -# Extract the oxlog tarball for re-packaging into the layered GZ archive. -pkg_dir="$tmp_gz/root/opt/oxide/oxlog" -mkdir -p "$pkg_dir" -cd "$pkg_dir" -tar -xvfz "$tarball_src_dir/oxlog.tar" -cd - - -# propolis should be bundled with this OS: Put the propolis-server zone image -# under /opt/oxide in the gz. -cp "$tarball_src_dir/propolis-server.tar.gz" "$tmp_gz/root/opt/oxide" - -# The zone overlay should also be bundled. -cp "$tarball_src_dir/overlay.tar.gz" "$tmp_gz/root/opt/oxide" - -# Create the final output and we're done -cd "$tmp_gz" && tar cvfz "$out_dir"/global-zone-packages.tar.gz oxide.json root diff --git a/tools/build-trampoline-global-zone-packages.sh b/tools/build-trampoline-global-zone-packages.sh deleted file mode 100755 index ee8e7b3371..0000000000 --- a/tools/build-trampoline-global-zone-packages.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -TOOLS_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" - -# Use the default "out" dir in omicron to find the needed packages if one isn't given -tarball_src_dir="$(readlink -f "${1:-"$TOOLS_DIR/../out"}")" -# Stash the final tgz in the given src dir if a different target isn't given -out_dir="$(readlink -f "${2:-$tarball_src_dir}")" - -# Make sure needed packages exist -deps=( - "$tarball_src_dir"/installinator.tar - "$tarball_src_dir"/mg-ddm-gz.tar -) -for dep in "${deps[@]}"; do - if [[ ! -e $dep ]]; then - echo "Missing Trampoline Global Zone dep: $(basename "$dep")" - exit 1 - fi -done - -# Assemble global zone files in a temporary directory. -tmp_trampoline=$(mktemp -d) -trap 'cd /; rm -rf "$tmp_trampoline"' EXIT # Cleanup on exit - -# Header file, identifying this is intended to be layered in the global zone. -# Within the ramdisk, this means that all files under "root/foo" should appear -# in the global zone as "/foo". -echo '{"v":"1","t":"layer"}' > "$tmp_trampoline/oxide.json" - -# Extract the installinator tarball for re-packaging into the layered GZ archive. -pkg_dir="$tmp_trampoline/root/opt/oxide/installinator" -mkdir -p "$pkg_dir" -cd "$pkg_dir" -tar -xvfz "$tarball_src_dir/installinator.tar" -# Ensure that the manifest for the sled agent exists in a location where it may -# be automatically initialized. -mkdir -p "$tmp_trampoline/root/lib/svc/manifest/site/" -mv pkg/manifest.xml "$tmp_trampoline/root/lib/svc/manifest/site/installinator.xml" -cd - -# Extract the mg-ddm tarball for re-packaging into the layered GZ archive. -pkg_dir="$tmp_trampoline/root/opt/oxide/mg-ddm" -mkdir -p "$pkg_dir" -cd "$pkg_dir" -tar -xvfz "$tarball_src_dir/mg-ddm-gz.tar" -cd - - -# Create the final output and we're done -cd "$tmp_trampoline" && tar cvfz "$out_dir"/trampoline-global-zone-packages.tar.gz oxide.json root From 2afaae9d5002a1ae52b487a546c88b6dc4ac1eb6 Mon Sep 17 00:00:00 2001 From: iliana etaoin Date: Fri, 21 Jun 2024 09:47:27 -0700 Subject: [PATCH 15/26] xtask download / releng / omicron-package: timeouts, keepalives, and retries (#5923) The HTTPS frontend for Buildomat has been hitting [illumos bug #16615](https://www.illumos.org/issues/16615), which resulted in a number of HTTP downloads from Buildomat artifact URLs not completing... and not timing out, either! This set of changes ensures that all of the HTTP downloads in `cargo xtask download`, `cargo xtask releng`, and `omicron-package` have timeouts and TCP keepalives configured, and have retries. Closes #5910. Closes #5911. --- dev-tools/releng/src/hubris.rs | 51 ++++++++++++++++++++++-------- dev-tools/releng/src/main.rs | 6 +++- dev-tools/xtask/src/download.rs | 45 +++++++++++++++++++------- package/src/bin/omicron-package.rs | 15 +++++++-- tools/softnpu_version | 2 ++ 5 files changed, 92 insertions(+), 27 deletions(-) create mode 100644 tools/softnpu_version diff --git a/dev-tools/releng/src/hubris.rs b/dev-tools/releng/src/hubris.rs index 685a729a9f..f46af4bfaf 100644 --- a/dev-tools/releng/src/hubris.rs +++ b/dev-tools/releng/src/hubris.rs @@ -14,12 +14,17 @@ use omicron_common::api::external::SemverVersion; use omicron_common::api::internal::nexus::KnownArtifactKind; use semver::Version; use serde::Deserialize; +use slog::warn; +use slog::Logger; use tufaceous_lib::assemble::DeserializedArtifactData; use tufaceous_lib::assemble::DeserializedArtifactSource; use tufaceous_lib::assemble::DeserializedFileArtifactSource; use tufaceous_lib::assemble::DeserializedManifest; +use crate::RETRY_ATTEMPTS; + pub(crate) async fn fetch_hubris_artifacts( + logger: Logger, base_url: &'static str, client: reqwest::Client, manifest_list: Utf8PathBuf, @@ -43,7 +48,7 @@ pub(crate) async fn fetch_hubris_artifacts( for line in fs::read_to_string(manifest_list).await?.lines() { if let Some(hash) = line.split_whitespace().next() { - let data = fetch_hash(base_url, &client, hash).await?; + let data = fetch_hash(&logger, base_url, &client, hash).await?; let str = String::from_utf8(data).with_context(|| { format!("hubris artifact manifest {} was not UTF-8", hash) })?; @@ -85,7 +90,9 @@ pub(crate) async fn fetch_hubris_artifacts( }, ); for hash in hashes { - let data = fetch_hash(base_url, &client, &hash).await?; + let data = + fetch_hash(&logger, base_url, &client, &hash) + .await?; fs::write(output_dir.join(zip!(hash)), data).await?; } } @@ -102,21 +109,39 @@ pub(crate) async fn fetch_hubris_artifacts( } async fn fetch_hash( + logger: &Logger, base_url: &'static str, client: &reqwest::Client, hash: &str, ) -> Result> { - client - .get(format!("{}/artifact/{}", base_url, hash)) - .send() - .and_then(|response| response.json()) - .await - .with_context(|| { - format!( - "failed to fetch hubris artifact {} from {}", - hash, base_url - ) - }) + let url = format!("{}/artifact/{}", base_url, hash); + for attempt in 1..=RETRY_ATTEMPTS { + let result = client + .get(&url) + .send() + .and_then(|response| { + futures::future::ready(response.error_for_status()) + }) + .and_then(|response| response.json()) + .await + .with_context(|| { + format!( + "failed to fetch hubris artifact {} from {}", + hash, base_url + ) + }); + match result { + Ok(data) => return Ok(data), + Err(err) => { + if attempt == RETRY_ATTEMPTS { + return Err(err); + } else { + warn!(logger, "fetching {} failed, retrying: {}", url, err); + } + } + } + } + unreachable!(); } // These structs are similar to `DeserializeManifest` and friends from diff --git a/dev-tools/releng/src/main.rs b/dev-tools/releng/src/main.rs index 9bb0cd33bb..9340de4961 100644 --- a/dev-tools/releng/src/main.rs +++ b/dev-tools/releng/src/main.rs @@ -43,6 +43,8 @@ use crate::job::Jobs; /// the future. const BASE_VERSION: Version = Version::new(9, 0, 0); +const RETRY_ATTEMPTS: usize = 3; + #[derive(Debug, Clone, Copy)] enum InstallMethod { /// Unpack the tarball to `/opt/oxide/`, and install @@ -234,7 +236,8 @@ async fn main() -> Result<()> { let client = reqwest::ClientBuilder::new() .connect_timeout(Duration::from_secs(15)) - .timeout(Duration::from_secs(15)) + .timeout(Duration::from_secs(120)) + .tcp_keepalive(Duration::from_secs(60)) .build() .context("failed to build reqwest client")?; @@ -565,6 +568,7 @@ async fn main() -> Result<()> { jobs.push( format!("hubris-{}", name), hubris::fetch_hubris_artifacts( + logger.clone(), base_url, client.clone(), WORKSPACE_DIR.join(format!("tools/permslip_{}", name)), diff --git a/dev-tools/xtask/src/download.rs b/dev-tools/xtask/src/download.rs index f7583d19a0..3002837507 100644 --- a/dev-tools/xtask/src/download.rs +++ b/dev-tools/xtask/src/download.rs @@ -15,6 +15,8 @@ use slog::{info, o, warn, Drain, Logger}; use std::collections::{BTreeSet, HashMap}; use std::io::Write; use std::os::unix::fs::PermissionsExt; +use std::sync::OnceLock; +use std::time::Duration; use strum::EnumIter; use strum::IntoEnumIterator; use tar::Archive; @@ -23,6 +25,7 @@ use tokio::process::Command; const BUILDOMAT_URL: &'static str = "https://buildomat.eng.oxide.computer/public/file"; +const RETRY_ATTEMPTS: usize = 3; /// What is being downloaded? #[derive( @@ -236,7 +239,17 @@ async fn get_values_from_file( /// /// Writes the response to the file as it is received. async fn streaming_download(url: &str, path: &Utf8Path) -> Result<()> { - let mut response = reqwest::get(url).await?; + static CLIENT: OnceLock = OnceLock::new(); + + let client = CLIENT.get_or_init(|| { + reqwest::ClientBuilder::new() + .timeout(Duration::from_secs(3600)) + .tcp_keepalive(Duration::from_secs(60)) + .connect_timeout(Duration::from_secs(15)) + .build() + .unwrap() + }); + let mut response = client.get(url).send().await?.error_for_status()?; let mut tarball = tokio::fs::File::create(&path).await?; while let Some(chunk) = response.chunk().await? { tarball.write_all(chunk.as_ref()).await?; @@ -410,8 +423,22 @@ async fn download_file_and_verify( }; if do_download { - info!(log, "Downloading {path}"); - streaming_download(&url, &path).await?; + for attempt in 1..=RETRY_ATTEMPTS { + info!( + log, + "Downloading {path} (attempt {attempt}/{RETRY_ATTEMPTS})" + ); + match streaming_download(&url, &path).await { + Ok(()) => break, + Err(err) => { + if attempt == RETRY_ATTEMPTS { + return Err(err); + } else { + warn!(log, "Download failed, retrying: {err}"); + } + } + } + } } let observed_checksum = algorithm.checksum(&path).await?; @@ -787,19 +814,15 @@ impl<'a> Downloader<'a> { let destination_dir = self.output_dir.join("npuzone"); tokio::fs::create_dir_all(&destination_dir).await?; - let repo = "oxidecomputer/softnpu"; + let checksums_path = self.versions_dir.join("softnpu_version"); + let [commit, sha2] = + get_values_from_file(["COMMIT", "SHA2"], &checksums_path).await?; - // TODO: This should probably live in a separate file, but - // at the moment we're just building parity with - // "ci_download_softnpu_machinery". - let commit = "3203c51cf4473d30991b522062ac0df2e045c2f2"; + let repo = "oxidecomputer/softnpu"; let filename = "npuzone"; let base_url = format!("{BUILDOMAT_URL}/{repo}/image/{commit}"); let artifact_url = format!("{base_url}/{filename}"); - let sha2_url = format!("{base_url}/{filename}.sha256.txt"); - let sha2 = reqwest::get(sha2_url).await?.text().await?; - let sha2 = sha2.trim(); let path = destination_dir.join(filename); download_file_and_verify( diff --git a/package/src/bin/omicron-package.rs b/package/src/bin/omicron-package.rs index 09fa7ab178..a8c5508b77 100644 --- a/package/src/bin/omicron-package.rs +++ b/package/src/bin/omicron-package.rs @@ -28,7 +28,8 @@ use std::env; use std::fs::create_dir_all; use std::io::Write; use std::str::FromStr; -use std::sync::Arc; +use std::sync::{Arc, OnceLock}; +use std::time::Duration; use swrite::{swrite, SWrite}; use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader}; use tokio::process::Command; @@ -350,6 +351,8 @@ async fn download_prebuilt( expected_digest: &Vec, path: &Utf8Path, ) -> Result<()> { + static CLIENT: OnceLock = OnceLock::new(); + progress.set_message("downloading prebuilt".into()); let url = format!( "https://buildomat.eng.oxide.computer/public/file/oxidecomputer/{}/image/{}/{}", @@ -357,7 +360,15 @@ async fn download_prebuilt( commit, path.file_name().unwrap(), ); - let response = reqwest::Client::new() + let client = CLIENT.get_or_init(|| { + reqwest::ClientBuilder::new() + .timeout(Duration::from_secs(3600)) + .tcp_keepalive(Duration::from_secs(60)) + .connect_timeout(Duration::from_secs(15)) + .build() + .unwrap() + }); + let response = client .get(&url) .send() .await diff --git a/tools/softnpu_version b/tools/softnpu_version new file mode 100644 index 0000000000..03f74d8865 --- /dev/null +++ b/tools/softnpu_version @@ -0,0 +1,2 @@ +COMMIT="3203c51cf4473d30991b522062ac0df2e045c2f2" +SHA2="36095c7f9d613b9208415aeb67335836a25f72eed2f7a41931ba7d91ddb00568" From 1c8de68e0bdc0784dcfcd720700285396279b687 Mon Sep 17 00:00:00 2001 From: David Crespo Date: Fri, 21 Jun 2024 13:09:44 -0500 Subject: [PATCH 16/26] Increase default session timeout to 8 hours idle, 24 hours absolute (#5920) We want to make the values configurable (#5477), but in the meantime we can improve the user experience substantially by increasing the hard-coded values so people get logged out less often. I picked 8 hours/24 hours so that someone could log in in the morning and stay logged in all day. It's worth noting that there are no deleterious effects if the IdP's own session timeout is less than ours as long as the customer is willing to accept the longer console session. It just means that whenever the user gets logged out of the console and wants to log back in, they may have to also complete the login step in their IdP. --- nexus/examples/config.toml | 2 +- nexus/tests/config.test.toml | 4 ++-- nexus/tests/integration_tests/console_api.rs | 2 +- nexus/tests/integration_tests/password_login.rs | 2 +- smf/nexus/multi-sled/config-partial.toml | 4 ++-- smf/nexus/single-sled/config-partial.toml | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nexus/examples/config.toml b/nexus/examples/config.toml index c282232ef8..3162cf212b 100644 --- a/nexus/examples/config.toml +++ b/nexus/examples/config.toml @@ -5,7 +5,7 @@ [console] # Directory for static assets. Absolute path or relative to CWD. static_dir = "out/console-assets" -session_idle_timeout_minutes = 480 # 6 hours +session_idle_timeout_minutes = 480 # 8 hours session_absolute_timeout_minutes = 1440 # 24 hours # List of authentication schemes to support. diff --git a/nexus/tests/config.test.toml b/nexus/tests/config.test.toml index 9aed5bcb69..952b324ac6 100644 --- a/nexus/tests/config.test.toml +++ b/nexus/tests/config.test.toml @@ -5,8 +5,8 @@ [console] # Directory for static assets. Absolute path or relative to CWD. static_dir = "tests/static" -session_idle_timeout_minutes = 60 -session_absolute_timeout_minutes = 480 +session_idle_timeout_minutes = 480 # 8 hours +session_absolute_timeout_minutes = 1440 # 24 hours # List of authentication schemes to support. [authn] diff --git a/nexus/tests/integration_tests/console_api.rs b/nexus/tests/integration_tests/console_api.rs index 8daaf44733..479baf2fec 100644 --- a/nexus/tests/integration_tests/console_api.rs +++ b/nexus/tests/integration_tests/console_api.rs @@ -892,7 +892,7 @@ async fn log_in_and_extract_token( let (session_token, rest) = session_cookie.split_once("; ").unwrap(); assert!(session_token.starts_with("session=")); - assert_eq!(rest, "Path=/; HttpOnly; SameSite=Lax; Max-Age=28800"); + assert_eq!(rest, "Path=/; HttpOnly; SameSite=Lax; Max-Age=86400"); session_token.to_string() } diff --git a/nexus/tests/integration_tests/password_login.rs b/nexus/tests/integration_tests/password_login.rs index a340a804e2..a7b0b627b9 100644 --- a/nexus/tests/integration_tests/password_login.rs +++ b/nexus/tests/integration_tests/password_login.rs @@ -447,7 +447,7 @@ async fn expect_login_success( .split_once("; ") .expect("session cookie: bad cookie header value (missing semicolon)"); assert!(token_cookie.starts_with("session=")); - assert_eq!(rest, "Path=/; HttpOnly; SameSite=Lax; Max-Age=28800"); + assert_eq!(rest, "Path=/; HttpOnly; SameSite=Lax; Max-Age=86400"); let (_, session_token) = token_cookie .split_once('=') .expect("session cookie: bad cookie header value (missing 'session=')"); diff --git a/smf/nexus/multi-sled/config-partial.toml b/smf/nexus/multi-sled/config-partial.toml index d4612ba15e..8d5adba401 100644 --- a/smf/nexus/multi-sled/config-partial.toml +++ b/smf/nexus/multi-sled/config-partial.toml @@ -5,8 +5,8 @@ [console] # Directory for static assets. Absolute path or relative to CWD. static_dir = "/var/nexus/static" -session_idle_timeout_minutes = 60 -session_absolute_timeout_minutes = 480 +session_idle_timeout_minutes = 480 # 8 hours +session_absolute_timeout_minutes = 1440 # 24 hours [authn] schemes_external = ["session_cookie", "access_token"] diff --git a/smf/nexus/single-sled/config-partial.toml b/smf/nexus/single-sled/config-partial.toml index 3b158d0387..58a4ad5b45 100644 --- a/smf/nexus/single-sled/config-partial.toml +++ b/smf/nexus/single-sled/config-partial.toml @@ -5,8 +5,8 @@ [console] # Directory for static assets. Absolute path or relative to CWD. static_dir = "/var/nexus/static" -session_idle_timeout_minutes = 60 -session_absolute_timeout_minutes = 480 +session_idle_timeout_minutes = 480 # 8 hours +session_absolute_timeout_minutes = 1440 # 24 hours [authn] schemes_external = ["session_cookie", "access_token"] From 15dd022674b90bb825b8a6fd319379ab660ecfbd Mon Sep 17 00:00:00 2001 From: iliana etaoin Date: Fri, 21 Jun 2024 11:39:04 -0700 Subject: [PATCH 17/26] pin sled (the database), write a note explaining why (#5926) --- Cargo.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2e6e556519..fbb301511b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -442,7 +442,12 @@ signal-hook = "0.3" signal-hook-tokio = { version = "0.3", features = [ "futures-v0_3" ] } sigpipe = "0.1.3" similar-asserts = "1.5.0" -sled = "0.34" +# Don't change sled's version on accident; sled's on-disk format is not yet +# stable and requires manual migrations. In the limit this won't matter because +# the upgrade system will replace the DNS server zones entirely, but while we +# are still doing mupdate a change to the on-disk format will break existing DNS +# server zones. +sled = "=0.34.7" sled-agent-client = { path = "clients/sled-agent-client" } sled-hardware = { path = "sled-hardware" } sled-hardware-types = { path = "sled-hardware/types" } From 964f6eb9167d91199f3b480db05e335602584061 Mon Sep 17 00:00:00 2001 From: Sean Klein Date: Fri, 21 Jun 2024 12:25:25 -0700 Subject: [PATCH 18/26] [sled agent] Deprecate the old service format (#5922) This portion of the Sled Agent was added in https://github.com/oxidecomputer/omicron/pull/4466, migrating an old "services" ledger into a new, zones-oriented format. This code served as a bridge between old and new format, but maintaining backwards compatibility here is a burden for modifying the zone format further. Specifically: in https://github.com/oxidecomputer/omicron/pull/5050 , which attempts to add the notion of "transient zone filesystem zpool" to the request from Nexus, the translation of "old format -> new format" is no longer possible without additional information about "where should the transient zone filesystem be placed". Given that this conversion has been deployed for multiple months - across releases - I figured it would be easier to remove the old support, rather than making another bridge for old code compatibility. --- schema/all-zone-requests.json | 801 ------------------ .../src/bin/services-ledger-check-migrate.rs | 80 -- sled-agent/src/lib.rs | 1 - sled-agent/src/services.rs | 273 +----- sled-agent/src/services_migration.rs | 623 -------------- .../old-service-ledgers/rack2-sled10.json | 1 - .../old-service-ledgers/rack2-sled11.json | 1 - .../old-service-ledgers/rack2-sled12.json | 1 - .../old-service-ledgers/rack2-sled14.json | 1 - .../old-service-ledgers/rack2-sled16.json | 1 - .../old-service-ledgers/rack2-sled17.json | 1 - .../old-service-ledgers/rack2-sled21.json | 1 - .../old-service-ledgers/rack2-sled23.json | 1 - .../old-service-ledgers/rack2-sled25.json | 1 - .../old-service-ledgers/rack2-sled8.json | 1 - .../old-service-ledgers/rack2-sled9.json | 1 - .../old-service-ledgers/rack3-sled0.json | 1 - .../old-service-ledgers/rack3-sled1.json | 1 - .../old-service-ledgers/rack3-sled11.json | 1 - .../old-service-ledgers/rack3-sled12.json | 1 - .../old-service-ledgers/rack3-sled13.json | 1 - .../old-service-ledgers/rack3-sled14.json | 1 - .../old-service-ledgers/rack3-sled15.json | 1 - .../old-service-ledgers/rack3-sled16.json | 1 - .../old-service-ledgers/rack3-sled17.json | 1 - .../old-service-ledgers/rack3-sled18.json | 1 - .../old-service-ledgers/rack3-sled19.json | 1 - .../old-service-ledgers/rack3-sled2.json | 1 - .../old-service-ledgers/rack3-sled20.json | 1 - .../old-service-ledgers/rack3-sled21.json | 1 - .../old-service-ledgers/rack3-sled22.json | 1 - .../old-service-ledgers/rack3-sled23.json | 1 - .../old-service-ledgers/rack3-sled24.json | 1 - .../old-service-ledgers/rack3-sled25.json | 1 - .../old-service-ledgers/rack3-sled26.json | 1 - .../old-service-ledgers/rack3-sled27.json | 1 - .../old-service-ledgers/rack3-sled28.json | 1 - .../old-service-ledgers/rack3-sled29.json | 1 - .../old-service-ledgers/rack3-sled3.json | 1 - .../old-service-ledgers/rack3-sled30.json | 1 - .../old-service-ledgers/rack3-sled31.json | 1 - .../old-service-ledgers/rack3-sled4.json | 1 - .../old-service-ledgers/rack3-sled5.json | 1 - .../old-service-ledgers/rack3-sled6.json | 1 - .../old-service-ledgers/rack3-sled7.json | 1 - .../old-service-ledgers/rack3-sled8.json | 1 - .../old-service-ledgers/rack3-sled9.json | 1 - .../new-zones-ledgers/rack2-sled10.json | 195 ----- .../new-zones-ledgers/rack2-sled11.json | 196 ----- .../new-zones-ledgers/rack2-sled12.json | 232 ----- .../new-zones-ledgers/rack2-sled14.json | 192 ----- .../new-zones-ledgers/rack2-sled16.json | 192 ----- .../new-zones-ledgers/rack2-sled17.json | 181 ---- .../new-zones-ledgers/rack2-sled21.json | 232 ----- .../new-zones-ledgers/rack2-sled23.json | 195 ----- .../new-zones-ledgers/rack2-sled25.json | 196 ----- .../output/new-zones-ledgers/rack2-sled8.json | 198 ----- .../output/new-zones-ledgers/rack2-sled9.json | 192 ----- .../output/new-zones-ledgers/rack3-sled0.json | 181 ---- .../output/new-zones-ledgers/rack3-sled1.json | 167 ---- .../new-zones-ledgers/rack3-sled11.json | 201 ----- .../new-zones-ledgers/rack3-sled12.json | 181 ---- .../new-zones-ledgers/rack3-sled13.json | 201 ----- .../new-zones-ledgers/rack3-sled14.json | 198 ----- .../new-zones-ledgers/rack3-sled15.json | 196 ----- .../new-zones-ledgers/rack3-sled16.json | 167 ---- .../new-zones-ledgers/rack3-sled17.json | 167 ---- .../new-zones-ledgers/rack3-sled18.json | 167 ---- .../new-zones-ledgers/rack3-sled19.json | 181 ---- .../output/new-zones-ledgers/rack3-sled2.json | 167 ---- .../new-zones-ledgers/rack3-sled20.json | 198 ----- .../new-zones-ledgers/rack3-sled21.json | 167 ---- .../new-zones-ledgers/rack3-sled22.json | 167 ---- .../new-zones-ledgers/rack3-sled23.json | 181 ---- .../new-zones-ledgers/rack3-sled24.json | 167 ---- .../new-zones-ledgers/rack3-sled25.json | 196 ----- .../new-zones-ledgers/rack3-sled26.json | 178 ---- .../new-zones-ledgers/rack3-sled27.json | 167 ---- .../new-zones-ledgers/rack3-sled28.json | 167 ---- .../new-zones-ledgers/rack3-sled29.json | 184 ---- .../output/new-zones-ledgers/rack3-sled3.json | 178 ---- .../new-zones-ledgers/rack3-sled30.json | 167 ---- .../new-zones-ledgers/rack3-sled31.json | 181 ---- .../output/new-zones-ledgers/rack3-sled4.json | 167 ---- .../output/new-zones-ledgers/rack3-sled5.json | 178 ---- .../output/new-zones-ledgers/rack3-sled6.json | 167 ---- .../output/new-zones-ledgers/rack3-sled7.json | 167 ---- .../output/new-zones-ledgers/rack3-sled8.json | 198 ----- .../output/new-zones-ledgers/rack3-sled9.json | 178 ---- 89 files changed, 35 insertions(+), 9513 deletions(-) delete mode 100644 schema/all-zone-requests.json delete mode 100644 sled-agent/src/bin/services-ledger-check-migrate.rs delete mode 100644 sled-agent/src/services_migration.rs delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled10.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled11.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled12.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled14.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled16.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled17.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled21.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled23.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled25.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled8.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled9.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled0.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled1.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled11.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled12.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled13.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled14.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled15.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled16.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled17.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled18.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled19.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled2.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled20.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled21.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled22.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled23.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled24.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled25.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled26.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled27.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled28.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled29.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled3.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled30.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled31.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled4.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled5.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled6.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled7.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled8.json delete mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled9.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json delete mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json diff --git a/schema/all-zone-requests.json b/schema/all-zone-requests.json deleted file mode 100644 index fde6ee18a4..0000000000 --- a/schema/all-zone-requests.json +++ /dev/null @@ -1,801 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllZoneRequests", - "description": "A wrapper around `ZoneRequest` that allows it to be serialized to a JSON file.", - "type": "object", - "required": [ - "generation", - "requests" - ], - "properties": { - "generation": { - "description": "ledger generation (not an Omicron-provided generation)", - "allOf": [ - { - "$ref": "#/definitions/Generation" - } - ] - }, - "requests": { - "type": "array", - "items": { - "$ref": "#/definitions/ZoneRequest" - } - } - }, - "definitions": { - "DatasetKind": { - "description": "The type of a dataset, and an auxiliary information necessary to successfully launch a zone managing the associated data.", - "oneOf": [ - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "cockroach_db" - ] - } - } - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "crucible" - ] - } - } - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "clickhouse" - ] - } - } - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "clickhouse_keeper" - ] - } - } - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "external_dns" - ] - } - } - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "internal_dns" - ] - } - } - } - ] - }, - "DatasetName": { - "type": "object", - "required": [ - "kind", - "pool_name" - ], - "properties": { - "kind": { - "$ref": "#/definitions/DatasetKind" - }, - "pool_name": { - "$ref": "#/definitions/ZpoolName" - } - } - }, - "DatasetRequest": { - "description": "Describes a request to provision a specific dataset", - "type": "object", - "required": [ - "id", - "name", - "service_address" - ], - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "$ref": "#/definitions/DatasetName" - }, - "service_address": { - "type": "string" - } - } - }, - "Generation": { - "description": "Generation numbers stored in the database, used for optimistic concurrency control", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "IpNet": { - "oneOf": [ - { - "title": "v4", - "allOf": [ - { - "$ref": "#/definitions/Ipv4Net" - } - ] - }, - { - "title": "v6", - "allOf": [ - { - "$ref": "#/definitions/Ipv6Net" - } - ] - } - ], - "x-rust-type": { - "crate": "oxnet", - "path": "oxnet::IpNet", - "version": "0.1.0" - } - }, - "Ipv4Net": { - "title": "An IPv4 subnet", - "description": "An IPv4 subnet, including prefix and prefix length", - "examples": [ - "192.168.1.0/24" - ], - "type": "string", - "pattern": "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/([0-9]|1[0-9]|2[0-9]|3[0-2])$", - "x-rust-type": { - "crate": "oxnet", - "path": "oxnet::Ipv4Net", - "version": "0.1.0" - } - }, - "Ipv6Net": { - "title": "An IPv6 subnet", - "description": "An IPv6 subnet, including prefix and subnet mask", - "examples": [ - "fd12:3456::/64" - ], - "type": "string", - "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$", - "x-rust-type": { - "crate": "oxnet", - "path": "oxnet::Ipv6Net", - "version": "0.1.0" - } - }, - "MacAddr": { - "title": "A MAC address", - "description": "A Media Access Control address, in EUI-48 format", - "examples": [ - "ff:ff:ff:ff:ff:ff" - ], - "type": "string", - "maxLength": 17, - "minLength": 5, - "pattern": "^([0-9a-fA-F]{0,2}:){5}[0-9a-fA-F]{0,2}$" - }, - "Name": { - "title": "A name unique within the parent collection", - "description": "Names must begin with a lower case ASCII letter, be composed exclusively of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end with a '-'. Names cannot be a UUID though they may contain a UUID.", - "type": "string", - "maxLength": 63, - "minLength": 1, - "pattern": "^(?![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}$)^[a-z]([a-zA-Z0-9-]*[a-zA-Z0-9]+)?$" - }, - "NetworkInterface": { - "description": "Information required to construct a virtual network interface", - "type": "object", - "required": [ - "id", - "ip", - "kind", - "mac", - "name", - "primary", - "slot", - "subnet", - "vni" - ], - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "ip": { - "type": "string", - "format": "ip" - }, - "kind": { - "$ref": "#/definitions/NetworkInterfaceKind" - }, - "mac": { - "$ref": "#/definitions/MacAddr" - }, - "name": { - "$ref": "#/definitions/Name" - }, - "primary": { - "type": "boolean" - }, - "slot": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "subnet": { - "$ref": "#/definitions/IpNet" - }, - "vni": { - "$ref": "#/definitions/Vni" - } - } - }, - "NetworkInterfaceKind": { - "description": "The type of network interface", - "oneOf": [ - { - "description": "A vNIC attached to a guest instance", - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "type": "string", - "enum": [ - "instance" - ] - } - } - }, - { - "description": "A vNIC associated with an internal service", - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "type": "string", - "enum": [ - "service" - ] - } - } - }, - { - "description": "A vNIC associated with a probe", - "type": "object", - "required": [ - "id", - "type" - ], - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "type": "string", - "enum": [ - "probe" - ] - } - } - } - ] - }, - "ServiceType": { - "description": "Describes service-specific parameters.", - "oneOf": [ - { - "type": "object", - "required": [ - "external_dns_servers", - "external_ip", - "external_tls", - "internal_address", - "nic", - "type" - ], - "properties": { - "external_dns_servers": { - "description": "External DNS servers Nexus can use to resolve external hosts.", - "type": "array", - "items": { - "type": "string", - "format": "ip" - } - }, - "external_ip": { - "description": "The address at which the external nexus server is reachable.", - "type": "string", - "format": "ip" - }, - "external_tls": { - "description": "Whether Nexus's external endpoint should use TLS", - "type": "boolean" - }, - "internal_address": { - "description": "The address at which the internal nexus server is reachable.", - "type": "string" - }, - "nic": { - "description": "The service vNIC providing external connectivity using OPTE.", - "allOf": [ - { - "$ref": "#/definitions/NetworkInterface" - } - ] - }, - "type": { - "type": "string", - "enum": [ - "nexus" - ] - } - } - }, - { - "type": "object", - "required": [ - "dns_address", - "http_address", - "nic", - "type" - ], - "properties": { - "dns_address": { - "description": "The address at which the external DNS server is reachable.", - "type": "string" - }, - "http_address": { - "description": "The address at which the external DNS server API is reachable.", - "type": "string" - }, - "nic": { - "description": "The service vNIC providing external connectivity using OPTE.", - "allOf": [ - { - "$ref": "#/definitions/NetworkInterface" - } - ] - }, - "type": { - "type": "string", - "enum": [ - "external_dns" - ] - } - } - }, - { - "type": "object", - "required": [ - "dns_address", - "gz_address", - "gz_address_index", - "http_address", - "type" - ], - "properties": { - "dns_address": { - "type": "string" - }, - "gz_address": { - "description": "The addresses in the global zone which should be created\n\nFor the DNS service, which exists outside the sleds's typical subnet - adding an address in the GZ is necessary to allow inter-zone traffic routing.", - "type": "string", - "format": "ipv6" - }, - "gz_address_index": { - "description": "The address is also identified with an auxiliary bit of information to ensure that the created global zone address can have a unique name.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "http_address": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "internal_dns" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "type" - ], - "properties": { - "address": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "oximeter" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "type" - ], - "properties": { - "address": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "crucible_pantry" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "dns_servers", - "nic", - "ntp_servers", - "snat_cfg", - "type" - ], - "properties": { - "address": { - "type": "string" - }, - "dns_servers": { - "type": "array", - "items": { - "type": "string", - "format": "ip" - } - }, - "domain": { - "type": [ - "string", - "null" - ] - }, - "nic": { - "description": "The service vNIC providing outbound connectivity using OPTE.", - "allOf": [ - { - "$ref": "#/definitions/NetworkInterface" - } - ] - }, - "ntp_servers": { - "type": "array", - "items": { - "type": "string" - } - }, - "snat_cfg": { - "description": "The SNAT configuration for outbound connections.", - "allOf": [ - { - "$ref": "#/definitions/SourceNatConfig" - } - ] - }, - "type": { - "type": "string", - "enum": [ - "boundary_ntp" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "dns_servers", - "ntp_servers", - "type" - ], - "properties": { - "address": { - "type": "string" - }, - "dns_servers": { - "type": "array", - "items": { - "type": "string", - "format": "ip" - } - }, - "domain": { - "type": [ - "string", - "null" - ] - }, - "ntp_servers": { - "type": "array", - "items": { - "type": "string" - } - }, - "type": { - "type": "string", - "enum": [ - "internal_ntp" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "type" - ], - "properties": { - "address": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "clickhouse" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "type" - ], - "properties": { - "address": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "clickhouse_keeper" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "type" - ], - "properties": { - "address": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "cockroach_db" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "type" - ], - "properties": { - "address": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "crucible" - ] - } - } - } - ] - }, - "ServiceZoneRequest": { - "description": "Describes a request to create a zone running one or more services.", - "type": "object", - "required": [ - "addresses", - "id", - "services", - "zone_type" - ], - "properties": { - "addresses": { - "type": "array", - "items": { - "type": "string", - "format": "ipv6" - } - }, - "dataset": { - "anyOf": [ - { - "$ref": "#/definitions/DatasetRequest" - }, - { - "type": "null" - } - ] - }, - "id": { - "type": "string", - "format": "uuid" - }, - "services": { - "type": "array", - "items": { - "$ref": "#/definitions/ServiceZoneService" - } - }, - "zone_type": { - "$ref": "#/definitions/ZoneType" - } - } - }, - "ServiceZoneService": { - "description": "Used to request that the Sled initialize a single service.", - "type": "object", - "required": [ - "details", - "id" - ], - "properties": { - "details": { - "$ref": "#/definitions/ServiceType" - }, - "id": { - "type": "string", - "format": "uuid" - } - } - }, - "SourceNatConfig": { - "description": "An IP address and port range used for source NAT, i.e., making outbound network connections from guests or services.", - "type": "object", - "required": [ - "first_port", - "ip", - "last_port" - ], - "properties": { - "first_port": { - "description": "The first port used for source NAT, inclusive.", - "type": "integer", - "format": "uint16", - "minimum": 0.0 - }, - "ip": { - "description": "The external address provided to the instance or service.", - "type": "string", - "format": "ip" - }, - "last_port": { - "description": "The last port used for source NAT, also inclusive.", - "type": "integer", - "format": "uint16", - "minimum": 0.0 - } - } - }, - "Vni": { - "description": "A Geneve Virtual Network Identifier", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "ZoneRequest": { - "description": "This struct represents the combo of \"what zone did you ask for\" + \"where did we put it\".", - "type": "object", - "required": [ - "root", - "zone" - ], - "properties": { - "root": { - "type": "string" - }, - "zone": { - "$ref": "#/definitions/ServiceZoneRequest" - } - } - }, - "ZoneType": { - "description": "The type of zone that Sled Agent may run", - "type": "string", - "enum": [ - "clickhouse", - "clickhouse_keeper", - "cockroach_db", - "crucible_pantry", - "crucible", - "external_dns", - "internal_dns", - "nexus", - "ntp", - "oximeter", - "switch" - ] - }, - "ZpoolName": { - "title": "The name of a Zpool", - "description": "Zpool names are of the format ox{i,p}_. They are either Internal or External, and should be unique", - "type": "string", - "pattern": "^ox[ip]_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - } - } -} \ No newline at end of file diff --git a/sled-agent/src/bin/services-ledger-check-migrate.rs b/sled-agent/src/bin/services-ledger-check-migrate.rs deleted file mode 100644 index 456fdc74b7..0000000000 --- a/sled-agent/src/bin/services-ledger-check-migrate.rs +++ /dev/null @@ -1,80 +0,0 @@ -// 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/. - -//! Test-migrates one or more old-format services ledger files to new-format -//! Omicron zones ledgers - -use anyhow::Context; -use camino::Utf8PathBuf; -use clap::Args; -use clap::Parser; -use omicron_common::cmd::fatal; -use omicron_common::cmd::CmdError; -use omicron_sled_agent::services::OmicronZonesConfigLocal; -use omicron_sled_agent::services_migration::AllZoneRequests; - -#[tokio::main] -async fn main() { - if let Err(message) = do_run().await { - fatal(CmdError::Failure(message)); - } -} - -#[derive(Debug, Parser)] -#[clap(about = "Test conversion of old-format services ledgers to new-format \ - zones ledgers")] -enum Converter { - /// checks whether one or more ledger file(s) can be converted successfully - Check(CheckArgs), - - /// for a given ledger file, prints the converted form - Show(ShowArgs), -} - -#[derive(Debug, Args)] -struct CheckArgs { - #[clap(action)] - files: Vec, -} - -#[derive(Debug, Args)] -struct ShowArgs { - #[clap(action)] - file: Utf8PathBuf, -} - -async fn do_run() -> Result<(), anyhow::Error> { - let args = Converter::parse(); - - let (files, do_show) = match args { - Converter::Check(CheckArgs { files }) => (files, false), - Converter::Show(ShowArgs { file }) => (vec![file], true), - }; - - for file_path in &files { - let contents = tokio::fs::read_to_string(file_path) - .await - .with_context(|| format!("read {:?}", &file_path))?; - let parsed: AllZoneRequests = serde_json::from_str(&contents) - .with_context(|| format!("parse {:?}", &file_path))?; - let converted = OmicronZonesConfigLocal::try_from(parsed) - .with_context(|| format!("convert contents of {:?}", &file_path))?; - if do_show { - println!( - "{:#}", - serde_json::to_string_pretty(&converted).with_context( - || format!("print contents of {:?}", &file_path) - )? - ); - } - eprintln!( - "{}: processed okay (zones: {})", - file_path, - converted.zones.len() - ); - } - - eprintln!("all files processed okay (files: {})", files.len()); - Ok(()) -} diff --git a/sled-agent/src/lib.rs b/sled-agent/src/lib.rs index 989f011ed8..f7dc23e4d9 100644 --- a/sled-agent/src/lib.rs +++ b/sled-agent/src/lib.rs @@ -33,7 +33,6 @@ mod profile; pub mod rack_setup; pub mod server; pub mod services; -pub mod services_migration; mod sled_agent; mod smf_helper; mod storage_monitor; diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 70d68f6a8e..f335c2c257 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -35,7 +35,6 @@ use crate::params::{ TimeSync, ZoneBundleCause, ZoneBundleMetadata, ZoneType, }; use crate::profile::*; -use crate::services_migration::{AllZoneRequests, SERVICES_LEDGER_FILENAME}; use crate::smf_helper::SmfHelper; use crate::zone_bundle::BundleError; use crate::zone_bundle::ZoneBundler; @@ -759,7 +758,11 @@ impl ServiceManager { self.inner.switch_zone_bootstrap_address } + // TODO: This function refers to an old, deprecated format for storing + // service information. It is not deprecated for cleanup purposes, but + // should otherwise not be called in new code. async fn all_service_ledgers(&self) -> Vec { + pub const SERVICES_LEDGER_FILENAME: &str = "services.json"; if let Some(dir) = self.inner.ledger_directory_override.get() { return vec![dir.join(SERVICES_LEDGER_FILENAME)]; } @@ -785,157 +788,54 @@ impl ServiceManager { // Loads persistent configuration about any Omicron-managed zones that we're // supposed to be running. - // - // For historical reasons, there are two possible places this configuration - // could live, each with its own format. This function first checks the - // newer one. If no configuration was found there, it checks the older - // one. If only the older one was found, it is converted into the new form - // so that future calls will only look at the new form. async fn load_ledgered_zones( &self, // This argument attempts to ensure that the caller holds the right // lock. _map: &MutexGuard<'_, ZoneMap>, ) -> Result>, Error> { - // First, try to load the current software's zone ledger. If that - // works, we're done. let log = &self.inner.log; + + // NOTE: This is a function where we used to access zones by "service + // ledgers". This format has since been deprecated, and these files, + // if they exist, should not be used. + // + // We try to clean them up at this spot. Deleting this "removal" code + // in the future should be a safe operation; this is a non-load-bearing + // cleanup. + for path in self.all_service_ledgers().await { + match tokio::fs::remove_file(&path).await { + Ok(_) => (), + Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => (), + Err(e) => { + warn!( + log, + "Failed to delete old service ledger"; + "err" => ?e, + "path" => ?path, + ); + } + } + } + + // Try to load the current software's zone ledger let ledger_paths = self.all_omicron_zone_ledgers().await; info!(log, "Loading Omicron zones from: {ledger_paths:?}"); let maybe_ledger = Ledger::::new(log, ledger_paths.clone()) .await; - if let Some(ledger) = maybe_ledger { - info!( - log, - "Loaded Omicron zones"; - "zones_config" => ?ledger.data() - ); - return Ok(Some(ledger)); - } + let Some(ledger) = maybe_ledger else { + info!(log, "Loading Omicron zones - No zones detected"); + return Ok(None); + }; - // Now look for the ledger used by previous versions. If we find it, - // we'll convert it and write out a new ledger used by the current - // software. info!( log, - "Loading Omicron zones - No zones detected \ - (will look for old-format services)" - ); - let services_ledger_paths = self.all_service_ledgers().await; - info!( - log, - "Loading old-format services from: {services_ledger_paths:?}" + "Loaded Omicron zones"; + "zones_config" => ?ledger.data() ); - - let maybe_ledger = - Ledger::::new(log, services_ledger_paths.clone()) - .await; - let maybe_converted = match maybe_ledger { - None => { - // The ledger ignores all errors attempting to load files. That - // might be fine most of the time. In this case, we want to - // raise a big red flag if we find an old-format ledger that we - // can't process. - if services_ledger_paths.iter().any(|p| p.exists()) { - Err(Error::ServicesMigration(anyhow!( - "failed to read or parse old-format ledger, \ - but one exists" - ))) - } else { - // There was no old-format ledger at all. - return Ok(None); - } - } - Some(ledger) => { - let all_services = ledger.into_inner(); - OmicronZonesConfigLocal::try_from(all_services) - .map_err(Error::ServicesMigration) - } - }; - - match maybe_converted { - Err(error) => { - // We've tried to test thoroughly so that this should never - // happen. If for some reason it does happen, engineering - // intervention is likely to be required to figure out how to - // proceed. The current software does not directly support - // whatever was in the ledger, and it's not safe to just come up - // with no zones when we're supposed to be running stuff. We'll - // need to figure out what's unexpected about what we found in - // the ledger and figure out how to fix the - // conversion. - error!( - log, - "Loading Omicron zones - found services but failed \ - to convert them (support intervention required): \ - {:#}", - error - ); - return Err(error); - } - Ok(new_config) => { - // We've successfully converted the old ledger. Write a new - // one. - info!( - log, - "Successfully migrated old-format services ledger to \ - zones ledger" - ); - let mut ledger = Ledger::::new_with( - log, - ledger_paths.clone(), - new_config, - ); - - ledger.commit().await?; - - // We could consider removing the old ledger here. That would - // not guarantee that it would be gone, though, because we could - // crash during `ledger.commit()` above having written at least - // one of the new ledgers. In that case, we won't go through - // this code path again on restart. If we wanted to ensure the - // old-format ledger was gone after the migration, we could - // consider unconditionally removing the old ledger paths in the - // caller, after we've got a copy of the new-format ledger. - // - // Should we? In principle, it shouldn't matter either way - // because we will never look at the old-format ledger unless we - // don't have a new-format one, and we should now have a - // new-format one forever now. - // - // When might it matter? Two cases: - // - // (1) If the sled agent is downgraded to a previous version - // that doesn't know about the new-format ledger. Do we - // want that sled agent to use the old-format one? It - // depends. If that downgrade happens immediately because - // the upgrade to the first new-format version was a - // disaster, then we'd probably rather the downgraded sled - // agent _did_ start its zones. If the downgrade happens - // months later, potentially after various additional - // reconfigurations, then that old-format ledger is probably - // out of date and shouldn't be used. There's no way to - // really know which case we're in, but the latter seems - // quite unlikely (why would we downgrade so far back after - // so long?). So that's a reason to keep the old-format - // ledger. - // - // (2) Suppose a developer or Oxide support engineer removes the - // new ledger for some reason, maybe thinking sled agent - // would come up with no zones running. They'll be - // surprised to discover that it actually starts running a - // potentially old set of zones. This probably only matters - // on a production system, and even then, it probably - // shouldn't happen. - // - // Given these cases, we're left ambivalent. We choose to keep - // the old ledger around. If nothing else, if something goes - // wrong, we'll have a copy of its last contents! - Ok(Some(ledger)) - } - } + Ok(Some(ledger)) } // TODO(https://github.com/oxidecomputer/omicron/issues/2973): @@ -4989,109 +4889,6 @@ mod test { logctx.cleanup_successful(); } - #[tokio::test] - async fn test_old_ledger_migration() { - let logctx = omicron_test_utils::dev::test_setup_log( - "test_old_ledger_migration", - ); - let test_config = TestConfig::new().await; - - // Before we start the service manager, stuff one of our old-format - // service ledgers into place. - let contents = - include_str!("../tests/old-service-ledgers/rack2-sled10.json"); - std::fs::write( - test_config.config_dir.path().join(SERVICES_LEDGER_FILENAME), - contents, - ) - .expect("failed to copy example old-format services ledger into place"); - - // Now start the service manager. - let mut helper = - LedgerTestHelper::new(logctx.log.clone(), &test_config).await; - let mgr = helper.new_service_manager(); - LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); - - // Trigger the migration code. (Yes, it's hokey that we create this - // fake argument.) - let unused = Mutex::new(BTreeMap::new()); - let migrated_ledger = mgr - .load_ledgered_zones(&unused.lock().await) - .await - .expect("failed to load ledgered zones") - .unwrap(); - - // As a quick check, the migrated ledger should have some zones. - let migrated_config = migrated_ledger.data(); - assert!(!migrated_config.zones.is_empty()); - - // The ServiceManager should now report the migrated zones, meaning that - // they've been copied into the new-format ledger. - let found = - mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found, migrated_config.clone().to_omicron_zones_config()); - // They should both match the expected converted output. - let expected: OmicronZonesConfigLocal = serde_json::from_str( - include_str!("../tests/output/new-zones-ledgers/rack2-sled10.json"), - ) - .unwrap(); - let expected_config = expected.to_omicron_zones_config(); - assert_eq!(found, expected_config); - - // Just to be sure, shut down the manager and create a new one without - // triggering migration again. It should also report the same zones. - drop_service_manager(mgr); - - let mgr = helper.new_service_manager(); - LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); - - let found = - mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found, expected_config); - - drop_service_manager(mgr); - helper.cleanup().await; - logctx.cleanup_successful(); - } - - #[tokio::test] - async fn test_old_ledger_migration_bad() { - let logctx = omicron_test_utils::dev::test_setup_log( - "test_old_ledger_migration_bad", - ); - let test_config = TestConfig::new().await; - let mut helper = - LedgerTestHelper::new(logctx.log.clone(), &test_config).await; - - // Before we start things, stuff a broken ledger into place. For this - // to test what we want, it needs to be a valid ledger that we simply - // failed to convert. - std::fs::write( - test_config.config_dir.path().join(SERVICES_LEDGER_FILENAME), - "{", - ) - .expect("failed to copy example old-format services ledger into place"); - - // Start the service manager. - let mgr = helper.new_service_manager(); - LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); - - // Trigger the migration code. - let unused = Mutex::new(BTreeMap::new()); - let error = mgr - .load_ledgered_zones(&unused.lock().await) - .await - .expect_err("succeeded in loading bogus ledgered zones"); - assert_eq!( - "Error migrating old-format services ledger: failed to read or \ - parse old-format ledger, but one exists", - format!("{:#}", error) - ); - - helper.cleanup().await; - logctx.cleanup_successful(); - } - #[test] fn test_bootstrap_addr_to_techport_prefixes() { let ba: Ipv6Addr = "fdb0:1122:3344:5566::".parse().unwrap(); diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs deleted file mode 100644 index 511368e2f6..0000000000 --- a/sled-agent/src/services_migration.rs +++ /dev/null @@ -1,623 +0,0 @@ -// 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/. - -//! Sled Agents are responsible for running zones that make up much of the -//! control plane (Omicron). Configuration for these zones is owned by the -//! control plane, but that configuration must be persisted locally in order to -//! support cold boot of the control plane. (The control plane can't very well -//! tell sled agents what to run if it's not online yet!) -//! -//! Historically, these configurations were represented as an -//! `AllZonesRequests`, which contains a bunch of `ZoneRequest`s, each -//! containing a `ServiceZoneRequest`. This last structure was quite general -//! and made it possible to express a world of configurations that are not -//! actually valid. To avoid spreading extra complexity, these structures were -//! replaced with `OmicronZonesConfigLocal` and `OmicronZonesConfig`, -//! respectively. Upgrading production systems across this change requires -//! migrating any locally-stored configuration in the old format into the new -//! one. -//! -//! This file defines these old-format types and functions to convert them to -//! the new types, solely to perform that migration. We can remove all this -//! when we're satified that all deployed systems that we care about have moved -//! past this change. - -use crate::params::{ - OmicronZoneConfig, OmicronZoneDataset, OmicronZoneType, OmicronZonesConfig, - ZoneType, -}; -use crate::services::{OmicronZoneConfigLocal, OmicronZonesConfigLocal}; -use anyhow::{anyhow, ensure, Context}; -use camino::Utf8PathBuf; -use omicron_common::api::external::Generation; -use omicron_common::api::internal::shared::{ - NetworkInterface, SourceNatConfig, -}; -use omicron_common::ledger::Ledgerable; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use sled_storage::dataset::{DatasetKind, DatasetName}; -use std::fmt::Debug; -use std::net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6}; -use uuid::Uuid; - -/// The filename of the ledger containing this old-format configuration. -pub const SERVICES_LEDGER_FILENAME: &str = "services.json"; - -/// A wrapper around `ZoneRequest` that allows it to be serialized to a JSON -/// file. -#[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -pub struct AllZoneRequests { - /// ledger generation (not an Omicron-provided generation) - generation: Generation, - requests: Vec, -} - -impl Default for AllZoneRequests { - fn default() -> Self { - Self { generation: Generation::new(), requests: vec![] } - } -} - -impl Ledgerable for AllZoneRequests { - fn is_newer_than(&self, other: &AllZoneRequests) -> bool { - self.generation >= other.generation - } - - fn generation_bump(&mut self) { - self.generation = self.generation.next(); - } -} - -impl TryFrom for OmicronZonesConfigLocal { - type Error = anyhow::Error; - - fn try_from(input: AllZoneRequests) -> Result { - // The Omicron generation number that we choose here (2) deserves some - // explanation. - // - // This is supposed to be the control-plane-issued generation number for - // this configuration. But any configuration that we're converting here - // predates the point where the control plane issued generation numbers - // at all. So what should we assign it? Well, what are the - // constraints? - // - // - It must be newer than generation 1 because generation 1 canonically - // represents the initial state of having no zones deployed. If we - // used generation 1 here, any code could ignore this configuration on - // the grounds that it's no newer than what it already has. (The - // contents of a given generation are supposed to be immutable.) - // - // - It should be older than anything else that the control plane might - // try to send us so that if the control plane wants to change - // anything, we won't ignore its request because we think this - // configuration is newer. But really this has to be the control - // plane's responsibility, not ours. That is: Nexus needs to ask us - // what our generation number is and subsequent configurations should - // use newer generation numbers. It's not a great plan for it to - // assume anything about the generation numbers deployed on sleds - // whose configurations it's never seen. (In practice, newly deployed - // systems currently wind up with generation 5, so it _could_ choose - // something like 6 to start with -- or some larger number to leave - // some buffer.) - // - // In summary, 2 seems fine. - let omicron_generation = OmicronZonesConfig::INITIAL_GENERATION.next(); - - // The ledger generation doesn't really matter. In case it's useful, we - // pick the generation from the ledger that we loaded. - let ledger_generation = input.generation; - - let ndatasets_input = - input.requests.iter().filter(|r| r.zone.dataset.is_some()).count(); - - let zones = input - .requests - .into_iter() - .map(OmicronZoneConfigLocal::try_from) - .collect::, _>>() - .context( - "mapping `AllZoneRequests` to `OmicronZonesConfigLocal`", - )?; - - // As a quick check, the number of datasets in the old and new - // generations ought to be the same. - let ndatasets_output = - zones.iter().filter(|r| r.zone.dataset_name().is_some()).count(); - ensure!( - ndatasets_input == ndatasets_output, - "conversion produced a different number of datasets" - ); - - Ok(OmicronZonesConfigLocal { - omicron_generation, - ledger_generation, - zones, - }) - } -} - -/// This struct represents the combo of "what zone did you ask for" + "where did -/// we put it". -#[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -struct ZoneRequest { - zone: ServiceZoneRequest, - #[schemars(with = "String")] - root: Utf8PathBuf, -} - -impl TryFrom for OmicronZoneConfigLocal { - type Error = anyhow::Error; - - fn try_from(input: ZoneRequest) -> Result { - Ok(OmicronZoneConfigLocal { - zone: OmicronZoneConfig::try_from(input.zone)?, - root: input.root, - }) - } -} - -/// Describes a request to create a zone running one or more services. -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -struct ServiceZoneRequest { - // The UUID of the zone to be initialized. - id: Uuid, - // The type of the zone to be created. - zone_type: ZoneType, - // The addresses on which the service should listen for requests. - addresses: Vec, - // Datasets which should be managed by this service. - #[serde(default)] - dataset: Option, - // Services that should be run in the zone - services: Vec, -} - -impl TryFrom for OmicronZoneConfig { - type Error = anyhow::Error; - - fn try_from(input: ServiceZoneRequest) -> Result { - let error_context = || { - format!( - "zone {} (type {:?})", - input.id, - input.zone_type.to_string() - ) - }; - - // Historically, this type was used to describe two distinct kinds of - // thing: - // - // 1. an "Omicron" zone: Clickhouse, CockroachDb, Nexus, etc. We call - // these Omicron zones because they're managed by the control plane - // (Omicron). Nexus knows about these, stores information in - // CockroachDB about them, and is responsible for using Sled Agent - // APIs to configure these zones. - // - // 2. a "sled-local" zone. The only such zone is the "switch" zone. - // This is not really known to Nexus nor exposed outside Sled Agent. - // It's configured either based on Sled Agent's config file or else - // autodetection of whether this system _is_ a Scrimlet. - // - // All of the types in this file describe the ledgered configuration of - // the Omicron zones. We don't care about the switch zone here. Even - // for Omicron zones, the `ServiceZoneRequest` type is much more general - // than was strictly necessary to represent the kinds of zones we - // defined in practice. The more constrained schema is described by - // `OmicronZoneConfig`. This function verifies that the structures we - // find conform to that more constrained schema. - // - // Many of these properties were determined by code inspection. They - // could be wrong! But we've tried hard to make sure we're not wrong. - - match input.zone_type { - ZoneType::Clickhouse - | ZoneType::ClickhouseKeeper - | ZoneType::CockroachDb - | ZoneType::CruciblePantry - | ZoneType::Crucible - | ZoneType::ExternalDns - | ZoneType::InternalDns - | ZoneType::Nexus - | ZoneType::Ntp - | ZoneType::Oximeter => (), - ZoneType::Switch => { - return Err(anyhow!("unsupported zone type")) - .with_context(error_context) - } - } - - let id = input.id; - - // In production systems, Omicron zones only ever had exactly one - // address here. Multiple addresses were used for the "switch" zone, - // which cannot appear here. - if input.addresses.len() != 1 { - return Err(anyhow!( - "expected exactly one address, found {}", - input.addresses.len() - )) - .with_context(error_context); - } - - let underlay_address = input.addresses[0]; - - // In production systems, Omicron zones only ever had exactly one - // "service" inside them. (Multiple services were only supported for - // the "switch" zone and for Omicron zones in pre-release versions of - // Omicron, neither of which we expect to see here.) - if input.services.len() != 1 { - return Err(anyhow!( - "expected exactly one service, found {}", - input.services.len(), - )) - .with_context(error_context); - } - - let service = input.services.into_iter().next().unwrap(); - - // The id for the one service we found must match the overall request - // id. - if service.id != input.id { - return Err(anyhow!( - "expected service id ({}) to match id ({})", - service.id, - input.id, - )) - .with_context(error_context); - } - - // If there's a dataset, its id must match the overall request id. - let dataset_request = input - .dataset - .ok_or_else(|| anyhow!("missing dataset")) - .with_context(error_context); - let has_dataset = dataset_request.is_ok(); - if let Ok(dataset) = &dataset_request { - if dataset.id != input.id { - return Err(anyhow!( - "expected dataset id ({}) to match id ({})", - dataset.id, - input.id, - )) - .with_context(error_context); - } - } - - let zone_type = match service.details { - ServiceType::Nexus { - internal_address, - external_ip, - nic, - external_tls, - external_dns_servers, - } => OmicronZoneType::Nexus { - internal_address, - external_ip, - nic, - external_tls, - external_dns_servers, - }, - ServiceType::ExternalDns { http_address, dns_address, nic } => { - OmicronZoneType::ExternalDns { - dataset: dataset_request?.to_omicron_zone_dataset( - DatasetKind::ExternalDns, - http_address, - )?, - http_address, - dns_address, - nic, - } - } - ServiceType::InternalDns { - http_address, - dns_address, - gz_address, - gz_address_index, - } => OmicronZoneType::InternalDns { - dataset: dataset_request?.to_omicron_zone_dataset( - DatasetKind::InternalDns, - http_address, - )?, - http_address, - dns_address, - gz_address, - gz_address_index, - }, - ServiceType::Oximeter { address } => { - OmicronZoneType::Oximeter { address } - } - ServiceType::CruciblePantry { address } => { - OmicronZoneType::CruciblePantry { address } - } - ServiceType::BoundaryNtp { - address, - ntp_servers, - dns_servers, - domain, - nic, - snat_cfg, - } => OmicronZoneType::BoundaryNtp { - address, - ntp_servers, - dns_servers, - domain, - nic, - snat_cfg, - }, - ServiceType::InternalNtp { - address, - ntp_servers, - dns_servers, - domain, - } => OmicronZoneType::InternalNtp { - address, - ntp_servers, - dns_servers, - domain, - }, - ServiceType::Clickhouse { address } => { - OmicronZoneType::Clickhouse { - address, - dataset: dataset_request?.to_omicron_zone_dataset( - DatasetKind::Clickhouse, - address, - )?, - } - } - ServiceType::ClickhouseKeeper { address } => { - OmicronZoneType::ClickhouseKeeper { - address, - dataset: dataset_request?.to_omicron_zone_dataset( - DatasetKind::ClickhouseKeeper, - address, - )?, - } - } - ServiceType::CockroachDb { address } => { - OmicronZoneType::CockroachDb { - address, - dataset: dataset_request?.to_omicron_zone_dataset( - DatasetKind::CockroachDb, - address, - )?, - } - } - ServiceType::Crucible { address } => OmicronZoneType::Crucible { - address, - dataset: dataset_request? - .to_omicron_zone_dataset(DatasetKind::Crucible, address)?, - }, - }; - - if zone_type.dataset_name().is_none() && has_dataset { - // This indicates that the legacy form specified a dataset for a - // zone type that we do not (today) believe should have one. This - // should be impossible. If it happens, we need to re-evaluate our - // assumptions in designing `OmicronZoneType`. - return Err(anyhow!("found dataset that went unused")) - .with_context(error_context); - } - - Ok(OmicronZoneConfig { id, underlay_address, zone_type }) - } -} - -/// Used to request that the Sled initialize a single service. -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -struct ServiceZoneService { - id: Uuid, - details: ServiceType, -} - -/// Describes service-specific parameters. -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -#[serde(tag = "type", rename_all = "snake_case")] -enum ServiceType { - Nexus { - /// The address at which the internal nexus server is reachable. - internal_address: SocketAddrV6, - /// The address at which the external nexus server is reachable. - external_ip: IpAddr, - /// The service vNIC providing external connectivity using OPTE. - nic: NetworkInterface, - /// Whether Nexus's external endpoint should use TLS - external_tls: bool, - /// External DNS servers Nexus can use to resolve external hosts. - external_dns_servers: Vec, - }, - ExternalDns { - /// The address at which the external DNS server API is reachable. - http_address: SocketAddrV6, - /// The address at which the external DNS server is reachable. - dns_address: SocketAddr, - /// The service vNIC providing external connectivity using OPTE. - nic: NetworkInterface, - }, - InternalDns { - http_address: SocketAddrV6, - dns_address: SocketAddrV6, - /// The addresses in the global zone which should be created - /// - /// For the DNS service, which exists outside the sleds's typical subnet - /// - adding an address in the GZ is necessary to allow inter-zone - /// traffic routing. - gz_address: Ipv6Addr, - - /// The address is also identified with an auxiliary bit of information - /// to ensure that the created global zone address can have a unique - /// name. - gz_address_index: u32, - }, - Oximeter { - address: SocketAddrV6, - }, - CruciblePantry { - address: SocketAddrV6, - }, - BoundaryNtp { - address: SocketAddrV6, - ntp_servers: Vec, - dns_servers: Vec, - domain: Option, - /// The service vNIC providing outbound connectivity using OPTE. - nic: NetworkInterface, - /// The SNAT configuration for outbound connections. - snat_cfg: SourceNatConfig, - }, - InternalNtp { - address: SocketAddrV6, - ntp_servers: Vec, - dns_servers: Vec, - domain: Option, - }, - Clickhouse { - address: SocketAddrV6, - }, - ClickhouseKeeper { - address: SocketAddrV6, - }, - CockroachDb { - address: SocketAddrV6, - }, - Crucible { - address: SocketAddrV6, - }, -} - -/// Describes a request to provision a specific dataset -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -struct DatasetRequest { - id: Uuid, - name: DatasetName, - service_address: SocketAddrV6, -} - -impl DatasetRequest { - fn to_omicron_zone_dataset( - self, - kind: DatasetKind, - service_address: SocketAddrV6, - ) -> Result { - ensure!( - kind == *self.name.dataset(), - "expected dataset kind {:?}, found {:?}", - kind, - self.name.dataset(), - ); - - ensure!( - self.service_address == service_address, - "expected dataset kind {:?} service address to be {}, found {}", - kind, - service_address, - self.service_address, - ); - - Ok(OmicronZoneDataset { pool_name: self.name.pool().clone() }) - } -} - -#[cfg(test)] -mod test { - use super::AllZoneRequests; - use crate::services::OmicronZonesConfigLocal; - use camino::Utf8PathBuf; - - /// Verifies that our understanding of this old-format ledger has not - /// changed. (If you need to change this for some reason, you must figure - /// out how that affects systems with old-format ledgers and update this - /// test accordingly.) - #[test] - fn test_all_services_requests_schema() { - let schema = schemars::schema_for!(AllZoneRequests); - expectorate::assert_contents( - "../schema/all-zone-requests.json", - &serde_json::to_string_pretty(&schema).unwrap(), - ); - } - - /// Verifies that we can successfully convert a corpus of known old-format - /// ledgers. These came from two racks operated by Oxide. In practice - /// there probably aren't many different configurations represented here but - /// it's easy enough to just check them all. - /// - /// In terms of verifying the output: all we have done by hand in - /// constructing this test is verify that the code successfully converts - /// them. The conversion code does some basic sanity checks as well, like - /// that we produced the same number of zones and datasets. - #[test] - fn test_convert_known_ledgers() { - let known_ledgers = &[ - /* rack2 */ - "rack2-sled8.json", - "rack2-sled9.json", - "rack2-sled10.json", - "rack2-sled11.json", - "rack2-sled12.json", - "rack2-sled14.json", - "rack2-sled16.json", - "rack2-sled17.json", - "rack2-sled21.json", - "rack2-sled23.json", - "rack2-sled25.json", - /* rack3 (no sled 10) */ - "rack3-sled0.json", - "rack3-sled1.json", - "rack3-sled2.json", - "rack3-sled3.json", - "rack3-sled4.json", - "rack3-sled5.json", - "rack3-sled6.json", - "rack3-sled7.json", - "rack3-sled8.json", - "rack3-sled9.json", - "rack3-sled11.json", - "rack3-sled12.json", - "rack3-sled13.json", - "rack3-sled14.json", - "rack3-sled15.json", - "rack3-sled16.json", - "rack3-sled17.json", - "rack3-sled18.json", - "rack3-sled19.json", - "rack3-sled20.json", - "rack3-sled21.json", - "rack3-sled22.json", - "rack3-sled23.json", - "rack3-sled24.json", - "rack3-sled25.json", - "rack3-sled26.json", - "rack3-sled27.json", - "rack3-sled28.json", - "rack3-sled29.json", - "rack3-sled30.json", - "rack3-sled31.json", - ]; - - let path = Utf8PathBuf::from("tests/old-service-ledgers"); - let out_path = Utf8PathBuf::from("tests/output/new-zones-ledgers"); - for ledger_basename in known_ledgers { - println!("checking {:?}", ledger_basename); - let contents = std::fs::read_to_string(path.join(ledger_basename)) - .expect("failed to read file"); - let parsed: AllZoneRequests = - serde_json::from_str(&contents).expect("failed to parse file"); - let converted = OmicronZonesConfigLocal::try_from(parsed) - .expect("failed to convert file"); - expectorate::assert_contents( - out_path.join(ledger_basename), - &serde_json::to_string_pretty(&converted).unwrap(), - ); - } - } -} diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled10.json b/sled-agent/tests/old-service-ledgers/rack2-sled10.json deleted file mode 100644 index b92a2bf4a0..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled10.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"04eef8aa-055c-42ab-bdb6-c982f63c9be0","zone_type":"crucible","addresses":["fd00:1122:3344:107::d"],"dataset":{"id":"04eef8aa-055c-42ab-bdb6-c982f63c9be0","name":{"pool_name":"oxp_845ff39a-3205-416f-8bda-e35829107c8a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::d]:32345"},"services":[{"id":"04eef8aa-055c-42ab-bdb6-c982f63c9be0","details":{"type":"crucible","address":"[fd00:1122:3344:107::d]:32345"}}]},"root":"/pool/ext/43efdd6d-7419-437a-a282-fc45bfafd042/crypt/zone"},{"zone":{"id":"8568c997-fbbb-46a8-8549-b78284530ffc","zone_type":"crucible","addresses":["fd00:1122:3344:107::5"],"dataset":{"id":"8568c997-fbbb-46a8-8549-b78284530ffc","name":{"pool_name":"oxp_0e485ad3-04e6-404b-b619-87d4fea9f5ae","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::5]:32345"},"services":[{"id":"8568c997-fbbb-46a8-8549-b78284530ffc","details":{"type":"crucible","address":"[fd00:1122:3344:107::5]:32345"}}]},"root":"/pool/ext/9b61d4b2-66f6-459f-86f4-13d0b8c5d6cf/crypt/zone"},{"zone":{"id":"6cec1d60-5c1a-4c1b-9632-2b4bc76bd37c","zone_type":"crucible","addresses":["fd00:1122:3344:107::e"],"dataset":{"id":"6cec1d60-5c1a-4c1b-9632-2b4bc76bd37c","name":{"pool_name":"oxp_62a4c68a-2073-42d0-8e49-01f5e8b90cd4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::e]:32345"},"services":[{"id":"6cec1d60-5c1a-4c1b-9632-2b4bc76bd37c","details":{"type":"crucible","address":"[fd00:1122:3344:107::e]:32345"}}]},"root":"/pool/ext/845ff39a-3205-416f-8bda-e35829107c8a/crypt/zone"},{"zone":{"id":"aa646c82-c6d7-4d0c-8401-150130927759","zone_type":"clickhouse","addresses":["fd00:1122:3344:107::4"],"dataset":{"id":"aa646c82-c6d7-4d0c-8401-150130927759","name":{"pool_name":"oxp_0e485ad3-04e6-404b-b619-87d4fea9f5ae","kind":{"type":"clickhouse"}},"service_address":"[fd00:1122:3344:107::4]:8123"},"services":[{"id":"aa646c82-c6d7-4d0c-8401-150130927759","details":{"type":"clickhouse","address":"[fd00:1122:3344:107::4]:8123"}}]},"root":"/pool/ext/fd82dcc7-00dd-4d01-826a-937a7d8238fb/crypt/zone"},{"zone":{"id":"2f294ca1-7a4f-468f-8966-2b7915804729","zone_type":"crucible","addresses":["fd00:1122:3344:107::7"],"dataset":{"id":"2f294ca1-7a4f-468f-8966-2b7915804729","name":{"pool_name":"oxp_43efdd6d-7419-437a-a282-fc45bfafd042","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::7]:32345"},"services":[{"id":"2f294ca1-7a4f-468f-8966-2b7915804729","details":{"type":"crucible","address":"[fd00:1122:3344:107::7]:32345"}}]},"root":"/pool/ext/fd82dcc7-00dd-4d01-826a-937a7d8238fb/crypt/zone"},{"zone":{"id":"1a77bd1d-4fd4-4d6c-a105-17f942d94ba6","zone_type":"crucible","addresses":["fd00:1122:3344:107::c"],"dataset":{"id":"1a77bd1d-4fd4-4d6c-a105-17f942d94ba6","name":{"pool_name":"oxp_b6bdfdaf-9c0d-4b74-926c-49ff3ed05562","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::c]:32345"},"services":[{"id":"1a77bd1d-4fd4-4d6c-a105-17f942d94ba6","details":{"type":"crucible","address":"[fd00:1122:3344:107::c]:32345"}}]},"root":"/pool/ext/9b61d4b2-66f6-459f-86f4-13d0b8c5d6cf/crypt/zone"},{"zone":{"id":"f65a6668-1aea-4deb-81ed-191fbe469328","zone_type":"crucible","addresses":["fd00:1122:3344:107::9"],"dataset":{"id":"f65a6668-1aea-4deb-81ed-191fbe469328","name":{"pool_name":"oxp_9b61d4b2-66f6-459f-86f4-13d0b8c5d6cf","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::9]:32345"},"services":[{"id":"f65a6668-1aea-4deb-81ed-191fbe469328","details":{"type":"crucible","address":"[fd00:1122:3344:107::9]:32345"}}]},"root":"/pool/ext/d0584f4a-20ba-436d-a75b-7709e80deb79/crypt/zone"},{"zone":{"id":"ee8bce67-8f8e-4221-97b0-85f1860d66d0","zone_type":"crucible","addresses":["fd00:1122:3344:107::8"],"dataset":{"id":"ee8bce67-8f8e-4221-97b0-85f1860d66d0","name":{"pool_name":"oxp_b252b176-3974-436a-915b-60382b21eb76","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::8]:32345"},"services":[{"id":"ee8bce67-8f8e-4221-97b0-85f1860d66d0","details":{"type":"crucible","address":"[fd00:1122:3344:107::8]:32345"}}]},"root":"/pool/ext/b6bdfdaf-9c0d-4b74-926c-49ff3ed05562/crypt/zone"},{"zone":{"id":"cf3b2d54-5e36-4c93-b44f-8bf36ac98071","zone_type":"crucible","addresses":["fd00:1122:3344:107::b"],"dataset":{"id":"cf3b2d54-5e36-4c93-b44f-8bf36ac98071","name":{"pool_name":"oxp_d0584f4a-20ba-436d-a75b-7709e80deb79","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::b]:32345"},"services":[{"id":"cf3b2d54-5e36-4c93-b44f-8bf36ac98071","details":{"type":"crucible","address":"[fd00:1122:3344:107::b]:32345"}}]},"root":"/pool/ext/4c157f35-865d-4310-9d81-c6259cb69293/crypt/zone"},{"zone":{"id":"5c8c244c-00dc-4b16-aa17-6d9eb4827fab","zone_type":"crucible","addresses":["fd00:1122:3344:107::a"],"dataset":{"id":"5c8c244c-00dc-4b16-aa17-6d9eb4827fab","name":{"pool_name":"oxp_4c157f35-865d-4310-9d81-c6259cb69293","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::a]:32345"},"services":[{"id":"5c8c244c-00dc-4b16-aa17-6d9eb4827fab","details":{"type":"crucible","address":"[fd00:1122:3344:107::a]:32345"}}]},"root":"/pool/ext/845ff39a-3205-416f-8bda-e35829107c8a/crypt/zone"},{"zone":{"id":"7d5e942b-926c-442d-937a-76cc4aa72bf3","zone_type":"crucible","addresses":["fd00:1122:3344:107::6"],"dataset":{"id":"7d5e942b-926c-442d-937a-76cc4aa72bf3","name":{"pool_name":"oxp_fd82dcc7-00dd-4d01-826a-937a7d8238fb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::6]:32345"},"services":[{"id":"7d5e942b-926c-442d-937a-76cc4aa72bf3","details":{"type":"crucible","address":"[fd00:1122:3344:107::6]:32345"}}]},"root":"/pool/ext/b252b176-3974-436a-915b-60382b21eb76/crypt/zone"},{"zone":{"id":"a3628a56-6f85-43b5-be50-71d8f0e04877","zone_type":"cockroach_db","addresses":["fd00:1122:3344:107::3"],"dataset":{"id":"a3628a56-6f85-43b5-be50-71d8f0e04877","name":{"pool_name":"oxp_0e485ad3-04e6-404b-b619-87d4fea9f5ae","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:107::3]:32221"},"services":[{"id":"a3628a56-6f85-43b5-be50-71d8f0e04877","details":{"type":"cockroach_db","address":"[fd00:1122:3344:107::3]:32221"}}]},"root":"/pool/ext/4c157f35-865d-4310-9d81-c6259cb69293/crypt/zone"},{"zone":{"id":"7529be1c-ca8b-441a-89aa-37166cc450df","zone_type":"ntp","addresses":["fd00:1122:3344:107::f"],"dataset":null,"services":[{"id":"7529be1c-ca8b-441a-89aa-37166cc450df","details":{"type":"internal_ntp","address":"[fd00:1122:3344:107::f]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/fd82dcc7-00dd-4d01-826a-937a7d8238fb/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled11.json b/sled-agent/tests/old-service-ledgers/rack2-sled11.json deleted file mode 100644 index 3833bed5c9..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled11.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"605be8b9-c652-4a5f-94ca-068ec7a39472","zone_type":"crucible","addresses":["fd00:1122:3344:106::a"],"dataset":{"id":"605be8b9-c652-4a5f-94ca-068ec7a39472","name":{"pool_name":"oxp_cf14d1b9-b4db-4594-b3ab-a9957e770ce9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::a]:32345"},"services":[{"id":"605be8b9-c652-4a5f-94ca-068ec7a39472","details":{"type":"crucible","address":"[fd00:1122:3344:106::a]:32345"}}]},"root":"/pool/ext/cf5f8849-0c5a-475b-8683-6d17da88d1d1/crypt/zone"},{"zone":{"id":"af8a8712-457c-4ea7-a8b6-aecb04761c1b","zone_type":"crucible","addresses":["fd00:1122:3344:106::9"],"dataset":{"id":"af8a8712-457c-4ea7-a8b6-aecb04761c1b","name":{"pool_name":"oxp_cf5f8849-0c5a-475b-8683-6d17da88d1d1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::9]:32345"},"services":[{"id":"af8a8712-457c-4ea7-a8b6-aecb04761c1b","details":{"type":"crucible","address":"[fd00:1122:3344:106::9]:32345"}}]},"root":"/pool/ext/7f778610-7328-4554-98f6-b17f74f551c7/crypt/zone"},{"zone":{"id":"0022703b-dcfc-44d4-897a-b42f6f53b433","zone_type":"crucible","addresses":["fd00:1122:3344:106::c"],"dataset":{"id":"0022703b-dcfc-44d4-897a-b42f6f53b433","name":{"pool_name":"oxp_025725fa-9e40-4b46-b018-c420408394ef","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::c]:32345"},"services":[{"id":"0022703b-dcfc-44d4-897a-b42f6f53b433","details":{"type":"crucible","address":"[fd00:1122:3344:106::c]:32345"}}]},"root":"/pool/ext/025725fa-9e40-4b46-b018-c420408394ef/crypt/zone"},{"zone":{"id":"fffddf56-10ca-4b62-9be3-5b3764a5f682","zone_type":"crucible","addresses":["fd00:1122:3344:106::d"],"dataset":{"id":"fffddf56-10ca-4b62-9be3-5b3764a5f682","name":{"pool_name":"oxp_4d2f5aaf-eb14-4b1e-aa99-ae38ec844605","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::d]:32345"},"services":[{"id":"fffddf56-10ca-4b62-9be3-5b3764a5f682","details":{"type":"crucible","address":"[fd00:1122:3344:106::d]:32345"}}]},"root":"/pool/ext/834c9aad-c53b-4357-bc3f-f422efa63848/crypt/zone"},{"zone":{"id":"9b8194ee-917d-4abc-a55c-94cea6cdaea1","zone_type":"crucible","addresses":["fd00:1122:3344:106::6"],"dataset":{"id":"9b8194ee-917d-4abc-a55c-94cea6cdaea1","name":{"pool_name":"oxp_d7665e0d-9354-4341-a76f-965d7c49f277","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::6]:32345"},"services":[{"id":"9b8194ee-917d-4abc-a55c-94cea6cdaea1","details":{"type":"crucible","address":"[fd00:1122:3344:106::6]:32345"}}]},"root":"/pool/ext/cf5f8849-0c5a-475b-8683-6d17da88d1d1/crypt/zone"},{"zone":{"id":"b369e133-485c-4d98-8fee-83542d1fd94d","zone_type":"crucible","addresses":["fd00:1122:3344:106::4"],"dataset":{"id":"b369e133-485c-4d98-8fee-83542d1fd94d","name":{"pool_name":"oxp_4366f80d-3902-4b93-8f2d-380008e805fc","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::4]:32345"},"services":[{"id":"b369e133-485c-4d98-8fee-83542d1fd94d","details":{"type":"crucible","address":"[fd00:1122:3344:106::4]:32345"}}]},"root":"/pool/ext/025725fa-9e40-4b46-b018-c420408394ef/crypt/zone"},{"zone":{"id":"edd99650-5df1-4241-815d-253e4ef2399c","zone_type":"external_dns","addresses":["fd00:1122:3344:106::3"],"dataset":{"id":"edd99650-5df1-4241-815d-253e4ef2399c","name":{"pool_name":"oxp_4366f80d-3902-4b93-8f2d-380008e805fc","kind":{"type":"external_dns"}},"service_address":"[fd00:1122:3344:106::3]:5353"},"services":[{"id":"edd99650-5df1-4241-815d-253e4ef2399c","details":{"type":"external_dns","http_address":"[fd00:1122:3344:106::3]:5353","dns_address":"172.20.26.1:53","nic":{"id":"99b759fc-8e2e-44b7-aca8-93c3b201974d","kind":{"type":"service","id":"edd99650-5df1-4241-815d-253e4ef2399c"},"name":"external-dns-edd99650-5df1-4241-815d-253e4ef2399c","ip":"172.30.1.5","mac":"A8:40:25:FF:B0:9C","subnet":"172.30.1.0/24","vni":100,"primary":true,"slot":0}}}]},"root":"/pool/ext/7f778610-7328-4554-98f6-b17f74f551c7/crypt/zone"},{"zone":{"id":"46d1afcc-cc3f-4b17-aafc-054dd4862d15","zone_type":"crucible","addresses":["fd00:1122:3344:106::5"],"dataset":{"id":"46d1afcc-cc3f-4b17-aafc-054dd4862d15","name":{"pool_name":"oxp_7f778610-7328-4554-98f6-b17f74f551c7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::5]:32345"},"services":[{"id":"46d1afcc-cc3f-4b17-aafc-054dd4862d15","details":{"type":"crucible","address":"[fd00:1122:3344:106::5]:32345"}}]},"root":"/pool/ext/cf5f8849-0c5a-475b-8683-6d17da88d1d1/crypt/zone"},{"zone":{"id":"12afe1c3-bfe6-4278-8240-91d401347d36","zone_type":"crucible","addresses":["fd00:1122:3344:106::8"],"dataset":{"id":"12afe1c3-bfe6-4278-8240-91d401347d36","name":{"pool_name":"oxp_534bcd4b-502f-4109-af6e-4b28a22c20f1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::8]:32345"},"services":[{"id":"12afe1c3-bfe6-4278-8240-91d401347d36","details":{"type":"crucible","address":"[fd00:1122:3344:106::8]:32345"}}]},"root":"/pool/ext/4366f80d-3902-4b93-8f2d-380008e805fc/crypt/zone"},{"zone":{"id":"c33b5912-9985-43ed-98f2-41297e2b796a","zone_type":"crucible","addresses":["fd00:1122:3344:106::b"],"dataset":{"id":"c33b5912-9985-43ed-98f2-41297e2b796a","name":{"pool_name":"oxp_834c9aad-c53b-4357-bc3f-f422efa63848","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::b]:32345"},"services":[{"id":"c33b5912-9985-43ed-98f2-41297e2b796a","details":{"type":"crucible","address":"[fd00:1122:3344:106::b]:32345"}}]},"root":"/pool/ext/d7665e0d-9354-4341-a76f-965d7c49f277/crypt/zone"},{"zone":{"id":"65b3db59-9361-4100-9cee-04e32a8c67d3","zone_type":"crucible","addresses":["fd00:1122:3344:106::7"],"dataset":{"id":"65b3db59-9361-4100-9cee-04e32a8c67d3","name":{"pool_name":"oxp_32b5303f-f667-4345-84d2-c7eec63b91b2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::7]:32345"},"services":[{"id":"65b3db59-9361-4100-9cee-04e32a8c67d3","details":{"type":"crucible","address":"[fd00:1122:3344:106::7]:32345"}}]},"root":"/pool/ext/d7665e0d-9354-4341-a76f-965d7c49f277/crypt/zone"},{"zone":{"id":"82500cc9-f33d-4d59-9e6e-d70ea6133077","zone_type":"ntp","addresses":["fd00:1122:3344:106::e"],"dataset":null,"services":[{"id":"82500cc9-f33d-4d59-9e6e-d70ea6133077","details":{"type":"internal_ntp","address":"[fd00:1122:3344:106::e]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/cf14d1b9-b4db-4594-b3ab-a9957e770ce9/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled12.json b/sled-agent/tests/old-service-ledgers/rack2-sled12.json deleted file mode 100644 index 5126c007f3..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled12.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":5,"requests":[{"zone":{"id":"a76b3357-b690-43b8-8352-3300568ffc2b","zone_type":"crucible","addresses":["fd00:1122:3344:104::a"],"dataset":{"id":"a76b3357-b690-43b8-8352-3300568ffc2b","name":{"pool_name":"oxp_05715ad8-59a1-44ab-ad5f-0cdffb46baab","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::a]:32345"},"services":[{"id":"a76b3357-b690-43b8-8352-3300568ffc2b","details":{"type":"crucible","address":"[fd00:1122:3344:104::a]:32345"}}]},"root":"/pool/ext/2ec2a731-3340-4777-b1bb-4a906c598174/crypt/zone"},{"zone":{"id":"8d202759-ca06-4383-b50f-7f3ec4062bf7","zone_type":"crucible","addresses":["fd00:1122:3344:104::4"],"dataset":{"id":"8d202759-ca06-4383-b50f-7f3ec4062bf7","name":{"pool_name":"oxp_56e32a8f-0877-4437-9cab-94a4928b1495","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::4]:32345"},"services":[{"id":"8d202759-ca06-4383-b50f-7f3ec4062bf7","details":{"type":"crucible","address":"[fd00:1122:3344:104::4]:32345"}}]},"root":"/pool/ext/613b58fc-5a80-42dc-a61c-b143cf220fb5/crypt/zone"},{"zone":{"id":"fcdda266-fc6a-4518-89db-aec007a4b682","zone_type":"crucible","addresses":["fd00:1122:3344:104::b"],"dataset":{"id":"fcdda266-fc6a-4518-89db-aec007a4b682","name":{"pool_name":"oxp_7e1293ad-b903-4054-aeae-2182d5e4a785","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::b]:32345"},"services":[{"id":"fcdda266-fc6a-4518-89db-aec007a4b682","details":{"type":"crucible","address":"[fd00:1122:3344:104::b]:32345"}}]},"root":"/pool/ext/416fd29e-d3b5-4fdf-8101-d0d163fa0706/crypt/zone"},{"zone":{"id":"167cf6a2-ec51-4de2-bc6c-7785bbc0e436","zone_type":"crucible","addresses":["fd00:1122:3344:104::c"],"dataset":{"id":"167cf6a2-ec51-4de2-bc6c-7785bbc0e436","name":{"pool_name":"oxp_f96c8d49-fdf7-4bd6-84f6-c282202d1abc","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::c]:32345"},"services":[{"id":"167cf6a2-ec51-4de2-bc6c-7785bbc0e436","details":{"type":"crucible","address":"[fd00:1122:3344:104::c]:32345"}}]},"root":"/pool/ext/56e32a8f-0877-4437-9cab-94a4928b1495/crypt/zone"},{"zone":{"id":"c6fde82d-8dae-4ef0-b557-6c3d094d9454","zone_type":"crucible","addresses":["fd00:1122:3344:104::9"],"dataset":{"id":"c6fde82d-8dae-4ef0-b557-6c3d094d9454","name":{"pool_name":"oxp_416fd29e-d3b5-4fdf-8101-d0d163fa0706","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::9]:32345"},"services":[{"id":"c6fde82d-8dae-4ef0-b557-6c3d094d9454","details":{"type":"crucible","address":"[fd00:1122:3344:104::9]:32345"}}]},"root":"/pool/ext/3af01cc4-1f16-47d9-a489-abafcb91c2db/crypt/zone"},{"zone":{"id":"650f5da7-86a0-4ade-af0f-bc96e021ded0","zone_type":"crucible","addresses":["fd00:1122:3344:104::5"],"dataset":{"id":"650f5da7-86a0-4ade-af0f-bc96e021ded0","name":{"pool_name":"oxp_b4a71d3d-1ecd-418a-9a52-8d118f82082b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::5]:32345"},"services":[{"id":"650f5da7-86a0-4ade-af0f-bc96e021ded0","details":{"type":"crucible","address":"[fd00:1122:3344:104::5]:32345"}}]},"root":"/pool/ext/613b58fc-5a80-42dc-a61c-b143cf220fb5/crypt/zone"},{"zone":{"id":"7ce9a2c5-2d37-4188-b7b5-a9db819396c3","zone_type":"crucible","addresses":["fd00:1122:3344:104::d"],"dataset":{"id":"7ce9a2c5-2d37-4188-b7b5-a9db819396c3","name":{"pool_name":"oxp_c87d16b8-e814-4159-8562-f8d7fdd19d13","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::d]:32345"},"services":[{"id":"7ce9a2c5-2d37-4188-b7b5-a9db819396c3","details":{"type":"crucible","address":"[fd00:1122:3344:104::d]:32345"}}]},"root":"/pool/ext/416fd29e-d3b5-4fdf-8101-d0d163fa0706/crypt/zone"},{"zone":{"id":"23e1cf01-70ab-422f-997b-6216158965c3","zone_type":"crucible","addresses":["fd00:1122:3344:104::8"],"dataset":{"id":"23e1cf01-70ab-422f-997b-6216158965c3","name":{"pool_name":"oxp_3af01cc4-1f16-47d9-a489-abafcb91c2db","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::8]:32345"},"services":[{"id":"23e1cf01-70ab-422f-997b-6216158965c3","details":{"type":"crucible","address":"[fd00:1122:3344:104::8]:32345"}}]},"root":"/pool/ext/3af01cc4-1f16-47d9-a489-abafcb91c2db/crypt/zone"},{"zone":{"id":"50209816-89fb-48ed-9595-16899d114844","zone_type":"crucible","addresses":["fd00:1122:3344:104::6"],"dataset":{"id":"50209816-89fb-48ed-9595-16899d114844","name":{"pool_name":"oxp_2ec2a731-3340-4777-b1bb-4a906c598174","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::6]:32345"},"services":[{"id":"50209816-89fb-48ed-9595-16899d114844","details":{"type":"crucible","address":"[fd00:1122:3344:104::6]:32345"}}]},"root":"/pool/ext/416fd29e-d3b5-4fdf-8101-d0d163fa0706/crypt/zone"},{"zone":{"id":"20b100d0-84c3-4119-aa9b-0c632b0b6a3a","zone_type":"nexus","addresses":["fd00:1122:3344:104::3"],"dataset":null,"services":[{"id":"20b100d0-84c3-4119-aa9b-0c632b0b6a3a","details":{"type":"nexus","internal_address":"[fd00:1122:3344:104::3]:12221","external_ip":"172.20.26.4","nic":{"id":"364b0ecd-bf08-4cac-a993-bbf4a70564c7","kind":{"type":"service","id":"20b100d0-84c3-4119-aa9b-0c632b0b6a3a"},"name":"nexus-20b100d0-84c3-4119-aa9b-0c632b0b6a3a","ip":"172.30.2.6","mac":"A8:40:25:FF:B4:C1","subnet":"172.30.2.0/24","vni":100,"primary":true,"slot":0},"external_tls":true,"external_dns_servers":["1.1.1.1","9.9.9.9"]}}]},"root":"/pool/ext/c87d16b8-e814-4159-8562-f8d7fdd19d13/crypt/zone"},{"zone":{"id":"8bc0f29e-0c20-437e-b8ca-7b9844acda22","zone_type":"crucible","addresses":["fd00:1122:3344:104::7"],"dataset":{"id":"8bc0f29e-0c20-437e-b8ca-7b9844acda22","name":{"pool_name":"oxp_613b58fc-5a80-42dc-a61c-b143cf220fb5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::7]:32345"},"services":[{"id":"8bc0f29e-0c20-437e-b8ca-7b9844acda22","details":{"type":"crucible","address":"[fd00:1122:3344:104::7]:32345"}}]},"root":"/pool/ext/56e32a8f-0877-4437-9cab-94a4928b1495/crypt/zone"},{"zone":{"id":"c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55","zone_type":"ntp","addresses":["fd00:1122:3344:104::e"],"dataset":null,"services":[{"id":"c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55","details":{"type":"boundary_ntp","address":"[fd00:1122:3344:104::e]:123","ntp_servers":["ntp.eng.oxide.computer"],"dns_servers":["1.1.1.1","9.9.9.9"],"domain":null,"nic":{"id":"a4b9bacf-6c04-431a-81ad-9bf0302af96e","kind":{"type":"service","id":"c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55"},"name":"ntp-c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55","ip":"172.30.3.5","mac":"A8:40:25:FF:B2:52","subnet":"172.30.3.0/24","vni":100,"primary":true,"slot":0},"snat_cfg":{"ip":"172.20.26.6","first_port":0,"last_port":16383}}}]},"root":"/pool/ext/3af01cc4-1f16-47d9-a489-abafcb91c2db/crypt/zone"},{"zone":{"id":"51c9ad09-7814-4643-8ad4-689ccbe53fbd","zone_type":"internal_dns","addresses":["fd00:1122:3344:1::1"],"dataset":{"id":"51c9ad09-7814-4643-8ad4-689ccbe53fbd","name":{"pool_name":"oxp_56e32a8f-0877-4437-9cab-94a4928b1495","kind":{"type":"internal_dns"}},"service_address":"[fd00:1122:3344:1::1]:5353"},"services":[{"id":"51c9ad09-7814-4643-8ad4-689ccbe53fbd","details":{"type":"internal_dns","http_address":"[fd00:1122:3344:1::1]:5353","dns_address":"[fd00:1122:3344:1::1]:53","gz_address":"fd00:1122:3344:1::2","gz_address_index":0}}]},"root":"/pool/ext/3af01cc4-1f16-47d9-a489-abafcb91c2db/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled14.json b/sled-agent/tests/old-service-ledgers/rack2-sled14.json deleted file mode 100644 index 421e21d84d..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled14.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"ee8b2cfa-87fe-46a6-98ef-23640b80a968","zone_type":"crucible","addresses":["fd00:1122:3344:10b::d"],"dataset":{"id":"ee8b2cfa-87fe-46a6-98ef-23640b80a968","name":{"pool_name":"oxp_4a624324-003a-4255-98e8-546a90b5b7fa","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::d]:32345"},"services":[{"id":"ee8b2cfa-87fe-46a6-98ef-23640b80a968","details":{"type":"crucible","address":"[fd00:1122:3344:10b::d]:32345"}}]},"root":"/pool/ext/6b9ec5f1-859f-459c-9c06-6a51ba87786f/crypt/zone"},{"zone":{"id":"9228f8ca-2a83-439f-9cb7-f2801b5fea27","zone_type":"crucible","addresses":["fd00:1122:3344:10b::6"],"dataset":{"id":"9228f8ca-2a83-439f-9cb7-f2801b5fea27","name":{"pool_name":"oxp_6b9ec5f1-859f-459c-9c06-6a51ba87786f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::6]:32345"},"services":[{"id":"9228f8ca-2a83-439f-9cb7-f2801b5fea27","details":{"type":"crucible","address":"[fd00:1122:3344:10b::6]:32345"}}]},"root":"/pool/ext/6b9ec5f1-859f-459c-9c06-6a51ba87786f/crypt/zone"},{"zone":{"id":"ee44cdde-7ac9-4469-9f1d-e8bcfeb5cc46","zone_type":"crucible","addresses":["fd00:1122:3344:10b::e"],"dataset":{"id":"ee44cdde-7ac9-4469-9f1d-e8bcfeb5cc46","name":{"pool_name":"oxp_11b02ce7-7e50-486f-86c2-de8af9575a45","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::e]:32345"},"services":[{"id":"ee44cdde-7ac9-4469-9f1d-e8bcfeb5cc46","details":{"type":"crucible","address":"[fd00:1122:3344:10b::e]:32345"}}]},"root":"/pool/ext/11b02ce7-7e50-486f-86c2-de8af9575a45/crypt/zone"},{"zone":{"id":"96bac0b1-8b34-4c81-9e76-6404d2c37630","zone_type":"crucible_pantry","addresses":["fd00:1122:3344:10b::4"],"dataset":null,"services":[{"id":"96bac0b1-8b34-4c81-9e76-6404d2c37630","details":{"type":"crucible_pantry","address":"[fd00:1122:3344:10b::4]:17000"}}]},"root":"/pool/ext/350b2814-7b7f-40f1-9bf6-9818a1ef49bb/crypt/zone"},{"zone":{"id":"d4e1e554-7b98-4413-809e-4a42561c3d0c","zone_type":"crucible","addresses":["fd00:1122:3344:10b::a"],"dataset":{"id":"d4e1e554-7b98-4413-809e-4a42561c3d0c","name":{"pool_name":"oxp_e6d2fe1d-c74d-40cd-8fae-bc7d06bdaac8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::a]:32345"},"services":[{"id":"d4e1e554-7b98-4413-809e-4a42561c3d0c","details":{"type":"crucible","address":"[fd00:1122:3344:10b::a]:32345"}}]},"root":"/pool/ext/6b9ec5f1-859f-459c-9c06-6a51ba87786f/crypt/zone"},{"zone":{"id":"1dd69b02-a032-46c3-8e2a-5012e8314455","zone_type":"crucible","addresses":["fd00:1122:3344:10b::b"],"dataset":{"id":"1dd69b02-a032-46c3-8e2a-5012e8314455","name":{"pool_name":"oxp_350b2814-7b7f-40f1-9bf6-9818a1ef49bb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::b]:32345"},"services":[{"id":"1dd69b02-a032-46c3-8e2a-5012e8314455","details":{"type":"crucible","address":"[fd00:1122:3344:10b::b]:32345"}}]},"root":"/pool/ext/350b2814-7b7f-40f1-9bf6-9818a1ef49bb/crypt/zone"},{"zone":{"id":"921f7752-d2f3-40df-a739-5cb1390abc2c","zone_type":"crucible","addresses":["fd00:1122:3344:10b::8"],"dataset":{"id":"921f7752-d2f3-40df-a739-5cb1390abc2c","name":{"pool_name":"oxp_2d1ebe24-6deb-4f81-8450-6842de28126c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::8]:32345"},"services":[{"id":"921f7752-d2f3-40df-a739-5cb1390abc2c","details":{"type":"crucible","address":"[fd00:1122:3344:10b::8]:32345"}}]},"root":"/pool/ext/91ea7bb6-2be7-4498-9b0d-a0521509ec00/crypt/zone"},{"zone":{"id":"609b25e8-9750-4308-ae6f-7202907a3675","zone_type":"crucible","addresses":["fd00:1122:3344:10b::9"],"dataset":{"id":"609b25e8-9750-4308-ae6f-7202907a3675","name":{"pool_name":"oxp_91ea7bb6-2be7-4498-9b0d-a0521509ec00","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::9]:32345"},"services":[{"id":"609b25e8-9750-4308-ae6f-7202907a3675","details":{"type":"crucible","address":"[fd00:1122:3344:10b::9]:32345"}}]},"root":"/pool/ext/2d1ebe24-6deb-4f81-8450-6842de28126c/crypt/zone"},{"zone":{"id":"a232eba2-e94f-4592-a5a6-ec23f9be3296","zone_type":"crucible","addresses":["fd00:1122:3344:10b::5"],"dataset":{"id":"a232eba2-e94f-4592-a5a6-ec23f9be3296","name":{"pool_name":"oxp_e12f29b8-1ab8-431e-bc96-1c1298947980","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::5]:32345"},"services":[{"id":"a232eba2-e94f-4592-a5a6-ec23f9be3296","details":{"type":"crucible","address":"[fd00:1122:3344:10b::5]:32345"}}]},"root":"/pool/ext/021afd19-2f87-4def-9284-ab7add1dd6ae/crypt/zone"},{"zone":{"id":"800d1758-9312-4b1a-8f02-dc6d644c2a9b","zone_type":"crucible","addresses":["fd00:1122:3344:10b::c"],"dataset":{"id":"800d1758-9312-4b1a-8f02-dc6d644c2a9b","name":{"pool_name":"oxp_b6932bb0-bab8-4876-914a-9c75a600e794","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::c]:32345"},"services":[{"id":"800d1758-9312-4b1a-8f02-dc6d644c2a9b","details":{"type":"crucible","address":"[fd00:1122:3344:10b::c]:32345"}}]},"root":"/pool/ext/b6932bb0-bab8-4876-914a-9c75a600e794/crypt/zone"},{"zone":{"id":"668a4d4a-96dc-4b45-866b-bed3d64c26ec","zone_type":"crucible","addresses":["fd00:1122:3344:10b::7"],"dataset":{"id":"668a4d4a-96dc-4b45-866b-bed3d64c26ec","name":{"pool_name":"oxp_021afd19-2f87-4def-9284-ab7add1dd6ae","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::7]:32345"},"services":[{"id":"668a4d4a-96dc-4b45-866b-bed3d64c26ec","details":{"type":"crucible","address":"[fd00:1122:3344:10b::7]:32345"}}]},"root":"/pool/ext/91ea7bb6-2be7-4498-9b0d-a0521509ec00/crypt/zone"},{"zone":{"id":"8bbea076-ff60-4330-8302-383e18140ef3","zone_type":"cockroach_db","addresses":["fd00:1122:3344:10b::3"],"dataset":{"id":"8bbea076-ff60-4330-8302-383e18140ef3","name":{"pool_name":"oxp_e12f29b8-1ab8-431e-bc96-1c1298947980","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:10b::3]:32221"},"services":[{"id":"8bbea076-ff60-4330-8302-383e18140ef3","details":{"type":"cockroach_db","address":"[fd00:1122:3344:10b::3]:32221"}}]},"root":"/pool/ext/4a624324-003a-4255-98e8-546a90b5b7fa/crypt/zone"},{"zone":{"id":"3ccea933-89f2-4ce5-8367-efb0afeffe97","zone_type":"ntp","addresses":["fd00:1122:3344:10b::f"],"dataset":null,"services":[{"id":"3ccea933-89f2-4ce5-8367-efb0afeffe97","details":{"type":"internal_ntp","address":"[fd00:1122:3344:10b::f]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/4a624324-003a-4255-98e8-546a90b5b7fa/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled16.json b/sled-agent/tests/old-service-ledgers/rack2-sled16.json deleted file mode 100644 index c928e004b2..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled16.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"b12aa520-a769-4eac-b56b-09960550a831","zone_type":"crucible","addresses":["fd00:1122:3344:108::7"],"dataset":{"id":"b12aa520-a769-4eac-b56b-09960550a831","name":{"pool_name":"oxp_34dadf3f-f60c-4acc-b82b-4b0c82224222","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::7]:32345"},"services":[{"id":"b12aa520-a769-4eac-b56b-09960550a831","details":{"type":"crucible","address":"[fd00:1122:3344:108::7]:32345"}}]},"root":"/pool/ext/8be8c577-23ac-452e-a205-6d9c95088f61/crypt/zone"},{"zone":{"id":"9bdc40ee-ccba-4d18-9efb-a30596e2d290","zone_type":"crucible","addresses":["fd00:1122:3344:108::d"],"dataset":{"id":"9bdc40ee-ccba-4d18-9efb-a30596e2d290","name":{"pool_name":"oxp_eb81728c-3b83-42fb-8133-ac32a0bdf70f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::d]:32345"},"services":[{"id":"9bdc40ee-ccba-4d18-9efb-a30596e2d290","details":{"type":"crucible","address":"[fd00:1122:3344:108::d]:32345"}}]},"root":"/pool/ext/8be8c577-23ac-452e-a205-6d9c95088f61/crypt/zone"},{"zone":{"id":"c9a367c7-64d7-48e4-b484-9ecb4e8faea7","zone_type":"crucible","addresses":["fd00:1122:3344:108::9"],"dataset":{"id":"c9a367c7-64d7-48e4-b484-9ecb4e8faea7","name":{"pool_name":"oxp_76ab5a67-e20f-4bf0-87b3-01fcc4144bd2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::9]:32345"},"services":[{"id":"c9a367c7-64d7-48e4-b484-9ecb4e8faea7","details":{"type":"crucible","address":"[fd00:1122:3344:108::9]:32345"}}]},"root":"/pool/ext/34dadf3f-f60c-4acc-b82b-4b0c82224222/crypt/zone"},{"zone":{"id":"bc5124d8-65e8-4879-bfac-64d59003d482","zone_type":"crucible","addresses":["fd00:1122:3344:108::a"],"dataset":{"id":"bc5124d8-65e8-4879-bfac-64d59003d482","name":{"pool_name":"oxp_5fac7a1d-e855-46e1-b8c2-dd848ac4fee6","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::a]:32345"},"services":[{"id":"bc5124d8-65e8-4879-bfac-64d59003d482","details":{"type":"crucible","address":"[fd00:1122:3344:108::a]:32345"}}]},"root":"/pool/ext/0c4ef358-5533-43db-ad38-a8eff716e53a/crypt/zone"},{"zone":{"id":"5cc7c840-8e6b-48c8-ac4b-f4297f8cf61a","zone_type":"crucible","addresses":["fd00:1122:3344:108::c"],"dataset":{"id":"5cc7c840-8e6b-48c8-ac4b-f4297f8cf61a","name":{"pool_name":"oxp_0c4ef358-5533-43db-ad38-a8eff716e53a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::c]:32345"},"services":[{"id":"5cc7c840-8e6b-48c8-ac4b-f4297f8cf61a","details":{"type":"crucible","address":"[fd00:1122:3344:108::c]:32345"}}]},"root":"/pool/ext/6d3e9cc6-f03b-4055-9785-05711d5e4fdc/crypt/zone"},{"zone":{"id":"3b767edf-a72d-4d80-a0fc-65d6801ed0e0","zone_type":"crucible","addresses":["fd00:1122:3344:108::e"],"dataset":{"id":"3b767edf-a72d-4d80-a0fc-65d6801ed0e0","name":{"pool_name":"oxp_f522118c-5dcd-4116-8044-07f0cceec52e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::e]:32345"},"services":[{"id":"3b767edf-a72d-4d80-a0fc-65d6801ed0e0","details":{"type":"crucible","address":"[fd00:1122:3344:108::e]:32345"}}]},"root":"/pool/ext/5fac7a1d-e855-46e1-b8c2-dd848ac4fee6/crypt/zone"},{"zone":{"id":"f3c02ed6-fbc5-45c3-a030-409f74b450fd","zone_type":"crucible_pantry","addresses":["fd00:1122:3344:108::4"],"dataset":null,"services":[{"id":"f3c02ed6-fbc5-45c3-a030-409f74b450fd","details":{"type":"crucible_pantry","address":"[fd00:1122:3344:108::4]:17000"}}]},"root":"/pool/ext/eb81728c-3b83-42fb-8133-ac32a0bdf70f/crypt/zone"},{"zone":{"id":"85bd9bdb-1ec5-4a8d-badb-8b5d502546a1","zone_type":"crucible","addresses":["fd00:1122:3344:108::5"],"dataset":{"id":"85bd9bdb-1ec5-4a8d-badb-8b5d502546a1","name":{"pool_name":"oxp_416232c1-bc8f-403f-bacb-28403dd8fced","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::5]:32345"},"services":[{"id":"85bd9bdb-1ec5-4a8d-badb-8b5d502546a1","details":{"type":"crucible","address":"[fd00:1122:3344:108::5]:32345"}}]},"root":"/pool/ext/34dadf3f-f60c-4acc-b82b-4b0c82224222/crypt/zone"},{"zone":{"id":"d2f1c3df-d4e0-4469-b50e-f1871da86ebf","zone_type":"crucible","addresses":["fd00:1122:3344:108::6"],"dataset":{"id":"d2f1c3df-d4e0-4469-b50e-f1871da86ebf","name":{"pool_name":"oxp_6d3e9cc6-f03b-4055-9785-05711d5e4fdc","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::6]:32345"},"services":[{"id":"d2f1c3df-d4e0-4469-b50e-f1871da86ebf","details":{"type":"crucible","address":"[fd00:1122:3344:108::6]:32345"}}]},"root":"/pool/ext/34dadf3f-f60c-4acc-b82b-4b0c82224222/crypt/zone"},{"zone":{"id":"88fe3c12-4c55-47df-b4ee-ed26b795439d","zone_type":"crucible","addresses":["fd00:1122:3344:108::8"],"dataset":{"id":"88fe3c12-4c55-47df-b4ee-ed26b795439d","name":{"pool_name":"oxp_8be8c577-23ac-452e-a205-6d9c95088f61","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::8]:32345"},"services":[{"id":"88fe3c12-4c55-47df-b4ee-ed26b795439d","details":{"type":"crucible","address":"[fd00:1122:3344:108::8]:32345"}}]},"root":"/pool/ext/34dadf3f-f60c-4acc-b82b-4b0c82224222/crypt/zone"},{"zone":{"id":"4d20175a-588b-44b8-8b9c-b16c6c3a97a0","zone_type":"crucible","addresses":["fd00:1122:3344:108::b"],"dataset":{"id":"4d20175a-588b-44b8-8b9c-b16c6c3a97a0","name":{"pool_name":"oxp_a726cacd-fa35-4ed2-ade6-31ad928b24cb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::b]:32345"},"services":[{"id":"4d20175a-588b-44b8-8b9c-b16c6c3a97a0","details":{"type":"crucible","address":"[fd00:1122:3344:108::b]:32345"}}]},"root":"/pool/ext/0c4ef358-5533-43db-ad38-a8eff716e53a/crypt/zone"},{"zone":{"id":"e86845b5-eabd-49f5-9a10-6dfef9066209","zone_type":"cockroach_db","addresses":["fd00:1122:3344:108::3"],"dataset":{"id":"e86845b5-eabd-49f5-9a10-6dfef9066209","name":{"pool_name":"oxp_416232c1-bc8f-403f-bacb-28403dd8fced","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:108::3]:32221"},"services":[{"id":"e86845b5-eabd-49f5-9a10-6dfef9066209","details":{"type":"cockroach_db","address":"[fd00:1122:3344:108::3]:32221"}}]},"root":"/pool/ext/416232c1-bc8f-403f-bacb-28403dd8fced/crypt/zone"},{"zone":{"id":"209b6213-588b-43b6-a89b-19ee5c84ffba","zone_type":"ntp","addresses":["fd00:1122:3344:108::f"],"dataset":null,"services":[{"id":"209b6213-588b-43b6-a89b-19ee5c84ffba","details":{"type":"internal_ntp","address":"[fd00:1122:3344:108::f]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/416232c1-bc8f-403f-bacb-28403dd8fced/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled17.json b/sled-agent/tests/old-service-ledgers/rack2-sled17.json deleted file mode 100644 index 93872adf13..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled17.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"90b53c3d-42fa-4ca9-bbfc-96fff245b508","zone_type":"crucible","addresses":["fd00:1122:3344:109::4"],"dataset":{"id":"90b53c3d-42fa-4ca9-bbfc-96fff245b508","name":{"pool_name":"oxp_ae56280b-17ce-4266-8573-e1da9db6c6bb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::4]:32345"},"services":[{"id":"90b53c3d-42fa-4ca9-bbfc-96fff245b508","details":{"type":"crucible","address":"[fd00:1122:3344:109::4]:32345"}}]},"root":"/pool/ext/b0e1a261-b932-47c4-81e9-1977275ae9d9/crypt/zone"},{"zone":{"id":"4f9f2e1d-be04-4e8b-a50b-ffb18557a650","zone_type":"crucible","addresses":["fd00:1122:3344:109::5"],"dataset":{"id":"4f9f2e1d-be04-4e8b-a50b-ffb18557a650","name":{"pool_name":"oxp_d5b07362-64db-4b18-a3e9-8d7cbabae2d5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::5]:32345"},"services":[{"id":"4f9f2e1d-be04-4e8b-a50b-ffb18557a650","details":{"type":"crucible","address":"[fd00:1122:3344:109::5]:32345"}}]},"root":"/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone"},{"zone":{"id":"2fa5671d-3109-4f11-ae70-1280f4fa3b89","zone_type":"crucible","addresses":["fd00:1122:3344:109::6"],"dataset":{"id":"2fa5671d-3109-4f11-ae70-1280f4fa3b89","name":{"pool_name":"oxp_9ba7bfbf-b9a2-4237-a142-94c1e68de984","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::6]:32345"},"services":[{"id":"2fa5671d-3109-4f11-ae70-1280f4fa3b89","details":{"type":"crucible","address":"[fd00:1122:3344:109::6]:32345"}}]},"root":"/pool/ext/3cafbb47-c194-4a42-99ff-34dfeab999ed/crypt/zone"},{"zone":{"id":"b63c6882-ca90-4156-b561-4781ab4a0962","zone_type":"crucible","addresses":["fd00:1122:3344:109::7"],"dataset":{"id":"b63c6882-ca90-4156-b561-4781ab4a0962","name":{"pool_name":"oxp_b0e1a261-b932-47c4-81e9-1977275ae9d9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::7]:32345"},"services":[{"id":"b63c6882-ca90-4156-b561-4781ab4a0962","details":{"type":"crucible","address":"[fd00:1122:3344:109::7]:32345"}}]},"root":"/pool/ext/d5b07362-64db-4b18-a3e9-8d7cbabae2d5/crypt/zone"},{"zone":{"id":"f71344eb-f7e2-439d-82a0-9941e6868fb6","zone_type":"crucible","addresses":["fd00:1122:3344:109::9"],"dataset":{"id":"f71344eb-f7e2-439d-82a0-9941e6868fb6","name":{"pool_name":"oxp_027a82e8-daa3-4fa6-8205-ed03445e1086","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::9]:32345"},"services":[{"id":"f71344eb-f7e2-439d-82a0-9941e6868fb6","details":{"type":"crucible","address":"[fd00:1122:3344:109::9]:32345"}}]},"root":"/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone"},{"zone":{"id":"a60cf0d7-12d5-43cb-aa3f-7a9e84de08fb","zone_type":"crucible","addresses":["fd00:1122:3344:109::a"],"dataset":{"id":"a60cf0d7-12d5-43cb-aa3f-7a9e84de08fb","name":{"pool_name":"oxp_8736aaf9-4d72-42b1-8e4f-07644d999c8b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::a]:32345"},"services":[{"id":"a60cf0d7-12d5-43cb-aa3f-7a9e84de08fb","details":{"type":"crucible","address":"[fd00:1122:3344:109::a]:32345"}}]},"root":"/pool/ext/8736aaf9-4d72-42b1-8e4f-07644d999c8b/crypt/zone"},{"zone":{"id":"5d0e03b2-8958-4c43-8851-bf819f102958","zone_type":"crucible","addresses":["fd00:1122:3344:109::8"],"dataset":{"id":"5d0e03b2-8958-4c43-8851-bf819f102958","name":{"pool_name":"oxp_62426615-7832-49e7-9426-e39ffeb42c69","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::8]:32345"},"services":[{"id":"5d0e03b2-8958-4c43-8851-bf819f102958","details":{"type":"crucible","address":"[fd00:1122:3344:109::8]:32345"}}]},"root":"/pool/ext/07fc8ec9-1216-4d98-be34-c2970b585e61/crypt/zone"},{"zone":{"id":"accc05a2-ec80-4856-a825-ec6b7f700eaa","zone_type":"crucible","addresses":["fd00:1122:3344:109::d"],"dataset":{"id":"accc05a2-ec80-4856-a825-ec6b7f700eaa","name":{"pool_name":"oxp_dc083c53-7014-4482-8a79-f338ba2b0fb4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::d]:32345"},"services":[{"id":"accc05a2-ec80-4856-a825-ec6b7f700eaa","details":{"type":"crucible","address":"[fd00:1122:3344:109::d]:32345"}}]},"root":"/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone"},{"zone":{"id":"2e32fdcc-737a-4430-8290-cb7028ea4d50","zone_type":"crucible","addresses":["fd00:1122:3344:109::b"],"dataset":{"id":"2e32fdcc-737a-4430-8290-cb7028ea4d50","name":{"pool_name":"oxp_3cafbb47-c194-4a42-99ff-34dfeab999ed","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::b]:32345"},"services":[{"id":"2e32fdcc-737a-4430-8290-cb7028ea4d50","details":{"type":"crucible","address":"[fd00:1122:3344:109::b]:32345"}}]},"root":"/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone"},{"zone":{"id":"a97c6ae2-37f6-4d93-a66e-cb5cd3c6aaa2","zone_type":"crucible","addresses":["fd00:1122:3344:109::c"],"dataset":{"id":"a97c6ae2-37f6-4d93-a66e-cb5cd3c6aaa2","name":{"pool_name":"oxp_07fc8ec9-1216-4d98-be34-c2970b585e61","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::c]:32345"},"services":[{"id":"a97c6ae2-37f6-4d93-a66e-cb5cd3c6aaa2","details":{"type":"crucible","address":"[fd00:1122:3344:109::c]:32345"}}]},"root":"/pool/ext/07fc8ec9-1216-4d98-be34-c2970b585e61/crypt/zone"},{"zone":{"id":"3237a532-acaa-4ebe-bf11-dde794fea739","zone_type":"cockroach_db","addresses":["fd00:1122:3344:109::3"],"dataset":{"id":"3237a532-acaa-4ebe-bf11-dde794fea739","name":{"pool_name":"oxp_ae56280b-17ce-4266-8573-e1da9db6c6bb","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:109::3]:32221"},"services":[{"id":"3237a532-acaa-4ebe-bf11-dde794fea739","details":{"type":"cockroach_db","address":"[fd00:1122:3344:109::3]:32221"}}]},"root":"/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone"},{"zone":{"id":"83257100-5590-484a-b72a-a079389d8da6","zone_type":"ntp","addresses":["fd00:1122:3344:109::e"],"dataset":null,"services":[{"id":"83257100-5590-484a-b72a-a079389d8da6","details":{"type":"internal_ntp","address":"[fd00:1122:3344:109::e]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/3cafbb47-c194-4a42-99ff-34dfeab999ed/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled21.json b/sled-agent/tests/old-service-ledgers/rack2-sled21.json deleted file mode 100644 index 78e003f79e..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled21.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":5,"requests":[{"zone":{"id":"0437b69d-73a8-4231-86f9-6b5556e7e7ef","zone_type":"crucible","addresses":["fd00:1122:3344:102::5"],"dataset":{"id":"0437b69d-73a8-4231-86f9-6b5556e7e7ef","name":{"pool_name":"oxp_aa0ffe35-76db-42ab-adf2-ceb072bdf811","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::5]:32345"},"services":[{"id":"0437b69d-73a8-4231-86f9-6b5556e7e7ef","details":{"type":"crucible","address":"[fd00:1122:3344:102::5]:32345"}}]},"root":"/pool/ext/0d2805da-6d24-4e57-a700-0c3865c05544/crypt/zone"},{"zone":{"id":"47234ca5-305f-436a-9e9a-36bca9667680","zone_type":"crucible","addresses":["fd00:1122:3344:102::b"],"dataset":{"id":"47234ca5-305f-436a-9e9a-36bca9667680","name":{"pool_name":"oxp_0d2805da-6d24-4e57-a700-0c3865c05544","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::b]:32345"},"services":[{"id":"47234ca5-305f-436a-9e9a-36bca9667680","details":{"type":"crucible","address":"[fd00:1122:3344:102::b]:32345"}}]},"root":"/pool/ext/160691d8-33a1-4d7d-a48a-c3fd27d76822/crypt/zone"},{"zone":{"id":"2898657e-4141-4c05-851b-147bffc6bbbd","zone_type":"nexus","addresses":["fd00:1122:3344:102::3"],"dataset":null,"services":[{"id":"2898657e-4141-4c05-851b-147bffc6bbbd","details":{"type":"nexus","internal_address":"[fd00:1122:3344:102::3]:12221","external_ip":"172.20.26.5","nic":{"id":"2e9a412e-c79a-48fe-8fa4-f5a6afed1040","kind":{"type":"service","id":"2898657e-4141-4c05-851b-147bffc6bbbd"},"name":"nexus-2898657e-4141-4c05-851b-147bffc6bbbd","ip":"172.30.2.7","mac":"A8:40:25:FF:C6:59","subnet":"172.30.2.0/24","vni":100,"primary":true,"slot":0},"external_tls":true,"external_dns_servers":["1.1.1.1","9.9.9.9"]}}]},"root":"/pool/ext/c0b4ecc1-a145-443f-90d1-2e8136b007bc/crypt/zone"},{"zone":{"id":"cf98c4d6-4a7b-49c0-9b14-48a8adf52ce9","zone_type":"crucible","addresses":["fd00:1122:3344:102::c"],"dataset":{"id":"cf98c4d6-4a7b-49c0-9b14-48a8adf52ce9","name":{"pool_name":"oxp_c0b4ecc1-a145-443f-90d1-2e8136b007bc","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::c]:32345"},"services":[{"id":"cf98c4d6-4a7b-49c0-9b14-48a8adf52ce9","details":{"type":"crucible","address":"[fd00:1122:3344:102::c]:32345"}}]},"root":"/pool/ext/f6acd70a-d6cb-464d-a460-dd5c60301562/crypt/zone"},{"zone":{"id":"13c1e91e-bfcc-4eea-8185-412fc37fdea3","zone_type":"crucible","addresses":["fd00:1122:3344:102::9"],"dataset":{"id":"13c1e91e-bfcc-4eea-8185-412fc37fdea3","name":{"pool_name":"oxp_e9b0a2e4-8060-41bd-a3b5-d0642246d06d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::9]:32345"},"services":[{"id":"13c1e91e-bfcc-4eea-8185-412fc37fdea3","details":{"type":"crucible","address":"[fd00:1122:3344:102::9]:32345"}}]},"root":"/pool/ext/c0b4ecc1-a145-443f-90d1-2e8136b007bc/crypt/zone"},{"zone":{"id":"c9cb60af-9e0e-4b3b-b971-53138a9b8d27","zone_type":"crucible","addresses":["fd00:1122:3344:102::4"],"dataset":{"id":"c9cb60af-9e0e-4b3b-b971-53138a9b8d27","name":{"pool_name":"oxp_77749ec7-39a9-489d-904b-87f7223c4e3c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::4]:32345"},"services":[{"id":"c9cb60af-9e0e-4b3b-b971-53138a9b8d27","details":{"type":"crucible","address":"[fd00:1122:3344:102::4]:32345"}}]},"root":"/pool/ext/77749ec7-39a9-489d-904b-87f7223c4e3c/crypt/zone"},{"zone":{"id":"32995cfa-47ec-4b84-8514-7c1c8a86c19d","zone_type":"crucible","addresses":["fd00:1122:3344:102::8"],"dataset":{"id":"32995cfa-47ec-4b84-8514-7c1c8a86c19d","name":{"pool_name":"oxp_eac83f81-eb51-4f3e-874e-82f55dd952ba","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::8]:32345"},"services":[{"id":"32995cfa-47ec-4b84-8514-7c1c8a86c19d","details":{"type":"crucible","address":"[fd00:1122:3344:102::8]:32345"}}]},"root":"/pool/ext/0d2805da-6d24-4e57-a700-0c3865c05544/crypt/zone"},{"zone":{"id":"b93d2e2d-d54b-4503-85c3-9878e3cee9c7","zone_type":"crucible","addresses":["fd00:1122:3344:102::a"],"dataset":{"id":"b93d2e2d-d54b-4503-85c3-9878e3cee9c7","name":{"pool_name":"oxp_160691d8-33a1-4d7d-a48a-c3fd27d76822","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::a]:32345"},"services":[{"id":"b93d2e2d-d54b-4503-85c3-9878e3cee9c7","details":{"type":"crucible","address":"[fd00:1122:3344:102::a]:32345"}}]},"root":"/pool/ext/138663ad-a382-4595-baf0-08f6b0276a67/crypt/zone"},{"zone":{"id":"2ebbac4f-7b0f-43eb-99fd-dd6ff7f9e097","zone_type":"crucible","addresses":["fd00:1122:3344:102::6"],"dataset":{"id":"2ebbac4f-7b0f-43eb-99fd-dd6ff7f9e097","name":{"pool_name":"oxp_138663ad-a382-4595-baf0-08f6b0276a67","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::6]:32345"},"services":[{"id":"2ebbac4f-7b0f-43eb-99fd-dd6ff7f9e097","details":{"type":"crucible","address":"[fd00:1122:3344:102::6]:32345"}}]},"root":"/pool/ext/e9b0a2e4-8060-41bd-a3b5-d0642246d06d/crypt/zone"},{"zone":{"id":"d0eea3b2-e5ac-42bf-97b7-531b78fa06d1","zone_type":"crucible","addresses":["fd00:1122:3344:102::7"],"dataset":{"id":"d0eea3b2-e5ac-42bf-97b7-531b78fa06d1","name":{"pool_name":"oxp_69f0b863-f73f-42b2-9822-b2cb99f09003","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::7]:32345"},"services":[{"id":"d0eea3b2-e5ac-42bf-97b7-531b78fa06d1","details":{"type":"crucible","address":"[fd00:1122:3344:102::7]:32345"}}]},"root":"/pool/ext/138663ad-a382-4595-baf0-08f6b0276a67/crypt/zone"},{"zone":{"id":"2b34cd1d-ea7d-41a1-82b9-75550fdf6eb0","zone_type":"crucible","addresses":["fd00:1122:3344:102::d"],"dataset":{"id":"2b34cd1d-ea7d-41a1-82b9-75550fdf6eb0","name":{"pool_name":"oxp_f6acd70a-d6cb-464d-a460-dd5c60301562","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::d]:32345"},"services":[{"id":"2b34cd1d-ea7d-41a1-82b9-75550fdf6eb0","details":{"type":"crucible","address":"[fd00:1122:3344:102::d]:32345"}}]},"root":"/pool/ext/c0b4ecc1-a145-443f-90d1-2e8136b007bc/crypt/zone"},{"zone":{"id":"6ea2684c-115e-48a6-8453-ab52d1cecd73","zone_type":"ntp","addresses":["fd00:1122:3344:102::e"],"dataset":null,"services":[{"id":"6ea2684c-115e-48a6-8453-ab52d1cecd73","details":{"type":"boundary_ntp","address":"[fd00:1122:3344:102::e]:123","ntp_servers":["ntp.eng.oxide.computer"],"dns_servers":["1.1.1.1","9.9.9.9"],"domain":null,"nic":{"id":"4effd079-ed4e-4cf6-8545-bb9574f516d2","kind":{"type":"service","id":"6ea2684c-115e-48a6-8453-ab52d1cecd73"},"name":"ntp-6ea2684c-115e-48a6-8453-ab52d1cecd73","ip":"172.30.3.6","mac":"A8:40:25:FF:A0:F9","subnet":"172.30.3.0/24","vni":100,"primary":true,"slot":0},"snat_cfg":{"ip":"172.20.26.7","first_port":16384,"last_port":32767}}}]},"root":"/pool/ext/aa0ffe35-76db-42ab-adf2-ceb072bdf811/crypt/zone"},{"zone":{"id":"3a1ea15f-06a4-4afd-959a-c3a00b2bdd80","zone_type":"internal_dns","addresses":["fd00:1122:3344:2::1"],"dataset":{"id":"3a1ea15f-06a4-4afd-959a-c3a00b2bdd80","name":{"pool_name":"oxp_77749ec7-39a9-489d-904b-87f7223c4e3c","kind":{"type":"internal_dns"}},"service_address":"[fd00:1122:3344:2::1]:5353"},"services":[{"id":"3a1ea15f-06a4-4afd-959a-c3a00b2bdd80","details":{"type":"internal_dns","http_address":"[fd00:1122:3344:2::1]:5353","dns_address":"[fd00:1122:3344:2::1]:53","gz_address":"fd00:1122:3344:2::2","gz_address_index":1}}]},"root":"/pool/ext/69f0b863-f73f-42b2-9822-b2cb99f09003/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled23.json b/sled-agent/tests/old-service-ledgers/rack2-sled23.json deleted file mode 100644 index 29b8c455d3..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled23.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":5,"requests":[{"zone":{"id":"1876cdcf-b2e7-4b79-ad2e-67df716e1860","zone_type":"crucible","addresses":["fd00:1122:3344:10a::8"],"dataset":{"id":"1876cdcf-b2e7-4b79-ad2e-67df716e1860","name":{"pool_name":"oxp_d4c6bdc6-5e99-4f6c-b57a-9bfcb9a76be4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::8]:32345"},"services":[{"id":"1876cdcf-b2e7-4b79-ad2e-67df716e1860","details":{"type":"crucible","address":"[fd00:1122:3344:10a::8]:32345"}}]},"root":"/pool/ext/86c58ea3-1413-4af3-9aff-9c0a3d758459/crypt/zone"},{"zone":{"id":"0e708ee3-b7a6-4993-a88a-4489add33e29","zone_type":"crucible","addresses":["fd00:1122:3344:10a::d"],"dataset":{"id":"0e708ee3-b7a6-4993-a88a-4489add33e29","name":{"pool_name":"oxp_718ad834-b415-4abb-934d-9f987cde0a96","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::d]:32345"},"services":[{"id":"0e708ee3-b7a6-4993-a88a-4489add33e29","details":{"type":"crucible","address":"[fd00:1122:3344:10a::d]:32345"}}]},"root":"/pool/ext/30f7d236-c835-46cc-bc27-9099a6826f67/crypt/zone"},{"zone":{"id":"4e1b9a65-848f-4649-b360-1df0d135b44d","zone_type":"crucible","addresses":["fd00:1122:3344:10a::c"],"dataset":{"id":"4e1b9a65-848f-4649-b360-1df0d135b44d","name":{"pool_name":"oxp_88ee08c6-1c0f-44c2-9110-b8d5a7589ebb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::c]:32345"},"services":[{"id":"4e1b9a65-848f-4649-b360-1df0d135b44d","details":{"type":"crucible","address":"[fd00:1122:3344:10a::c]:32345"}}]},"root":"/pool/ext/30f7d236-c835-46cc-bc27-9099a6826f67/crypt/zone"},{"zone":{"id":"da510a57-3af1-4d2b-b2ed-2e8849f27d8b","zone_type":"oximeter","addresses":["fd00:1122:3344:10a::3"],"dataset":null,"services":[{"id":"da510a57-3af1-4d2b-b2ed-2e8849f27d8b","details":{"type":"oximeter","address":"[fd00:1122:3344:10a::3]:12223"}}]},"root":"/pool/ext/718ad834-b415-4abb-934d-9f987cde0a96/crypt/zone"},{"zone":{"id":"d4d9acc8-3e0b-4fab-a0a2-d21920fabd7e","zone_type":"crucible","addresses":["fd00:1122:3344:10a::6"],"dataset":{"id":"d4d9acc8-3e0b-4fab-a0a2-d21920fabd7e","name":{"pool_name":"oxp_9dfe424f-cba6-4bfb-a3dd-e8bd7fdea57d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::6]:32345"},"services":[{"id":"d4d9acc8-3e0b-4fab-a0a2-d21920fabd7e","details":{"type":"crucible","address":"[fd00:1122:3344:10a::6]:32345"}}]},"root":"/pool/ext/30f7d236-c835-46cc-bc27-9099a6826f67/crypt/zone"},{"zone":{"id":"fcb75972-836b-4f55-ba21-9722832cf5c2","zone_type":"crucible","addresses":["fd00:1122:3344:10a::7"],"dataset":{"id":"fcb75972-836b-4f55-ba21-9722832cf5c2","name":{"pool_name":"oxp_9005671f-3d90-4ed1-be15-ad65b9a65bd5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::7]:32345"},"services":[{"id":"fcb75972-836b-4f55-ba21-9722832cf5c2","details":{"type":"crucible","address":"[fd00:1122:3344:10a::7]:32345"}}]},"root":"/pool/ext/d4c6bdc6-5e99-4f6c-b57a-9bfcb9a76be4/crypt/zone"},{"zone":{"id":"624beba0-7dcd-4d55-af05-4670c6fcb1fb","zone_type":"crucible","addresses":["fd00:1122:3344:10a::4"],"dataset":{"id":"624beba0-7dcd-4d55-af05-4670c6fcb1fb","name":{"pool_name":"oxp_93867156-a43d-4c03-a899-1535e566c8bd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::4]:32345"},"services":[{"id":"624beba0-7dcd-4d55-af05-4670c6fcb1fb","details":{"type":"crucible","address":"[fd00:1122:3344:10a::4]:32345"}}]},"root":"/pool/ext/93867156-a43d-4c03-a899-1535e566c8bd/crypt/zone"},{"zone":{"id":"26fb3830-898e-4086-afaf-8f9654716b8c","zone_type":"crucible","addresses":["fd00:1122:3344:10a::b"],"dataset":{"id":"26fb3830-898e-4086-afaf-8f9654716b8c","name":{"pool_name":"oxp_86c58ea3-1413-4af3-9aff-9c0a3d758459","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::b]:32345"},"services":[{"id":"26fb3830-898e-4086-afaf-8f9654716b8c","details":{"type":"crucible","address":"[fd00:1122:3344:10a::b]:32345"}}]},"root":"/pool/ext/93867156-a43d-4c03-a899-1535e566c8bd/crypt/zone"},{"zone":{"id":"a3ef7eba-c08e-48ef-ae7a-89e2fcb49b66","zone_type":"crucible","addresses":["fd00:1122:3344:10a::a"],"dataset":{"id":"a3ef7eba-c08e-48ef-ae7a-89e2fcb49b66","name":{"pool_name":"oxp_cd3fdbae-a9d9-4db7-866a-bca36f6dd634","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::a]:32345"},"services":[{"id":"a3ef7eba-c08e-48ef-ae7a-89e2fcb49b66","details":{"type":"crucible","address":"[fd00:1122:3344:10a::a]:32345"}}]},"root":"/pool/ext/718ad834-b415-4abb-934d-9f987cde0a96/crypt/zone"},{"zone":{"id":"5c1d4a02-f33b-433a-81f5-5c149e3433bd","zone_type":"crucible","addresses":["fd00:1122:3344:10a::5"],"dataset":{"id":"5c1d4a02-f33b-433a-81f5-5c149e3433bd","name":{"pool_name":"oxp_9adfc865-2eef-4880-a6e3-9d2f88c8efd0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::5]:32345"},"services":[{"id":"5c1d4a02-f33b-433a-81f5-5c149e3433bd","details":{"type":"crucible","address":"[fd00:1122:3344:10a::5]:32345"}}]},"root":"/pool/ext/cd3fdbae-a9d9-4db7-866a-bca36f6dd634/crypt/zone"},{"zone":{"id":"ee77efe9-81d0-4395-a237-15e30c2c2d04","zone_type":"crucible","addresses":["fd00:1122:3344:10a::9"],"dataset":{"id":"ee77efe9-81d0-4395-a237-15e30c2c2d04","name":{"pool_name":"oxp_30f7d236-c835-46cc-bc27-9099a6826f67","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::9]:32345"},"services":[{"id":"ee77efe9-81d0-4395-a237-15e30c2c2d04","details":{"type":"crucible","address":"[fd00:1122:3344:10a::9]:32345"}}]},"root":"/pool/ext/88ee08c6-1c0f-44c2-9110-b8d5a7589ebb/crypt/zone"},{"zone":{"id":"71ab91b7-48d4-4d31-b47e-59f29f419116","zone_type":"ntp","addresses":["fd00:1122:3344:10a::e"],"dataset":null,"services":[{"id":"71ab91b7-48d4-4d31-b47e-59f29f419116","details":{"type":"internal_ntp","address":"[fd00:1122:3344:10a::e]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/cd3fdbae-a9d9-4db7-866a-bca36f6dd634/crypt/zone"},{"zone":{"id":"46ccd8fe-4e3c-4307-97ae-1f7ac505082a","zone_type":"internal_dns","addresses":["fd00:1122:3344:3::1"],"dataset":{"id":"46ccd8fe-4e3c-4307-97ae-1f7ac505082a","name":{"pool_name":"oxp_93867156-a43d-4c03-a899-1535e566c8bd","kind":{"type":"internal_dns"}},"service_address":"[fd00:1122:3344:3::1]:5353"},"services":[{"id":"46ccd8fe-4e3c-4307-97ae-1f7ac505082a","details":{"type":"internal_dns","http_address":"[fd00:1122:3344:3::1]:5353","dns_address":"[fd00:1122:3344:3::1]:53","gz_address":"fd00:1122:3344:3::2","gz_address_index":2}}]},"root":"/pool/ext/9dfe424f-cba6-4bfb-a3dd-e8bd7fdea57d/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled25.json b/sled-agent/tests/old-service-ledgers/rack2-sled25.json deleted file mode 100644 index e48ef68faa..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled25.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"180d466d-eb36-4546-8922-e52c4c076823","zone_type":"crucible","addresses":["fd00:1122:3344:101::5"],"dataset":{"id":"180d466d-eb36-4546-8922-e52c4c076823","name":{"pool_name":"oxp_ac789935-fa42-4d00-8967-df0d96dbb74e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::5]:32345"},"services":[{"id":"180d466d-eb36-4546-8922-e52c4c076823","details":{"type":"crucible","address":"[fd00:1122:3344:101::5]:32345"}}]},"root":"/pool/ext/d732addc-cfe8-4c2c-8028-72eb4481b04e/crypt/zone"},{"zone":{"id":"b5af0303-bc03-40a3-b733-0396d705dfbf","zone_type":"crucible","addresses":["fd00:1122:3344:101::7"],"dataset":{"id":"b5af0303-bc03-40a3-b733-0396d705dfbf","name":{"pool_name":"oxp_d732addc-cfe8-4c2c-8028-72eb4481b04e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::7]:32345"},"services":[{"id":"b5af0303-bc03-40a3-b733-0396d705dfbf","details":{"type":"crucible","address":"[fd00:1122:3344:101::7]:32345"}}]},"root":"/pool/ext/677b0057-3a80-461b-aca8-c2cb501a7278/crypt/zone"},{"zone":{"id":"9c7c805a-f5ed-4e48-86e3-7aa81a718881","zone_type":"crucible","addresses":["fd00:1122:3344:101::c"],"dataset":{"id":"9c7c805a-f5ed-4e48-86e3-7aa81a718881","name":{"pool_name":"oxp_923c930c-80f8-448d-8321-cebfc6c41760","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::c]:32345"},"services":[{"id":"9c7c805a-f5ed-4e48-86e3-7aa81a718881","details":{"type":"crucible","address":"[fd00:1122:3344:101::c]:32345"}}]},"root":"/pool/ext/ac789935-fa42-4d00-8967-df0d96dbb74e/crypt/zone"},{"zone":{"id":"4e49c83c-2d4a-491a-91ac-4ab022026dcf","zone_type":"crucible","addresses":["fd00:1122:3344:101::4"],"dataset":{"id":"4e49c83c-2d4a-491a-91ac-4ab022026dcf","name":{"pool_name":"oxp_c99e6032-1d4f-47d2-9efe-ae2b2479554e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::4]:32345"},"services":[{"id":"4e49c83c-2d4a-491a-91ac-4ab022026dcf","details":{"type":"crucible","address":"[fd00:1122:3344:101::4]:32345"}}]},"root":"/pool/ext/653065d2-ab70-47c9-b832-34238fdc95ef/crypt/zone"},{"zone":{"id":"0e38475e-b8b2-4813-bf80-3c170081081a","zone_type":"crucible","addresses":["fd00:1122:3344:101::d"],"dataset":{"id":"0e38475e-b8b2-4813-bf80-3c170081081a","name":{"pool_name":"oxp_653065d2-ab70-47c9-b832-34238fdc95ef","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::d]:32345"},"services":[{"id":"0e38475e-b8b2-4813-bf80-3c170081081a","details":{"type":"crucible","address":"[fd00:1122:3344:101::d]:32345"}}]},"root":"/pool/ext/4c7ad252-55c2-4a1a-9d93-9dfcdfdfacca/crypt/zone"},{"zone":{"id":"75123e60-1116-4b8d-a466-7302220127da","zone_type":"crucible","addresses":["fd00:1122:3344:101::8"],"dataset":{"id":"75123e60-1116-4b8d-a466-7302220127da","name":{"pool_name":"oxp_c764a8ae-6862-4eec-9db0-cc6ea478e4a7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::8]:32345"},"services":[{"id":"75123e60-1116-4b8d-a466-7302220127da","details":{"type":"crucible","address":"[fd00:1122:3344:101::8]:32345"}}]},"root":"/pool/ext/c764a8ae-6862-4eec-9db0-cc6ea478e4a7/crypt/zone"},{"zone":{"id":"fbd0379c-97fa-49ea-8980-17ae30ffff3c","zone_type":"crucible","addresses":["fd00:1122:3344:101::b"],"dataset":{"id":"fbd0379c-97fa-49ea-8980-17ae30ffff3c","name":{"pool_name":"oxp_fcb0e4c7-e046-4cf5-ad35-3ad90e1eb90c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::b]:32345"},"services":[{"id":"fbd0379c-97fa-49ea-8980-17ae30ffff3c","details":{"type":"crucible","address":"[fd00:1122:3344:101::b]:32345"}}]},"root":"/pool/ext/4c7ad252-55c2-4a1a-9d93-9dfcdfdfacca/crypt/zone"},{"zone":{"id":"ec635326-cd1d-4f73-b8e6-c3a36a7020db","zone_type":"crucible","addresses":["fd00:1122:3344:101::a"],"dataset":{"id":"ec635326-cd1d-4f73-b8e6-c3a36a7020db","name":{"pool_name":"oxp_6bfb4120-488d-4f3d-90ef-e9bfa523b388","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::a]:32345"},"services":[{"id":"ec635326-cd1d-4f73-b8e6-c3a36a7020db","details":{"type":"crucible","address":"[fd00:1122:3344:101::a]:32345"}}]},"root":"/pool/ext/c99e6032-1d4f-47d2-9efe-ae2b2479554e/crypt/zone"},{"zone":{"id":"f500d564-c40a-4eca-ac8a-a26b435f2037","zone_type":"external_dns","addresses":["fd00:1122:3344:101::3"],"dataset":{"id":"f500d564-c40a-4eca-ac8a-a26b435f2037","name":{"pool_name":"oxp_c99e6032-1d4f-47d2-9efe-ae2b2479554e","kind":{"type":"external_dns"}},"service_address":"[fd00:1122:3344:101::3]:5353"},"services":[{"id":"f500d564-c40a-4eca-ac8a-a26b435f2037","details":{"type":"external_dns","http_address":"[fd00:1122:3344:101::3]:5353","dns_address":"172.20.26.2:53","nic":{"id":"b0b42776-3914-4a69-889f-4831dc72327c","kind":{"type":"service","id":"f500d564-c40a-4eca-ac8a-a26b435f2037"},"name":"external-dns-f500d564-c40a-4eca-ac8a-a26b435f2037","ip":"172.30.1.6","mac":"A8:40:25:FF:D0:B4","subnet":"172.30.1.0/24","vni":100,"primary":true,"slot":0}}}]},"root":"/pool/ext/ac789935-fa42-4d00-8967-df0d96dbb74e/crypt/zone"},{"zone":{"id":"56d4dbcc-3b4a-4ed0-8795-7734aadcc4c0","zone_type":"crucible","addresses":["fd00:1122:3344:101::9"],"dataset":{"id":"56d4dbcc-3b4a-4ed0-8795-7734aadcc4c0","name":{"pool_name":"oxp_4c7ad252-55c2-4a1a-9d93-9dfcdfdfacca","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::9]:32345"},"services":[{"id":"56d4dbcc-3b4a-4ed0-8795-7734aadcc4c0","details":{"type":"crucible","address":"[fd00:1122:3344:101::9]:32345"}}]},"root":"/pool/ext/4c7ad252-55c2-4a1a-9d93-9dfcdfdfacca/crypt/zone"},{"zone":{"id":"0d3a1bd5-f6fe-49cb-807a-190dabc90103","zone_type":"crucible","addresses":["fd00:1122:3344:101::6"],"dataset":{"id":"0d3a1bd5-f6fe-49cb-807a-190dabc90103","name":{"pool_name":"oxp_677b0057-3a80-461b-aca8-c2cb501a7278","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::6]:32345"},"services":[{"id":"0d3a1bd5-f6fe-49cb-807a-190dabc90103","details":{"type":"crucible","address":"[fd00:1122:3344:101::6]:32345"}}]},"root":"/pool/ext/6bfb4120-488d-4f3d-90ef-e9bfa523b388/crypt/zone"},{"zone":{"id":"d34c7184-5d4e-4cb5-8f91-df74a343ffbc","zone_type":"ntp","addresses":["fd00:1122:3344:101::e"],"dataset":null,"services":[{"id":"d34c7184-5d4e-4cb5-8f91-df74a343ffbc","details":{"type":"internal_ntp","address":"[fd00:1122:3344:101::e]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/ac789935-fa42-4d00-8967-df0d96dbb74e/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled8.json b/sled-agent/tests/old-service-ledgers/rack2-sled8.json deleted file mode 100644 index 7d52980d9f..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled8.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"7153983f-8fd7-4fb9-92ac-0f07a07798b4","zone_type":"crucible","addresses":["fd00:1122:3344:103::a"],"dataset":{"id":"7153983f-8fd7-4fb9-92ac-0f07a07798b4","name":{"pool_name":"oxp_bf428719-1b16-4503-99f4-ad95846d916f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::a]:32345"},"services":[{"id":"7153983f-8fd7-4fb9-92ac-0f07a07798b4","details":{"type":"crucible","address":"[fd00:1122:3344:103::a]:32345"}}]},"root":"/pool/ext/26e698bb-006d-4208-94b9-d1bc279111fa/crypt/zone"},{"zone":{"id":"7d44ba36-4a69-490a-bc40-f6f90a4208d4","zone_type":"crucible","addresses":["fd00:1122:3344:103::c"],"dataset":{"id":"7d44ba36-4a69-490a-bc40-f6f90a4208d4","name":{"pool_name":"oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::c]:32345"},"services":[{"id":"7d44ba36-4a69-490a-bc40-f6f90a4208d4","details":{"type":"crucible","address":"[fd00:1122:3344:103::c]:32345"}}]},"root":"/pool/ext/cf940e15-dbc5-481b-866a-4de4b018898e/crypt/zone"},{"zone":{"id":"65a11c18-7f59-41ac-b9e7-680627f996e7","zone_type":"nexus","addresses":["fd00:1122:3344:103::3"],"dataset":null,"services":[{"id":"65a11c18-7f59-41ac-b9e7-680627f996e7","details":{"type":"nexus","internal_address":"[fd00:1122:3344:103::3]:12221","external_ip":"172.20.26.3","nic":{"id":"a3e13dde-a2bc-4170-ad84-aad8085b6034","kind":{"type":"service","id":"65a11c18-7f59-41ac-b9e7-680627f996e7"},"name":"nexus-65a11c18-7f59-41ac-b9e7-680627f996e7","ip":"172.30.2.5","mac":"A8:40:25:FF:A6:83","subnet":"172.30.2.0/24","vni":100,"primary":true,"slot":0},"external_tls":true,"external_dns_servers":["1.1.1.1","9.9.9.9"]}}]},"root":"/pool/ext/e126ddcc-8bee-46ba-8199-2a74df0ba040/crypt/zone"},{"zone":{"id":"072fdae8-2adf-4fd2-94ce-e9b0663b91e7","zone_type":"crucible","addresses":["fd00:1122:3344:103::b"],"dataset":{"id":"072fdae8-2adf-4fd2-94ce-e9b0663b91e7","name":{"pool_name":"oxp_26e698bb-006d-4208-94b9-d1bc279111fa","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::b]:32345"},"services":[{"id":"072fdae8-2adf-4fd2-94ce-e9b0663b91e7","details":{"type":"crucible","address":"[fd00:1122:3344:103::b]:32345"}}]},"root":"/pool/ext/bf428719-1b16-4503-99f4-ad95846d916f/crypt/zone"},{"zone":{"id":"01f93020-7e7d-4185-93fb-6ca234056c82","zone_type":"crucible","addresses":["fd00:1122:3344:103::5"],"dataset":{"id":"01f93020-7e7d-4185-93fb-6ca234056c82","name":{"pool_name":"oxp_7b24095a-72df-45e3-984f-2b795e052ac7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::5]:32345"},"services":[{"id":"01f93020-7e7d-4185-93fb-6ca234056c82","details":{"type":"crucible","address":"[fd00:1122:3344:103::5]:32345"}}]},"root":"/pool/ext/7b24095a-72df-45e3-984f-2b795e052ac7/crypt/zone"},{"zone":{"id":"e238116d-e5cc-43d4-9c8a-6f138ae8a15d","zone_type":"crucible","addresses":["fd00:1122:3344:103::6"],"dataset":{"id":"e238116d-e5cc-43d4-9c8a-6f138ae8a15d","name":{"pool_name":"oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::6]:32345"},"services":[{"id":"e238116d-e5cc-43d4-9c8a-6f138ae8a15d","details":{"type":"crucible","address":"[fd00:1122:3344:103::6]:32345"}}]},"root":"/pool/ext/7b24095a-72df-45e3-984f-2b795e052ac7/crypt/zone"},{"zone":{"id":"585cd8c5-c41e-4be4-beb8-bfbef9b53856","zone_type":"crucible","addresses":["fd00:1122:3344:103::7"],"dataset":{"id":"585cd8c5-c41e-4be4-beb8-bfbef9b53856","name":{"pool_name":"oxp_6340805e-c5af-418d-8bd1-fc0085667f33","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::7]:32345"},"services":[{"id":"585cd8c5-c41e-4be4-beb8-bfbef9b53856","details":{"type":"crucible","address":"[fd00:1122:3344:103::7]:32345"}}]},"root":"/pool/ext/414e235b-55c3-4dc1-a568-8adf4ea1a052/crypt/zone"},{"zone":{"id":"0b41c560-3b20-42f4-82ad-92f5bb575d6b","zone_type":"crucible","addresses":["fd00:1122:3344:103::9"],"dataset":{"id":"0b41c560-3b20-42f4-82ad-92f5bb575d6b","name":{"pool_name":"oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::9]:32345"},"services":[{"id":"0b41c560-3b20-42f4-82ad-92f5bb575d6b","details":{"type":"crucible","address":"[fd00:1122:3344:103::9]:32345"}}]},"root":"/pool/ext/6340805e-c5af-418d-8bd1-fc0085667f33/crypt/zone"},{"zone":{"id":"0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9","zone_type":"crucible","addresses":["fd00:1122:3344:103::d"],"dataset":{"id":"0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9","name":{"pool_name":"oxp_2115b084-be0f-4fba-941b-33a659798a9e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::d]:32345"},"services":[{"id":"0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9","details":{"type":"crucible","address":"[fd00:1122:3344:103::d]:32345"}}]},"root":"/pool/ext/414e235b-55c3-4dc1-a568-8adf4ea1a052/crypt/zone"},{"zone":{"id":"a6ba8273-0320-4dab-b801-281f041b0c50","zone_type":"crucible","addresses":["fd00:1122:3344:103::4"],"dataset":{"id":"a6ba8273-0320-4dab-b801-281f041b0c50","name":{"pool_name":"oxp_8a199f12-4f5c-483a-8aca-f97856658a35","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::4]:32345"},"services":[{"id":"a6ba8273-0320-4dab-b801-281f041b0c50","details":{"type":"crucible","address":"[fd00:1122:3344:103::4]:32345"}}]},"root":"/pool/ext/b93f880e-c55b-4d6c-9a16-939d84b628fc/crypt/zone"},{"zone":{"id":"b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4","zone_type":"crucible","addresses":["fd00:1122:3344:103::8"],"dataset":{"id":"b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4","name":{"pool_name":"oxp_cf940e15-dbc5-481b-866a-4de4b018898e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::8]:32345"},"services":[{"id":"b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4","details":{"type":"crucible","address":"[fd00:1122:3344:103::8]:32345"}}]},"root":"/pool/ext/cf940e15-dbc5-481b-866a-4de4b018898e/crypt/zone"},{"zone":{"id":"7a85d50e-b524-41c1-a052-118027eb77db","zone_type":"ntp","addresses":["fd00:1122:3344:103::e"],"dataset":null,"services":[{"id":"7a85d50e-b524-41c1-a052-118027eb77db","details":{"type":"internal_ntp","address":"[fd00:1122:3344:103::e]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/b93f880e-c55b-4d6c-9a16-939d84b628fc/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack2-sled9.json b/sled-agent/tests/old-service-ledgers/rack2-sled9.json deleted file mode 100644 index 36af68759b..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack2-sled9.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"912346a2-d7e6-427e-b373-e8dcbe4fcea9","zone_type":"crucible","addresses":["fd00:1122:3344:105::5"],"dataset":{"id":"912346a2-d7e6-427e-b373-e8dcbe4fcea9","name":{"pool_name":"oxp_b358fb1e-f52a-4a63-9aab-170225509b37","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::5]:32345"},"services":[{"id":"912346a2-d7e6-427e-b373-e8dcbe4fcea9","details":{"type":"crucible","address":"[fd00:1122:3344:105::5]:32345"}}]},"root":"/pool/ext/0ae29053-29a2-489e-a1e6-6aec0ecd05f8/crypt/zone"},{"zone":{"id":"3d420dff-c616-4c7d-bab1-0f9c2b5396bf","zone_type":"crucible","addresses":["fd00:1122:3344:105::a"],"dataset":{"id":"3d420dff-c616-4c7d-bab1-0f9c2b5396bf","name":{"pool_name":"oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::a]:32345"},"services":[{"id":"3d420dff-c616-4c7d-bab1-0f9c2b5396bf","details":{"type":"crucible","address":"[fd00:1122:3344:105::a]:32345"}}]},"root":"/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone"},{"zone":{"id":"9c5d88c9-8ff1-4f23-9438-7b81322eaf68","zone_type":"crucible","addresses":["fd00:1122:3344:105::b"],"dataset":{"id":"9c5d88c9-8ff1-4f23-9438-7b81322eaf68","name":{"pool_name":"oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::b]:32345"},"services":[{"id":"9c5d88c9-8ff1-4f23-9438-7b81322eaf68","details":{"type":"crucible","address":"[fd00:1122:3344:105::b]:32345"}}]},"root":"/pool/ext/4358f47f-f21e-4cc8-829e-0c7fc2400a59/crypt/zone"},{"zone":{"id":"f9c1deca-1898-429e-8c93-254c7aa7bae6","zone_type":"crucible","addresses":["fd00:1122:3344:105::8"],"dataset":{"id":"f9c1deca-1898-429e-8c93-254c7aa7bae6","name":{"pool_name":"oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::8]:32345"},"services":[{"id":"f9c1deca-1898-429e-8c93-254c7aa7bae6","details":{"type":"crucible","address":"[fd00:1122:3344:105::8]:32345"}}]},"root":"/pool/ext/f8b11629-ced6-412a-9c3f-d169b99ee996/crypt/zone"},{"zone":{"id":"ce8563f3-4a93-45ff-b727-cbfbee6aa413","zone_type":"crucible","addresses":["fd00:1122:3344:105::9"],"dataset":{"id":"ce8563f3-4a93-45ff-b727-cbfbee6aa413","name":{"pool_name":"oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::9]:32345"},"services":[{"id":"ce8563f3-4a93-45ff-b727-cbfbee6aa413","details":{"type":"crucible","address":"[fd00:1122:3344:105::9]:32345"}}]},"root":"/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone"},{"zone":{"id":"9470ea7d-1920-4b4b-8fca-e7659a1ef733","zone_type":"crucible","addresses":["fd00:1122:3344:105::c"],"dataset":{"id":"9470ea7d-1920-4b4b-8fca-e7659a1ef733","name":{"pool_name":"oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::c]:32345"},"services":[{"id":"9470ea7d-1920-4b4b-8fca-e7659a1ef733","details":{"type":"crucible","address":"[fd00:1122:3344:105::c]:32345"}}]},"root":"/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone"},{"zone":{"id":"375296e5-0a23-466c-b605-4204080f8103","zone_type":"crucible_pantry","addresses":["fd00:1122:3344:105::4"],"dataset":null,"services":[{"id":"375296e5-0a23-466c-b605-4204080f8103","details":{"type":"crucible_pantry","address":"[fd00:1122:3344:105::4]:17000"}}]},"root":"/pool/ext/4eb2e4eb-41d8-496c-9a5a-687d7e004aa4/crypt/zone"},{"zone":{"id":"f9940969-b0e8-4e8c-86c7-4bc49cd15a5f","zone_type":"crucible","addresses":["fd00:1122:3344:105::7"],"dataset":{"id":"f9940969-b0e8-4e8c-86c7-4bc49cd15a5f","name":{"pool_name":"oxp_f8b11629-ced6-412a-9c3f-d169b99ee996","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::7]:32345"},"services":[{"id":"f9940969-b0e8-4e8c-86c7-4bc49cd15a5f","details":{"type":"crucible","address":"[fd00:1122:3344:105::7]:32345"}}]},"root":"/pool/ext/17eff217-f0b1-4353-b133-0f68bbd5ceaa/crypt/zone"},{"zone":{"id":"23dca27d-c79b-4930-a817-392e8aeaa4c1","zone_type":"crucible","addresses":["fd00:1122:3344:105::e"],"dataset":{"id":"23dca27d-c79b-4930-a817-392e8aeaa4c1","name":{"pool_name":"oxp_57650e05-36ff-4de8-865f-b9562bdb67f5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::e]:32345"},"services":[{"id":"23dca27d-c79b-4930-a817-392e8aeaa4c1","details":{"type":"crucible","address":"[fd00:1122:3344:105::e]:32345"}}]},"root":"/pool/ext/0ae29053-29a2-489e-a1e6-6aec0ecd05f8/crypt/zone"},{"zone":{"id":"92d3e4e9-0768-4772-83c1-23cce52190e9","zone_type":"crucible","addresses":["fd00:1122:3344:105::6"],"dataset":{"id":"92d3e4e9-0768-4772-83c1-23cce52190e9","name":{"pool_name":"oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::6]:32345"},"services":[{"id":"92d3e4e9-0768-4772-83c1-23cce52190e9","details":{"type":"crucible","address":"[fd00:1122:3344:105::6]:32345"}}]},"root":"/pool/ext/b358fb1e-f52a-4a63-9aab-170225509b37/crypt/zone"},{"zone":{"id":"b3e9fee2-24d2-44e7-8539-a6918e85cf2b","zone_type":"crucible","addresses":["fd00:1122:3344:105::d"],"dataset":{"id":"b3e9fee2-24d2-44e7-8539-a6918e85cf2b","name":{"pool_name":"oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::d]:32345"},"services":[{"id":"b3e9fee2-24d2-44e7-8539-a6918e85cf2b","details":{"type":"crucible","address":"[fd00:1122:3344:105::d]:32345"}}]},"root":"/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone"},{"zone":{"id":"4c3ef132-ec83-4b1b-9574-7c7d3035f9e9","zone_type":"cockroach_db","addresses":["fd00:1122:3344:105::3"],"dataset":{"id":"4c3ef132-ec83-4b1b-9574-7c7d3035f9e9","name":{"pool_name":"oxp_b358fb1e-f52a-4a63-9aab-170225509b37","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:105::3]:32221"},"services":[{"id":"4c3ef132-ec83-4b1b-9574-7c7d3035f9e9","details":{"type":"cockroach_db","address":"[fd00:1122:3344:105::3]:32221"}}]},"root":"/pool/ext/d1cb6b7d-2b92-4b7d-8a4d-551987f0277e/crypt/zone"},{"zone":{"id":"76b79b96-eaa2-4341-9aba-e77cfc92e0a9","zone_type":"ntp","addresses":["fd00:1122:3344:105::f"],"dataset":null,"services":[{"id":"76b79b96-eaa2-4341-9aba-e77cfc92e0a9","details":{"type":"internal_ntp","address":"[fd00:1122:3344:105::f]:123","ntp_servers":["c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal","6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/0ae29053-29a2-489e-a1e6-6aec0ecd05f8/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled0.json b/sled-agent/tests/old-service-ledgers/rack3-sled0.json deleted file mode 100644 index a853a525bc..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled0.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"0710ecea-dbc4-417f-a6f7-1b97c3045db1","zone_type":"crucible","addresses":["fd00:1122:3344:116::6"],"dataset":{"id":"0710ecea-dbc4-417f-a6f7-1b97c3045db1","name":{"pool_name":"oxp_d5313ef5-019c-4c47-bc5e-63794107a1bb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::6]:32345"},"services":[{"id":"0710ecea-dbc4-417f-a6f7-1b97c3045db1","details":{"type":"crucible","address":"[fd00:1122:3344:116::6]:32345"}}]},"root":"/pool/ext/904e93a9-d175-4a20-9006-8c1e847aecf7/crypt/zone"},{"zone":{"id":"28b29d14-d55f-4b55-bbc1-f66e46ae3e70","zone_type":"crucible","addresses":["fd00:1122:3344:116::9"],"dataset":{"id":"28b29d14-d55f-4b55-bbc1-f66e46ae3e70","name":{"pool_name":"oxp_60755ffe-e9ee-4619-a751-8b3ea6405e67","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::9]:32345"},"services":[{"id":"28b29d14-d55f-4b55-bbc1-f66e46ae3e70","details":{"type":"crucible","address":"[fd00:1122:3344:116::9]:32345"}}]},"root":"/pool/ext/d5313ef5-019c-4c47-bc5e-63794107a1bb/crypt/zone"},{"zone":{"id":"6f8f9fd2-b139-4069-a7e2-8d40efd58f6c","zone_type":"crucible","addresses":["fd00:1122:3344:116::d"],"dataset":{"id":"6f8f9fd2-b139-4069-a7e2-8d40efd58f6c","name":{"pool_name":"oxp_ccd2cb0b-782f-4026-a160-6d1192f04ca3","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::d]:32345"},"services":[{"id":"6f8f9fd2-b139-4069-a7e2-8d40efd58f6c","details":{"type":"crucible","address":"[fd00:1122:3344:116::d]:32345"}}]},"root":"/pool/ext/d5313ef5-019c-4c47-bc5e-63794107a1bb/crypt/zone"},{"zone":{"id":"450308ad-bf4d-40ff-ba62-f3290f7fffaf","zone_type":"crucible","addresses":["fd00:1122:3344:116::4"],"dataset":{"id":"450308ad-bf4d-40ff-ba62-f3290f7fffaf","name":{"pool_name":"oxp_46b09442-65ba-4d59-9121-9803fe3b724b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::4]:32345"},"services":[{"id":"450308ad-bf4d-40ff-ba62-f3290f7fffaf","details":{"type":"crucible","address":"[fd00:1122:3344:116::4]:32345"}}]},"root":"/pool/ext/54d901cc-f75e-417d-8a9f-24363136d0ef/crypt/zone"},{"zone":{"id":"9a22bbaa-eab4-4a32-8546-9882dc029483","zone_type":"crucible","addresses":["fd00:1122:3344:116::8"],"dataset":{"id":"9a22bbaa-eab4-4a32-8546-9882dc029483","name":{"pool_name":"oxp_93e3f350-75a0-4af0-bdac-baf9b423926f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::8]:32345"},"services":[{"id":"9a22bbaa-eab4-4a32-8546-9882dc029483","details":{"type":"crucible","address":"[fd00:1122:3344:116::8]:32345"}}]},"root":"/pool/ext/d5313ef5-019c-4c47-bc5e-63794107a1bb/crypt/zone"},{"zone":{"id":"63a9dc49-0b5b-4483-95ed-553b545dc202","zone_type":"crucible","addresses":["fd00:1122:3344:116::a"],"dataset":{"id":"63a9dc49-0b5b-4483-95ed-553b545dc202","name":{"pool_name":"oxp_e3532845-76c0-42a9-903b-a07f7992e937","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::a]:32345"},"services":[{"id":"63a9dc49-0b5b-4483-95ed-553b545dc202","details":{"type":"crucible","address":"[fd00:1122:3344:116::a]:32345"}}]},"root":"/pool/ext/60755ffe-e9ee-4619-a751-8b3ea6405e67/crypt/zone"},{"zone":{"id":"1fef5b6c-78e4-4ad9-9973-9d8c78f1e232","zone_type":"crucible","addresses":["fd00:1122:3344:116::7"],"dataset":{"id":"1fef5b6c-78e4-4ad9-9973-9d8c78f1e232","name":{"pool_name":"oxp_54d901cc-f75e-417d-8a9f-24363136d0ef","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::7]:32345"},"services":[{"id":"1fef5b6c-78e4-4ad9-9973-9d8c78f1e232","details":{"type":"crucible","address":"[fd00:1122:3344:116::7]:32345"}}]},"root":"/pool/ext/90d7b6f9-3e28-48b0-86ac-0486728075cf/crypt/zone"},{"zone":{"id":"b2aab21a-cccd-4aa9-977f-a32090e6eaa7","zone_type":"crucible","addresses":["fd00:1122:3344:116::5"],"dataset":{"id":"b2aab21a-cccd-4aa9-977f-a32090e6eaa7","name":{"pool_name":"oxp_90d7b6f9-3e28-48b0-86ac-0486728075cf","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::5]:32345"},"services":[{"id":"b2aab21a-cccd-4aa9-977f-a32090e6eaa7","details":{"type":"crucible","address":"[fd00:1122:3344:116::5]:32345"}}]},"root":"/pool/ext/46b09442-65ba-4d59-9121-9803fe3b724b/crypt/zone"},{"zone":{"id":"fc1bbf28-24f3-4c1f-b367-2bc8231eb7d4","zone_type":"crucible","addresses":["fd00:1122:3344:116::b"],"dataset":{"id":"fc1bbf28-24f3-4c1f-b367-2bc8231eb7d4","name":{"pool_name":"oxp_0a7bb0d3-408b-42b1-8846-76cf106a9580","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::b]:32345"},"services":[{"id":"fc1bbf28-24f3-4c1f-b367-2bc8231eb7d4","details":{"type":"crucible","address":"[fd00:1122:3344:116::b]:32345"}}]},"root":"/pool/ext/e3532845-76c0-42a9-903b-a07f7992e937/crypt/zone"},{"zone":{"id":"bcb7617a-f76a-4912-8ccc-802d2a697e3c","zone_type":"crucible","addresses":["fd00:1122:3344:116::c"],"dataset":{"id":"bcb7617a-f76a-4912-8ccc-802d2a697e3c","name":{"pool_name":"oxp_904e93a9-d175-4a20-9006-8c1e847aecf7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:116::c]:32345"},"services":[{"id":"bcb7617a-f76a-4912-8ccc-802d2a697e3c","details":{"type":"crucible","address":"[fd00:1122:3344:116::c]:32345"}}]},"root":"/pool/ext/ccd2cb0b-782f-4026-a160-6d1192f04ca3/crypt/zone"},{"zone":{"id":"371fba3a-658b-469b-b675-c90cc0d39254","zone_type":"cockroach_db","addresses":["fd00:1122:3344:116::3"],"dataset":{"id":"371fba3a-658b-469b-b675-c90cc0d39254","name":{"pool_name":"oxp_46b09442-65ba-4d59-9121-9803fe3b724b","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:116::3]:32221"},"services":[{"id":"371fba3a-658b-469b-b675-c90cc0d39254","details":{"type":"cockroach_db","address":"[fd00:1122:3344:116::3]:32221"}}]},"root":"/pool/ext/46b09442-65ba-4d59-9121-9803fe3b724b/crypt/zone"},{"zone":{"id":"5a4d89f5-49e0-4566-a99c-342d1bb26b1c","zone_type":"ntp","addresses":["fd00:1122:3344:116::e"],"dataset":null,"services":[{"id":"5a4d89f5-49e0-4566-a99c-342d1bb26b1c","details":{"type":"internal_ntp","address":"[fd00:1122:3344:116::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/60755ffe-e9ee-4619-a751-8b3ea6405e67/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled1.json b/sled-agent/tests/old-service-ledgers/rack3-sled1.json deleted file mode 100644 index bd735e5e64..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled1.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"f401d06c-46fc-42f8-aa51-7515a51355ce","zone_type":"crucible","addresses":["fd00:1122:3344:11c::8"],"dataset":{"id":"f401d06c-46fc-42f8-aa51-7515a51355ce","name":{"pool_name":"oxp_8a88768a-2dd5-43b7-bd40-0db77be4d3a8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::8]:32345"},"services":[{"id":"f401d06c-46fc-42f8-aa51-7515a51355ce","details":{"type":"crucible","address":"[fd00:1122:3344:11c::8]:32345"}}]},"root":"/pool/ext/19d23d27-6a33-4203-b8c1-4b0df4ac791f/crypt/zone"},{"zone":{"id":"721c96ea-08d4-4c89-828f-600e7e344916","zone_type":"crucible","addresses":["fd00:1122:3344:11c::6"],"dataset":{"id":"721c96ea-08d4-4c89-828f-600e7e344916","name":{"pool_name":"oxp_15259003-fb04-4547-b4a9-b4511893c0fd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::6]:32345"},"services":[{"id":"721c96ea-08d4-4c89-828f-600e7e344916","details":{"type":"crucible","address":"[fd00:1122:3344:11c::6]:32345"}}]},"root":"/pool/ext/d2a8ed82-22ef-46d8-ad40-e1cb2cecebee/crypt/zone"},{"zone":{"id":"ca17bdf9-51c5-4e1e-b822-856609070ec6","zone_type":"crucible","addresses":["fd00:1122:3344:11c::5"],"dataset":{"id":"ca17bdf9-51c5-4e1e-b822-856609070ec6","name":{"pool_name":"oxp_d2a8ed82-22ef-46d8-ad40-e1cb2cecebee","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::5]:32345"},"services":[{"id":"ca17bdf9-51c5-4e1e-b822-856609070ec6","details":{"type":"crucible","address":"[fd00:1122:3344:11c::5]:32345"}}]},"root":"/pool/ext/15259003-fb04-4547-b4a9-b4511893c0fd/crypt/zone"},{"zone":{"id":"5825447e-1b5b-4960-b202-e75853d3d250","zone_type":"crucible","addresses":["fd00:1122:3344:11c::9"],"dataset":{"id":"5825447e-1b5b-4960-b202-e75853d3d250","name":{"pool_name":"oxp_04e94454-cbd4-4cee-ad69-42372bcbabd5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::9]:32345"},"services":[{"id":"5825447e-1b5b-4960-b202-e75853d3d250","details":{"type":"crucible","address":"[fd00:1122:3344:11c::9]:32345"}}]},"root":"/pool/ext/542e0fb3-552c-4d3b-b853-da1f13b581a0/crypt/zone"},{"zone":{"id":"b937d3f0-1352-47a2-b9d1-a9ccf9c82b16","zone_type":"crucible","addresses":["fd00:1122:3344:11c::c"],"dataset":{"id":"b937d3f0-1352-47a2-b9d1-a9ccf9c82b16","name":{"pool_name":"oxp_542e0fb3-552c-4d3b-b853-da1f13b581a0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::c]:32345"},"services":[{"id":"b937d3f0-1352-47a2-b9d1-a9ccf9c82b16","details":{"type":"crucible","address":"[fd00:1122:3344:11c::c]:32345"}}]},"root":"/pool/ext/eedd1d58-4892-456f-aaf7-9d650c7921ca/crypt/zone"},{"zone":{"id":"d63a677b-8dac-44ee-89a2-cc4cb151254d","zone_type":"crucible","addresses":["fd00:1122:3344:11c::3"],"dataset":{"id":"d63a677b-8dac-44ee-89a2-cc4cb151254d","name":{"pool_name":"oxp_45b5f1ee-7b66-4d74-8364-54fa0c73775f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::3]:32345"},"services":[{"id":"d63a677b-8dac-44ee-89a2-cc4cb151254d","details":{"type":"crucible","address":"[fd00:1122:3344:11c::3]:32345"}}]},"root":"/pool/ext/8a88768a-2dd5-43b7-bd40-0db77be4d3a8/crypt/zone"},{"zone":{"id":"abcb92ea-9f17-4cd8-897b-9d0d1ef7903a","zone_type":"crucible","addresses":["fd00:1122:3344:11c::4"],"dataset":{"id":"abcb92ea-9f17-4cd8-897b-9d0d1ef7903a","name":{"pool_name":"oxp_341d49db-c06a-416d-90e1-b0a3426ed02e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::4]:32345"},"services":[{"id":"abcb92ea-9f17-4cd8-897b-9d0d1ef7903a","details":{"type":"crucible","address":"[fd00:1122:3344:11c::4]:32345"}}]},"root":"/pool/ext/eedd1d58-4892-456f-aaf7-9d650c7921ca/crypt/zone"},{"zone":{"id":"000ac89d-db07-47ae-83cf-d9cafef013de","zone_type":"crucible","addresses":["fd00:1122:3344:11c::b"],"dataset":{"id":"000ac89d-db07-47ae-83cf-d9cafef013de","name":{"pool_name":"oxp_eedd1d58-4892-456f-aaf7-9d650c7921ca","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::b]:32345"},"services":[{"id":"000ac89d-db07-47ae-83cf-d9cafef013de","details":{"type":"crucible","address":"[fd00:1122:3344:11c::b]:32345"}}]},"root":"/pool/ext/04e94454-cbd4-4cee-ad69-42372bcbabd5/crypt/zone"},{"zone":{"id":"29e1e2e4-695e-4c05-8f0c-c16a0a61d390","zone_type":"crucible","addresses":["fd00:1122:3344:11c::7"],"dataset":{"id":"29e1e2e4-695e-4c05-8f0c-c16a0a61d390","name":{"pool_name":"oxp_19d23d27-6a33-4203-b8c1-4b0df4ac791f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::7]:32345"},"services":[{"id":"29e1e2e4-695e-4c05-8f0c-c16a0a61d390","details":{"type":"crucible","address":"[fd00:1122:3344:11c::7]:32345"}}]},"root":"/pool/ext/d2a8ed82-22ef-46d8-ad40-e1cb2cecebee/crypt/zone"},{"zone":{"id":"9fa7d7be-a6de-4d36-b56b-d1cc5ca7c82c","zone_type":"crucible","addresses":["fd00:1122:3344:11c::a"],"dataset":{"id":"9fa7d7be-a6de-4d36-b56b-d1cc5ca7c82c","name":{"pool_name":"oxp_0fd7a0b1-ed4b-4dc6-8c44-a49c9628c7e1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11c::a]:32345"},"services":[{"id":"9fa7d7be-a6de-4d36-b56b-d1cc5ca7c82c","details":{"type":"crucible","address":"[fd00:1122:3344:11c::a]:32345"}}]},"root":"/pool/ext/d2a8ed82-22ef-46d8-ad40-e1cb2cecebee/crypt/zone"},{"zone":{"id":"249db5f1-45e2-4a5c-a91f-cc51dbd87040","zone_type":"ntp","addresses":["fd00:1122:3344:11c::d"],"dataset":null,"services":[{"id":"249db5f1-45e2-4a5c-a91f-cc51dbd87040","details":{"type":"internal_ntp","address":"[fd00:1122:3344:11c::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/542e0fb3-552c-4d3b-b853-da1f13b581a0/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled11.json b/sled-agent/tests/old-service-ledgers/rack3-sled11.json deleted file mode 100644 index 2918c74c4b..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled11.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":5,"requests":[{"zone":{"id":"7ddd0738-59df-4b67-a41e-7f0de9827187","zone_type":"crucible","addresses":["fd00:1122:3344:11e::4"],"dataset":{"id":"7ddd0738-59df-4b67-a41e-7f0de9827187","name":{"pool_name":"oxp_09af632a-6b1b-4a18-8c91-d392da38b02f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::4]:32345"},"services":[{"id":"7ddd0738-59df-4b67-a41e-7f0de9827187","details":{"type":"crucible","address":"[fd00:1122:3344:11e::4]:32345"}}]},"root":"/pool/ext/09af632a-6b1b-4a18-8c91-d392da38b02f/crypt/zone"},{"zone":{"id":"9706189f-713a-4394-b5dc-45dcf67dc46e","zone_type":"crucible","addresses":["fd00:1122:3344:11e::9"],"dataset":{"id":"9706189f-713a-4394-b5dc-45dcf67dc46e","name":{"pool_name":"oxp_4e1837c8-91ab-4d1d-abfd-f5144d88535e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::9]:32345"},"services":[{"id":"9706189f-713a-4394-b5dc-45dcf67dc46e","details":{"type":"crucible","address":"[fd00:1122:3344:11e::9]:32345"}}]},"root":"/pool/ext/2f0d47cb-28d1-4350-8656-60c6121f773b/crypt/zone"},{"zone":{"id":"7bdd841b-5e34-4c19-9066-b12578651446","zone_type":"crucible","addresses":["fd00:1122:3344:11e::a"],"dataset":{"id":"7bdd841b-5e34-4c19-9066-b12578651446","name":{"pool_name":"oxp_78d1e7f7-8d11-4fed-8b1e-be58908aea2f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::a]:32345"},"services":[{"id":"7bdd841b-5e34-4c19-9066-b12578651446","details":{"type":"crucible","address":"[fd00:1122:3344:11e::a]:32345"}}]},"root":"/pool/ext/62c23f4b-8e7b-4cd8-9055-19c1d8bd5ac8/crypt/zone"},{"zone":{"id":"74c0f60b-de5f-4456-a85f-f992a6e10424","zone_type":"crucible","addresses":["fd00:1122:3344:11e::b"],"dataset":{"id":"74c0f60b-de5f-4456-a85f-f992a6e10424","name":{"pool_name":"oxp_3b81d709-bf10-4dd7-a2c0-759d8acc2da0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::b]:32345"},"services":[{"id":"74c0f60b-de5f-4456-a85f-f992a6e10424","details":{"type":"crucible","address":"[fd00:1122:3344:11e::b]:32345"}}]},"root":"/pool/ext/09af632a-6b1b-4a18-8c91-d392da38b02f/crypt/zone"},{"zone":{"id":"da81ce6f-bd38-440e-b966-8a743092fa21","zone_type":"crucible","addresses":["fd00:1122:3344:11e::6"],"dataset":{"id":"da81ce6f-bd38-440e-b966-8a743092fa21","name":{"pool_name":"oxp_62c23f4b-8e7b-4cd8-9055-19c1d8bd5ac8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::6]:32345"},"services":[{"id":"da81ce6f-bd38-440e-b966-8a743092fa21","details":{"type":"crucible","address":"[fd00:1122:3344:11e::6]:32345"}}]},"root":"/pool/ext/215dd02b-0de6-488a-9e65-5e588cd079fb/crypt/zone"},{"zone":{"id":"febbca37-5279-400f-a2e9-6b5271b2d2fc","zone_type":"crucible","addresses":["fd00:1122:3344:11e::7"],"dataset":{"id":"febbca37-5279-400f-a2e9-6b5271b2d2fc","name":{"pool_name":"oxp_fb33e773-fb93-41a0-8078-b653b9078dda","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::7]:32345"},"services":[{"id":"febbca37-5279-400f-a2e9-6b5271b2d2fc","details":{"type":"crucible","address":"[fd00:1122:3344:11e::7]:32345"}}]},"root":"/pool/ext/2f0d47cb-28d1-4350-8656-60c6121f773b/crypt/zone"},{"zone":{"id":"5100e222-5ea4-4e67-9040-679137e666c8","zone_type":"crucible","addresses":["fd00:1122:3344:11e::5"],"dataset":{"id":"5100e222-5ea4-4e67-9040-679137e666c8","name":{"pool_name":"oxp_23767587-2253-431b-8944-18b9bfefcb3d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::5]:32345"},"services":[{"id":"5100e222-5ea4-4e67-9040-679137e666c8","details":{"type":"crucible","address":"[fd00:1122:3344:11e::5]:32345"}}]},"root":"/pool/ext/3b81d709-bf10-4dd7-a2c0-759d8acc2da0/crypt/zone"},{"zone":{"id":"c7ec3bc8-08ca-4901-a45e-0d68db72c6a7","zone_type":"crucible","addresses":["fd00:1122:3344:11e::3"],"dataset":{"id":"c7ec3bc8-08ca-4901-a45e-0d68db72c6a7","name":{"pool_name":"oxp_2f0d47cb-28d1-4350-8656-60c6121f773b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::3]:32345"},"services":[{"id":"c7ec3bc8-08ca-4901-a45e-0d68db72c6a7","details":{"type":"crucible","address":"[fd00:1122:3344:11e::3]:32345"}}]},"root":"/pool/ext/215dd02b-0de6-488a-9e65-5e588cd079fb/crypt/zone"},{"zone":{"id":"1fc80dd3-0fd9-4403-96bd-5bbf9eb0f15a","zone_type":"crucible","addresses":["fd00:1122:3344:11e::c"],"dataset":{"id":"1fc80dd3-0fd9-4403-96bd-5bbf9eb0f15a","name":{"pool_name":"oxp_2c932d54-41fb-4ffe-a57f-0479b9e5841e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::c]:32345"},"services":[{"id":"1fc80dd3-0fd9-4403-96bd-5bbf9eb0f15a","details":{"type":"crucible","address":"[fd00:1122:3344:11e::c]:32345"}}]},"root":"/pool/ext/3b81d709-bf10-4dd7-a2c0-759d8acc2da0/crypt/zone"},{"zone":{"id":"4eacc68d-5699-440a-ab33-c75f259e4cc3","zone_type":"crucible","addresses":["fd00:1122:3344:11e::8"],"dataset":{"id":"4eacc68d-5699-440a-ab33-c75f259e4cc3","name":{"pool_name":"oxp_215dd02b-0de6-488a-9e65-5e588cd079fb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11e::8]:32345"},"services":[{"id":"4eacc68d-5699-440a-ab33-c75f259e4cc3","details":{"type":"crucible","address":"[fd00:1122:3344:11e::8]:32345"}}]},"root":"/pool/ext/4e1837c8-91ab-4d1d-abfd-f5144d88535e/crypt/zone"},{"zone":{"id":"cb901d3e-8811-4c4c-a274-a44130501ecf","zone_type":"ntp","addresses":["fd00:1122:3344:11e::d"],"dataset":null,"services":[{"id":"cb901d3e-8811-4c4c-a274-a44130501ecf","details":{"type":"boundary_ntp","address":"[fd00:1122:3344:11e::d]:123","ntp_servers":["time.cloudflare.com"],"dns_servers":["1.1.1.1","8.8.8.8"],"domain":null,"nic":{"id":"bcf9d9eb-b4ba-4fd5-91e0-55a3414ae049","kind":{"type":"service","id":"cb901d3e-8811-4c4c-a274-a44130501ecf"},"name":"ntp-cb901d3e-8811-4c4c-a274-a44130501ecf","ip":"172.30.3.6","mac":"A8:40:25:FF:D5:2F","subnet":"172.30.3.0/24","vni":100,"primary":true,"slot":0},"snat_cfg":{"ip":"45.154.216.39","first_port":16384,"last_port":32767}}}]},"root":"/pool/ext/23767587-2253-431b-8944-18b9bfefcb3d/crypt/zone"},{"zone":{"id":"be4aada9-d160-401d-a630-a0764c039702","zone_type":"internal_dns","addresses":["fd00:1122:3344:2::1"],"dataset":{"id":"be4aada9-d160-401d-a630-a0764c039702","name":{"pool_name":"oxp_2f0d47cb-28d1-4350-8656-60c6121f773b","kind":{"type":"internal_dns"}},"service_address":"[fd00:1122:3344:2::1]:5353"},"services":[{"id":"be4aada9-d160-401d-a630-a0764c039702","details":{"type":"internal_dns","http_address":"[fd00:1122:3344:2::1]:5353","dns_address":"[fd00:1122:3344:2::1]:53","gz_address":"fd00:1122:3344:2::2","gz_address_index":1}}]},"root":"/pool/ext/78d1e7f7-8d11-4fed-8b1e-be58908aea2f/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled12.json b/sled-agent/tests/old-service-ledgers/rack3-sled12.json deleted file mode 100644 index c81f586e01..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled12.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"d8f1b9d2-fa2e-4f03-bbea-2039448d7792","zone_type":"crucible","addresses":["fd00:1122:3344:112::5"],"dataset":{"id":"d8f1b9d2-fa2e-4f03-bbea-2039448d7792","name":{"pool_name":"oxp_7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::5]:32345"},"services":[{"id":"d8f1b9d2-fa2e-4f03-bbea-2039448d7792","details":{"type":"crucible","address":"[fd00:1122:3344:112::5]:32345"}}]},"root":"/pool/ext/78d9f0ae-8e7f-450e-abc2-76b983efa5cd/crypt/zone"},{"zone":{"id":"2074a935-c0b3-4c4f-aae5-a29adae3e1ac","zone_type":"crucible","addresses":["fd00:1122:3344:112::8"],"dataset":{"id":"2074a935-c0b3-4c4f-aae5-a29adae3e1ac","name":{"pool_name":"oxp_ac663368-45fb-447c-811e-561c68e37bdd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::8]:32345"},"services":[{"id":"2074a935-c0b3-4c4f-aae5-a29adae3e1ac","details":{"type":"crucible","address":"[fd00:1122:3344:112::8]:32345"}}]},"root":"/pool/ext/ac663368-45fb-447c-811e-561c68e37bdd/crypt/zone"},{"zone":{"id":"2885d3c7-ad7d-445c-8630-dc6c81f8caa0","zone_type":"crucible","addresses":["fd00:1122:3344:112::a"],"dataset":{"id":"2885d3c7-ad7d-445c-8630-dc6c81f8caa0","name":{"pool_name":"oxp_8e82e8da-e1c5-4867-bc1c-b5441f9c1010","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::a]:32345"},"services":[{"id":"2885d3c7-ad7d-445c-8630-dc6c81f8caa0","details":{"type":"crucible","address":"[fd00:1122:3344:112::a]:32345"}}]},"root":"/pool/ext/8e82e8da-e1c5-4867-bc1c-b5441f9c1010/crypt/zone"},{"zone":{"id":"1eca241b-6868-4c59-876b-58356654f3b5","zone_type":"crucible","addresses":["fd00:1122:3344:112::c"],"dataset":{"id":"1eca241b-6868-4c59-876b-58356654f3b5","name":{"pool_name":"oxp_fde16c69-aa47-4a15-bb3f-3a5861ae45bd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::c]:32345"},"services":[{"id":"1eca241b-6868-4c59-876b-58356654f3b5","details":{"type":"crucible","address":"[fd00:1122:3344:112::c]:32345"}}]},"root":"/pool/ext/7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1/crypt/zone"},{"zone":{"id":"cc656f2e-8542-4986-8524-2f55984939c1","zone_type":"crucible","addresses":["fd00:1122:3344:112::d"],"dataset":{"id":"cc656f2e-8542-4986-8524-2f55984939c1","name":{"pool_name":"oxp_21e6d0f9-887e-4d6f-9a00-4cd61139eea6","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::d]:32345"},"services":[{"id":"cc656f2e-8542-4986-8524-2f55984939c1","details":{"type":"crucible","address":"[fd00:1122:3344:112::d]:32345"}}]},"root":"/pool/ext/21e6d0f9-887e-4d6f-9a00-4cd61139eea6/crypt/zone"},{"zone":{"id":"dfb1ebce-a4c7-4b50-9435-9a79b884c1af","zone_type":"clickhouse","addresses":["fd00:1122:3344:112::3"],"dataset":{"id":"dfb1ebce-a4c7-4b50-9435-9a79b884c1af","name":{"pool_name":"oxp_4f045315-de51-46ed-a011-16496615278f","kind":{"type":"clickhouse"}},"service_address":"[fd00:1122:3344:112::3]:8123"},"services":[{"id":"dfb1ebce-a4c7-4b50-9435-9a79b884c1af","details":{"type":"clickhouse","address":"[fd00:1122:3344:112::3]:8123"}}]},"root":"/pool/ext/7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1/crypt/zone"},{"zone":{"id":"a95d90ed-b2b1-4a5d-8d0d-4195b34bc764","zone_type":"crucible","addresses":["fd00:1122:3344:112::6"],"dataset":{"id":"a95d90ed-b2b1-4a5d-8d0d-4195b34bc764","name":{"pool_name":"oxp_d2c77c69-14d7-442e-8b47-a0d7af5a0e7e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::6]:32345"},"services":[{"id":"a95d90ed-b2b1-4a5d-8d0d-4195b34bc764","details":{"type":"crucible","address":"[fd00:1122:3344:112::6]:32345"}}]},"root":"/pool/ext/fad56ff1-ad9f-4215-b584-522eab18cf7b/crypt/zone"},{"zone":{"id":"1d3ebc90-d5a5-4cb0-ae90-50bb2163ae13","zone_type":"crucible","addresses":["fd00:1122:3344:112::b"],"dataset":{"id":"1d3ebc90-d5a5-4cb0-ae90-50bb2163ae13","name":{"pool_name":"oxp_fad56ff1-ad9f-4215-b584-522eab18cf7b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::b]:32345"},"services":[{"id":"1d3ebc90-d5a5-4cb0-ae90-50bb2163ae13","details":{"type":"crucible","address":"[fd00:1122:3344:112::b]:32345"}}]},"root":"/pool/ext/7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1/crypt/zone"},{"zone":{"id":"7af9f38b-0c7a-402e-8db3-7c7fb50b4665","zone_type":"crucible","addresses":["fd00:1122:3344:112::9"],"dataset":{"id":"7af9f38b-0c7a-402e-8db3-7c7fb50b4665","name":{"pool_name":"oxp_d0693580-5c5a-449f-803f-ce7188ebc580","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::9]:32345"},"services":[{"id":"7af9f38b-0c7a-402e-8db3-7c7fb50b4665","details":{"type":"crucible","address":"[fd00:1122:3344:112::9]:32345"}}]},"root":"/pool/ext/d2c77c69-14d7-442e-8b47-a0d7af5a0e7e/crypt/zone"},{"zone":{"id":"94d9bb0a-ecd2-4501-b960-60982f55ad12","zone_type":"crucible","addresses":["fd00:1122:3344:112::7"],"dataset":{"id":"94d9bb0a-ecd2-4501-b960-60982f55ad12","name":{"pool_name":"oxp_78d9f0ae-8e7f-450e-abc2-76b983efa5cd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::7]:32345"},"services":[{"id":"94d9bb0a-ecd2-4501-b960-60982f55ad12","details":{"type":"crucible","address":"[fd00:1122:3344:112::7]:32345"}}]},"root":"/pool/ext/ac663368-45fb-447c-811e-561c68e37bdd/crypt/zone"},{"zone":{"id":"277c1105-576e-4ec1-8e2c-cbae2f5ac9f6","zone_type":"crucible","addresses":["fd00:1122:3344:112::4"],"dataset":{"id":"277c1105-576e-4ec1-8e2c-cbae2f5ac9f6","name":{"pool_name":"oxp_4f045315-de51-46ed-a011-16496615278f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:112::4]:32345"},"services":[{"id":"277c1105-576e-4ec1-8e2c-cbae2f5ac9f6","details":{"type":"crucible","address":"[fd00:1122:3344:112::4]:32345"}}]},"root":"/pool/ext/7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1/crypt/zone"},{"zone":{"id":"555c3407-a76c-4ea4-a17a-a670d85a59b0","zone_type":"ntp","addresses":["fd00:1122:3344:112::e"],"dataset":null,"services":[{"id":"555c3407-a76c-4ea4-a17a-a670d85a59b0","details":{"type":"internal_ntp","address":"[fd00:1122:3344:112::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/8e82e8da-e1c5-4867-bc1c-b5441f9c1010/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled13.json b/sled-agent/tests/old-service-ledgers/rack3-sled13.json deleted file mode 100644 index ab151a828e..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled13.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":5,"requests":[{"zone":{"id":"fbcf51c9-a732-4a03-8c19-cfb5b819cb7a","zone_type":"crucible","addresses":["fd00:1122:3344:104::5"],"dataset":{"id":"fbcf51c9-a732-4a03-8c19-cfb5b819cb7a","name":{"pool_name":"oxp_382a2961-cd27-4a9c-901d-468a45ff5708","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::5]:32345"},"services":[{"id":"fbcf51c9-a732-4a03-8c19-cfb5b819cb7a","details":{"type":"crucible","address":"[fd00:1122:3344:104::5]:32345"}}]},"root":"/pool/ext/e99994ae-61ca-4742-a02c-eb0a8a5b69ff/crypt/zone"},{"zone":{"id":"7f8a5026-1f1d-4ab3-8c04-077bfda2f815","zone_type":"crucible","addresses":["fd00:1122:3344:104::4"],"dataset":{"id":"7f8a5026-1f1d-4ab3-8c04-077bfda2f815","name":{"pool_name":"oxp_9c99b9b6-8018-455e-a58a-c048ddd3e11b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::4]:32345"},"services":[{"id":"7f8a5026-1f1d-4ab3-8c04-077bfda2f815","details":{"type":"crucible","address":"[fd00:1122:3344:104::4]:32345"}}]},"root":"/pool/ext/22c79e54-37ef-4ad2-a6cb-a7ee3e4f7167/crypt/zone"},{"zone":{"id":"6d45d856-0e49-4eb7-ad76-989a9ae636a2","zone_type":"crucible","addresses":["fd00:1122:3344:104::3"],"dataset":{"id":"6d45d856-0e49-4eb7-ad76-989a9ae636a2","name":{"pool_name":"oxp_b74a84fa-b4c8-4c5f-92f4-f4e62a0a311d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::3]:32345"},"services":[{"id":"6d45d856-0e49-4eb7-ad76-989a9ae636a2","details":{"type":"crucible","address":"[fd00:1122:3344:104::3]:32345"}}]},"root":"/pool/ext/9c99b9b6-8018-455e-a58a-c048ddd3e11b/crypt/zone"},{"zone":{"id":"c8dc7fff-72c8-49eb-a552-d605f8655134","zone_type":"crucible","addresses":["fd00:1122:3344:104::6"],"dataset":{"id":"c8dc7fff-72c8-49eb-a552-d605f8655134","name":{"pool_name":"oxp_22c79e54-37ef-4ad2-a6cb-a7ee3e4f7167","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::6]:32345"},"services":[{"id":"c8dc7fff-72c8-49eb-a552-d605f8655134","details":{"type":"crucible","address":"[fd00:1122:3344:104::6]:32345"}}]},"root":"/pool/ext/22c79e54-37ef-4ad2-a6cb-a7ee3e4f7167/crypt/zone"},{"zone":{"id":"128a90f5-8889-4665-8343-2c7098f2922c","zone_type":"crucible","addresses":["fd00:1122:3344:104::7"],"dataset":{"id":"128a90f5-8889-4665-8343-2c7098f2922c","name":{"pool_name":"oxp_8b3d0b51-c6a5-4d2c-827a-0d0d1471136d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::7]:32345"},"services":[{"id":"128a90f5-8889-4665-8343-2c7098f2922c","details":{"type":"crucible","address":"[fd00:1122:3344:104::7]:32345"}}]},"root":"/pool/ext/29cd042b-e772-4d26-ac85-ef16009950bd/crypt/zone"},{"zone":{"id":"a72f1878-3b03-4267-9024-5df5ebae69de","zone_type":"crucible","addresses":["fd00:1122:3344:104::a"],"dataset":{"id":"a72f1878-3b03-4267-9024-5df5ebae69de","name":{"pool_name":"oxp_e99994ae-61ca-4742-a02c-eb0a8a5b69ff","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::a]:32345"},"services":[{"id":"a72f1878-3b03-4267-9024-5df5ebae69de","details":{"type":"crucible","address":"[fd00:1122:3344:104::a]:32345"}}]},"root":"/pool/ext/8b3d0b51-c6a5-4d2c-827a-0d0d1471136d/crypt/zone"},{"zone":{"id":"6a9165a2-9b66-485a-aaf0-70d89d60bb6c","zone_type":"crucible","addresses":["fd00:1122:3344:104::b"],"dataset":{"id":"6a9165a2-9b66-485a-aaf0-70d89d60bb6c","name":{"pool_name":"oxp_6a02f05f-e400-4c80-8df8-89aaecb6c12b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::b]:32345"},"services":[{"id":"6a9165a2-9b66-485a-aaf0-70d89d60bb6c","details":{"type":"crucible","address":"[fd00:1122:3344:104::b]:32345"}}]},"root":"/pool/ext/9c99b9b6-8018-455e-a58a-c048ddd3e11b/crypt/zone"},{"zone":{"id":"9677c4ed-96bc-4dcb-ae74-f7a3e9d2b5e2","zone_type":"crucible","addresses":["fd00:1122:3344:104::c"],"dataset":{"id":"9677c4ed-96bc-4dcb-ae74-f7a3e9d2b5e2","name":{"pool_name":"oxp_7c30978f-ee87-4e53-8fdf-3455e5e851b7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::c]:32345"},"services":[{"id":"9677c4ed-96bc-4dcb-ae74-f7a3e9d2b5e2","details":{"type":"crucible","address":"[fd00:1122:3344:104::c]:32345"}}]},"root":"/pool/ext/29cd042b-e772-4d26-ac85-ef16009950bd/crypt/zone"},{"zone":{"id":"179039e7-3ffd-4b76-9379-bef41d42a5ff","zone_type":"crucible","addresses":["fd00:1122:3344:104::8"],"dataset":{"id":"179039e7-3ffd-4b76-9379-bef41d42a5ff","name":{"pool_name":"oxp_4db7e002-e112-4bfc-a41e-8ae26991b01e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::8]:32345"},"services":[{"id":"179039e7-3ffd-4b76-9379-bef41d42a5ff","details":{"type":"crucible","address":"[fd00:1122:3344:104::8]:32345"}}]},"root":"/pool/ext/8b3d0b51-c6a5-4d2c-827a-0d0d1471136d/crypt/zone"},{"zone":{"id":"6067e31e-b6a3-4114-9e49-0296adc8e7af","zone_type":"crucible","addresses":["fd00:1122:3344:104::9"],"dataset":{"id":"6067e31e-b6a3-4114-9e49-0296adc8e7af","name":{"pool_name":"oxp_29cd042b-e772-4d26-ac85-ef16009950bd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:104::9]:32345"},"services":[{"id":"6067e31e-b6a3-4114-9e49-0296adc8e7af","details":{"type":"crucible","address":"[fd00:1122:3344:104::9]:32345"}}]},"root":"/pool/ext/9c99b9b6-8018-455e-a58a-c048ddd3e11b/crypt/zone"},{"zone":{"id":"440dd615-e11f-4a5d-aeb4-dcf88bb314de","zone_type":"ntp","addresses":["fd00:1122:3344:104::d"],"dataset":null,"services":[{"id":"440dd615-e11f-4a5d-aeb4-dcf88bb314de","details":{"type":"boundary_ntp","address":"[fd00:1122:3344:104::d]:123","ntp_servers":["time.cloudflare.com"],"dns_servers":["1.1.1.1","8.8.8.8"],"domain":null,"nic":{"id":"0b52fe1b-f4cc-43b1-9ac3-4ebb4ab60133","kind":{"type":"service","id":"440dd615-e11f-4a5d-aeb4-dcf88bb314de"},"name":"ntp-440dd615-e11f-4a5d-aeb4-dcf88bb314de","ip":"172.30.3.5","mac":"A8:40:25:FF:85:1E","subnet":"172.30.3.0/24","vni":100,"primary":true,"slot":0},"snat_cfg":{"ip":"45.154.216.38","first_port":0,"last_port":16383}}}]},"root":"/pool/ext/382a2961-cd27-4a9c-901d-468a45ff5708/crypt/zone"},{"zone":{"id":"06e2de03-bd92-404c-a8ea-a13185539d24","zone_type":"internal_dns","addresses":["fd00:1122:3344:1::1"],"dataset":{"id":"06e2de03-bd92-404c-a8ea-a13185539d24","name":{"pool_name":"oxp_b74a84fa-b4c8-4c5f-92f4-f4e62a0a311d","kind":{"type":"internal_dns"}},"service_address":"[fd00:1122:3344:1::1]:5353"},"services":[{"id":"06e2de03-bd92-404c-a8ea-a13185539d24","details":{"type":"internal_dns","http_address":"[fd00:1122:3344:1::1]:5353","dns_address":"[fd00:1122:3344:1::1]:53","gz_address":"fd00:1122:3344:1::2","gz_address_index":0}}]},"root":"/pool/ext/e99994ae-61ca-4742-a02c-eb0a8a5b69ff/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled14.json b/sled-agent/tests/old-service-ledgers/rack3-sled14.json deleted file mode 100644 index 89c12a015f..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled14.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"ac35afab-a312-43c3-a42d-04b8e99fcbde","zone_type":"crucible","addresses":["fd00:1122:3344:111::4"],"dataset":{"id":"ac35afab-a312-43c3-a42d-04b8e99fcbde","name":{"pool_name":"oxp_6601065c-c172-4118-81b4-16adde7e9401","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::4]:32345"},"services":[{"id":"ac35afab-a312-43c3-a42d-04b8e99fcbde","details":{"type":"crucible","address":"[fd00:1122:3344:111::4]:32345"}}]},"root":"/pool/ext/24d7e250-9fc6-459e-8155-30f8e8ccb28c/crypt/zone"},{"zone":{"id":"6cd94da2-35b9-4683-a931-29ad4a5ed0ef","zone_type":"crucible","addresses":["fd00:1122:3344:111::c"],"dataset":{"id":"6cd94da2-35b9-4683-a931-29ad4a5ed0ef","name":{"pool_name":"oxp_58276eba-a53c-4ef3-b374-4cdcde4d6e12","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::c]:32345"},"services":[{"id":"6cd94da2-35b9-4683-a931-29ad4a5ed0ef","details":{"type":"crucible","address":"[fd00:1122:3344:111::c]:32345"}}]},"root":"/pool/ext/24d7e250-9fc6-459e-8155-30f8e8ccb28c/crypt/zone"},{"zone":{"id":"41f07d39-fcc0-4796-8b7c-7cfcd9135f78","zone_type":"crucible","addresses":["fd00:1122:3344:111::9"],"dataset":{"id":"41f07d39-fcc0-4796-8b7c-7cfcd9135f78","name":{"pool_name":"oxp_4b90abdc-3348-4158-bedc-5bcd56e281d8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::9]:32345"},"services":[{"id":"41f07d39-fcc0-4796-8b7c-7cfcd9135f78","details":{"type":"crucible","address":"[fd00:1122:3344:111::9]:32345"}}]},"root":"/pool/ext/8e955f54-fbef-4021-9eec-457825468813/crypt/zone"},{"zone":{"id":"44c35566-dd64-4e4a-896e-c50aaa3df14f","zone_type":"nexus","addresses":["fd00:1122:3344:111::3"],"dataset":null,"services":[{"id":"44c35566-dd64-4e4a-896e-c50aaa3df14f","details":{"type":"nexus","internal_address":"[fd00:1122:3344:111::3]:12221","external_ip":"45.154.216.37","nic":{"id":"6f824d20-6ce0-4e8b-9ce3-b12dd2b59913","kind":{"type":"service","id":"44c35566-dd64-4e4a-896e-c50aaa3df14f"},"name":"nexus-44c35566-dd64-4e4a-896e-c50aaa3df14f","ip":"172.30.2.7","mac":"A8:40:25:FF:E8:5F","subnet":"172.30.2.0/24","vni":100,"primary":true,"slot":0},"external_tls":true,"external_dns_servers":["1.1.1.1","8.8.8.8"]}}]},"root":"/pool/ext/435d7a1b-2865-4d49-903f-a68f464ade4d/crypt/zone"},{"zone":{"id":"e5020d24-8652-456b-bf92-cd7d255a34c5","zone_type":"crucible","addresses":["fd00:1122:3344:111::6"],"dataset":{"id":"e5020d24-8652-456b-bf92-cd7d255a34c5","name":{"pool_name":"oxp_f6925045-363d-4e18-9bde-ee2987b33d21","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::6]:32345"},"services":[{"id":"e5020d24-8652-456b-bf92-cd7d255a34c5","details":{"type":"crucible","address":"[fd00:1122:3344:111::6]:32345"}}]},"root":"/pool/ext/6601065c-c172-4118-81b4-16adde7e9401/crypt/zone"},{"zone":{"id":"8f25f258-afd7-4351-83e4-24220ec0c251","zone_type":"crucible","addresses":["fd00:1122:3344:111::8"],"dataset":{"id":"8f25f258-afd7-4351-83e4-24220ec0c251","name":{"pool_name":"oxp_8e955f54-fbef-4021-9eec-457825468813","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::8]:32345"},"services":[{"id":"8f25f258-afd7-4351-83e4-24220ec0c251","details":{"type":"crucible","address":"[fd00:1122:3344:111::8]:32345"}}]},"root":"/pool/ext/6601065c-c172-4118-81b4-16adde7e9401/crypt/zone"},{"zone":{"id":"26aa50ec-d70a-47ea-85fc-e55c62a2e0c6","zone_type":"crucible","addresses":["fd00:1122:3344:111::5"],"dataset":{"id":"26aa50ec-d70a-47ea-85fc-e55c62a2e0c6","name":{"pool_name":"oxp_24d7e250-9fc6-459e-8155-30f8e8ccb28c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::5]:32345"},"services":[{"id":"26aa50ec-d70a-47ea-85fc-e55c62a2e0c6","details":{"type":"crucible","address":"[fd00:1122:3344:111::5]:32345"}}]},"root":"/pool/ext/435d7a1b-2865-4d49-903f-a68f464ade4d/crypt/zone"},{"zone":{"id":"68dc212f-a96a-420f-8334-b11ee5d7cb95","zone_type":"crucible","addresses":["fd00:1122:3344:111::7"],"dataset":{"id":"68dc212f-a96a-420f-8334-b11ee5d7cb95","name":{"pool_name":"oxp_4353b00b-937e-4d07-aea6-014c57b6f12c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::7]:32345"},"services":[{"id":"68dc212f-a96a-420f-8334-b11ee5d7cb95","details":{"type":"crucible","address":"[fd00:1122:3344:111::7]:32345"}}]},"root":"/pool/ext/24d7e250-9fc6-459e-8155-30f8e8ccb28c/crypt/zone"},{"zone":{"id":"475140fa-a5dc-4ec1-876d-751c48adfc37","zone_type":"crucible","addresses":["fd00:1122:3344:111::a"],"dataset":{"id":"475140fa-a5dc-4ec1-876d-751c48adfc37","name":{"pool_name":"oxp_ee55b053-6874-4e20-86b5-2e105e64c068","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::a]:32345"},"services":[{"id":"475140fa-a5dc-4ec1-876d-751c48adfc37","details":{"type":"crucible","address":"[fd00:1122:3344:111::a]:32345"}}]},"root":"/pool/ext/ee55b053-6874-4e20-86b5-2e105e64c068/crypt/zone"},{"zone":{"id":"09d5a8c9-00db-4914-a2c6-7ae3d2da4558","zone_type":"crucible","addresses":["fd00:1122:3344:111::d"],"dataset":{"id":"09d5a8c9-00db-4914-a2c6-7ae3d2da4558","name":{"pool_name":"oxp_9ab5aba5-47dc-4bc4-8f6d-7cbe0f98a9a2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::d]:32345"},"services":[{"id":"09d5a8c9-00db-4914-a2c6-7ae3d2da4558","details":{"type":"crucible","address":"[fd00:1122:3344:111::d]:32345"}}]},"root":"/pool/ext/8e955f54-fbef-4021-9eec-457825468813/crypt/zone"},{"zone":{"id":"014f6a39-ad64-4f0a-9fef-01ca0d184cbf","zone_type":"crucible","addresses":["fd00:1122:3344:111::b"],"dataset":{"id":"014f6a39-ad64-4f0a-9fef-01ca0d184cbf","name":{"pool_name":"oxp_435d7a1b-2865-4d49-903f-a68f464ade4d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:111::b]:32345"},"services":[{"id":"014f6a39-ad64-4f0a-9fef-01ca0d184cbf","details":{"type":"crucible","address":"[fd00:1122:3344:111::b]:32345"}}]},"root":"/pool/ext/f6925045-363d-4e18-9bde-ee2987b33d21/crypt/zone"},{"zone":{"id":"aceaf348-ba07-4965-a543-63a800826fe8","zone_type":"ntp","addresses":["fd00:1122:3344:111::e"],"dataset":null,"services":[{"id":"aceaf348-ba07-4965-a543-63a800826fe8","details":{"type":"internal_ntp","address":"[fd00:1122:3344:111::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/8e955f54-fbef-4021-9eec-457825468813/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled15.json b/sled-agent/tests/old-service-ledgers/rack3-sled15.json deleted file mode 100644 index 880f29409e..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled15.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"09a9ecee-1e7c-4819-b27a-73bb61099ce7","zone_type":"external_dns","addresses":["fd00:1122:3344:114::3"],"dataset":{"id":"09a9ecee-1e7c-4819-b27a-73bb61099ce7","name":{"pool_name":"oxp_b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e","kind":{"type":"external_dns"}},"service_address":"[fd00:1122:3344:114::3]:5353"},"services":[{"id":"09a9ecee-1e7c-4819-b27a-73bb61099ce7","details":{"type":"external_dns","http_address":"[fd00:1122:3344:114::3]:5353","dns_address":"45.154.216.33:53","nic":{"id":"400ca77b-7fee-47d5-8f17-1f4b9c729f27","kind":{"type":"service","id":"09a9ecee-1e7c-4819-b27a-73bb61099ce7"},"name":"external-dns-09a9ecee-1e7c-4819-b27a-73bb61099ce7","ip":"172.30.1.5","mac":"A8:40:25:FF:B7:C7","subnet":"172.30.1.0/24","vni":100,"primary":true,"slot":0}}}]},"root":"/pool/ext/9e878b1e-bf92-4155-8162-640851c2f5d5/crypt/zone"},{"zone":{"id":"1792e003-55f7-49b8-906c-4160db91bc23","zone_type":"crucible","addresses":["fd00:1122:3344:114::5"],"dataset":{"id":"1792e003-55f7-49b8-906c-4160db91bc23","name":{"pool_name":"oxp_7f3a760f-a4c0-456f-8a22-2d06ecac1022","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::5]:32345"},"services":[{"id":"1792e003-55f7-49b8-906c-4160db91bc23","details":{"type":"crucible","address":"[fd00:1122:3344:114::5]:32345"}}]},"root":"/pool/ext/76f09ad5-c96c-4748-bbe4-71afaea7bc5e/crypt/zone"},{"zone":{"id":"73bc7c0e-1034-449f-8920-4a1f418653ff","zone_type":"crucible","addresses":["fd00:1122:3344:114::8"],"dataset":{"id":"73bc7c0e-1034-449f-8920-4a1f418653ff","name":{"pool_name":"oxp_e87037be-1cdf-4c6e-a8a3-c27b830eaef9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::8]:32345"},"services":[{"id":"73bc7c0e-1034-449f-8920-4a1f418653ff","details":{"type":"crucible","address":"[fd00:1122:3344:114::8]:32345"}}]},"root":"/pool/ext/b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e/crypt/zone"},{"zone":{"id":"06dc6619-6251-4543-9a10-da1698af49d5","zone_type":"crucible","addresses":["fd00:1122:3344:114::9"],"dataset":{"id":"06dc6619-6251-4543-9a10-da1698af49d5","name":{"pool_name":"oxp_ee34c530-ce70-4f1a-8c97-d0ebb77ccfc8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::9]:32345"},"services":[{"id":"06dc6619-6251-4543-9a10-da1698af49d5","details":{"type":"crucible","address":"[fd00:1122:3344:114::9]:32345"}}]},"root":"/pool/ext/9e878b1e-bf92-4155-8162-640851c2f5d5/crypt/zone"},{"zone":{"id":"0d796c52-37ca-490d-b42f-dcc22fe5fd6b","zone_type":"crucible","addresses":["fd00:1122:3344:114::c"],"dataset":{"id":"0d796c52-37ca-490d-b42f-dcc22fe5fd6b","name":{"pool_name":"oxp_9ec2b893-d486-4b24-a077-1a297f9eb15f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::c]:32345"},"services":[{"id":"0d796c52-37ca-490d-b42f-dcc22fe5fd6b","details":{"type":"crucible","address":"[fd00:1122:3344:114::c]:32345"}}]},"root":"/pool/ext/9e72c0e2-4895-4791-b606-2f18e432fb69/crypt/zone"},{"zone":{"id":"91d0011f-de44-4823-bc26-a447affa39bc","zone_type":"crucible","addresses":["fd00:1122:3344:114::a"],"dataset":{"id":"91d0011f-de44-4823-bc26-a447affa39bc","name":{"pool_name":"oxp_85e81a14-031d-4a63-a91f-981c64e91f60","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::a]:32345"},"services":[{"id":"91d0011f-de44-4823-bc26-a447affa39bc","details":{"type":"crucible","address":"[fd00:1122:3344:114::a]:32345"}}]},"root":"/pool/ext/b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e/crypt/zone"},{"zone":{"id":"0c44a2f1-559a-459c-9931-e0e7964d41c6","zone_type":"crucible","addresses":["fd00:1122:3344:114::b"],"dataset":{"id":"0c44a2f1-559a-459c-9931-e0e7964d41c6","name":{"pool_name":"oxp_76f09ad5-c96c-4748-bbe4-71afaea7bc5e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::b]:32345"},"services":[{"id":"0c44a2f1-559a-459c-9931-e0e7964d41c6","details":{"type":"crucible","address":"[fd00:1122:3344:114::b]:32345"}}]},"root":"/pool/ext/e87037be-1cdf-4c6e-a8a3-c27b830eaef9/crypt/zone"},{"zone":{"id":"ea363819-96f6-4fb6-a203-f18414f1c60e","zone_type":"crucible","addresses":["fd00:1122:3344:114::4"],"dataset":{"id":"ea363819-96f6-4fb6-a203-f18414f1c60e","name":{"pool_name":"oxp_b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::4]:32345"},"services":[{"id":"ea363819-96f6-4fb6-a203-f18414f1c60e","details":{"type":"crucible","address":"[fd00:1122:3344:114::4]:32345"}}]},"root":"/pool/ext/b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e/crypt/zone"},{"zone":{"id":"21592c39-da6b-4527-842e-edeeceffafa1","zone_type":"crucible","addresses":["fd00:1122:3344:114::6"],"dataset":{"id":"21592c39-da6b-4527-842e-edeeceffafa1","name":{"pool_name":"oxp_9e72c0e2-4895-4791-b606-2f18e432fb69","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::6]:32345"},"services":[{"id":"21592c39-da6b-4527-842e-edeeceffafa1","details":{"type":"crucible","address":"[fd00:1122:3344:114::6]:32345"}}]},"root":"/pool/ext/7aff8429-b65d-4a53-a796-7221ac7581a9/crypt/zone"},{"zone":{"id":"f33b1263-f1b2-43a6-a8aa-5f8570dd4e72","zone_type":"crucible","addresses":["fd00:1122:3344:114::7"],"dataset":{"id":"f33b1263-f1b2-43a6-a8aa-5f8570dd4e72","name":{"pool_name":"oxp_9e878b1e-bf92-4155-8162-640851c2f5d5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::7]:32345"},"services":[{"id":"f33b1263-f1b2-43a6-a8aa-5f8570dd4e72","details":{"type":"crucible","address":"[fd00:1122:3344:114::7]:32345"}}]},"root":"/pool/ext/7f3a760f-a4c0-456f-8a22-2d06ecac1022/crypt/zone"},{"zone":{"id":"6f42b469-5a36-4048-a152-e884f7e8a206","zone_type":"crucible","addresses":["fd00:1122:3344:114::d"],"dataset":{"id":"6f42b469-5a36-4048-a152-e884f7e8a206","name":{"pool_name":"oxp_7aff8429-b65d-4a53-a796-7221ac7581a9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:114::d]:32345"},"services":[{"id":"6f42b469-5a36-4048-a152-e884f7e8a206","details":{"type":"crucible","address":"[fd00:1122:3344:114::d]:32345"}}]},"root":"/pool/ext/9e72c0e2-4895-4791-b606-2f18e432fb69/crypt/zone"},{"zone":{"id":"ad77d594-8f78-4d33-a5e4-59887060178e","zone_type":"ntp","addresses":["fd00:1122:3344:114::e"],"dataset":null,"services":[{"id":"ad77d594-8f78-4d33-a5e4-59887060178e","details":{"type":"internal_ntp","address":"[fd00:1122:3344:114::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/85e81a14-031d-4a63-a91f-981c64e91f60/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled16.json b/sled-agent/tests/old-service-ledgers/rack3-sled16.json deleted file mode 100644 index 3a1cbeb411..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled16.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"dcb9a4ae-2c89-4a74-905b-b7936ff49c19","zone_type":"crucible","addresses":["fd00:1122:3344:11f::9"],"dataset":{"id":"dcb9a4ae-2c89-4a74-905b-b7936ff49c19","name":{"pool_name":"oxp_af509039-d27f-4095-bc9d-cecbc5c606db","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::9]:32345"},"services":[{"id":"dcb9a4ae-2c89-4a74-905b-b7936ff49c19","details":{"type":"crucible","address":"[fd00:1122:3344:11f::9]:32345"}}]},"root":"/pool/ext/44ee0fb4-6034-44e8-b3de-b3a44457ffca/crypt/zone"},{"zone":{"id":"dbd46f71-ec39-4b72-a77d-9d281ccb37e0","zone_type":"crucible","addresses":["fd00:1122:3344:11f::b"],"dataset":{"id":"dbd46f71-ec39-4b72-a77d-9d281ccb37e0","name":{"pool_name":"oxp_44ee0fb4-6034-44e8-b3de-b3a44457ffca","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::b]:32345"},"services":[{"id":"dbd46f71-ec39-4b72-a77d-9d281ccb37e0","details":{"type":"crucible","address":"[fd00:1122:3344:11f::b]:32345"}}]},"root":"/pool/ext/5e32c0a3-1210-402b-91fb-256946eeac2b/crypt/zone"},{"zone":{"id":"a1f30569-a5c6-4a6d-922e-241966aea142","zone_type":"crucible","addresses":["fd00:1122:3344:11f::6"],"dataset":{"id":"a1f30569-a5c6-4a6d-922e-241966aea142","name":{"pool_name":"oxp_d2133e8b-51cc-455e-89d0-5454fd4fe109","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::6]:32345"},"services":[{"id":"a1f30569-a5c6-4a6d-922e-241966aea142","details":{"type":"crucible","address":"[fd00:1122:3344:11f::6]:32345"}}]},"root":"/pool/ext/3f57835b-1469-499a-8757-7cc56acc5d49/crypt/zone"},{"zone":{"id":"a33e25ae-4e41-40f4-843d-3d12f62d8cb6","zone_type":"crucible","addresses":["fd00:1122:3344:11f::8"],"dataset":{"id":"a33e25ae-4e41-40f4-843d-3d12f62d8cb6","name":{"pool_name":"oxp_c8e4a7f4-1ae6-4683-8397-ea53475a53e8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::8]:32345"},"services":[{"id":"a33e25ae-4e41-40f4-843d-3d12f62d8cb6","details":{"type":"crucible","address":"[fd00:1122:3344:11f::8]:32345"}}]},"root":"/pool/ext/5e32c0a3-1210-402b-91fb-256946eeac2b/crypt/zone"},{"zone":{"id":"65ed75c2-2d80-4de5-a6f6-adfa6516c7cf","zone_type":"crucible","addresses":["fd00:1122:3344:11f::c"],"dataset":{"id":"65ed75c2-2d80-4de5-a6f6-adfa6516c7cf","name":{"pool_name":"oxp_3f57835b-1469-499a-8757-7cc56acc5d49","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::c]:32345"},"services":[{"id":"65ed75c2-2d80-4de5-a6f6-adfa6516c7cf","details":{"type":"crucible","address":"[fd00:1122:3344:11f::c]:32345"}}]},"root":"/pool/ext/cd8cd75c-632b-4527-889a-7ca0c080fe2c/crypt/zone"},{"zone":{"id":"bc6ccf18-6b9b-4687-8b70-c7917d972ae0","zone_type":"crucible","addresses":["fd00:1122:3344:11f::a"],"dataset":{"id":"bc6ccf18-6b9b-4687-8b70-c7917d972ae0","name":{"pool_name":"oxp_cd8cd75c-632b-4527-889a-7ca0c080fe2c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::a]:32345"},"services":[{"id":"bc6ccf18-6b9b-4687-8b70-c7917d972ae0","details":{"type":"crucible","address":"[fd00:1122:3344:11f::a]:32345"}}]},"root":"/pool/ext/5e32c0a3-1210-402b-91fb-256946eeac2b/crypt/zone"},{"zone":{"id":"06233bfe-a857-4819-aefe-212af9eeb90f","zone_type":"crucible","addresses":["fd00:1122:3344:11f::5"],"dataset":{"id":"06233bfe-a857-4819-aefe-212af9eeb90f","name":{"pool_name":"oxp_c8a1aaf1-d27c-45fd-9f8d-80ac6bf6865d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::5]:32345"},"services":[{"id":"06233bfe-a857-4819-aefe-212af9eeb90f","details":{"type":"crucible","address":"[fd00:1122:3344:11f::5]:32345"}}]},"root":"/pool/ext/af509039-d27f-4095-bc9d-cecbc5c606db/crypt/zone"},{"zone":{"id":"0bbfef71-9eae-43b6-b5e7-0060ce9269dd","zone_type":"crucible","addresses":["fd00:1122:3344:11f::4"],"dataset":{"id":"0bbfef71-9eae-43b6-b5e7-0060ce9269dd","name":{"pool_name":"oxp_5e32c0a3-1210-402b-91fb-256946eeac2b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::4]:32345"},"services":[{"id":"0bbfef71-9eae-43b6-b5e7-0060ce9269dd","details":{"type":"crucible","address":"[fd00:1122:3344:11f::4]:32345"}}]},"root":"/pool/ext/af509039-d27f-4095-bc9d-cecbc5c606db/crypt/zone"},{"zone":{"id":"550e10ee-24d1-444f-80be-2744dd321e0f","zone_type":"crucible","addresses":["fd00:1122:3344:11f::7"],"dataset":{"id":"550e10ee-24d1-444f-80be-2744dd321e0f","name":{"pool_name":"oxp_f437ce0e-eb45-4be8-b1fe-33ed2656eb01","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11f::7]:32345"},"services":[{"id":"550e10ee-24d1-444f-80be-2744dd321e0f","details":{"type":"crucible","address":"[fd00:1122:3344:11f::7]:32345"}}]},"root":"/pool/ext/44ee0fb4-6034-44e8-b3de-b3a44457ffca/crypt/zone"},{"zone":{"id":"86d768f3-ece2-4956-983f-999bdb23a983","zone_type":"cockroach_db","addresses":["fd00:1122:3344:11f::3"],"dataset":{"id":"86d768f3-ece2-4956-983f-999bdb23a983","name":{"pool_name":"oxp_5e32c0a3-1210-402b-91fb-256946eeac2b","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:11f::3]:32221"},"services":[{"id":"86d768f3-ece2-4956-983f-999bdb23a983","details":{"type":"cockroach_db","address":"[fd00:1122:3344:11f::3]:32221"}}]},"root":"/pool/ext/c8a1aaf1-d27c-45fd-9f8d-80ac6bf6865d/crypt/zone"},{"zone":{"id":"2f358812-f72c-4838-a5ea-7d78d0954be0","zone_type":"ntp","addresses":["fd00:1122:3344:11f::d"],"dataset":null,"services":[{"id":"2f358812-f72c-4838-a5ea-7d78d0954be0","details":{"type":"internal_ntp","address":"[fd00:1122:3344:11f::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/f437ce0e-eb45-4be8-b1fe-33ed2656eb01/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled17.json b/sled-agent/tests/old-service-ledgers/rack3-sled17.json deleted file mode 100644 index 4063fed2e2..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled17.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"525a19a2-d4ac-418d-bdcf-2ce26e7abe70","zone_type":"crucible","addresses":["fd00:1122:3344:107::a"],"dataset":{"id":"525a19a2-d4ac-418d-bdcf-2ce26e7abe70","name":{"pool_name":"oxp_cb774d2f-ff86-4fd7-866b-17a6b10e61f0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::a]:32345"},"services":[{"id":"525a19a2-d4ac-418d-bdcf-2ce26e7abe70","details":{"type":"crucible","address":"[fd00:1122:3344:107::a]:32345"}}]},"root":"/pool/ext/e17b68b5-f50c-4fc3-b55a-80d284c6c32d/crypt/zone"},{"zone":{"id":"7af188e1-6175-4769-9e4f-2ca7a98b76f6","zone_type":"crucible","addresses":["fd00:1122:3344:107::4"],"dataset":{"id":"7af188e1-6175-4769-9e4f-2ca7a98b76f6","name":{"pool_name":"oxp_0cbbcf22-770d-4e75-9148-e6109b129093","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::4]:32345"},"services":[{"id":"7af188e1-6175-4769-9e4f-2ca7a98b76f6","details":{"type":"crucible","address":"[fd00:1122:3344:107::4]:32345"}}]},"root":"/pool/ext/b998e8df-ea69-4bdd-84cb-b7f17075b060/crypt/zone"},{"zone":{"id":"2544540f-6ffc-46c0-84bf-f42a110c02d7","zone_type":"crucible","addresses":["fd00:1122:3344:107::6"],"dataset":{"id":"2544540f-6ffc-46c0-84bf-f42a110c02d7","name":{"pool_name":"oxp_e17b68b5-f50c-4fc3-b55a-80d284c6c32d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::6]:32345"},"services":[{"id":"2544540f-6ffc-46c0-84bf-f42a110c02d7","details":{"type":"crucible","address":"[fd00:1122:3344:107::6]:32345"}}]},"root":"/pool/ext/521fa477-4d83-49a8-a5cf-c267b7f0c409/crypt/zone"},{"zone":{"id":"cfc20f72-cac2-4681-a6d8-e5a0accafbb7","zone_type":"crucible","addresses":["fd00:1122:3344:107::7"],"dataset":{"id":"cfc20f72-cac2-4681-a6d8-e5a0accafbb7","name":{"pool_name":"oxp_b998e8df-ea69-4bdd-84cb-b7f17075b060","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::7]:32345"},"services":[{"id":"cfc20f72-cac2-4681-a6d8-e5a0accafbb7","details":{"type":"crucible","address":"[fd00:1122:3344:107::7]:32345"}}]},"root":"/pool/ext/0cbbcf22-770d-4e75-9148-e6109b129093/crypt/zone"},{"zone":{"id":"e24be791-5773-425e-a3df-e35ca81570c7","zone_type":"crucible","addresses":["fd00:1122:3344:107::9"],"dataset":{"id":"e24be791-5773-425e-a3df-e35ca81570c7","name":{"pool_name":"oxp_7849c221-dc7f-43ac-ac47-bc51864e083b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::9]:32345"},"services":[{"id":"e24be791-5773-425e-a3df-e35ca81570c7","details":{"type":"crucible","address":"[fd00:1122:3344:107::9]:32345"}}]},"root":"/pool/ext/7849c221-dc7f-43ac-ac47-bc51864e083b/crypt/zone"},{"zone":{"id":"170856ee-21cf-4780-8903-175d558bc7cc","zone_type":"crucible","addresses":["fd00:1122:3344:107::3"],"dataset":{"id":"170856ee-21cf-4780-8903-175d558bc7cc","name":{"pool_name":"oxp_618e21e5-77d4-40ba-9f8e-7960e9ad92e2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::3]:32345"},"services":[{"id":"170856ee-21cf-4780-8903-175d558bc7cc","details":{"type":"crucible","address":"[fd00:1122:3344:107::3]:32345"}}]},"root":"/pool/ext/aa7a37fb-2f03-4d5c-916b-db3a4fc269ac/crypt/zone"},{"zone":{"id":"604278ff-525a-4d41-82ff-07aef3174d38","zone_type":"crucible","addresses":["fd00:1122:3344:107::5"],"dataset":{"id":"604278ff-525a-4d41-82ff-07aef3174d38","name":{"pool_name":"oxp_521fa477-4d83-49a8-a5cf-c267b7f0c409","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::5]:32345"},"services":[{"id":"604278ff-525a-4d41-82ff-07aef3174d38","details":{"type":"crucible","address":"[fd00:1122:3344:107::5]:32345"}}]},"root":"/pool/ext/0cbbcf22-770d-4e75-9148-e6109b129093/crypt/zone"},{"zone":{"id":"d0d4fcc0-6ed0-410a-99c7-5daf34014421","zone_type":"crucible","addresses":["fd00:1122:3344:107::b"],"dataset":{"id":"d0d4fcc0-6ed0-410a-99c7-5daf34014421","name":{"pool_name":"oxp_aa7a37fb-2f03-4d5c-916b-db3a4fc269ac","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::b]:32345"},"services":[{"id":"d0d4fcc0-6ed0-410a-99c7-5daf34014421","details":{"type":"crucible","address":"[fd00:1122:3344:107::b]:32345"}}]},"root":"/pool/ext/aa7a37fb-2f03-4d5c-916b-db3a4fc269ac/crypt/zone"},{"zone":{"id":"c935df7b-2629-48ee-bc10-20508301905d","zone_type":"crucible","addresses":["fd00:1122:3344:107::c"],"dataset":{"id":"c935df7b-2629-48ee-bc10-20508301905d","name":{"pool_name":"oxp_793fd018-5fdc-4e54-9c45-f8023fa3ea18","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::c]:32345"},"services":[{"id":"c935df7b-2629-48ee-bc10-20508301905d","details":{"type":"crucible","address":"[fd00:1122:3344:107::c]:32345"}}]},"root":"/pool/ext/7849c221-dc7f-43ac-ac47-bc51864e083b/crypt/zone"},{"zone":{"id":"4ba5f3b6-8be5-4a85-bc57-a5e3b0b867d8","zone_type":"crucible","addresses":["fd00:1122:3344:107::8"],"dataset":{"id":"4ba5f3b6-8be5-4a85-bc57-a5e3b0b867d8","name":{"pool_name":"oxp_e80e7996-c572-481e-8c22-61c16c6e47f4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:107::8]:32345"},"services":[{"id":"4ba5f3b6-8be5-4a85-bc57-a5e3b0b867d8","details":{"type":"crucible","address":"[fd00:1122:3344:107::8]:32345"}}]},"root":"/pool/ext/e17b68b5-f50c-4fc3-b55a-80d284c6c32d/crypt/zone"},{"zone":{"id":"395c9d6e-3bd0-445e-9269-46c3260edb83","zone_type":"ntp","addresses":["fd00:1122:3344:107::d"],"dataset":null,"services":[{"id":"395c9d6e-3bd0-445e-9269-46c3260edb83","details":{"type":"internal_ntp","address":"[fd00:1122:3344:107::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/0cbbcf22-770d-4e75-9148-e6109b129093/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled18.json b/sled-agent/tests/old-service-ledgers/rack3-sled18.json deleted file mode 100644 index f47e912424..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled18.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"c7096dd4-e429-4a6f-9725-041a77ef2513","zone_type":"crucible","addresses":["fd00:1122:3344:11a::6"],"dataset":{"id":"c7096dd4-e429-4a6f-9725-041a77ef2513","name":{"pool_name":"oxp_dcf62af6-c0f9-4eb5-9b23-9424ef8f3d32","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::6]:32345"},"services":[{"id":"c7096dd4-e429-4a6f-9725-041a77ef2513","details":{"type":"crucible","address":"[fd00:1122:3344:11a::6]:32345"}}]},"root":"/pool/ext/b869e463-c8b9-4c12-a6b9-13175b3896dd/crypt/zone"},{"zone":{"id":"09dd367f-b32f-43f3-aa53-11ccec1cd0c9","zone_type":"crucible","addresses":["fd00:1122:3344:11a::9"],"dataset":{"id":"09dd367f-b32f-43f3-aa53-11ccec1cd0c9","name":{"pool_name":"oxp_d7d00317-42c7-4d1e-a04c-85491fb230cd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::9]:32345"},"services":[{"id":"09dd367f-b32f-43f3-aa53-11ccec1cd0c9","details":{"type":"crucible","address":"[fd00:1122:3344:11a::9]:32345"}}]},"root":"/pool/ext/d7d00317-42c7-4d1e-a04c-85491fb230cd/crypt/zone"},{"zone":{"id":"fb2f85f1-05b3-432f-9bb5-63fb27a762b1","zone_type":"crucible","addresses":["fd00:1122:3344:11a::5"],"dataset":{"id":"fb2f85f1-05b3-432f-9bb5-63fb27a762b1","name":{"pool_name":"oxp_db4a9949-68da-4c1c-9a1c-49083eba14fe","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::5]:32345"},"services":[{"id":"fb2f85f1-05b3-432f-9bb5-63fb27a762b1","details":{"type":"crucible","address":"[fd00:1122:3344:11a::5]:32345"}}]},"root":"/pool/ext/db4a9949-68da-4c1c-9a1c-49083eba14fe/crypt/zone"},{"zone":{"id":"5b89425e-69e4-4305-8f33-dc5768a1849e","zone_type":"crucible","addresses":["fd00:1122:3344:11a::a"],"dataset":{"id":"5b89425e-69e4-4305-8f33-dc5768a1849e","name":{"pool_name":"oxp_64a1bad7-d1b1-4e39-a3f3-9b8d73c4709e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::a]:32345"},"services":[{"id":"5b89425e-69e4-4305-8f33-dc5768a1849e","details":{"type":"crucible","address":"[fd00:1122:3344:11a::a]:32345"}}]},"root":"/pool/ext/64a1bad7-d1b1-4e39-a3f3-9b8d73c4709e/crypt/zone"},{"zone":{"id":"a5156db4-273a-4f8b-b8d8-df77062a6c63","zone_type":"crucible","addresses":["fd00:1122:3344:11a::4"],"dataset":{"id":"a5156db4-273a-4f8b-b8d8-df77062a6c63","name":{"pool_name":"oxp_b869e463-c8b9-4c12-a6b9-13175b3896dd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::4]:32345"},"services":[{"id":"a5156db4-273a-4f8b-b8d8-df77062a6c63","details":{"type":"crucible","address":"[fd00:1122:3344:11a::4]:32345"}}]},"root":"/pool/ext/dcf62af6-c0f9-4eb5-9b23-9424ef8f3d32/crypt/zone"},{"zone":{"id":"1f2d2f86-b69b-4130-bb9b-e62ba0cb6802","zone_type":"crucible","addresses":["fd00:1122:3344:11a::b"],"dataset":{"id":"1f2d2f86-b69b-4130-bb9b-e62ba0cb6802","name":{"pool_name":"oxp_153ffee4-5d7a-4786-ad33-d5567b434fe0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::b]:32345"},"services":[{"id":"1f2d2f86-b69b-4130-bb9b-e62ba0cb6802","details":{"type":"crucible","address":"[fd00:1122:3344:11a::b]:32345"}}]},"root":"/pool/ext/174a067d-1c5a-49f7-a29f-1e62ab1c3796/crypt/zone"},{"zone":{"id":"1e249cc9-52e7-4d66-b713-8ace1392e991","zone_type":"crucible","addresses":["fd00:1122:3344:11a::7"],"dataset":{"id":"1e249cc9-52e7-4d66-b713-8ace1392e991","name":{"pool_name":"oxp_04b6215e-9651-4a3c-ba1b-b8a1e67b3d89","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::7]:32345"},"services":[{"id":"1e249cc9-52e7-4d66-b713-8ace1392e991","details":{"type":"crucible","address":"[fd00:1122:3344:11a::7]:32345"}}]},"root":"/pool/ext/db4a9949-68da-4c1c-9a1c-49083eba14fe/crypt/zone"},{"zone":{"id":"eb779538-2b1b-4d1d-8c7e-b15f04db6e53","zone_type":"crucible","addresses":["fd00:1122:3344:11a::3"],"dataset":{"id":"eb779538-2b1b-4d1d-8c7e-b15f04db6e53","name":{"pool_name":"oxp_aacb8524-3562-4f97-a616-9023230d6efa","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::3]:32345"},"services":[{"id":"eb779538-2b1b-4d1d-8c7e-b15f04db6e53","details":{"type":"crucible","address":"[fd00:1122:3344:11a::3]:32345"}}]},"root":"/pool/ext/174a067d-1c5a-49f7-a29f-1e62ab1c3796/crypt/zone"},{"zone":{"id":"b575d52d-be7d-46af-814b-91e6d18f3464","zone_type":"crucible","addresses":["fd00:1122:3344:11a::8"],"dataset":{"id":"b575d52d-be7d-46af-814b-91e6d18f3464","name":{"pool_name":"oxp_174a067d-1c5a-49f7-a29f-1e62ab1c3796","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::8]:32345"},"services":[{"id":"b575d52d-be7d-46af-814b-91e6d18f3464","details":{"type":"crucible","address":"[fd00:1122:3344:11a::8]:32345"}}]},"root":"/pool/ext/64a1bad7-d1b1-4e39-a3f3-9b8d73c4709e/crypt/zone"},{"zone":{"id":"274200bc-eac7-47d7-8a57-4b7be794caba","zone_type":"crucible","addresses":["fd00:1122:3344:11a::c"],"dataset":{"id":"274200bc-eac7-47d7-8a57-4b7be794caba","name":{"pool_name":"oxp_2e7644e4-7d46-42bf-8e7a-9c3f39085b3f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11a::c]:32345"},"services":[{"id":"274200bc-eac7-47d7-8a57-4b7be794caba","details":{"type":"crucible","address":"[fd00:1122:3344:11a::c]:32345"}}]},"root":"/pool/ext/2e7644e4-7d46-42bf-8e7a-9c3f39085b3f/crypt/zone"},{"zone":{"id":"bc20ba3a-df62-4a62-97c2-75b5653f84b4","zone_type":"ntp","addresses":["fd00:1122:3344:11a::d"],"dataset":null,"services":[{"id":"bc20ba3a-df62-4a62-97c2-75b5653f84b4","details":{"type":"internal_ntp","address":"[fd00:1122:3344:11a::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/04b6215e-9651-4a3c-ba1b-b8a1e67b3d89/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled19.json b/sled-agent/tests/old-service-ledgers/rack3-sled19.json deleted file mode 100644 index c450320a73..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled19.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"9c73abb9-edb8-4aa2-835b-c25ebe4466d9","zone_type":"crucible","addresses":["fd00:1122:3344:109::7"],"dataset":{"id":"9c73abb9-edb8-4aa2-835b-c25ebe4466d9","name":{"pool_name":"oxp_b7a3032f-7b8c-4a6a-9fa2-e5773bfdbc94","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::7]:32345"},"services":[{"id":"9c73abb9-edb8-4aa2-835b-c25ebe4466d9","details":{"type":"crucible","address":"[fd00:1122:3344:109::7]:32345"}}]},"root":"/pool/ext/46d21f3d-23be-4361-b5c5-9d0f6ece5b8c/crypt/zone"},{"zone":{"id":"ca576bda-cbdd-4bb9-9d75-ce06d569e926","zone_type":"crucible","addresses":["fd00:1122:3344:109::a"],"dataset":{"id":"ca576bda-cbdd-4bb9-9d75-ce06d569e926","name":{"pool_name":"oxp_863c4bc4-9c7e-453c-99d8-a3d509f49f3e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::a]:32345"},"services":[{"id":"ca576bda-cbdd-4bb9-9d75-ce06d569e926","details":{"type":"crucible","address":"[fd00:1122:3344:109::a]:32345"}}]},"root":"/pool/ext/7e67cb32-0c00-4090-9647-eb7bae75deeb/crypt/zone"},{"zone":{"id":"f010978d-346e-49cd-b265-7607a25685f9","zone_type":"crucible","addresses":["fd00:1122:3344:109::c"],"dataset":{"id":"f010978d-346e-49cd-b265-7607a25685f9","name":{"pool_name":"oxp_9bc1dab8-2d2a-4f92-bdfb-94ebca7881f1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::c]:32345"},"services":[{"id":"f010978d-346e-49cd-b265-7607a25685f9","details":{"type":"crucible","address":"[fd00:1122:3344:109::c]:32345"}}]},"root":"/pool/ext/9bc1dab8-2d2a-4f92-bdfb-94ebca7881f1/crypt/zone"},{"zone":{"id":"daff4162-cc81-4586-a457-91d767b8f1d9","zone_type":"crucible","addresses":["fd00:1122:3344:109::6"],"dataset":{"id":"daff4162-cc81-4586-a457-91d767b8f1d9","name":{"pool_name":"oxp_b9b5b50c-e823-41ae-9585-01b818883521","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::6]:32345"},"services":[{"id":"daff4162-cc81-4586-a457-91d767b8f1d9","details":{"type":"crucible","address":"[fd00:1122:3344:109::6]:32345"}}]},"root":"/pool/ext/de682b18-afaf-4d53-b62e-934f6bd4a1f8/crypt/zone"},{"zone":{"id":"9f300d3d-e698-4cc8-be4c-1f81ac8c927f","zone_type":"crucible","addresses":["fd00:1122:3344:109::d"],"dataset":{"id":"9f300d3d-e698-4cc8-be4c-1f81ac8c927f","name":{"pool_name":"oxp_f1d82c22-ad7d-4cda-9ab0-8f5f496d90ce","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::d]:32345"},"services":[{"id":"9f300d3d-e698-4cc8-be4c-1f81ac8c927f","details":{"type":"crucible","address":"[fd00:1122:3344:109::d]:32345"}}]},"root":"/pool/ext/de682b18-afaf-4d53-b62e-934f6bd4a1f8/crypt/zone"},{"zone":{"id":"8db7c7be-da40-4a1c-9681-4d02606a7eb7","zone_type":"crucible","addresses":["fd00:1122:3344:109::9"],"dataset":{"id":"8db7c7be-da40-4a1c-9681-4d02606a7eb7","name":{"pool_name":"oxp_46d21f3d-23be-4361-b5c5-9d0f6ece5b8c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::9]:32345"},"services":[{"id":"8db7c7be-da40-4a1c-9681-4d02606a7eb7","details":{"type":"crucible","address":"[fd00:1122:3344:109::9]:32345"}}]},"root":"/pool/ext/b7a3032f-7b8c-4a6a-9fa2-e5773bfdbc94/crypt/zone"},{"zone":{"id":"b990911b-805a-4f9d-bd83-e977f5b19a35","zone_type":"crucible","addresses":["fd00:1122:3344:109::4"],"dataset":{"id":"b990911b-805a-4f9d-bd83-e977f5b19a35","name":{"pool_name":"oxp_7e67cb32-0c00-4090-9647-eb7bae75deeb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::4]:32345"},"services":[{"id":"b990911b-805a-4f9d-bd83-e977f5b19a35","details":{"type":"crucible","address":"[fd00:1122:3344:109::4]:32345"}}]},"root":"/pool/ext/de682b18-afaf-4d53-b62e-934f6bd4a1f8/crypt/zone"},{"zone":{"id":"c99392f5-8f30-41ac-9eeb-12d7f4b707f1","zone_type":"crucible","addresses":["fd00:1122:3344:109::b"],"dataset":{"id":"c99392f5-8f30-41ac-9eeb-12d7f4b707f1","name":{"pool_name":"oxp_de682b18-afaf-4d53-b62e-934f6bd4a1f8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::b]:32345"},"services":[{"id":"c99392f5-8f30-41ac-9eeb-12d7f4b707f1","details":{"type":"crucible","address":"[fd00:1122:3344:109::b]:32345"}}]},"root":"/pool/ext/46d21f3d-23be-4361-b5c5-9d0f6ece5b8c/crypt/zone"},{"zone":{"id":"7f6cb339-9eb1-4866-8a4f-383bad25b36f","zone_type":"crucible","addresses":["fd00:1122:3344:109::5"],"dataset":{"id":"7f6cb339-9eb1-4866-8a4f-383bad25b36f","name":{"pool_name":"oxp_458cbfa3-3752-415d-8a3b-fb64e88468e1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::5]:32345"},"services":[{"id":"7f6cb339-9eb1-4866-8a4f-383bad25b36f","details":{"type":"crucible","address":"[fd00:1122:3344:109::5]:32345"}}]},"root":"/pool/ext/b9b5b50c-e823-41ae-9585-01b818883521/crypt/zone"},{"zone":{"id":"11946372-f253-4648-b00c-c7874a7b2888","zone_type":"crucible","addresses":["fd00:1122:3344:109::8"],"dataset":{"id":"11946372-f253-4648-b00c-c7874a7b2888","name":{"pool_name":"oxp_d73332f5-b2a5-46c0-94cf-c5c5712abfe8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:109::8]:32345"},"services":[{"id":"11946372-f253-4648-b00c-c7874a7b2888","details":{"type":"crucible","address":"[fd00:1122:3344:109::8]:32345"}}]},"root":"/pool/ext/b9b5b50c-e823-41ae-9585-01b818883521/crypt/zone"},{"zone":{"id":"58ece9e1-387f-4d2f-a42f-69cd34f9f380","zone_type":"cockroach_db","addresses":["fd00:1122:3344:109::3"],"dataset":{"id":"58ece9e1-387f-4d2f-a42f-69cd34f9f380","name":{"pool_name":"oxp_7e67cb32-0c00-4090-9647-eb7bae75deeb","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:109::3]:32221"},"services":[{"id":"58ece9e1-387f-4d2f-a42f-69cd34f9f380","details":{"type":"cockroach_db","address":"[fd00:1122:3344:109::3]:32221"}}]},"root":"/pool/ext/b9b5b50c-e823-41ae-9585-01b818883521/crypt/zone"},{"zone":{"id":"f016a25a-deb5-4f20-bdb0-2425c00d41a6","zone_type":"ntp","addresses":["fd00:1122:3344:109::e"],"dataset":null,"services":[{"id":"f016a25a-deb5-4f20-bdb0-2425c00d41a6","details":{"type":"internal_ntp","address":"[fd00:1122:3344:109::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/b9b5b50c-e823-41ae-9585-01b818883521/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled2.json b/sled-agent/tests/old-service-ledgers/rack3-sled2.json deleted file mode 100644 index 6c420c989d..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled2.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"dd799dd4-03f9-451d-85e2-844155753a03","zone_type":"crucible","addresses":["fd00:1122:3344:10a::7"],"dataset":{"id":"dd799dd4-03f9-451d-85e2-844155753a03","name":{"pool_name":"oxp_7dcf3acc-bde9-4306-bb46-4c6a6cbbb7ba","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::7]:32345"},"services":[{"id":"dd799dd4-03f9-451d-85e2-844155753a03","details":{"type":"crucible","address":"[fd00:1122:3344:10a::7]:32345"}}]},"root":"/pool/ext/7dcf3acc-bde9-4306-bb46-4c6a6cbbb7ba/crypt/zone"},{"zone":{"id":"dbf9346d-b46d-4402-bb44-92ce20fb5290","zone_type":"crucible","addresses":["fd00:1122:3344:10a::9"],"dataset":{"id":"dbf9346d-b46d-4402-bb44-92ce20fb5290","name":{"pool_name":"oxp_9275d50f-da2c-4f84-9775-598a364309ad","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::9]:32345"},"services":[{"id":"dbf9346d-b46d-4402-bb44-92ce20fb5290","details":{"type":"crucible","address":"[fd00:1122:3344:10a::9]:32345"}}]},"root":"/pool/ext/d83e36ef-dd7a-4cc2-be19-379b1114c031/crypt/zone"},{"zone":{"id":"9a55ebdd-eeef-4954-b0a1-e32b04837f14","zone_type":"crucible","addresses":["fd00:1122:3344:10a::4"],"dataset":{"id":"9a55ebdd-eeef-4954-b0a1-e32b04837f14","name":{"pool_name":"oxp_7f30f77e-5998-4676-a226-b433b5940e77","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::4]:32345"},"services":[{"id":"9a55ebdd-eeef-4954-b0a1-e32b04837f14","details":{"type":"crucible","address":"[fd00:1122:3344:10a::4]:32345"}}]},"root":"/pool/ext/9275d50f-da2c-4f84-9775-598a364309ad/crypt/zone"},{"zone":{"id":"bc2935f8-e4fa-4015-968e-f90985533a6a","zone_type":"crucible","addresses":["fd00:1122:3344:10a::6"],"dataset":{"id":"bc2935f8-e4fa-4015-968e-f90985533a6a","name":{"pool_name":"oxp_022c9d58-e91f-480d-bda6-0cf32ce3b1f5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::6]:32345"},"services":[{"id":"bc2935f8-e4fa-4015-968e-f90985533a6a","details":{"type":"crucible","address":"[fd00:1122:3344:10a::6]:32345"}}]},"root":"/pool/ext/c395dcc3-6ece-4b3f-b143-e111a54ef7da/crypt/zone"},{"zone":{"id":"63f8c861-fa1d-4121-92d9-7efa5ef7f5a0","zone_type":"crucible","addresses":["fd00:1122:3344:10a::a"],"dataset":{"id":"63f8c861-fa1d-4121-92d9-7efa5ef7f5a0","name":{"pool_name":"oxp_3c805784-f403-4d01-9eb0-4f77d0821980","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::a]:32345"},"services":[{"id":"63f8c861-fa1d-4121-92d9-7efa5ef7f5a0","details":{"type":"crucible","address":"[fd00:1122:3344:10a::a]:32345"}}]},"root":"/pool/ext/9275d50f-da2c-4f84-9775-598a364309ad/crypt/zone"},{"zone":{"id":"4996dcf9-78de-4f69-94fa-c09cc86a8d3c","zone_type":"crucible","addresses":["fd00:1122:3344:10a::b"],"dataset":{"id":"4996dcf9-78de-4f69-94fa-c09cc86a8d3c","name":{"pool_name":"oxp_f9fe9ce6-be0d-4974-bc30-78a8f1330496","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::b]:32345"},"services":[{"id":"4996dcf9-78de-4f69-94fa-c09cc86a8d3c","details":{"type":"crucible","address":"[fd00:1122:3344:10a::b]:32345"}}]},"root":"/pool/ext/9275d50f-da2c-4f84-9775-598a364309ad/crypt/zone"},{"zone":{"id":"36b9a4bf-7b30-4fe7-903d-3b722c79fa86","zone_type":"crucible","addresses":["fd00:1122:3344:10a::c"],"dataset":{"id":"36b9a4bf-7b30-4fe7-903d-3b722c79fa86","name":{"pool_name":"oxp_cb1052e0-4c70-4d37-b979-dd55e6a25f08","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::c]:32345"},"services":[{"id":"36b9a4bf-7b30-4fe7-903d-3b722c79fa86","details":{"type":"crucible","address":"[fd00:1122:3344:10a::c]:32345"}}]},"root":"/pool/ext/3c805784-f403-4d01-9eb0-4f77d0821980/crypt/zone"},{"zone":{"id":"a109a902-6a27-41b6-a881-c353e28e5389","zone_type":"crucible","addresses":["fd00:1122:3344:10a::8"],"dataset":{"id":"a109a902-6a27-41b6-a881-c353e28e5389","name":{"pool_name":"oxp_d83e36ef-dd7a-4cc2-be19-379b1114c031","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::8]:32345"},"services":[{"id":"a109a902-6a27-41b6-a881-c353e28e5389","details":{"type":"crucible","address":"[fd00:1122:3344:10a::8]:32345"}}]},"root":"/pool/ext/d83e36ef-dd7a-4cc2-be19-379b1114c031/crypt/zone"},{"zone":{"id":"d2a9a0bc-ea12-44e3-ac4a-904c76120d11","zone_type":"crucible","addresses":["fd00:1122:3344:10a::3"],"dataset":{"id":"d2a9a0bc-ea12-44e3-ac4a-904c76120d11","name":{"pool_name":"oxp_c395dcc3-6ece-4b3f-b143-e111a54ef7da","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::3]:32345"},"services":[{"id":"d2a9a0bc-ea12-44e3-ac4a-904c76120d11","details":{"type":"crucible","address":"[fd00:1122:3344:10a::3]:32345"}}]},"root":"/pool/ext/9898a289-2f0d-43a6-b053-850f6e784e9a/crypt/zone"},{"zone":{"id":"b3c3e53b-d9ec-4dd8-bd2c-bd811319aa44","zone_type":"crucible","addresses":["fd00:1122:3344:10a::5"],"dataset":{"id":"b3c3e53b-d9ec-4dd8-bd2c-bd811319aa44","name":{"pool_name":"oxp_9898a289-2f0d-43a6-b053-850f6e784e9a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10a::5]:32345"},"services":[{"id":"b3c3e53b-d9ec-4dd8-bd2c-bd811319aa44","details":{"type":"crucible","address":"[fd00:1122:3344:10a::5]:32345"}}]},"root":"/pool/ext/9275d50f-da2c-4f84-9775-598a364309ad/crypt/zone"},{"zone":{"id":"7b445d3b-fd25-4538-ac3f-f439c66d1223","zone_type":"ntp","addresses":["fd00:1122:3344:10a::d"],"dataset":null,"services":[{"id":"7b445d3b-fd25-4538-ac3f-f439c66d1223","details":{"type":"internal_ntp","address":"[fd00:1122:3344:10a::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/f9fe9ce6-be0d-4974-bc30-78a8f1330496/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled20.json b/sled-agent/tests/old-service-ledgers/rack3-sled20.json deleted file mode 100644 index 20c9d60624..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled20.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"4b49e669-264d-4bfb-8ab1-555b520b679c","zone_type":"crucible","addresses":["fd00:1122:3344:108::c"],"dataset":{"id":"4b49e669-264d-4bfb-8ab1-555b520b679c","name":{"pool_name":"oxp_799a1c86-9e1a-4626-91e2-a19f7ff5356e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::c]:32345"},"services":[{"id":"4b49e669-264d-4bfb-8ab1-555b520b679c","details":{"type":"crucible","address":"[fd00:1122:3344:108::c]:32345"}}]},"root":"/pool/ext/d2478613-b7c9-4bd3-856f-1fe8e9c903c2/crypt/zone"},{"zone":{"id":"d802baae-9c3f-437a-85fe-cd72653b6db1","zone_type":"crucible","addresses":["fd00:1122:3344:108::5"],"dataset":{"id":"d802baae-9c3f-437a-85fe-cd72653b6db1","name":{"pool_name":"oxp_d2478613-b7c9-4bd3-856f-1fe8e9c903c2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::5]:32345"},"services":[{"id":"d802baae-9c3f-437a-85fe-cd72653b6db1","details":{"type":"crucible","address":"[fd00:1122:3344:108::5]:32345"}}]},"root":"/pool/ext/116f216c-e151-410f-82bf-8913904cf7b4/crypt/zone"},{"zone":{"id":"e5f69e60-3421-49a4-8c1d-2db8cbb6a5e9","zone_type":"crucible","addresses":["fd00:1122:3344:108::b"],"dataset":{"id":"e5f69e60-3421-49a4-8c1d-2db8cbb6a5e9","name":{"pool_name":"oxp_116f216c-e151-410f-82bf-8913904cf7b4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::b]:32345"},"services":[{"id":"e5f69e60-3421-49a4-8c1d-2db8cbb6a5e9","details":{"type":"crucible","address":"[fd00:1122:3344:108::b]:32345"}}]},"root":"/pool/ext/eea15142-4635-4e40-b0b4-b0c4f13eca3c/crypt/zone"},{"zone":{"id":"3e598962-ef8c-4cb6-bdfe-ec8563939d6a","zone_type":"crucible","addresses":["fd00:1122:3344:108::4"],"dataset":{"id":"3e598962-ef8c-4cb6-bdfe-ec8563939d6a","name":{"pool_name":"oxp_ababce44-01d1-4c50-b389-f60464c5dde9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::4]:32345"},"services":[{"id":"3e598962-ef8c-4cb6-bdfe-ec8563939d6a","details":{"type":"crucible","address":"[fd00:1122:3344:108::4]:32345"}}]},"root":"/pool/ext/ababce44-01d1-4c50-b389-f60464c5dde9/crypt/zone"},{"zone":{"id":"25355c9f-cc2b-4b24-8eaa-65190f8936a8","zone_type":"crucible","addresses":["fd00:1122:3344:108::d"],"dataset":{"id":"25355c9f-cc2b-4b24-8eaa-65190f8936a8","name":{"pool_name":"oxp_fed46d41-136d-4462-8782-359014efba59","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::d]:32345"},"services":[{"id":"25355c9f-cc2b-4b24-8eaa-65190f8936a8","details":{"type":"crucible","address":"[fd00:1122:3344:108::d]:32345"}}]},"root":"/pool/ext/eea15142-4635-4e40-b0b4-b0c4f13eca3c/crypt/zone"},{"zone":{"id":"efb2f16c-ebad-4192-b575-dcb4d9b1d5cd","zone_type":"crucible","addresses":["fd00:1122:3344:108::a"],"dataset":{"id":"efb2f16c-ebad-4192-b575-dcb4d9b1d5cd","name":{"pool_name":"oxp_bf509067-0165-456d-98ae-72c86378e626","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::a]:32345"},"services":[{"id":"efb2f16c-ebad-4192-b575-dcb4d9b1d5cd","details":{"type":"crucible","address":"[fd00:1122:3344:108::a]:32345"}}]},"root":"/pool/ext/95220093-e3b8-4f7f-9f5a-cb32cb75180a/crypt/zone"},{"zone":{"id":"89191f0d-4e0b-47fa-9a9e-fbe2a6db1385","zone_type":"crucible","addresses":["fd00:1122:3344:108::8"],"dataset":{"id":"89191f0d-4e0b-47fa-9a9e-fbe2a6db1385","name":{"pool_name":"oxp_eea15142-4635-4e40-b0b4-b0c4f13eca3c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::8]:32345"},"services":[{"id":"89191f0d-4e0b-47fa-9a9e-fbe2a6db1385","details":{"type":"crucible","address":"[fd00:1122:3344:108::8]:32345"}}]},"root":"/pool/ext/eea15142-4635-4e40-b0b4-b0c4f13eca3c/crypt/zone"},{"zone":{"id":"e4589324-c528-49c7-9141-35e0a7af6947","zone_type":"crucible","addresses":["fd00:1122:3344:108::6"],"dataset":{"id":"e4589324-c528-49c7-9141-35e0a7af6947","name":{"pool_name":"oxp_95220093-e3b8-4f7f-9f5a-cb32cb75180a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::6]:32345"},"services":[{"id":"e4589324-c528-49c7-9141-35e0a7af6947","details":{"type":"crucible","address":"[fd00:1122:3344:108::6]:32345"}}]},"root":"/pool/ext/ababce44-01d1-4c50-b389-f60464c5dde9/crypt/zone"},{"zone":{"id":"95ebe94d-0e68-421d-9260-c30bd7fe4bd6","zone_type":"nexus","addresses":["fd00:1122:3344:108::3"],"dataset":null,"services":[{"id":"95ebe94d-0e68-421d-9260-c30bd7fe4bd6","details":{"type":"nexus","internal_address":"[fd00:1122:3344:108::3]:12221","external_ip":"45.154.216.35","nic":{"id":"301aa595-f072-4da3-a533-99647b44a66a","kind":{"type":"service","id":"95ebe94d-0e68-421d-9260-c30bd7fe4bd6"},"name":"nexus-95ebe94d-0e68-421d-9260-c30bd7fe4bd6","ip":"172.30.2.5","mac":"A8:40:25:FF:F1:30","subnet":"172.30.2.0/24","vni":100,"primary":true,"slot":0},"external_tls":true,"external_dns_servers":["1.1.1.1","8.8.8.8"]}}]},"root":"/pool/ext/eea15142-4635-4e40-b0b4-b0c4f13eca3c/crypt/zone"},{"zone":{"id":"4b7a7052-f8e8-4196-8d6b-315943986ce6","zone_type":"crucible","addresses":["fd00:1122:3344:108::7"],"dataset":{"id":"4b7a7052-f8e8-4196-8d6b-315943986ce6","name":{"pool_name":"oxp_a549421c-2f12-45cc-b691-202f0a9bfa8b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::7]:32345"},"services":[{"id":"4b7a7052-f8e8-4196-8d6b-315943986ce6","details":{"type":"crucible","address":"[fd00:1122:3344:108::7]:32345"}}]},"root":"/pool/ext/bf509067-0165-456d-98ae-72c86378e626/crypt/zone"},{"zone":{"id":"71b8ff53-c781-47bb-8ddc-2c7129680542","zone_type":"crucible","addresses":["fd00:1122:3344:108::9"],"dataset":{"id":"71b8ff53-c781-47bb-8ddc-2c7129680542","name":{"pool_name":"oxp_9d19f891-a3d9-4c6e-b1e1-6b0b085a9440","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:108::9]:32345"},"services":[{"id":"71b8ff53-c781-47bb-8ddc-2c7129680542","details":{"type":"crucible","address":"[fd00:1122:3344:108::9]:32345"}}]},"root":"/pool/ext/fed46d41-136d-4462-8782-359014efba59/crypt/zone"},{"zone":{"id":"eaf7bf77-f4c2-4016-9909-4b88a27e9d9a","zone_type":"ntp","addresses":["fd00:1122:3344:108::e"],"dataset":null,"services":[{"id":"eaf7bf77-f4c2-4016-9909-4b88a27e9d9a","details":{"type":"internal_ntp","address":"[fd00:1122:3344:108::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/ababce44-01d1-4c50-b389-f60464c5dde9/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled21.json b/sled-agent/tests/old-service-ledgers/rack3-sled21.json deleted file mode 100644 index 4f69e01c7f..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled21.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"a91e4af3-5d18-4b08-8cb6-0583db8f8842","zone_type":"crucible","addresses":["fd00:1122:3344:117::a"],"dataset":{"id":"a91e4af3-5d18-4b08-8cb6-0583db8f8842","name":{"pool_name":"oxp_4b2896b8-5f0e-42fb-a474-658b28421e65","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::a]:32345"},"services":[{"id":"a91e4af3-5d18-4b08-8cb6-0583db8f8842","details":{"type":"crucible","address":"[fd00:1122:3344:117::a]:32345"}}]},"root":"/pool/ext/23393ed9-acee-4686-861f-7fc825af1249/crypt/zone"},{"zone":{"id":"1ce74512-ce3a-4125-95f1-12c86e0275d5","zone_type":"crucible","addresses":["fd00:1122:3344:117::8"],"dataset":{"id":"1ce74512-ce3a-4125-95f1-12c86e0275d5","name":{"pool_name":"oxp_46ece76f-ef00-4dd0-9f73-326c63959470","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::8]:32345"},"services":[{"id":"1ce74512-ce3a-4125-95f1-12c86e0275d5","details":{"type":"crucible","address":"[fd00:1122:3344:117::8]:32345"}}]},"root":"/pool/ext/1bd5955e-14a9-463f-adeb-f12bcb45a6c1/crypt/zone"},{"zone":{"id":"fef5d35f-9622-4dee-8635-d26e9f7f6869","zone_type":"crucible","addresses":["fd00:1122:3344:117::4"],"dataset":{"id":"fef5d35f-9622-4dee-8635-d26e9f7f6869","name":{"pool_name":"oxp_e4d7c2e8-016b-4617-afb5-38a2d9c1b508","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::4]:32345"},"services":[{"id":"fef5d35f-9622-4dee-8635-d26e9f7f6869","details":{"type":"crucible","address":"[fd00:1122:3344:117::4]:32345"}}]},"root":"/pool/ext/e372bba3-ef60-466f-b819-a3d5b9acbe77/crypt/zone"},{"zone":{"id":"4f024a31-cd38-4219-8381-9f1af70d1d54","zone_type":"crucible","addresses":["fd00:1122:3344:117::c"],"dataset":{"id":"4f024a31-cd38-4219-8381-9f1af70d1d54","name":{"pool_name":"oxp_7cb2a3c2-9d33-4c6a-af57-669f251cf4cf","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::c]:32345"},"services":[{"id":"4f024a31-cd38-4219-8381-9f1af70d1d54","details":{"type":"crucible","address":"[fd00:1122:3344:117::c]:32345"}}]},"root":"/pool/ext/cfbd185d-e185-4aaa-a598-9216124ceec4/crypt/zone"},{"zone":{"id":"d00e1d0b-e12f-420a-a4df-21e4cac176f6","zone_type":"crucible","addresses":["fd00:1122:3344:117::b"],"dataset":{"id":"d00e1d0b-e12f-420a-a4df-21e4cac176f6","name":{"pool_name":"oxp_e372bba3-ef60-466f-b819-a3d5b9acbe77","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::b]:32345"},"services":[{"id":"d00e1d0b-e12f-420a-a4df-21e4cac176f6","details":{"type":"crucible","address":"[fd00:1122:3344:117::b]:32345"}}]},"root":"/pool/ext/cfbd185d-e185-4aaa-a598-9216124ceec4/crypt/zone"},{"zone":{"id":"1598058a-6064-449e-b39c-1e3d345ed793","zone_type":"crucible","addresses":["fd00:1122:3344:117::5"],"dataset":{"id":"1598058a-6064-449e-b39c-1e3d345ed793","name":{"pool_name":"oxp_022a8d67-1e00-49f3-81ed-a0a1bc187cfa","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::5]:32345"},"services":[{"id":"1598058a-6064-449e-b39c-1e3d345ed793","details":{"type":"crucible","address":"[fd00:1122:3344:117::5]:32345"}}]},"root":"/pool/ext/022a8d67-1e00-49f3-81ed-a0a1bc187cfa/crypt/zone"},{"zone":{"id":"c723c4b8-3031-4b25-8c16-fe08bc0b5f00","zone_type":"crucible","addresses":["fd00:1122:3344:117::7"],"dataset":{"id":"c723c4b8-3031-4b25-8c16-fe08bc0b5f00","name":{"pool_name":"oxp_23393ed9-acee-4686-861f-7fc825af1249","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::7]:32345"},"services":[{"id":"c723c4b8-3031-4b25-8c16-fe08bc0b5f00","details":{"type":"crucible","address":"[fd00:1122:3344:117::7]:32345"}}]},"root":"/pool/ext/1bd5955e-14a9-463f-adeb-f12bcb45a6c1/crypt/zone"},{"zone":{"id":"7751b307-888f-46c8-8787-75d2f3fdaef3","zone_type":"crucible","addresses":["fd00:1122:3344:117::9"],"dataset":{"id":"7751b307-888f-46c8-8787-75d2f3fdaef3","name":{"pool_name":"oxp_e54e53d4-f68f-4b19-b8c1-9d5ab42e51c1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::9]:32345"},"services":[{"id":"7751b307-888f-46c8-8787-75d2f3fdaef3","details":{"type":"crucible","address":"[fd00:1122:3344:117::9]:32345"}}]},"root":"/pool/ext/e372bba3-ef60-466f-b819-a3d5b9acbe77/crypt/zone"},{"zone":{"id":"89413ff1-d5de-4931-8389-e84e7ea321af","zone_type":"crucible","addresses":["fd00:1122:3344:117::6"],"dataset":{"id":"89413ff1-d5de-4931-8389-e84e7ea321af","name":{"pool_name":"oxp_1bd5955e-14a9-463f-adeb-f12bcb45a6c1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::6]:32345"},"services":[{"id":"89413ff1-d5de-4931-8389-e84e7ea321af","details":{"type":"crucible","address":"[fd00:1122:3344:117::6]:32345"}}]},"root":"/pool/ext/1bd5955e-14a9-463f-adeb-f12bcb45a6c1/crypt/zone"},{"zone":{"id":"287b0b24-72aa-41b5-a597-8523d84225ef","zone_type":"crucible","addresses":["fd00:1122:3344:117::3"],"dataset":{"id":"287b0b24-72aa-41b5-a597-8523d84225ef","name":{"pool_name":"oxp_cfbd185d-e185-4aaa-a598-9216124ceec4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:117::3]:32345"},"services":[{"id":"287b0b24-72aa-41b5-a597-8523d84225ef","details":{"type":"crucible","address":"[fd00:1122:3344:117::3]:32345"}}]},"root":"/pool/ext/cfbd185d-e185-4aaa-a598-9216124ceec4/crypt/zone"},{"zone":{"id":"4728253e-c534-4a5b-b707-c64ac9a8eb8c","zone_type":"ntp","addresses":["fd00:1122:3344:117::d"],"dataset":null,"services":[{"id":"4728253e-c534-4a5b-b707-c64ac9a8eb8c","details":{"type":"internal_ntp","address":"[fd00:1122:3344:117::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/cfbd185d-e185-4aaa-a598-9216124ceec4/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled22.json b/sled-agent/tests/old-service-ledgers/rack3-sled22.json deleted file mode 100644 index dc98c0390c..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled22.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"49f20cd1-a8a3-4fa8-9209-59da60cd8f9b","zone_type":"crucible","addresses":["fd00:1122:3344:103::5"],"dataset":{"id":"49f20cd1-a8a3-4fa8-9209-59da60cd8f9b","name":{"pool_name":"oxp_13a9ef4a-f33a-4781-8f83-712c07a79b1f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::5]:32345"},"services":[{"id":"49f20cd1-a8a3-4fa8-9209-59da60cd8f9b","details":{"type":"crucible","address":"[fd00:1122:3344:103::5]:32345"}}]},"root":"/pool/ext/711eff4e-736c-478e-83aa-ae86f5efbf1d/crypt/zone"},{"zone":{"id":"896fd564-f94e-496b-9fcf-ddfbfcfac9f7","zone_type":"crucible","addresses":["fd00:1122:3344:103::c"],"dataset":{"id":"896fd564-f94e-496b-9fcf-ddfbfcfac9f7","name":{"pool_name":"oxp_0944c0a2-0fb7-4f51-bced-52cc257cd2f6","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::c]:32345"},"services":[{"id":"896fd564-f94e-496b-9fcf-ddfbfcfac9f7","details":{"type":"crucible","address":"[fd00:1122:3344:103::c]:32345"}}]},"root":"/pool/ext/bc54d8c5-955d-429d-84e0-a20a4e5e27a3/crypt/zone"},{"zone":{"id":"911fb8b3-05c2-4af7-8974-6c74a61d94ad","zone_type":"crucible","addresses":["fd00:1122:3344:103::9"],"dataset":{"id":"911fb8b3-05c2-4af7-8974-6c74a61d94ad","name":{"pool_name":"oxp_29f59fce-a867-4571-9d2e-b03fa5c13510","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::9]:32345"},"services":[{"id":"911fb8b3-05c2-4af7-8974-6c74a61d94ad","details":{"type":"crucible","address":"[fd00:1122:3344:103::9]:32345"}}]},"root":"/pool/ext/711eff4e-736c-478e-83aa-ae86f5efbf1d/crypt/zone"},{"zone":{"id":"682b34db-0b06-4770-a8fe-74437cf184d6","zone_type":"crucible","addresses":["fd00:1122:3344:103::6"],"dataset":{"id":"682b34db-0b06-4770-a8fe-74437cf184d6","name":{"pool_name":"oxp_094d11d2-8049-4138-bcf4-562f5f8e77c0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::6]:32345"},"services":[{"id":"682b34db-0b06-4770-a8fe-74437cf184d6","details":{"type":"crucible","address":"[fd00:1122:3344:103::6]:32345"}}]},"root":"/pool/ext/0944c0a2-0fb7-4f51-bced-52cc257cd2f6/crypt/zone"},{"zone":{"id":"d8d20365-ecd3-4fd5-9495-c0670e3bd5d9","zone_type":"crucible","addresses":["fd00:1122:3344:103::a"],"dataset":{"id":"d8d20365-ecd3-4fd5-9495-c0670e3bd5d9","name":{"pool_name":"oxp_fb97ff7b-0225-400c-a137-3b38a786c0a0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::a]:32345"},"services":[{"id":"d8d20365-ecd3-4fd5-9495-c0670e3bd5d9","details":{"type":"crucible","address":"[fd00:1122:3344:103::a]:32345"}}]},"root":"/pool/ext/094d11d2-8049-4138-bcf4-562f5f8e77c0/crypt/zone"},{"zone":{"id":"673620b6-44d9-4310-8e17-3024ac84e708","zone_type":"crucible","addresses":["fd00:1122:3344:103::7"],"dataset":{"id":"673620b6-44d9-4310-8e17-3024ac84e708","name":{"pool_name":"oxp_711eff4e-736c-478e-83aa-ae86f5efbf1d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::7]:32345"},"services":[{"id":"673620b6-44d9-4310-8e17-3024ac84e708","details":{"type":"crucible","address":"[fd00:1122:3344:103::7]:32345"}}]},"root":"/pool/ext/fb97ff7b-0225-400c-a137-3b38a786c0a0/crypt/zone"},{"zone":{"id":"bf6dfc04-4d4c-41b6-a011-40ffc3bc5080","zone_type":"crucible","addresses":["fd00:1122:3344:103::8"],"dataset":{"id":"bf6dfc04-4d4c-41b6-a011-40ffc3bc5080","name":{"pool_name":"oxp_f815f1b6-48ef-436d-8768-eb08227e2386","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::8]:32345"},"services":[{"id":"bf6dfc04-4d4c-41b6-a011-40ffc3bc5080","details":{"type":"crucible","address":"[fd00:1122:3344:103::8]:32345"}}]},"root":"/pool/ext/13a9ef4a-f33a-4781-8f83-712c07a79b1f/crypt/zone"},{"zone":{"id":"ac8a82a8-fb6f-4635-a9a9-d98617eab390","zone_type":"crucible","addresses":["fd00:1122:3344:103::3"],"dataset":{"id":"ac8a82a8-fb6f-4635-a9a9-d98617eab390","name":{"pool_name":"oxp_97d6c860-4e2f-496e-974b-2e293fee6af9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::3]:32345"},"services":[{"id":"ac8a82a8-fb6f-4635-a9a9-d98617eab390","details":{"type":"crucible","address":"[fd00:1122:3344:103::3]:32345"}}]},"root":"/pool/ext/0944c0a2-0fb7-4f51-bced-52cc257cd2f6/crypt/zone"},{"zone":{"id":"4ed66558-4815-4b85-9b94-9edf3ee69ead","zone_type":"crucible","addresses":["fd00:1122:3344:103::4"],"dataset":{"id":"4ed66558-4815-4b85-9b94-9edf3ee69ead","name":{"pool_name":"oxp_bc54d8c5-955d-429d-84e0-a20a4e5e27a3","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::4]:32345"},"services":[{"id":"4ed66558-4815-4b85-9b94-9edf3ee69ead","details":{"type":"crucible","address":"[fd00:1122:3344:103::4]:32345"}}]},"root":"/pool/ext/13a9ef4a-f33a-4781-8f83-712c07a79b1f/crypt/zone"},{"zone":{"id":"8a71c6ee-b08d-4c3d-b13c-c9cebc4c328a","zone_type":"crucible","addresses":["fd00:1122:3344:103::b"],"dataset":{"id":"8a71c6ee-b08d-4c3d-b13c-c9cebc4c328a","name":{"pool_name":"oxp_2bdfa429-09bd-4fa1-aa20-eea99f0d2b85","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:103::b]:32345"},"services":[{"id":"8a71c6ee-b08d-4c3d-b13c-c9cebc4c328a","details":{"type":"crucible","address":"[fd00:1122:3344:103::b]:32345"}}]},"root":"/pool/ext/29f59fce-a867-4571-9d2e-b03fa5c13510/crypt/zone"},{"zone":{"id":"7e6b8962-7a1e-4d7b-b7ea-49e64a51d98d","zone_type":"ntp","addresses":["fd00:1122:3344:103::d"],"dataset":null,"services":[{"id":"7e6b8962-7a1e-4d7b-b7ea-49e64a51d98d","details":{"type":"internal_ntp","address":"[fd00:1122:3344:103::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/2bdfa429-09bd-4fa1-aa20-eea99f0d2b85/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled23.json b/sled-agent/tests/old-service-ledgers/rack3-sled23.json deleted file mode 100644 index ade2144287..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled23.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"6b7e931d-4b91-4dc6-9a7b-4c19ac669e5d","zone_type":"crucible","addresses":["fd00:1122:3344:105::4"],"dataset":{"id":"6b7e931d-4b91-4dc6-9a7b-4c19ac669e5d","name":{"pool_name":"oxp_24dab7f5-164a-47f3-a878-f32ab1e68cce","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::4]:32345"},"services":[{"id":"6b7e931d-4b91-4dc6-9a7b-4c19ac669e5d","details":{"type":"crucible","address":"[fd00:1122:3344:105::4]:32345"}}]},"root":"/pool/ext/ad493851-2d11-4c2d-8d75-989579d9616a/crypt/zone"},{"zone":{"id":"6c58e7aa-71e1-4868-9d4b-e12c7ef40303","zone_type":"crucible","addresses":["fd00:1122:3344:105::a"],"dataset":{"id":"6c58e7aa-71e1-4868-9d4b-e12c7ef40303","name":{"pool_name":"oxp_d664c9e8-bc81-4225-a618-a8ae2d057186","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::a]:32345"},"services":[{"id":"6c58e7aa-71e1-4868-9d4b-e12c7ef40303","details":{"type":"crucible","address":"[fd00:1122:3344:105::a]:32345"}}]},"root":"/pool/ext/ad493851-2d11-4c2d-8d75-989579d9616a/crypt/zone"},{"zone":{"id":"51c6dc8d-b1a4-454a-9b19-01e45eb0b599","zone_type":"crucible","addresses":["fd00:1122:3344:105::d"],"dataset":{"id":"51c6dc8d-b1a4-454a-9b19-01e45eb0b599","name":{"pool_name":"oxp_f5f85537-eb25-4d0e-8e94-b775c41abd73","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::d]:32345"},"services":[{"id":"51c6dc8d-b1a4-454a-9b19-01e45eb0b599","details":{"type":"crucible","address":"[fd00:1122:3344:105::d]:32345"}}]},"root":"/pool/ext/4f1eafe9-b28d-49d3-83e2-ceac8721d6b5/crypt/zone"},{"zone":{"id":"8cbffa61-0bd0-4ad2-bd7d-30fe0dd57469","zone_type":"crucible","addresses":["fd00:1122:3344:105::9"],"dataset":{"id":"8cbffa61-0bd0-4ad2-bd7d-30fe0dd57469","name":{"pool_name":"oxp_88abca38-3f61-4d4b-80a1-4ea3e4827f84","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::9]:32345"},"services":[{"id":"8cbffa61-0bd0-4ad2-bd7d-30fe0dd57469","details":{"type":"crucible","address":"[fd00:1122:3344:105::9]:32345"}}]},"root":"/pool/ext/88abca38-3f61-4d4b-80a1-4ea3e4827f84/crypt/zone"},{"zone":{"id":"2177f37f-2ac9-4e66-bf74-a10bd91f4d33","zone_type":"crucible","addresses":["fd00:1122:3344:105::6"],"dataset":{"id":"2177f37f-2ac9-4e66-bf74-a10bd91f4d33","name":{"pool_name":"oxp_59e20871-4670-40d6-8ff4-aa97899fc991","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::6]:32345"},"services":[{"id":"2177f37f-2ac9-4e66-bf74-a10bd91f4d33","details":{"type":"crucible","address":"[fd00:1122:3344:105::6]:32345"}}]},"root":"/pool/ext/4f1eafe9-b28d-49d3-83e2-ceac8721d6b5/crypt/zone"},{"zone":{"id":"e4e43855-4879-4910-a2ba-40f625c1cc2d","zone_type":"crucible","addresses":["fd00:1122:3344:105::b"],"dataset":{"id":"e4e43855-4879-4910-a2ba-40f625c1cc2d","name":{"pool_name":"oxp_967d2f05-b141-44f5-837d-9b2aa67ee128","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::b]:32345"},"services":[{"id":"e4e43855-4879-4910-a2ba-40f625c1cc2d","details":{"type":"crucible","address":"[fd00:1122:3344:105::b]:32345"}}]},"root":"/pool/ext/6b6f34cd-6d3d-4832-a4e6-3df112c97133/crypt/zone"},{"zone":{"id":"8d2517e1-f9ad-40f2-abb9-2f5122839910","zone_type":"crucible","addresses":["fd00:1122:3344:105::7"],"dataset":{"id":"8d2517e1-f9ad-40f2-abb9-2f5122839910","name":{"pool_name":"oxp_ad493851-2d11-4c2d-8d75-989579d9616a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::7]:32345"},"services":[{"id":"8d2517e1-f9ad-40f2-abb9-2f5122839910","details":{"type":"crucible","address":"[fd00:1122:3344:105::7]:32345"}}]},"root":"/pool/ext/88abca38-3f61-4d4b-80a1-4ea3e4827f84/crypt/zone"},{"zone":{"id":"44cb3698-a7b1-4388-9165-ac76082ec8bc","zone_type":"crucible","addresses":["fd00:1122:3344:105::5"],"dataset":{"id":"44cb3698-a7b1-4388-9165-ac76082ec8bc","name":{"pool_name":"oxp_4292a83c-8c1f-4b2e-9120-72e0c510bf3c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::5]:32345"},"services":[{"id":"44cb3698-a7b1-4388-9165-ac76082ec8bc","details":{"type":"crucible","address":"[fd00:1122:3344:105::5]:32345"}}]},"root":"/pool/ext/24dab7f5-164a-47f3-a878-f32ab1e68cce/crypt/zone"},{"zone":{"id":"931b5c86-9d72-4518-bfd6-97863152ac65","zone_type":"crucible","addresses":["fd00:1122:3344:105::c"],"dataset":{"id":"931b5c86-9d72-4518-bfd6-97863152ac65","name":{"pool_name":"oxp_6b6f34cd-6d3d-4832-a4e6-3df112c97133","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::c]:32345"},"services":[{"id":"931b5c86-9d72-4518-bfd6-97863152ac65","details":{"type":"crucible","address":"[fd00:1122:3344:105::c]:32345"}}]},"root":"/pool/ext/ad493851-2d11-4c2d-8d75-989579d9616a/crypt/zone"},{"zone":{"id":"ac568073-1889-463e-8cc4-cfed16ce2a34","zone_type":"crucible","addresses":["fd00:1122:3344:105::8"],"dataset":{"id":"ac568073-1889-463e-8cc4-cfed16ce2a34","name":{"pool_name":"oxp_4f1eafe9-b28d-49d3-83e2-ceac8721d6b5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:105::8]:32345"},"services":[{"id":"ac568073-1889-463e-8cc4-cfed16ce2a34","details":{"type":"crucible","address":"[fd00:1122:3344:105::8]:32345"}}]},"root":"/pool/ext/4292a83c-8c1f-4b2e-9120-72e0c510bf3c/crypt/zone"},{"zone":{"id":"e8f86fbb-864e-4d5a-961c-b50b54ae853e","zone_type":"cockroach_db","addresses":["fd00:1122:3344:105::3"],"dataset":{"id":"e8f86fbb-864e-4d5a-961c-b50b54ae853e","name":{"pool_name":"oxp_24dab7f5-164a-47f3-a878-f32ab1e68cce","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:105::3]:32221"},"services":[{"id":"e8f86fbb-864e-4d5a-961c-b50b54ae853e","details":{"type":"cockroach_db","address":"[fd00:1122:3344:105::3]:32221"}}]},"root":"/pool/ext/4f1eafe9-b28d-49d3-83e2-ceac8721d6b5/crypt/zone"},{"zone":{"id":"c79caea0-37b1-49d6-ae6e-8cf849d91374","zone_type":"ntp","addresses":["fd00:1122:3344:105::e"],"dataset":null,"services":[{"id":"c79caea0-37b1-49d6-ae6e-8cf849d91374","details":{"type":"internal_ntp","address":"[fd00:1122:3344:105::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/24dab7f5-164a-47f3-a878-f32ab1e68cce/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled24.json b/sled-agent/tests/old-service-ledgers/rack3-sled24.json deleted file mode 100644 index e7bd3050d6..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled24.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"d2b1e468-bc3c-4d08-b855-ae3327465375","zone_type":"crucible","addresses":["fd00:1122:3344:106::3"],"dataset":{"id":"d2b1e468-bc3c-4d08-b855-ae3327465375","name":{"pool_name":"oxp_9db196bf-828d-4e55-a2c1-dd9d579d3908","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::3]:32345"},"services":[{"id":"d2b1e468-bc3c-4d08-b855-ae3327465375","details":{"type":"crucible","address":"[fd00:1122:3344:106::3]:32345"}}]},"root":"/pool/ext/74df4c92-edbb-4431-a770-1d015110e66b/crypt/zone"},{"zone":{"id":"61f94a16-79fd-42e3-b225-a4dc67228437","zone_type":"crucible","addresses":["fd00:1122:3344:106::6"],"dataset":{"id":"61f94a16-79fd-42e3-b225-a4dc67228437","name":{"pool_name":"oxp_d77d5b08-5f70-496a-997b-b38804dc3b8a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::6]:32345"},"services":[{"id":"61f94a16-79fd-42e3-b225-a4dc67228437","details":{"type":"crucible","address":"[fd00:1122:3344:106::6]:32345"}}]},"root":"/pool/ext/daf9e3cd-5a40-4eba-a0f6-4f94dab37dae/crypt/zone"},{"zone":{"id":"7d32ef34-dec5-4fd8-899e-20bbc473a3ee","zone_type":"crucible","addresses":["fd00:1122:3344:106::7"],"dataset":{"id":"7d32ef34-dec5-4fd8-899e-20bbc473a3ee","name":{"pool_name":"oxp_50c1b653-6231-41fe-b3cf-b7ba709a0746","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::7]:32345"},"services":[{"id":"7d32ef34-dec5-4fd8-899e-20bbc473a3ee","details":{"type":"crucible","address":"[fd00:1122:3344:106::7]:32345"}}]},"root":"/pool/ext/9db196bf-828d-4e55-a2c1-dd9d579d3908/crypt/zone"},{"zone":{"id":"c34b7ae5-26b9-4651-a3c4-20bba2bd0d2c","zone_type":"crucible","addresses":["fd00:1122:3344:106::5"],"dataset":{"id":"c34b7ae5-26b9-4651-a3c4-20bba2bd0d2c","name":{"pool_name":"oxp_88aea92c-ab92-44c1-9471-eb8e30e075d3","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::5]:32345"},"services":[{"id":"c34b7ae5-26b9-4651-a3c4-20bba2bd0d2c","details":{"type":"crucible","address":"[fd00:1122:3344:106::5]:32345"}}]},"root":"/pool/ext/8da316d4-6b18-4980-a0a8-6e76e72cc40d/crypt/zone"},{"zone":{"id":"36472be8-9a70-4c14-bd02-439b725cec1a","zone_type":"crucible","addresses":["fd00:1122:3344:106::8"],"dataset":{"id":"36472be8-9a70-4c14-bd02-439b725cec1a","name":{"pool_name":"oxp_54544b3a-1513-4db2-911e-7c1eb4b12385","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::8]:32345"},"services":[{"id":"36472be8-9a70-4c14-bd02-439b725cec1a","details":{"type":"crucible","address":"[fd00:1122:3344:106::8]:32345"}}]},"root":"/pool/ext/54544b3a-1513-4db2-911e-7c1eb4b12385/crypt/zone"},{"zone":{"id":"2548f8ab-5255-4334-a1fb-5d7d95213129","zone_type":"crucible","addresses":["fd00:1122:3344:106::9"],"dataset":{"id":"2548f8ab-5255-4334-a1fb-5d7d95213129","name":{"pool_name":"oxp_08050450-967f-431c-9a12-0d051aff020e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::9]:32345"},"services":[{"id":"2548f8ab-5255-4334-a1fb-5d7d95213129","details":{"type":"crucible","address":"[fd00:1122:3344:106::9]:32345"}}]},"root":"/pool/ext/08050450-967f-431c-9a12-0d051aff020e/crypt/zone"},{"zone":{"id":"1455c069-853c-49cd-853a-3ea81b89acd4","zone_type":"crucible","addresses":["fd00:1122:3344:106::c"],"dataset":{"id":"1455c069-853c-49cd-853a-3ea81b89acd4","name":{"pool_name":"oxp_8da316d4-6b18-4980-a0a8-6e76e72cc40d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::c]:32345"},"services":[{"id":"1455c069-853c-49cd-853a-3ea81b89acd4","details":{"type":"crucible","address":"[fd00:1122:3344:106::c]:32345"}}]},"root":"/pool/ext/08050450-967f-431c-9a12-0d051aff020e/crypt/zone"},{"zone":{"id":"27c0244b-f91a-46c3-bc96-e8eec009371e","zone_type":"crucible","addresses":["fd00:1122:3344:106::b"],"dataset":{"id":"27c0244b-f91a-46c3-bc96-e8eec009371e","name":{"pool_name":"oxp_daf9e3cd-5a40-4eba-a0f6-4f94dab37dae","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::b]:32345"},"services":[{"id":"27c0244b-f91a-46c3-bc96-e8eec009371e","details":{"type":"crucible","address":"[fd00:1122:3344:106::b]:32345"}}]},"root":"/pool/ext/74df4c92-edbb-4431-a770-1d015110e66b/crypt/zone"},{"zone":{"id":"9e46d837-1e0f-42b6-a352-84e6946b8734","zone_type":"crucible","addresses":["fd00:1122:3344:106::4"],"dataset":{"id":"9e46d837-1e0f-42b6-a352-84e6946b8734","name":{"pool_name":"oxp_74df4c92-edbb-4431-a770-1d015110e66b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::4]:32345"},"services":[{"id":"9e46d837-1e0f-42b6-a352-84e6946b8734","details":{"type":"crucible","address":"[fd00:1122:3344:106::4]:32345"}}]},"root":"/pool/ext/15f94c39-d48c-41f6-a913-cc1d04aef1a2/crypt/zone"},{"zone":{"id":"b972fcd4-c1b3-4b3c-9e24-f59c7a7cb192","zone_type":"crucible","addresses":["fd00:1122:3344:106::a"],"dataset":{"id":"b972fcd4-c1b3-4b3c-9e24-f59c7a7cb192","name":{"pool_name":"oxp_15f94c39-d48c-41f6-a913-cc1d04aef1a2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:106::a]:32345"},"services":[{"id":"b972fcd4-c1b3-4b3c-9e24-f59c7a7cb192","details":{"type":"crucible","address":"[fd00:1122:3344:106::a]:32345"}}]},"root":"/pool/ext/74df4c92-edbb-4431-a770-1d015110e66b/crypt/zone"},{"zone":{"id":"e1c8c655-1950-42d5-ae1f-a4ce84854bbc","zone_type":"ntp","addresses":["fd00:1122:3344:106::d"],"dataset":null,"services":[{"id":"e1c8c655-1950-42d5-ae1f-a4ce84854bbc","details":{"type":"internal_ntp","address":"[fd00:1122:3344:106::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/15f94c39-d48c-41f6-a913-cc1d04aef1a2/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled25.json b/sled-agent/tests/old-service-ledgers/rack3-sled25.json deleted file mode 100644 index 642657bbce..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled25.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"10b80058-9b2e-4d6c-8a1a-a61a8258c12f","zone_type":"crucible","addresses":["fd00:1122:3344:118::9"],"dataset":{"id":"10b80058-9b2e-4d6c-8a1a-a61a8258c12f","name":{"pool_name":"oxp_953c19bb-9fff-4488-8a7b-29de9994a948","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::9]:32345"},"services":[{"id":"10b80058-9b2e-4d6c-8a1a-a61a8258c12f","details":{"type":"crucible","address":"[fd00:1122:3344:118::9]:32345"}}]},"root":"/pool/ext/a78caf97-6145-4908-83b5-a03a6d2e0ac4/crypt/zone"},{"zone":{"id":"f58fef96-7b5e-40c2-9482-669088a19209","zone_type":"crucible","addresses":["fd00:1122:3344:118::d"],"dataset":{"id":"f58fef96-7b5e-40c2-9482-669088a19209","name":{"pool_name":"oxp_d7976706-d6ed-4465-8b04-450c96d8feec","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::d]:32345"},"services":[{"id":"f58fef96-7b5e-40c2-9482-669088a19209","details":{"type":"crucible","address":"[fd00:1122:3344:118::d]:32345"}}]},"root":"/pool/ext/d7976706-d6ed-4465-8b04-450c96d8feec/crypt/zone"},{"zone":{"id":"624f1168-47b6-4aa1-84da-e20a0d74d783","zone_type":"crucible","addresses":["fd00:1122:3344:118::b"],"dataset":{"id":"624f1168-47b6-4aa1-84da-e20a0d74d783","name":{"pool_name":"oxp_a78caf97-6145-4908-83b5-a03a6d2e0ac4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::b]:32345"},"services":[{"id":"624f1168-47b6-4aa1-84da-e20a0d74d783","details":{"type":"crucible","address":"[fd00:1122:3344:118::b]:32345"}}]},"root":"/pool/ext/a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d/crypt/zone"},{"zone":{"id":"8ea85412-19b4-45c1-a53c-027ddd629296","zone_type":"crucible","addresses":["fd00:1122:3344:118::6"],"dataset":{"id":"8ea85412-19b4-45c1-a53c-027ddd629296","name":{"pool_name":"oxp_d5f4c903-155a-4c91-aadd-6039a4f64821","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::6]:32345"},"services":[{"id":"8ea85412-19b4-45c1-a53c-027ddd629296","details":{"type":"crucible","address":"[fd00:1122:3344:118::6]:32345"}}]},"root":"/pool/ext/7d2a7685-c1c9-4d2d-a2bb-df65d96ea3e2/crypt/zone"},{"zone":{"id":"fd226b82-71d7-4719-b32c-a6c7abe28a2a","zone_type":"external_dns","addresses":["fd00:1122:3344:118::3"],"dataset":{"id":"fd226b82-71d7-4719-b32c-a6c7abe28a2a","name":{"pool_name":"oxp_84a80b58-70e9-439c-9558-5b343d9a4b53","kind":{"type":"external_dns"}},"service_address":"[fd00:1122:3344:118::3]:5353"},"services":[{"id":"fd226b82-71d7-4719-b32c-a6c7abe28a2a","details":{"type":"external_dns","http_address":"[fd00:1122:3344:118::3]:5353","dns_address":"45.154.216.34:53","nic":{"id":"7f72b6fd-1120-44dc-b3a7-f727502ba47c","kind":{"type":"service","id":"fd226b82-71d7-4719-b32c-a6c7abe28a2a"},"name":"external-dns-fd226b82-71d7-4719-b32c-a6c7abe28a2a","ip":"172.30.1.6","mac":"A8:40:25:FF:9E:D1","subnet":"172.30.1.0/24","vni":100,"primary":true,"slot":0}}}]},"root":"/pool/ext/a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d/crypt/zone"},{"zone":{"id":"08d0c38d-f0d9-45b9-856d-b85059fe5f07","zone_type":"crucible","addresses":["fd00:1122:3344:118::4"],"dataset":{"id":"08d0c38d-f0d9-45b9-856d-b85059fe5f07","name":{"pool_name":"oxp_84a80b58-70e9-439c-9558-5b343d9a4b53","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::4]:32345"},"services":[{"id":"08d0c38d-f0d9-45b9-856d-b85059fe5f07","details":{"type":"crucible","address":"[fd00:1122:3344:118::4]:32345"}}]},"root":"/pool/ext/a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d/crypt/zone"},{"zone":{"id":"5de7d3fd-4a3f-4fdd-b6b2-d1186e16dce5","zone_type":"crucible","addresses":["fd00:1122:3344:118::7"],"dataset":{"id":"5de7d3fd-4a3f-4fdd-b6b2-d1186e16dce5","name":{"pool_name":"oxp_d76e058f-2d1e-4b15-b3a0-e5509a246876","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::7]:32345"},"services":[{"id":"5de7d3fd-4a3f-4fdd-b6b2-d1186e16dce5","details":{"type":"crucible","address":"[fd00:1122:3344:118::7]:32345"}}]},"root":"/pool/ext/a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d/crypt/zone"},{"zone":{"id":"5d0f5cad-10b3-497c-903b-eeeabce920e2","zone_type":"crucible","addresses":["fd00:1122:3344:118::8"],"dataset":{"id":"5d0f5cad-10b3-497c-903b-eeeabce920e2","name":{"pool_name":"oxp_3a3ad639-8800-4951-bc2a-201d269e47a2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::8]:32345"},"services":[{"id":"5d0f5cad-10b3-497c-903b-eeeabce920e2","details":{"type":"crucible","address":"[fd00:1122:3344:118::8]:32345"}}]},"root":"/pool/ext/3a3ad639-8800-4951-bc2a-201d269e47a2/crypt/zone"},{"zone":{"id":"39f9cefa-801c-4843-9fb9-05446ffbdd1a","zone_type":"crucible","addresses":["fd00:1122:3344:118::a"],"dataset":{"id":"39f9cefa-801c-4843-9fb9-05446ffbdd1a","name":{"pool_name":"oxp_7d2a7685-c1c9-4d2d-a2bb-df65d96ea3e2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::a]:32345"},"services":[{"id":"39f9cefa-801c-4843-9fb9-05446ffbdd1a","details":{"type":"crucible","address":"[fd00:1122:3344:118::a]:32345"}}]},"root":"/pool/ext/a78caf97-6145-4908-83b5-a03a6d2e0ac4/crypt/zone"},{"zone":{"id":"0711e710-7fdd-4e68-94c8-294b8677e804","zone_type":"crucible","addresses":["fd00:1122:3344:118::5"],"dataset":{"id":"0711e710-7fdd-4e68-94c8-294b8677e804","name":{"pool_name":"oxp_a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::5]:32345"},"services":[{"id":"0711e710-7fdd-4e68-94c8-294b8677e804","details":{"type":"crucible","address":"[fd00:1122:3344:118::5]:32345"}}]},"root":"/pool/ext/3a3ad639-8800-4951-bc2a-201d269e47a2/crypt/zone"},{"zone":{"id":"318a62cc-5c6c-4805-9fb6-c0f6a75ce31c","zone_type":"crucible","addresses":["fd00:1122:3344:118::c"],"dataset":{"id":"318a62cc-5c6c-4805-9fb6-c0f6a75ce31c","name":{"pool_name":"oxp_1d5f0ba3-6b31-4cea-a9a9-2065a538887d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:118::c]:32345"},"services":[{"id":"318a62cc-5c6c-4805-9fb6-c0f6a75ce31c","details":{"type":"crucible","address":"[fd00:1122:3344:118::c]:32345"}}]},"root":"/pool/ext/d7976706-d6ed-4465-8b04-450c96d8feec/crypt/zone"},{"zone":{"id":"463d0498-85b9-40eb-af96-d99af58a587c","zone_type":"ntp","addresses":["fd00:1122:3344:118::e"],"dataset":null,"services":[{"id":"463d0498-85b9-40eb-af96-d99af58a587c","details":{"type":"internal_ntp","address":"[fd00:1122:3344:118::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/d5f4c903-155a-4c91-aadd-6039a4f64821/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled26.json b/sled-agent/tests/old-service-ledgers/rack3-sled26.json deleted file mode 100644 index 0978cb9e45..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled26.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"d8b3de97-cc79-48f6-83ad-02017c21223b","zone_type":"crucible_pantry","addresses":["fd00:1122:3344:119::3"],"dataset":null,"services":[{"id":"d8b3de97-cc79-48f6-83ad-02017c21223b","details":{"type":"crucible_pantry","address":"[fd00:1122:3344:119::3]:17000"}}]},"root":"/pool/ext/e0faea44-8b5c-40b0-bb75-a1aec1a10377/crypt/zone"},{"zone":{"id":"adba1a3b-5bac-44d5-aa5a-879dc6eadb5f","zone_type":"crucible","addresses":["fd00:1122:3344:119::c"],"dataset":{"id":"adba1a3b-5bac-44d5-aa5a-879dc6eadb5f","name":{"pool_name":"oxp_21c339c3-6461-4bdb-8b0e-c0f9f08ee10b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::c]:32345"},"services":[{"id":"adba1a3b-5bac-44d5-aa5a-879dc6eadb5f","details":{"type":"crucible","address":"[fd00:1122:3344:119::c]:32345"}}]},"root":"/pool/ext/f5c73c28-2168-4321-b737-4ca6663155c9/crypt/zone"},{"zone":{"id":"42bb9833-5c39-4aba-b2c4-da2ca1287728","zone_type":"crucible","addresses":["fd00:1122:3344:119::a"],"dataset":{"id":"42bb9833-5c39-4aba-b2c4-da2ca1287728","name":{"pool_name":"oxp_1f91451d-a466-4c9a-a6e6-0abd7985595f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::a]:32345"},"services":[{"id":"42bb9833-5c39-4aba-b2c4-da2ca1287728","details":{"type":"crucible","address":"[fd00:1122:3344:119::a]:32345"}}]},"root":"/pool/ext/21c339c3-6461-4bdb-8b0e-c0f9f08ee10b/crypt/zone"},{"zone":{"id":"197695e1-d949-4982-b679-6e5c9ab4bcc7","zone_type":"crucible","addresses":["fd00:1122:3344:119::b"],"dataset":{"id":"197695e1-d949-4982-b679-6e5c9ab4bcc7","name":{"pool_name":"oxp_e0faea44-8b5c-40b0-bb75-a1aec1a10377","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::b]:32345"},"services":[{"id":"197695e1-d949-4982-b679-6e5c9ab4bcc7","details":{"type":"crucible","address":"[fd00:1122:3344:119::b]:32345"}}]},"root":"/pool/ext/b31e1815-cae0-4145-940c-874fff63bdd5/crypt/zone"},{"zone":{"id":"bf99d4f8-edf1-4de5-98d4-8e6a24965005","zone_type":"crucible","addresses":["fd00:1122:3344:119::8"],"dataset":{"id":"bf99d4f8-edf1-4de5-98d4-8e6a24965005","name":{"pool_name":"oxp_ef2c3afb-6962-4f6b-b567-14766bbd9ec0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::8]:32345"},"services":[{"id":"bf99d4f8-edf1-4de5-98d4-8e6a24965005","details":{"type":"crucible","address":"[fd00:1122:3344:119::8]:32345"}}]},"root":"/pool/ext/21c339c3-6461-4bdb-8b0e-c0f9f08ee10b/crypt/zone"},{"zone":{"id":"390d1853-8be9-4987-b8b6-f022999bf4e7","zone_type":"crucible","addresses":["fd00:1122:3344:119::7"],"dataset":{"id":"390d1853-8be9-4987-b8b6-f022999bf4e7","name":{"pool_name":"oxp_06eed00a-d8d3-4b9d-84c9-23fce535f63e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::7]:32345"},"services":[{"id":"390d1853-8be9-4987-b8b6-f022999bf4e7","details":{"type":"crucible","address":"[fd00:1122:3344:119::7]:32345"}}]},"root":"/pool/ext/ef2c3afb-6962-4f6b-b567-14766bbd9ec0/crypt/zone"},{"zone":{"id":"76fe2161-90df-41b5-9c94-067de9c29db1","zone_type":"crucible","addresses":["fd00:1122:3344:119::4"],"dataset":{"id":"76fe2161-90df-41b5-9c94-067de9c29db1","name":{"pool_name":"oxp_f5c73c28-2168-4321-b737-4ca6663155c9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::4]:32345"},"services":[{"id":"76fe2161-90df-41b5-9c94-067de9c29db1","details":{"type":"crucible","address":"[fd00:1122:3344:119::4]:32345"}}]},"root":"/pool/ext/ef2c3afb-6962-4f6b-b567-14766bbd9ec0/crypt/zone"},{"zone":{"id":"f49dc522-2b13-4055-964c-8315671096aa","zone_type":"crucible","addresses":["fd00:1122:3344:119::d"],"dataset":{"id":"f49dc522-2b13-4055-964c-8315671096aa","name":{"pool_name":"oxp_662c278b-7f5f-4c7e-91ff-70207e8a307b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::d]:32345"},"services":[{"id":"f49dc522-2b13-4055-964c-8315671096aa","details":{"type":"crucible","address":"[fd00:1122:3344:119::d]:32345"}}]},"root":"/pool/ext/1f91451d-a466-4c9a-a6e6-0abd7985595f/crypt/zone"},{"zone":{"id":"08cc7bd6-368e-4d16-a619-28b17eff35af","zone_type":"crucible","addresses":["fd00:1122:3344:119::9"],"dataset":{"id":"08cc7bd6-368e-4d16-a619-28b17eff35af","name":{"pool_name":"oxp_5516b9ac-b139-40da-aa3b-f094568ba095","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::9]:32345"},"services":[{"id":"08cc7bd6-368e-4d16-a619-28b17eff35af","details":{"type":"crucible","address":"[fd00:1122:3344:119::9]:32345"}}]},"root":"/pool/ext/06eed00a-d8d3-4b9d-84c9-23fce535f63e/crypt/zone"},{"zone":{"id":"74b0613f-bce8-4922-93e0-b5bfccfc8443","zone_type":"crucible","addresses":["fd00:1122:3344:119::5"],"dataset":{"id":"74b0613f-bce8-4922-93e0-b5bfccfc8443","name":{"pool_name":"oxp_b31e1815-cae0-4145-940c-874fff63bdd5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::5]:32345"},"services":[{"id":"74b0613f-bce8-4922-93e0-b5bfccfc8443","details":{"type":"crucible","address":"[fd00:1122:3344:119::5]:32345"}}]},"root":"/pool/ext/21c339c3-6461-4bdb-8b0e-c0f9f08ee10b/crypt/zone"},{"zone":{"id":"55fcfc62-8435-475f-a2aa-29373901b993","zone_type":"crucible","addresses":["fd00:1122:3344:119::6"],"dataset":{"id":"55fcfc62-8435-475f-a2aa-29373901b993","name":{"pool_name":"oxp_eadf6a03-1028-4d48-ac0d-0d27ef2c8c0f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:119::6]:32345"},"services":[{"id":"55fcfc62-8435-475f-a2aa-29373901b993","details":{"type":"crucible","address":"[fd00:1122:3344:119::6]:32345"}}]},"root":"/pool/ext/1f91451d-a466-4c9a-a6e6-0abd7985595f/crypt/zone"},{"zone":{"id":"d52ccea3-6d7f-43a6-a19f-e0409f4e9cdc","zone_type":"ntp","addresses":["fd00:1122:3344:119::e"],"dataset":null,"services":[{"id":"d52ccea3-6d7f-43a6-a19f-e0409f4e9cdc","details":{"type":"internal_ntp","address":"[fd00:1122:3344:119::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/f5c73c28-2168-4321-b737-4ca6663155c9/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled27.json b/sled-agent/tests/old-service-ledgers/rack3-sled27.json deleted file mode 100644 index 0b2db29c4a..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled27.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"095e612f-e218-4a16-aa6e-98c3d69a470a","zone_type":"crucible","addresses":["fd00:1122:3344:10d::a"],"dataset":{"id":"095e612f-e218-4a16-aa6e-98c3d69a470a","name":{"pool_name":"oxp_9f657858-623f-4d78-9841-6e620b5ede30","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::a]:32345"},"services":[{"id":"095e612f-e218-4a16-aa6e-98c3d69a470a","details":{"type":"crucible","address":"[fd00:1122:3344:10d::a]:32345"}}]},"root":"/pool/ext/2d086b51-2b77-4bc7-adc6-43586ea38ce9/crypt/zone"},{"zone":{"id":"de818730-0e3b-4567-94e7-344bd9b6f564","zone_type":"crucible","addresses":["fd00:1122:3344:10d::3"],"dataset":{"id":"de818730-0e3b-4567-94e7-344bd9b6f564","name":{"pool_name":"oxp_ba6ab301-07e1-4d35-80ac-59612f2c2bdb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::3]:32345"},"services":[{"id":"de818730-0e3b-4567-94e7-344bd9b6f564","details":{"type":"crucible","address":"[fd00:1122:3344:10d::3]:32345"}}]},"root":"/pool/ext/7cee2806-e898-47d8-b568-e276a6e271f8/crypt/zone"},{"zone":{"id":"6a21dc3c-3a9d-4520-9a91-7d8f2737bcd4","zone_type":"crucible","addresses":["fd00:1122:3344:10d::4"],"dataset":{"id":"6a21dc3c-3a9d-4520-9a91-7d8f2737bcd4","name":{"pool_name":"oxp_7cee2806-e898-47d8-b568-e276a6e271f8","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::4]:32345"},"services":[{"id":"6a21dc3c-3a9d-4520-9a91-7d8f2737bcd4","details":{"type":"crucible","address":"[fd00:1122:3344:10d::4]:32345"}}]},"root":"/pool/ext/cef23d87-31ed-40d5-99b8-12d7be8e46e7/crypt/zone"},{"zone":{"id":"e01b7f45-b8d7-4944-ba5b-41fb699889a9","zone_type":"crucible","addresses":["fd00:1122:3344:10d::b"],"dataset":{"id":"e01b7f45-b8d7-4944-ba5b-41fb699889a9","name":{"pool_name":"oxp_d9af8878-50bd-4425-95d9-e6556ce92cfa","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::b]:32345"},"services":[{"id":"e01b7f45-b8d7-4944-ba5b-41fb699889a9","details":{"type":"crucible","address":"[fd00:1122:3344:10d::b]:32345"}}]},"root":"/pool/ext/6fe9bcaa-88cb-451d-b086-24a3ad53fa22/crypt/zone"},{"zone":{"id":"4271ef62-d319-4e80-b157-915321cec8c7","zone_type":"crucible","addresses":["fd00:1122:3344:10d::c"],"dataset":{"id":"4271ef62-d319-4e80-b157-915321cec8c7","name":{"pool_name":"oxp_ba8ee7dd-cdfb-48bd-92ce-4dc45e070930","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::c]:32345"},"services":[{"id":"4271ef62-d319-4e80-b157-915321cec8c7","details":{"type":"crucible","address":"[fd00:1122:3344:10d::c]:32345"}}]},"root":"/pool/ext/9f657858-623f-4d78-9841-6e620b5ede30/crypt/zone"},{"zone":{"id":"6bdcc159-aeb9-4903-9486-dd8b43a3dc16","zone_type":"crucible","addresses":["fd00:1122:3344:10d::8"],"dataset":{"id":"6bdcc159-aeb9-4903-9486-dd8b43a3dc16","name":{"pool_name":"oxp_5b03a5dc-bb5a-4bf4-bc21-0af849cd1dab","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::8]:32345"},"services":[{"id":"6bdcc159-aeb9-4903-9486-dd8b43a3dc16","details":{"type":"crucible","address":"[fd00:1122:3344:10d::8]:32345"}}]},"root":"/pool/ext/d9af8878-50bd-4425-95d9-e6556ce92cfa/crypt/zone"},{"zone":{"id":"85540e54-cdd7-4baa-920c-5cf54cbc1f83","zone_type":"crucible","addresses":["fd00:1122:3344:10d::7"],"dataset":{"id":"85540e54-cdd7-4baa-920c-5cf54cbc1f83","name":{"pool_name":"oxp_ee24f9a6-84ab-49a5-a28f-e394abfcaa95","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::7]:32345"},"services":[{"id":"85540e54-cdd7-4baa-920c-5cf54cbc1f83","details":{"type":"crucible","address":"[fd00:1122:3344:10d::7]:32345"}}]},"root":"/pool/ext/9f657858-623f-4d78-9841-6e620b5ede30/crypt/zone"},{"zone":{"id":"750d1a0b-6a14-46c5-9a0b-a504caefb198","zone_type":"crucible","addresses":["fd00:1122:3344:10d::9"],"dataset":{"id":"750d1a0b-6a14-46c5-9a0b-a504caefb198","name":{"pool_name":"oxp_cef23d87-31ed-40d5-99b8-12d7be8e46e7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::9]:32345"},"services":[{"id":"750d1a0b-6a14-46c5-9a0b-a504caefb198","details":{"type":"crucible","address":"[fd00:1122:3344:10d::9]:32345"}}]},"root":"/pool/ext/ba8ee7dd-cdfb-48bd-92ce-4dc45e070930/crypt/zone"},{"zone":{"id":"b5996893-1a9a-434e-a257-d702694f058b","zone_type":"crucible","addresses":["fd00:1122:3344:10d::6"],"dataset":{"id":"b5996893-1a9a-434e-a257-d702694f058b","name":{"pool_name":"oxp_2d086b51-2b77-4bc7-adc6-43586ea38ce9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::6]:32345"},"services":[{"id":"b5996893-1a9a-434e-a257-d702694f058b","details":{"type":"crucible","address":"[fd00:1122:3344:10d::6]:32345"}}]},"root":"/pool/ext/7cee2806-e898-47d8-b568-e276a6e271f8/crypt/zone"},{"zone":{"id":"8b36686a-b98d-451a-9124-a3583000a83a","zone_type":"crucible","addresses":["fd00:1122:3344:10d::5"],"dataset":{"id":"8b36686a-b98d-451a-9124-a3583000a83a","name":{"pool_name":"oxp_6fe9bcaa-88cb-451d-b086-24a3ad53fa22","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10d::5]:32345"},"services":[{"id":"8b36686a-b98d-451a-9124-a3583000a83a","details":{"type":"crucible","address":"[fd00:1122:3344:10d::5]:32345"}}]},"root":"/pool/ext/9f657858-623f-4d78-9841-6e620b5ede30/crypt/zone"},{"zone":{"id":"88d695a2-c8c1-41af-85b0-77424f4d650d","zone_type":"ntp","addresses":["fd00:1122:3344:10d::d"],"dataset":null,"services":[{"id":"88d695a2-c8c1-41af-85b0-77424f4d650d","details":{"type":"internal_ntp","address":"[fd00:1122:3344:10d::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/ba6ab301-07e1-4d35-80ac-59612f2c2bdb/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled28.json b/sled-agent/tests/old-service-ledgers/rack3-sled28.json deleted file mode 100644 index ec137c18fa..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled28.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"a126365d-f459-43bf-9f99-dbe1c4cdecf8","zone_type":"crucible","addresses":["fd00:1122:3344:113::4"],"dataset":{"id":"a126365d-f459-43bf-9f99-dbe1c4cdecf8","name":{"pool_name":"oxp_c99eabb2-6815-416a-9660-87e2609b357a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::4]:32345"},"services":[{"id":"a126365d-f459-43bf-9f99-dbe1c4cdecf8","details":{"type":"crucible","address":"[fd00:1122:3344:113::4]:32345"}}]},"root":"/pool/ext/6461a450-f043-4d1e-bc03-4a68ed5fe94a/crypt/zone"},{"zone":{"id":"52f57ef8-546a-43bd-a0f3-8c42b99c37a6","zone_type":"crucible","addresses":["fd00:1122:3344:113::3"],"dataset":{"id":"52f57ef8-546a-43bd-a0f3-8c42b99c37a6","name":{"pool_name":"oxp_f6530e9c-6d64-44fa-93d5-ae427916fbf1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::3]:32345"},"services":[{"id":"52f57ef8-546a-43bd-a0f3-8c42b99c37a6","details":{"type":"crucible","address":"[fd00:1122:3344:113::3]:32345"}}]},"root":"/pool/ext/97662260-6b62-450f-9d7e-42f7dee5d568/crypt/zone"},{"zone":{"id":"3ee87855-9423-43ff-800a-fa4fdbf1d956","zone_type":"crucible","addresses":["fd00:1122:3344:113::a"],"dataset":{"id":"3ee87855-9423-43ff-800a-fa4fdbf1d956","name":{"pool_name":"oxp_6461a450-f043-4d1e-bc03-4a68ed5fe94a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::a]:32345"},"services":[{"id":"3ee87855-9423-43ff-800a-fa4fdbf1d956","details":{"type":"crucible","address":"[fd00:1122:3344:113::a]:32345"}}]},"root":"/pool/ext/9515dc86-fe62-4d4f-b38d-b3461cc042fc/crypt/zone"},{"zone":{"id":"55d0ddf9-9b24-4a7a-b97f-248e240f9ba6","zone_type":"crucible","addresses":["fd00:1122:3344:113::5"],"dataset":{"id":"55d0ddf9-9b24-4a7a-b97f-248e240f9ba6","name":{"pool_name":"oxp_97662260-6b62-450f-9d7e-42f7dee5d568","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::5]:32345"},"services":[{"id":"55d0ddf9-9b24-4a7a-b97f-248e240f9ba6","details":{"type":"crucible","address":"[fd00:1122:3344:113::5]:32345"}}]},"root":"/pool/ext/9515dc86-fe62-4d4f-b38d-b3461cc042fc/crypt/zone"},{"zone":{"id":"014cad37-56a7-4b2a-9c9e-505b15b4de85","zone_type":"crucible","addresses":["fd00:1122:3344:113::b"],"dataset":{"id":"014cad37-56a7-4b2a-9c9e-505b15b4de85","name":{"pool_name":"oxp_8529ce8e-21d2-4b23-b9fd-6b90c7ae4f90","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::b]:32345"},"services":[{"id":"014cad37-56a7-4b2a-9c9e-505b15b4de85","details":{"type":"crucible","address":"[fd00:1122:3344:113::b]:32345"}}]},"root":"/pool/ext/6461a450-f043-4d1e-bc03-4a68ed5fe94a/crypt/zone"},{"zone":{"id":"e14fb192-aaab-42ab-aa86-c85f13955940","zone_type":"crucible","addresses":["fd00:1122:3344:113::6"],"dataset":{"id":"e14fb192-aaab-42ab-aa86-c85f13955940","name":{"pool_name":"oxp_5a9455ca-fb01-4549-9a70-7579c031779d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::6]:32345"},"services":[{"id":"e14fb192-aaab-42ab-aa86-c85f13955940","details":{"type":"crucible","address":"[fd00:1122:3344:113::6]:32345"}}]},"root":"/pool/ext/f6530e9c-6d64-44fa-93d5-ae427916fbf1/crypt/zone"},{"zone":{"id":"14540609-9371-442b-8486-88c244e97cd4","zone_type":"crucible","addresses":["fd00:1122:3344:113::8"],"dataset":{"id":"14540609-9371-442b-8486-88c244e97cd4","name":{"pool_name":"oxp_2916d6f3-8775-4887-a6d3-f9723982756f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::8]:32345"},"services":[{"id":"14540609-9371-442b-8486-88c244e97cd4","details":{"type":"crucible","address":"[fd00:1122:3344:113::8]:32345"}}]},"root":"/pool/ext/8529ce8e-21d2-4b23-b9fd-6b90c7ae4f90/crypt/zone"},{"zone":{"id":"97a6b35f-0af9-41eb-93a1-f8bc5dbba357","zone_type":"crucible","addresses":["fd00:1122:3344:113::7"],"dataset":{"id":"97a6b35f-0af9-41eb-93a1-f8bc5dbba357","name":{"pool_name":"oxp_9515dc86-fe62-4d4f-b38d-b3461cc042fc","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::7]:32345"},"services":[{"id":"97a6b35f-0af9-41eb-93a1-f8bc5dbba357","details":{"type":"crucible","address":"[fd00:1122:3344:113::7]:32345"}}]},"root":"/pool/ext/8529ce8e-21d2-4b23-b9fd-6b90c7ae4f90/crypt/zone"},{"zone":{"id":"5734aa24-cb66-4b0a-9eb2-564646f8d729","zone_type":"crucible","addresses":["fd00:1122:3344:113::9"],"dataset":{"id":"5734aa24-cb66-4b0a-9eb2-564646f8d729","name":{"pool_name":"oxp_9f889a6c-17b1-4edd-9659-458d91439dc1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::9]:32345"},"services":[{"id":"5734aa24-cb66-4b0a-9eb2-564646f8d729","details":{"type":"crucible","address":"[fd00:1122:3344:113::9]:32345"}}]},"root":"/pool/ext/a5074e7f-8d3b-40e0-a79e-dbd9af9d5693/crypt/zone"},{"zone":{"id":"ba86eca1-1427-4540-b4a6-1d9a0e1bc656","zone_type":"crucible","addresses":["fd00:1122:3344:113::c"],"dataset":{"id":"ba86eca1-1427-4540-b4a6-1d9a0e1bc656","name":{"pool_name":"oxp_a5074e7f-8d3b-40e0-a79e-dbd9af9d5693","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:113::c]:32345"},"services":[{"id":"ba86eca1-1427-4540-b4a6-1d9a0e1bc656","details":{"type":"crucible","address":"[fd00:1122:3344:113::c]:32345"}}]},"root":"/pool/ext/2916d6f3-8775-4887-a6d3-f9723982756f/crypt/zone"},{"zone":{"id":"6634dbc4-d22f-40a4-8cd3-4f271d781fa1","zone_type":"ntp","addresses":["fd00:1122:3344:113::d"],"dataset":null,"services":[{"id":"6634dbc4-d22f-40a4-8cd3-4f271d781fa1","details":{"type":"internal_ntp","address":"[fd00:1122:3344:113::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/a5074e7f-8d3b-40e0-a79e-dbd9af9d5693/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled29.json b/sled-agent/tests/old-service-ledgers/rack3-sled29.json deleted file mode 100644 index 2618364e4f..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled29.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":5,"requests":[{"zone":{"id":"1cdd1ebf-9321-4f2d-914c-1e617f60b41a","zone_type":"crucible","addresses":["fd00:1122:3344:120::8"],"dataset":{"id":"1cdd1ebf-9321-4f2d-914c-1e617f60b41a","name":{"pool_name":"oxp_74046573-78a2-46b4-86dc-40bb2ee29dd5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::8]:32345"},"services":[{"id":"1cdd1ebf-9321-4f2d-914c-1e617f60b41a","details":{"type":"crucible","address":"[fd00:1122:3344:120::8]:32345"}}]},"root":"/pool/ext/c1f0a9e4-ea10-4fd9-8b6d-79a2bacfec5e/crypt/zone"},{"zone":{"id":"720a0d08-d1c0-43ba-af86-f2dac1a53639","zone_type":"crucible","addresses":["fd00:1122:3344:120::c"],"dataset":{"id":"720a0d08-d1c0-43ba-af86-f2dac1a53639","name":{"pool_name":"oxp_068d2790-1044-41ed-97a5-b493490b14d1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::c]:32345"},"services":[{"id":"720a0d08-d1c0-43ba-af86-f2dac1a53639","details":{"type":"crucible","address":"[fd00:1122:3344:120::c]:32345"}}]},"root":"/pool/ext/86cd16cf-d00d-40bc-b14a-8220b1e11476/crypt/zone"},{"zone":{"id":"d9f0b97b-2cef-4155-b45f-7db89263e4cf","zone_type":"crucible","addresses":["fd00:1122:3344:120::9"],"dataset":{"id":"d9f0b97b-2cef-4155-b45f-7db89263e4cf","name":{"pool_name":"oxp_8171bf0d-e61e-43f9-87d6-ec8833b80102","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::9]:32345"},"services":[{"id":"d9f0b97b-2cef-4155-b45f-7db89263e4cf","details":{"type":"crucible","address":"[fd00:1122:3344:120::9]:32345"}}]},"root":"/pool/ext/86cd16cf-d00d-40bc-b14a-8220b1e11476/crypt/zone"},{"zone":{"id":"018edff1-0d95-45a3-9a01-39c419bec55a","zone_type":"crucible","addresses":["fd00:1122:3344:120::b"],"dataset":{"id":"018edff1-0d95-45a3-9a01-39c419bec55a","name":{"pool_name":"oxp_0b11e026-f265-49a0-935f-7b234c19c789","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::b]:32345"},"services":[{"id":"018edff1-0d95-45a3-9a01-39c419bec55a","details":{"type":"crucible","address":"[fd00:1122:3344:120::b]:32345"}}]},"root":"/pool/ext/35db8700-d6a7-498c-9d2c-08eb9ab41b7c/crypt/zone"},{"zone":{"id":"f8cc1c1e-a556-436c-836d-42052101c38a","zone_type":"crucible","addresses":["fd00:1122:3344:120::3"],"dataset":{"id":"f8cc1c1e-a556-436c-836d-42052101c38a","name":{"pool_name":"oxp_ed8e5a26-5591-405a-b792-408f5b16e444","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::3]:32345"},"services":[{"id":"f8cc1c1e-a556-436c-836d-42052101c38a","details":{"type":"crucible","address":"[fd00:1122:3344:120::3]:32345"}}]},"root":"/pool/ext/1069bdee-fe5a-4164-a856-ff8ae56c07fb/crypt/zone"},{"zone":{"id":"f9600313-fac0-45a1-a1b5-02dd6af468b9","zone_type":"crucible","addresses":["fd00:1122:3344:120::4"],"dataset":{"id":"f9600313-fac0-45a1-a1b5-02dd6af468b9","name":{"pool_name":"oxp_c1f0a9e4-ea10-4fd9-8b6d-79a2bacfec5e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::4]:32345"},"services":[{"id":"f9600313-fac0-45a1-a1b5-02dd6af468b9","details":{"type":"crucible","address":"[fd00:1122:3344:120::4]:32345"}}]},"root":"/pool/ext/74046573-78a2-46b4-86dc-40bb2ee29dd5/crypt/zone"},{"zone":{"id":"869e4f7c-5312-4b98-bacc-1508f236bf5a","zone_type":"crucible","addresses":["fd00:1122:3344:120::6"],"dataset":{"id":"869e4f7c-5312-4b98-bacc-1508f236bf5a","name":{"pool_name":"oxp_04aea8dc-4316-432f-a13a-d7d9b2efa3f2","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::6]:32345"},"services":[{"id":"869e4f7c-5312-4b98-bacc-1508f236bf5a","details":{"type":"crucible","address":"[fd00:1122:3344:120::6]:32345"}}]},"root":"/pool/ext/0b11e026-f265-49a0-935f-7b234c19c789/crypt/zone"},{"zone":{"id":"31ed5a0c-7caf-4825-b730-85ee94fe27f1","zone_type":"crucible","addresses":["fd00:1122:3344:120::a"],"dataset":{"id":"31ed5a0c-7caf-4825-b730-85ee94fe27f1","name":{"pool_name":"oxp_86cd16cf-d00d-40bc-b14a-8220b1e11476","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::a]:32345"},"services":[{"id":"31ed5a0c-7caf-4825-b730-85ee94fe27f1","details":{"type":"crucible","address":"[fd00:1122:3344:120::a]:32345"}}]},"root":"/pool/ext/04aea8dc-4316-432f-a13a-d7d9b2efa3f2/crypt/zone"},{"zone":{"id":"7e5a3c39-152a-4270-b01e-9e144cca4aaa","zone_type":"crucible","addresses":["fd00:1122:3344:120::5"],"dataset":{"id":"7e5a3c39-152a-4270-b01e-9e144cca4aaa","name":{"pool_name":"oxp_1069bdee-fe5a-4164-a856-ff8ae56c07fb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::5]:32345"},"services":[{"id":"7e5a3c39-152a-4270-b01e-9e144cca4aaa","details":{"type":"crucible","address":"[fd00:1122:3344:120::5]:32345"}}]},"root":"/pool/ext/04aea8dc-4316-432f-a13a-d7d9b2efa3f2/crypt/zone"},{"zone":{"id":"9a03a386-7304-4a86-bee8-153ef643195e","zone_type":"crucible","addresses":["fd00:1122:3344:120::7"],"dataset":{"id":"9a03a386-7304-4a86-bee8-153ef643195e","name":{"pool_name":"oxp_35db8700-d6a7-498c-9d2c-08eb9ab41b7c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:120::7]:32345"},"services":[{"id":"9a03a386-7304-4a86-bee8-153ef643195e","details":{"type":"crucible","address":"[fd00:1122:3344:120::7]:32345"}}]},"root":"/pool/ext/068d2790-1044-41ed-97a5-b493490b14d1/crypt/zone"},{"zone":{"id":"a800d0a7-1020-481c-8be8-ecfd28b7a2be","zone_type":"ntp","addresses":["fd00:1122:3344:120::d"],"dataset":null,"services":[{"id":"a800d0a7-1020-481c-8be8-ecfd28b7a2be","details":{"type":"internal_ntp","address":"[fd00:1122:3344:120::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/c1f0a9e4-ea10-4fd9-8b6d-79a2bacfec5e/crypt/zone"},{"zone":{"id":"be469efd-8e07-4b8e-bcee-6fd33373cdef","zone_type":"internal_dns","addresses":["fd00:1122:3344:3::1"],"dataset":{"id":"be469efd-8e07-4b8e-bcee-6fd33373cdef","name":{"pool_name":"oxp_ed8e5a26-5591-405a-b792-408f5b16e444","kind":{"type":"internal_dns"}},"service_address":"[fd00:1122:3344:3::1]:5353"},"services":[{"id":"be469efd-8e07-4b8e-bcee-6fd33373cdef","details":{"type":"internal_dns","http_address":"[fd00:1122:3344:3::1]:5353","dns_address":"[fd00:1122:3344:3::1]:53","gz_address":"fd00:1122:3344:3::2","gz_address_index":2}}]},"root":"/pool/ext/068d2790-1044-41ed-97a5-b493490b14d1/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled3.json b/sled-agent/tests/old-service-ledgers/rack3-sled3.json deleted file mode 100644 index 6bcb626cf6..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled3.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"19d091b8-e005-4ff4-97e1-026de95e3667","zone_type":"crucible","addresses":["fd00:1122:3344:10f::c"],"dataset":{"id":"19d091b8-e005-4ff4-97e1-026de95e3667","name":{"pool_name":"oxp_11a63469-4f57-4976-8620-0055bf82dc97","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::c]:32345"},"services":[{"id":"19d091b8-e005-4ff4-97e1-026de95e3667","details":{"type":"crucible","address":"[fd00:1122:3344:10f::c]:32345"}}]},"root":"/pool/ext/6a73a62c-c636-4557-af45-042cb287aee6/crypt/zone"},{"zone":{"id":"57d77171-104e-4977-b2f9-9b529ee7f8a0","zone_type":"crucible","addresses":["fd00:1122:3344:10f::8"],"dataset":{"id":"57d77171-104e-4977-b2f9-9b529ee7f8a0","name":{"pool_name":"oxp_7f3060af-058f-4f52-ab80-902bd13e7ef4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::8]:32345"},"services":[{"id":"57d77171-104e-4977-b2f9-9b529ee7f8a0","details":{"type":"crucible","address":"[fd00:1122:3344:10f::8]:32345"}}]},"root":"/pool/ext/7f3060af-058f-4f52-ab80-902bd13e7ef4/crypt/zone"},{"zone":{"id":"b0371ccf-67da-4562-baf2-eaabe5243e9b","zone_type":"crucible","addresses":["fd00:1122:3344:10f::7"],"dataset":{"id":"b0371ccf-67da-4562-baf2-eaabe5243e9b","name":{"pool_name":"oxp_58ae04cb-26ff-4e30-a20d-9f847bafba4d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::7]:32345"},"services":[{"id":"b0371ccf-67da-4562-baf2-eaabe5243e9b","details":{"type":"crucible","address":"[fd00:1122:3344:10f::7]:32345"}}]},"root":"/pool/ext/125ddcda-f94b-46bc-a10a-94e9acf40265/crypt/zone"},{"zone":{"id":"ae3791ff-2657-4252-bd61-58ec5dc237cd","zone_type":"crucible","addresses":["fd00:1122:3344:10f::9"],"dataset":{"id":"ae3791ff-2657-4252-bd61-58ec5dc237cd","name":{"pool_name":"oxp_125ddcda-f94b-46bc-a10a-94e9acf40265","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::9]:32345"},"services":[{"id":"ae3791ff-2657-4252-bd61-58ec5dc237cd","details":{"type":"crucible","address":"[fd00:1122:3344:10f::9]:32345"}}]},"root":"/pool/ext/58ae04cb-26ff-4e30-a20d-9f847bafba4d/crypt/zone"},{"zone":{"id":"73f865dc-5db7-48c6-9dc4-dff56dd8c045","zone_type":"crucible_pantry","addresses":["fd00:1122:3344:10f::3"],"dataset":null,"services":[{"id":"73f865dc-5db7-48c6-9dc4-dff56dd8c045","details":{"type":"crucible_pantry","address":"[fd00:1122:3344:10f::3]:17000"}}]},"root":"/pool/ext/11a63469-4f57-4976-8620-0055bf82dc97/crypt/zone"},{"zone":{"id":"e5d0170a-0d60-4c51-8f72-4c301979690e","zone_type":"crucible","addresses":["fd00:1122:3344:10f::6"],"dataset":{"id":"e5d0170a-0d60-4c51-8f72-4c301979690e","name":{"pool_name":"oxp_efe4cbab-2a39-4d7d-ae6c-83eb3ab8d4b5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::6]:32345"},"services":[{"id":"e5d0170a-0d60-4c51-8f72-4c301979690e","details":{"type":"crucible","address":"[fd00:1122:3344:10f::6]:32345"}}]},"root":"/pool/ext/6a73a62c-c636-4557-af45-042cb287aee6/crypt/zone"},{"zone":{"id":"ea6894de-c575-43bc-86e9-65b8a58499ff","zone_type":"crucible","addresses":["fd00:1122:3344:10f::a"],"dataset":{"id":"ea6894de-c575-43bc-86e9-65b8a58499ff","name":{"pool_name":"oxp_a87dc882-8b88-4a99-9628-5db79072cffa","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::a]:32345"},"services":[{"id":"ea6894de-c575-43bc-86e9-65b8a58499ff","details":{"type":"crucible","address":"[fd00:1122:3344:10f::a]:32345"}}]},"root":"/pool/ext/11a63469-4f57-4976-8620-0055bf82dc97/crypt/zone"},{"zone":{"id":"3081dc99-4fa9-4238-adfa-b9ca381c1f7b","zone_type":"crucible","addresses":["fd00:1122:3344:10f::b"],"dataset":{"id":"3081dc99-4fa9-4238-adfa-b9ca381c1f7b","name":{"pool_name":"oxp_6a73a62c-c636-4557-af45-042cb287aee6","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::b]:32345"},"services":[{"id":"3081dc99-4fa9-4238-adfa-b9ca381c1f7b","details":{"type":"crucible","address":"[fd00:1122:3344:10f::b]:32345"}}]},"root":"/pool/ext/a87dc882-8b88-4a99-9628-5db79072cffa/crypt/zone"},{"zone":{"id":"b4a3d7c8-487d-4d76-ae4e-a6a51595a5a6","zone_type":"crucible","addresses":["fd00:1122:3344:10f::d"],"dataset":{"id":"b4a3d7c8-487d-4d76-ae4e-a6a51595a5a6","name":{"pool_name":"oxp_a12f87ee-9918-4269-9de4-4bad4fb41caa","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::d]:32345"},"services":[{"id":"b4a3d7c8-487d-4d76-ae4e-a6a51595a5a6","details":{"type":"crucible","address":"[fd00:1122:3344:10f::d]:32345"}}]},"root":"/pool/ext/a12f87ee-9918-4269-9de4-4bad4fb41caa/crypt/zone"},{"zone":{"id":"5ebcee26-f76c-4206-8d81-584ac138d3b9","zone_type":"crucible","addresses":["fd00:1122:3344:10f::4"],"dataset":{"id":"5ebcee26-f76c-4206-8d81-584ac138d3b9","name":{"pool_name":"oxp_27f1917e-fb69-496a-9d40-8ef0d0c0ee55","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::4]:32345"},"services":[{"id":"5ebcee26-f76c-4206-8d81-584ac138d3b9","details":{"type":"crucible","address":"[fd00:1122:3344:10f::4]:32345"}}]},"root":"/pool/ext/58ae04cb-26ff-4e30-a20d-9f847bafba4d/crypt/zone"},{"zone":{"id":"90b2bc57-3a2a-4117-bb6d-7eda7542329a","zone_type":"crucible","addresses":["fd00:1122:3344:10f::5"],"dataset":{"id":"90b2bc57-3a2a-4117-bb6d-7eda7542329a","name":{"pool_name":"oxp_a222e405-40f6-4fdd-9146-94f7d94ed08a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10f::5]:32345"},"services":[{"id":"90b2bc57-3a2a-4117-bb6d-7eda7542329a","details":{"type":"crucible","address":"[fd00:1122:3344:10f::5]:32345"}}]},"root":"/pool/ext/a12f87ee-9918-4269-9de4-4bad4fb41caa/crypt/zone"},{"zone":{"id":"0fb540af-58d3-4abc-bfad-e49765c2b1ee","zone_type":"ntp","addresses":["fd00:1122:3344:10f::e"],"dataset":null,"services":[{"id":"0fb540af-58d3-4abc-bfad-e49765c2b1ee","details":{"type":"internal_ntp","address":"[fd00:1122:3344:10f::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/58ae04cb-26ff-4e30-a20d-9f847bafba4d/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled30.json b/sled-agent/tests/old-service-ledgers/rack3-sled30.json deleted file mode 100644 index e919de3488..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled30.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"dda0f1c6-84a5-472c-b350-a799c8d3d0eb","zone_type":"crucible","addresses":["fd00:1122:3344:115::8"],"dataset":{"id":"dda0f1c6-84a5-472c-b350-a799c8d3d0eb","name":{"pool_name":"oxp_028b6c9e-5a0e-43d2-a8ed-a5946cf62924","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::8]:32345"},"services":[{"id":"dda0f1c6-84a5-472c-b350-a799c8d3d0eb","details":{"type":"crucible","address":"[fd00:1122:3344:115::8]:32345"}}]},"root":"/pool/ext/b8d84b9c-a65e-4c86-8196-69da5317ae63/crypt/zone"},{"zone":{"id":"157672f9-113f-48b7-9808-dff3c3e67dcd","zone_type":"crucible","addresses":["fd00:1122:3344:115::a"],"dataset":{"id":"157672f9-113f-48b7-9808-dff3c3e67dcd","name":{"pool_name":"oxp_4fdca201-b37e-4072-a1cc-3cb7705954eb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::a]:32345"},"services":[{"id":"157672f9-113f-48b7-9808-dff3c3e67dcd","details":{"type":"crucible","address":"[fd00:1122:3344:115::a]:32345"}}]},"root":"/pool/ext/b8d84b9c-a65e-4c86-8196-69da5317ae63/crypt/zone"},{"zone":{"id":"5a7d4f67-a70f-4d8b-8d35-4dc600991fb5","zone_type":"crucible","addresses":["fd00:1122:3344:115::5"],"dataset":{"id":"5a7d4f67-a70f-4d8b-8d35-4dc600991fb5","name":{"pool_name":"oxp_11a991e5-19a9-48b0-8186-34249ef67957","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::5]:32345"},"services":[{"id":"5a7d4f67-a70f-4d8b-8d35-4dc600991fb5","details":{"type":"crucible","address":"[fd00:1122:3344:115::5]:32345"}}]},"root":"/pool/ext/1e9c9764-aaa4-4681-b110-a937b4c52748/crypt/zone"},{"zone":{"id":"c7036645-b680-4816-834f-8ae1af24c159","zone_type":"crucible","addresses":["fd00:1122:3344:115::b"],"dataset":{"id":"c7036645-b680-4816-834f-8ae1af24c159","name":{"pool_name":"oxp_0780be56-c13d-4c6a-a1ac-37753a0da820","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::b]:32345"},"services":[{"id":"c7036645-b680-4816-834f-8ae1af24c159","details":{"type":"crucible","address":"[fd00:1122:3344:115::b]:32345"}}]},"root":"/pool/ext/80a8d756-ee22-4c88-8b5b-4a46f7eca249/crypt/zone"},{"zone":{"id":"45e47e4b-708f-40b5-a8c8-fbfd73696d45","zone_type":"crucible","addresses":["fd00:1122:3344:115::7"],"dataset":{"id":"45e47e4b-708f-40b5-a8c8-fbfd73696d45","name":{"pool_name":"oxp_80a8d756-ee22-4c88-8b5b-4a46f7eca249","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::7]:32345"},"services":[{"id":"45e47e4b-708f-40b5-a8c8-fbfd73696d45","details":{"type":"crucible","address":"[fd00:1122:3344:115::7]:32345"}}]},"root":"/pool/ext/4fdca201-b37e-4072-a1cc-3cb7705954eb/crypt/zone"},{"zone":{"id":"e805b0c1-3f80-49da-8dc1-caaf843e5003","zone_type":"crucible","addresses":["fd00:1122:3344:115::c"],"dataset":{"id":"e805b0c1-3f80-49da-8dc1-caaf843e5003","name":{"pool_name":"oxp_d54e1ed7-e589-4413-a487-6e9a257104e7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::c]:32345"},"services":[{"id":"e805b0c1-3f80-49da-8dc1-caaf843e5003","details":{"type":"crucible","address":"[fd00:1122:3344:115::c]:32345"}}]},"root":"/pool/ext/d54e1ed7-e589-4413-a487-6e9a257104e7/crypt/zone"},{"zone":{"id":"e47d3f81-3df6-4c35-bec6-41277bc74c07","zone_type":"crucible","addresses":["fd00:1122:3344:115::4"],"dataset":{"id":"e47d3f81-3df6-4c35-bec6-41277bc74c07","name":{"pool_name":"oxp_b8d84b9c-a65e-4c86-8196-69da5317ae63","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::4]:32345"},"services":[{"id":"e47d3f81-3df6-4c35-bec6-41277bc74c07","details":{"type":"crucible","address":"[fd00:1122:3344:115::4]:32345"}}]},"root":"/pool/ext/772b3aaa-3501-4dc7-9b3d-048b8b1f7970/crypt/zone"},{"zone":{"id":"2a796a69-b061-44c7-b2df-35bc611f10f5","zone_type":"crucible","addresses":["fd00:1122:3344:115::6"],"dataset":{"id":"2a796a69-b061-44c7-b2df-35bc611f10f5","name":{"pool_name":"oxp_73abe9e0-d38e-48fc-bdec-b094bfa5670d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::6]:32345"},"services":[{"id":"2a796a69-b061-44c7-b2df-35bc611f10f5","details":{"type":"crucible","address":"[fd00:1122:3344:115::6]:32345"}}]},"root":"/pool/ext/028b6c9e-5a0e-43d2-a8ed-a5946cf62924/crypt/zone"},{"zone":{"id":"4e1d2af1-8ef4-4762-aa80-b08da08b45bb","zone_type":"crucible","addresses":["fd00:1122:3344:115::3"],"dataset":{"id":"4e1d2af1-8ef4-4762-aa80-b08da08b45bb","name":{"pool_name":"oxp_772b3aaa-3501-4dc7-9b3d-048b8b1f7970","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::3]:32345"},"services":[{"id":"4e1d2af1-8ef4-4762-aa80-b08da08b45bb","details":{"type":"crucible","address":"[fd00:1122:3344:115::3]:32345"}}]},"root":"/pool/ext/d54e1ed7-e589-4413-a487-6e9a257104e7/crypt/zone"},{"zone":{"id":"fb1b10d5-b7cb-416d-98fc-b5d3bc02d495","zone_type":"crucible","addresses":["fd00:1122:3344:115::9"],"dataset":{"id":"fb1b10d5-b7cb-416d-98fc-b5d3bc02d495","name":{"pool_name":"oxp_1e9c9764-aaa4-4681-b110-a937b4c52748","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:115::9]:32345"},"services":[{"id":"fb1b10d5-b7cb-416d-98fc-b5d3bc02d495","details":{"type":"crucible","address":"[fd00:1122:3344:115::9]:32345"}}]},"root":"/pool/ext/b8d84b9c-a65e-4c86-8196-69da5317ae63/crypt/zone"},{"zone":{"id":"5155463c-8a09-45a5-ad1b-817f2e93b284","zone_type":"ntp","addresses":["fd00:1122:3344:115::d"],"dataset":null,"services":[{"id":"5155463c-8a09-45a5-ad1b-817f2e93b284","details":{"type":"internal_ntp","address":"[fd00:1122:3344:115::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/772b3aaa-3501-4dc7-9b3d-048b8b1f7970/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled31.json b/sled-agent/tests/old-service-ledgers/rack3-sled31.json deleted file mode 100644 index d984227227..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled31.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"a0eae689-8e6b-4297-bb3d-8b7ffc5c4a07","zone_type":"crucible","addresses":["fd00:1122:3344:102::c"],"dataset":{"id":"a0eae689-8e6b-4297-bb3d-8b7ffc5c4a07","name":{"pool_name":"oxp_274cb567-fd74-4e00-b9c7-6ca367b3fda4","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::c]:32345"},"services":[{"id":"a0eae689-8e6b-4297-bb3d-8b7ffc5c4a07","details":{"type":"crucible","address":"[fd00:1122:3344:102::c]:32345"}}]},"root":"/pool/ext/1443b190-de16-42b0-b881-e87e875dd507/crypt/zone"},{"zone":{"id":"9cea406d-451e-4328-9052-b58487f799a5","zone_type":"crucible","addresses":["fd00:1122:3344:102::b"],"dataset":{"id":"9cea406d-451e-4328-9052-b58487f799a5","name":{"pool_name":"oxp_89c7f72e-632c-462b-a515-01cd80683711","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::b]:32345"},"services":[{"id":"9cea406d-451e-4328-9052-b58487f799a5","details":{"type":"crucible","address":"[fd00:1122:3344:102::b]:32345"}}]},"root":"/pool/ext/274cb567-fd74-4e00-b9c7-6ca367b3fda4/crypt/zone"},{"zone":{"id":"9c7dad7e-7f60-4bf4-8efc-0883a17e7cf6","zone_type":"crucible","addresses":["fd00:1122:3344:102::6"],"dataset":{"id":"9c7dad7e-7f60-4bf4-8efc-0883a17e7cf6","name":{"pool_name":"oxp_2c8e5637-b989-4b8f-82ac-ff2e9102b560","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::6]:32345"},"services":[{"id":"9c7dad7e-7f60-4bf4-8efc-0883a17e7cf6","details":{"type":"crucible","address":"[fd00:1122:3344:102::6]:32345"}}]},"root":"/pool/ext/1443b190-de16-42b0-b881-e87e875dd507/crypt/zone"},{"zone":{"id":"73015cba-79c6-4a67-97d8-fa0819cbf750","zone_type":"crucible","addresses":["fd00:1122:3344:102::a"],"dataset":{"id":"73015cba-79c6-4a67-97d8-fa0819cbf750","name":{"pool_name":"oxp_fa62108e-f7bb-4f6d-86f3-8094a1ea8352","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::a]:32345"},"services":[{"id":"73015cba-79c6-4a67-97d8-fa0819cbf750","details":{"type":"crucible","address":"[fd00:1122:3344:102::a]:32345"}}]},"root":"/pool/ext/2c8e5637-b989-4b8f-82ac-ff2e9102b560/crypt/zone"},{"zone":{"id":"f9ca3097-072e-4e7f-9f50-eb7c7ae39b6f","zone_type":"crucible","addresses":["fd00:1122:3344:102::5"],"dataset":{"id":"f9ca3097-072e-4e7f-9f50-eb7c7ae39b6f","name":{"pool_name":"oxp_42c6602c-2ccf-48ce-8344-693c832fd693","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::5]:32345"},"services":[{"id":"f9ca3097-072e-4e7f-9f50-eb7c7ae39b6f","details":{"type":"crucible","address":"[fd00:1122:3344:102::5]:32345"}}]},"root":"/pool/ext/2c8e5637-b989-4b8f-82ac-ff2e9102b560/crypt/zone"},{"zone":{"id":"e7855e05-a125-4a80-ac2c-8a2db96e1bf8","zone_type":"crucible","addresses":["fd00:1122:3344:102::7"],"dataset":{"id":"e7855e05-a125-4a80-ac2c-8a2db96e1bf8","name":{"pool_name":"oxp_1f72afd3-d2aa-46a8-b81a-54dbcc2f6317","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::7]:32345"},"services":[{"id":"e7855e05-a125-4a80-ac2c-8a2db96e1bf8","details":{"type":"crucible","address":"[fd00:1122:3344:102::7]:32345"}}]},"root":"/pool/ext/42c6602c-2ccf-48ce-8344-693c832fd693/crypt/zone"},{"zone":{"id":"e5de9bc9-e996-4fea-8318-ad7a8a6be4a3","zone_type":"crucible","addresses":["fd00:1122:3344:102::4"],"dataset":{"id":"e5de9bc9-e996-4fea-8318-ad7a8a6be4a3","name":{"pool_name":"oxp_1443b190-de16-42b0-b881-e87e875dd507","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::4]:32345"},"services":[{"id":"e5de9bc9-e996-4fea-8318-ad7a8a6be4a3","details":{"type":"crucible","address":"[fd00:1122:3344:102::4]:32345"}}]},"root":"/pool/ext/89c7f72e-632c-462b-a515-01cd80683711/crypt/zone"},{"zone":{"id":"cd0d0aac-44ff-4566-9260-a64ae6cecef4","zone_type":"crucible","addresses":["fd00:1122:3344:102::8"],"dataset":{"id":"cd0d0aac-44ff-4566-9260-a64ae6cecef4","name":{"pool_name":"oxp_92c0d1f6-cb4d-4ddb-b5ba-979fb3491812","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::8]:32345"},"services":[{"id":"cd0d0aac-44ff-4566-9260-a64ae6cecef4","details":{"type":"crucible","address":"[fd00:1122:3344:102::8]:32345"}}]},"root":"/pool/ext/89c7f72e-632c-462b-a515-01cd80683711/crypt/zone"},{"zone":{"id":"a8230592-0e7a-46c8-a653-7587a27f05bf","zone_type":"crucible","addresses":["fd00:1122:3344:102::9"],"dataset":{"id":"a8230592-0e7a-46c8-a653-7587a27f05bf","name":{"pool_name":"oxp_1b7873de-99fd-454f-b576-bff695524133","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::9]:32345"},"services":[{"id":"a8230592-0e7a-46c8-a653-7587a27f05bf","details":{"type":"crucible","address":"[fd00:1122:3344:102::9]:32345"}}]},"root":"/pool/ext/92c0d1f6-cb4d-4ddb-b5ba-979fb3491812/crypt/zone"},{"zone":{"id":"c19ffbb1-4dc1-4825-a3cf-080e9b543b16","zone_type":"crucible","addresses":["fd00:1122:3344:102::d"],"dataset":{"id":"c19ffbb1-4dc1-4825-a3cf-080e9b543b16","name":{"pool_name":"oxp_67823df7-511c-4984-b98c-7a8f5c40c22d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:102::d]:32345"},"services":[{"id":"c19ffbb1-4dc1-4825-a3cf-080e9b543b16","details":{"type":"crucible","address":"[fd00:1122:3344:102::d]:32345"}}]},"root":"/pool/ext/1443b190-de16-42b0-b881-e87e875dd507/crypt/zone"},{"zone":{"id":"ff30fe7c-51f3-43b9-a788-d8f94a7bb028","zone_type":"cockroach_db","addresses":["fd00:1122:3344:102::3"],"dataset":{"id":"ff30fe7c-51f3-43b9-a788-d8f94a7bb028","name":{"pool_name":"oxp_1443b190-de16-42b0-b881-e87e875dd507","kind":{"type":"cockroach_db"}},"service_address":"[fd00:1122:3344:102::3]:32221"},"services":[{"id":"ff30fe7c-51f3-43b9-a788-d8f94a7bb028","details":{"type":"cockroach_db","address":"[fd00:1122:3344:102::3]:32221"}}]},"root":"/pool/ext/fa62108e-f7bb-4f6d-86f3-8094a1ea8352/crypt/zone"},{"zone":{"id":"16b50c55-8117-4efd-aabf-0273677b89d5","zone_type":"ntp","addresses":["fd00:1122:3344:102::e"],"dataset":null,"services":[{"id":"16b50c55-8117-4efd-aabf-0273677b89d5","details":{"type":"internal_ntp","address":"[fd00:1122:3344:102::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/fa62108e-f7bb-4f6d-86f3-8094a1ea8352/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled4.json b/sled-agent/tests/old-service-ledgers/rack3-sled4.json deleted file mode 100644 index e9e5ce5569..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled4.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"22452953-ee80-4659-a555-8e027bf205b0","zone_type":"crucible","addresses":["fd00:1122:3344:10c::4"],"dataset":{"id":"22452953-ee80-4659-a555-8e027bf205b0","name":{"pool_name":"oxp_92ba1667-a6f7-4913-9b00-14825384c7bf","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::4]:32345"},"services":[{"id":"22452953-ee80-4659-a555-8e027bf205b0","details":{"type":"crucible","address":"[fd00:1122:3344:10c::4]:32345"}}]},"root":"/pool/ext/ab62b941-5f84-42c7-929d-295b20efffe7/crypt/zone"},{"zone":{"id":"9a5a2fcf-44a0-4468-979a-a71686cef627","zone_type":"crucible","addresses":["fd00:1122:3344:10c::3"],"dataset":{"id":"9a5a2fcf-44a0-4468-979a-a71686cef627","name":{"pool_name":"oxp_dbfdc981-1b81-4d7d-9449-9530890b199a","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::3]:32345"},"services":[{"id":"9a5a2fcf-44a0-4468-979a-a71686cef627","details":{"type":"crucible","address":"[fd00:1122:3344:10c::3]:32345"}}]},"root":"/pool/ext/74ac4da9-cdae-4c08-8431-11211184aa09/crypt/zone"},{"zone":{"id":"a014f12e-2636-4258-af76-e01d9b8d1c1f","zone_type":"crucible","addresses":["fd00:1122:3344:10c::b"],"dataset":{"id":"a014f12e-2636-4258-af76-e01d9b8d1c1f","name":{"pool_name":"oxp_ab62b941-5f84-42c7-929d-295b20efffe7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::b]:32345"},"services":[{"id":"a014f12e-2636-4258-af76-e01d9b8d1c1f","details":{"type":"crucible","address":"[fd00:1122:3344:10c::b]:32345"}}]},"root":"/pool/ext/a624a843-1c4e-41c3-a1d2-4be7a6c57e9b/crypt/zone"},{"zone":{"id":"431768b8-26ba-4ab4-b616-9e183bb79b8b","zone_type":"crucible","addresses":["fd00:1122:3344:10c::7"],"dataset":{"id":"431768b8-26ba-4ab4-b616-9e183bb79b8b","name":{"pool_name":"oxp_7c121177-3210-4457-9b42-3657add6e166","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::7]:32345"},"services":[{"id":"431768b8-26ba-4ab4-b616-9e183bb79b8b","details":{"type":"crucible","address":"[fd00:1122:3344:10c::7]:32345"}}]},"root":"/pool/ext/74ac4da9-cdae-4c08-8431-11211184aa09/crypt/zone"},{"zone":{"id":"22992c56-bd5a-4d0f-86c5-d6f8e87b7bbb","zone_type":"crucible","addresses":["fd00:1122:3344:10c::9"],"dataset":{"id":"22992c56-bd5a-4d0f-86c5-d6f8e87b7bbb","name":{"pool_name":"oxp_842bdd28-196e-4b18-83db-68bd81176a44","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::9]:32345"},"services":[{"id":"22992c56-bd5a-4d0f-86c5-d6f8e87b7bbb","details":{"type":"crucible","address":"[fd00:1122:3344:10c::9]:32345"}}]},"root":"/pool/ext/74ac4da9-cdae-4c08-8431-11211184aa09/crypt/zone"},{"zone":{"id":"de376149-aa45-4660-9ae6-15e8ba4a4233","zone_type":"crucible","addresses":["fd00:1122:3344:10c::5"],"dataset":{"id":"de376149-aa45-4660-9ae6-15e8ba4a4233","name":{"pool_name":"oxp_25856a84-6707-4b94-81d1-b43d5bc990d7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::5]:32345"},"services":[{"id":"de376149-aa45-4660-9ae6-15e8ba4a4233","details":{"type":"crucible","address":"[fd00:1122:3344:10c::5]:32345"}}]},"root":"/pool/ext/7c121177-3210-4457-9b42-3657add6e166/crypt/zone"},{"zone":{"id":"ceeba69d-8c0a-47df-a37b-7f1b90f23016","zone_type":"crucible","addresses":["fd00:1122:3344:10c::a"],"dataset":{"id":"ceeba69d-8c0a-47df-a37b-7f1b90f23016","name":{"pool_name":"oxp_a624a843-1c4e-41c3-a1d2-4be7a6c57e9b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::a]:32345"},"services":[{"id":"ceeba69d-8c0a-47df-a37b-7f1b90f23016","details":{"type":"crucible","address":"[fd00:1122:3344:10c::a]:32345"}}]},"root":"/pool/ext/74ac4da9-cdae-4c08-8431-11211184aa09/crypt/zone"},{"zone":{"id":"65293ce4-2e63-4336-9207-3c61f58667f9","zone_type":"crucible","addresses":["fd00:1122:3344:10c::c"],"dataset":{"id":"65293ce4-2e63-4336-9207-3c61f58667f9","name":{"pool_name":"oxp_74ac4da9-cdae-4c08-8431-11211184aa09","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::c]:32345"},"services":[{"id":"65293ce4-2e63-4336-9207-3c61f58667f9","details":{"type":"crucible","address":"[fd00:1122:3344:10c::c]:32345"}}]},"root":"/pool/ext/842bdd28-196e-4b18-83db-68bd81176a44/crypt/zone"},{"zone":{"id":"e8f55a5d-65f9-436c-bc25-1d1a7070e876","zone_type":"crucible","addresses":["fd00:1122:3344:10c::6"],"dataset":{"id":"e8f55a5d-65f9-436c-bc25-1d1a7070e876","name":{"pool_name":"oxp_9bfe385c-16dd-4209-bc0b-f28ae75d58e3","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::6]:32345"},"services":[{"id":"e8f55a5d-65f9-436c-bc25-1d1a7070e876","details":{"type":"crucible","address":"[fd00:1122:3344:10c::6]:32345"}}]},"root":"/pool/ext/92ba1667-a6f7-4913-9b00-14825384c7bf/crypt/zone"},{"zone":{"id":"2dfbd4c6-afbf-4c8c-bf40-764f02727852","zone_type":"crucible","addresses":["fd00:1122:3344:10c::8"],"dataset":{"id":"2dfbd4c6-afbf-4c8c-bf40-764f02727852","name":{"pool_name":"oxp_55eb093d-6b6f-418c-9767-09afe4c51fff","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10c::8]:32345"},"services":[{"id":"2dfbd4c6-afbf-4c8c-bf40-764f02727852","details":{"type":"crucible","address":"[fd00:1122:3344:10c::8]:32345"}}]},"root":"/pool/ext/dbfdc981-1b81-4d7d-9449-9530890b199a/crypt/zone"},{"zone":{"id":"8c73baf7-1a58-4e2c-b4d1-966c89a18d03","zone_type":"ntp","addresses":["fd00:1122:3344:10c::d"],"dataset":null,"services":[{"id":"8c73baf7-1a58-4e2c-b4d1-966c89a18d03","details":{"type":"internal_ntp","address":"[fd00:1122:3344:10c::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/842bdd28-196e-4b18-83db-68bd81176a44/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled5.json b/sled-agent/tests/old-service-ledgers/rack3-sled5.json deleted file mode 100644 index ea7b5ec40a..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled5.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"2f488e7b-fd93-48a6-8b2b-61f6e8336268","zone_type":"crucible","addresses":["fd00:1122:3344:101::b"],"dataset":{"id":"2f488e7b-fd93-48a6-8b2b-61f6e8336268","name":{"pool_name":"oxp_5840a3b7-f765-45d3-8a41-7f543f936bee","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::b]:32345"},"services":[{"id":"2f488e7b-fd93-48a6-8b2b-61f6e8336268","details":{"type":"crucible","address":"[fd00:1122:3344:101::b]:32345"}}]},"root":"/pool/ext/dd084b76-1130-4ad3-9196-6b02be607fe9/crypt/zone"},{"zone":{"id":"1ed5fd3f-933a-4921-a91f-5c286823f8d4","zone_type":"crucible","addresses":["fd00:1122:3344:101::a"],"dataset":{"id":"1ed5fd3f-933a-4921-a91f-5c286823f8d4","name":{"pool_name":"oxp_c1e807e7-b64a-4dbd-b845-ffed0b9a54f1","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::a]:32345"},"services":[{"id":"1ed5fd3f-933a-4921-a91f-5c286823f8d4","details":{"type":"crucible","address":"[fd00:1122:3344:101::a]:32345"}}]},"root":"/pool/ext/be06ea9c-df86-4fec-b5dd-8809710893af/crypt/zone"},{"zone":{"id":"0f8f1013-465d-4b49-b55d-f0b9bf6f789a","zone_type":"crucible","addresses":["fd00:1122:3344:101::6"],"dataset":{"id":"0f8f1013-465d-4b49-b55d-f0b9bf6f789a","name":{"pool_name":"oxp_4dfa7003-0305-47f5-b23d-88a228c1e12e","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::6]:32345"},"services":[{"id":"0f8f1013-465d-4b49-b55d-f0b9bf6f789a","details":{"type":"crucible","address":"[fd00:1122:3344:101::6]:32345"}}]},"root":"/pool/ext/be06ea9c-df86-4fec-b5dd-8809710893af/crypt/zone"},{"zone":{"id":"2e4ef017-6c62-40bc-bab5-f2e01addad22","zone_type":"crucible","addresses":["fd00:1122:3344:101::7"],"dataset":{"id":"2e4ef017-6c62-40bc-bab5-f2e01addad22","name":{"pool_name":"oxp_d94e9c58-e6d1-444b-b7d8-19ac17dea042","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::7]:32345"},"services":[{"id":"2e4ef017-6c62-40bc-bab5-f2e01addad22","details":{"type":"crucible","address":"[fd00:1122:3344:101::7]:32345"}}]},"root":"/pool/ext/c1e807e7-b64a-4dbd-b845-ffed0b9a54f1/crypt/zone"},{"zone":{"id":"6a0baf13-a80b-4778-a0ab-a69cd851de2d","zone_type":"crucible","addresses":["fd00:1122:3344:101::9"],"dataset":{"id":"6a0baf13-a80b-4778-a0ab-a69cd851de2d","name":{"pool_name":"oxp_be06ea9c-df86-4fec-b5dd-8809710893af","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::9]:32345"},"services":[{"id":"6a0baf13-a80b-4778-a0ab-a69cd851de2d","details":{"type":"crucible","address":"[fd00:1122:3344:101::9]:32345"}}]},"root":"/pool/ext/a9d419d4-5915-4a40-baa3-3512785de034/crypt/zone"},{"zone":{"id":"391ec257-fd47-4cc8-9bfa-49a0747a9a67","zone_type":"crucible","addresses":["fd00:1122:3344:101::8"],"dataset":{"id":"391ec257-fd47-4cc8-9bfa-49a0747a9a67","name":{"pool_name":"oxp_a9d419d4-5915-4a40-baa3-3512785de034","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::8]:32345"},"services":[{"id":"391ec257-fd47-4cc8-9bfa-49a0747a9a67","details":{"type":"crucible","address":"[fd00:1122:3344:101::8]:32345"}}]},"root":"/pool/ext/709d5d04-5dff-4558-8b5d-fbc2a7d83036/crypt/zone"},{"zone":{"id":"fd8e615a-f170-4da9-b8d0-2a5a123d8682","zone_type":"crucible_pantry","addresses":["fd00:1122:3344:101::3"],"dataset":null,"services":[{"id":"fd8e615a-f170-4da9-b8d0-2a5a123d8682","details":{"type":"crucible_pantry","address":"[fd00:1122:3344:101::3]:17000"}}]},"root":"/pool/ext/dd084b76-1130-4ad3-9196-6b02be607fe9/crypt/zone"},{"zone":{"id":"f8a793f4-cd08-49ec-8fee-6bcd37092fdc","zone_type":"crucible","addresses":["fd00:1122:3344:101::c"],"dataset":{"id":"f8a793f4-cd08-49ec-8fee-6bcd37092fdc","name":{"pool_name":"oxp_709d5d04-5dff-4558-8b5d-fbc2a7d83036","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::c]:32345"},"services":[{"id":"f8a793f4-cd08-49ec-8fee-6bcd37092fdc","details":{"type":"crucible","address":"[fd00:1122:3344:101::c]:32345"}}]},"root":"/pool/ext/d94e9c58-e6d1-444b-b7d8-19ac17dea042/crypt/zone"},{"zone":{"id":"c67d44be-d6b8-4a08-a7e0-3ab300749ad6","zone_type":"crucible","addresses":["fd00:1122:3344:101::4"],"dataset":{"id":"c67d44be-d6b8-4a08-a7e0-3ab300749ad6","name":{"pool_name":"oxp_231cd696-2839-4a9a-ae42-6d875a98a797","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::4]:32345"},"services":[{"id":"c67d44be-d6b8-4a08-a7e0-3ab300749ad6","details":{"type":"crucible","address":"[fd00:1122:3344:101::4]:32345"}}]},"root":"/pool/ext/709d5d04-5dff-4558-8b5d-fbc2a7d83036/crypt/zone"},{"zone":{"id":"e91b4957-8165-451d-9fa5-090c3a39f199","zone_type":"crucible","addresses":["fd00:1122:3344:101::d"],"dataset":{"id":"e91b4957-8165-451d-9fa5-090c3a39f199","name":{"pool_name":"oxp_dd084b76-1130-4ad3-9196-6b02be607fe9","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::d]:32345"},"services":[{"id":"e91b4957-8165-451d-9fa5-090c3a39f199","details":{"type":"crucible","address":"[fd00:1122:3344:101::d]:32345"}}]},"root":"/pool/ext/5840a3b7-f765-45d3-8a41-7f543f936bee/crypt/zone"},{"zone":{"id":"5e737b6e-d33d-4a2c-b8c0-3cad9d05a68f","zone_type":"crucible","addresses":["fd00:1122:3344:101::5"],"dataset":{"id":"5e737b6e-d33d-4a2c-b8c0-3cad9d05a68f","name":{"pool_name":"oxp_8fa4f837-c6f3-4c65-88d4-21eb3cd7ffee","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:101::5]:32345"},"services":[{"id":"5e737b6e-d33d-4a2c-b8c0-3cad9d05a68f","details":{"type":"crucible","address":"[fd00:1122:3344:101::5]:32345"}}]},"root":"/pool/ext/dd084b76-1130-4ad3-9196-6b02be607fe9/crypt/zone"},{"zone":{"id":"7e6b7816-b1a6-40f3-894a-a5d5c0571dbb","zone_type":"ntp","addresses":["fd00:1122:3344:101::e"],"dataset":null,"services":[{"id":"7e6b7816-b1a6-40f3-894a-a5d5c0571dbb","details":{"type":"internal_ntp","address":"[fd00:1122:3344:101::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/be06ea9c-df86-4fec-b5dd-8809710893af/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled6.json b/sled-agent/tests/old-service-ledgers/rack3-sled6.json deleted file mode 100644 index 2c499813cd..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled6.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"eafffae7-69fd-49e1-9541-7cf237ab12b3","zone_type":"crucible","addresses":["fd00:1122:3344:110::3"],"dataset":{"id":"eafffae7-69fd-49e1-9541-7cf237ab12b3","name":{"pool_name":"oxp_929404cd-2522-4440-b21c-91d466a9a7e0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::3]:32345"},"services":[{"id":"eafffae7-69fd-49e1-9541-7cf237ab12b3","details":{"type":"crucible","address":"[fd00:1122:3344:110::3]:32345"}}]},"root":"/pool/ext/aff390ed-8d70-49fa-9000-5420b54ab118/crypt/zone"},{"zone":{"id":"f4bccf15-d69f-402d-9bd2-7959a4cb2823","zone_type":"crucible","addresses":["fd00:1122:3344:110::9"],"dataset":{"id":"f4bccf15-d69f-402d-9bd2-7959a4cb2823","name":{"pool_name":"oxp_f80f96be-a3d7-490a-96a7-faf7da80a579","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::9]:32345"},"services":[{"id":"f4bccf15-d69f-402d-9bd2-7959a4cb2823","details":{"type":"crucible","address":"[fd00:1122:3344:110::9]:32345"}}]},"root":"/pool/ext/6bcd54c8-d4a8-429d-8f17-cf02615eb063/crypt/zone"},{"zone":{"id":"82e51c9d-c187-4baa-8307-e46eeafc5ff2","zone_type":"crucible","addresses":["fd00:1122:3344:110::5"],"dataset":{"id":"82e51c9d-c187-4baa-8307-e46eeafc5ff2","name":{"pool_name":"oxp_37d86199-6834-49d9-888a-88ff6f281b29","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::5]:32345"},"services":[{"id":"82e51c9d-c187-4baa-8307-e46eeafc5ff2","details":{"type":"crucible","address":"[fd00:1122:3344:110::5]:32345"}}]},"root":"/pool/ext/d2e27e2a-2deb-42ae-84a7-c2d06f3aeb4f/crypt/zone"},{"zone":{"id":"cf667caf-304c-40c4-acce-f0eb05d011ef","zone_type":"crucible","addresses":["fd00:1122:3344:110::8"],"dataset":{"id":"cf667caf-304c-40c4-acce-f0eb05d011ef","name":{"pool_name":"oxp_625c0110-644e-4d63-8321-b85ab5642260","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::8]:32345"},"services":[{"id":"cf667caf-304c-40c4-acce-f0eb05d011ef","details":{"type":"crucible","address":"[fd00:1122:3344:110::8]:32345"}}]},"root":"/pool/ext/d2e27e2a-2deb-42ae-84a7-c2d06f3aeb4f/crypt/zone"},{"zone":{"id":"14e60912-108e-4dd3-984e-2332a183b346","zone_type":"crucible","addresses":["fd00:1122:3344:110::b"],"dataset":{"id":"14e60912-108e-4dd3-984e-2332a183b346","name":{"pool_name":"oxp_fa6470f5-0a4c-4fef-b0b1-57c8749c6cca","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::b]:32345"},"services":[{"id":"14e60912-108e-4dd3-984e-2332a183b346","details":{"type":"crucible","address":"[fd00:1122:3344:110::b]:32345"}}]},"root":"/pool/ext/6c5ab641-3bd4-4d8c-96f4-4f56c1045142/crypt/zone"},{"zone":{"id":"1aacf923-c96f-4bab-acb0-63f28e86eef6","zone_type":"crucible","addresses":["fd00:1122:3344:110::c"],"dataset":{"id":"1aacf923-c96f-4bab-acb0-63f28e86eef6","name":{"pool_name":"oxp_21b0f3ed-d27f-4996-968b-bf2b494d9308","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::c]:32345"},"services":[{"id":"1aacf923-c96f-4bab-acb0-63f28e86eef6","details":{"type":"crucible","address":"[fd00:1122:3344:110::c]:32345"}}]},"root":"/pool/ext/625c0110-644e-4d63-8321-b85ab5642260/crypt/zone"},{"zone":{"id":"b9db0845-04d3-4dc1-84ba-224749562a6c","zone_type":"crucible","addresses":["fd00:1122:3344:110::6"],"dataset":{"id":"b9db0845-04d3-4dc1-84ba-224749562a6c","name":{"pool_name":"oxp_d2e27e2a-2deb-42ae-84a7-c2d06f3aeb4f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::6]:32345"},"services":[{"id":"b9db0845-04d3-4dc1-84ba-224749562a6c","details":{"type":"crucible","address":"[fd00:1122:3344:110::6]:32345"}}]},"root":"/pool/ext/aff390ed-8d70-49fa-9000-5420b54ab118/crypt/zone"},{"zone":{"id":"38b51865-ee80-4e1b-a40b-3452951f9022","zone_type":"crucible","addresses":["fd00:1122:3344:110::7"],"dataset":{"id":"38b51865-ee80-4e1b-a40b-3452951f9022","name":{"pool_name":"oxp_6bcd54c8-d4a8-429d-8f17-cf02615eb063","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::7]:32345"},"services":[{"id":"38b51865-ee80-4e1b-a40b-3452951f9022","details":{"type":"crucible","address":"[fd00:1122:3344:110::7]:32345"}}]},"root":"/pool/ext/37d86199-6834-49d9-888a-88ff6f281b29/crypt/zone"},{"zone":{"id":"4bc441f6-f7e5-4d68-8751-53ef1e251c47","zone_type":"crucible","addresses":["fd00:1122:3344:110::a"],"dataset":{"id":"4bc441f6-f7e5-4d68-8751-53ef1e251c47","name":{"pool_name":"oxp_6c5ab641-3bd4-4d8c-96f4-4f56c1045142","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::a]:32345"},"services":[{"id":"4bc441f6-f7e5-4d68-8751-53ef1e251c47","details":{"type":"crucible","address":"[fd00:1122:3344:110::a]:32345"}}]},"root":"/pool/ext/21b0f3ed-d27f-4996-968b-bf2b494d9308/crypt/zone"},{"zone":{"id":"d2c20cf8-ed4c-4815-add9-45996364f721","zone_type":"crucible","addresses":["fd00:1122:3344:110::4"],"dataset":{"id":"d2c20cf8-ed4c-4815-add9-45996364f721","name":{"pool_name":"oxp_aff390ed-8d70-49fa-9000-5420b54ab118","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:110::4]:32345"},"services":[{"id":"d2c20cf8-ed4c-4815-add9-45996364f721","details":{"type":"crucible","address":"[fd00:1122:3344:110::4]:32345"}}]},"root":"/pool/ext/6c5ab641-3bd4-4d8c-96f4-4f56c1045142/crypt/zone"},{"zone":{"id":"1bb548cb-889a-411e-8c67-d1b785225180","zone_type":"ntp","addresses":["fd00:1122:3344:110::d"],"dataset":null,"services":[{"id":"1bb548cb-889a-411e-8c67-d1b785225180","details":{"type":"internal_ntp","address":"[fd00:1122:3344:110::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/6bcd54c8-d4a8-429d-8f17-cf02615eb063/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled7.json b/sled-agent/tests/old-service-ledgers/rack3-sled7.json deleted file mode 100644 index fb701a2bdb..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled7.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"2eb74fa3-71ec-484c-8ffa-3daeab0e4c78","zone_type":"crucible","addresses":["fd00:1122:3344:11d::3"],"dataset":{"id":"2eb74fa3-71ec-484c-8ffa-3daeab0e4c78","name":{"pool_name":"oxp_c6b63fea-e3e2-4806-b8dc-bdfe7b5c3d89","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::3]:32345"},"services":[{"id":"2eb74fa3-71ec-484c-8ffa-3daeab0e4c78","details":{"type":"crucible","address":"[fd00:1122:3344:11d::3]:32345"}}]},"root":"/pool/ext/9f20cbae-7a63-4c31-9386-2ac3cbe12030/crypt/zone"},{"zone":{"id":"9f92bfcf-7435-44a6-8e77-0597f93cd0b4","zone_type":"crucible","addresses":["fd00:1122:3344:11d::7"],"dataset":{"id":"9f92bfcf-7435-44a6-8e77-0597f93cd0b4","name":{"pool_name":"oxp_9fa336f1-2b69-4ebf-9553-e3bab7e3e6ef","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::7]:32345"},"services":[{"id":"9f92bfcf-7435-44a6-8e77-0597f93cd0b4","details":{"type":"crucible","address":"[fd00:1122:3344:11d::7]:32345"}}]},"root":"/pool/ext/e05a6264-63f2-4961-bc14-57b4f65614c0/crypt/zone"},{"zone":{"id":"1bf9aed4-9fd3-4d87-b8e7-7f066d25ec1d","zone_type":"crucible","addresses":["fd00:1122:3344:11d::b"],"dataset":{"id":"1bf9aed4-9fd3-4d87-b8e7-7f066d25ec1d","name":{"pool_name":"oxp_a5a52f47-9c9a-4519-83dc-abc56619495d","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::b]:32345"},"services":[{"id":"1bf9aed4-9fd3-4d87-b8e7-7f066d25ec1d","details":{"type":"crucible","address":"[fd00:1122:3344:11d::b]:32345"}}]},"root":"/pool/ext/cbcad26e-5e52-41b7-9875-1a84d30d8a15/crypt/zone"},{"zone":{"id":"2a722aa7-cd8a-445d-83fe-57fc9b9a8249","zone_type":"crucible","addresses":["fd00:1122:3344:11d::8"],"dataset":{"id":"2a722aa7-cd8a-445d-83fe-57fc9b9a8249","name":{"pool_name":"oxp_1f4b71eb-505f-4706-912c-b13dd3f2eafb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::8]:32345"},"services":[{"id":"2a722aa7-cd8a-445d-83fe-57fc9b9a8249","details":{"type":"crucible","address":"[fd00:1122:3344:11d::8]:32345"}}]},"root":"/pool/ext/a5a52f47-9c9a-4519-83dc-abc56619495d/crypt/zone"},{"zone":{"id":"76af5b23-d833-435c-b848-2a09d9fad9a1","zone_type":"crucible","addresses":["fd00:1122:3344:11d::c"],"dataset":{"id":"76af5b23-d833-435c-b848-2a09d9fad9a1","name":{"pool_name":"oxp_cbcad26e-5e52-41b7-9875-1a84d30d8a15","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::c]:32345"},"services":[{"id":"76af5b23-d833-435c-b848-2a09d9fad9a1","details":{"type":"crucible","address":"[fd00:1122:3344:11d::c]:32345"}}]},"root":"/pool/ext/9f20cbae-7a63-4c31-9386-2ac3cbe12030/crypt/zone"},{"zone":{"id":"3a412bf4-a385-4e66-9ada-a87f6536d6ca","zone_type":"crucible","addresses":["fd00:1122:3344:11d::4"],"dataset":{"id":"3a412bf4-a385-4e66-9ada-a87f6536d6ca","name":{"pool_name":"oxp_e05a6264-63f2-4961-bc14-57b4f65614c0","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::4]:32345"},"services":[{"id":"3a412bf4-a385-4e66-9ada-a87f6536d6ca","details":{"type":"crucible","address":"[fd00:1122:3344:11d::4]:32345"}}]},"root":"/pool/ext/e05a6264-63f2-4961-bc14-57b4f65614c0/crypt/zone"},{"zone":{"id":"99a25fa7-8231-4a46-a6ec-ffc5281db1f8","zone_type":"crucible","addresses":["fd00:1122:3344:11d::5"],"dataset":{"id":"99a25fa7-8231-4a46-a6ec-ffc5281db1f8","name":{"pool_name":"oxp_722494ab-9a2b-481b-ac11-292fded682a5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::5]:32345"},"services":[{"id":"99a25fa7-8231-4a46-a6ec-ffc5281db1f8","details":{"type":"crucible","address":"[fd00:1122:3344:11d::5]:32345"}}]},"root":"/pool/ext/e05a6264-63f2-4961-bc14-57b4f65614c0/crypt/zone"},{"zone":{"id":"06c7ddc8-9b3e-48ef-9874-0c40874e9877","zone_type":"crucible","addresses":["fd00:1122:3344:11d::a"],"dataset":{"id":"06c7ddc8-9b3e-48ef-9874-0c40874e9877","name":{"pool_name":"oxp_8c3972d1-5b17-4479-88cc-1c33e4344160","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::a]:32345"},"services":[{"id":"06c7ddc8-9b3e-48ef-9874-0c40874e9877","details":{"type":"crucible","address":"[fd00:1122:3344:11d::a]:32345"}}]},"root":"/pool/ext/8c3972d1-5b17-4479-88cc-1c33e4344160/crypt/zone"},{"zone":{"id":"1212b2dc-157d-4bd3-94af-fb5db1d91f24","zone_type":"crucible","addresses":["fd00:1122:3344:11d::9"],"dataset":{"id":"1212b2dc-157d-4bd3-94af-fb5db1d91f24","name":{"pool_name":"oxp_9f20cbae-7a63-4c31-9386-2ac3cbe12030","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::9]:32345"},"services":[{"id":"1212b2dc-157d-4bd3-94af-fb5db1d91f24","details":{"type":"crucible","address":"[fd00:1122:3344:11d::9]:32345"}}]},"root":"/pool/ext/977aa6c3-2026-4178-9948-e09f78008575/crypt/zone"},{"zone":{"id":"b1fb5f2e-b20d-4f4c-9f6f-bbeb1a98dd50","zone_type":"crucible","addresses":["fd00:1122:3344:11d::6"],"dataset":{"id":"b1fb5f2e-b20d-4f4c-9f6f-bbeb1a98dd50","name":{"pool_name":"oxp_977aa6c3-2026-4178-9948-e09f78008575","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:11d::6]:32345"},"services":[{"id":"b1fb5f2e-b20d-4f4c-9f6f-bbeb1a98dd50","details":{"type":"crucible","address":"[fd00:1122:3344:11d::6]:32345"}}]},"root":"/pool/ext/722494ab-9a2b-481b-ac11-292fded682a5/crypt/zone"},{"zone":{"id":"e68dde0f-0647-46db-ae1c-711835c13e25","zone_type":"ntp","addresses":["fd00:1122:3344:11d::d"],"dataset":null,"services":[{"id":"e68dde0f-0647-46db-ae1c-711835c13e25","details":{"type":"internal_ntp","address":"[fd00:1122:3344:11d::d]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/1f4b71eb-505f-4706-912c-b13dd3f2eafb/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled8.json b/sled-agent/tests/old-service-ledgers/rack3-sled8.json deleted file mode 100644 index cf96f8ae81..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled8.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"85c18b7c-a100-458c-b18d-ecfdacaefac4","zone_type":"crucible","addresses":["fd00:1122:3344:10e::5"],"dataset":{"id":"85c18b7c-a100-458c-b18d-ecfdacaefac4","name":{"pool_name":"oxp_07b266bc-86c3-4a76-9522-8b34ba1ae78c","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::5]:32345"},"services":[{"id":"85c18b7c-a100-458c-b18d-ecfdacaefac4","details":{"type":"crucible","address":"[fd00:1122:3344:10e::5]:32345"}}]},"root":"/pool/ext/5b88e44e-f886-4de8-8a6b-48ea5ed9d70b/crypt/zone"},{"zone":{"id":"db303465-7879-4d86-8da8-a0c7162e5184","zone_type":"crucible","addresses":["fd00:1122:3344:10e::4"],"dataset":{"id":"db303465-7879-4d86-8da8-a0c7162e5184","name":{"pool_name":"oxp_e9488a32-880d-44a2-8948-db0b7e3a35b5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::4]:32345"},"services":[{"id":"db303465-7879-4d86-8da8-a0c7162e5184","details":{"type":"crucible","address":"[fd00:1122:3344:10e::4]:32345"}}]},"root":"/pool/ext/8d798756-7200-4db4-9faf-f41b75106a63/crypt/zone"},{"zone":{"id":"c44ce6be-512d-4104-9260-a5b8fe373937","zone_type":"crucible","addresses":["fd00:1122:3344:10e::9"],"dataset":{"id":"c44ce6be-512d-4104-9260-a5b8fe373937","name":{"pool_name":"oxp_025dfc06-5aeb-407f-adc8-ba18dc9bba35","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::9]:32345"},"services":[{"id":"c44ce6be-512d-4104-9260-a5b8fe373937","details":{"type":"crucible","address":"[fd00:1122:3344:10e::9]:32345"}}]},"root":"/pool/ext/1544ce68-3544-4cba-b3b6-1927d08b78a5/crypt/zone"},{"zone":{"id":"1cfdb5b6-e568-436a-a85f-7fecf1b8eef2","zone_type":"nexus","addresses":["fd00:1122:3344:10e::3"],"dataset":null,"services":[{"id":"1cfdb5b6-e568-436a-a85f-7fecf1b8eef2","details":{"type":"nexus","internal_address":"[fd00:1122:3344:10e::3]:12221","external_ip":"45.154.216.36","nic":{"id":"569754a2-a5e0-4aa8-90a7-2fa65f43b667","kind":{"type":"service","id":"1cfdb5b6-e568-436a-a85f-7fecf1b8eef2"},"name":"nexus-1cfdb5b6-e568-436a-a85f-7fecf1b8eef2","ip":"172.30.2.6","mac":"A8:40:25:FF:EC:6B","subnet":"172.30.2.0/24","vni":100,"primary":true,"slot":0},"external_tls":true,"external_dns_servers":["1.1.1.1","8.8.8.8"]}}]},"root":"/pool/ext/025dfc06-5aeb-407f-adc8-ba18dc9bba35/crypt/zone"},{"zone":{"id":"44a68792-ca14-442e-b7a9-11970d50ba0e","zone_type":"crucible","addresses":["fd00:1122:3344:10e::a"],"dataset":{"id":"44a68792-ca14-442e-b7a9-11970d50ba0e","name":{"pool_name":"oxp_2a492098-7df3-4409-9466-561edb7aa99b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::a]:32345"},"services":[{"id":"44a68792-ca14-442e-b7a9-11970d50ba0e","details":{"type":"crucible","address":"[fd00:1122:3344:10e::a]:32345"}}]},"root":"/pool/ext/1544ce68-3544-4cba-b3b6-1927d08b78a5/crypt/zone"},{"zone":{"id":"514cf0ca-6d23-434e-9785-446b83b2f029","zone_type":"crucible","addresses":["fd00:1122:3344:10e::7"],"dataset":{"id":"514cf0ca-6d23-434e-9785-446b83b2f029","name":{"pool_name":"oxp_5b88e44e-f886-4de8-8a6b-48ea5ed9d70b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::7]:32345"},"services":[{"id":"514cf0ca-6d23-434e-9785-446b83b2f029","details":{"type":"crucible","address":"[fd00:1122:3344:10e::7]:32345"}}]},"root":"/pool/ext/5b88e44e-f886-4de8-8a6b-48ea5ed9d70b/crypt/zone"},{"zone":{"id":"bc6d8347-8f64-4031-912c-932349df07fe","zone_type":"crucible","addresses":["fd00:1122:3344:10e::6"],"dataset":{"id":"bc6d8347-8f64-4031-912c-932349df07fe","name":{"pool_name":"oxp_1544ce68-3544-4cba-b3b6-1927d08b78a5","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::6]:32345"},"services":[{"id":"bc6d8347-8f64-4031-912c-932349df07fe","details":{"type":"crucible","address":"[fd00:1122:3344:10e::6]:32345"}}]},"root":"/pool/ext/1544ce68-3544-4cba-b3b6-1927d08b78a5/crypt/zone"},{"zone":{"id":"1ab0a4f5-99ad-4341-8c89-7fd03e5ccb08","zone_type":"crucible","addresses":["fd00:1122:3344:10e::b"],"dataset":{"id":"1ab0a4f5-99ad-4341-8c89-7fd03e5ccb08","name":{"pool_name":"oxp_033eb462-968f-42ce-9c29-377bd40a3014","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::b]:32345"},"services":[{"id":"1ab0a4f5-99ad-4341-8c89-7fd03e5ccb08","details":{"type":"crucible","address":"[fd00:1122:3344:10e::b]:32345"}}]},"root":"/pool/ext/9e1a0803-7453-4eac-91c9-d7891ecd634f/crypt/zone"},{"zone":{"id":"d6f2520b-3d04-44d9-bd46-6ffccfcb46d2","zone_type":"crucible","addresses":["fd00:1122:3344:10e::8"],"dataset":{"id":"d6f2520b-3d04-44d9-bd46-6ffccfcb46d2","name":{"pool_name":"oxp_36e8d29c-1e88-4c2b-8f59-f312201067c3","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::8]:32345"},"services":[{"id":"d6f2520b-3d04-44d9-bd46-6ffccfcb46d2","details":{"type":"crucible","address":"[fd00:1122:3344:10e::8]:32345"}}]},"root":"/pool/ext/1544ce68-3544-4cba-b3b6-1927d08b78a5/crypt/zone"},{"zone":{"id":"d6da9d13-bfcf-469d-a99e-faeb5e30be32","zone_type":"crucible","addresses":["fd00:1122:3344:10e::c"],"dataset":{"id":"d6da9d13-bfcf-469d-a99e-faeb5e30be32","name":{"pool_name":"oxp_9e1a0803-7453-4eac-91c9-d7891ecd634f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::c]:32345"},"services":[{"id":"d6da9d13-bfcf-469d-a99e-faeb5e30be32","details":{"type":"crucible","address":"[fd00:1122:3344:10e::c]:32345"}}]},"root":"/pool/ext/8d798756-7200-4db4-9faf-f41b75106a63/crypt/zone"},{"zone":{"id":"a1dc59c2-5883-4fb8-83be-ac2d95d255d1","zone_type":"crucible","addresses":["fd00:1122:3344:10e::d"],"dataset":{"id":"a1dc59c2-5883-4fb8-83be-ac2d95d255d1","name":{"pool_name":"oxp_8d798756-7200-4db4-9faf-f41b75106a63","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10e::d]:32345"},"services":[{"id":"a1dc59c2-5883-4fb8-83be-ac2d95d255d1","details":{"type":"crucible","address":"[fd00:1122:3344:10e::d]:32345"}}]},"root":"/pool/ext/36e8d29c-1e88-4c2b-8f59-f312201067c3/crypt/zone"},{"zone":{"id":"48f25dba-7392-44ce-9bb0-28489ebc44bc","zone_type":"ntp","addresses":["fd00:1122:3344:10e::e"],"dataset":null,"services":[{"id":"48f25dba-7392-44ce-9bb0-28489ebc44bc","details":{"type":"internal_ntp","address":"[fd00:1122:3344:10e::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/5b88e44e-f886-4de8-8a6b-48ea5ed9d70b/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/old-service-ledgers/rack3-sled9.json b/sled-agent/tests/old-service-ledgers/rack3-sled9.json deleted file mode 100644 index c225f50081..0000000000 --- a/sled-agent/tests/old-service-ledgers/rack3-sled9.json +++ /dev/null @@ -1 +0,0 @@ -{"generation":4,"requests":[{"zone":{"id":"b452e5e1-ab4c-4994-9679-ef21b3b4fee9","zone_type":"crucible","addresses":["fd00:1122:3344:10b::6"],"dataset":{"id":"b452e5e1-ab4c-4994-9679-ef21b3b4fee9","name":{"pool_name":"oxp_d63a297d-ae6a-4072-9dca-dda404044989","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::6]:32345"},"services":[{"id":"b452e5e1-ab4c-4994-9679-ef21b3b4fee9","details":{"type":"crucible","address":"[fd00:1122:3344:10b::6]:32345"}}]},"root":"/pool/ext/7c204111-31df-4c32-9a3e-780411f700fd/crypt/zone"},{"zone":{"id":"e9826cdc-6d3a-4eff-b1b5-ec4364ebe6b9","zone_type":"oximeter","addresses":["fd00:1122:3344:10b::3"],"dataset":null,"services":[{"id":"e9826cdc-6d3a-4eff-b1b5-ec4364ebe6b9","details":{"type":"oximeter","address":"[fd00:1122:3344:10b::3]:12223"}}]},"root":"/pool/ext/7c204111-31df-4c32-9a3e-780411f700fd/crypt/zone"},{"zone":{"id":"b0cde4a8-f27c-46e8-8355-756be9045afc","zone_type":"crucible","addresses":["fd00:1122:3344:10b::b"],"dataset":{"id":"b0cde4a8-f27c-46e8-8355-756be9045afc","name":{"pool_name":"oxp_07c1a8e7-51f5-4f12-a43d-734719fef92b","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::b]:32345"},"services":[{"id":"b0cde4a8-f27c-46e8-8355-756be9045afc","details":{"type":"crucible","address":"[fd00:1122:3344:10b::b]:32345"}}]},"root":"/pool/ext/1f6adf64-c9b9-4ed7-b3e2-37fb25624646/crypt/zone"},{"zone":{"id":"e2f70cf6-e285-4212-9b01-77ebf2ca9219","zone_type":"crucible","addresses":["fd00:1122:3344:10b::d"],"dataset":{"id":"e2f70cf6-e285-4212-9b01-77ebf2ca9219","name":{"pool_name":"oxp_a809f28a-7f25-4362-bc56-0cbdd72af2cb","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::d]:32345"},"services":[{"id":"e2f70cf6-e285-4212-9b01-77ebf2ca9219","details":{"type":"crucible","address":"[fd00:1122:3344:10b::d]:32345"}}]},"root":"/pool/ext/92a1bd39-6e8a-4226-b9d0-e3e8a9b8504f/crypt/zone"},{"zone":{"id":"b0949c9d-4aa1-4bc4-9cb3-5875b9166885","zone_type":"crucible","addresses":["fd00:1122:3344:10b::a"],"dataset":{"id":"b0949c9d-4aa1-4bc4-9cb3-5875b9166885","name":{"pool_name":"oxp_af0cc12b-43c5-473a-89a7-28351fbbb430","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::a]:32345"},"services":[{"id":"b0949c9d-4aa1-4bc4-9cb3-5875b9166885","details":{"type":"crucible","address":"[fd00:1122:3344:10b::a]:32345"}}]},"root":"/pool/ext/cf1594ed-7c0c-467c-b0af-a689dcb427a3/crypt/zone"},{"zone":{"id":"7cea4d59-a8ca-4826-901d-8d5bd935dc09","zone_type":"crucible","addresses":["fd00:1122:3344:10b::9"],"dataset":{"id":"7cea4d59-a8ca-4826-901d-8d5bd935dc09","name":{"pool_name":"oxp_d75dae09-4992-4a61-ab7d-5ae1d2b068ba","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::9]:32345"},"services":[{"id":"7cea4d59-a8ca-4826-901d-8d5bd935dc09","details":{"type":"crucible","address":"[fd00:1122:3344:10b::9]:32345"}}]},"root":"/pool/ext/a809f28a-7f25-4362-bc56-0cbdd72af2cb/crypt/zone"},{"zone":{"id":"08adaeee-c3b5-4cd8-8fbd-ac371b3101c9","zone_type":"crucible","addresses":["fd00:1122:3344:10b::4"],"dataset":{"id":"08adaeee-c3b5-4cd8-8fbd-ac371b3101c9","name":{"pool_name":"oxp_d9f23187-fbf9-4ea5-a103-bc112263a9a7","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::4]:32345"},"services":[{"id":"08adaeee-c3b5-4cd8-8fbd-ac371b3101c9","details":{"type":"crucible","address":"[fd00:1122:3344:10b::4]:32345"}}]},"root":"/pool/ext/7c204111-31df-4c32-9a3e-780411f700fd/crypt/zone"},{"zone":{"id":"3da1ade5-3fcb-4e64-aa08-81ee8a9ef723","zone_type":"crucible","addresses":["fd00:1122:3344:10b::8"],"dataset":{"id":"3da1ade5-3fcb-4e64-aa08-81ee8a9ef723","name":{"pool_name":"oxp_1f6adf64-c9b9-4ed7-b3e2-37fb25624646","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::8]:32345"},"services":[{"id":"3da1ade5-3fcb-4e64-aa08-81ee8a9ef723","details":{"type":"crucible","address":"[fd00:1122:3344:10b::8]:32345"}}]},"root":"/pool/ext/07c1a8e7-51f5-4f12-a43d-734719fef92b/crypt/zone"},{"zone":{"id":"816f26a7-4c28-4a39-b9ad-a036678520ab","zone_type":"crucible","addresses":["fd00:1122:3344:10b::7"],"dataset":{"id":"816f26a7-4c28-4a39-b9ad-a036678520ab","name":{"pool_name":"oxp_92a1bd39-6e8a-4226-b9d0-e3e8a9b8504f","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::7]:32345"},"services":[{"id":"816f26a7-4c28-4a39-b9ad-a036678520ab","details":{"type":"crucible","address":"[fd00:1122:3344:10b::7]:32345"}}]},"root":"/pool/ext/d9f23187-fbf9-4ea5-a103-bc112263a9a7/crypt/zone"},{"zone":{"id":"839f9839-409f-45d3-b8a6-7085507b90f6","zone_type":"crucible","addresses":["fd00:1122:3344:10b::c"],"dataset":{"id":"839f9839-409f-45d3-b8a6-7085507b90f6","name":{"pool_name":"oxp_7c204111-31df-4c32-9a3e-780411f700fd","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::c]:32345"},"services":[{"id":"839f9839-409f-45d3-b8a6-7085507b90f6","details":{"type":"crucible","address":"[fd00:1122:3344:10b::c]:32345"}}]},"root":"/pool/ext/af0cc12b-43c5-473a-89a7-28351fbbb430/crypt/zone"},{"zone":{"id":"c717c81f-a228-4412-a34e-90f8c491d847","zone_type":"crucible","addresses":["fd00:1122:3344:10b::5"],"dataset":{"id":"c717c81f-a228-4412-a34e-90f8c491d847","name":{"pool_name":"oxp_cf1594ed-7c0c-467c-b0af-a689dcb427a3","kind":{"type":"crucible"}},"service_address":"[fd00:1122:3344:10b::5]:32345"},"services":[{"id":"c717c81f-a228-4412-a34e-90f8c491d847","details":{"type":"crucible","address":"[fd00:1122:3344:10b::5]:32345"}}]},"root":"/pool/ext/d63a297d-ae6a-4072-9dca-dda404044989/crypt/zone"},{"zone":{"id":"e1fa2023-6c86-40a4-ae59-a0de112cf7a9","zone_type":"ntp","addresses":["fd00:1122:3344:10b::e"],"dataset":null,"services":[{"id":"e1fa2023-6c86-40a4-ae59-a0de112cf7a9","details":{"type":"internal_ntp","address":"[fd00:1122:3344:10b::e]:123","ntp_servers":["440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal","cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal"],"dns_servers":["fd00:1122:3344:1::1","fd00:1122:3344:2::1","fd00:1122:3344:3::1"],"domain":null}}]},"root":"/pool/ext/d9f23187-fbf9-4ea5-a103-bc112263a9a7/crypt/zone"}]} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json deleted file mode 100644 index c00a65e8ea..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "04eef8aa-055c-42ab-bdb6-c982f63c9be0", - "underlay_address": "fd00:1122:3344:107::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::d]:32345", - "dataset": { - "pool_name": "oxp_845ff39a-3205-416f-8bda-e35829107c8a" - } - } - }, - "root": "/pool/ext/43efdd6d-7419-437a-a282-fc45bfafd042/crypt/zone" - }, - { - "zone": { - "id": "8568c997-fbbb-46a8-8549-b78284530ffc", - "underlay_address": "fd00:1122:3344:107::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::5]:32345", - "dataset": { - "pool_name": "oxp_0e485ad3-04e6-404b-b619-87d4fea9f5ae" - } - } - }, - "root": "/pool/ext/9b61d4b2-66f6-459f-86f4-13d0b8c5d6cf/crypt/zone" - }, - { - "zone": { - "id": "6cec1d60-5c1a-4c1b-9632-2b4bc76bd37c", - "underlay_address": "fd00:1122:3344:107::e", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::e]:32345", - "dataset": { - "pool_name": "oxp_62a4c68a-2073-42d0-8e49-01f5e8b90cd4" - } - } - }, - "root": "/pool/ext/845ff39a-3205-416f-8bda-e35829107c8a/crypt/zone" - }, - { - "zone": { - "id": "aa646c82-c6d7-4d0c-8401-150130927759", - "underlay_address": "fd00:1122:3344:107::4", - "zone_type": { - "type": "clickhouse", - "address": "[fd00:1122:3344:107::4]:8123", - "dataset": { - "pool_name": "oxp_0e485ad3-04e6-404b-b619-87d4fea9f5ae" - } - } - }, - "root": "/pool/ext/fd82dcc7-00dd-4d01-826a-937a7d8238fb/crypt/zone" - }, - { - "zone": { - "id": "2f294ca1-7a4f-468f-8966-2b7915804729", - "underlay_address": "fd00:1122:3344:107::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::7]:32345", - "dataset": { - "pool_name": "oxp_43efdd6d-7419-437a-a282-fc45bfafd042" - } - } - }, - "root": "/pool/ext/fd82dcc7-00dd-4d01-826a-937a7d8238fb/crypt/zone" - }, - { - "zone": { - "id": "1a77bd1d-4fd4-4d6c-a105-17f942d94ba6", - "underlay_address": "fd00:1122:3344:107::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::c]:32345", - "dataset": { - "pool_name": "oxp_b6bdfdaf-9c0d-4b74-926c-49ff3ed05562" - } - } - }, - "root": "/pool/ext/9b61d4b2-66f6-459f-86f4-13d0b8c5d6cf/crypt/zone" - }, - { - "zone": { - "id": "f65a6668-1aea-4deb-81ed-191fbe469328", - "underlay_address": "fd00:1122:3344:107::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::9]:32345", - "dataset": { - "pool_name": "oxp_9b61d4b2-66f6-459f-86f4-13d0b8c5d6cf" - } - } - }, - "root": "/pool/ext/d0584f4a-20ba-436d-a75b-7709e80deb79/crypt/zone" - }, - { - "zone": { - "id": "ee8bce67-8f8e-4221-97b0-85f1860d66d0", - "underlay_address": "fd00:1122:3344:107::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::8]:32345", - "dataset": { - "pool_name": "oxp_b252b176-3974-436a-915b-60382b21eb76" - } - } - }, - "root": "/pool/ext/b6bdfdaf-9c0d-4b74-926c-49ff3ed05562/crypt/zone" - }, - { - "zone": { - "id": "cf3b2d54-5e36-4c93-b44f-8bf36ac98071", - "underlay_address": "fd00:1122:3344:107::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::b]:32345", - "dataset": { - "pool_name": "oxp_d0584f4a-20ba-436d-a75b-7709e80deb79" - } - } - }, - "root": "/pool/ext/4c157f35-865d-4310-9d81-c6259cb69293/crypt/zone" - }, - { - "zone": { - "id": "5c8c244c-00dc-4b16-aa17-6d9eb4827fab", - "underlay_address": "fd00:1122:3344:107::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::a]:32345", - "dataset": { - "pool_name": "oxp_4c157f35-865d-4310-9d81-c6259cb69293" - } - } - }, - "root": "/pool/ext/845ff39a-3205-416f-8bda-e35829107c8a/crypt/zone" - }, - { - "zone": { - "id": "7d5e942b-926c-442d-937a-76cc4aa72bf3", - "underlay_address": "fd00:1122:3344:107::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::6]:32345", - "dataset": { - "pool_name": "oxp_fd82dcc7-00dd-4d01-826a-937a7d8238fb" - } - } - }, - "root": "/pool/ext/b252b176-3974-436a-915b-60382b21eb76/crypt/zone" - }, - { - "zone": { - "id": "a3628a56-6f85-43b5-be50-71d8f0e04877", - "underlay_address": "fd00:1122:3344:107::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:107::3]:32221", - "dataset": { - "pool_name": "oxp_0e485ad3-04e6-404b-b619-87d4fea9f5ae" - } - } - }, - "root": "/pool/ext/4c157f35-865d-4310-9d81-c6259cb69293/crypt/zone" - }, - { - "zone": { - "id": "7529be1c-ca8b-441a-89aa-37166cc450df", - "underlay_address": "fd00:1122:3344:107::f", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:107::f]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/fd82dcc7-00dd-4d01-826a-937a7d8238fb/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json deleted file mode 100644 index 79aae3e8c1..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json +++ /dev/null @@ -1,196 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "605be8b9-c652-4a5f-94ca-068ec7a39472", - "underlay_address": "fd00:1122:3344:106::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::a]:32345", - "dataset": { - "pool_name": "oxp_cf14d1b9-b4db-4594-b3ab-a9957e770ce9" - } - } - }, - "root": "/pool/ext/cf5f8849-0c5a-475b-8683-6d17da88d1d1/crypt/zone" - }, - { - "zone": { - "id": "af8a8712-457c-4ea7-a8b6-aecb04761c1b", - "underlay_address": "fd00:1122:3344:106::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::9]:32345", - "dataset": { - "pool_name": "oxp_cf5f8849-0c5a-475b-8683-6d17da88d1d1" - } - } - }, - "root": "/pool/ext/7f778610-7328-4554-98f6-b17f74f551c7/crypt/zone" - }, - { - "zone": { - "id": "0022703b-dcfc-44d4-897a-b42f6f53b433", - "underlay_address": "fd00:1122:3344:106::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::c]:32345", - "dataset": { - "pool_name": "oxp_025725fa-9e40-4b46-b018-c420408394ef" - } - } - }, - "root": "/pool/ext/025725fa-9e40-4b46-b018-c420408394ef/crypt/zone" - }, - { - "zone": { - "id": "fffddf56-10ca-4b62-9be3-5b3764a5f682", - "underlay_address": "fd00:1122:3344:106::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::d]:32345", - "dataset": { - "pool_name": "oxp_4d2f5aaf-eb14-4b1e-aa99-ae38ec844605" - } - } - }, - "root": "/pool/ext/834c9aad-c53b-4357-bc3f-f422efa63848/crypt/zone" - }, - { - "zone": { - "id": "9b8194ee-917d-4abc-a55c-94cea6cdaea1", - "underlay_address": "fd00:1122:3344:106::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::6]:32345", - "dataset": { - "pool_name": "oxp_d7665e0d-9354-4341-a76f-965d7c49f277" - } - } - }, - "root": "/pool/ext/cf5f8849-0c5a-475b-8683-6d17da88d1d1/crypt/zone" - }, - { - "zone": { - "id": "b369e133-485c-4d98-8fee-83542d1fd94d", - "underlay_address": "fd00:1122:3344:106::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::4]:32345", - "dataset": { - "pool_name": "oxp_4366f80d-3902-4b93-8f2d-380008e805fc" - } - } - }, - "root": "/pool/ext/025725fa-9e40-4b46-b018-c420408394ef/crypt/zone" - }, - { - "zone": { - "id": "edd99650-5df1-4241-815d-253e4ef2399c", - "underlay_address": "fd00:1122:3344:106::3", - "zone_type": { - "type": "external_dns", - "dataset": { - "pool_name": "oxp_4366f80d-3902-4b93-8f2d-380008e805fc" - }, - "http_address": "[fd00:1122:3344:106::3]:5353", - "dns_address": "172.20.26.1:53", - "nic": { - "id": "99b759fc-8e2e-44b7-aca8-93c3b201974d", - "kind": { - "type": "service", - "id": "edd99650-5df1-4241-815d-253e4ef2399c" - }, - "name": "external-dns-edd99650-5df1-4241-815d-253e4ef2399c", - "ip": "172.30.1.5", - "mac": "A8:40:25:FF:B0:9C", - "subnet": "172.30.1.0/24", - "vni": 100, - "primary": true, - "slot": 0 - } - } - }, - "root": "/pool/ext/7f778610-7328-4554-98f6-b17f74f551c7/crypt/zone" - }, - { - "zone": { - "id": "46d1afcc-cc3f-4b17-aafc-054dd4862d15", - "underlay_address": "fd00:1122:3344:106::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::5]:32345", - "dataset": { - "pool_name": "oxp_7f778610-7328-4554-98f6-b17f74f551c7" - } - } - }, - "root": "/pool/ext/cf5f8849-0c5a-475b-8683-6d17da88d1d1/crypt/zone" - }, - { - "zone": { - "id": "12afe1c3-bfe6-4278-8240-91d401347d36", - "underlay_address": "fd00:1122:3344:106::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::8]:32345", - "dataset": { - "pool_name": "oxp_534bcd4b-502f-4109-af6e-4b28a22c20f1" - } - } - }, - "root": "/pool/ext/4366f80d-3902-4b93-8f2d-380008e805fc/crypt/zone" - }, - { - "zone": { - "id": "c33b5912-9985-43ed-98f2-41297e2b796a", - "underlay_address": "fd00:1122:3344:106::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::b]:32345", - "dataset": { - "pool_name": "oxp_834c9aad-c53b-4357-bc3f-f422efa63848" - } - } - }, - "root": "/pool/ext/d7665e0d-9354-4341-a76f-965d7c49f277/crypt/zone" - }, - { - "zone": { - "id": "65b3db59-9361-4100-9cee-04e32a8c67d3", - "underlay_address": "fd00:1122:3344:106::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::7]:32345", - "dataset": { - "pool_name": "oxp_32b5303f-f667-4345-84d2-c7eec63b91b2" - } - } - }, - "root": "/pool/ext/d7665e0d-9354-4341-a76f-965d7c49f277/crypt/zone" - }, - { - "zone": { - "id": "82500cc9-f33d-4d59-9e6e-d70ea6133077", - "underlay_address": "fd00:1122:3344:106::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:106::e]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/cf14d1b9-b4db-4594-b3ab-a9957e770ce9/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json deleted file mode 100644 index 39ebad3183..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 5, - "zones": [ - { - "zone": { - "id": "a76b3357-b690-43b8-8352-3300568ffc2b", - "underlay_address": "fd00:1122:3344:104::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::a]:32345", - "dataset": { - "pool_name": "oxp_05715ad8-59a1-44ab-ad5f-0cdffb46baab" - } - } - }, - "root": "/pool/ext/2ec2a731-3340-4777-b1bb-4a906c598174/crypt/zone" - }, - { - "zone": { - "id": "8d202759-ca06-4383-b50f-7f3ec4062bf7", - "underlay_address": "fd00:1122:3344:104::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::4]:32345", - "dataset": { - "pool_name": "oxp_56e32a8f-0877-4437-9cab-94a4928b1495" - } - } - }, - "root": "/pool/ext/613b58fc-5a80-42dc-a61c-b143cf220fb5/crypt/zone" - }, - { - "zone": { - "id": "fcdda266-fc6a-4518-89db-aec007a4b682", - "underlay_address": "fd00:1122:3344:104::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::b]:32345", - "dataset": { - "pool_name": "oxp_7e1293ad-b903-4054-aeae-2182d5e4a785" - } - } - }, - "root": "/pool/ext/416fd29e-d3b5-4fdf-8101-d0d163fa0706/crypt/zone" - }, - { - "zone": { - "id": "167cf6a2-ec51-4de2-bc6c-7785bbc0e436", - "underlay_address": "fd00:1122:3344:104::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::c]:32345", - "dataset": { - "pool_name": "oxp_f96c8d49-fdf7-4bd6-84f6-c282202d1abc" - } - } - }, - "root": "/pool/ext/56e32a8f-0877-4437-9cab-94a4928b1495/crypt/zone" - }, - { - "zone": { - "id": "c6fde82d-8dae-4ef0-b557-6c3d094d9454", - "underlay_address": "fd00:1122:3344:104::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::9]:32345", - "dataset": { - "pool_name": "oxp_416fd29e-d3b5-4fdf-8101-d0d163fa0706" - } - } - }, - "root": "/pool/ext/3af01cc4-1f16-47d9-a489-abafcb91c2db/crypt/zone" - }, - { - "zone": { - "id": "650f5da7-86a0-4ade-af0f-bc96e021ded0", - "underlay_address": "fd00:1122:3344:104::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::5]:32345", - "dataset": { - "pool_name": "oxp_b4a71d3d-1ecd-418a-9a52-8d118f82082b" - } - } - }, - "root": "/pool/ext/613b58fc-5a80-42dc-a61c-b143cf220fb5/crypt/zone" - }, - { - "zone": { - "id": "7ce9a2c5-2d37-4188-b7b5-a9db819396c3", - "underlay_address": "fd00:1122:3344:104::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::d]:32345", - "dataset": { - "pool_name": "oxp_c87d16b8-e814-4159-8562-f8d7fdd19d13" - } - } - }, - "root": "/pool/ext/416fd29e-d3b5-4fdf-8101-d0d163fa0706/crypt/zone" - }, - { - "zone": { - "id": "23e1cf01-70ab-422f-997b-6216158965c3", - "underlay_address": "fd00:1122:3344:104::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::8]:32345", - "dataset": { - "pool_name": "oxp_3af01cc4-1f16-47d9-a489-abafcb91c2db" - } - } - }, - "root": "/pool/ext/3af01cc4-1f16-47d9-a489-abafcb91c2db/crypt/zone" - }, - { - "zone": { - "id": "50209816-89fb-48ed-9595-16899d114844", - "underlay_address": "fd00:1122:3344:104::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::6]:32345", - "dataset": { - "pool_name": "oxp_2ec2a731-3340-4777-b1bb-4a906c598174" - } - } - }, - "root": "/pool/ext/416fd29e-d3b5-4fdf-8101-d0d163fa0706/crypt/zone" - }, - { - "zone": { - "id": "20b100d0-84c3-4119-aa9b-0c632b0b6a3a", - "underlay_address": "fd00:1122:3344:104::3", - "zone_type": { - "type": "nexus", - "internal_address": "[fd00:1122:3344:104::3]:12221", - "external_ip": "172.20.26.4", - "nic": { - "id": "364b0ecd-bf08-4cac-a993-bbf4a70564c7", - "kind": { - "type": "service", - "id": "20b100d0-84c3-4119-aa9b-0c632b0b6a3a" - }, - "name": "nexus-20b100d0-84c3-4119-aa9b-0c632b0b6a3a", - "ip": "172.30.2.6", - "mac": "A8:40:25:FF:B4:C1", - "subnet": "172.30.2.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "external_tls": true, - "external_dns_servers": [ - "1.1.1.1", - "9.9.9.9" - ] - } - }, - "root": "/pool/ext/c87d16b8-e814-4159-8562-f8d7fdd19d13/crypt/zone" - }, - { - "zone": { - "id": "8bc0f29e-0c20-437e-b8ca-7b9844acda22", - "underlay_address": "fd00:1122:3344:104::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::7]:32345", - "dataset": { - "pool_name": "oxp_613b58fc-5a80-42dc-a61c-b143cf220fb5" - } - } - }, - "root": "/pool/ext/56e32a8f-0877-4437-9cab-94a4928b1495/crypt/zone" - }, - { - "zone": { - "id": "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55", - "underlay_address": "fd00:1122:3344:104::e", - "zone_type": { - "type": "boundary_ntp", - "address": "[fd00:1122:3344:104::e]:123", - "ntp_servers": [ - "ntp.eng.oxide.computer" - ], - "dns_servers": [ - "1.1.1.1", - "9.9.9.9" - ], - "domain": null, - "nic": { - "id": "a4b9bacf-6c04-431a-81ad-9bf0302af96e", - "kind": { - "type": "service", - "id": "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55" - }, - "name": "ntp-c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55", - "ip": "172.30.3.5", - "mac": "A8:40:25:FF:B2:52", - "subnet": "172.30.3.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "snat_cfg": { - "ip": "172.20.26.6", - "first_port": 0, - "last_port": 16383 - } - } - }, - "root": "/pool/ext/3af01cc4-1f16-47d9-a489-abafcb91c2db/crypt/zone" - }, - { - "zone": { - "id": "51c9ad09-7814-4643-8ad4-689ccbe53fbd", - "underlay_address": "fd00:1122:3344:1::1", - "zone_type": { - "type": "internal_dns", - "dataset": { - "pool_name": "oxp_56e32a8f-0877-4437-9cab-94a4928b1495" - }, - "http_address": "[fd00:1122:3344:1::1]:5353", - "dns_address": "[fd00:1122:3344:1::1]:53", - "gz_address": "fd00:1122:3344:1::2", - "gz_address_index": 0 - } - }, - "root": "/pool/ext/3af01cc4-1f16-47d9-a489-abafcb91c2db/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json deleted file mode 100644 index 25dfb72a78..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "ee8b2cfa-87fe-46a6-98ef-23640b80a968", - "underlay_address": "fd00:1122:3344:10b::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::d]:32345", - "dataset": { - "pool_name": "oxp_4a624324-003a-4255-98e8-546a90b5b7fa" - } - } - }, - "root": "/pool/ext/6b9ec5f1-859f-459c-9c06-6a51ba87786f/crypt/zone" - }, - { - "zone": { - "id": "9228f8ca-2a83-439f-9cb7-f2801b5fea27", - "underlay_address": "fd00:1122:3344:10b::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::6]:32345", - "dataset": { - "pool_name": "oxp_6b9ec5f1-859f-459c-9c06-6a51ba87786f" - } - } - }, - "root": "/pool/ext/6b9ec5f1-859f-459c-9c06-6a51ba87786f/crypt/zone" - }, - { - "zone": { - "id": "ee44cdde-7ac9-4469-9f1d-e8bcfeb5cc46", - "underlay_address": "fd00:1122:3344:10b::e", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::e]:32345", - "dataset": { - "pool_name": "oxp_11b02ce7-7e50-486f-86c2-de8af9575a45" - } - } - }, - "root": "/pool/ext/11b02ce7-7e50-486f-86c2-de8af9575a45/crypt/zone" - }, - { - "zone": { - "id": "96bac0b1-8b34-4c81-9e76-6404d2c37630", - "underlay_address": "fd00:1122:3344:10b::4", - "zone_type": { - "type": "crucible_pantry", - "address": "[fd00:1122:3344:10b::4]:17000" - } - }, - "root": "/pool/ext/350b2814-7b7f-40f1-9bf6-9818a1ef49bb/crypt/zone" - }, - { - "zone": { - "id": "d4e1e554-7b98-4413-809e-4a42561c3d0c", - "underlay_address": "fd00:1122:3344:10b::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::a]:32345", - "dataset": { - "pool_name": "oxp_e6d2fe1d-c74d-40cd-8fae-bc7d06bdaac8" - } - } - }, - "root": "/pool/ext/6b9ec5f1-859f-459c-9c06-6a51ba87786f/crypt/zone" - }, - { - "zone": { - "id": "1dd69b02-a032-46c3-8e2a-5012e8314455", - "underlay_address": "fd00:1122:3344:10b::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::b]:32345", - "dataset": { - "pool_name": "oxp_350b2814-7b7f-40f1-9bf6-9818a1ef49bb" - } - } - }, - "root": "/pool/ext/350b2814-7b7f-40f1-9bf6-9818a1ef49bb/crypt/zone" - }, - { - "zone": { - "id": "921f7752-d2f3-40df-a739-5cb1390abc2c", - "underlay_address": "fd00:1122:3344:10b::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::8]:32345", - "dataset": { - "pool_name": "oxp_2d1ebe24-6deb-4f81-8450-6842de28126c" - } - } - }, - "root": "/pool/ext/91ea7bb6-2be7-4498-9b0d-a0521509ec00/crypt/zone" - }, - { - "zone": { - "id": "609b25e8-9750-4308-ae6f-7202907a3675", - "underlay_address": "fd00:1122:3344:10b::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::9]:32345", - "dataset": { - "pool_name": "oxp_91ea7bb6-2be7-4498-9b0d-a0521509ec00" - } - } - }, - "root": "/pool/ext/2d1ebe24-6deb-4f81-8450-6842de28126c/crypt/zone" - }, - { - "zone": { - "id": "a232eba2-e94f-4592-a5a6-ec23f9be3296", - "underlay_address": "fd00:1122:3344:10b::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::5]:32345", - "dataset": { - "pool_name": "oxp_e12f29b8-1ab8-431e-bc96-1c1298947980" - } - } - }, - "root": "/pool/ext/021afd19-2f87-4def-9284-ab7add1dd6ae/crypt/zone" - }, - { - "zone": { - "id": "800d1758-9312-4b1a-8f02-dc6d644c2a9b", - "underlay_address": "fd00:1122:3344:10b::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::c]:32345", - "dataset": { - "pool_name": "oxp_b6932bb0-bab8-4876-914a-9c75a600e794" - } - } - }, - "root": "/pool/ext/b6932bb0-bab8-4876-914a-9c75a600e794/crypt/zone" - }, - { - "zone": { - "id": "668a4d4a-96dc-4b45-866b-bed3d64c26ec", - "underlay_address": "fd00:1122:3344:10b::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::7]:32345", - "dataset": { - "pool_name": "oxp_021afd19-2f87-4def-9284-ab7add1dd6ae" - } - } - }, - "root": "/pool/ext/91ea7bb6-2be7-4498-9b0d-a0521509ec00/crypt/zone" - }, - { - "zone": { - "id": "8bbea076-ff60-4330-8302-383e18140ef3", - "underlay_address": "fd00:1122:3344:10b::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:10b::3]:32221", - "dataset": { - "pool_name": "oxp_e12f29b8-1ab8-431e-bc96-1c1298947980" - } - } - }, - "root": "/pool/ext/4a624324-003a-4255-98e8-546a90b5b7fa/crypt/zone" - }, - { - "zone": { - "id": "3ccea933-89f2-4ce5-8367-efb0afeffe97", - "underlay_address": "fd00:1122:3344:10b::f", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:10b::f]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/4a624324-003a-4255-98e8-546a90b5b7fa/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json deleted file mode 100644 index 905742e678..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "b12aa520-a769-4eac-b56b-09960550a831", - "underlay_address": "fd00:1122:3344:108::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::7]:32345", - "dataset": { - "pool_name": "oxp_34dadf3f-f60c-4acc-b82b-4b0c82224222" - } - } - }, - "root": "/pool/ext/8be8c577-23ac-452e-a205-6d9c95088f61/crypt/zone" - }, - { - "zone": { - "id": "9bdc40ee-ccba-4d18-9efb-a30596e2d290", - "underlay_address": "fd00:1122:3344:108::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::d]:32345", - "dataset": { - "pool_name": "oxp_eb81728c-3b83-42fb-8133-ac32a0bdf70f" - } - } - }, - "root": "/pool/ext/8be8c577-23ac-452e-a205-6d9c95088f61/crypt/zone" - }, - { - "zone": { - "id": "c9a367c7-64d7-48e4-b484-9ecb4e8faea7", - "underlay_address": "fd00:1122:3344:108::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::9]:32345", - "dataset": { - "pool_name": "oxp_76ab5a67-e20f-4bf0-87b3-01fcc4144bd2" - } - } - }, - "root": "/pool/ext/34dadf3f-f60c-4acc-b82b-4b0c82224222/crypt/zone" - }, - { - "zone": { - "id": "bc5124d8-65e8-4879-bfac-64d59003d482", - "underlay_address": "fd00:1122:3344:108::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::a]:32345", - "dataset": { - "pool_name": "oxp_5fac7a1d-e855-46e1-b8c2-dd848ac4fee6" - } - } - }, - "root": "/pool/ext/0c4ef358-5533-43db-ad38-a8eff716e53a/crypt/zone" - }, - { - "zone": { - "id": "5cc7c840-8e6b-48c8-ac4b-f4297f8cf61a", - "underlay_address": "fd00:1122:3344:108::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::c]:32345", - "dataset": { - "pool_name": "oxp_0c4ef358-5533-43db-ad38-a8eff716e53a" - } - } - }, - "root": "/pool/ext/6d3e9cc6-f03b-4055-9785-05711d5e4fdc/crypt/zone" - }, - { - "zone": { - "id": "3b767edf-a72d-4d80-a0fc-65d6801ed0e0", - "underlay_address": "fd00:1122:3344:108::e", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::e]:32345", - "dataset": { - "pool_name": "oxp_f522118c-5dcd-4116-8044-07f0cceec52e" - } - } - }, - "root": "/pool/ext/5fac7a1d-e855-46e1-b8c2-dd848ac4fee6/crypt/zone" - }, - { - "zone": { - "id": "f3c02ed6-fbc5-45c3-a030-409f74b450fd", - "underlay_address": "fd00:1122:3344:108::4", - "zone_type": { - "type": "crucible_pantry", - "address": "[fd00:1122:3344:108::4]:17000" - } - }, - "root": "/pool/ext/eb81728c-3b83-42fb-8133-ac32a0bdf70f/crypt/zone" - }, - { - "zone": { - "id": "85bd9bdb-1ec5-4a8d-badb-8b5d502546a1", - "underlay_address": "fd00:1122:3344:108::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::5]:32345", - "dataset": { - "pool_name": "oxp_416232c1-bc8f-403f-bacb-28403dd8fced" - } - } - }, - "root": "/pool/ext/34dadf3f-f60c-4acc-b82b-4b0c82224222/crypt/zone" - }, - { - "zone": { - "id": "d2f1c3df-d4e0-4469-b50e-f1871da86ebf", - "underlay_address": "fd00:1122:3344:108::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::6]:32345", - "dataset": { - "pool_name": "oxp_6d3e9cc6-f03b-4055-9785-05711d5e4fdc" - } - } - }, - "root": "/pool/ext/34dadf3f-f60c-4acc-b82b-4b0c82224222/crypt/zone" - }, - { - "zone": { - "id": "88fe3c12-4c55-47df-b4ee-ed26b795439d", - "underlay_address": "fd00:1122:3344:108::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::8]:32345", - "dataset": { - "pool_name": "oxp_8be8c577-23ac-452e-a205-6d9c95088f61" - } - } - }, - "root": "/pool/ext/34dadf3f-f60c-4acc-b82b-4b0c82224222/crypt/zone" - }, - { - "zone": { - "id": "4d20175a-588b-44b8-8b9c-b16c6c3a97a0", - "underlay_address": "fd00:1122:3344:108::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::b]:32345", - "dataset": { - "pool_name": "oxp_a726cacd-fa35-4ed2-ade6-31ad928b24cb" - } - } - }, - "root": "/pool/ext/0c4ef358-5533-43db-ad38-a8eff716e53a/crypt/zone" - }, - { - "zone": { - "id": "e86845b5-eabd-49f5-9a10-6dfef9066209", - "underlay_address": "fd00:1122:3344:108::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:108::3]:32221", - "dataset": { - "pool_name": "oxp_416232c1-bc8f-403f-bacb-28403dd8fced" - } - } - }, - "root": "/pool/ext/416232c1-bc8f-403f-bacb-28403dd8fced/crypt/zone" - }, - { - "zone": { - "id": "209b6213-588b-43b6-a89b-19ee5c84ffba", - "underlay_address": "fd00:1122:3344:108::f", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:108::f]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/416232c1-bc8f-403f-bacb-28403dd8fced/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json deleted file mode 100644 index 1cccd0467b..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "90b53c3d-42fa-4ca9-bbfc-96fff245b508", - "underlay_address": "fd00:1122:3344:109::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::4]:32345", - "dataset": { - "pool_name": "oxp_ae56280b-17ce-4266-8573-e1da9db6c6bb" - } - } - }, - "root": "/pool/ext/b0e1a261-b932-47c4-81e9-1977275ae9d9/crypt/zone" - }, - { - "zone": { - "id": "4f9f2e1d-be04-4e8b-a50b-ffb18557a650", - "underlay_address": "fd00:1122:3344:109::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::5]:32345", - "dataset": { - "pool_name": "oxp_d5b07362-64db-4b18-a3e9-8d7cbabae2d5" - } - } - }, - "root": "/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone" - }, - { - "zone": { - "id": "2fa5671d-3109-4f11-ae70-1280f4fa3b89", - "underlay_address": "fd00:1122:3344:109::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::6]:32345", - "dataset": { - "pool_name": "oxp_9ba7bfbf-b9a2-4237-a142-94c1e68de984" - } - } - }, - "root": "/pool/ext/3cafbb47-c194-4a42-99ff-34dfeab999ed/crypt/zone" - }, - { - "zone": { - "id": "b63c6882-ca90-4156-b561-4781ab4a0962", - "underlay_address": "fd00:1122:3344:109::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::7]:32345", - "dataset": { - "pool_name": "oxp_b0e1a261-b932-47c4-81e9-1977275ae9d9" - } - } - }, - "root": "/pool/ext/d5b07362-64db-4b18-a3e9-8d7cbabae2d5/crypt/zone" - }, - { - "zone": { - "id": "f71344eb-f7e2-439d-82a0-9941e6868fb6", - "underlay_address": "fd00:1122:3344:109::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::9]:32345", - "dataset": { - "pool_name": "oxp_027a82e8-daa3-4fa6-8205-ed03445e1086" - } - } - }, - "root": "/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone" - }, - { - "zone": { - "id": "a60cf0d7-12d5-43cb-aa3f-7a9e84de08fb", - "underlay_address": "fd00:1122:3344:109::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::a]:32345", - "dataset": { - "pool_name": "oxp_8736aaf9-4d72-42b1-8e4f-07644d999c8b" - } - } - }, - "root": "/pool/ext/8736aaf9-4d72-42b1-8e4f-07644d999c8b/crypt/zone" - }, - { - "zone": { - "id": "5d0e03b2-8958-4c43-8851-bf819f102958", - "underlay_address": "fd00:1122:3344:109::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::8]:32345", - "dataset": { - "pool_name": "oxp_62426615-7832-49e7-9426-e39ffeb42c69" - } - } - }, - "root": "/pool/ext/07fc8ec9-1216-4d98-be34-c2970b585e61/crypt/zone" - }, - { - "zone": { - "id": "accc05a2-ec80-4856-a825-ec6b7f700eaa", - "underlay_address": "fd00:1122:3344:109::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::d]:32345", - "dataset": { - "pool_name": "oxp_dc083c53-7014-4482-8a79-f338ba2b0fb4" - } - } - }, - "root": "/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone" - }, - { - "zone": { - "id": "2e32fdcc-737a-4430-8290-cb7028ea4d50", - "underlay_address": "fd00:1122:3344:109::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::b]:32345", - "dataset": { - "pool_name": "oxp_3cafbb47-c194-4a42-99ff-34dfeab999ed" - } - } - }, - "root": "/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone" - }, - { - "zone": { - "id": "a97c6ae2-37f6-4d93-a66e-cb5cd3c6aaa2", - "underlay_address": "fd00:1122:3344:109::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::c]:32345", - "dataset": { - "pool_name": "oxp_07fc8ec9-1216-4d98-be34-c2970b585e61" - } - } - }, - "root": "/pool/ext/07fc8ec9-1216-4d98-be34-c2970b585e61/crypt/zone" - }, - { - "zone": { - "id": "3237a532-acaa-4ebe-bf11-dde794fea739", - "underlay_address": "fd00:1122:3344:109::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:109::3]:32221", - "dataset": { - "pool_name": "oxp_ae56280b-17ce-4266-8573-e1da9db6c6bb" - } - } - }, - "root": "/pool/ext/027a82e8-daa3-4fa6-8205-ed03445e1086/crypt/zone" - }, - { - "zone": { - "id": "83257100-5590-484a-b72a-a079389d8da6", - "underlay_address": "fd00:1122:3344:109::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:109::e]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/3cafbb47-c194-4a42-99ff-34dfeab999ed/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json deleted file mode 100644 index 35caa638e8..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 5, - "zones": [ - { - "zone": { - "id": "0437b69d-73a8-4231-86f9-6b5556e7e7ef", - "underlay_address": "fd00:1122:3344:102::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::5]:32345", - "dataset": { - "pool_name": "oxp_aa0ffe35-76db-42ab-adf2-ceb072bdf811" - } - } - }, - "root": "/pool/ext/0d2805da-6d24-4e57-a700-0c3865c05544/crypt/zone" - }, - { - "zone": { - "id": "47234ca5-305f-436a-9e9a-36bca9667680", - "underlay_address": "fd00:1122:3344:102::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::b]:32345", - "dataset": { - "pool_name": "oxp_0d2805da-6d24-4e57-a700-0c3865c05544" - } - } - }, - "root": "/pool/ext/160691d8-33a1-4d7d-a48a-c3fd27d76822/crypt/zone" - }, - { - "zone": { - "id": "2898657e-4141-4c05-851b-147bffc6bbbd", - "underlay_address": "fd00:1122:3344:102::3", - "zone_type": { - "type": "nexus", - "internal_address": "[fd00:1122:3344:102::3]:12221", - "external_ip": "172.20.26.5", - "nic": { - "id": "2e9a412e-c79a-48fe-8fa4-f5a6afed1040", - "kind": { - "type": "service", - "id": "2898657e-4141-4c05-851b-147bffc6bbbd" - }, - "name": "nexus-2898657e-4141-4c05-851b-147bffc6bbbd", - "ip": "172.30.2.7", - "mac": "A8:40:25:FF:C6:59", - "subnet": "172.30.2.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "external_tls": true, - "external_dns_servers": [ - "1.1.1.1", - "9.9.9.9" - ] - } - }, - "root": "/pool/ext/c0b4ecc1-a145-443f-90d1-2e8136b007bc/crypt/zone" - }, - { - "zone": { - "id": "cf98c4d6-4a7b-49c0-9b14-48a8adf52ce9", - "underlay_address": "fd00:1122:3344:102::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::c]:32345", - "dataset": { - "pool_name": "oxp_c0b4ecc1-a145-443f-90d1-2e8136b007bc" - } - } - }, - "root": "/pool/ext/f6acd70a-d6cb-464d-a460-dd5c60301562/crypt/zone" - }, - { - "zone": { - "id": "13c1e91e-bfcc-4eea-8185-412fc37fdea3", - "underlay_address": "fd00:1122:3344:102::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::9]:32345", - "dataset": { - "pool_name": "oxp_e9b0a2e4-8060-41bd-a3b5-d0642246d06d" - } - } - }, - "root": "/pool/ext/c0b4ecc1-a145-443f-90d1-2e8136b007bc/crypt/zone" - }, - { - "zone": { - "id": "c9cb60af-9e0e-4b3b-b971-53138a9b8d27", - "underlay_address": "fd00:1122:3344:102::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::4]:32345", - "dataset": { - "pool_name": "oxp_77749ec7-39a9-489d-904b-87f7223c4e3c" - } - } - }, - "root": "/pool/ext/77749ec7-39a9-489d-904b-87f7223c4e3c/crypt/zone" - }, - { - "zone": { - "id": "32995cfa-47ec-4b84-8514-7c1c8a86c19d", - "underlay_address": "fd00:1122:3344:102::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::8]:32345", - "dataset": { - "pool_name": "oxp_eac83f81-eb51-4f3e-874e-82f55dd952ba" - } - } - }, - "root": "/pool/ext/0d2805da-6d24-4e57-a700-0c3865c05544/crypt/zone" - }, - { - "zone": { - "id": "b93d2e2d-d54b-4503-85c3-9878e3cee9c7", - "underlay_address": "fd00:1122:3344:102::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::a]:32345", - "dataset": { - "pool_name": "oxp_160691d8-33a1-4d7d-a48a-c3fd27d76822" - } - } - }, - "root": "/pool/ext/138663ad-a382-4595-baf0-08f6b0276a67/crypt/zone" - }, - { - "zone": { - "id": "2ebbac4f-7b0f-43eb-99fd-dd6ff7f9e097", - "underlay_address": "fd00:1122:3344:102::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::6]:32345", - "dataset": { - "pool_name": "oxp_138663ad-a382-4595-baf0-08f6b0276a67" - } - } - }, - "root": "/pool/ext/e9b0a2e4-8060-41bd-a3b5-d0642246d06d/crypt/zone" - }, - { - "zone": { - "id": "d0eea3b2-e5ac-42bf-97b7-531b78fa06d1", - "underlay_address": "fd00:1122:3344:102::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::7]:32345", - "dataset": { - "pool_name": "oxp_69f0b863-f73f-42b2-9822-b2cb99f09003" - } - } - }, - "root": "/pool/ext/138663ad-a382-4595-baf0-08f6b0276a67/crypt/zone" - }, - { - "zone": { - "id": "2b34cd1d-ea7d-41a1-82b9-75550fdf6eb0", - "underlay_address": "fd00:1122:3344:102::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::d]:32345", - "dataset": { - "pool_name": "oxp_f6acd70a-d6cb-464d-a460-dd5c60301562" - } - } - }, - "root": "/pool/ext/c0b4ecc1-a145-443f-90d1-2e8136b007bc/crypt/zone" - }, - { - "zone": { - "id": "6ea2684c-115e-48a6-8453-ab52d1cecd73", - "underlay_address": "fd00:1122:3344:102::e", - "zone_type": { - "type": "boundary_ntp", - "address": "[fd00:1122:3344:102::e]:123", - "ntp_servers": [ - "ntp.eng.oxide.computer" - ], - "dns_servers": [ - "1.1.1.1", - "9.9.9.9" - ], - "domain": null, - "nic": { - "id": "4effd079-ed4e-4cf6-8545-bb9574f516d2", - "kind": { - "type": "service", - "id": "6ea2684c-115e-48a6-8453-ab52d1cecd73" - }, - "name": "ntp-6ea2684c-115e-48a6-8453-ab52d1cecd73", - "ip": "172.30.3.6", - "mac": "A8:40:25:FF:A0:F9", - "subnet": "172.30.3.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "snat_cfg": { - "ip": "172.20.26.7", - "first_port": 16384, - "last_port": 32767 - } - } - }, - "root": "/pool/ext/aa0ffe35-76db-42ab-adf2-ceb072bdf811/crypt/zone" - }, - { - "zone": { - "id": "3a1ea15f-06a4-4afd-959a-c3a00b2bdd80", - "underlay_address": "fd00:1122:3344:2::1", - "zone_type": { - "type": "internal_dns", - "dataset": { - "pool_name": "oxp_77749ec7-39a9-489d-904b-87f7223c4e3c" - }, - "http_address": "[fd00:1122:3344:2::1]:5353", - "dns_address": "[fd00:1122:3344:2::1]:53", - "gz_address": "fd00:1122:3344:2::2", - "gz_address_index": 1 - } - }, - "root": "/pool/ext/69f0b863-f73f-42b2-9822-b2cb99f09003/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json deleted file mode 100644 index 94fcb3a327..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 5, - "zones": [ - { - "zone": { - "id": "1876cdcf-b2e7-4b79-ad2e-67df716e1860", - "underlay_address": "fd00:1122:3344:10a::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::8]:32345", - "dataset": { - "pool_name": "oxp_d4c6bdc6-5e99-4f6c-b57a-9bfcb9a76be4" - } - } - }, - "root": "/pool/ext/86c58ea3-1413-4af3-9aff-9c0a3d758459/crypt/zone" - }, - { - "zone": { - "id": "0e708ee3-b7a6-4993-a88a-4489add33e29", - "underlay_address": "fd00:1122:3344:10a::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::d]:32345", - "dataset": { - "pool_name": "oxp_718ad834-b415-4abb-934d-9f987cde0a96" - } - } - }, - "root": "/pool/ext/30f7d236-c835-46cc-bc27-9099a6826f67/crypt/zone" - }, - { - "zone": { - "id": "4e1b9a65-848f-4649-b360-1df0d135b44d", - "underlay_address": "fd00:1122:3344:10a::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::c]:32345", - "dataset": { - "pool_name": "oxp_88ee08c6-1c0f-44c2-9110-b8d5a7589ebb" - } - } - }, - "root": "/pool/ext/30f7d236-c835-46cc-bc27-9099a6826f67/crypt/zone" - }, - { - "zone": { - "id": "da510a57-3af1-4d2b-b2ed-2e8849f27d8b", - "underlay_address": "fd00:1122:3344:10a::3", - "zone_type": { - "type": "oximeter", - "address": "[fd00:1122:3344:10a::3]:12223" - } - }, - "root": "/pool/ext/718ad834-b415-4abb-934d-9f987cde0a96/crypt/zone" - }, - { - "zone": { - "id": "d4d9acc8-3e0b-4fab-a0a2-d21920fabd7e", - "underlay_address": "fd00:1122:3344:10a::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::6]:32345", - "dataset": { - "pool_name": "oxp_9dfe424f-cba6-4bfb-a3dd-e8bd7fdea57d" - } - } - }, - "root": "/pool/ext/30f7d236-c835-46cc-bc27-9099a6826f67/crypt/zone" - }, - { - "zone": { - "id": "fcb75972-836b-4f55-ba21-9722832cf5c2", - "underlay_address": "fd00:1122:3344:10a::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::7]:32345", - "dataset": { - "pool_name": "oxp_9005671f-3d90-4ed1-be15-ad65b9a65bd5" - } - } - }, - "root": "/pool/ext/d4c6bdc6-5e99-4f6c-b57a-9bfcb9a76be4/crypt/zone" - }, - { - "zone": { - "id": "624beba0-7dcd-4d55-af05-4670c6fcb1fb", - "underlay_address": "fd00:1122:3344:10a::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::4]:32345", - "dataset": { - "pool_name": "oxp_93867156-a43d-4c03-a899-1535e566c8bd" - } - } - }, - "root": "/pool/ext/93867156-a43d-4c03-a899-1535e566c8bd/crypt/zone" - }, - { - "zone": { - "id": "26fb3830-898e-4086-afaf-8f9654716b8c", - "underlay_address": "fd00:1122:3344:10a::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::b]:32345", - "dataset": { - "pool_name": "oxp_86c58ea3-1413-4af3-9aff-9c0a3d758459" - } - } - }, - "root": "/pool/ext/93867156-a43d-4c03-a899-1535e566c8bd/crypt/zone" - }, - { - "zone": { - "id": "a3ef7eba-c08e-48ef-ae7a-89e2fcb49b66", - "underlay_address": "fd00:1122:3344:10a::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::a]:32345", - "dataset": { - "pool_name": "oxp_cd3fdbae-a9d9-4db7-866a-bca36f6dd634" - } - } - }, - "root": "/pool/ext/718ad834-b415-4abb-934d-9f987cde0a96/crypt/zone" - }, - { - "zone": { - "id": "5c1d4a02-f33b-433a-81f5-5c149e3433bd", - "underlay_address": "fd00:1122:3344:10a::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::5]:32345", - "dataset": { - "pool_name": "oxp_9adfc865-2eef-4880-a6e3-9d2f88c8efd0" - } - } - }, - "root": "/pool/ext/cd3fdbae-a9d9-4db7-866a-bca36f6dd634/crypt/zone" - }, - { - "zone": { - "id": "ee77efe9-81d0-4395-a237-15e30c2c2d04", - "underlay_address": "fd00:1122:3344:10a::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::9]:32345", - "dataset": { - "pool_name": "oxp_30f7d236-c835-46cc-bc27-9099a6826f67" - } - } - }, - "root": "/pool/ext/88ee08c6-1c0f-44c2-9110-b8d5a7589ebb/crypt/zone" - }, - { - "zone": { - "id": "71ab91b7-48d4-4d31-b47e-59f29f419116", - "underlay_address": "fd00:1122:3344:10a::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:10a::e]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/cd3fdbae-a9d9-4db7-866a-bca36f6dd634/crypt/zone" - }, - { - "zone": { - "id": "46ccd8fe-4e3c-4307-97ae-1f7ac505082a", - "underlay_address": "fd00:1122:3344:3::1", - "zone_type": { - "type": "internal_dns", - "dataset": { - "pool_name": "oxp_93867156-a43d-4c03-a899-1535e566c8bd" - }, - "http_address": "[fd00:1122:3344:3::1]:5353", - "dns_address": "[fd00:1122:3344:3::1]:53", - "gz_address": "fd00:1122:3344:3::2", - "gz_address_index": 2 - } - }, - "root": "/pool/ext/9dfe424f-cba6-4bfb-a3dd-e8bd7fdea57d/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json deleted file mode 100644 index 09a07149cf..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json +++ /dev/null @@ -1,196 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "180d466d-eb36-4546-8922-e52c4c076823", - "underlay_address": "fd00:1122:3344:101::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::5]:32345", - "dataset": { - "pool_name": "oxp_ac789935-fa42-4d00-8967-df0d96dbb74e" - } - } - }, - "root": "/pool/ext/d732addc-cfe8-4c2c-8028-72eb4481b04e/crypt/zone" - }, - { - "zone": { - "id": "b5af0303-bc03-40a3-b733-0396d705dfbf", - "underlay_address": "fd00:1122:3344:101::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::7]:32345", - "dataset": { - "pool_name": "oxp_d732addc-cfe8-4c2c-8028-72eb4481b04e" - } - } - }, - "root": "/pool/ext/677b0057-3a80-461b-aca8-c2cb501a7278/crypt/zone" - }, - { - "zone": { - "id": "9c7c805a-f5ed-4e48-86e3-7aa81a718881", - "underlay_address": "fd00:1122:3344:101::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::c]:32345", - "dataset": { - "pool_name": "oxp_923c930c-80f8-448d-8321-cebfc6c41760" - } - } - }, - "root": "/pool/ext/ac789935-fa42-4d00-8967-df0d96dbb74e/crypt/zone" - }, - { - "zone": { - "id": "4e49c83c-2d4a-491a-91ac-4ab022026dcf", - "underlay_address": "fd00:1122:3344:101::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::4]:32345", - "dataset": { - "pool_name": "oxp_c99e6032-1d4f-47d2-9efe-ae2b2479554e" - } - } - }, - "root": "/pool/ext/653065d2-ab70-47c9-b832-34238fdc95ef/crypt/zone" - }, - { - "zone": { - "id": "0e38475e-b8b2-4813-bf80-3c170081081a", - "underlay_address": "fd00:1122:3344:101::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::d]:32345", - "dataset": { - "pool_name": "oxp_653065d2-ab70-47c9-b832-34238fdc95ef" - } - } - }, - "root": "/pool/ext/4c7ad252-55c2-4a1a-9d93-9dfcdfdfacca/crypt/zone" - }, - { - "zone": { - "id": "75123e60-1116-4b8d-a466-7302220127da", - "underlay_address": "fd00:1122:3344:101::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::8]:32345", - "dataset": { - "pool_name": "oxp_c764a8ae-6862-4eec-9db0-cc6ea478e4a7" - } - } - }, - "root": "/pool/ext/c764a8ae-6862-4eec-9db0-cc6ea478e4a7/crypt/zone" - }, - { - "zone": { - "id": "fbd0379c-97fa-49ea-8980-17ae30ffff3c", - "underlay_address": "fd00:1122:3344:101::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::b]:32345", - "dataset": { - "pool_name": "oxp_fcb0e4c7-e046-4cf5-ad35-3ad90e1eb90c" - } - } - }, - "root": "/pool/ext/4c7ad252-55c2-4a1a-9d93-9dfcdfdfacca/crypt/zone" - }, - { - "zone": { - "id": "ec635326-cd1d-4f73-b8e6-c3a36a7020db", - "underlay_address": "fd00:1122:3344:101::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::a]:32345", - "dataset": { - "pool_name": "oxp_6bfb4120-488d-4f3d-90ef-e9bfa523b388" - } - } - }, - "root": "/pool/ext/c99e6032-1d4f-47d2-9efe-ae2b2479554e/crypt/zone" - }, - { - "zone": { - "id": "f500d564-c40a-4eca-ac8a-a26b435f2037", - "underlay_address": "fd00:1122:3344:101::3", - "zone_type": { - "type": "external_dns", - "dataset": { - "pool_name": "oxp_c99e6032-1d4f-47d2-9efe-ae2b2479554e" - }, - "http_address": "[fd00:1122:3344:101::3]:5353", - "dns_address": "172.20.26.2:53", - "nic": { - "id": "b0b42776-3914-4a69-889f-4831dc72327c", - "kind": { - "type": "service", - "id": "f500d564-c40a-4eca-ac8a-a26b435f2037" - }, - "name": "external-dns-f500d564-c40a-4eca-ac8a-a26b435f2037", - "ip": "172.30.1.6", - "mac": "A8:40:25:FF:D0:B4", - "subnet": "172.30.1.0/24", - "vni": 100, - "primary": true, - "slot": 0 - } - } - }, - "root": "/pool/ext/ac789935-fa42-4d00-8967-df0d96dbb74e/crypt/zone" - }, - { - "zone": { - "id": "56d4dbcc-3b4a-4ed0-8795-7734aadcc4c0", - "underlay_address": "fd00:1122:3344:101::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::9]:32345", - "dataset": { - "pool_name": "oxp_4c7ad252-55c2-4a1a-9d93-9dfcdfdfacca" - } - } - }, - "root": "/pool/ext/4c7ad252-55c2-4a1a-9d93-9dfcdfdfacca/crypt/zone" - }, - { - "zone": { - "id": "0d3a1bd5-f6fe-49cb-807a-190dabc90103", - "underlay_address": "fd00:1122:3344:101::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::6]:32345", - "dataset": { - "pool_name": "oxp_677b0057-3a80-461b-aca8-c2cb501a7278" - } - } - }, - "root": "/pool/ext/6bfb4120-488d-4f3d-90ef-e9bfa523b388/crypt/zone" - }, - { - "zone": { - "id": "d34c7184-5d4e-4cb5-8f91-df74a343ffbc", - "underlay_address": "fd00:1122:3344:101::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:101::e]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/ac789935-fa42-4d00-8967-df0d96dbb74e/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json deleted file mode 100644 index 669889b3c5..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json +++ /dev/null @@ -1,198 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "7153983f-8fd7-4fb9-92ac-0f07a07798b4", - "underlay_address": "fd00:1122:3344:103::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::a]:32345", - "dataset": { - "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f" - } - } - }, - "root": "/pool/ext/26e698bb-006d-4208-94b9-d1bc279111fa/crypt/zone" - }, - { - "zone": { - "id": "7d44ba36-4a69-490a-bc40-f6f90a4208d4", - "underlay_address": "fd00:1122:3344:103::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::c]:32345", - "dataset": { - "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052" - } - } - }, - "root": "/pool/ext/cf940e15-dbc5-481b-866a-4de4b018898e/crypt/zone" - }, - { - "zone": { - "id": "65a11c18-7f59-41ac-b9e7-680627f996e7", - "underlay_address": "fd00:1122:3344:103::3", - "zone_type": { - "type": "nexus", - "internal_address": "[fd00:1122:3344:103::3]:12221", - "external_ip": "172.20.26.3", - "nic": { - "id": "a3e13dde-a2bc-4170-ad84-aad8085b6034", - "kind": { - "type": "service", - "id": "65a11c18-7f59-41ac-b9e7-680627f996e7" - }, - "name": "nexus-65a11c18-7f59-41ac-b9e7-680627f996e7", - "ip": "172.30.2.5", - "mac": "A8:40:25:FF:A6:83", - "subnet": "172.30.2.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "external_tls": true, - "external_dns_servers": [ - "1.1.1.1", - "9.9.9.9" - ] - } - }, - "root": "/pool/ext/e126ddcc-8bee-46ba-8199-2a74df0ba040/crypt/zone" - }, - { - "zone": { - "id": "072fdae8-2adf-4fd2-94ce-e9b0663b91e7", - "underlay_address": "fd00:1122:3344:103::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::b]:32345", - "dataset": { - "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa" - } - } - }, - "root": "/pool/ext/bf428719-1b16-4503-99f4-ad95846d916f/crypt/zone" - }, - { - "zone": { - "id": "01f93020-7e7d-4185-93fb-6ca234056c82", - "underlay_address": "fd00:1122:3344:103::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::5]:32345", - "dataset": { - "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7" - } - } - }, - "root": "/pool/ext/7b24095a-72df-45e3-984f-2b795e052ac7/crypt/zone" - }, - { - "zone": { - "id": "e238116d-e5cc-43d4-9c8a-6f138ae8a15d", - "underlay_address": "fd00:1122:3344:103::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::6]:32345", - "dataset": { - "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040" - } - } - }, - "root": "/pool/ext/7b24095a-72df-45e3-984f-2b795e052ac7/crypt/zone" - }, - { - "zone": { - "id": "585cd8c5-c41e-4be4-beb8-bfbef9b53856", - "underlay_address": "fd00:1122:3344:103::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::7]:32345", - "dataset": { - "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33" - } - } - }, - "root": "/pool/ext/414e235b-55c3-4dc1-a568-8adf4ea1a052/crypt/zone" - }, - { - "zone": { - "id": "0b41c560-3b20-42f4-82ad-92f5bb575d6b", - "underlay_address": "fd00:1122:3344:103::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::9]:32345", - "dataset": { - "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc" - } - } - }, - "root": "/pool/ext/6340805e-c5af-418d-8bd1-fc0085667f33/crypt/zone" - }, - { - "zone": { - "id": "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9", - "underlay_address": "fd00:1122:3344:103::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::d]:32345", - "dataset": { - "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e" - } - } - }, - "root": "/pool/ext/414e235b-55c3-4dc1-a568-8adf4ea1a052/crypt/zone" - }, - { - "zone": { - "id": "a6ba8273-0320-4dab-b801-281f041b0c50", - "underlay_address": "fd00:1122:3344:103::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::4]:32345", - "dataset": { - "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35" - } - } - }, - "root": "/pool/ext/b93f880e-c55b-4d6c-9a16-939d84b628fc/crypt/zone" - }, - { - "zone": { - "id": "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4", - "underlay_address": "fd00:1122:3344:103::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::8]:32345", - "dataset": { - "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e" - } - } - }, - "root": "/pool/ext/cf940e15-dbc5-481b-866a-4de4b018898e/crypt/zone" - }, - { - "zone": { - "id": "7a85d50e-b524-41c1-a052-118027eb77db", - "underlay_address": "fd00:1122:3344:103::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:103::e]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/b93f880e-c55b-4d6c-9a16-939d84b628fc/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json deleted file mode 100644 index d4a429f9b0..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "912346a2-d7e6-427e-b373-e8dcbe4fcea9", - "underlay_address": "fd00:1122:3344:105::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::5]:32345", - "dataset": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37" - } - } - }, - "root": "/pool/ext/0ae29053-29a2-489e-a1e6-6aec0ecd05f8/crypt/zone" - }, - { - "zone": { - "id": "3d420dff-c616-4c7d-bab1-0f9c2b5396bf", - "underlay_address": "fd00:1122:3344:105::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::a]:32345", - "dataset": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4" - } - } - }, - "root": "/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone" - }, - { - "zone": { - "id": "9c5d88c9-8ff1-4f23-9438-7b81322eaf68", - "underlay_address": "fd00:1122:3344:105::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::b]:32345", - "dataset": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11" - } - } - }, - "root": "/pool/ext/4358f47f-f21e-4cc8-829e-0c7fc2400a59/crypt/zone" - }, - { - "zone": { - "id": "f9c1deca-1898-429e-8c93-254c7aa7bae6", - "underlay_address": "fd00:1122:3344:105::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::8]:32345", - "dataset": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e" - } - } - }, - "root": "/pool/ext/f8b11629-ced6-412a-9c3f-d169b99ee996/crypt/zone" - }, - { - "zone": { - "id": "ce8563f3-4a93-45ff-b727-cbfbee6aa413", - "underlay_address": "fd00:1122:3344:105::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::9]:32345", - "dataset": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59" - } - } - }, - "root": "/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone" - }, - { - "zone": { - "id": "9470ea7d-1920-4b4b-8fca-e7659a1ef733", - "underlay_address": "fd00:1122:3344:105::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::c]:32345", - "dataset": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa" - } - } - }, - "root": "/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone" - }, - { - "zone": { - "id": "375296e5-0a23-466c-b605-4204080f8103", - "underlay_address": "fd00:1122:3344:105::4", - "zone_type": { - "type": "crucible_pantry", - "address": "[fd00:1122:3344:105::4]:17000" - } - }, - "root": "/pool/ext/4eb2e4eb-41d8-496c-9a5a-687d7e004aa4/crypt/zone" - }, - { - "zone": { - "id": "f9940969-b0e8-4e8c-86c7-4bc49cd15a5f", - "underlay_address": "fd00:1122:3344:105::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::7]:32345", - "dataset": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996" - } - } - }, - "root": "/pool/ext/17eff217-f0b1-4353-b133-0f68bbd5ceaa/crypt/zone" - }, - { - "zone": { - "id": "23dca27d-c79b-4930-a817-392e8aeaa4c1", - "underlay_address": "fd00:1122:3344:105::e", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::e]:32345", - "dataset": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5" - } - } - }, - "root": "/pool/ext/0ae29053-29a2-489e-a1e6-6aec0ecd05f8/crypt/zone" - }, - { - "zone": { - "id": "92d3e4e9-0768-4772-83c1-23cce52190e9", - "underlay_address": "fd00:1122:3344:105::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::6]:32345", - "dataset": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1" - } - } - }, - "root": "/pool/ext/b358fb1e-f52a-4a63-9aab-170225509b37/crypt/zone" - }, - { - "zone": { - "id": "b3e9fee2-24d2-44e7-8539-a6918e85cf2b", - "underlay_address": "fd00:1122:3344:105::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::d]:32345", - "dataset": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8" - } - } - }, - "root": "/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone" - }, - { - "zone": { - "id": "4c3ef132-ec83-4b1b-9574-7c7d3035f9e9", - "underlay_address": "fd00:1122:3344:105::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:105::3]:32221", - "dataset": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37" - } - } - }, - "root": "/pool/ext/d1cb6b7d-2b92-4b7d-8a4d-551987f0277e/crypt/zone" - }, - { - "zone": { - "id": "76b79b96-eaa2-4341-9aba-e77cfc92e0a9", - "underlay_address": "fd00:1122:3344:105::f", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:105::f]:123", - "ntp_servers": [ - "c3ec3d1a-3172-4d36-bfd3-f54a04d5ba55.host.control-plane.oxide.internal", - "6ea2684c-115e-48a6-8453-ab52d1cecd73.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/0ae29053-29a2-489e-a1e6-6aec0ecd05f8/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json deleted file mode 100644 index db6c55f556..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "0710ecea-dbc4-417f-a6f7-1b97c3045db1", - "underlay_address": "fd00:1122:3344:116::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::6]:32345", - "dataset": { - "pool_name": "oxp_d5313ef5-019c-4c47-bc5e-63794107a1bb" - } - } - }, - "root": "/pool/ext/904e93a9-d175-4a20-9006-8c1e847aecf7/crypt/zone" - }, - { - "zone": { - "id": "28b29d14-d55f-4b55-bbc1-f66e46ae3e70", - "underlay_address": "fd00:1122:3344:116::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::9]:32345", - "dataset": { - "pool_name": "oxp_60755ffe-e9ee-4619-a751-8b3ea6405e67" - } - } - }, - "root": "/pool/ext/d5313ef5-019c-4c47-bc5e-63794107a1bb/crypt/zone" - }, - { - "zone": { - "id": "6f8f9fd2-b139-4069-a7e2-8d40efd58f6c", - "underlay_address": "fd00:1122:3344:116::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::d]:32345", - "dataset": { - "pool_name": "oxp_ccd2cb0b-782f-4026-a160-6d1192f04ca3" - } - } - }, - "root": "/pool/ext/d5313ef5-019c-4c47-bc5e-63794107a1bb/crypt/zone" - }, - { - "zone": { - "id": "450308ad-bf4d-40ff-ba62-f3290f7fffaf", - "underlay_address": "fd00:1122:3344:116::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::4]:32345", - "dataset": { - "pool_name": "oxp_46b09442-65ba-4d59-9121-9803fe3b724b" - } - } - }, - "root": "/pool/ext/54d901cc-f75e-417d-8a9f-24363136d0ef/crypt/zone" - }, - { - "zone": { - "id": "9a22bbaa-eab4-4a32-8546-9882dc029483", - "underlay_address": "fd00:1122:3344:116::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::8]:32345", - "dataset": { - "pool_name": "oxp_93e3f350-75a0-4af0-bdac-baf9b423926f" - } - } - }, - "root": "/pool/ext/d5313ef5-019c-4c47-bc5e-63794107a1bb/crypt/zone" - }, - { - "zone": { - "id": "63a9dc49-0b5b-4483-95ed-553b545dc202", - "underlay_address": "fd00:1122:3344:116::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::a]:32345", - "dataset": { - "pool_name": "oxp_e3532845-76c0-42a9-903b-a07f7992e937" - } - } - }, - "root": "/pool/ext/60755ffe-e9ee-4619-a751-8b3ea6405e67/crypt/zone" - }, - { - "zone": { - "id": "1fef5b6c-78e4-4ad9-9973-9d8c78f1e232", - "underlay_address": "fd00:1122:3344:116::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::7]:32345", - "dataset": { - "pool_name": "oxp_54d901cc-f75e-417d-8a9f-24363136d0ef" - } - } - }, - "root": "/pool/ext/90d7b6f9-3e28-48b0-86ac-0486728075cf/crypt/zone" - }, - { - "zone": { - "id": "b2aab21a-cccd-4aa9-977f-a32090e6eaa7", - "underlay_address": "fd00:1122:3344:116::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::5]:32345", - "dataset": { - "pool_name": "oxp_90d7b6f9-3e28-48b0-86ac-0486728075cf" - } - } - }, - "root": "/pool/ext/46b09442-65ba-4d59-9121-9803fe3b724b/crypt/zone" - }, - { - "zone": { - "id": "fc1bbf28-24f3-4c1f-b367-2bc8231eb7d4", - "underlay_address": "fd00:1122:3344:116::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::b]:32345", - "dataset": { - "pool_name": "oxp_0a7bb0d3-408b-42b1-8846-76cf106a9580" - } - } - }, - "root": "/pool/ext/e3532845-76c0-42a9-903b-a07f7992e937/crypt/zone" - }, - { - "zone": { - "id": "bcb7617a-f76a-4912-8ccc-802d2a697e3c", - "underlay_address": "fd00:1122:3344:116::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:116::c]:32345", - "dataset": { - "pool_name": "oxp_904e93a9-d175-4a20-9006-8c1e847aecf7" - } - } - }, - "root": "/pool/ext/ccd2cb0b-782f-4026-a160-6d1192f04ca3/crypt/zone" - }, - { - "zone": { - "id": "371fba3a-658b-469b-b675-c90cc0d39254", - "underlay_address": "fd00:1122:3344:116::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:116::3]:32221", - "dataset": { - "pool_name": "oxp_46b09442-65ba-4d59-9121-9803fe3b724b" - } - } - }, - "root": "/pool/ext/46b09442-65ba-4d59-9121-9803fe3b724b/crypt/zone" - }, - { - "zone": { - "id": "5a4d89f5-49e0-4566-a99c-342d1bb26b1c", - "underlay_address": "fd00:1122:3344:116::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:116::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/60755ffe-e9ee-4619-a751-8b3ea6405e67/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json deleted file mode 100644 index ae3e3d8f4a..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "f401d06c-46fc-42f8-aa51-7515a51355ce", - "underlay_address": "fd00:1122:3344:11c::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::8]:32345", - "dataset": { - "pool_name": "oxp_8a88768a-2dd5-43b7-bd40-0db77be4d3a8" - } - } - }, - "root": "/pool/ext/19d23d27-6a33-4203-b8c1-4b0df4ac791f/crypt/zone" - }, - { - "zone": { - "id": "721c96ea-08d4-4c89-828f-600e7e344916", - "underlay_address": "fd00:1122:3344:11c::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::6]:32345", - "dataset": { - "pool_name": "oxp_15259003-fb04-4547-b4a9-b4511893c0fd" - } - } - }, - "root": "/pool/ext/d2a8ed82-22ef-46d8-ad40-e1cb2cecebee/crypt/zone" - }, - { - "zone": { - "id": "ca17bdf9-51c5-4e1e-b822-856609070ec6", - "underlay_address": "fd00:1122:3344:11c::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::5]:32345", - "dataset": { - "pool_name": "oxp_d2a8ed82-22ef-46d8-ad40-e1cb2cecebee" - } - } - }, - "root": "/pool/ext/15259003-fb04-4547-b4a9-b4511893c0fd/crypt/zone" - }, - { - "zone": { - "id": "5825447e-1b5b-4960-b202-e75853d3d250", - "underlay_address": "fd00:1122:3344:11c::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::9]:32345", - "dataset": { - "pool_name": "oxp_04e94454-cbd4-4cee-ad69-42372bcbabd5" - } - } - }, - "root": "/pool/ext/542e0fb3-552c-4d3b-b853-da1f13b581a0/crypt/zone" - }, - { - "zone": { - "id": "b937d3f0-1352-47a2-b9d1-a9ccf9c82b16", - "underlay_address": "fd00:1122:3344:11c::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::c]:32345", - "dataset": { - "pool_name": "oxp_542e0fb3-552c-4d3b-b853-da1f13b581a0" - } - } - }, - "root": "/pool/ext/eedd1d58-4892-456f-aaf7-9d650c7921ca/crypt/zone" - }, - { - "zone": { - "id": "d63a677b-8dac-44ee-89a2-cc4cb151254d", - "underlay_address": "fd00:1122:3344:11c::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::3]:32345", - "dataset": { - "pool_name": "oxp_45b5f1ee-7b66-4d74-8364-54fa0c73775f" - } - } - }, - "root": "/pool/ext/8a88768a-2dd5-43b7-bd40-0db77be4d3a8/crypt/zone" - }, - { - "zone": { - "id": "abcb92ea-9f17-4cd8-897b-9d0d1ef7903a", - "underlay_address": "fd00:1122:3344:11c::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::4]:32345", - "dataset": { - "pool_name": "oxp_341d49db-c06a-416d-90e1-b0a3426ed02e" - } - } - }, - "root": "/pool/ext/eedd1d58-4892-456f-aaf7-9d650c7921ca/crypt/zone" - }, - { - "zone": { - "id": "000ac89d-db07-47ae-83cf-d9cafef013de", - "underlay_address": "fd00:1122:3344:11c::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::b]:32345", - "dataset": { - "pool_name": "oxp_eedd1d58-4892-456f-aaf7-9d650c7921ca" - } - } - }, - "root": "/pool/ext/04e94454-cbd4-4cee-ad69-42372bcbabd5/crypt/zone" - }, - { - "zone": { - "id": "29e1e2e4-695e-4c05-8f0c-c16a0a61d390", - "underlay_address": "fd00:1122:3344:11c::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::7]:32345", - "dataset": { - "pool_name": "oxp_19d23d27-6a33-4203-b8c1-4b0df4ac791f" - } - } - }, - "root": "/pool/ext/d2a8ed82-22ef-46d8-ad40-e1cb2cecebee/crypt/zone" - }, - { - "zone": { - "id": "9fa7d7be-a6de-4d36-b56b-d1cc5ca7c82c", - "underlay_address": "fd00:1122:3344:11c::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11c::a]:32345", - "dataset": { - "pool_name": "oxp_0fd7a0b1-ed4b-4dc6-8c44-a49c9628c7e1" - } - } - }, - "root": "/pool/ext/d2a8ed82-22ef-46d8-ad40-e1cb2cecebee/crypt/zone" - }, - { - "zone": { - "id": "249db5f1-45e2-4a5c-a91f-cc51dbd87040", - "underlay_address": "fd00:1122:3344:11c::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:11c::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/542e0fb3-552c-4d3b-b853-da1f13b581a0/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json deleted file mode 100644 index c94417ffb8..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json +++ /dev/null @@ -1,201 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 5, - "zones": [ - { - "zone": { - "id": "7ddd0738-59df-4b67-a41e-7f0de9827187", - "underlay_address": "fd00:1122:3344:11e::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::4]:32345", - "dataset": { - "pool_name": "oxp_09af632a-6b1b-4a18-8c91-d392da38b02f" - } - } - }, - "root": "/pool/ext/09af632a-6b1b-4a18-8c91-d392da38b02f/crypt/zone" - }, - { - "zone": { - "id": "9706189f-713a-4394-b5dc-45dcf67dc46e", - "underlay_address": "fd00:1122:3344:11e::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::9]:32345", - "dataset": { - "pool_name": "oxp_4e1837c8-91ab-4d1d-abfd-f5144d88535e" - } - } - }, - "root": "/pool/ext/2f0d47cb-28d1-4350-8656-60c6121f773b/crypt/zone" - }, - { - "zone": { - "id": "7bdd841b-5e34-4c19-9066-b12578651446", - "underlay_address": "fd00:1122:3344:11e::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::a]:32345", - "dataset": { - "pool_name": "oxp_78d1e7f7-8d11-4fed-8b1e-be58908aea2f" - } - } - }, - "root": "/pool/ext/62c23f4b-8e7b-4cd8-9055-19c1d8bd5ac8/crypt/zone" - }, - { - "zone": { - "id": "74c0f60b-de5f-4456-a85f-f992a6e10424", - "underlay_address": "fd00:1122:3344:11e::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::b]:32345", - "dataset": { - "pool_name": "oxp_3b81d709-bf10-4dd7-a2c0-759d8acc2da0" - } - } - }, - "root": "/pool/ext/09af632a-6b1b-4a18-8c91-d392da38b02f/crypt/zone" - }, - { - "zone": { - "id": "da81ce6f-bd38-440e-b966-8a743092fa21", - "underlay_address": "fd00:1122:3344:11e::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::6]:32345", - "dataset": { - "pool_name": "oxp_62c23f4b-8e7b-4cd8-9055-19c1d8bd5ac8" - } - } - }, - "root": "/pool/ext/215dd02b-0de6-488a-9e65-5e588cd079fb/crypt/zone" - }, - { - "zone": { - "id": "febbca37-5279-400f-a2e9-6b5271b2d2fc", - "underlay_address": "fd00:1122:3344:11e::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::7]:32345", - "dataset": { - "pool_name": "oxp_fb33e773-fb93-41a0-8078-b653b9078dda" - } - } - }, - "root": "/pool/ext/2f0d47cb-28d1-4350-8656-60c6121f773b/crypt/zone" - }, - { - "zone": { - "id": "5100e222-5ea4-4e67-9040-679137e666c8", - "underlay_address": "fd00:1122:3344:11e::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::5]:32345", - "dataset": { - "pool_name": "oxp_23767587-2253-431b-8944-18b9bfefcb3d" - } - } - }, - "root": "/pool/ext/3b81d709-bf10-4dd7-a2c0-759d8acc2da0/crypt/zone" - }, - { - "zone": { - "id": "c7ec3bc8-08ca-4901-a45e-0d68db72c6a7", - "underlay_address": "fd00:1122:3344:11e::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::3]:32345", - "dataset": { - "pool_name": "oxp_2f0d47cb-28d1-4350-8656-60c6121f773b" - } - } - }, - "root": "/pool/ext/215dd02b-0de6-488a-9e65-5e588cd079fb/crypt/zone" - }, - { - "zone": { - "id": "1fc80dd3-0fd9-4403-96bd-5bbf9eb0f15a", - "underlay_address": "fd00:1122:3344:11e::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::c]:32345", - "dataset": { - "pool_name": "oxp_2c932d54-41fb-4ffe-a57f-0479b9e5841e" - } - } - }, - "root": "/pool/ext/3b81d709-bf10-4dd7-a2c0-759d8acc2da0/crypt/zone" - }, - { - "zone": { - "id": "4eacc68d-5699-440a-ab33-c75f259e4cc3", - "underlay_address": "fd00:1122:3344:11e::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11e::8]:32345", - "dataset": { - "pool_name": "oxp_215dd02b-0de6-488a-9e65-5e588cd079fb" - } - } - }, - "root": "/pool/ext/4e1837c8-91ab-4d1d-abfd-f5144d88535e/crypt/zone" - }, - { - "zone": { - "id": "cb901d3e-8811-4c4c-a274-a44130501ecf", - "underlay_address": "fd00:1122:3344:11e::d", - "zone_type": { - "type": "boundary_ntp", - "address": "[fd00:1122:3344:11e::d]:123", - "ntp_servers": [ - "time.cloudflare.com" - ], - "dns_servers": [ - "1.1.1.1", - "8.8.8.8" - ], - "domain": null, - "nic": { - "id": "bcf9d9eb-b4ba-4fd5-91e0-55a3414ae049", - "kind": { - "type": "service", - "id": "cb901d3e-8811-4c4c-a274-a44130501ecf" - }, - "name": "ntp-cb901d3e-8811-4c4c-a274-a44130501ecf", - "ip": "172.30.3.6", - "mac": "A8:40:25:FF:D5:2F", - "subnet": "172.30.3.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "snat_cfg": { - "ip": "45.154.216.39", - "first_port": 16384, - "last_port": 32767 - } - } - }, - "root": "/pool/ext/23767587-2253-431b-8944-18b9bfefcb3d/crypt/zone" - }, - { - "zone": { - "id": "be4aada9-d160-401d-a630-a0764c039702", - "underlay_address": "fd00:1122:3344:2::1", - "zone_type": { - "type": "internal_dns", - "dataset": { - "pool_name": "oxp_2f0d47cb-28d1-4350-8656-60c6121f773b" - }, - "http_address": "[fd00:1122:3344:2::1]:5353", - "dns_address": "[fd00:1122:3344:2::1]:53", - "gz_address": "fd00:1122:3344:2::2", - "gz_address_index": 1 - } - }, - "root": "/pool/ext/78d1e7f7-8d11-4fed-8b1e-be58908aea2f/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json deleted file mode 100644 index bfc30cf160..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "d8f1b9d2-fa2e-4f03-bbea-2039448d7792", - "underlay_address": "fd00:1122:3344:112::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::5]:32345", - "dataset": { - "pool_name": "oxp_7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1" - } - } - }, - "root": "/pool/ext/78d9f0ae-8e7f-450e-abc2-76b983efa5cd/crypt/zone" - }, - { - "zone": { - "id": "2074a935-c0b3-4c4f-aae5-a29adae3e1ac", - "underlay_address": "fd00:1122:3344:112::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::8]:32345", - "dataset": { - "pool_name": "oxp_ac663368-45fb-447c-811e-561c68e37bdd" - } - } - }, - "root": "/pool/ext/ac663368-45fb-447c-811e-561c68e37bdd/crypt/zone" - }, - { - "zone": { - "id": "2885d3c7-ad7d-445c-8630-dc6c81f8caa0", - "underlay_address": "fd00:1122:3344:112::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::a]:32345", - "dataset": { - "pool_name": "oxp_8e82e8da-e1c5-4867-bc1c-b5441f9c1010" - } - } - }, - "root": "/pool/ext/8e82e8da-e1c5-4867-bc1c-b5441f9c1010/crypt/zone" - }, - { - "zone": { - "id": "1eca241b-6868-4c59-876b-58356654f3b5", - "underlay_address": "fd00:1122:3344:112::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::c]:32345", - "dataset": { - "pool_name": "oxp_fde16c69-aa47-4a15-bb3f-3a5861ae45bd" - } - } - }, - "root": "/pool/ext/7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1/crypt/zone" - }, - { - "zone": { - "id": "cc656f2e-8542-4986-8524-2f55984939c1", - "underlay_address": "fd00:1122:3344:112::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::d]:32345", - "dataset": { - "pool_name": "oxp_21e6d0f9-887e-4d6f-9a00-4cd61139eea6" - } - } - }, - "root": "/pool/ext/21e6d0f9-887e-4d6f-9a00-4cd61139eea6/crypt/zone" - }, - { - "zone": { - "id": "dfb1ebce-a4c7-4b50-9435-9a79b884c1af", - "underlay_address": "fd00:1122:3344:112::3", - "zone_type": { - "type": "clickhouse", - "address": "[fd00:1122:3344:112::3]:8123", - "dataset": { - "pool_name": "oxp_4f045315-de51-46ed-a011-16496615278f" - } - } - }, - "root": "/pool/ext/7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1/crypt/zone" - }, - { - "zone": { - "id": "a95d90ed-b2b1-4a5d-8d0d-4195b34bc764", - "underlay_address": "fd00:1122:3344:112::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::6]:32345", - "dataset": { - "pool_name": "oxp_d2c77c69-14d7-442e-8b47-a0d7af5a0e7e" - } - } - }, - "root": "/pool/ext/fad56ff1-ad9f-4215-b584-522eab18cf7b/crypt/zone" - }, - { - "zone": { - "id": "1d3ebc90-d5a5-4cb0-ae90-50bb2163ae13", - "underlay_address": "fd00:1122:3344:112::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::b]:32345", - "dataset": { - "pool_name": "oxp_fad56ff1-ad9f-4215-b584-522eab18cf7b" - } - } - }, - "root": "/pool/ext/7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1/crypt/zone" - }, - { - "zone": { - "id": "7af9f38b-0c7a-402e-8db3-7c7fb50b4665", - "underlay_address": "fd00:1122:3344:112::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::9]:32345", - "dataset": { - "pool_name": "oxp_d0693580-5c5a-449f-803f-ce7188ebc580" - } - } - }, - "root": "/pool/ext/d2c77c69-14d7-442e-8b47-a0d7af5a0e7e/crypt/zone" - }, - { - "zone": { - "id": "94d9bb0a-ecd2-4501-b960-60982f55ad12", - "underlay_address": "fd00:1122:3344:112::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::7]:32345", - "dataset": { - "pool_name": "oxp_78d9f0ae-8e7f-450e-abc2-76b983efa5cd" - } - } - }, - "root": "/pool/ext/ac663368-45fb-447c-811e-561c68e37bdd/crypt/zone" - }, - { - "zone": { - "id": "277c1105-576e-4ec1-8e2c-cbae2f5ac9f6", - "underlay_address": "fd00:1122:3344:112::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:112::4]:32345", - "dataset": { - "pool_name": "oxp_4f045315-de51-46ed-a011-16496615278f" - } - } - }, - "root": "/pool/ext/7d7ed1b7-7b77-4f0a-abb1-27de7cb584d1/crypt/zone" - }, - { - "zone": { - "id": "555c3407-a76c-4ea4-a17a-a670d85a59b0", - "underlay_address": "fd00:1122:3344:112::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:112::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/8e82e8da-e1c5-4867-bc1c-b5441f9c1010/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json deleted file mode 100644 index 66c04be148..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json +++ /dev/null @@ -1,201 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 5, - "zones": [ - { - "zone": { - "id": "fbcf51c9-a732-4a03-8c19-cfb5b819cb7a", - "underlay_address": "fd00:1122:3344:104::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::5]:32345", - "dataset": { - "pool_name": "oxp_382a2961-cd27-4a9c-901d-468a45ff5708" - } - } - }, - "root": "/pool/ext/e99994ae-61ca-4742-a02c-eb0a8a5b69ff/crypt/zone" - }, - { - "zone": { - "id": "7f8a5026-1f1d-4ab3-8c04-077bfda2f815", - "underlay_address": "fd00:1122:3344:104::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::4]:32345", - "dataset": { - "pool_name": "oxp_9c99b9b6-8018-455e-a58a-c048ddd3e11b" - } - } - }, - "root": "/pool/ext/22c79e54-37ef-4ad2-a6cb-a7ee3e4f7167/crypt/zone" - }, - { - "zone": { - "id": "6d45d856-0e49-4eb7-ad76-989a9ae636a2", - "underlay_address": "fd00:1122:3344:104::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::3]:32345", - "dataset": { - "pool_name": "oxp_b74a84fa-b4c8-4c5f-92f4-f4e62a0a311d" - } - } - }, - "root": "/pool/ext/9c99b9b6-8018-455e-a58a-c048ddd3e11b/crypt/zone" - }, - { - "zone": { - "id": "c8dc7fff-72c8-49eb-a552-d605f8655134", - "underlay_address": "fd00:1122:3344:104::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::6]:32345", - "dataset": { - "pool_name": "oxp_22c79e54-37ef-4ad2-a6cb-a7ee3e4f7167" - } - } - }, - "root": "/pool/ext/22c79e54-37ef-4ad2-a6cb-a7ee3e4f7167/crypt/zone" - }, - { - "zone": { - "id": "128a90f5-8889-4665-8343-2c7098f2922c", - "underlay_address": "fd00:1122:3344:104::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::7]:32345", - "dataset": { - "pool_name": "oxp_8b3d0b51-c6a5-4d2c-827a-0d0d1471136d" - } - } - }, - "root": "/pool/ext/29cd042b-e772-4d26-ac85-ef16009950bd/crypt/zone" - }, - { - "zone": { - "id": "a72f1878-3b03-4267-9024-5df5ebae69de", - "underlay_address": "fd00:1122:3344:104::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::a]:32345", - "dataset": { - "pool_name": "oxp_e99994ae-61ca-4742-a02c-eb0a8a5b69ff" - } - } - }, - "root": "/pool/ext/8b3d0b51-c6a5-4d2c-827a-0d0d1471136d/crypt/zone" - }, - { - "zone": { - "id": "6a9165a2-9b66-485a-aaf0-70d89d60bb6c", - "underlay_address": "fd00:1122:3344:104::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::b]:32345", - "dataset": { - "pool_name": "oxp_6a02f05f-e400-4c80-8df8-89aaecb6c12b" - } - } - }, - "root": "/pool/ext/9c99b9b6-8018-455e-a58a-c048ddd3e11b/crypt/zone" - }, - { - "zone": { - "id": "9677c4ed-96bc-4dcb-ae74-f7a3e9d2b5e2", - "underlay_address": "fd00:1122:3344:104::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::c]:32345", - "dataset": { - "pool_name": "oxp_7c30978f-ee87-4e53-8fdf-3455e5e851b7" - } - } - }, - "root": "/pool/ext/29cd042b-e772-4d26-ac85-ef16009950bd/crypt/zone" - }, - { - "zone": { - "id": "179039e7-3ffd-4b76-9379-bef41d42a5ff", - "underlay_address": "fd00:1122:3344:104::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::8]:32345", - "dataset": { - "pool_name": "oxp_4db7e002-e112-4bfc-a41e-8ae26991b01e" - } - } - }, - "root": "/pool/ext/8b3d0b51-c6a5-4d2c-827a-0d0d1471136d/crypt/zone" - }, - { - "zone": { - "id": "6067e31e-b6a3-4114-9e49-0296adc8e7af", - "underlay_address": "fd00:1122:3344:104::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:104::9]:32345", - "dataset": { - "pool_name": "oxp_29cd042b-e772-4d26-ac85-ef16009950bd" - } - } - }, - "root": "/pool/ext/9c99b9b6-8018-455e-a58a-c048ddd3e11b/crypt/zone" - }, - { - "zone": { - "id": "440dd615-e11f-4a5d-aeb4-dcf88bb314de", - "underlay_address": "fd00:1122:3344:104::d", - "zone_type": { - "type": "boundary_ntp", - "address": "[fd00:1122:3344:104::d]:123", - "ntp_servers": [ - "time.cloudflare.com" - ], - "dns_servers": [ - "1.1.1.1", - "8.8.8.8" - ], - "domain": null, - "nic": { - "id": "0b52fe1b-f4cc-43b1-9ac3-4ebb4ab60133", - "kind": { - "type": "service", - "id": "440dd615-e11f-4a5d-aeb4-dcf88bb314de" - }, - "name": "ntp-440dd615-e11f-4a5d-aeb4-dcf88bb314de", - "ip": "172.30.3.5", - "mac": "A8:40:25:FF:85:1E", - "subnet": "172.30.3.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "snat_cfg": { - "ip": "45.154.216.38", - "first_port": 0, - "last_port": 16383 - } - } - }, - "root": "/pool/ext/382a2961-cd27-4a9c-901d-468a45ff5708/crypt/zone" - }, - { - "zone": { - "id": "06e2de03-bd92-404c-a8ea-a13185539d24", - "underlay_address": "fd00:1122:3344:1::1", - "zone_type": { - "type": "internal_dns", - "dataset": { - "pool_name": "oxp_b74a84fa-b4c8-4c5f-92f4-f4e62a0a311d" - }, - "http_address": "[fd00:1122:3344:1::1]:5353", - "dns_address": "[fd00:1122:3344:1::1]:53", - "gz_address": "fd00:1122:3344:1::2", - "gz_address_index": 0 - } - }, - "root": "/pool/ext/e99994ae-61ca-4742-a02c-eb0a8a5b69ff/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json deleted file mode 100644 index e8d061dbfd..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json +++ /dev/null @@ -1,198 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "ac35afab-a312-43c3-a42d-04b8e99fcbde", - "underlay_address": "fd00:1122:3344:111::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::4]:32345", - "dataset": { - "pool_name": "oxp_6601065c-c172-4118-81b4-16adde7e9401" - } - } - }, - "root": "/pool/ext/24d7e250-9fc6-459e-8155-30f8e8ccb28c/crypt/zone" - }, - { - "zone": { - "id": "6cd94da2-35b9-4683-a931-29ad4a5ed0ef", - "underlay_address": "fd00:1122:3344:111::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::c]:32345", - "dataset": { - "pool_name": "oxp_58276eba-a53c-4ef3-b374-4cdcde4d6e12" - } - } - }, - "root": "/pool/ext/24d7e250-9fc6-459e-8155-30f8e8ccb28c/crypt/zone" - }, - { - "zone": { - "id": "41f07d39-fcc0-4796-8b7c-7cfcd9135f78", - "underlay_address": "fd00:1122:3344:111::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::9]:32345", - "dataset": { - "pool_name": "oxp_4b90abdc-3348-4158-bedc-5bcd56e281d8" - } - } - }, - "root": "/pool/ext/8e955f54-fbef-4021-9eec-457825468813/crypt/zone" - }, - { - "zone": { - "id": "44c35566-dd64-4e4a-896e-c50aaa3df14f", - "underlay_address": "fd00:1122:3344:111::3", - "zone_type": { - "type": "nexus", - "internal_address": "[fd00:1122:3344:111::3]:12221", - "external_ip": "45.154.216.37", - "nic": { - "id": "6f824d20-6ce0-4e8b-9ce3-b12dd2b59913", - "kind": { - "type": "service", - "id": "44c35566-dd64-4e4a-896e-c50aaa3df14f" - }, - "name": "nexus-44c35566-dd64-4e4a-896e-c50aaa3df14f", - "ip": "172.30.2.7", - "mac": "A8:40:25:FF:E8:5F", - "subnet": "172.30.2.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "external_tls": true, - "external_dns_servers": [ - "1.1.1.1", - "8.8.8.8" - ] - } - }, - "root": "/pool/ext/435d7a1b-2865-4d49-903f-a68f464ade4d/crypt/zone" - }, - { - "zone": { - "id": "e5020d24-8652-456b-bf92-cd7d255a34c5", - "underlay_address": "fd00:1122:3344:111::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::6]:32345", - "dataset": { - "pool_name": "oxp_f6925045-363d-4e18-9bde-ee2987b33d21" - } - } - }, - "root": "/pool/ext/6601065c-c172-4118-81b4-16adde7e9401/crypt/zone" - }, - { - "zone": { - "id": "8f25f258-afd7-4351-83e4-24220ec0c251", - "underlay_address": "fd00:1122:3344:111::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::8]:32345", - "dataset": { - "pool_name": "oxp_8e955f54-fbef-4021-9eec-457825468813" - } - } - }, - "root": "/pool/ext/6601065c-c172-4118-81b4-16adde7e9401/crypt/zone" - }, - { - "zone": { - "id": "26aa50ec-d70a-47ea-85fc-e55c62a2e0c6", - "underlay_address": "fd00:1122:3344:111::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::5]:32345", - "dataset": { - "pool_name": "oxp_24d7e250-9fc6-459e-8155-30f8e8ccb28c" - } - } - }, - "root": "/pool/ext/435d7a1b-2865-4d49-903f-a68f464ade4d/crypt/zone" - }, - { - "zone": { - "id": "68dc212f-a96a-420f-8334-b11ee5d7cb95", - "underlay_address": "fd00:1122:3344:111::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::7]:32345", - "dataset": { - "pool_name": "oxp_4353b00b-937e-4d07-aea6-014c57b6f12c" - } - } - }, - "root": "/pool/ext/24d7e250-9fc6-459e-8155-30f8e8ccb28c/crypt/zone" - }, - { - "zone": { - "id": "475140fa-a5dc-4ec1-876d-751c48adfc37", - "underlay_address": "fd00:1122:3344:111::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::a]:32345", - "dataset": { - "pool_name": "oxp_ee55b053-6874-4e20-86b5-2e105e64c068" - } - } - }, - "root": "/pool/ext/ee55b053-6874-4e20-86b5-2e105e64c068/crypt/zone" - }, - { - "zone": { - "id": "09d5a8c9-00db-4914-a2c6-7ae3d2da4558", - "underlay_address": "fd00:1122:3344:111::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::d]:32345", - "dataset": { - "pool_name": "oxp_9ab5aba5-47dc-4bc4-8f6d-7cbe0f98a9a2" - } - } - }, - "root": "/pool/ext/8e955f54-fbef-4021-9eec-457825468813/crypt/zone" - }, - { - "zone": { - "id": "014f6a39-ad64-4f0a-9fef-01ca0d184cbf", - "underlay_address": "fd00:1122:3344:111::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:111::b]:32345", - "dataset": { - "pool_name": "oxp_435d7a1b-2865-4d49-903f-a68f464ade4d" - } - } - }, - "root": "/pool/ext/f6925045-363d-4e18-9bde-ee2987b33d21/crypt/zone" - }, - { - "zone": { - "id": "aceaf348-ba07-4965-a543-63a800826fe8", - "underlay_address": "fd00:1122:3344:111::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:111::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/8e955f54-fbef-4021-9eec-457825468813/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json deleted file mode 100644 index e3b3dba86a..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json +++ /dev/null @@ -1,196 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "09a9ecee-1e7c-4819-b27a-73bb61099ce7", - "underlay_address": "fd00:1122:3344:114::3", - "zone_type": { - "type": "external_dns", - "dataset": { - "pool_name": "oxp_b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e" - }, - "http_address": "[fd00:1122:3344:114::3]:5353", - "dns_address": "45.154.216.33:53", - "nic": { - "id": "400ca77b-7fee-47d5-8f17-1f4b9c729f27", - "kind": { - "type": "service", - "id": "09a9ecee-1e7c-4819-b27a-73bb61099ce7" - }, - "name": "external-dns-09a9ecee-1e7c-4819-b27a-73bb61099ce7", - "ip": "172.30.1.5", - "mac": "A8:40:25:FF:B7:C7", - "subnet": "172.30.1.0/24", - "vni": 100, - "primary": true, - "slot": 0 - } - } - }, - "root": "/pool/ext/9e878b1e-bf92-4155-8162-640851c2f5d5/crypt/zone" - }, - { - "zone": { - "id": "1792e003-55f7-49b8-906c-4160db91bc23", - "underlay_address": "fd00:1122:3344:114::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::5]:32345", - "dataset": { - "pool_name": "oxp_7f3a760f-a4c0-456f-8a22-2d06ecac1022" - } - } - }, - "root": "/pool/ext/76f09ad5-c96c-4748-bbe4-71afaea7bc5e/crypt/zone" - }, - { - "zone": { - "id": "73bc7c0e-1034-449f-8920-4a1f418653ff", - "underlay_address": "fd00:1122:3344:114::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::8]:32345", - "dataset": { - "pool_name": "oxp_e87037be-1cdf-4c6e-a8a3-c27b830eaef9" - } - } - }, - "root": "/pool/ext/b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e/crypt/zone" - }, - { - "zone": { - "id": "06dc6619-6251-4543-9a10-da1698af49d5", - "underlay_address": "fd00:1122:3344:114::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::9]:32345", - "dataset": { - "pool_name": "oxp_ee34c530-ce70-4f1a-8c97-d0ebb77ccfc8" - } - } - }, - "root": "/pool/ext/9e878b1e-bf92-4155-8162-640851c2f5d5/crypt/zone" - }, - { - "zone": { - "id": "0d796c52-37ca-490d-b42f-dcc22fe5fd6b", - "underlay_address": "fd00:1122:3344:114::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::c]:32345", - "dataset": { - "pool_name": "oxp_9ec2b893-d486-4b24-a077-1a297f9eb15f" - } - } - }, - "root": "/pool/ext/9e72c0e2-4895-4791-b606-2f18e432fb69/crypt/zone" - }, - { - "zone": { - "id": "91d0011f-de44-4823-bc26-a447affa39bc", - "underlay_address": "fd00:1122:3344:114::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::a]:32345", - "dataset": { - "pool_name": "oxp_85e81a14-031d-4a63-a91f-981c64e91f60" - } - } - }, - "root": "/pool/ext/b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e/crypt/zone" - }, - { - "zone": { - "id": "0c44a2f1-559a-459c-9931-e0e7964d41c6", - "underlay_address": "fd00:1122:3344:114::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::b]:32345", - "dataset": { - "pool_name": "oxp_76f09ad5-c96c-4748-bbe4-71afaea7bc5e" - } - } - }, - "root": "/pool/ext/e87037be-1cdf-4c6e-a8a3-c27b830eaef9/crypt/zone" - }, - { - "zone": { - "id": "ea363819-96f6-4fb6-a203-f18414f1c60e", - "underlay_address": "fd00:1122:3344:114::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::4]:32345", - "dataset": { - "pool_name": "oxp_b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e" - } - } - }, - "root": "/pool/ext/b7fbb6db-aa4a-4a6d-8206-b7bdc000d56e/crypt/zone" - }, - { - "zone": { - "id": "21592c39-da6b-4527-842e-edeeceffafa1", - "underlay_address": "fd00:1122:3344:114::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::6]:32345", - "dataset": { - "pool_name": "oxp_9e72c0e2-4895-4791-b606-2f18e432fb69" - } - } - }, - "root": "/pool/ext/7aff8429-b65d-4a53-a796-7221ac7581a9/crypt/zone" - }, - { - "zone": { - "id": "f33b1263-f1b2-43a6-a8aa-5f8570dd4e72", - "underlay_address": "fd00:1122:3344:114::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::7]:32345", - "dataset": { - "pool_name": "oxp_9e878b1e-bf92-4155-8162-640851c2f5d5" - } - } - }, - "root": "/pool/ext/7f3a760f-a4c0-456f-8a22-2d06ecac1022/crypt/zone" - }, - { - "zone": { - "id": "6f42b469-5a36-4048-a152-e884f7e8a206", - "underlay_address": "fd00:1122:3344:114::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:114::d]:32345", - "dataset": { - "pool_name": "oxp_7aff8429-b65d-4a53-a796-7221ac7581a9" - } - } - }, - "root": "/pool/ext/9e72c0e2-4895-4791-b606-2f18e432fb69/crypt/zone" - }, - { - "zone": { - "id": "ad77d594-8f78-4d33-a5e4-59887060178e", - "underlay_address": "fd00:1122:3344:114::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:114::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/85e81a14-031d-4a63-a91f-981c64e91f60/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json deleted file mode 100644 index 3cd727e1bc..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "dcb9a4ae-2c89-4a74-905b-b7936ff49c19", - "underlay_address": "fd00:1122:3344:11f::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::9]:32345", - "dataset": { - "pool_name": "oxp_af509039-d27f-4095-bc9d-cecbc5c606db" - } - } - }, - "root": "/pool/ext/44ee0fb4-6034-44e8-b3de-b3a44457ffca/crypt/zone" - }, - { - "zone": { - "id": "dbd46f71-ec39-4b72-a77d-9d281ccb37e0", - "underlay_address": "fd00:1122:3344:11f::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::b]:32345", - "dataset": { - "pool_name": "oxp_44ee0fb4-6034-44e8-b3de-b3a44457ffca" - } - } - }, - "root": "/pool/ext/5e32c0a3-1210-402b-91fb-256946eeac2b/crypt/zone" - }, - { - "zone": { - "id": "a1f30569-a5c6-4a6d-922e-241966aea142", - "underlay_address": "fd00:1122:3344:11f::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::6]:32345", - "dataset": { - "pool_name": "oxp_d2133e8b-51cc-455e-89d0-5454fd4fe109" - } - } - }, - "root": "/pool/ext/3f57835b-1469-499a-8757-7cc56acc5d49/crypt/zone" - }, - { - "zone": { - "id": "a33e25ae-4e41-40f4-843d-3d12f62d8cb6", - "underlay_address": "fd00:1122:3344:11f::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::8]:32345", - "dataset": { - "pool_name": "oxp_c8e4a7f4-1ae6-4683-8397-ea53475a53e8" - } - } - }, - "root": "/pool/ext/5e32c0a3-1210-402b-91fb-256946eeac2b/crypt/zone" - }, - { - "zone": { - "id": "65ed75c2-2d80-4de5-a6f6-adfa6516c7cf", - "underlay_address": "fd00:1122:3344:11f::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::c]:32345", - "dataset": { - "pool_name": "oxp_3f57835b-1469-499a-8757-7cc56acc5d49" - } - } - }, - "root": "/pool/ext/cd8cd75c-632b-4527-889a-7ca0c080fe2c/crypt/zone" - }, - { - "zone": { - "id": "bc6ccf18-6b9b-4687-8b70-c7917d972ae0", - "underlay_address": "fd00:1122:3344:11f::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::a]:32345", - "dataset": { - "pool_name": "oxp_cd8cd75c-632b-4527-889a-7ca0c080fe2c" - } - } - }, - "root": "/pool/ext/5e32c0a3-1210-402b-91fb-256946eeac2b/crypt/zone" - }, - { - "zone": { - "id": "06233bfe-a857-4819-aefe-212af9eeb90f", - "underlay_address": "fd00:1122:3344:11f::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::5]:32345", - "dataset": { - "pool_name": "oxp_c8a1aaf1-d27c-45fd-9f8d-80ac6bf6865d" - } - } - }, - "root": "/pool/ext/af509039-d27f-4095-bc9d-cecbc5c606db/crypt/zone" - }, - { - "zone": { - "id": "0bbfef71-9eae-43b6-b5e7-0060ce9269dd", - "underlay_address": "fd00:1122:3344:11f::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::4]:32345", - "dataset": { - "pool_name": "oxp_5e32c0a3-1210-402b-91fb-256946eeac2b" - } - } - }, - "root": "/pool/ext/af509039-d27f-4095-bc9d-cecbc5c606db/crypt/zone" - }, - { - "zone": { - "id": "550e10ee-24d1-444f-80be-2744dd321e0f", - "underlay_address": "fd00:1122:3344:11f::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11f::7]:32345", - "dataset": { - "pool_name": "oxp_f437ce0e-eb45-4be8-b1fe-33ed2656eb01" - } - } - }, - "root": "/pool/ext/44ee0fb4-6034-44e8-b3de-b3a44457ffca/crypt/zone" - }, - { - "zone": { - "id": "86d768f3-ece2-4956-983f-999bdb23a983", - "underlay_address": "fd00:1122:3344:11f::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:11f::3]:32221", - "dataset": { - "pool_name": "oxp_5e32c0a3-1210-402b-91fb-256946eeac2b" - } - } - }, - "root": "/pool/ext/c8a1aaf1-d27c-45fd-9f8d-80ac6bf6865d/crypt/zone" - }, - { - "zone": { - "id": "2f358812-f72c-4838-a5ea-7d78d0954be0", - "underlay_address": "fd00:1122:3344:11f::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:11f::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/f437ce0e-eb45-4be8-b1fe-33ed2656eb01/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json deleted file mode 100644 index 09981ecacc..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "525a19a2-d4ac-418d-bdcf-2ce26e7abe70", - "underlay_address": "fd00:1122:3344:107::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::a]:32345", - "dataset": { - "pool_name": "oxp_cb774d2f-ff86-4fd7-866b-17a6b10e61f0" - } - } - }, - "root": "/pool/ext/e17b68b5-f50c-4fc3-b55a-80d284c6c32d/crypt/zone" - }, - { - "zone": { - "id": "7af188e1-6175-4769-9e4f-2ca7a98b76f6", - "underlay_address": "fd00:1122:3344:107::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::4]:32345", - "dataset": { - "pool_name": "oxp_0cbbcf22-770d-4e75-9148-e6109b129093" - } - } - }, - "root": "/pool/ext/b998e8df-ea69-4bdd-84cb-b7f17075b060/crypt/zone" - }, - { - "zone": { - "id": "2544540f-6ffc-46c0-84bf-f42a110c02d7", - "underlay_address": "fd00:1122:3344:107::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::6]:32345", - "dataset": { - "pool_name": "oxp_e17b68b5-f50c-4fc3-b55a-80d284c6c32d" - } - } - }, - "root": "/pool/ext/521fa477-4d83-49a8-a5cf-c267b7f0c409/crypt/zone" - }, - { - "zone": { - "id": "cfc20f72-cac2-4681-a6d8-e5a0accafbb7", - "underlay_address": "fd00:1122:3344:107::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::7]:32345", - "dataset": { - "pool_name": "oxp_b998e8df-ea69-4bdd-84cb-b7f17075b060" - } - } - }, - "root": "/pool/ext/0cbbcf22-770d-4e75-9148-e6109b129093/crypt/zone" - }, - { - "zone": { - "id": "e24be791-5773-425e-a3df-e35ca81570c7", - "underlay_address": "fd00:1122:3344:107::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::9]:32345", - "dataset": { - "pool_name": "oxp_7849c221-dc7f-43ac-ac47-bc51864e083b" - } - } - }, - "root": "/pool/ext/7849c221-dc7f-43ac-ac47-bc51864e083b/crypt/zone" - }, - { - "zone": { - "id": "170856ee-21cf-4780-8903-175d558bc7cc", - "underlay_address": "fd00:1122:3344:107::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::3]:32345", - "dataset": { - "pool_name": "oxp_618e21e5-77d4-40ba-9f8e-7960e9ad92e2" - } - } - }, - "root": "/pool/ext/aa7a37fb-2f03-4d5c-916b-db3a4fc269ac/crypt/zone" - }, - { - "zone": { - "id": "604278ff-525a-4d41-82ff-07aef3174d38", - "underlay_address": "fd00:1122:3344:107::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::5]:32345", - "dataset": { - "pool_name": "oxp_521fa477-4d83-49a8-a5cf-c267b7f0c409" - } - } - }, - "root": "/pool/ext/0cbbcf22-770d-4e75-9148-e6109b129093/crypt/zone" - }, - { - "zone": { - "id": "d0d4fcc0-6ed0-410a-99c7-5daf34014421", - "underlay_address": "fd00:1122:3344:107::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::b]:32345", - "dataset": { - "pool_name": "oxp_aa7a37fb-2f03-4d5c-916b-db3a4fc269ac" - } - } - }, - "root": "/pool/ext/aa7a37fb-2f03-4d5c-916b-db3a4fc269ac/crypt/zone" - }, - { - "zone": { - "id": "c935df7b-2629-48ee-bc10-20508301905d", - "underlay_address": "fd00:1122:3344:107::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::c]:32345", - "dataset": { - "pool_name": "oxp_793fd018-5fdc-4e54-9c45-f8023fa3ea18" - } - } - }, - "root": "/pool/ext/7849c221-dc7f-43ac-ac47-bc51864e083b/crypt/zone" - }, - { - "zone": { - "id": "4ba5f3b6-8be5-4a85-bc57-a5e3b0b867d8", - "underlay_address": "fd00:1122:3344:107::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:107::8]:32345", - "dataset": { - "pool_name": "oxp_e80e7996-c572-481e-8c22-61c16c6e47f4" - } - } - }, - "root": "/pool/ext/e17b68b5-f50c-4fc3-b55a-80d284c6c32d/crypt/zone" - }, - { - "zone": { - "id": "395c9d6e-3bd0-445e-9269-46c3260edb83", - "underlay_address": "fd00:1122:3344:107::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:107::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/0cbbcf22-770d-4e75-9148-e6109b129093/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json deleted file mode 100644 index 708019883e..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "c7096dd4-e429-4a6f-9725-041a77ef2513", - "underlay_address": "fd00:1122:3344:11a::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::6]:32345", - "dataset": { - "pool_name": "oxp_dcf62af6-c0f9-4eb5-9b23-9424ef8f3d32" - } - } - }, - "root": "/pool/ext/b869e463-c8b9-4c12-a6b9-13175b3896dd/crypt/zone" - }, - { - "zone": { - "id": "09dd367f-b32f-43f3-aa53-11ccec1cd0c9", - "underlay_address": "fd00:1122:3344:11a::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::9]:32345", - "dataset": { - "pool_name": "oxp_d7d00317-42c7-4d1e-a04c-85491fb230cd" - } - } - }, - "root": "/pool/ext/d7d00317-42c7-4d1e-a04c-85491fb230cd/crypt/zone" - }, - { - "zone": { - "id": "fb2f85f1-05b3-432f-9bb5-63fb27a762b1", - "underlay_address": "fd00:1122:3344:11a::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::5]:32345", - "dataset": { - "pool_name": "oxp_db4a9949-68da-4c1c-9a1c-49083eba14fe" - } - } - }, - "root": "/pool/ext/db4a9949-68da-4c1c-9a1c-49083eba14fe/crypt/zone" - }, - { - "zone": { - "id": "5b89425e-69e4-4305-8f33-dc5768a1849e", - "underlay_address": "fd00:1122:3344:11a::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::a]:32345", - "dataset": { - "pool_name": "oxp_64a1bad7-d1b1-4e39-a3f3-9b8d73c4709e" - } - } - }, - "root": "/pool/ext/64a1bad7-d1b1-4e39-a3f3-9b8d73c4709e/crypt/zone" - }, - { - "zone": { - "id": "a5156db4-273a-4f8b-b8d8-df77062a6c63", - "underlay_address": "fd00:1122:3344:11a::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::4]:32345", - "dataset": { - "pool_name": "oxp_b869e463-c8b9-4c12-a6b9-13175b3896dd" - } - } - }, - "root": "/pool/ext/dcf62af6-c0f9-4eb5-9b23-9424ef8f3d32/crypt/zone" - }, - { - "zone": { - "id": "1f2d2f86-b69b-4130-bb9b-e62ba0cb6802", - "underlay_address": "fd00:1122:3344:11a::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::b]:32345", - "dataset": { - "pool_name": "oxp_153ffee4-5d7a-4786-ad33-d5567b434fe0" - } - } - }, - "root": "/pool/ext/174a067d-1c5a-49f7-a29f-1e62ab1c3796/crypt/zone" - }, - { - "zone": { - "id": "1e249cc9-52e7-4d66-b713-8ace1392e991", - "underlay_address": "fd00:1122:3344:11a::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::7]:32345", - "dataset": { - "pool_name": "oxp_04b6215e-9651-4a3c-ba1b-b8a1e67b3d89" - } - } - }, - "root": "/pool/ext/db4a9949-68da-4c1c-9a1c-49083eba14fe/crypt/zone" - }, - { - "zone": { - "id": "eb779538-2b1b-4d1d-8c7e-b15f04db6e53", - "underlay_address": "fd00:1122:3344:11a::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::3]:32345", - "dataset": { - "pool_name": "oxp_aacb8524-3562-4f97-a616-9023230d6efa" - } - } - }, - "root": "/pool/ext/174a067d-1c5a-49f7-a29f-1e62ab1c3796/crypt/zone" - }, - { - "zone": { - "id": "b575d52d-be7d-46af-814b-91e6d18f3464", - "underlay_address": "fd00:1122:3344:11a::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::8]:32345", - "dataset": { - "pool_name": "oxp_174a067d-1c5a-49f7-a29f-1e62ab1c3796" - } - } - }, - "root": "/pool/ext/64a1bad7-d1b1-4e39-a3f3-9b8d73c4709e/crypt/zone" - }, - { - "zone": { - "id": "274200bc-eac7-47d7-8a57-4b7be794caba", - "underlay_address": "fd00:1122:3344:11a::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11a::c]:32345", - "dataset": { - "pool_name": "oxp_2e7644e4-7d46-42bf-8e7a-9c3f39085b3f" - } - } - }, - "root": "/pool/ext/2e7644e4-7d46-42bf-8e7a-9c3f39085b3f/crypt/zone" - }, - { - "zone": { - "id": "bc20ba3a-df62-4a62-97c2-75b5653f84b4", - "underlay_address": "fd00:1122:3344:11a::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:11a::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/04b6215e-9651-4a3c-ba1b-b8a1e67b3d89/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json deleted file mode 100644 index 197df304e3..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "9c73abb9-edb8-4aa2-835b-c25ebe4466d9", - "underlay_address": "fd00:1122:3344:109::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::7]:32345", - "dataset": { - "pool_name": "oxp_b7a3032f-7b8c-4a6a-9fa2-e5773bfdbc94" - } - } - }, - "root": "/pool/ext/46d21f3d-23be-4361-b5c5-9d0f6ece5b8c/crypt/zone" - }, - { - "zone": { - "id": "ca576bda-cbdd-4bb9-9d75-ce06d569e926", - "underlay_address": "fd00:1122:3344:109::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::a]:32345", - "dataset": { - "pool_name": "oxp_863c4bc4-9c7e-453c-99d8-a3d509f49f3e" - } - } - }, - "root": "/pool/ext/7e67cb32-0c00-4090-9647-eb7bae75deeb/crypt/zone" - }, - { - "zone": { - "id": "f010978d-346e-49cd-b265-7607a25685f9", - "underlay_address": "fd00:1122:3344:109::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::c]:32345", - "dataset": { - "pool_name": "oxp_9bc1dab8-2d2a-4f92-bdfb-94ebca7881f1" - } - } - }, - "root": "/pool/ext/9bc1dab8-2d2a-4f92-bdfb-94ebca7881f1/crypt/zone" - }, - { - "zone": { - "id": "daff4162-cc81-4586-a457-91d767b8f1d9", - "underlay_address": "fd00:1122:3344:109::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::6]:32345", - "dataset": { - "pool_name": "oxp_b9b5b50c-e823-41ae-9585-01b818883521" - } - } - }, - "root": "/pool/ext/de682b18-afaf-4d53-b62e-934f6bd4a1f8/crypt/zone" - }, - { - "zone": { - "id": "9f300d3d-e698-4cc8-be4c-1f81ac8c927f", - "underlay_address": "fd00:1122:3344:109::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::d]:32345", - "dataset": { - "pool_name": "oxp_f1d82c22-ad7d-4cda-9ab0-8f5f496d90ce" - } - } - }, - "root": "/pool/ext/de682b18-afaf-4d53-b62e-934f6bd4a1f8/crypt/zone" - }, - { - "zone": { - "id": "8db7c7be-da40-4a1c-9681-4d02606a7eb7", - "underlay_address": "fd00:1122:3344:109::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::9]:32345", - "dataset": { - "pool_name": "oxp_46d21f3d-23be-4361-b5c5-9d0f6ece5b8c" - } - } - }, - "root": "/pool/ext/b7a3032f-7b8c-4a6a-9fa2-e5773bfdbc94/crypt/zone" - }, - { - "zone": { - "id": "b990911b-805a-4f9d-bd83-e977f5b19a35", - "underlay_address": "fd00:1122:3344:109::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::4]:32345", - "dataset": { - "pool_name": "oxp_7e67cb32-0c00-4090-9647-eb7bae75deeb" - } - } - }, - "root": "/pool/ext/de682b18-afaf-4d53-b62e-934f6bd4a1f8/crypt/zone" - }, - { - "zone": { - "id": "c99392f5-8f30-41ac-9eeb-12d7f4b707f1", - "underlay_address": "fd00:1122:3344:109::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::b]:32345", - "dataset": { - "pool_name": "oxp_de682b18-afaf-4d53-b62e-934f6bd4a1f8" - } - } - }, - "root": "/pool/ext/46d21f3d-23be-4361-b5c5-9d0f6ece5b8c/crypt/zone" - }, - { - "zone": { - "id": "7f6cb339-9eb1-4866-8a4f-383bad25b36f", - "underlay_address": "fd00:1122:3344:109::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::5]:32345", - "dataset": { - "pool_name": "oxp_458cbfa3-3752-415d-8a3b-fb64e88468e1" - } - } - }, - "root": "/pool/ext/b9b5b50c-e823-41ae-9585-01b818883521/crypt/zone" - }, - { - "zone": { - "id": "11946372-f253-4648-b00c-c7874a7b2888", - "underlay_address": "fd00:1122:3344:109::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:109::8]:32345", - "dataset": { - "pool_name": "oxp_d73332f5-b2a5-46c0-94cf-c5c5712abfe8" - } - } - }, - "root": "/pool/ext/b9b5b50c-e823-41ae-9585-01b818883521/crypt/zone" - }, - { - "zone": { - "id": "58ece9e1-387f-4d2f-a42f-69cd34f9f380", - "underlay_address": "fd00:1122:3344:109::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:109::3]:32221", - "dataset": { - "pool_name": "oxp_7e67cb32-0c00-4090-9647-eb7bae75deeb" - } - } - }, - "root": "/pool/ext/b9b5b50c-e823-41ae-9585-01b818883521/crypt/zone" - }, - { - "zone": { - "id": "f016a25a-deb5-4f20-bdb0-2425c00d41a6", - "underlay_address": "fd00:1122:3344:109::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:109::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/b9b5b50c-e823-41ae-9585-01b818883521/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json deleted file mode 100644 index ba6ab6f915..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "dd799dd4-03f9-451d-85e2-844155753a03", - "underlay_address": "fd00:1122:3344:10a::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::7]:32345", - "dataset": { - "pool_name": "oxp_7dcf3acc-bde9-4306-bb46-4c6a6cbbb7ba" - } - } - }, - "root": "/pool/ext/7dcf3acc-bde9-4306-bb46-4c6a6cbbb7ba/crypt/zone" - }, - { - "zone": { - "id": "dbf9346d-b46d-4402-bb44-92ce20fb5290", - "underlay_address": "fd00:1122:3344:10a::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::9]:32345", - "dataset": { - "pool_name": "oxp_9275d50f-da2c-4f84-9775-598a364309ad" - } - } - }, - "root": "/pool/ext/d83e36ef-dd7a-4cc2-be19-379b1114c031/crypt/zone" - }, - { - "zone": { - "id": "9a55ebdd-eeef-4954-b0a1-e32b04837f14", - "underlay_address": "fd00:1122:3344:10a::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::4]:32345", - "dataset": { - "pool_name": "oxp_7f30f77e-5998-4676-a226-b433b5940e77" - } - } - }, - "root": "/pool/ext/9275d50f-da2c-4f84-9775-598a364309ad/crypt/zone" - }, - { - "zone": { - "id": "bc2935f8-e4fa-4015-968e-f90985533a6a", - "underlay_address": "fd00:1122:3344:10a::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::6]:32345", - "dataset": { - "pool_name": "oxp_022c9d58-e91f-480d-bda6-0cf32ce3b1f5" - } - } - }, - "root": "/pool/ext/c395dcc3-6ece-4b3f-b143-e111a54ef7da/crypt/zone" - }, - { - "zone": { - "id": "63f8c861-fa1d-4121-92d9-7efa5ef7f5a0", - "underlay_address": "fd00:1122:3344:10a::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::a]:32345", - "dataset": { - "pool_name": "oxp_3c805784-f403-4d01-9eb0-4f77d0821980" - } - } - }, - "root": "/pool/ext/9275d50f-da2c-4f84-9775-598a364309ad/crypt/zone" - }, - { - "zone": { - "id": "4996dcf9-78de-4f69-94fa-c09cc86a8d3c", - "underlay_address": "fd00:1122:3344:10a::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::b]:32345", - "dataset": { - "pool_name": "oxp_f9fe9ce6-be0d-4974-bc30-78a8f1330496" - } - } - }, - "root": "/pool/ext/9275d50f-da2c-4f84-9775-598a364309ad/crypt/zone" - }, - { - "zone": { - "id": "36b9a4bf-7b30-4fe7-903d-3b722c79fa86", - "underlay_address": "fd00:1122:3344:10a::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::c]:32345", - "dataset": { - "pool_name": "oxp_cb1052e0-4c70-4d37-b979-dd55e6a25f08" - } - } - }, - "root": "/pool/ext/3c805784-f403-4d01-9eb0-4f77d0821980/crypt/zone" - }, - { - "zone": { - "id": "a109a902-6a27-41b6-a881-c353e28e5389", - "underlay_address": "fd00:1122:3344:10a::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::8]:32345", - "dataset": { - "pool_name": "oxp_d83e36ef-dd7a-4cc2-be19-379b1114c031" - } - } - }, - "root": "/pool/ext/d83e36ef-dd7a-4cc2-be19-379b1114c031/crypt/zone" - }, - { - "zone": { - "id": "d2a9a0bc-ea12-44e3-ac4a-904c76120d11", - "underlay_address": "fd00:1122:3344:10a::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::3]:32345", - "dataset": { - "pool_name": "oxp_c395dcc3-6ece-4b3f-b143-e111a54ef7da" - } - } - }, - "root": "/pool/ext/9898a289-2f0d-43a6-b053-850f6e784e9a/crypt/zone" - }, - { - "zone": { - "id": "b3c3e53b-d9ec-4dd8-bd2c-bd811319aa44", - "underlay_address": "fd00:1122:3344:10a::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10a::5]:32345", - "dataset": { - "pool_name": "oxp_9898a289-2f0d-43a6-b053-850f6e784e9a" - } - } - }, - "root": "/pool/ext/9275d50f-da2c-4f84-9775-598a364309ad/crypt/zone" - }, - { - "zone": { - "id": "7b445d3b-fd25-4538-ac3f-f439c66d1223", - "underlay_address": "fd00:1122:3344:10a::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:10a::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/f9fe9ce6-be0d-4974-bc30-78a8f1330496/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json deleted file mode 100644 index f02f1f05e5..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json +++ /dev/null @@ -1,198 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "4b49e669-264d-4bfb-8ab1-555b520b679c", - "underlay_address": "fd00:1122:3344:108::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::c]:32345", - "dataset": { - "pool_name": "oxp_799a1c86-9e1a-4626-91e2-a19f7ff5356e" - } - } - }, - "root": "/pool/ext/d2478613-b7c9-4bd3-856f-1fe8e9c903c2/crypt/zone" - }, - { - "zone": { - "id": "d802baae-9c3f-437a-85fe-cd72653b6db1", - "underlay_address": "fd00:1122:3344:108::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::5]:32345", - "dataset": { - "pool_name": "oxp_d2478613-b7c9-4bd3-856f-1fe8e9c903c2" - } - } - }, - "root": "/pool/ext/116f216c-e151-410f-82bf-8913904cf7b4/crypt/zone" - }, - { - "zone": { - "id": "e5f69e60-3421-49a4-8c1d-2db8cbb6a5e9", - "underlay_address": "fd00:1122:3344:108::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::b]:32345", - "dataset": { - "pool_name": "oxp_116f216c-e151-410f-82bf-8913904cf7b4" - } - } - }, - "root": "/pool/ext/eea15142-4635-4e40-b0b4-b0c4f13eca3c/crypt/zone" - }, - { - "zone": { - "id": "3e598962-ef8c-4cb6-bdfe-ec8563939d6a", - "underlay_address": "fd00:1122:3344:108::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::4]:32345", - "dataset": { - "pool_name": "oxp_ababce44-01d1-4c50-b389-f60464c5dde9" - } - } - }, - "root": "/pool/ext/ababce44-01d1-4c50-b389-f60464c5dde9/crypt/zone" - }, - { - "zone": { - "id": "25355c9f-cc2b-4b24-8eaa-65190f8936a8", - "underlay_address": "fd00:1122:3344:108::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::d]:32345", - "dataset": { - "pool_name": "oxp_fed46d41-136d-4462-8782-359014efba59" - } - } - }, - "root": "/pool/ext/eea15142-4635-4e40-b0b4-b0c4f13eca3c/crypt/zone" - }, - { - "zone": { - "id": "efb2f16c-ebad-4192-b575-dcb4d9b1d5cd", - "underlay_address": "fd00:1122:3344:108::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::a]:32345", - "dataset": { - "pool_name": "oxp_bf509067-0165-456d-98ae-72c86378e626" - } - } - }, - "root": "/pool/ext/95220093-e3b8-4f7f-9f5a-cb32cb75180a/crypt/zone" - }, - { - "zone": { - "id": "89191f0d-4e0b-47fa-9a9e-fbe2a6db1385", - "underlay_address": "fd00:1122:3344:108::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::8]:32345", - "dataset": { - "pool_name": "oxp_eea15142-4635-4e40-b0b4-b0c4f13eca3c" - } - } - }, - "root": "/pool/ext/eea15142-4635-4e40-b0b4-b0c4f13eca3c/crypt/zone" - }, - { - "zone": { - "id": "e4589324-c528-49c7-9141-35e0a7af6947", - "underlay_address": "fd00:1122:3344:108::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::6]:32345", - "dataset": { - "pool_name": "oxp_95220093-e3b8-4f7f-9f5a-cb32cb75180a" - } - } - }, - "root": "/pool/ext/ababce44-01d1-4c50-b389-f60464c5dde9/crypt/zone" - }, - { - "zone": { - "id": "95ebe94d-0e68-421d-9260-c30bd7fe4bd6", - "underlay_address": "fd00:1122:3344:108::3", - "zone_type": { - "type": "nexus", - "internal_address": "[fd00:1122:3344:108::3]:12221", - "external_ip": "45.154.216.35", - "nic": { - "id": "301aa595-f072-4da3-a533-99647b44a66a", - "kind": { - "type": "service", - "id": "95ebe94d-0e68-421d-9260-c30bd7fe4bd6" - }, - "name": "nexus-95ebe94d-0e68-421d-9260-c30bd7fe4bd6", - "ip": "172.30.2.5", - "mac": "A8:40:25:FF:F1:30", - "subnet": "172.30.2.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "external_tls": true, - "external_dns_servers": [ - "1.1.1.1", - "8.8.8.8" - ] - } - }, - "root": "/pool/ext/eea15142-4635-4e40-b0b4-b0c4f13eca3c/crypt/zone" - }, - { - "zone": { - "id": "4b7a7052-f8e8-4196-8d6b-315943986ce6", - "underlay_address": "fd00:1122:3344:108::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::7]:32345", - "dataset": { - "pool_name": "oxp_a549421c-2f12-45cc-b691-202f0a9bfa8b" - } - } - }, - "root": "/pool/ext/bf509067-0165-456d-98ae-72c86378e626/crypt/zone" - }, - { - "zone": { - "id": "71b8ff53-c781-47bb-8ddc-2c7129680542", - "underlay_address": "fd00:1122:3344:108::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:108::9]:32345", - "dataset": { - "pool_name": "oxp_9d19f891-a3d9-4c6e-b1e1-6b0b085a9440" - } - } - }, - "root": "/pool/ext/fed46d41-136d-4462-8782-359014efba59/crypt/zone" - }, - { - "zone": { - "id": "eaf7bf77-f4c2-4016-9909-4b88a27e9d9a", - "underlay_address": "fd00:1122:3344:108::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:108::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/ababce44-01d1-4c50-b389-f60464c5dde9/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json deleted file mode 100644 index d6c19b96ed..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "a91e4af3-5d18-4b08-8cb6-0583db8f8842", - "underlay_address": "fd00:1122:3344:117::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::a]:32345", - "dataset": { - "pool_name": "oxp_4b2896b8-5f0e-42fb-a474-658b28421e65" - } - } - }, - "root": "/pool/ext/23393ed9-acee-4686-861f-7fc825af1249/crypt/zone" - }, - { - "zone": { - "id": "1ce74512-ce3a-4125-95f1-12c86e0275d5", - "underlay_address": "fd00:1122:3344:117::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::8]:32345", - "dataset": { - "pool_name": "oxp_46ece76f-ef00-4dd0-9f73-326c63959470" - } - } - }, - "root": "/pool/ext/1bd5955e-14a9-463f-adeb-f12bcb45a6c1/crypt/zone" - }, - { - "zone": { - "id": "fef5d35f-9622-4dee-8635-d26e9f7f6869", - "underlay_address": "fd00:1122:3344:117::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::4]:32345", - "dataset": { - "pool_name": "oxp_e4d7c2e8-016b-4617-afb5-38a2d9c1b508" - } - } - }, - "root": "/pool/ext/e372bba3-ef60-466f-b819-a3d5b9acbe77/crypt/zone" - }, - { - "zone": { - "id": "4f024a31-cd38-4219-8381-9f1af70d1d54", - "underlay_address": "fd00:1122:3344:117::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::c]:32345", - "dataset": { - "pool_name": "oxp_7cb2a3c2-9d33-4c6a-af57-669f251cf4cf" - } - } - }, - "root": "/pool/ext/cfbd185d-e185-4aaa-a598-9216124ceec4/crypt/zone" - }, - { - "zone": { - "id": "d00e1d0b-e12f-420a-a4df-21e4cac176f6", - "underlay_address": "fd00:1122:3344:117::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::b]:32345", - "dataset": { - "pool_name": "oxp_e372bba3-ef60-466f-b819-a3d5b9acbe77" - } - } - }, - "root": "/pool/ext/cfbd185d-e185-4aaa-a598-9216124ceec4/crypt/zone" - }, - { - "zone": { - "id": "1598058a-6064-449e-b39c-1e3d345ed793", - "underlay_address": "fd00:1122:3344:117::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::5]:32345", - "dataset": { - "pool_name": "oxp_022a8d67-1e00-49f3-81ed-a0a1bc187cfa" - } - } - }, - "root": "/pool/ext/022a8d67-1e00-49f3-81ed-a0a1bc187cfa/crypt/zone" - }, - { - "zone": { - "id": "c723c4b8-3031-4b25-8c16-fe08bc0b5f00", - "underlay_address": "fd00:1122:3344:117::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::7]:32345", - "dataset": { - "pool_name": "oxp_23393ed9-acee-4686-861f-7fc825af1249" - } - } - }, - "root": "/pool/ext/1bd5955e-14a9-463f-adeb-f12bcb45a6c1/crypt/zone" - }, - { - "zone": { - "id": "7751b307-888f-46c8-8787-75d2f3fdaef3", - "underlay_address": "fd00:1122:3344:117::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::9]:32345", - "dataset": { - "pool_name": "oxp_e54e53d4-f68f-4b19-b8c1-9d5ab42e51c1" - } - } - }, - "root": "/pool/ext/e372bba3-ef60-466f-b819-a3d5b9acbe77/crypt/zone" - }, - { - "zone": { - "id": "89413ff1-d5de-4931-8389-e84e7ea321af", - "underlay_address": "fd00:1122:3344:117::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::6]:32345", - "dataset": { - "pool_name": "oxp_1bd5955e-14a9-463f-adeb-f12bcb45a6c1" - } - } - }, - "root": "/pool/ext/1bd5955e-14a9-463f-adeb-f12bcb45a6c1/crypt/zone" - }, - { - "zone": { - "id": "287b0b24-72aa-41b5-a597-8523d84225ef", - "underlay_address": "fd00:1122:3344:117::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:117::3]:32345", - "dataset": { - "pool_name": "oxp_cfbd185d-e185-4aaa-a598-9216124ceec4" - } - } - }, - "root": "/pool/ext/cfbd185d-e185-4aaa-a598-9216124ceec4/crypt/zone" - }, - { - "zone": { - "id": "4728253e-c534-4a5b-b707-c64ac9a8eb8c", - "underlay_address": "fd00:1122:3344:117::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:117::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/cfbd185d-e185-4aaa-a598-9216124ceec4/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json deleted file mode 100644 index 1cd6fed362..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "49f20cd1-a8a3-4fa8-9209-59da60cd8f9b", - "underlay_address": "fd00:1122:3344:103::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::5]:32345", - "dataset": { - "pool_name": "oxp_13a9ef4a-f33a-4781-8f83-712c07a79b1f" - } - } - }, - "root": "/pool/ext/711eff4e-736c-478e-83aa-ae86f5efbf1d/crypt/zone" - }, - { - "zone": { - "id": "896fd564-f94e-496b-9fcf-ddfbfcfac9f7", - "underlay_address": "fd00:1122:3344:103::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::c]:32345", - "dataset": { - "pool_name": "oxp_0944c0a2-0fb7-4f51-bced-52cc257cd2f6" - } - } - }, - "root": "/pool/ext/bc54d8c5-955d-429d-84e0-a20a4e5e27a3/crypt/zone" - }, - { - "zone": { - "id": "911fb8b3-05c2-4af7-8974-6c74a61d94ad", - "underlay_address": "fd00:1122:3344:103::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::9]:32345", - "dataset": { - "pool_name": "oxp_29f59fce-a867-4571-9d2e-b03fa5c13510" - } - } - }, - "root": "/pool/ext/711eff4e-736c-478e-83aa-ae86f5efbf1d/crypt/zone" - }, - { - "zone": { - "id": "682b34db-0b06-4770-a8fe-74437cf184d6", - "underlay_address": "fd00:1122:3344:103::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::6]:32345", - "dataset": { - "pool_name": "oxp_094d11d2-8049-4138-bcf4-562f5f8e77c0" - } - } - }, - "root": "/pool/ext/0944c0a2-0fb7-4f51-bced-52cc257cd2f6/crypt/zone" - }, - { - "zone": { - "id": "d8d20365-ecd3-4fd5-9495-c0670e3bd5d9", - "underlay_address": "fd00:1122:3344:103::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::a]:32345", - "dataset": { - "pool_name": "oxp_fb97ff7b-0225-400c-a137-3b38a786c0a0" - } - } - }, - "root": "/pool/ext/094d11d2-8049-4138-bcf4-562f5f8e77c0/crypt/zone" - }, - { - "zone": { - "id": "673620b6-44d9-4310-8e17-3024ac84e708", - "underlay_address": "fd00:1122:3344:103::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::7]:32345", - "dataset": { - "pool_name": "oxp_711eff4e-736c-478e-83aa-ae86f5efbf1d" - } - } - }, - "root": "/pool/ext/fb97ff7b-0225-400c-a137-3b38a786c0a0/crypt/zone" - }, - { - "zone": { - "id": "bf6dfc04-4d4c-41b6-a011-40ffc3bc5080", - "underlay_address": "fd00:1122:3344:103::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::8]:32345", - "dataset": { - "pool_name": "oxp_f815f1b6-48ef-436d-8768-eb08227e2386" - } - } - }, - "root": "/pool/ext/13a9ef4a-f33a-4781-8f83-712c07a79b1f/crypt/zone" - }, - { - "zone": { - "id": "ac8a82a8-fb6f-4635-a9a9-d98617eab390", - "underlay_address": "fd00:1122:3344:103::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::3]:32345", - "dataset": { - "pool_name": "oxp_97d6c860-4e2f-496e-974b-2e293fee6af9" - } - } - }, - "root": "/pool/ext/0944c0a2-0fb7-4f51-bced-52cc257cd2f6/crypt/zone" - }, - { - "zone": { - "id": "4ed66558-4815-4b85-9b94-9edf3ee69ead", - "underlay_address": "fd00:1122:3344:103::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::4]:32345", - "dataset": { - "pool_name": "oxp_bc54d8c5-955d-429d-84e0-a20a4e5e27a3" - } - } - }, - "root": "/pool/ext/13a9ef4a-f33a-4781-8f83-712c07a79b1f/crypt/zone" - }, - { - "zone": { - "id": "8a71c6ee-b08d-4c3d-b13c-c9cebc4c328a", - "underlay_address": "fd00:1122:3344:103::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:103::b]:32345", - "dataset": { - "pool_name": "oxp_2bdfa429-09bd-4fa1-aa20-eea99f0d2b85" - } - } - }, - "root": "/pool/ext/29f59fce-a867-4571-9d2e-b03fa5c13510/crypt/zone" - }, - { - "zone": { - "id": "7e6b8962-7a1e-4d7b-b7ea-49e64a51d98d", - "underlay_address": "fd00:1122:3344:103::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:103::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/2bdfa429-09bd-4fa1-aa20-eea99f0d2b85/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json deleted file mode 100644 index ab171ad8cd..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "6b7e931d-4b91-4dc6-9a7b-4c19ac669e5d", - "underlay_address": "fd00:1122:3344:105::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::4]:32345", - "dataset": { - "pool_name": "oxp_24dab7f5-164a-47f3-a878-f32ab1e68cce" - } - } - }, - "root": "/pool/ext/ad493851-2d11-4c2d-8d75-989579d9616a/crypt/zone" - }, - { - "zone": { - "id": "6c58e7aa-71e1-4868-9d4b-e12c7ef40303", - "underlay_address": "fd00:1122:3344:105::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::a]:32345", - "dataset": { - "pool_name": "oxp_d664c9e8-bc81-4225-a618-a8ae2d057186" - } - } - }, - "root": "/pool/ext/ad493851-2d11-4c2d-8d75-989579d9616a/crypt/zone" - }, - { - "zone": { - "id": "51c6dc8d-b1a4-454a-9b19-01e45eb0b599", - "underlay_address": "fd00:1122:3344:105::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::d]:32345", - "dataset": { - "pool_name": "oxp_f5f85537-eb25-4d0e-8e94-b775c41abd73" - } - } - }, - "root": "/pool/ext/4f1eafe9-b28d-49d3-83e2-ceac8721d6b5/crypt/zone" - }, - { - "zone": { - "id": "8cbffa61-0bd0-4ad2-bd7d-30fe0dd57469", - "underlay_address": "fd00:1122:3344:105::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::9]:32345", - "dataset": { - "pool_name": "oxp_88abca38-3f61-4d4b-80a1-4ea3e4827f84" - } - } - }, - "root": "/pool/ext/88abca38-3f61-4d4b-80a1-4ea3e4827f84/crypt/zone" - }, - { - "zone": { - "id": "2177f37f-2ac9-4e66-bf74-a10bd91f4d33", - "underlay_address": "fd00:1122:3344:105::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::6]:32345", - "dataset": { - "pool_name": "oxp_59e20871-4670-40d6-8ff4-aa97899fc991" - } - } - }, - "root": "/pool/ext/4f1eafe9-b28d-49d3-83e2-ceac8721d6b5/crypt/zone" - }, - { - "zone": { - "id": "e4e43855-4879-4910-a2ba-40f625c1cc2d", - "underlay_address": "fd00:1122:3344:105::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::b]:32345", - "dataset": { - "pool_name": "oxp_967d2f05-b141-44f5-837d-9b2aa67ee128" - } - } - }, - "root": "/pool/ext/6b6f34cd-6d3d-4832-a4e6-3df112c97133/crypt/zone" - }, - { - "zone": { - "id": "8d2517e1-f9ad-40f2-abb9-2f5122839910", - "underlay_address": "fd00:1122:3344:105::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::7]:32345", - "dataset": { - "pool_name": "oxp_ad493851-2d11-4c2d-8d75-989579d9616a" - } - } - }, - "root": "/pool/ext/88abca38-3f61-4d4b-80a1-4ea3e4827f84/crypt/zone" - }, - { - "zone": { - "id": "44cb3698-a7b1-4388-9165-ac76082ec8bc", - "underlay_address": "fd00:1122:3344:105::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::5]:32345", - "dataset": { - "pool_name": "oxp_4292a83c-8c1f-4b2e-9120-72e0c510bf3c" - } - } - }, - "root": "/pool/ext/24dab7f5-164a-47f3-a878-f32ab1e68cce/crypt/zone" - }, - { - "zone": { - "id": "931b5c86-9d72-4518-bfd6-97863152ac65", - "underlay_address": "fd00:1122:3344:105::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::c]:32345", - "dataset": { - "pool_name": "oxp_6b6f34cd-6d3d-4832-a4e6-3df112c97133" - } - } - }, - "root": "/pool/ext/ad493851-2d11-4c2d-8d75-989579d9616a/crypt/zone" - }, - { - "zone": { - "id": "ac568073-1889-463e-8cc4-cfed16ce2a34", - "underlay_address": "fd00:1122:3344:105::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::8]:32345", - "dataset": { - "pool_name": "oxp_4f1eafe9-b28d-49d3-83e2-ceac8721d6b5" - } - } - }, - "root": "/pool/ext/4292a83c-8c1f-4b2e-9120-72e0c510bf3c/crypt/zone" - }, - { - "zone": { - "id": "e8f86fbb-864e-4d5a-961c-b50b54ae853e", - "underlay_address": "fd00:1122:3344:105::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:105::3]:32221", - "dataset": { - "pool_name": "oxp_24dab7f5-164a-47f3-a878-f32ab1e68cce" - } - } - }, - "root": "/pool/ext/4f1eafe9-b28d-49d3-83e2-ceac8721d6b5/crypt/zone" - }, - { - "zone": { - "id": "c79caea0-37b1-49d6-ae6e-8cf849d91374", - "underlay_address": "fd00:1122:3344:105::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:105::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/24dab7f5-164a-47f3-a878-f32ab1e68cce/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json deleted file mode 100644 index 9968abe6d9..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "d2b1e468-bc3c-4d08-b855-ae3327465375", - "underlay_address": "fd00:1122:3344:106::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::3]:32345", - "dataset": { - "pool_name": "oxp_9db196bf-828d-4e55-a2c1-dd9d579d3908" - } - } - }, - "root": "/pool/ext/74df4c92-edbb-4431-a770-1d015110e66b/crypt/zone" - }, - { - "zone": { - "id": "61f94a16-79fd-42e3-b225-a4dc67228437", - "underlay_address": "fd00:1122:3344:106::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::6]:32345", - "dataset": { - "pool_name": "oxp_d77d5b08-5f70-496a-997b-b38804dc3b8a" - } - } - }, - "root": "/pool/ext/daf9e3cd-5a40-4eba-a0f6-4f94dab37dae/crypt/zone" - }, - { - "zone": { - "id": "7d32ef34-dec5-4fd8-899e-20bbc473a3ee", - "underlay_address": "fd00:1122:3344:106::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::7]:32345", - "dataset": { - "pool_name": "oxp_50c1b653-6231-41fe-b3cf-b7ba709a0746" - } - } - }, - "root": "/pool/ext/9db196bf-828d-4e55-a2c1-dd9d579d3908/crypt/zone" - }, - { - "zone": { - "id": "c34b7ae5-26b9-4651-a3c4-20bba2bd0d2c", - "underlay_address": "fd00:1122:3344:106::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::5]:32345", - "dataset": { - "pool_name": "oxp_88aea92c-ab92-44c1-9471-eb8e30e075d3" - } - } - }, - "root": "/pool/ext/8da316d4-6b18-4980-a0a8-6e76e72cc40d/crypt/zone" - }, - { - "zone": { - "id": "36472be8-9a70-4c14-bd02-439b725cec1a", - "underlay_address": "fd00:1122:3344:106::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::8]:32345", - "dataset": { - "pool_name": "oxp_54544b3a-1513-4db2-911e-7c1eb4b12385" - } - } - }, - "root": "/pool/ext/54544b3a-1513-4db2-911e-7c1eb4b12385/crypt/zone" - }, - { - "zone": { - "id": "2548f8ab-5255-4334-a1fb-5d7d95213129", - "underlay_address": "fd00:1122:3344:106::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::9]:32345", - "dataset": { - "pool_name": "oxp_08050450-967f-431c-9a12-0d051aff020e" - } - } - }, - "root": "/pool/ext/08050450-967f-431c-9a12-0d051aff020e/crypt/zone" - }, - { - "zone": { - "id": "1455c069-853c-49cd-853a-3ea81b89acd4", - "underlay_address": "fd00:1122:3344:106::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::c]:32345", - "dataset": { - "pool_name": "oxp_8da316d4-6b18-4980-a0a8-6e76e72cc40d" - } - } - }, - "root": "/pool/ext/08050450-967f-431c-9a12-0d051aff020e/crypt/zone" - }, - { - "zone": { - "id": "27c0244b-f91a-46c3-bc96-e8eec009371e", - "underlay_address": "fd00:1122:3344:106::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::b]:32345", - "dataset": { - "pool_name": "oxp_daf9e3cd-5a40-4eba-a0f6-4f94dab37dae" - } - } - }, - "root": "/pool/ext/74df4c92-edbb-4431-a770-1d015110e66b/crypt/zone" - }, - { - "zone": { - "id": "9e46d837-1e0f-42b6-a352-84e6946b8734", - "underlay_address": "fd00:1122:3344:106::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::4]:32345", - "dataset": { - "pool_name": "oxp_74df4c92-edbb-4431-a770-1d015110e66b" - } - } - }, - "root": "/pool/ext/15f94c39-d48c-41f6-a913-cc1d04aef1a2/crypt/zone" - }, - { - "zone": { - "id": "b972fcd4-c1b3-4b3c-9e24-f59c7a7cb192", - "underlay_address": "fd00:1122:3344:106::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:106::a]:32345", - "dataset": { - "pool_name": "oxp_15f94c39-d48c-41f6-a913-cc1d04aef1a2" - } - } - }, - "root": "/pool/ext/74df4c92-edbb-4431-a770-1d015110e66b/crypt/zone" - }, - { - "zone": { - "id": "e1c8c655-1950-42d5-ae1f-a4ce84854bbc", - "underlay_address": "fd00:1122:3344:106::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:106::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/15f94c39-d48c-41f6-a913-cc1d04aef1a2/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json deleted file mode 100644 index 8deca6b56a..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json +++ /dev/null @@ -1,196 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "10b80058-9b2e-4d6c-8a1a-a61a8258c12f", - "underlay_address": "fd00:1122:3344:118::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::9]:32345", - "dataset": { - "pool_name": "oxp_953c19bb-9fff-4488-8a7b-29de9994a948" - } - } - }, - "root": "/pool/ext/a78caf97-6145-4908-83b5-a03a6d2e0ac4/crypt/zone" - }, - { - "zone": { - "id": "f58fef96-7b5e-40c2-9482-669088a19209", - "underlay_address": "fd00:1122:3344:118::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::d]:32345", - "dataset": { - "pool_name": "oxp_d7976706-d6ed-4465-8b04-450c96d8feec" - } - } - }, - "root": "/pool/ext/d7976706-d6ed-4465-8b04-450c96d8feec/crypt/zone" - }, - { - "zone": { - "id": "624f1168-47b6-4aa1-84da-e20a0d74d783", - "underlay_address": "fd00:1122:3344:118::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::b]:32345", - "dataset": { - "pool_name": "oxp_a78caf97-6145-4908-83b5-a03a6d2e0ac4" - } - } - }, - "root": "/pool/ext/a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d/crypt/zone" - }, - { - "zone": { - "id": "8ea85412-19b4-45c1-a53c-027ddd629296", - "underlay_address": "fd00:1122:3344:118::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::6]:32345", - "dataset": { - "pool_name": "oxp_d5f4c903-155a-4c91-aadd-6039a4f64821" - } - } - }, - "root": "/pool/ext/7d2a7685-c1c9-4d2d-a2bb-df65d96ea3e2/crypt/zone" - }, - { - "zone": { - "id": "fd226b82-71d7-4719-b32c-a6c7abe28a2a", - "underlay_address": "fd00:1122:3344:118::3", - "zone_type": { - "type": "external_dns", - "dataset": { - "pool_name": "oxp_84a80b58-70e9-439c-9558-5b343d9a4b53" - }, - "http_address": "[fd00:1122:3344:118::3]:5353", - "dns_address": "45.154.216.34:53", - "nic": { - "id": "7f72b6fd-1120-44dc-b3a7-f727502ba47c", - "kind": { - "type": "service", - "id": "fd226b82-71d7-4719-b32c-a6c7abe28a2a" - }, - "name": "external-dns-fd226b82-71d7-4719-b32c-a6c7abe28a2a", - "ip": "172.30.1.6", - "mac": "A8:40:25:FF:9E:D1", - "subnet": "172.30.1.0/24", - "vni": 100, - "primary": true, - "slot": 0 - } - } - }, - "root": "/pool/ext/a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d/crypt/zone" - }, - { - "zone": { - "id": "08d0c38d-f0d9-45b9-856d-b85059fe5f07", - "underlay_address": "fd00:1122:3344:118::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::4]:32345", - "dataset": { - "pool_name": "oxp_84a80b58-70e9-439c-9558-5b343d9a4b53" - } - } - }, - "root": "/pool/ext/a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d/crypt/zone" - }, - { - "zone": { - "id": "5de7d3fd-4a3f-4fdd-b6b2-d1186e16dce5", - "underlay_address": "fd00:1122:3344:118::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::7]:32345", - "dataset": { - "pool_name": "oxp_d76e058f-2d1e-4b15-b3a0-e5509a246876" - } - } - }, - "root": "/pool/ext/a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d/crypt/zone" - }, - { - "zone": { - "id": "5d0f5cad-10b3-497c-903b-eeeabce920e2", - "underlay_address": "fd00:1122:3344:118::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::8]:32345", - "dataset": { - "pool_name": "oxp_3a3ad639-8800-4951-bc2a-201d269e47a2" - } - } - }, - "root": "/pool/ext/3a3ad639-8800-4951-bc2a-201d269e47a2/crypt/zone" - }, - { - "zone": { - "id": "39f9cefa-801c-4843-9fb9-05446ffbdd1a", - "underlay_address": "fd00:1122:3344:118::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::a]:32345", - "dataset": { - "pool_name": "oxp_7d2a7685-c1c9-4d2d-a2bb-df65d96ea3e2" - } - } - }, - "root": "/pool/ext/a78caf97-6145-4908-83b5-a03a6d2e0ac4/crypt/zone" - }, - { - "zone": { - "id": "0711e710-7fdd-4e68-94c8-294b8677e804", - "underlay_address": "fd00:1122:3344:118::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::5]:32345", - "dataset": { - "pool_name": "oxp_a5b16ffe-a834-4a83-a4e9-487d4cbb7e3d" - } - } - }, - "root": "/pool/ext/3a3ad639-8800-4951-bc2a-201d269e47a2/crypt/zone" - }, - { - "zone": { - "id": "318a62cc-5c6c-4805-9fb6-c0f6a75ce31c", - "underlay_address": "fd00:1122:3344:118::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:118::c]:32345", - "dataset": { - "pool_name": "oxp_1d5f0ba3-6b31-4cea-a9a9-2065a538887d" - } - } - }, - "root": "/pool/ext/d7976706-d6ed-4465-8b04-450c96d8feec/crypt/zone" - }, - { - "zone": { - "id": "463d0498-85b9-40eb-af96-d99af58a587c", - "underlay_address": "fd00:1122:3344:118::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:118::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/d5f4c903-155a-4c91-aadd-6039a4f64821/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json deleted file mode 100644 index a3c5d97b53..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "d8b3de97-cc79-48f6-83ad-02017c21223b", - "underlay_address": "fd00:1122:3344:119::3", - "zone_type": { - "type": "crucible_pantry", - "address": "[fd00:1122:3344:119::3]:17000" - } - }, - "root": "/pool/ext/e0faea44-8b5c-40b0-bb75-a1aec1a10377/crypt/zone" - }, - { - "zone": { - "id": "adba1a3b-5bac-44d5-aa5a-879dc6eadb5f", - "underlay_address": "fd00:1122:3344:119::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::c]:32345", - "dataset": { - "pool_name": "oxp_21c339c3-6461-4bdb-8b0e-c0f9f08ee10b" - } - } - }, - "root": "/pool/ext/f5c73c28-2168-4321-b737-4ca6663155c9/crypt/zone" - }, - { - "zone": { - "id": "42bb9833-5c39-4aba-b2c4-da2ca1287728", - "underlay_address": "fd00:1122:3344:119::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::a]:32345", - "dataset": { - "pool_name": "oxp_1f91451d-a466-4c9a-a6e6-0abd7985595f" - } - } - }, - "root": "/pool/ext/21c339c3-6461-4bdb-8b0e-c0f9f08ee10b/crypt/zone" - }, - { - "zone": { - "id": "197695e1-d949-4982-b679-6e5c9ab4bcc7", - "underlay_address": "fd00:1122:3344:119::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::b]:32345", - "dataset": { - "pool_name": "oxp_e0faea44-8b5c-40b0-bb75-a1aec1a10377" - } - } - }, - "root": "/pool/ext/b31e1815-cae0-4145-940c-874fff63bdd5/crypt/zone" - }, - { - "zone": { - "id": "bf99d4f8-edf1-4de5-98d4-8e6a24965005", - "underlay_address": "fd00:1122:3344:119::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::8]:32345", - "dataset": { - "pool_name": "oxp_ef2c3afb-6962-4f6b-b567-14766bbd9ec0" - } - } - }, - "root": "/pool/ext/21c339c3-6461-4bdb-8b0e-c0f9f08ee10b/crypt/zone" - }, - { - "zone": { - "id": "390d1853-8be9-4987-b8b6-f022999bf4e7", - "underlay_address": "fd00:1122:3344:119::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::7]:32345", - "dataset": { - "pool_name": "oxp_06eed00a-d8d3-4b9d-84c9-23fce535f63e" - } - } - }, - "root": "/pool/ext/ef2c3afb-6962-4f6b-b567-14766bbd9ec0/crypt/zone" - }, - { - "zone": { - "id": "76fe2161-90df-41b5-9c94-067de9c29db1", - "underlay_address": "fd00:1122:3344:119::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::4]:32345", - "dataset": { - "pool_name": "oxp_f5c73c28-2168-4321-b737-4ca6663155c9" - } - } - }, - "root": "/pool/ext/ef2c3afb-6962-4f6b-b567-14766bbd9ec0/crypt/zone" - }, - { - "zone": { - "id": "f49dc522-2b13-4055-964c-8315671096aa", - "underlay_address": "fd00:1122:3344:119::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::d]:32345", - "dataset": { - "pool_name": "oxp_662c278b-7f5f-4c7e-91ff-70207e8a307b" - } - } - }, - "root": "/pool/ext/1f91451d-a466-4c9a-a6e6-0abd7985595f/crypt/zone" - }, - { - "zone": { - "id": "08cc7bd6-368e-4d16-a619-28b17eff35af", - "underlay_address": "fd00:1122:3344:119::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::9]:32345", - "dataset": { - "pool_name": "oxp_5516b9ac-b139-40da-aa3b-f094568ba095" - } - } - }, - "root": "/pool/ext/06eed00a-d8d3-4b9d-84c9-23fce535f63e/crypt/zone" - }, - { - "zone": { - "id": "74b0613f-bce8-4922-93e0-b5bfccfc8443", - "underlay_address": "fd00:1122:3344:119::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::5]:32345", - "dataset": { - "pool_name": "oxp_b31e1815-cae0-4145-940c-874fff63bdd5" - } - } - }, - "root": "/pool/ext/21c339c3-6461-4bdb-8b0e-c0f9f08ee10b/crypt/zone" - }, - { - "zone": { - "id": "55fcfc62-8435-475f-a2aa-29373901b993", - "underlay_address": "fd00:1122:3344:119::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:119::6]:32345", - "dataset": { - "pool_name": "oxp_eadf6a03-1028-4d48-ac0d-0d27ef2c8c0f" - } - } - }, - "root": "/pool/ext/1f91451d-a466-4c9a-a6e6-0abd7985595f/crypt/zone" - }, - { - "zone": { - "id": "d52ccea3-6d7f-43a6-a19f-e0409f4e9cdc", - "underlay_address": "fd00:1122:3344:119::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:119::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/f5c73c28-2168-4321-b737-4ca6663155c9/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json deleted file mode 100644 index 193df7a567..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "095e612f-e218-4a16-aa6e-98c3d69a470a", - "underlay_address": "fd00:1122:3344:10d::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::a]:32345", - "dataset": { - "pool_name": "oxp_9f657858-623f-4d78-9841-6e620b5ede30" - } - } - }, - "root": "/pool/ext/2d086b51-2b77-4bc7-adc6-43586ea38ce9/crypt/zone" - }, - { - "zone": { - "id": "de818730-0e3b-4567-94e7-344bd9b6f564", - "underlay_address": "fd00:1122:3344:10d::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::3]:32345", - "dataset": { - "pool_name": "oxp_ba6ab301-07e1-4d35-80ac-59612f2c2bdb" - } - } - }, - "root": "/pool/ext/7cee2806-e898-47d8-b568-e276a6e271f8/crypt/zone" - }, - { - "zone": { - "id": "6a21dc3c-3a9d-4520-9a91-7d8f2737bcd4", - "underlay_address": "fd00:1122:3344:10d::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::4]:32345", - "dataset": { - "pool_name": "oxp_7cee2806-e898-47d8-b568-e276a6e271f8" - } - } - }, - "root": "/pool/ext/cef23d87-31ed-40d5-99b8-12d7be8e46e7/crypt/zone" - }, - { - "zone": { - "id": "e01b7f45-b8d7-4944-ba5b-41fb699889a9", - "underlay_address": "fd00:1122:3344:10d::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::b]:32345", - "dataset": { - "pool_name": "oxp_d9af8878-50bd-4425-95d9-e6556ce92cfa" - } - } - }, - "root": "/pool/ext/6fe9bcaa-88cb-451d-b086-24a3ad53fa22/crypt/zone" - }, - { - "zone": { - "id": "4271ef62-d319-4e80-b157-915321cec8c7", - "underlay_address": "fd00:1122:3344:10d::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::c]:32345", - "dataset": { - "pool_name": "oxp_ba8ee7dd-cdfb-48bd-92ce-4dc45e070930" - } - } - }, - "root": "/pool/ext/9f657858-623f-4d78-9841-6e620b5ede30/crypt/zone" - }, - { - "zone": { - "id": "6bdcc159-aeb9-4903-9486-dd8b43a3dc16", - "underlay_address": "fd00:1122:3344:10d::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::8]:32345", - "dataset": { - "pool_name": "oxp_5b03a5dc-bb5a-4bf4-bc21-0af849cd1dab" - } - } - }, - "root": "/pool/ext/d9af8878-50bd-4425-95d9-e6556ce92cfa/crypt/zone" - }, - { - "zone": { - "id": "85540e54-cdd7-4baa-920c-5cf54cbc1f83", - "underlay_address": "fd00:1122:3344:10d::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::7]:32345", - "dataset": { - "pool_name": "oxp_ee24f9a6-84ab-49a5-a28f-e394abfcaa95" - } - } - }, - "root": "/pool/ext/9f657858-623f-4d78-9841-6e620b5ede30/crypt/zone" - }, - { - "zone": { - "id": "750d1a0b-6a14-46c5-9a0b-a504caefb198", - "underlay_address": "fd00:1122:3344:10d::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::9]:32345", - "dataset": { - "pool_name": "oxp_cef23d87-31ed-40d5-99b8-12d7be8e46e7" - } - } - }, - "root": "/pool/ext/ba8ee7dd-cdfb-48bd-92ce-4dc45e070930/crypt/zone" - }, - { - "zone": { - "id": "b5996893-1a9a-434e-a257-d702694f058b", - "underlay_address": "fd00:1122:3344:10d::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::6]:32345", - "dataset": { - "pool_name": "oxp_2d086b51-2b77-4bc7-adc6-43586ea38ce9" - } - } - }, - "root": "/pool/ext/7cee2806-e898-47d8-b568-e276a6e271f8/crypt/zone" - }, - { - "zone": { - "id": "8b36686a-b98d-451a-9124-a3583000a83a", - "underlay_address": "fd00:1122:3344:10d::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10d::5]:32345", - "dataset": { - "pool_name": "oxp_6fe9bcaa-88cb-451d-b086-24a3ad53fa22" - } - } - }, - "root": "/pool/ext/9f657858-623f-4d78-9841-6e620b5ede30/crypt/zone" - }, - { - "zone": { - "id": "88d695a2-c8c1-41af-85b0-77424f4d650d", - "underlay_address": "fd00:1122:3344:10d::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:10d::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/ba6ab301-07e1-4d35-80ac-59612f2c2bdb/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json deleted file mode 100644 index 210b388a19..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "a126365d-f459-43bf-9f99-dbe1c4cdecf8", - "underlay_address": "fd00:1122:3344:113::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::4]:32345", - "dataset": { - "pool_name": "oxp_c99eabb2-6815-416a-9660-87e2609b357a" - } - } - }, - "root": "/pool/ext/6461a450-f043-4d1e-bc03-4a68ed5fe94a/crypt/zone" - }, - { - "zone": { - "id": "52f57ef8-546a-43bd-a0f3-8c42b99c37a6", - "underlay_address": "fd00:1122:3344:113::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::3]:32345", - "dataset": { - "pool_name": "oxp_f6530e9c-6d64-44fa-93d5-ae427916fbf1" - } - } - }, - "root": "/pool/ext/97662260-6b62-450f-9d7e-42f7dee5d568/crypt/zone" - }, - { - "zone": { - "id": "3ee87855-9423-43ff-800a-fa4fdbf1d956", - "underlay_address": "fd00:1122:3344:113::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::a]:32345", - "dataset": { - "pool_name": "oxp_6461a450-f043-4d1e-bc03-4a68ed5fe94a" - } - } - }, - "root": "/pool/ext/9515dc86-fe62-4d4f-b38d-b3461cc042fc/crypt/zone" - }, - { - "zone": { - "id": "55d0ddf9-9b24-4a7a-b97f-248e240f9ba6", - "underlay_address": "fd00:1122:3344:113::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::5]:32345", - "dataset": { - "pool_name": "oxp_97662260-6b62-450f-9d7e-42f7dee5d568" - } - } - }, - "root": "/pool/ext/9515dc86-fe62-4d4f-b38d-b3461cc042fc/crypt/zone" - }, - { - "zone": { - "id": "014cad37-56a7-4b2a-9c9e-505b15b4de85", - "underlay_address": "fd00:1122:3344:113::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::b]:32345", - "dataset": { - "pool_name": "oxp_8529ce8e-21d2-4b23-b9fd-6b90c7ae4f90" - } - } - }, - "root": "/pool/ext/6461a450-f043-4d1e-bc03-4a68ed5fe94a/crypt/zone" - }, - { - "zone": { - "id": "e14fb192-aaab-42ab-aa86-c85f13955940", - "underlay_address": "fd00:1122:3344:113::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::6]:32345", - "dataset": { - "pool_name": "oxp_5a9455ca-fb01-4549-9a70-7579c031779d" - } - } - }, - "root": "/pool/ext/f6530e9c-6d64-44fa-93d5-ae427916fbf1/crypt/zone" - }, - { - "zone": { - "id": "14540609-9371-442b-8486-88c244e97cd4", - "underlay_address": "fd00:1122:3344:113::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::8]:32345", - "dataset": { - "pool_name": "oxp_2916d6f3-8775-4887-a6d3-f9723982756f" - } - } - }, - "root": "/pool/ext/8529ce8e-21d2-4b23-b9fd-6b90c7ae4f90/crypt/zone" - }, - { - "zone": { - "id": "97a6b35f-0af9-41eb-93a1-f8bc5dbba357", - "underlay_address": "fd00:1122:3344:113::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::7]:32345", - "dataset": { - "pool_name": "oxp_9515dc86-fe62-4d4f-b38d-b3461cc042fc" - } - } - }, - "root": "/pool/ext/8529ce8e-21d2-4b23-b9fd-6b90c7ae4f90/crypt/zone" - }, - { - "zone": { - "id": "5734aa24-cb66-4b0a-9eb2-564646f8d729", - "underlay_address": "fd00:1122:3344:113::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::9]:32345", - "dataset": { - "pool_name": "oxp_9f889a6c-17b1-4edd-9659-458d91439dc1" - } - } - }, - "root": "/pool/ext/a5074e7f-8d3b-40e0-a79e-dbd9af9d5693/crypt/zone" - }, - { - "zone": { - "id": "ba86eca1-1427-4540-b4a6-1d9a0e1bc656", - "underlay_address": "fd00:1122:3344:113::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:113::c]:32345", - "dataset": { - "pool_name": "oxp_a5074e7f-8d3b-40e0-a79e-dbd9af9d5693" - } - } - }, - "root": "/pool/ext/2916d6f3-8775-4887-a6d3-f9723982756f/crypt/zone" - }, - { - "zone": { - "id": "6634dbc4-d22f-40a4-8cd3-4f271d781fa1", - "underlay_address": "fd00:1122:3344:113::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:113::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/a5074e7f-8d3b-40e0-a79e-dbd9af9d5693/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json deleted file mode 100644 index ccd1bd65be..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json +++ /dev/null @@ -1,184 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 5, - "zones": [ - { - "zone": { - "id": "1cdd1ebf-9321-4f2d-914c-1e617f60b41a", - "underlay_address": "fd00:1122:3344:120::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::8]:32345", - "dataset": { - "pool_name": "oxp_74046573-78a2-46b4-86dc-40bb2ee29dd5" - } - } - }, - "root": "/pool/ext/c1f0a9e4-ea10-4fd9-8b6d-79a2bacfec5e/crypt/zone" - }, - { - "zone": { - "id": "720a0d08-d1c0-43ba-af86-f2dac1a53639", - "underlay_address": "fd00:1122:3344:120::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::c]:32345", - "dataset": { - "pool_name": "oxp_068d2790-1044-41ed-97a5-b493490b14d1" - } - } - }, - "root": "/pool/ext/86cd16cf-d00d-40bc-b14a-8220b1e11476/crypt/zone" - }, - { - "zone": { - "id": "d9f0b97b-2cef-4155-b45f-7db89263e4cf", - "underlay_address": "fd00:1122:3344:120::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::9]:32345", - "dataset": { - "pool_name": "oxp_8171bf0d-e61e-43f9-87d6-ec8833b80102" - } - } - }, - "root": "/pool/ext/86cd16cf-d00d-40bc-b14a-8220b1e11476/crypt/zone" - }, - { - "zone": { - "id": "018edff1-0d95-45a3-9a01-39c419bec55a", - "underlay_address": "fd00:1122:3344:120::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::b]:32345", - "dataset": { - "pool_name": "oxp_0b11e026-f265-49a0-935f-7b234c19c789" - } - } - }, - "root": "/pool/ext/35db8700-d6a7-498c-9d2c-08eb9ab41b7c/crypt/zone" - }, - { - "zone": { - "id": "f8cc1c1e-a556-436c-836d-42052101c38a", - "underlay_address": "fd00:1122:3344:120::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::3]:32345", - "dataset": { - "pool_name": "oxp_ed8e5a26-5591-405a-b792-408f5b16e444" - } - } - }, - "root": "/pool/ext/1069bdee-fe5a-4164-a856-ff8ae56c07fb/crypt/zone" - }, - { - "zone": { - "id": "f9600313-fac0-45a1-a1b5-02dd6af468b9", - "underlay_address": "fd00:1122:3344:120::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::4]:32345", - "dataset": { - "pool_name": "oxp_c1f0a9e4-ea10-4fd9-8b6d-79a2bacfec5e" - } - } - }, - "root": "/pool/ext/74046573-78a2-46b4-86dc-40bb2ee29dd5/crypt/zone" - }, - { - "zone": { - "id": "869e4f7c-5312-4b98-bacc-1508f236bf5a", - "underlay_address": "fd00:1122:3344:120::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::6]:32345", - "dataset": { - "pool_name": "oxp_04aea8dc-4316-432f-a13a-d7d9b2efa3f2" - } - } - }, - "root": "/pool/ext/0b11e026-f265-49a0-935f-7b234c19c789/crypt/zone" - }, - { - "zone": { - "id": "31ed5a0c-7caf-4825-b730-85ee94fe27f1", - "underlay_address": "fd00:1122:3344:120::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::a]:32345", - "dataset": { - "pool_name": "oxp_86cd16cf-d00d-40bc-b14a-8220b1e11476" - } - } - }, - "root": "/pool/ext/04aea8dc-4316-432f-a13a-d7d9b2efa3f2/crypt/zone" - }, - { - "zone": { - "id": "7e5a3c39-152a-4270-b01e-9e144cca4aaa", - "underlay_address": "fd00:1122:3344:120::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::5]:32345", - "dataset": { - "pool_name": "oxp_1069bdee-fe5a-4164-a856-ff8ae56c07fb" - } - } - }, - "root": "/pool/ext/04aea8dc-4316-432f-a13a-d7d9b2efa3f2/crypt/zone" - }, - { - "zone": { - "id": "9a03a386-7304-4a86-bee8-153ef643195e", - "underlay_address": "fd00:1122:3344:120::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:120::7]:32345", - "dataset": { - "pool_name": "oxp_35db8700-d6a7-498c-9d2c-08eb9ab41b7c" - } - } - }, - "root": "/pool/ext/068d2790-1044-41ed-97a5-b493490b14d1/crypt/zone" - }, - { - "zone": { - "id": "a800d0a7-1020-481c-8be8-ecfd28b7a2be", - "underlay_address": "fd00:1122:3344:120::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:120::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/c1f0a9e4-ea10-4fd9-8b6d-79a2bacfec5e/crypt/zone" - }, - { - "zone": { - "id": "be469efd-8e07-4b8e-bcee-6fd33373cdef", - "underlay_address": "fd00:1122:3344:3::1", - "zone_type": { - "type": "internal_dns", - "dataset": { - "pool_name": "oxp_ed8e5a26-5591-405a-b792-408f5b16e444" - }, - "http_address": "[fd00:1122:3344:3::1]:5353", - "dns_address": "[fd00:1122:3344:3::1]:53", - "gz_address": "fd00:1122:3344:3::2", - "gz_address_index": 2 - } - }, - "root": "/pool/ext/068d2790-1044-41ed-97a5-b493490b14d1/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json deleted file mode 100644 index 5da6d95389..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "19d091b8-e005-4ff4-97e1-026de95e3667", - "underlay_address": "fd00:1122:3344:10f::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::c]:32345", - "dataset": { - "pool_name": "oxp_11a63469-4f57-4976-8620-0055bf82dc97" - } - } - }, - "root": "/pool/ext/6a73a62c-c636-4557-af45-042cb287aee6/crypt/zone" - }, - { - "zone": { - "id": "57d77171-104e-4977-b2f9-9b529ee7f8a0", - "underlay_address": "fd00:1122:3344:10f::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::8]:32345", - "dataset": { - "pool_name": "oxp_7f3060af-058f-4f52-ab80-902bd13e7ef4" - } - } - }, - "root": "/pool/ext/7f3060af-058f-4f52-ab80-902bd13e7ef4/crypt/zone" - }, - { - "zone": { - "id": "b0371ccf-67da-4562-baf2-eaabe5243e9b", - "underlay_address": "fd00:1122:3344:10f::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::7]:32345", - "dataset": { - "pool_name": "oxp_58ae04cb-26ff-4e30-a20d-9f847bafba4d" - } - } - }, - "root": "/pool/ext/125ddcda-f94b-46bc-a10a-94e9acf40265/crypt/zone" - }, - { - "zone": { - "id": "ae3791ff-2657-4252-bd61-58ec5dc237cd", - "underlay_address": "fd00:1122:3344:10f::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::9]:32345", - "dataset": { - "pool_name": "oxp_125ddcda-f94b-46bc-a10a-94e9acf40265" - } - } - }, - "root": "/pool/ext/58ae04cb-26ff-4e30-a20d-9f847bafba4d/crypt/zone" - }, - { - "zone": { - "id": "73f865dc-5db7-48c6-9dc4-dff56dd8c045", - "underlay_address": "fd00:1122:3344:10f::3", - "zone_type": { - "type": "crucible_pantry", - "address": "[fd00:1122:3344:10f::3]:17000" - } - }, - "root": "/pool/ext/11a63469-4f57-4976-8620-0055bf82dc97/crypt/zone" - }, - { - "zone": { - "id": "e5d0170a-0d60-4c51-8f72-4c301979690e", - "underlay_address": "fd00:1122:3344:10f::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::6]:32345", - "dataset": { - "pool_name": "oxp_efe4cbab-2a39-4d7d-ae6c-83eb3ab8d4b5" - } - } - }, - "root": "/pool/ext/6a73a62c-c636-4557-af45-042cb287aee6/crypt/zone" - }, - { - "zone": { - "id": "ea6894de-c575-43bc-86e9-65b8a58499ff", - "underlay_address": "fd00:1122:3344:10f::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::a]:32345", - "dataset": { - "pool_name": "oxp_a87dc882-8b88-4a99-9628-5db79072cffa" - } - } - }, - "root": "/pool/ext/11a63469-4f57-4976-8620-0055bf82dc97/crypt/zone" - }, - { - "zone": { - "id": "3081dc99-4fa9-4238-adfa-b9ca381c1f7b", - "underlay_address": "fd00:1122:3344:10f::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::b]:32345", - "dataset": { - "pool_name": "oxp_6a73a62c-c636-4557-af45-042cb287aee6" - } - } - }, - "root": "/pool/ext/a87dc882-8b88-4a99-9628-5db79072cffa/crypt/zone" - }, - { - "zone": { - "id": "b4a3d7c8-487d-4d76-ae4e-a6a51595a5a6", - "underlay_address": "fd00:1122:3344:10f::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::d]:32345", - "dataset": { - "pool_name": "oxp_a12f87ee-9918-4269-9de4-4bad4fb41caa" - } - } - }, - "root": "/pool/ext/a12f87ee-9918-4269-9de4-4bad4fb41caa/crypt/zone" - }, - { - "zone": { - "id": "5ebcee26-f76c-4206-8d81-584ac138d3b9", - "underlay_address": "fd00:1122:3344:10f::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::4]:32345", - "dataset": { - "pool_name": "oxp_27f1917e-fb69-496a-9d40-8ef0d0c0ee55" - } - } - }, - "root": "/pool/ext/58ae04cb-26ff-4e30-a20d-9f847bafba4d/crypt/zone" - }, - { - "zone": { - "id": "90b2bc57-3a2a-4117-bb6d-7eda7542329a", - "underlay_address": "fd00:1122:3344:10f::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10f::5]:32345", - "dataset": { - "pool_name": "oxp_a222e405-40f6-4fdd-9146-94f7d94ed08a" - } - } - }, - "root": "/pool/ext/a12f87ee-9918-4269-9de4-4bad4fb41caa/crypt/zone" - }, - { - "zone": { - "id": "0fb540af-58d3-4abc-bfad-e49765c2b1ee", - "underlay_address": "fd00:1122:3344:10f::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:10f::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/58ae04cb-26ff-4e30-a20d-9f847bafba4d/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json deleted file mode 100644 index c92a638b85..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "dda0f1c6-84a5-472c-b350-a799c8d3d0eb", - "underlay_address": "fd00:1122:3344:115::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::8]:32345", - "dataset": { - "pool_name": "oxp_028b6c9e-5a0e-43d2-a8ed-a5946cf62924" - } - } - }, - "root": "/pool/ext/b8d84b9c-a65e-4c86-8196-69da5317ae63/crypt/zone" - }, - { - "zone": { - "id": "157672f9-113f-48b7-9808-dff3c3e67dcd", - "underlay_address": "fd00:1122:3344:115::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::a]:32345", - "dataset": { - "pool_name": "oxp_4fdca201-b37e-4072-a1cc-3cb7705954eb" - } - } - }, - "root": "/pool/ext/b8d84b9c-a65e-4c86-8196-69da5317ae63/crypt/zone" - }, - { - "zone": { - "id": "5a7d4f67-a70f-4d8b-8d35-4dc600991fb5", - "underlay_address": "fd00:1122:3344:115::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::5]:32345", - "dataset": { - "pool_name": "oxp_11a991e5-19a9-48b0-8186-34249ef67957" - } - } - }, - "root": "/pool/ext/1e9c9764-aaa4-4681-b110-a937b4c52748/crypt/zone" - }, - { - "zone": { - "id": "c7036645-b680-4816-834f-8ae1af24c159", - "underlay_address": "fd00:1122:3344:115::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::b]:32345", - "dataset": { - "pool_name": "oxp_0780be56-c13d-4c6a-a1ac-37753a0da820" - } - } - }, - "root": "/pool/ext/80a8d756-ee22-4c88-8b5b-4a46f7eca249/crypt/zone" - }, - { - "zone": { - "id": "45e47e4b-708f-40b5-a8c8-fbfd73696d45", - "underlay_address": "fd00:1122:3344:115::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::7]:32345", - "dataset": { - "pool_name": "oxp_80a8d756-ee22-4c88-8b5b-4a46f7eca249" - } - } - }, - "root": "/pool/ext/4fdca201-b37e-4072-a1cc-3cb7705954eb/crypt/zone" - }, - { - "zone": { - "id": "e805b0c1-3f80-49da-8dc1-caaf843e5003", - "underlay_address": "fd00:1122:3344:115::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::c]:32345", - "dataset": { - "pool_name": "oxp_d54e1ed7-e589-4413-a487-6e9a257104e7" - } - } - }, - "root": "/pool/ext/d54e1ed7-e589-4413-a487-6e9a257104e7/crypt/zone" - }, - { - "zone": { - "id": "e47d3f81-3df6-4c35-bec6-41277bc74c07", - "underlay_address": "fd00:1122:3344:115::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::4]:32345", - "dataset": { - "pool_name": "oxp_b8d84b9c-a65e-4c86-8196-69da5317ae63" - } - } - }, - "root": "/pool/ext/772b3aaa-3501-4dc7-9b3d-048b8b1f7970/crypt/zone" - }, - { - "zone": { - "id": "2a796a69-b061-44c7-b2df-35bc611f10f5", - "underlay_address": "fd00:1122:3344:115::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::6]:32345", - "dataset": { - "pool_name": "oxp_73abe9e0-d38e-48fc-bdec-b094bfa5670d" - } - } - }, - "root": "/pool/ext/028b6c9e-5a0e-43d2-a8ed-a5946cf62924/crypt/zone" - }, - { - "zone": { - "id": "4e1d2af1-8ef4-4762-aa80-b08da08b45bb", - "underlay_address": "fd00:1122:3344:115::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::3]:32345", - "dataset": { - "pool_name": "oxp_772b3aaa-3501-4dc7-9b3d-048b8b1f7970" - } - } - }, - "root": "/pool/ext/d54e1ed7-e589-4413-a487-6e9a257104e7/crypt/zone" - }, - { - "zone": { - "id": "fb1b10d5-b7cb-416d-98fc-b5d3bc02d495", - "underlay_address": "fd00:1122:3344:115::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:115::9]:32345", - "dataset": { - "pool_name": "oxp_1e9c9764-aaa4-4681-b110-a937b4c52748" - } - } - }, - "root": "/pool/ext/b8d84b9c-a65e-4c86-8196-69da5317ae63/crypt/zone" - }, - { - "zone": { - "id": "5155463c-8a09-45a5-ad1b-817f2e93b284", - "underlay_address": "fd00:1122:3344:115::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:115::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/772b3aaa-3501-4dc7-9b3d-048b8b1f7970/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json deleted file mode 100644 index 5e38262740..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "a0eae689-8e6b-4297-bb3d-8b7ffc5c4a07", - "underlay_address": "fd00:1122:3344:102::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::c]:32345", - "dataset": { - "pool_name": "oxp_274cb567-fd74-4e00-b9c7-6ca367b3fda4" - } - } - }, - "root": "/pool/ext/1443b190-de16-42b0-b881-e87e875dd507/crypt/zone" - }, - { - "zone": { - "id": "9cea406d-451e-4328-9052-b58487f799a5", - "underlay_address": "fd00:1122:3344:102::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::b]:32345", - "dataset": { - "pool_name": "oxp_89c7f72e-632c-462b-a515-01cd80683711" - } - } - }, - "root": "/pool/ext/274cb567-fd74-4e00-b9c7-6ca367b3fda4/crypt/zone" - }, - { - "zone": { - "id": "9c7dad7e-7f60-4bf4-8efc-0883a17e7cf6", - "underlay_address": "fd00:1122:3344:102::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::6]:32345", - "dataset": { - "pool_name": "oxp_2c8e5637-b989-4b8f-82ac-ff2e9102b560" - } - } - }, - "root": "/pool/ext/1443b190-de16-42b0-b881-e87e875dd507/crypt/zone" - }, - { - "zone": { - "id": "73015cba-79c6-4a67-97d8-fa0819cbf750", - "underlay_address": "fd00:1122:3344:102::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::a]:32345", - "dataset": { - "pool_name": "oxp_fa62108e-f7bb-4f6d-86f3-8094a1ea8352" - } - } - }, - "root": "/pool/ext/2c8e5637-b989-4b8f-82ac-ff2e9102b560/crypt/zone" - }, - { - "zone": { - "id": "f9ca3097-072e-4e7f-9f50-eb7c7ae39b6f", - "underlay_address": "fd00:1122:3344:102::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::5]:32345", - "dataset": { - "pool_name": "oxp_42c6602c-2ccf-48ce-8344-693c832fd693" - } - } - }, - "root": "/pool/ext/2c8e5637-b989-4b8f-82ac-ff2e9102b560/crypt/zone" - }, - { - "zone": { - "id": "e7855e05-a125-4a80-ac2c-8a2db96e1bf8", - "underlay_address": "fd00:1122:3344:102::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::7]:32345", - "dataset": { - "pool_name": "oxp_1f72afd3-d2aa-46a8-b81a-54dbcc2f6317" - } - } - }, - "root": "/pool/ext/42c6602c-2ccf-48ce-8344-693c832fd693/crypt/zone" - }, - { - "zone": { - "id": "e5de9bc9-e996-4fea-8318-ad7a8a6be4a3", - "underlay_address": "fd00:1122:3344:102::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::4]:32345", - "dataset": { - "pool_name": "oxp_1443b190-de16-42b0-b881-e87e875dd507" - } - } - }, - "root": "/pool/ext/89c7f72e-632c-462b-a515-01cd80683711/crypt/zone" - }, - { - "zone": { - "id": "cd0d0aac-44ff-4566-9260-a64ae6cecef4", - "underlay_address": "fd00:1122:3344:102::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::8]:32345", - "dataset": { - "pool_name": "oxp_92c0d1f6-cb4d-4ddb-b5ba-979fb3491812" - } - } - }, - "root": "/pool/ext/89c7f72e-632c-462b-a515-01cd80683711/crypt/zone" - }, - { - "zone": { - "id": "a8230592-0e7a-46c8-a653-7587a27f05bf", - "underlay_address": "fd00:1122:3344:102::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::9]:32345", - "dataset": { - "pool_name": "oxp_1b7873de-99fd-454f-b576-bff695524133" - } - } - }, - "root": "/pool/ext/92c0d1f6-cb4d-4ddb-b5ba-979fb3491812/crypt/zone" - }, - { - "zone": { - "id": "c19ffbb1-4dc1-4825-a3cf-080e9b543b16", - "underlay_address": "fd00:1122:3344:102::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:102::d]:32345", - "dataset": { - "pool_name": "oxp_67823df7-511c-4984-b98c-7a8f5c40c22d" - } - } - }, - "root": "/pool/ext/1443b190-de16-42b0-b881-e87e875dd507/crypt/zone" - }, - { - "zone": { - "id": "ff30fe7c-51f3-43b9-a788-d8f94a7bb028", - "underlay_address": "fd00:1122:3344:102::3", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:102::3]:32221", - "dataset": { - "pool_name": "oxp_1443b190-de16-42b0-b881-e87e875dd507" - } - } - }, - "root": "/pool/ext/fa62108e-f7bb-4f6d-86f3-8094a1ea8352/crypt/zone" - }, - { - "zone": { - "id": "16b50c55-8117-4efd-aabf-0273677b89d5", - "underlay_address": "fd00:1122:3344:102::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:102::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/fa62108e-f7bb-4f6d-86f3-8094a1ea8352/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json deleted file mode 100644 index 7c1d269d61..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "22452953-ee80-4659-a555-8e027bf205b0", - "underlay_address": "fd00:1122:3344:10c::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::4]:32345", - "dataset": { - "pool_name": "oxp_92ba1667-a6f7-4913-9b00-14825384c7bf" - } - } - }, - "root": "/pool/ext/ab62b941-5f84-42c7-929d-295b20efffe7/crypt/zone" - }, - { - "zone": { - "id": "9a5a2fcf-44a0-4468-979a-a71686cef627", - "underlay_address": "fd00:1122:3344:10c::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::3]:32345", - "dataset": { - "pool_name": "oxp_dbfdc981-1b81-4d7d-9449-9530890b199a" - } - } - }, - "root": "/pool/ext/74ac4da9-cdae-4c08-8431-11211184aa09/crypt/zone" - }, - { - "zone": { - "id": "a014f12e-2636-4258-af76-e01d9b8d1c1f", - "underlay_address": "fd00:1122:3344:10c::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::b]:32345", - "dataset": { - "pool_name": "oxp_ab62b941-5f84-42c7-929d-295b20efffe7" - } - } - }, - "root": "/pool/ext/a624a843-1c4e-41c3-a1d2-4be7a6c57e9b/crypt/zone" - }, - { - "zone": { - "id": "431768b8-26ba-4ab4-b616-9e183bb79b8b", - "underlay_address": "fd00:1122:3344:10c::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::7]:32345", - "dataset": { - "pool_name": "oxp_7c121177-3210-4457-9b42-3657add6e166" - } - } - }, - "root": "/pool/ext/74ac4da9-cdae-4c08-8431-11211184aa09/crypt/zone" - }, - { - "zone": { - "id": "22992c56-bd5a-4d0f-86c5-d6f8e87b7bbb", - "underlay_address": "fd00:1122:3344:10c::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::9]:32345", - "dataset": { - "pool_name": "oxp_842bdd28-196e-4b18-83db-68bd81176a44" - } - } - }, - "root": "/pool/ext/74ac4da9-cdae-4c08-8431-11211184aa09/crypt/zone" - }, - { - "zone": { - "id": "de376149-aa45-4660-9ae6-15e8ba4a4233", - "underlay_address": "fd00:1122:3344:10c::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::5]:32345", - "dataset": { - "pool_name": "oxp_25856a84-6707-4b94-81d1-b43d5bc990d7" - } - } - }, - "root": "/pool/ext/7c121177-3210-4457-9b42-3657add6e166/crypt/zone" - }, - { - "zone": { - "id": "ceeba69d-8c0a-47df-a37b-7f1b90f23016", - "underlay_address": "fd00:1122:3344:10c::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::a]:32345", - "dataset": { - "pool_name": "oxp_a624a843-1c4e-41c3-a1d2-4be7a6c57e9b" - } - } - }, - "root": "/pool/ext/74ac4da9-cdae-4c08-8431-11211184aa09/crypt/zone" - }, - { - "zone": { - "id": "65293ce4-2e63-4336-9207-3c61f58667f9", - "underlay_address": "fd00:1122:3344:10c::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::c]:32345", - "dataset": { - "pool_name": "oxp_74ac4da9-cdae-4c08-8431-11211184aa09" - } - } - }, - "root": "/pool/ext/842bdd28-196e-4b18-83db-68bd81176a44/crypt/zone" - }, - { - "zone": { - "id": "e8f55a5d-65f9-436c-bc25-1d1a7070e876", - "underlay_address": "fd00:1122:3344:10c::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::6]:32345", - "dataset": { - "pool_name": "oxp_9bfe385c-16dd-4209-bc0b-f28ae75d58e3" - } - } - }, - "root": "/pool/ext/92ba1667-a6f7-4913-9b00-14825384c7bf/crypt/zone" - }, - { - "zone": { - "id": "2dfbd4c6-afbf-4c8c-bf40-764f02727852", - "underlay_address": "fd00:1122:3344:10c::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10c::8]:32345", - "dataset": { - "pool_name": "oxp_55eb093d-6b6f-418c-9767-09afe4c51fff" - } - } - }, - "root": "/pool/ext/dbfdc981-1b81-4d7d-9449-9530890b199a/crypt/zone" - }, - { - "zone": { - "id": "8c73baf7-1a58-4e2c-b4d1-966c89a18d03", - "underlay_address": "fd00:1122:3344:10c::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:10c::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/842bdd28-196e-4b18-83db-68bd81176a44/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json deleted file mode 100644 index acbfa17eda..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "2f488e7b-fd93-48a6-8b2b-61f6e8336268", - "underlay_address": "fd00:1122:3344:101::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::b]:32345", - "dataset": { - "pool_name": "oxp_5840a3b7-f765-45d3-8a41-7f543f936bee" - } - } - }, - "root": "/pool/ext/dd084b76-1130-4ad3-9196-6b02be607fe9/crypt/zone" - }, - { - "zone": { - "id": "1ed5fd3f-933a-4921-a91f-5c286823f8d4", - "underlay_address": "fd00:1122:3344:101::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::a]:32345", - "dataset": { - "pool_name": "oxp_c1e807e7-b64a-4dbd-b845-ffed0b9a54f1" - } - } - }, - "root": "/pool/ext/be06ea9c-df86-4fec-b5dd-8809710893af/crypt/zone" - }, - { - "zone": { - "id": "0f8f1013-465d-4b49-b55d-f0b9bf6f789a", - "underlay_address": "fd00:1122:3344:101::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::6]:32345", - "dataset": { - "pool_name": "oxp_4dfa7003-0305-47f5-b23d-88a228c1e12e" - } - } - }, - "root": "/pool/ext/be06ea9c-df86-4fec-b5dd-8809710893af/crypt/zone" - }, - { - "zone": { - "id": "2e4ef017-6c62-40bc-bab5-f2e01addad22", - "underlay_address": "fd00:1122:3344:101::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::7]:32345", - "dataset": { - "pool_name": "oxp_d94e9c58-e6d1-444b-b7d8-19ac17dea042" - } - } - }, - "root": "/pool/ext/c1e807e7-b64a-4dbd-b845-ffed0b9a54f1/crypt/zone" - }, - { - "zone": { - "id": "6a0baf13-a80b-4778-a0ab-a69cd851de2d", - "underlay_address": "fd00:1122:3344:101::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::9]:32345", - "dataset": { - "pool_name": "oxp_be06ea9c-df86-4fec-b5dd-8809710893af" - } - } - }, - "root": "/pool/ext/a9d419d4-5915-4a40-baa3-3512785de034/crypt/zone" - }, - { - "zone": { - "id": "391ec257-fd47-4cc8-9bfa-49a0747a9a67", - "underlay_address": "fd00:1122:3344:101::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::8]:32345", - "dataset": { - "pool_name": "oxp_a9d419d4-5915-4a40-baa3-3512785de034" - } - } - }, - "root": "/pool/ext/709d5d04-5dff-4558-8b5d-fbc2a7d83036/crypt/zone" - }, - { - "zone": { - "id": "fd8e615a-f170-4da9-b8d0-2a5a123d8682", - "underlay_address": "fd00:1122:3344:101::3", - "zone_type": { - "type": "crucible_pantry", - "address": "[fd00:1122:3344:101::3]:17000" - } - }, - "root": "/pool/ext/dd084b76-1130-4ad3-9196-6b02be607fe9/crypt/zone" - }, - { - "zone": { - "id": "f8a793f4-cd08-49ec-8fee-6bcd37092fdc", - "underlay_address": "fd00:1122:3344:101::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::c]:32345", - "dataset": { - "pool_name": "oxp_709d5d04-5dff-4558-8b5d-fbc2a7d83036" - } - } - }, - "root": "/pool/ext/d94e9c58-e6d1-444b-b7d8-19ac17dea042/crypt/zone" - }, - { - "zone": { - "id": "c67d44be-d6b8-4a08-a7e0-3ab300749ad6", - "underlay_address": "fd00:1122:3344:101::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::4]:32345", - "dataset": { - "pool_name": "oxp_231cd696-2839-4a9a-ae42-6d875a98a797" - } - } - }, - "root": "/pool/ext/709d5d04-5dff-4558-8b5d-fbc2a7d83036/crypt/zone" - }, - { - "zone": { - "id": "e91b4957-8165-451d-9fa5-090c3a39f199", - "underlay_address": "fd00:1122:3344:101::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::d]:32345", - "dataset": { - "pool_name": "oxp_dd084b76-1130-4ad3-9196-6b02be607fe9" - } - } - }, - "root": "/pool/ext/5840a3b7-f765-45d3-8a41-7f543f936bee/crypt/zone" - }, - { - "zone": { - "id": "5e737b6e-d33d-4a2c-b8c0-3cad9d05a68f", - "underlay_address": "fd00:1122:3344:101::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:101::5]:32345", - "dataset": { - "pool_name": "oxp_8fa4f837-c6f3-4c65-88d4-21eb3cd7ffee" - } - } - }, - "root": "/pool/ext/dd084b76-1130-4ad3-9196-6b02be607fe9/crypt/zone" - }, - { - "zone": { - "id": "7e6b7816-b1a6-40f3-894a-a5d5c0571dbb", - "underlay_address": "fd00:1122:3344:101::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:101::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/be06ea9c-df86-4fec-b5dd-8809710893af/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json deleted file mode 100644 index ce4b6f03cd..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "eafffae7-69fd-49e1-9541-7cf237ab12b3", - "underlay_address": "fd00:1122:3344:110::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::3]:32345", - "dataset": { - "pool_name": "oxp_929404cd-2522-4440-b21c-91d466a9a7e0" - } - } - }, - "root": "/pool/ext/aff390ed-8d70-49fa-9000-5420b54ab118/crypt/zone" - }, - { - "zone": { - "id": "f4bccf15-d69f-402d-9bd2-7959a4cb2823", - "underlay_address": "fd00:1122:3344:110::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::9]:32345", - "dataset": { - "pool_name": "oxp_f80f96be-a3d7-490a-96a7-faf7da80a579" - } - } - }, - "root": "/pool/ext/6bcd54c8-d4a8-429d-8f17-cf02615eb063/crypt/zone" - }, - { - "zone": { - "id": "82e51c9d-c187-4baa-8307-e46eeafc5ff2", - "underlay_address": "fd00:1122:3344:110::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::5]:32345", - "dataset": { - "pool_name": "oxp_37d86199-6834-49d9-888a-88ff6f281b29" - } - } - }, - "root": "/pool/ext/d2e27e2a-2deb-42ae-84a7-c2d06f3aeb4f/crypt/zone" - }, - { - "zone": { - "id": "cf667caf-304c-40c4-acce-f0eb05d011ef", - "underlay_address": "fd00:1122:3344:110::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::8]:32345", - "dataset": { - "pool_name": "oxp_625c0110-644e-4d63-8321-b85ab5642260" - } - } - }, - "root": "/pool/ext/d2e27e2a-2deb-42ae-84a7-c2d06f3aeb4f/crypt/zone" - }, - { - "zone": { - "id": "14e60912-108e-4dd3-984e-2332a183b346", - "underlay_address": "fd00:1122:3344:110::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::b]:32345", - "dataset": { - "pool_name": "oxp_fa6470f5-0a4c-4fef-b0b1-57c8749c6cca" - } - } - }, - "root": "/pool/ext/6c5ab641-3bd4-4d8c-96f4-4f56c1045142/crypt/zone" - }, - { - "zone": { - "id": "1aacf923-c96f-4bab-acb0-63f28e86eef6", - "underlay_address": "fd00:1122:3344:110::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::c]:32345", - "dataset": { - "pool_name": "oxp_21b0f3ed-d27f-4996-968b-bf2b494d9308" - } - } - }, - "root": "/pool/ext/625c0110-644e-4d63-8321-b85ab5642260/crypt/zone" - }, - { - "zone": { - "id": "b9db0845-04d3-4dc1-84ba-224749562a6c", - "underlay_address": "fd00:1122:3344:110::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::6]:32345", - "dataset": { - "pool_name": "oxp_d2e27e2a-2deb-42ae-84a7-c2d06f3aeb4f" - } - } - }, - "root": "/pool/ext/aff390ed-8d70-49fa-9000-5420b54ab118/crypt/zone" - }, - { - "zone": { - "id": "38b51865-ee80-4e1b-a40b-3452951f9022", - "underlay_address": "fd00:1122:3344:110::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::7]:32345", - "dataset": { - "pool_name": "oxp_6bcd54c8-d4a8-429d-8f17-cf02615eb063" - } - } - }, - "root": "/pool/ext/37d86199-6834-49d9-888a-88ff6f281b29/crypt/zone" - }, - { - "zone": { - "id": "4bc441f6-f7e5-4d68-8751-53ef1e251c47", - "underlay_address": "fd00:1122:3344:110::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::a]:32345", - "dataset": { - "pool_name": "oxp_6c5ab641-3bd4-4d8c-96f4-4f56c1045142" - } - } - }, - "root": "/pool/ext/21b0f3ed-d27f-4996-968b-bf2b494d9308/crypt/zone" - }, - { - "zone": { - "id": "d2c20cf8-ed4c-4815-add9-45996364f721", - "underlay_address": "fd00:1122:3344:110::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:110::4]:32345", - "dataset": { - "pool_name": "oxp_aff390ed-8d70-49fa-9000-5420b54ab118" - } - } - }, - "root": "/pool/ext/6c5ab641-3bd4-4d8c-96f4-4f56c1045142/crypt/zone" - }, - { - "zone": { - "id": "1bb548cb-889a-411e-8c67-d1b785225180", - "underlay_address": "fd00:1122:3344:110::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:110::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/6bcd54c8-d4a8-429d-8f17-cf02615eb063/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json deleted file mode 100644 index 62653d0767..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "2eb74fa3-71ec-484c-8ffa-3daeab0e4c78", - "underlay_address": "fd00:1122:3344:11d::3", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::3]:32345", - "dataset": { - "pool_name": "oxp_c6b63fea-e3e2-4806-b8dc-bdfe7b5c3d89" - } - } - }, - "root": "/pool/ext/9f20cbae-7a63-4c31-9386-2ac3cbe12030/crypt/zone" - }, - { - "zone": { - "id": "9f92bfcf-7435-44a6-8e77-0597f93cd0b4", - "underlay_address": "fd00:1122:3344:11d::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::7]:32345", - "dataset": { - "pool_name": "oxp_9fa336f1-2b69-4ebf-9553-e3bab7e3e6ef" - } - } - }, - "root": "/pool/ext/e05a6264-63f2-4961-bc14-57b4f65614c0/crypt/zone" - }, - { - "zone": { - "id": "1bf9aed4-9fd3-4d87-b8e7-7f066d25ec1d", - "underlay_address": "fd00:1122:3344:11d::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::b]:32345", - "dataset": { - "pool_name": "oxp_a5a52f47-9c9a-4519-83dc-abc56619495d" - } - } - }, - "root": "/pool/ext/cbcad26e-5e52-41b7-9875-1a84d30d8a15/crypt/zone" - }, - { - "zone": { - "id": "2a722aa7-cd8a-445d-83fe-57fc9b9a8249", - "underlay_address": "fd00:1122:3344:11d::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::8]:32345", - "dataset": { - "pool_name": "oxp_1f4b71eb-505f-4706-912c-b13dd3f2eafb" - } - } - }, - "root": "/pool/ext/a5a52f47-9c9a-4519-83dc-abc56619495d/crypt/zone" - }, - { - "zone": { - "id": "76af5b23-d833-435c-b848-2a09d9fad9a1", - "underlay_address": "fd00:1122:3344:11d::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::c]:32345", - "dataset": { - "pool_name": "oxp_cbcad26e-5e52-41b7-9875-1a84d30d8a15" - } - } - }, - "root": "/pool/ext/9f20cbae-7a63-4c31-9386-2ac3cbe12030/crypt/zone" - }, - { - "zone": { - "id": "3a412bf4-a385-4e66-9ada-a87f6536d6ca", - "underlay_address": "fd00:1122:3344:11d::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::4]:32345", - "dataset": { - "pool_name": "oxp_e05a6264-63f2-4961-bc14-57b4f65614c0" - } - } - }, - "root": "/pool/ext/e05a6264-63f2-4961-bc14-57b4f65614c0/crypt/zone" - }, - { - "zone": { - "id": "99a25fa7-8231-4a46-a6ec-ffc5281db1f8", - "underlay_address": "fd00:1122:3344:11d::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::5]:32345", - "dataset": { - "pool_name": "oxp_722494ab-9a2b-481b-ac11-292fded682a5" - } - } - }, - "root": "/pool/ext/e05a6264-63f2-4961-bc14-57b4f65614c0/crypt/zone" - }, - { - "zone": { - "id": "06c7ddc8-9b3e-48ef-9874-0c40874e9877", - "underlay_address": "fd00:1122:3344:11d::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::a]:32345", - "dataset": { - "pool_name": "oxp_8c3972d1-5b17-4479-88cc-1c33e4344160" - } - } - }, - "root": "/pool/ext/8c3972d1-5b17-4479-88cc-1c33e4344160/crypt/zone" - }, - { - "zone": { - "id": "1212b2dc-157d-4bd3-94af-fb5db1d91f24", - "underlay_address": "fd00:1122:3344:11d::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::9]:32345", - "dataset": { - "pool_name": "oxp_9f20cbae-7a63-4c31-9386-2ac3cbe12030" - } - } - }, - "root": "/pool/ext/977aa6c3-2026-4178-9948-e09f78008575/crypt/zone" - }, - { - "zone": { - "id": "b1fb5f2e-b20d-4f4c-9f6f-bbeb1a98dd50", - "underlay_address": "fd00:1122:3344:11d::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:11d::6]:32345", - "dataset": { - "pool_name": "oxp_977aa6c3-2026-4178-9948-e09f78008575" - } - } - }, - "root": "/pool/ext/722494ab-9a2b-481b-ac11-292fded682a5/crypt/zone" - }, - { - "zone": { - "id": "e68dde0f-0647-46db-ae1c-711835c13e25", - "underlay_address": "fd00:1122:3344:11d::d", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:11d::d]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/1f4b71eb-505f-4706-912c-b13dd3f2eafb/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json deleted file mode 100644 index b848826231..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json +++ /dev/null @@ -1,198 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "85c18b7c-a100-458c-b18d-ecfdacaefac4", - "underlay_address": "fd00:1122:3344:10e::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::5]:32345", - "dataset": { - "pool_name": "oxp_07b266bc-86c3-4a76-9522-8b34ba1ae78c" - } - } - }, - "root": "/pool/ext/5b88e44e-f886-4de8-8a6b-48ea5ed9d70b/crypt/zone" - }, - { - "zone": { - "id": "db303465-7879-4d86-8da8-a0c7162e5184", - "underlay_address": "fd00:1122:3344:10e::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::4]:32345", - "dataset": { - "pool_name": "oxp_e9488a32-880d-44a2-8948-db0b7e3a35b5" - } - } - }, - "root": "/pool/ext/8d798756-7200-4db4-9faf-f41b75106a63/crypt/zone" - }, - { - "zone": { - "id": "c44ce6be-512d-4104-9260-a5b8fe373937", - "underlay_address": "fd00:1122:3344:10e::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::9]:32345", - "dataset": { - "pool_name": "oxp_025dfc06-5aeb-407f-adc8-ba18dc9bba35" - } - } - }, - "root": "/pool/ext/1544ce68-3544-4cba-b3b6-1927d08b78a5/crypt/zone" - }, - { - "zone": { - "id": "1cfdb5b6-e568-436a-a85f-7fecf1b8eef2", - "underlay_address": "fd00:1122:3344:10e::3", - "zone_type": { - "type": "nexus", - "internal_address": "[fd00:1122:3344:10e::3]:12221", - "external_ip": "45.154.216.36", - "nic": { - "id": "569754a2-a5e0-4aa8-90a7-2fa65f43b667", - "kind": { - "type": "service", - "id": "1cfdb5b6-e568-436a-a85f-7fecf1b8eef2" - }, - "name": "nexus-1cfdb5b6-e568-436a-a85f-7fecf1b8eef2", - "ip": "172.30.2.6", - "mac": "A8:40:25:FF:EC:6B", - "subnet": "172.30.2.0/24", - "vni": 100, - "primary": true, - "slot": 0 - }, - "external_tls": true, - "external_dns_servers": [ - "1.1.1.1", - "8.8.8.8" - ] - } - }, - "root": "/pool/ext/025dfc06-5aeb-407f-adc8-ba18dc9bba35/crypt/zone" - }, - { - "zone": { - "id": "44a68792-ca14-442e-b7a9-11970d50ba0e", - "underlay_address": "fd00:1122:3344:10e::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::a]:32345", - "dataset": { - "pool_name": "oxp_2a492098-7df3-4409-9466-561edb7aa99b" - } - } - }, - "root": "/pool/ext/1544ce68-3544-4cba-b3b6-1927d08b78a5/crypt/zone" - }, - { - "zone": { - "id": "514cf0ca-6d23-434e-9785-446b83b2f029", - "underlay_address": "fd00:1122:3344:10e::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::7]:32345", - "dataset": { - "pool_name": "oxp_5b88e44e-f886-4de8-8a6b-48ea5ed9d70b" - } - } - }, - "root": "/pool/ext/5b88e44e-f886-4de8-8a6b-48ea5ed9d70b/crypt/zone" - }, - { - "zone": { - "id": "bc6d8347-8f64-4031-912c-932349df07fe", - "underlay_address": "fd00:1122:3344:10e::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::6]:32345", - "dataset": { - "pool_name": "oxp_1544ce68-3544-4cba-b3b6-1927d08b78a5" - } - } - }, - "root": "/pool/ext/1544ce68-3544-4cba-b3b6-1927d08b78a5/crypt/zone" - }, - { - "zone": { - "id": "1ab0a4f5-99ad-4341-8c89-7fd03e5ccb08", - "underlay_address": "fd00:1122:3344:10e::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::b]:32345", - "dataset": { - "pool_name": "oxp_033eb462-968f-42ce-9c29-377bd40a3014" - } - } - }, - "root": "/pool/ext/9e1a0803-7453-4eac-91c9-d7891ecd634f/crypt/zone" - }, - { - "zone": { - "id": "d6f2520b-3d04-44d9-bd46-6ffccfcb46d2", - "underlay_address": "fd00:1122:3344:10e::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::8]:32345", - "dataset": { - "pool_name": "oxp_36e8d29c-1e88-4c2b-8f59-f312201067c3" - } - } - }, - "root": "/pool/ext/1544ce68-3544-4cba-b3b6-1927d08b78a5/crypt/zone" - }, - { - "zone": { - "id": "d6da9d13-bfcf-469d-a99e-faeb5e30be32", - "underlay_address": "fd00:1122:3344:10e::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::c]:32345", - "dataset": { - "pool_name": "oxp_9e1a0803-7453-4eac-91c9-d7891ecd634f" - } - } - }, - "root": "/pool/ext/8d798756-7200-4db4-9faf-f41b75106a63/crypt/zone" - }, - { - "zone": { - "id": "a1dc59c2-5883-4fb8-83be-ac2d95d255d1", - "underlay_address": "fd00:1122:3344:10e::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10e::d]:32345", - "dataset": { - "pool_name": "oxp_8d798756-7200-4db4-9faf-f41b75106a63" - } - } - }, - "root": "/pool/ext/36e8d29c-1e88-4c2b-8f59-f312201067c3/crypt/zone" - }, - { - "zone": { - "id": "48f25dba-7392-44ce-9bb0-28489ebc44bc", - "underlay_address": "fd00:1122:3344:10e::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:10e::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/5b88e44e-f886-4de8-8a6b-48ea5ed9d70b/crypt/zone" - } - ] -} \ No newline at end of file diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json deleted file mode 100644 index 62d45a2f5a..0000000000 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "omicron_generation": 2, - "ledger_generation": 4, - "zones": [ - { - "zone": { - "id": "b452e5e1-ab4c-4994-9679-ef21b3b4fee9", - "underlay_address": "fd00:1122:3344:10b::6", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::6]:32345", - "dataset": { - "pool_name": "oxp_d63a297d-ae6a-4072-9dca-dda404044989" - } - } - }, - "root": "/pool/ext/7c204111-31df-4c32-9a3e-780411f700fd/crypt/zone" - }, - { - "zone": { - "id": "e9826cdc-6d3a-4eff-b1b5-ec4364ebe6b9", - "underlay_address": "fd00:1122:3344:10b::3", - "zone_type": { - "type": "oximeter", - "address": "[fd00:1122:3344:10b::3]:12223" - } - }, - "root": "/pool/ext/7c204111-31df-4c32-9a3e-780411f700fd/crypt/zone" - }, - { - "zone": { - "id": "b0cde4a8-f27c-46e8-8355-756be9045afc", - "underlay_address": "fd00:1122:3344:10b::b", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::b]:32345", - "dataset": { - "pool_name": "oxp_07c1a8e7-51f5-4f12-a43d-734719fef92b" - } - } - }, - "root": "/pool/ext/1f6adf64-c9b9-4ed7-b3e2-37fb25624646/crypt/zone" - }, - { - "zone": { - "id": "e2f70cf6-e285-4212-9b01-77ebf2ca9219", - "underlay_address": "fd00:1122:3344:10b::d", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::d]:32345", - "dataset": { - "pool_name": "oxp_a809f28a-7f25-4362-bc56-0cbdd72af2cb" - } - } - }, - "root": "/pool/ext/92a1bd39-6e8a-4226-b9d0-e3e8a9b8504f/crypt/zone" - }, - { - "zone": { - "id": "b0949c9d-4aa1-4bc4-9cb3-5875b9166885", - "underlay_address": "fd00:1122:3344:10b::a", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::a]:32345", - "dataset": { - "pool_name": "oxp_af0cc12b-43c5-473a-89a7-28351fbbb430" - } - } - }, - "root": "/pool/ext/cf1594ed-7c0c-467c-b0af-a689dcb427a3/crypt/zone" - }, - { - "zone": { - "id": "7cea4d59-a8ca-4826-901d-8d5bd935dc09", - "underlay_address": "fd00:1122:3344:10b::9", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::9]:32345", - "dataset": { - "pool_name": "oxp_d75dae09-4992-4a61-ab7d-5ae1d2b068ba" - } - } - }, - "root": "/pool/ext/a809f28a-7f25-4362-bc56-0cbdd72af2cb/crypt/zone" - }, - { - "zone": { - "id": "08adaeee-c3b5-4cd8-8fbd-ac371b3101c9", - "underlay_address": "fd00:1122:3344:10b::4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::4]:32345", - "dataset": { - "pool_name": "oxp_d9f23187-fbf9-4ea5-a103-bc112263a9a7" - } - } - }, - "root": "/pool/ext/7c204111-31df-4c32-9a3e-780411f700fd/crypt/zone" - }, - { - "zone": { - "id": "3da1ade5-3fcb-4e64-aa08-81ee8a9ef723", - "underlay_address": "fd00:1122:3344:10b::8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::8]:32345", - "dataset": { - "pool_name": "oxp_1f6adf64-c9b9-4ed7-b3e2-37fb25624646" - } - } - }, - "root": "/pool/ext/07c1a8e7-51f5-4f12-a43d-734719fef92b/crypt/zone" - }, - { - "zone": { - "id": "816f26a7-4c28-4a39-b9ad-a036678520ab", - "underlay_address": "fd00:1122:3344:10b::7", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::7]:32345", - "dataset": { - "pool_name": "oxp_92a1bd39-6e8a-4226-b9d0-e3e8a9b8504f" - } - } - }, - "root": "/pool/ext/d9f23187-fbf9-4ea5-a103-bc112263a9a7/crypt/zone" - }, - { - "zone": { - "id": "839f9839-409f-45d3-b8a6-7085507b90f6", - "underlay_address": "fd00:1122:3344:10b::c", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::c]:32345", - "dataset": { - "pool_name": "oxp_7c204111-31df-4c32-9a3e-780411f700fd" - } - } - }, - "root": "/pool/ext/af0cc12b-43c5-473a-89a7-28351fbbb430/crypt/zone" - }, - { - "zone": { - "id": "c717c81f-a228-4412-a34e-90f8c491d847", - "underlay_address": "fd00:1122:3344:10b::5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:10b::5]:32345", - "dataset": { - "pool_name": "oxp_cf1594ed-7c0c-467c-b0af-a689dcb427a3" - } - } - }, - "root": "/pool/ext/d63a297d-ae6a-4072-9dca-dda404044989/crypt/zone" - }, - { - "zone": { - "id": "e1fa2023-6c86-40a4-ae59-a0de112cf7a9", - "underlay_address": "fd00:1122:3344:10b::e", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:10b::e]:123", - "ntp_servers": [ - "440dd615-e11f-4a5d-aeb4-dcf88bb314de.host.control-plane.oxide.internal", - "cb901d3e-8811-4c4c-a274-a44130501ecf.host.control-plane.oxide.internal" - ], - "dns_servers": [ - "fd00:1122:3344:1::1", - "fd00:1122:3344:2::1", - "fd00:1122:3344:3::1" - ], - "domain": null - } - }, - "root": "/pool/ext/d9f23187-fbf9-4ea5-a103-bc112263a9a7/crypt/zone" - } - ] -} \ No newline at end of file From 32a37f56e68b24b78647d6bda5401f2af1df6f88 Mon Sep 17 00:00:00 2001 From: Benjamin Naecker Date: Fri, 21 Jun 2024 18:51:10 -0700 Subject: [PATCH 19/26] Add tests for ClickHouse schema upgrades (#5932) - Adds a check that verifies the SQL contained in each upgrade. This does the basic sanity checks like: one statement per file, no data modifications, but doesn't actually apply the upgrades. - Adds another test that ensures that the set of tables we arrive at either by upgrading or directly initializing the latest database version are the same. --- oximeter/db/src/client/mod.rs | 238 ++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) diff --git a/oximeter/db/src/client/mod.rs b/oximeter/db/src/client/mod.rs index 9a2b7b1bd3..0db71d195a 100644 --- a/oximeter/db/src/client/mod.rs +++ b/oximeter/db/src/client/mod.rs @@ -4185,4 +4185,242 @@ mod tests { db.cleanup().await.unwrap(); logctx.cleanup_successful(); } + + // The schema directory, used in tests. The actual updater uses the + // zone-image files copied in during construction. + const SCHEMA_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/schema"); + + #[tokio::test] + async fn check_actual_schema_upgrades_are_valid_single_node() { + check_actual_schema_upgrades_are_valid_impl(false).await; + } + + #[tokio::test] + async fn check_actual_schema_upgrades_are_valid_replicated() { + check_actual_schema_upgrades_are_valid_impl(true).await; + } + + // NOTE: This does not actually run the upgrades, only checks them for + // validity. + async fn check_actual_schema_upgrades_are_valid_impl(replicated: bool) { + let name = format!( + "check_actual_schema_upgrades_are_valid_{}", + if replicated { "replicated" } else { "single_node" } + ); + let logctx = test_setup_log(&name); + let log = &logctx.log; + + // We really started tracking the database version in 2. However, that + // set of files is not valid by construction, since we were just + // creating the full database from scratch as an "upgrade". So we'll + // start by applying version 3, and then do all later ones. + const FIRST_VERSION: u64 = 3; + for version in FIRST_VERSION..=OXIMETER_VERSION { + let upgrade_file_contents = Client::read_schema_upgrade_sql_files( + log, false, version, SCHEMA_DIR, + ) + .await + .expect("failed to read schema upgrade files"); + + if let Err(e) = + Client::verify_schema_upgrades(&upgrade_file_contents) + { + panic!( + "Schema update files for version {version} \ + are not valid: {e:?}" + ); + } + } + logctx.cleanup_successful(); + } + + // Either a cluster or single node. + // + // How does this not already exist... + enum ClickHouse { + Cluster(ClickHouseCluster), + Single(ClickHouseInstance), + } + + impl ClickHouse { + fn port(&self) -> u16 { + match self { + ClickHouse::Cluster(cluster) => cluster.replica_1.port(), + ClickHouse::Single(node) => node.port(), + } + } + + async fn cleanup(mut self) { + match &mut self { + ClickHouse::Cluster(cluster) => { + cluster + .keeper_1 + .cleanup() + .await + .expect("Failed to cleanup ClickHouse keeper 1"); + cluster + .keeper_2 + .cleanup() + .await + .expect("Failed to cleanup ClickHouse keeper 2"); + cluster + .keeper_3 + .cleanup() + .await + .expect("Failed to cleanup ClickHouse keeper 3"); + cluster + .replica_1 + .cleanup() + .await + .expect("Failed to cleanup ClickHouse server 1"); + cluster + .replica_2 + .cleanup() + .await + .expect("Failed to cleanup ClickHouse server 2"); + } + ClickHouse::Single(node) => node + .cleanup() + .await + .expect("Failed to cleanup single node ClickHouse"), + } + } + } + + #[tokio::test] + async fn check_db_init_is_sum_of_all_up_single_node() { + check_db_init_is_sum_of_all_up_impl(false).await; + } + + #[tokio::test] + async fn check_db_init_is_sum_of_all_up_replicated() { + check_db_init_is_sum_of_all_up_impl(true).await; + } + + // Check that the set of tables we arrive at through upgrades equals those + // we get by creating the latest version directly. + async fn check_db_init_is_sum_of_all_up_impl(replicated: bool) { + let name = format!( + "check_db_init_is_sum_of_all_up_{}", + if replicated { "replicated" } else { "single_node" } + ); + let logctx = test_setup_log(&name); + let log = &logctx.log; + let db = if replicated { + ClickHouse::Cluster(create_cluster(&logctx).await) + } else { + ClickHouse::Single( + ClickHouseInstance::new_single_node(&logctx, 0) + .await + .expect("Failed to start ClickHouse"), + ) + }; + let address = SocketAddr::new(Ipv6Addr::LOCALHOST.into(), db.port()); + let client = Client::new(address, &log); + + // Let's start with version 2, which is the first tracked and contains + // the full SQL files we need to populate the DB. + client + .initialize_db_with_version(replicated, 2) + .await + .expect("Failed to initialize timeseries database"); + + // Now let's apply all the SQL updates from here to the latest. + for version in 3..=OXIMETER_VERSION { + client + .ensure_schema(replicated, version, SCHEMA_DIR) + .await + .expect("Failed to ensure schema"); + } + + // Fetch all the tables as a JSON blob. + let tables_through_upgrades = + fetch_oximeter_table_details(&client).await; + + // We'll completely re-init the DB with the real version now. + if replicated { + client.wipe_replicated_db().await.unwrap() + } else { + client.wipe_single_node_db().await.unwrap() + } + client + .initialize_db_with_version(replicated, OXIMETER_VERSION) + .await + .expect("Failed to initialize timeseries database"); + + // Fetch the tables again and compare. + let tables = fetch_oximeter_table_details(&client).await; + + // This is an annoying comparison. Since the tables are quite + // complicated, we want to really be careful about what errors we show. + // Iterate through all the expected tables (from the direct creation), + // and check each expected field matches. Then we also check that the + // tables from the upgrade path don't have anything else in them. + for (name, json) in tables.iter() { + let upgrade_table = + tables_through_upgrades.get(name).unwrap_or_else(|| { + panic!("The tables via upgrade are missing table '{name}'") + }); + for (key, value) in json.iter() { + let other_value = upgrade_table.get(key).unwrap_or_else(|| { + panic!("Upgrade table is missing key '{key}'") + }); + assert_eq!( + value, + other_value, + "{} database table {name} disagree on the value \ + of the column {key} between the direct table creation \ + and the upgrade path.\nDirect:\n\n{value} \ + \n\nUpgrade:\n\n{other_value}", + if replicated { "Replicated" } else { "Single-node" }, + ); + } + } + + // Check there are zero keys in the upgrade path that don't appear in + // the direct path. + let extra_keys: Vec<_> = tables_through_upgrades + .keys() + .filter(|k| !tables.contains_key(k.as_str())) + .cloned() + .collect(); + assert!( + extra_keys.is_empty(), + "The oximeter database contains tables in the upgrade path \ + that are not in the direct path: {extra_keys:?}" + ); + + db.cleanup().await; + logctx.cleanup_successful(); + } + + // Read the relevant table details from the `oximeter` database, and return + // it keyed on the table name. + async fn fetch_oximeter_table_details( + client: &Client, + ) -> BTreeMap> { + let out = client + .execute_with_body( + "SELECT \ + name, + engine_full, + create_table_query, + sorting_key, + primary_key + FROM system.tables \ + WHERE database = 'oximeter'\ + FORMAT JSONEachRow;", + ) + .await + .unwrap() + .1; + out.lines() + .map(|line| { + let json: serde_json::Map = + serde_json::from_str(&line).unwrap(); + let name = json.get("name").unwrap().to_string(); + (name, json) + }) + .collect() + } } From 909d49756d59611c5cd0d03af8f99e6932976a37 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Sat, 22 Jun 2024 12:36:21 -0400 Subject: [PATCH 20/26] Bump gimlet/psc/sidecar (#5928) Automated bump --- tools/permslip_staging | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/permslip_staging b/tools/permslip_staging index e0c4b4ad70..bc9250ae93 100644 --- a/tools/permslip_staging +++ b/tools/permslip_staging @@ -1,5 +1,5 @@ -844c56d542700c4b613d9cd7aee5ab306c8d0b969e5dfe194b1b7468a6a9752b manifest-gimlet-v1.0.21.toml +c28eaa13638f55100a42916727227242ee02d18cebecb1412d6af5c8aa945b99 manifest-gimlet-v1.0.22.toml b973cc9feb20f7bba447e7f5291c4070387fa9992deab81301f67f0a3844cd0c manifest-oxide-rot-1-v1.0.11.toml -ca14a77639db3b71c60234e4edebd01ff31ba5a93a842100a991dbf3ad6e94fb manifest-psc-v1.0.20.toml -af0f6c7d0723db33a2972343cc42e4c2ee2ab8884c49808c9c3d8289c193f97b manifest-sidecar-v1.0.21.toml +6d53bfbfdd6baa3fc150153a003abfac6d4b46c34f61fa7a8ec2af8af19a7d5a manifest-psc-v1.0.21.toml +d608dba3fa5a1fce3592ff3f643319787218b84706134147e5918f5bd1c0345d manifest-sidecar-v1.0.22.toml c0fecaefac7674138337f3bd4ce4ce5b884053dead5ec27b575701471631ea2f manifest-bootleby-v1.3.0.toml From 070391e056ce6efc29151cbe394ad070457d2767 Mon Sep 17 00:00:00 2001 From: Adam Leventhal Date: Sat, 22 Jun 2024 10:48:47 -0700 Subject: [PATCH 21/26] have oximeter-producer re-export dropshot types in its interface (#5933) --- oximeter/producer/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/oximeter/producer/src/lib.rs b/oximeter/producer/src/lib.rs index 6bf8954ae0..36b05d7bb1 100644 --- a/oximeter/producer/src/lib.rs +++ b/oximeter/producer/src/lib.rs @@ -9,7 +9,6 @@ use dropshot::endpoint; use dropshot::ApiDescription; use dropshot::ConfigDropshot; -use dropshot::ConfigLogging; use dropshot::HttpError; use dropshot::HttpResponseOk; use dropshot::HttpServer; @@ -42,6 +41,13 @@ use std::time::Duration; use thiserror::Error; use uuid::Uuid; +// Our public interface depends directly or indirectly on these types; we +// export them so that consumers need not depend on dropshot themselves and +// to simplify how we stage incompatible upgrades. +pub use dropshot::ConfigLogging; +pub use dropshot::ConfigLoggingIfExists; +pub use dropshot::ConfigLoggingLevel; + #[derive(Debug, Clone, Error)] pub enum Error { #[error("Error running producer HTTP server: {0}")] From 895f2800ad96b51c538ae8011df3654d511563c5 Mon Sep 17 00:00:00 2001 From: iliana etaoin Date: Mon, 24 Jun 2024 11:21:15 -0700 Subject: [PATCH 22/26] omicron-package: allow building specific packages and their dependencies (#5799) --- Cargo.lock | 2 +- dev-tools/xtask/src/check_workspace_deps.rs | 17 ++ installinator/Cargo.toml | 2 - package/Cargo.toml | 4 +- package/src/bin/omicron-package.rs | 259 ++++++++++++++------ package/src/lib.rs | 3 + sled-agent/Cargo.toml | 7 - 7 files changed, 204 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4592b555bf..ac3149c6ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5632,6 +5632,7 @@ version = "0.1.0" dependencies = [ "anyhow", "camino", + "cargo_metadata", "clap", "expectorate", "futures", @@ -5653,7 +5654,6 @@ dependencies = [ "slog-term", "smf", "strum", - "swrite", "tar", "thiserror", "tokio", diff --git a/dev-tools/xtask/src/check_workspace_deps.rs b/dev-tools/xtask/src/check_workspace_deps.rs index 94de557a46..73d5643ffb 100644 --- a/dev-tools/xtask/src/check_workspace_deps.rs +++ b/dev-tools/xtask/src/check_workspace_deps.rs @@ -146,6 +146,23 @@ pub fn run_cmd() -> Result<()> { } } + let mut seen_bins = BTreeSet::new(); + for package in &workspace.packages { + if workspace.workspace_members.contains(&package.id) { + for target in &package.targets { + if target.is_bin() { + if !seen_bins.insert(&target.name) { + eprintln!( + "error: bin target {:?} seen multiple times", + target.name + ); + nerrors += 1; + } + } + } + } + } + eprintln!( "check-workspace-deps: errors: {}, warnings: {}", nerrors, nwarnings diff --git a/installinator/Cargo.toml b/installinator/Cargo.toml index ebdb6269b7..c21c3f2ee2 100644 --- a/installinator/Cargo.toml +++ b/installinator/Cargo.toml @@ -57,5 +57,3 @@ tokio-stream.workspace = true [features] image-standard = [] -image-trampoline = [] -rack-topology-single-sled = [] diff --git a/package/Cargo.toml b/package/Cargo.toml index 4632e66731..b63a5ed96f 100644 --- a/package/Cargo.toml +++ b/package/Cargo.toml @@ -11,11 +11,13 @@ workspace = true [dependencies] anyhow.workspace = true camino.workspace = true +cargo_metadata.workspace = true clap.workspace = true futures.workspace = true hex.workspace = true illumos-utils.workspace = true indicatif.workspace = true +omicron-workspace-hack.workspace = true omicron-zone-package.workspace = true petgraph.workspace = true rayon.workspace = true @@ -30,13 +32,11 @@ slog-bunyan.workspace = true slog-term.workspace = true smf.workspace = true strum.workspace = true -swrite.workspace = true tar.workspace = true thiserror.workspace = true tokio = { workspace = true, features = [ "full" ] } toml.workspace = true walkdir.workspace = true -omicron-workspace-hack.workspace = true [dev-dependencies] expectorate.workspace = true diff --git a/package/src/bin/omicron-package.rs b/package/src/bin/omicron-package.rs index a8c5508b77..6db168c9f8 100644 --- a/package/src/bin/omicron-package.rs +++ b/package/src/bin/omicron-package.rs @@ -4,7 +4,7 @@ //! Utility for bundling target binaries as tarfiles. -use anyhow::{anyhow, bail, Context, Result}; +use anyhow::{anyhow, bail, ensure, Context, Result}; use camino::{Utf8Path, Utf8PathBuf}; use clap::{Parser, Subcommand}; use futures::stream::{self, StreamExt, TryStreamExt}; @@ -12,7 +12,7 @@ use illumos_utils::{zfs, zone}; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use omicron_package::target::KnownTarget; use omicron_package::{parse, BuildCommand, DeployCommand, TargetCommand}; -use omicron_zone_package::config::Config as PackageConfig; +use omicron_zone_package::config::{Config as PackageConfig, PackageMap}; use omicron_zone_package::package::{Package, PackageOutput, PackageSource}; use omicron_zone_package::progress::Progress; use omicron_zone_package::target::Target; @@ -24,13 +24,13 @@ use slog::o; use slog::Drain; use slog::Logger; use slog::{info, warn}; +use std::collections::{BTreeMap, BTreeSet}; use std::env; use std::fs::create_dir_all; use std::io::Write; use std::str::FromStr; use std::sync::{Arc, OnceLock}; use std::time::Duration; -use swrite::{swrite, SWrite}; use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader}; use tokio::process::Command; @@ -105,82 +105,117 @@ struct Args { subcommand: SubCommand, } -async fn run_cargo_on_packages( - subcmd: &str, - packages: I, +#[derive(Debug, Default)] +struct CargoPlan<'a> { + command: &'a str, + bins: BTreeSet<&'a String>, + features: BTreeSet<&'a String>, release: bool, - features: &str, -) -> Result<()> -where - I: IntoIterator, - S: AsRef, -{ - let mut cmd = Command::new("cargo"); - // We rely on the rust-toolchain.toml file for toolchain information, - // rather than specifying one within the packaging tool. - cmd.arg(subcmd); - for package in packages { - cmd.arg("-p").arg(package); - } - cmd.arg("--features").arg(features); - if release { - cmd.arg("--release"); - } - let status = cmd - .status() - .await - .context(format!("Failed to run command: ({:?})", cmd))?; - if !status.success() { - bail!("Failed to build packages"); - } +} - Ok(()) +impl<'a> CargoPlan<'a> { + async fn run(&self, log: &Logger) -> Result<()> { + if self.bins.is_empty() { + return Ok(()); + } + + let mut cmd = Command::new("cargo"); + // We rely on the rust-toolchain.toml file for toolchain information, + // rather than specifying one within the packaging tool. + cmd.arg(self.command); + for bin in &self.bins { + cmd.arg("--bin").arg(bin); + } + if !self.features.is_empty() { + cmd.arg("--features").arg(self.features.iter().fold( + String::new(), + |mut acc, s| { + if !acc.is_empty() { + acc.push(' '); + } + acc.push_str(s); + acc + }, + )); + } + if self.release { + cmd.arg("--release"); + } + info!(log, "running: {:?}", cmd.as_std()); + let status = cmd + .status() + .await + .context(format!("Failed to run command: ({:?})", cmd))?; + if !status.success() { + bail!("Failed to build packages"); + } + + Ok(()) + } } async fn do_for_all_rust_packages( config: &Config, command: &str, ) -> Result<()> { - // First, filter out all Rust packages from the configuration that should be - // built, and partition them into "release" and "debug" categories. - let (release_pkgs, debug_pkgs): (Vec<_>, _) = config - .package_config - .packages_to_build(&config.target) - .0 + // Collect a map of all of the workspace packages + let workspace = cargo_metadata::MetadataCommand::new().no_deps().exec()?; + let workspace_pkgs = workspace + .packages .into_iter() - .filter_map(|(name, pkg)| match &pkg.source { - PackageSource::Local { rust: Some(rust_pkg), .. } => { - Some((name, rust_pkg.release)) - } - _ => None, + .filter_map(|package| { + workspace + .workspace_members + .contains(&package.id) + .then_some((package.name.clone(), package)) }) - .partition(|(_, release)| *release); - - let features = - config.target.0.iter().fold(String::new(), |mut acc, (name, value)| { - swrite!(acc, "{}-{} ", name, value); - acc - }); + .collect::>(); - // Execute all the release / debug packages at the same time. - if !release_pkgs.is_empty() { - run_cargo_on_packages( - command, - release_pkgs.iter().map(|(name, _)| name), - true, - &features, - ) - .await?; - } - if !debug_pkgs.is_empty() { - run_cargo_on_packages( - command, - debug_pkgs.iter().map(|(name, _)| name), - false, - &features, - ) - .await?; + // Generate a list of all features we might want to request + let features = config + .target + .0 + .iter() + .map(|(name, value)| format!("{name}-{value}")) + .collect::>(); + + // We split the packages to be built into "release" and "debug" lists + let mut release = + CargoPlan { command, release: true, ..Default::default() }; + let mut debug = CargoPlan { command, release: false, ..Default::default() }; + + for (name, pkg) in config.packages_to_build().0 { + // If this is a Rust package... + if let PackageSource::Local { rust: Some(rust_pkg), .. } = &pkg.source { + let plan = if rust_pkg.release { &mut release } else { &mut debug }; + // Get the package metadata + let metadata = workspace_pkgs.get(name).with_context(|| { + format!("package '{name}' is not a workspace package") + })?; + // Add the binaries we want to build to the plan + let bins = metadata + .targets + .iter() + .filter_map(|target| target.is_bin().then_some(&target.name)) + .collect::>(); + for bin in &rust_pkg.binary_names { + ensure!( + bins.contains(bin), + "bin target '{bin}' does not belong to package '{name}'" + ); + plan.bins.insert(bin); + } + // Add all features we want to request to the plan + plan.features.extend( + features + .iter() + .filter(|feature| metadata.features.contains_key(*feature)), + ); + } } + + release.run(&config.log).await?; + debug.run(&config.log).await?; Ok(()) } @@ -205,9 +240,7 @@ async fn do_list_outputs( output_directory: &Utf8Path, intermediate: bool, ) -> Result<()> { - for (name, package) in - config.package_config.packages_to_build(&config.target).0 - { + for (name, package) in config.packages_to_build().0 { if !intermediate && package.output == (PackageOutput::Zone { intermediate_only: true }) @@ -508,7 +541,7 @@ async fn do_package( do_build(&config).await?; - let packages = config.package_config.packages_to_build(&config.target); + let packages = config.packages_to_build(); let package_iter = packages.build_order(); for batch in package_iter { @@ -912,6 +945,8 @@ struct Config { package_config: PackageConfig, // Description of the target we're trying to operate on. target: Target, + // The list of packages the user wants us to build (all, if empty) + only: Vec, // True if we should skip confirmations for destructive operations. force: bool, // Number of times to retry failed downloads. @@ -937,6 +972,67 @@ impl Config { _ => bail!("Aborting"), } } + + /// Returns target packages to be assembled on the builder machine, limited + /// to those specified in `only` (if set). + fn packages_to_build(&self) -> PackageMap<'_> { + let packages = self.package_config.packages_to_build(&self.target); + if self.only.is_empty() { + return packages; + } + + let mut filtered_packages = PackageMap(BTreeMap::new()); + let mut to_walk = PackageMap(BTreeMap::new()); + // add the requested packages to `to_walk` + for package_name in &self.only { + to_walk.0.insert( + package_name, + packages.0.get(package_name).unwrap_or_else(|| { + panic!( + "Explicitly-requested package '{}' does not exist", + package_name + ) + }), + ); + } + // dependencies are listed by output name, so create a lookup table to + // get a package by its output name. + let lookup_by_output = packages + .0 + .iter() + .map(|(name, package)| { + (package.get_output_file(name), (*name, *package)) + }) + .collect::>(); + // packages yet to be walked are added to `to_walk`. pop each entry and + // add its dependencies to `to_walk`, then add the package we finished + // walking to `filtered_packages`. + while let Some((package_name, package)) = to_walk.0.pop_first() { + if let PackageSource::Composite { packages } = &package.source { + for output in packages { + // find the package by output name + let (dep_name, dep_package) = + lookup_by_output.get(output).unwrap_or_else(|| { + panic!( + "Could not find a package which creates '{}'", + output + ) + }); + if dep_name.as_str() == package_name { + panic!("'{}' depends on itself", package_name); + } + // if we've seen this package already, it will be in + // `filtered_packages`. otherwise, add it to `to_walk`. + if !filtered_packages.0.contains_key(dep_name) { + to_walk.0.insert(dep_name, dep_package); + } + } + } + // we're done looking at this package's deps + filtered_packages.0.insert(package_name, package); + } + filtered_packages + } } #[tokio::main] @@ -989,6 +1085,7 @@ async fn main() -> Result<()> { log: log.clone(), package_config, target, + only: Vec::new(), force: args.force, retry_count: args.retry_count, retry_duration: args.retry_duration, @@ -1004,7 +1101,7 @@ async fn main() -> Result<()> { })?; } - match &args.subcommand { + match args.subcommand { SubCommand::Build(BuildCommand::Target { subcommand }) => { do_target(&args.artifact_dir, &args.target, &subcommand).await?; } @@ -1012,16 +1109,22 @@ async fn main() -> Result<()> { do_dot(&get_config()?).await?; } SubCommand::Build(BuildCommand::ListOutputs { intermediate }) => { - do_list_outputs(&get_config()?, &args.artifact_dir, *intermediate) + do_list_outputs(&get_config()?, &args.artifact_dir, intermediate) .await?; } - SubCommand::Build(BuildCommand::Package { disable_cache }) => { - do_package(&get_config()?, &args.artifact_dir, *disable_cache) - .await?; + SubCommand::Build(BuildCommand::Package { disable_cache, only }) => { + let mut config = get_config()?; + config.only = only; + do_package(&config, &args.artifact_dir, disable_cache).await?; } SubCommand::Build(BuildCommand::Stamp { package_name, version }) => { - do_stamp(&get_config()?, &args.artifact_dir, package_name, version) - .await?; + do_stamp( + &get_config()?, + &args.artifact_dir, + &package_name, + &version, + ) + .await?; } SubCommand::Build(BuildCommand::Check) => { do_check(&get_config()?).await? diff --git a/package/src/lib.rs b/package/src/lib.rs index 2b99cfbe07..2009de9dfe 100644 --- a/package/src/lib.rs +++ b/package/src/lib.rs @@ -103,6 +103,9 @@ pub enum BuildCommand { /// By default, the cache is used. #[clap(short, long)] disable_cache: bool, + /// Limit to building only these packages + #[clap(long)] + only: Vec, }, /// Stamps semver versions onto packages within a manifest Stamp { diff --git a/sled-agent/Cargo.toml b/sled-agent/Cargo.toml index 167ac987ca..b798ba783d 100644 --- a/sled-agent/Cargo.toml +++ b/sled-agent/Cargo.toml @@ -127,14 +127,7 @@ name = "sled-agent" doc = false [features] -image-standard = [] image-trampoline = [] -machine-gimlet = [] -machine-gimlet-standalone = [] -machine-non-gimlet = [] switch-asic = [] switch-stub = [] switch-softnpu = [] -switch-hypersoftnpu = [] -rack-topology-single-sled = [] -rack-topology-multi-sled = [] From 8238f985dd70f09fd45a4738dcbbcc07e790d2f0 Mon Sep 17 00:00:00 2001 From: Zeeshan Lakhani Date: Mon, 24 Jun 2024 17:12:58 -0400 Subject: [PATCH 23/26] Additional tracking on histograms for means, std dev, p* quantile estimates (#5897) Closes https://github.com/oxidecomputer/omicron/issues/4913. This is part 1 of tracking more information within a histogram to compute min, max, means, std_dev, and estimates for p50, p90, and p99 and how to store/retrieve the associated info from Clickhouse. --- Cargo.lock | 19 + Cargo.toml | 2 + docs/how-to-run.adoc | 6 +- openapi/nexus.json | 712 ++++++++++++++++++- oximeter/db/schema/replicated/5/up01.sql | 1 + oximeter/db/schema/replicated/5/up02.sql | 1 + oximeter/db/schema/replicated/5/up03.sql | 25 + oximeter/db/schema/replicated/5/up04.sql | 3 + oximeter/db/schema/replicated/5/up05.sql | 1 + oximeter/db/schema/replicated/5/up06.sql | 1 + oximeter/db/schema/replicated/5/up07.sql | 25 + oximeter/db/schema/replicated/5/up08.sql | 3 + oximeter/db/schema/replicated/5/up09.sql | 1 + oximeter/db/schema/replicated/5/up10.sql | 1 + oximeter/db/schema/replicated/5/up11.sql | 25 + oximeter/db/schema/replicated/5/up12.sql | 3 + oximeter/db/schema/replicated/5/up13.sql | 1 + oximeter/db/schema/replicated/5/up14.sql | 1 + oximeter/db/schema/replicated/5/up15.sql | 25 + oximeter/db/schema/replicated/5/up16.sql | 3 + oximeter/db/schema/replicated/5/up17.sql | 1 + oximeter/db/schema/replicated/5/up18.sql | 1 + oximeter/db/schema/replicated/5/up19.sql | 25 + oximeter/db/schema/replicated/5/up20.sql | 3 + oximeter/db/schema/replicated/5/up21.sql | 1 + oximeter/db/schema/replicated/5/up22.sql | 1 + oximeter/db/schema/replicated/5/up23.sql | 25 + oximeter/db/schema/replicated/5/up24.sql | 3 + oximeter/db/schema/replicated/5/up25.sql | 1 + oximeter/db/schema/replicated/5/up26.sql | 1 + oximeter/db/schema/replicated/5/up27.sql | 25 + oximeter/db/schema/replicated/5/up28.sql | 3 + oximeter/db/schema/replicated/5/up29.sql | 1 + oximeter/db/schema/replicated/5/up30.sql | 1 + oximeter/db/schema/replicated/5/up31.sql | 25 + oximeter/db/schema/replicated/5/up32.sql | 3 + oximeter/db/schema/replicated/5/up33.sql | 1 + oximeter/db/schema/replicated/5/up34.sql | 1 + oximeter/db/schema/replicated/5/up35.sql | 25 + oximeter/db/schema/replicated/5/up36.sql | 3 + oximeter/db/schema/replicated/5/up37.sql | 1 + oximeter/db/schema/replicated/5/up38.sql | 1 + oximeter/db/schema/replicated/5/up39.sql | 25 + oximeter/db/schema/replicated/5/up40.sql | 3 + oximeter/db/schema/replicated/db-init.sql | 240 ++++--- oximeter/db/schema/single-node/5/up01.sql | 1 + oximeter/db/schema/single-node/5/up02.sql | 25 + oximeter/db/schema/single-node/5/up03.sql | 1 + oximeter/db/schema/single-node/5/up04.sql | 25 + oximeter/db/schema/single-node/5/up05.sql | 1 + oximeter/db/schema/single-node/5/up06.sql | 25 + oximeter/db/schema/single-node/5/up07.sql | 1 + oximeter/db/schema/single-node/5/up08.sql | 25 + oximeter/db/schema/single-node/5/up09.sql | 1 + oximeter/db/schema/single-node/5/up10.sql | 25 + oximeter/db/schema/single-node/5/up11.sql | 1 + oximeter/db/schema/single-node/5/up12.sql | 25 + oximeter/db/schema/single-node/5/up13.sql | 1 + oximeter/db/schema/single-node/5/up14.sql | 25 + oximeter/db/schema/single-node/5/up15.sql | 1 + oximeter/db/schema/single-node/5/up16.sql | 25 + oximeter/db/schema/single-node/5/up17.sql | 1 + oximeter/db/schema/single-node/5/up18.sql | 25 + oximeter/db/schema/single-node/5/up19.sql | 1 + oximeter/db/schema/single-node/5/up20.sql | 25 + oximeter/db/schema/single-node/db-init.sql | 150 +++- oximeter/db/src/bin/oxdb/oxql.rs | 101 ++- oximeter/db/src/bin/oxdb/sql.rs | 39 +- oximeter/db/src/client/mod.rs | 2 +- oximeter/db/src/client/oxql.rs | 10 +- oximeter/db/src/model.rs | 272 +++++-- oximeter/db/src/oxql/ast/table_ops/filter.rs | 10 +- oximeter/db/src/oxql/point.rs | 280 +++++++- oximeter/db/src/oxql/query/mod.rs | 32 + oximeter/db/src/sql/mod.rs | 23 +- oximeter/instruments/src/http.rs | 6 +- oximeter/oximeter/Cargo.toml | 3 + oximeter/oximeter/src/histogram.rs | 639 +++++++++++++---- oximeter/oximeter/src/lib.rs | 3 + oximeter/oximeter/src/quantile.rs | 592 +++++++++++++++ oximeter/oximeter/src/test_util.rs | 2 +- 81 files changed, 3302 insertions(+), 401 deletions(-) create mode 100644 oximeter/db/schema/replicated/5/up01.sql create mode 100644 oximeter/db/schema/replicated/5/up02.sql create mode 100644 oximeter/db/schema/replicated/5/up03.sql create mode 100644 oximeter/db/schema/replicated/5/up04.sql create mode 100644 oximeter/db/schema/replicated/5/up05.sql create mode 100644 oximeter/db/schema/replicated/5/up06.sql create mode 100644 oximeter/db/schema/replicated/5/up07.sql create mode 100644 oximeter/db/schema/replicated/5/up08.sql create mode 100644 oximeter/db/schema/replicated/5/up09.sql create mode 100644 oximeter/db/schema/replicated/5/up10.sql create mode 100644 oximeter/db/schema/replicated/5/up11.sql create mode 100644 oximeter/db/schema/replicated/5/up12.sql create mode 100644 oximeter/db/schema/replicated/5/up13.sql create mode 100644 oximeter/db/schema/replicated/5/up14.sql create mode 100644 oximeter/db/schema/replicated/5/up15.sql create mode 100644 oximeter/db/schema/replicated/5/up16.sql create mode 100644 oximeter/db/schema/replicated/5/up17.sql create mode 100644 oximeter/db/schema/replicated/5/up18.sql create mode 100644 oximeter/db/schema/replicated/5/up19.sql create mode 100644 oximeter/db/schema/replicated/5/up20.sql create mode 100644 oximeter/db/schema/replicated/5/up21.sql create mode 100644 oximeter/db/schema/replicated/5/up22.sql create mode 100644 oximeter/db/schema/replicated/5/up23.sql create mode 100644 oximeter/db/schema/replicated/5/up24.sql create mode 100644 oximeter/db/schema/replicated/5/up25.sql create mode 100644 oximeter/db/schema/replicated/5/up26.sql create mode 100644 oximeter/db/schema/replicated/5/up27.sql create mode 100644 oximeter/db/schema/replicated/5/up28.sql create mode 100644 oximeter/db/schema/replicated/5/up29.sql create mode 100644 oximeter/db/schema/replicated/5/up30.sql create mode 100644 oximeter/db/schema/replicated/5/up31.sql create mode 100644 oximeter/db/schema/replicated/5/up32.sql create mode 100644 oximeter/db/schema/replicated/5/up33.sql create mode 100644 oximeter/db/schema/replicated/5/up34.sql create mode 100644 oximeter/db/schema/replicated/5/up35.sql create mode 100644 oximeter/db/schema/replicated/5/up36.sql create mode 100644 oximeter/db/schema/replicated/5/up37.sql create mode 100644 oximeter/db/schema/replicated/5/up38.sql create mode 100644 oximeter/db/schema/replicated/5/up39.sql create mode 100644 oximeter/db/schema/replicated/5/up40.sql create mode 100644 oximeter/db/schema/single-node/5/up01.sql create mode 100644 oximeter/db/schema/single-node/5/up02.sql create mode 100644 oximeter/db/schema/single-node/5/up03.sql create mode 100644 oximeter/db/schema/single-node/5/up04.sql create mode 100644 oximeter/db/schema/single-node/5/up05.sql create mode 100644 oximeter/db/schema/single-node/5/up06.sql create mode 100644 oximeter/db/schema/single-node/5/up07.sql create mode 100644 oximeter/db/schema/single-node/5/up08.sql create mode 100644 oximeter/db/schema/single-node/5/up09.sql create mode 100644 oximeter/db/schema/single-node/5/up10.sql create mode 100644 oximeter/db/schema/single-node/5/up11.sql create mode 100644 oximeter/db/schema/single-node/5/up12.sql create mode 100644 oximeter/db/schema/single-node/5/up13.sql create mode 100644 oximeter/db/schema/single-node/5/up14.sql create mode 100644 oximeter/db/schema/single-node/5/up15.sql create mode 100644 oximeter/db/schema/single-node/5/up16.sql create mode 100644 oximeter/db/schema/single-node/5/up17.sql create mode 100644 oximeter/db/schema/single-node/5/up18.sql create mode 100644 oximeter/db/schema/single-node/5/up19.sql create mode 100644 oximeter/db/schema/single-node/5/up20.sql create mode 100644 oximeter/oximeter/src/quantile.rs diff --git a/Cargo.lock b/Cargo.lock index ac3149c6ff..093061216a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2435,6 +2435,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "float-ord" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d" + [[package]] name = "flume" version = "0.11.0" @@ -6222,10 +6228,13 @@ dependencies = [ "approx", "bytes", "chrono", + "float-ord", "num", "omicron-common", "omicron-workspace-hack", "oximeter-macro-impl", + "rand 0.8.5", + "rand_distr", "regex", "rstest", "schemars", @@ -7457,6 +7466,16 @@ dependencies = [ "getrandom 0.2.14", ] +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "rand_hc" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index fbb301511b..1291f18726 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -280,6 +280,7 @@ expectorate = "1.1.0" fatfs = "0.3.6" filetime = "0.2.23" flate2 = "1.0.30" +float-ord = "0.3.2" flume = "0.11.0" foreign-types = "0.3.2" fs-err = "2.11.0" @@ -408,6 +409,7 @@ proptest = "1.4.0" quote = "1.0" rand = "0.8.5" rand_core = "0.6.4" +rand_distr = "0.4.3" rand_seeder = "0.2.3" ratatui = "0.26.2" rayon = "1.10" diff --git a/docs/how-to-run.adoc b/docs/how-to-run.adoc index 097467ef04..9bd99c23d3 100644 --- a/docs/how-to-run.adoc +++ b/docs/how-to-run.adoc @@ -173,7 +173,7 @@ Then install prerequisite software with the following script: [source,text] ---- -$ pfexec ./tools/install_prerequisites.sh +$ ./tools/install_prerequisites.sh ---- You need to do this step once per workspace and potentially again each time you fetch new changes. If the script reports any PATH problems, you'll need to correct those before proceeding. @@ -410,9 +410,9 @@ $ pfexec ./target/release/omicron-package install [WARNING] ==== -**Do not use `pfexec cargo run` directly**; it will cause files in `~/.cargo` and `target/` to be owned by root, which will cause problems down the road. +**Do not use `pfexec cargo run` directly**; it will cause files in `~/.cargo`, `out/`, and `target/` to be owned by root, which will cause problems down the road. -If you've done this already, and you wish to recover, run from the root of this repository `pfexec chown -R $USER:$(id -ng $USER) target ${CARGO_HOME:-~/.cargo}`. +If you've done this already, and you wish to recover, run from the root of this repository `pfexec chown -R $USER:$(id -ng $USER) out target ${CARGO_HOME:-~/.cargo}`. ==== This command installs an SMF service called `svc:/oxide/sled-agent:default`, which itself starts the other required services. This will take a few minutes. You can watch the progress by looking at the Sled Agent log: diff --git a/openapi/nexus.json b/openapi/nexus.json index 42ccb567cf..ab7192d1e0 100644 --- a/openapi/nexus.json +++ b/openapi/nexus.json @@ -12309,7 +12309,7 @@ ] }, "Distributiondouble": { - "description": "A distribution is a sequence of bins and counts in those bins.", + "description": "A distribution is a sequence of bins and counts in those bins, and some statistical information tracked to compute the mean, standard deviation, and quantile estimates.\n\nMin, max, and the p-* quantiles are treated as optional due to the possibility of distribution operations, like subtraction.", "type": "object", "properties": { "bins": { @@ -12326,15 +12326,59 @@ "format": "uint64", "minimum": 0 } + }, + "max": { + "nullable": true, + "type": "number", + "format": "double" + }, + "min": { + "nullable": true, + "type": "number", + "format": "double" + }, + "p50": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "type": "number", + "format": "double" + }, + "sum_of_samples": { + "type": "number", + "format": "double" } }, "required": [ "bins", - "counts" + "counts", + "squared_mean", + "sum_of_samples" ] }, "Distributionint64": { - "description": "A distribution is a sequence of bins and counts in those bins.", + "description": "A distribution is a sequence of bins and counts in those bins, and some statistical information tracked to compute the mean, standard deviation, and quantile estimates.\n\nMin, max, and the p-* quantiles are treated as optional due to the possibility of distribution operations, like subtraction.", "type": "object", "properties": { "bins": { @@ -12351,11 +12395,55 @@ "format": "uint64", "minimum": 0 } + }, + "max": { + "nullable": true, + "type": "integer", + "format": "int64" + }, + "min": { + "nullable": true, + "type": "integer", + "format": "int64" + }, + "p50": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "type": "number", + "format": "double" + }, + "sum_of_samples": { + "type": "integer", + "format": "int64" } }, "required": [ "bins", - "counts" + "counts", + "squared_mean", + "sum_of_samples" ] }, "EphemeralIpCreate": { @@ -13112,25 +13200,79 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Bindouble" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "number", + "format": "double" + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "number", + "format": "double" + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "number", + "format": "double" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramfloat": { @@ -13138,25 +13280,79 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binfloat" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "number", + "format": "float" + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "number", + "format": "float" + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "number", + "format": "double" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramint16": { @@ -13164,25 +13360,79 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binint16" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "integer", + "format": "int16" + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "integer", + "format": "int16" + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "integer", + "format": "int64" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramint32": { @@ -13190,25 +13440,79 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binint32" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "integer", + "format": "int32" + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "integer", + "format": "int32" + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "integer", + "format": "int64" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramint64": { @@ -13216,25 +13520,79 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binint64" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "integer", + "format": "int64" + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "integer", + "format": "int64" + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "integer", + "format": "int64" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramint8": { @@ -13242,25 +13600,79 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binint8" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "integer", + "format": "int8" + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "integer", + "format": "int8" + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "integer", + "format": "int64" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramuint16": { @@ -13268,25 +13680,81 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binuint16" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "integer", + "format": "uint16", + "minimum": 0 + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "integer", + "format": "uint16", + "minimum": 0 + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "integer", + "format": "int64" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramuint32": { @@ -13294,25 +13762,81 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binuint32" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "integer", + "format": "int64" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramuint64": { @@ -13320,25 +13844,81 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binuint64" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "integer", + "format": "int64" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Histogramuint8": { @@ -13346,25 +13926,81 @@ "type": "object", "properties": { "bins": { + "description": "The bins of the histogram.", "type": "array", "items": { "$ref": "#/components/schemas/Binuint8" } }, + "max": { + "description": "The maximum value of all samples in the histogram.", + "type": "integer", + "format": "uint8", + "minimum": 0 + }, + "min": { + "description": "The minimum value of all samples in the histogram.", + "type": "integer", + "format": "uint8", + "minimum": 0 + }, "n_samples": { + "description": "The total number of samples in the histogram.", "type": "integer", "format": "uint64", "minimum": 0 }, + "p50": { + "description": "p50 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p90": { + "description": "p95 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "p99": { + "description": "p99 Quantile", + "allOf": [ + { + "$ref": "#/components/schemas/Quantile" + } + ] + }, + "squared_mean": { + "description": "M2 for Welford's algorithm for variance calculation.\n\nRead about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) for more information on the algorithm.", + "type": "number", + "format": "double" + }, "start_time": { + "description": "The start time of the histogram.", "type": "string", "format": "date-time" + }, + "sum_of_samples": { + "description": "The sum of all samples in the histogram.", + "type": "integer", + "format": "int64" } }, "required": [ "bins", + "max", + "min", "n_samples", - "start_time" + "p50", + "p90", + "p99", + "squared_mean", + "start_time", + "sum_of_samples" ] }, "Hostname": { @@ -15756,6 +16392,54 @@ } } }, + "Quantile": { + "description": "Structure for estimating the p-quantile of a population.\n\nThis is based on the P² algorithm for estimating quantiles using constant space.\n\nThe algorithm consists of maintaining five markers: the minimum, the p/2-, p-, and (1 + p)/2 quantiles, and the maximum.", + "type": "object", + "properties": { + "desired_marker_positions": { + "description": "The desired marker positions.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "minItems": 5, + "maxItems": 5 + }, + "marker_heights": { + "description": "The heights of the markers.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "minItems": 5, + "maxItems": 5 + }, + "marker_positions": { + "description": "The positions of the markers.\n\nWe track sample size in the 5th position, as useful observations won't start until we've filled the heights at the 6th sample anyway This does deviate from the paper, but it's a more useful representation that works according to the paper's algorithm.", + "type": "array", + "items": { + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "minItems": 5, + "maxItems": 5 + }, + "p": { + "description": "The p value for the quantile.", + "type": "number", + "format": "double" + } + }, + "required": [ + "desired_marker_positions", + "marker_heights", + "marker_positions", + "p" + ] + }, "Rack": { "description": "View of an Rack", "type": "object", diff --git a/oximeter/db/schema/replicated/5/up01.sql b/oximeter/db/schema/replicated/5/up01.sql new file mode 100644 index 0000000000..5fd811bcbb --- /dev/null +++ b/oximeter/db/schema/replicated/5/up01.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami8_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up02.sql b/oximeter/db/schema/replicated/5/up02.sql new file mode 100644 index 0000000000..78f6bf30fc --- /dev/null +++ b/oximeter/db/schema/replicated/5/up02.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami8 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up03.sql b/oximeter/db/schema/replicated/5/up03.sql new file mode 100644 index 0000000000..79208d2c45 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up03.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami8_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Int8), + counts Array(UInt64), + min Int8, + max Int8, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogrami8_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up04.sql b/oximeter/db/schema/replicated/5/up04.sql new file mode 100644 index 0000000000..1c8a62d2a5 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up04.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami8 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogrami8_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogrami8_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up05.sql b/oximeter/db/schema/replicated/5/up05.sql new file mode 100644 index 0000000000..5736e4cfce --- /dev/null +++ b/oximeter/db/schema/replicated/5/up05.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu8_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up06.sql b/oximeter/db/schema/replicated/5/up06.sql new file mode 100644 index 0000000000..485c79dd7d --- /dev/null +++ b/oximeter/db/schema/replicated/5/up06.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu8 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up07.sql b/oximeter/db/schema/replicated/5/up07.sql new file mode 100644 index 0000000000..3fe9810a9e --- /dev/null +++ b/oximeter/db/schema/replicated/5/up07.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu8_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(UInt8), + counts Array(UInt64), + min UInt8, + max UInt8, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramu8_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up08.sql b/oximeter/db/schema/replicated/5/up08.sql new file mode 100644 index 0000000000..80cf392978 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up08.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu8 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogramu8_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramu8_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up09.sql b/oximeter/db/schema/replicated/5/up09.sql new file mode 100644 index 0000000000..5d43e5db84 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up09.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami16_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up10.sql b/oximeter/db/schema/replicated/5/up10.sql new file mode 100644 index 0000000000..ea2776fd06 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up10.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami16 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up11.sql b/oximeter/db/schema/replicated/5/up11.sql new file mode 100644 index 0000000000..ac5ef4fbb9 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up11.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami16_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Int16), + counts Array(UInt64), + min Int16, + max Int16, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogrami16_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up12.sql b/oximeter/db/schema/replicated/5/up12.sql new file mode 100644 index 0000000000..3e3cdd4e71 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up12.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami16 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogrami16_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogrami16_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up13.sql b/oximeter/db/schema/replicated/5/up13.sql new file mode 100644 index 0000000000..cfe3e278d4 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up13.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu16_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up14.sql b/oximeter/db/schema/replicated/5/up14.sql new file mode 100644 index 0000000000..4905db35c3 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up14.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu16 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up15.sql b/oximeter/db/schema/replicated/5/up15.sql new file mode 100644 index 0000000000..c505bb7892 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up15.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu16_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(UInt16), + counts Array(UInt64), + min UInt16, + max UInt16, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramu16_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up16.sql b/oximeter/db/schema/replicated/5/up16.sql new file mode 100644 index 0000000000..0a0607de26 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up16.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu16 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogramu16_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramu16_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up17.sql b/oximeter/db/schema/replicated/5/up17.sql new file mode 100644 index 0000000000..741cf9bed1 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up17.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami32_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up18.sql b/oximeter/db/schema/replicated/5/up18.sql new file mode 100644 index 0000000000..b4c7888e3e --- /dev/null +++ b/oximeter/db/schema/replicated/5/up18.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami32 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up19.sql b/oximeter/db/schema/replicated/5/up19.sql new file mode 100644 index 0000000000..391e77a1cf --- /dev/null +++ b/oximeter/db/schema/replicated/5/up19.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami32_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Int32), + counts Array(UInt64), + min Int32, + max Int32, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogrami32_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up20.sql b/oximeter/db/schema/replicated/5/up20.sql new file mode 100644 index 0000000000..4680183918 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up20.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami32 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogrami32_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogrami32_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up21.sql b/oximeter/db/schema/replicated/5/up21.sql new file mode 100644 index 0000000000..863ebdd677 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up21.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu32_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up22.sql b/oximeter/db/schema/replicated/5/up22.sql new file mode 100644 index 0000000000..969d0ec578 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up22.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu32 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up23.sql b/oximeter/db/schema/replicated/5/up23.sql new file mode 100644 index 0000000000..3b65222ab9 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up23.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu32_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(UInt32), + counts Array(UInt64), + min UInt32, + max UInt32, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramu32_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up24.sql b/oximeter/db/schema/replicated/5/up24.sql new file mode 100644 index 0000000000..8e66095c28 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up24.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu32 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogramu32_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramu32_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up25.sql b/oximeter/db/schema/replicated/5/up25.sql new file mode 100644 index 0000000000..79f1337bb6 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up25.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami64_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up26.sql b/oximeter/db/schema/replicated/5/up26.sql new file mode 100644 index 0000000000..be7ac420c3 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up26.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami64 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up27.sql b/oximeter/db/schema/replicated/5/up27.sql new file mode 100644 index 0000000000..716d450f18 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up27.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami64_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Int64), + counts Array(UInt64), + min Int64, + max Int64, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogrami64_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up28.sql b/oximeter/db/schema/replicated/5/up28.sql new file mode 100644 index 0000000000..81031811c4 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up28.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami64 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogrami64_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogrami64_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up29.sql b/oximeter/db/schema/replicated/5/up29.sql new file mode 100644 index 0000000000..e02de80c59 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up29.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu64_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up30.sql b/oximeter/db/schema/replicated/5/up30.sql new file mode 100644 index 0000000000..4f938b220c --- /dev/null +++ b/oximeter/db/schema/replicated/5/up30.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu64 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up31.sql b/oximeter/db/schema/replicated/5/up31.sql new file mode 100644 index 0000000000..603e78e668 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up31.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu64_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(UInt64), + counts Array(UInt64), + min UInt64, + max UInt64, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramu64_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up32.sql b/oximeter/db/schema/replicated/5/up32.sql new file mode 100644 index 0000000000..9fa2e1b730 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up32.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu64 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogramu64_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramu64_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up33.sql b/oximeter/db/schema/replicated/5/up33.sql new file mode 100644 index 0000000000..36bb01b64b --- /dev/null +++ b/oximeter/db/schema/replicated/5/up33.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramf32_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up34.sql b/oximeter/db/schema/replicated/5/up34.sql new file mode 100644 index 0000000000..00f8c60701 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up34.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramf32 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up35.sql b/oximeter/db/schema/replicated/5/up35.sql new file mode 100644 index 0000000000..c1ef9c505c --- /dev/null +++ b/oximeter/db/schema/replicated/5/up35.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf32_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Float32), + counts Array(UInt64), + min Float32, + max Float32, + sum_of_samples Float64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramf32_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up36.sql b/oximeter/db/schema/replicated/5/up36.sql new file mode 100644 index 0000000000..935eac5e8c --- /dev/null +++ b/oximeter/db/schema/replicated/5/up36.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf32 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogramf32_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramf32_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/5/up37.sql b/oximeter/db/schema/replicated/5/up37.sql new file mode 100644 index 0000000000..7a1a1e19d6 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up37.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramf64_local ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up38.sql b/oximeter/db/schema/replicated/5/up38.sql new file mode 100644 index 0000000000..c643d5532c --- /dev/null +++ b/oximeter/db/schema/replicated/5/up38.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramf64 ON CLUSTER oximeter_cluster SYNC; diff --git a/oximeter/db/schema/replicated/5/up39.sql b/oximeter/db/schema/replicated/5/up39.sql new file mode 100644 index 0000000000..703832106a --- /dev/null +++ b/oximeter/db/schema/replicated/5/up39.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf64_local ON CLUSTER oximeter_cluster +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Float64), + counts Array(UInt64), + min Float64, + max Float64, + sum_of_samples Float64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramf64_local', '{replica}') +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/replicated/5/up40.sql b/oximeter/db/schema/replicated/5/up40.sql new file mode 100644 index 0000000000..4f3e6c58a3 --- /dev/null +++ b/oximeter/db/schema/replicated/5/up40.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf64 ON CLUSTER oximeter_cluster +AS oximeter.measurements_histogramf64_local +ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramf64_local', xxHash64(splitByChar(':', timeseries_name)[1])); diff --git a/oximeter/db/schema/replicated/db-init.sql b/oximeter/db/schema/replicated/db-init.sql index 27df02b709..8f651b4510 100644 --- a/oximeter/db/schema/replicated/db-init.sql +++ b/oximeter/db/schema/replicated/db-init.sql @@ -374,21 +374,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami8_local ON CLUSTER ox start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Int8), - counts Array(UInt64) + counts Array(UInt64), + min Int8, + max Int8, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogrami8_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami8 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(Int8), - counts Array(UInt64) -) +AS oximeter.measurements_histogrami8_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogrami8_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu8_local ON CLUSTER oximeter_cluster @@ -398,21 +404,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu8_local ON CLUSTER ox start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(UInt8), - counts Array(UInt64) + counts Array(UInt64), + min UInt8, + max UInt8, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramu8_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu8 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(UInt8), - counts Array(UInt64) -) +AS oximeter.measurements_histogramu8_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramu8_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami16_local ON CLUSTER oximeter_cluster @@ -422,21 +434,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami16_local ON CLUSTER o start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Int16), - counts Array(UInt64) + counts Array(UInt64), + min Int16, + max Int16, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogrami16_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami16 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(Int16), - counts Array(UInt64) -) +AS oximeter.measurements_histogrami16_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogrami16_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu16_local ON CLUSTER oximeter_cluster @@ -446,21 +464,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu16_local ON CLUSTER o start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(UInt16), - counts Array(UInt64) + counts Array(UInt64), + min UInt16, + max UInt16, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramu16_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu16 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(UInt16), - counts Array(UInt64) -) +AS oximeter.measurements_histogramu16_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramu16_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami32_local ON CLUSTER oximeter_cluster @@ -470,21 +494,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami32_local ON CLUSTER o start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Int32), - counts Array(UInt64) + counts Array(UInt64), + min Int32, + max Int32, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogrami32_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami32 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(Int32), - counts Array(UInt64) -) +AS oximeter.measurements_histogrami32_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogrami32_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu32_local ON CLUSTER oximeter_cluster @@ -494,21 +524,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu32_local ON CLUSTER o start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(UInt32), - counts Array(UInt64) + counts Array(UInt64), + min UInt32, + max UInt32, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramu32_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu32 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(UInt32), - counts Array(UInt64) -) +AS oximeter.measurements_histogramu32_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramu32_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami64_local ON CLUSTER oximeter_cluster @@ -518,21 +554,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami64_local ON CLUSTER o start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Int64), - counts Array(UInt64) + counts Array(UInt64), + min Int64, + max Int64, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogrami64_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami64 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(Int64), - counts Array(UInt64) -) +AS oximeter.measurements_histogrami64_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogrami64_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu64_local ON CLUSTER oximeter_cluster @@ -542,21 +584,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu64_local ON CLUSTER o start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(UInt64), - counts Array(UInt64) + counts Array(UInt64), + min UInt64, + max UInt64, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramu64_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu64 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(UInt64), - counts Array(UInt64) -) +AS oximeter.measurements_histogramu64_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramu64_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf32_local ON CLUSTER oximeter_cluster @@ -566,21 +614,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf32_local ON CLUSTER o start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Float32), - counts Array(UInt64) + counts Array(UInt64), + min Float32, + max Float32, + sum_of_samples Float64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramf32_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf32 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(Float32), - counts Array(UInt64) -) +AS oximeter.measurements_histogramf32_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramf32_local', xxHash64(splitByChar(':', timeseries_name)[1])); CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf64_local ON CLUSTER oximeter_cluster @@ -590,21 +644,27 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf64_local ON CLUSTER o start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Float64), - counts Array(UInt64) + counts Array(UInt64), + min Float64, + max Float64, + sum_of_samples Float64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/measurements_histogramf64_local', '{replica}') ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) TTL toDateTime(timestamp) + INTERVAL 30 DAY; CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf64 ON CLUSTER oximeter_cluster -( - timeseries_name String, - timeseries_key UInt64, - start_time DateTime64(9, 'UTC'), - timestamp DateTime64(9, 'UTC'), - bins Array(Float64), - counts Array(UInt64) -) +AS oximeter.measurements_histogramf64_local ENGINE = Distributed('oximeter_cluster', 'oximeter', 'measurements_histogramf64_local', xxHash64(splitByChar(':', timeseries_name)[1])); /* The field tables store named dimensions of each timeseries. diff --git a/oximeter/db/schema/single-node/5/up01.sql b/oximeter/db/schema/single-node/5/up01.sql new file mode 100644 index 0000000000..41751aac7a --- /dev/null +++ b/oximeter/db/schema/single-node/5/up01.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami8; diff --git a/oximeter/db/schema/single-node/5/up02.sql b/oximeter/db/schema/single-node/5/up02.sql new file mode 100644 index 0000000000..ba9b2c1762 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up02.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami8 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Int8), + counts Array(UInt64), + min Int8, + max Int8, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up03.sql b/oximeter/db/schema/single-node/5/up03.sql new file mode 100644 index 0000000000..dec872f0ae --- /dev/null +++ b/oximeter/db/schema/single-node/5/up03.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu8; diff --git a/oximeter/db/schema/single-node/5/up04.sql b/oximeter/db/schema/single-node/5/up04.sql new file mode 100644 index 0000000000..1337a4ffe2 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up04.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu8 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(UInt8), + counts Array(UInt64), + min UInt8, + max UInt8, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up05.sql b/oximeter/db/schema/single-node/5/up05.sql new file mode 100644 index 0000000000..2a789beaf2 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up05.sql @@ -0,0 +1 @@ +DROP TABLE oximeter.measurements_histogrami16; diff --git a/oximeter/db/schema/single-node/5/up06.sql b/oximeter/db/schema/single-node/5/up06.sql new file mode 100644 index 0000000000..7aa8fa6696 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up06.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami16 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Int16), + counts Array(UInt64), + min Int16, + max Int16, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up07.sql b/oximeter/db/schema/single-node/5/up07.sql new file mode 100644 index 0000000000..3fb69b754b --- /dev/null +++ b/oximeter/db/schema/single-node/5/up07.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu16; diff --git a/oximeter/db/schema/single-node/5/up08.sql b/oximeter/db/schema/single-node/5/up08.sql new file mode 100644 index 0000000000..cbe0aedc05 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up08.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu16 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(UInt16), + counts Array(UInt64), + min UInt16, + max UInt16, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up09.sql b/oximeter/db/schema/single-node/5/up09.sql new file mode 100644 index 0000000000..c57462016b --- /dev/null +++ b/oximeter/db/schema/single-node/5/up09.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami32; diff --git a/oximeter/db/schema/single-node/5/up10.sql b/oximeter/db/schema/single-node/5/up10.sql new file mode 100644 index 0000000000..571cdfb924 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up10.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami32 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Int32), + counts Array(UInt64), + min Int32, + max Int32, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up11.sql b/oximeter/db/schema/single-node/5/up11.sql new file mode 100644 index 0000000000..5029f357aa --- /dev/null +++ b/oximeter/db/schema/single-node/5/up11.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu32; diff --git a/oximeter/db/schema/single-node/5/up12.sql b/oximeter/db/schema/single-node/5/up12.sql new file mode 100644 index 0000000000..c430ee9046 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up12.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu32 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(UInt32), + counts Array(UInt64), + min UInt32, + max UInt32, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up13.sql b/oximeter/db/schema/single-node/5/up13.sql new file mode 100644 index 0000000000..a1669359ef --- /dev/null +++ b/oximeter/db/schema/single-node/5/up13.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogrami64; diff --git a/oximeter/db/schema/single-node/5/up14.sql b/oximeter/db/schema/single-node/5/up14.sql new file mode 100644 index 0000000000..bda2eab542 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up14.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami64 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Int64), + counts Array(UInt64), + min Int64, + max Int64, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up15.sql b/oximeter/db/schema/single-node/5/up15.sql new file mode 100644 index 0000000000..3bd8b61024 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up15.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramu64; diff --git a/oximeter/db/schema/single-node/5/up16.sql b/oximeter/db/schema/single-node/5/up16.sql new file mode 100644 index 0000000000..8d6f07c96e --- /dev/null +++ b/oximeter/db/schema/single-node/5/up16.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu64 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(UInt64), + counts Array(UInt64), + min UInt64, + max UInt64, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up17.sql b/oximeter/db/schema/single-node/5/up17.sql new file mode 100644 index 0000000000..91d7743445 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up17.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramf32; diff --git a/oximeter/db/schema/single-node/5/up18.sql b/oximeter/db/schema/single-node/5/up18.sql new file mode 100644 index 0000000000..a8335944a7 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up18.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf32 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Float32), + counts Array(UInt64), + min Float32, + max Float32, + sum_of_samples Float64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/5/up19.sql b/oximeter/db/schema/single-node/5/up19.sql new file mode 100644 index 0000000000..f690feff00 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up19.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS oximeter.measurements_histogramf64; diff --git a/oximeter/db/schema/single-node/5/up20.sql b/oximeter/db/schema/single-node/5/up20.sql new file mode 100644 index 0000000000..ceed990747 --- /dev/null +++ b/oximeter/db/schema/single-node/5/up20.sql @@ -0,0 +1,25 @@ +CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf64 +( + timeseries_name String, + timeseries_key UInt64, + start_time DateTime64(9, 'UTC'), + timestamp DateTime64(9, 'UTC'), + bins Array(Float64), + counts Array(UInt64), + min Float64, + max Float64, + sum_of_samples Float64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) +) +ENGINE = MergeTree() +ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) +TTL toDateTime(timestamp) + INTERVAL 30 DAY; diff --git a/oximeter/db/schema/single-node/db-init.sql b/oximeter/db/schema/single-node/db-init.sql index 510c1071c8..38e9d0b70c 100644 --- a/oximeter/db/schema/single-node/db-init.sql +++ b/oximeter/db/schema/single-node/db-init.sql @@ -235,7 +235,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami8 * to figure out another way to represent missing samples here. */ bins Array(Int8), - counts Array(UInt64) + counts Array(UInt64), + min Int8, + max Int8, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -248,7 +261,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu8 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(UInt8), - counts Array(UInt64) + counts Array(UInt64), + min UInt8, + max UInt8, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -261,7 +287,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami16 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Int16), - counts Array(UInt64) + counts Array(UInt64), + min Int16, + max Int16, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -274,7 +313,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu16 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(UInt16), - counts Array(UInt64) + counts Array(UInt64), + min UInt16, + max UInt16, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -287,7 +339,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami32 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Int32), - counts Array(UInt64) + counts Array(UInt64), + min Int32, + max Int32, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -300,7 +365,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu32 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(UInt32), - counts Array(UInt64) + counts Array(UInt64), + min UInt32, + max UInt32, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -313,7 +391,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogrami64 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Int64), - counts Array(UInt64) + counts Array(UInt64), + min Int64, + max Int64, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -326,7 +417,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramu64 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(UInt64), - counts Array(UInt64) + counts Array(UInt64), + min UInt64, + max UInt64, + sum_of_samples Int64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -339,7 +443,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf32 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Float32), - counts Array(UInt64) + counts Array(UInt64), + min Float32, + max Float32, + sum_of_samples Float64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) @@ -352,7 +469,20 @@ CREATE TABLE IF NOT EXISTS oximeter.measurements_histogramf64 start_time DateTime64(9, 'UTC'), timestamp DateTime64(9, 'UTC'), bins Array(Float64), - counts Array(UInt64) + counts Array(UInt64), + min Float64, + max Float64, + sum_of_samples Float64, + squared_mean Float64, + p50_marker_heights Array(Float64), + p50_marker_positions Array(UInt64), + p50_desired_marker_positions Array(Float64), + p90_marker_heights Array(Float64), + p90_marker_positions Array(UInt64), + p90_desired_marker_positions Array(Float64), + p99_marker_heights Array(Float64), + p99_marker_positions Array(UInt64), + p99_desired_marker_positions Array(Float64) ) ENGINE = MergeTree() ORDER BY (timeseries_name, timeseries_key, start_time, timestamp) diff --git a/oximeter/db/src/bin/oxdb/oxql.rs b/oximeter/db/src/bin/oxdb/oxql.rs index 54e40afa15..ebe55dc7a7 100644 --- a/oximeter/db/src/bin/oxdb/oxql.rs +++ b/oximeter/db/src/bin/oxdb/oxql.rs @@ -11,6 +11,7 @@ use clap::Args; use crossterm::style::Stylize; use dropshot::EmptyScanParams; use dropshot::WhichPage; +use oximeter::TimeseriesSchema; use oximeter_db::oxql::query::special_idents; use oximeter_db::oxql::Table; use oximeter_db::Client; @@ -145,7 +146,70 @@ async fn list_timeseries(client: &Client) -> anyhow::Result<()> { } } -// Describe a single timeseries. +/// Prepare the columns for a timeseries or virtual table. +pub(crate) fn prepare_columns( + schema: &TimeseriesSchema, +) -> (Vec, Vec) { + let mut cols = Vec::with_capacity(schema.field_schema.len() + 2); + let mut types = cols.clone(); + + for field in schema.field_schema.iter() { + cols.push(field.name.clone()); + types.push(field.field_type.to_string()); + } + + cols.push(special_idents::TIMESTAMP.into()); + types.push(special_idents::DATETIME64.into()); + + if schema.datum_type.is_histogram() { + cols.push(special_idents::START_TIME.into()); + types.push(special_idents::DATETIME64.into()); + + cols.push(special_idents::BINS.into()); + types.push( + special_idents::array_type_name_from_histogram_type( + schema.datum_type, + ) + .unwrap(), + ); + + cols.push(special_idents::COUNTS.into()); + types.push(special_idents::ARRAYU64.into()); + + cols.push(special_idents::MIN.into()); + types.push(special_idents::FLOAT64.into()); + + cols.push(special_idents::MAX.into()); + types.push(special_idents::FLOAT64.into()); + + cols.push(special_idents::SUM_OF_SAMPLES.into()); + types.push(special_idents::UINT64.into()); + + cols.push(special_idents::SQUARED_MEAN.into()); + types.push(special_idents::UINT64.into()); + + for quantile in ["P50", "P90", "P99"].iter() { + cols.push(format!("{}_MARKER_HEIGHTS", quantile)); + types.push(special_idents::ARRAYFLOAT64.into()); + cols.push(format!("{}_MARKER_POSITIONS", quantile)); + types.push(special_idents::ARRAYINT64.into()); + cols.push(format!("{}_DESIRED_MARKER_POSITIONS", quantile)); + types.push(special_idents::ARRAYFLOAT64.into()); + } + } else if schema.datum_type.is_cumulative() { + cols.push(special_idents::START_TIME.into()); + types.push(special_idents::DATETIME64.into()); + cols.push(special_idents::DATUM.into()); + types.push(schema.datum_type.to_string()); + } else { + cols.push(special_idents::DATUM.into()); + types.push(schema.datum_type.to_string()); + } + + (cols, types) +} + +/// Describe a single timeseries. async fn describe_timeseries( client: &Client, timeseries: &str, @@ -158,40 +222,7 @@ async fn describe_timeseries( ), Ok(name) => { if let Some(schema) = client.schema_for_timeseries(&name).await? { - let mut cols = - Vec::with_capacity(schema.field_schema.len() + 2); - let mut types = cols.clone(); - for field in schema.field_schema.iter() { - cols.push(field.name.clone()); - types.push(field.field_type.to_string()); - } - cols.push(special_idents::TIMESTAMP.into()); - types.push(special_idents::DATETIME64.into()); - - if schema.datum_type.is_histogram() { - cols.push(special_idents::START_TIME.into()); - types.push(special_idents::DATETIME64.into()); - - cols.push(special_idents::BINS.into()); - types.push( - special_idents::array_type_name_from_histogram_type( - schema.datum_type, - ) - .unwrap(), - ); - - cols.push(special_idents::COUNTS.into()); - types.push(special_idents::ARRAYU64.into()); - } else if schema.datum_type.is_cumulative() { - cols.push(special_idents::START_TIME.into()); - types.push(special_idents::DATETIME64.into()); - cols.push(special_idents::DATUM.into()); - types.push(schema.datum_type.to_string()); - } else { - cols.push(special_idents::DATUM.into()); - types.push(schema.datum_type.to_string()); - } - + let (cols, types) = prepare_columns(&schema); let mut builder = tabled::builder::Builder::default(); builder.push_record(cols); // first record is the header builder.push_record(types); diff --git a/oximeter/db/src/bin/oxdb/sql.rs b/oximeter/db/src/bin/oxdb/sql.rs index d50a60f4d7..44780592fc 100644 --- a/oximeter/db/src/bin/oxdb/sql.rs +++ b/oximeter/db/src/bin/oxdb/sql.rs @@ -6,6 +6,7 @@ // Copyright 2024 Oxide Computer Company +use super::oxql; use crate::make_client; use clap::Args; use dropshot::EmptyScanParams; @@ -63,43 +64,7 @@ async fn describe_virtual_table( Err(_) => println!("Invalid timeseries name: {table}"), Ok(name) => { if let Some(schema) = client.schema_for_timeseries(&name).await? { - let mut cols = - Vec::with_capacity(schema.field_schema.len() + 2); - let mut types = cols.clone(); - for field in schema.field_schema.iter() { - cols.push(field.name.clone()); - types.push(field.field_type.to_string()); - } - cols.push("timestamp".into()); - types.push("DateTime64".into()); - - if schema.datum_type.is_histogram() { - cols.push("start_time".into()); - types.push("DateTime64".into()); - - cols.push("bins".into()); - types.push(format!( - "Array[{}]", - schema - .datum_type - .to_string() - .strip_prefix("Histogram") - .unwrap() - .to_lowercase(), - )); - - cols.push("counts".into()); - types.push("Array[u64]".into()); - } else if schema.datum_type.is_cumulative() { - cols.push("start_time".into()); - types.push("DateTime64".into()); - cols.push("datum".into()); - types.push(schema.datum_type.to_string()); - } else { - cols.push("datum".into()); - types.push(schema.datum_type.to_string()); - } - + let (cols, types) = oxql::prepare_columns(&schema); let mut builder = tabled::builder::Builder::default(); builder.push_record(cols); // first record is the header builder.push_record(types); diff --git a/oximeter/db/src/client/mod.rs b/oximeter/db/src/client/mod.rs index 0db71d195a..2d6212971e 100644 --- a/oximeter/db/src/client/mod.rs +++ b/oximeter/db/src/client/mod.rs @@ -4217,7 +4217,7 @@ mod tests { const FIRST_VERSION: u64 = 3; for version in FIRST_VERSION..=OXIMETER_VERSION { let upgrade_file_contents = Client::read_schema_upgrade_sql_files( - log, false, version, SCHEMA_DIR, + log, replicated, version, SCHEMA_DIR, ) .await .expect("failed to read schema upgrade files"); diff --git a/oximeter/db/src/client/oxql.rs b/oximeter/db/src/client/oxql.rs index d1ce131581..29586b8189 100644 --- a/oximeter/db/src/client/oxql.rs +++ b/oximeter/db/src/client/oxql.rs @@ -825,7 +825,13 @@ impl Client { datum_type: oximeter::DatumType, ) -> String { let value_columns = if datum_type.is_histogram() { - "timeseries_key, start_time, timestamp, bins, counts" + concat!( + "timeseries_key, start_time, timestamp, bins, counts, min, max, ", + "sum_of_samples, squared_mean, p50_marker_heights, p50_marker_positions, ", + "p50_desired_marker_positions, p90_marker_heights, p90_marker_positions, ", + "p90_desired_marker_positions, p99_marker_heights, p99_marker_positions, ", + "p99_desired_marker_positions" + ) } else if datum_type.is_cumulative() { "timeseries_key, start_time, timestamp, datum" } else { @@ -1203,7 +1209,7 @@ mod tests { // Create the first metric, starting from a count of 0. let mut metric = SomeMetric { foo: *foo, datum }; - // Create all the samples,, incrementing the datum and sample + // Create all the samples, incrementing the datum and sample // time. for i in 0..N_SAMPLES_PER_TIMESERIES { let sample_time = diff --git a/oximeter/db/src/model.rs b/oximeter/db/src/model.rs index 106c347ef6..e7f9f56b63 100644 --- a/oximeter/db/src/model.rs +++ b/oximeter/db/src/model.rs @@ -4,7 +4,7 @@ //! Models for timeseries data in ClickHouse -// Copyright 2023 Oxide Computer Company +// Copyright 2024 Oxide Computer Company use crate::DbFieldSource; use crate::FieldSchema; @@ -16,6 +16,7 @@ use crate::TimeseriesSchema; use bytes::Bytes; use chrono::DateTime; use chrono::Utc; +use num::traits::Zero; use oximeter::histogram::Histogram; use oximeter::traits; use oximeter::types::Cumulative; @@ -27,6 +28,7 @@ use oximeter::types::FieldValue; use oximeter::types::Measurement; use oximeter::types::MissingDatum; use oximeter::types::Sample; +use oximeter::Quantile; use serde::Deserialize; use serde::Serialize; use std::collections::BTreeMap; @@ -43,7 +45,7 @@ use uuid::Uuid; /// - [`crate::Client::initialize_db_with_version`] /// - [`crate::Client::ensure_schema`] /// - The `clickhouse-schema-updater` binary in this crate -pub const OXIMETER_VERSION: u64 = 4; +pub const OXIMETER_VERSION: u64 = 5; // Wrapper type to represent a boolean in the database. // @@ -446,15 +448,83 @@ declare_cumulative_measurement_row! { CumulativeU64MeasurementRow, u64, "cumulat declare_cumulative_measurement_row! { CumulativeF32MeasurementRow, f32, "cumulativef32" } declare_cumulative_measurement_row! { CumulativeF64MeasurementRow, f64, "cumulativef64" } +/// A representation of all quantiles for a histogram. +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq)] +struct AllQuantiles { + p50_marker_heights: [f64; 5], + p50_marker_positions: [u64; 5], + p50_desired_marker_positions: [f64; 5], + + p90_marker_heights: [f64; 5], + p90_marker_positions: [u64; 5], + p90_desired_marker_positions: [f64; 5], + + p99_marker_heights: [f64; 5], + p99_marker_positions: [u64; 5], + p99_desired_marker_positions: [f64; 5], +} + +impl AllQuantiles { + /// Create a flat `AllQuantiles` struct from the given quantiles. + fn flatten(q50: Quantile, q90: Quantile, q99: Quantile) -> Self { + Self { + p50_marker_heights: q50.marker_heights(), + p50_marker_positions: q50.marker_positions(), + p50_desired_marker_positions: q50.desired_marker_positions(), + + p90_marker_heights: q90.marker_heights(), + p90_marker_positions: q90.marker_positions(), + p90_desired_marker_positions: q90.desired_marker_positions(), + + p99_marker_heights: q99.marker_heights(), + p99_marker_positions: q99.marker_positions(), + p99_desired_marker_positions: q99.desired_marker_positions(), + } + } + + /// Split the quantiles into separate `Quantile` structs in order of P. + fn split(&self) -> (Quantile, Quantile, Quantile) { + ( + Quantile::from_parts( + 0.5, + self.p50_marker_heights, + self.p50_marker_positions, + self.p50_desired_marker_positions, + ), + Quantile::from_parts( + 0.9, + self.p90_marker_heights, + self.p90_marker_positions, + self.p90_desired_marker_positions, + ), + Quantile::from_parts( + 0.99, + self.p99_marker_heights, + self.p99_marker_positions, + self.p99_desired_marker_positions, + ), + ) + } +} + // Representation of a histogram in ClickHouse. // -// The tables storing measurements of a histogram metric use a pair of arrays to represent them, -// for the bins and counts, respectively. This handles conversion between the type used to -// represent histograms in Rust, [`Histogram`], and this in-database representation. +// The tables storing measurements of a histogram metric use a set of arrays to +// represent them. This handles conversion between the type used to represent +// histograms in Rust, [`Histogram`], and this in-database representation. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -struct DbHistogram { +struct DbHistogram +where + T: traits::HistogramSupport, +{ pub bins: Vec, pub counts: Vec, + pub min: T, + pub max: T, + pub sum_of_samples: T::Width, + pub squared_mean: f64, + #[serde(flatten)] + pub quantiles: AllQuantiles, } // We use an empty histogram to indicate a missing sample. @@ -467,9 +537,24 @@ struct DbHistogram { // // That means we can currently use an empty array from the database as a // sentinel for a missing sample. -impl DbHistogram { +impl DbHistogram +where + T: traits::HistogramSupport, +{ fn null() -> Self { - Self { bins: vec![], counts: vec![] } + let p50 = Quantile::p50(); + let p90 = Quantile::p90(); + let p99 = Quantile::p99(); + + Self { + bins: vec![], + counts: vec![], + min: T::zero(), + max: T::zero(), + sum_of_samples: T::Width::zero(), + squared_mean: 0.0, + quantiles: AllQuantiles::flatten(p50, p90, p99), + } } } @@ -478,8 +563,20 @@ where T: traits::HistogramSupport, { fn from(hist: &Histogram) -> Self { - let (bins, counts) = hist.to_arrays(); - Self { bins, counts } + let (bins, counts) = hist.bins_and_counts(); + Self { + bins, + counts, + min: hist.min(), + max: hist.max(), + sum_of_samples: hist.sum_of_samples(), + squared_mean: hist.squared_mean(), + quantiles: AllQuantiles::flatten( + hist.p50q(), + hist.p90q(), + hist.p99q(), + ), + } } } @@ -1255,7 +1352,10 @@ struct DbTimeseriesScalarCumulativeSample { // A histogram timestamped sample from a timeseries, as extracted from a query to the database. #[derive(Debug, Clone, Deserialize)] -struct DbTimeseriesHistogramSample { +struct DbTimeseriesHistogramSample +where + T: traits::HistogramSupport, +{ timeseries_key: TimeseriesKey, #[serde(with = "serde_timestamp")] start_time: DateTime, @@ -1263,6 +1363,12 @@ struct DbTimeseriesHistogramSample { timestamp: DateTime, bins: Vec, counts: Vec, + min: T, + max: T, + sum_of_samples: T::Width, + squared_mean: f64, + #[serde(flatten)] + quantiles: AllQuantiles, } impl From> for Measurement @@ -1314,14 +1420,30 @@ where .unwrap(), ) } else { - Datum::from( - Histogram::from_arrays( - sample.start_time, - sample.bins, - sample.counts, - ) - .unwrap(), + if sample.bins.len() != sample.counts.len() { + panic!( + "Array size mismatch: bins: {}, counts: {}", + sample.bins.len(), + sample.counts.len() + ); + } + + let (p50, p90, p99) = sample.quantiles.split(); + let hist = Histogram::from_parts( + sample.start_time, + sample.bins, + sample.counts, + sample.min, + sample.max, + sample.sum_of_samples, + sample.squared_mean, + p50, + p90, + p99, ) + .unwrap(); + + Datum::from(hist) }; Measurement::new(sample.timestamp, datum) } @@ -1475,12 +1597,16 @@ where (sample.timeseries_key, sample.into()) } -fn parse_timeseries_histogram_measurement( - line: &str, +fn parse_timeseries_histogram_measurement<'a, T>( + line: &'a str, ) -> (TimeseriesKey, Measurement) where - T: Into + traits::HistogramSupport + FromDbHistogram, + T: Into + + traits::HistogramSupport + + FromDbHistogram + + Deserialize<'a>, Datum: From>, + ::Width: Deserialize<'a>, { let sample = serde_json::from_str::>(line).unwrap(); @@ -1741,6 +1867,7 @@ pub(crate) fn parse_field_select_row( mod tests { use super::*; use chrono::Timelike; + use oximeter::histogram::Record; use oximeter::test_util; use oximeter::Datum; @@ -1826,9 +1953,18 @@ mod tests { hist.sample(1).unwrap(); hist.sample(10).unwrap(); let dbhist = DbHistogram::from(&hist); - let (bins, counts) = hist.to_arrays(); + let (bins, counts) = hist.bins_and_counts(); assert_eq!(dbhist.bins, bins); assert_eq!(dbhist.counts, counts); + assert_eq!(dbhist.min, hist.min()); + assert_eq!(dbhist.max, hist.max()); + assert_eq!(dbhist.sum_of_samples, hist.sum_of_samples()); + assert_eq!(dbhist.squared_mean, hist.squared_mean()); + + let (p50, p90, p99) = dbhist.quantiles.split(); + assert_eq!(p50, hist.p50q()); + assert_eq!(p90, hist.p90q()); + assert_eq!(p99, hist.p99q()); } #[test] @@ -1877,10 +2013,20 @@ mod tests { assert_eq!(table_name, "oximeter.measurements_histogramf64"); let unpacked: HistogramF64MeasurementRow = serde_json::from_str(&row).unwrap(); - let unpacked_hist = Histogram::from_arrays( + let (unpacked_p50, unpacked_p90, unpacked_p99) = + unpacked.datum.quantiles.split(); + + let unpacked_hist = Histogram::from_parts( unpacked.start_time, unpacked.datum.bins, unpacked.datum.counts, + unpacked.datum.min, + unpacked.datum.max, + unpacked.datum.sum_of_samples, + unpacked.datum.squared_mean, + unpacked_p50, + unpacked_p90, + unpacked_p99, ) .unwrap(); let measurement = &sample.measurement; @@ -1986,7 +2132,27 @@ mod tests { .with_nanosecond(123_456_789) .unwrap(); - let line = r#"{"timeseries_key": 12, "start_time": "2021-01-01 00:00:00.123456789", "timestamp": "2021-01-01 01:00:00.123456789", "bins": [0, 1], "counts": [1, 1] }"#; + let line = r#" + { + "timeseries_key": 12, + "start_time": "2021-01-01 00:00:00.123456789", + "timestamp": "2021-01-01 01:00:00.123456789", + "bins": [0, 1], + "counts": [1, 1], + "min": 0, + "max": 1, + "sum_of_samples": 2, + "squared_mean": 2.0, + "p50_marker_heights": [0.0, 0.0, 0.0, 0.0, 1.0], + "p50_marker_positions": [1, 2, 3, 4, 2], + "p50_desired_marker_positions": [1.0, 3.0, 5.0, 5.0, 5.0], + "p90_marker_heights": [0.0, 0.0, 0.0, 0.0, 1.0], + "p90_marker_positions": [1, 2, 3, 4, 2], + "p90_desired_marker_positions": [1.0, 3.0, 5.0, 5.0, 5.0], + "p99_marker_heights": [0.0, 0.0, 0.0, 0.0, 1.0], + "p99_marker_positions": [1, 2, 3, 4, 2], + "p99_desired_marker_positions": [1.0, 3.0, 5.0, 5.0, 5.0] + }"#; let (key, measurement) = parse_measurement_from_row(line, DatumType::HistogramI64); assert_eq!(key, 12); @@ -1997,6 +2163,38 @@ mod tests { }; assert_eq!(hist.n_bins(), 3); assert_eq!(hist.n_samples(), 2); + assert_eq!(hist.min(), 0); + assert_eq!(hist.max(), 1); + assert_eq!(hist.sum_of_samples(), 2); + assert_eq!(hist.squared_mean(), 2.); + assert_eq!( + hist.p50q(), + Quantile::from_parts( + 0.5, + [0.0, 0.0, 0.0, 0.0, 1.0], + [1, 2, 3, 4, 2], + [1.0, 3.0, 5.0, 5.0, 5.0], + ) + ); + assert_eq!( + hist.p90q(), + Quantile::from_parts( + 0.9, + [0.0, 0.0, 0.0, 0.0, 1.0], + [1, 2, 3, 4, 2], + [1.0, 3.0, 5.0, 5.0, 5.0], + ) + ); + + assert_eq!( + hist.p99q(), + Quantile::from_parts( + 0.99, + [0.0, 0.0, 0.0, 0.0, 1.0], + [1, 2, 3, 4, 2], + [1.0, 3.0, 5.0, 5.0, 5.0], + ) + ); } #[test] @@ -2007,32 +2205,6 @@ mod tests { assert_eq!(measurement.datum(), &Datum::from("/some/path")); } - #[test] - fn test_histogram_to_arrays() { - let mut hist = Histogram::new(&[0, 10, 20]).unwrap(); - hist.sample(1).unwrap(); - hist.sample(11).unwrap(); - - let (bins, counts) = hist.to_arrays(); - assert_eq!( - bins.len(), - counts.len(), - "Bins and counts should have the same size" - ); - assert_eq!( - bins.len(), - hist.n_bins(), - "Paired-array bins should be of the same length as the histogram" - ); - assert_eq!(counts, &[0, 1, 1, 0], "Paired-array counts are incorrect"); - - let rebuilt = - Histogram::from_arrays(hist.start_time(), bins, counts).unwrap(); - assert_eq!( - hist, rebuilt, - "Histogram reconstructed from paired arrays is not correct" - ); - } #[test] fn test_parse_bytes_measurement() { let s = r#"{"timeseries_key": 101, "timestamp": "2023-11-21 18:25:21.963714255", "datum": "\u0001\u0002\u0003"}"#; diff --git a/oximeter/db/src/oxql/ast/table_ops/filter.rs b/oximeter/db/src/oxql/ast/table_ops/filter.rs index 4e838f3388..9e796bc730 100644 --- a/oximeter/db/src/oxql/ast/table_ops/filter.rs +++ b/oximeter/db/src/oxql/ast/table_ops/filter.rs @@ -518,8 +518,9 @@ fn implicit_field_names( MetricType::Gauge, DataType::IntegerDistribution | DataType::DoubleDistribution, ) => { - out.insert(special_idents::BINS); - out.insert(special_idents::COUNTS); + special_idents::DISTRIBUTION_IDENTS.iter().for_each(|ident| { + out.insert(ident); + }); } // Scalars, either delta or cumulatives. ( @@ -534,8 +535,9 @@ fn implicit_field_names( MetricType::Delta | MetricType::Cumulative, DataType::IntegerDistribution | DataType::DoubleDistribution, ) => { - out.insert(special_idents::BINS); - out.insert(special_idents::COUNTS); + special_idents::DISTRIBUTION_IDENTS.iter().for_each(|ident| { + out.insert(ident); + }); out.insert(special_idents::START_TIME); } // Impossible combinations diff --git a/oximeter/db/src/oxql/point.rs b/oximeter/db/src/oxql/point.rs index e12214aaf0..7805ec64be 100644 --- a/oximeter/db/src/oxql/point.rs +++ b/oximeter/db/src/oxql/point.rs @@ -11,12 +11,15 @@ use anyhow::Context; use chrono::DateTime; use chrono::Utc; use num::ToPrimitive; +use oximeter::traits::HistogramSupport; use oximeter::DatumType; use oximeter::Measurement; +use oximeter::Quantile; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; use std::fmt; +use std::ops::Sub; /// The type of each individual data point's value in a timeseries. #[derive( @@ -1428,7 +1431,7 @@ impl ValueArray { CumulativeDatum::DoubleDistribution(last), oximeter::Datum::HistogramF32(new), ) => { - let new = Distribution::from(new); + let new = Distribution::::from(new); self.as_double_distribution_mut()? .push(Some(new.checked_sub(&last)?)); } @@ -1436,7 +1439,7 @@ impl ValueArray { CumulativeDatum::DoubleDistribution(last), oximeter::Datum::HistogramF64(new), ) => { - let new = Distribution::from(new); + let new = Distribution::::from(new); self.as_double_distribution_mut()? .push(Some(new.checked_sub(&last)?)); } @@ -1517,15 +1520,30 @@ pub trait DistributionSupport: impl DistributionSupport for i64 {} impl DistributionSupport for f64 {} -/// A distribution is a sequence of bins and counts in those bins. +/// A distribution is a sequence of bins and counts in those bins, and some +/// statistical information tracked to compute the mean, standard deviation, and +/// quantile estimates. +/// +/// Min, max, and the p-* quantiles are treated as optional due to the +/// possibility of distribution operations, like subtraction. #[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)] #[schemars(rename = "Distribution{T}")] pub struct Distribution { bins: Vec, counts: Vec, + min: Option, + max: Option, + sum_of_samples: T, + squared_mean: f64, + p50: Option, + p90: Option, + p99: Option, } -impl fmt::Display for Distribution { +impl fmt::Display for Distribution +where + T: DistributionSupport + HistogramSupport + Sub, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let elems = self .bins @@ -1534,12 +1552,52 @@ impl fmt::Display for Distribution { .map(|(bin, count)| format!("{bin}: {count}")) .collect::>() .join(", "); - write!(f, "{}", elems) + + let unwrap_estimate = |opt: Option| { + opt.map_or("None".to_string(), |v| match v.estimate() { + Ok(v) => v.to_string(), + Err(err) => err.to_string(), + }) + }; + + let p50_estimate = unwrap_estimate(self.p50); + let p90_estimate = unwrap_estimate(self.p90); + let p99_estimate = unwrap_estimate(self.p99); + + write!( + f, + "{}, min: {}, max: {}, mean: {}, std_dev: {}, p50: {}, p90: {}, p99: {}", + elems, + self.min.map_or("none".to_string(), |m| m.to_string()), + self.max.unwrap_or_default(), + self.mean(), + self.std_dev().unwrap_or_default(), + p50_estimate, + p90_estimate, + p99_estimate + ) } } -impl Distribution { - // Subtract two distributions, checking that they have the same bins. +impl Distribution +where + T: DistributionSupport + HistogramSupport + Sub, +{ + /// Subtract two distributions, checking that they have the same bins. + /// + /// Min and max values are returned as None, as they lose meaning + /// when subtracting distributions. The same is true for p50, p90, and p99 + /// quantiles. + /// + /// TODO: It's not really clear how to compute the "difference" of two + /// histograms for items like min, max, p*'s. It's certainly not linear, and + /// although we might be able to make some estimates in the case of min and + /// max, we'll defer it for now. Instead, we'll store None for all these + /// values when computing the diff. They will be very useful later, when we + /// start generating distributions in OxQL itself, from a sequence of + /// scalars (similar to a DTrace aggregation). We'll wait to put that in + /// place until we have more data that we want to start aggregating that + /// way. fn checked_sub( &self, rhs: &Distribution, @@ -1548,14 +1606,34 @@ impl Distribution { self.bins == rhs.bins, "Cannot subtract distributions with different bins", ); - let counts = self + let counts: Vec<_> = self .counts .iter() - .zip(rhs.counts.iter().copied()) - .map(|(x, y)| x.checked_sub(y)) + .zip(rhs.counts.iter()) + .map(|(x, y)| x.checked_sub(*y)) .collect::>() .context("Underflow subtracting distributions values")?; - Ok(Self { bins: self.bins.clone(), counts }) + + // Subtract sum_of_samples. + // This can be negative as T is either i64 or f64. + let sum_of_samples = self.sum_of_samples - rhs.sum_of_samples; + + // Squared means are not linear, so we subtract the means and then + // square that number. + let sub_means = self.mean() - rhs.mean(); + let squared_mean = sub_means.powi(2); + + Ok(Self { + bins: self.bins.clone(), + counts, + min: None, + max: None, + sum_of_samples, + squared_mean, + p50: None, + p90: None, + p99: None, + }) } /// Return the slice of bins. @@ -1568,6 +1646,85 @@ impl Distribution { &self.counts } + /// Return the number of samples in the distribution. + pub fn n_samples(&self) -> u64 { + self.counts.iter().sum() + } + + /// Return the minimum value in the distribution. + pub fn min(&self) -> Option { + self.min + } + + /// Return the maximum value in the distribution. + pub fn max(&self) -> Option { + self.max + } + + /// Return the mean of the distribution. + pub fn mean(&self) -> f64 { + if self.n_samples() > 0 { + // We can unwrap here because we know n_samples() > 0, + // so the sum_of_samples should convert to f64 without issue. + self.sum_of_samples + .to_f64() + .map(|sum| sum / (self.n_samples() as f64)) + .unwrap() + } else { + 0. + } + } + + /// Return the variance for inputs to the histogram based on the Welford's + /// algorithm, using the squared mean (M2). + /// + /// Returns `None` if there are fewer than two samples. + pub fn variance(&self) -> Option { + (self.n_samples() > 1) + .then(|| self.squared_mean / (self.n_samples() as f64)) + } + + /// Return the sample variance for inputs to the histogram based on the + /// Welford's algorithm, using the squared mean (M2). + /// + /// Returns `None` if there are fewer than two samples. + pub fn sample_variance(&self) -> Option { + (self.n_samples() > 1) + .then(|| self.squared_mean / ((self.n_samples() - 1) as f64)) + } + + /// Return the standard deviation for inputs to the histogram. + /// + /// This is a biased (as a consequence of Jensen’s inequality), estimate of + /// the population deviation that returns the standard deviation of the + /// samples seen by the histogram. + /// + /// Returns `None` if the variance is `None`, i.e., if there are fewer than + /// two samples. + pub fn std_dev(&self) -> Option { + match self.variance() { + Some(variance) => Some(variance.sqrt()), + None => None, + } + } + + /// Return the "corrected" sample standard deviation for inputs to the + /// histogram. + /// + /// This is an unbiased estimate of the population deviation, applying + /// Bessel's correction, which corrects the bias in the estimation of the + /// population variance, and some, but not all of the bias in the estimation + /// of the population standard deviation. + /// + /// Returns `None` if the variance is `None`, i.e., if there are fewer than + /// two samples. + pub fn sample_std_dev(&self) -> Option { + match self.sample_variance() { + Some(variance) => Some(variance.sqrt()), + None => None, + } + } + /// Return an iterator over each bin and count. pub fn iter(&self) -> impl ExactSizeIterator + '_ { self.bins.iter().zip(self.counts.iter()) @@ -1578,8 +1735,18 @@ macro_rules! i64_dist_from { ($t:ty) => { impl From<&oximeter::histogram::Histogram<$t>> for Distribution { fn from(hist: &oximeter::histogram::Histogram<$t>) -> Self { - let (bins, counts) = hist.to_arrays(); - Self { bins: bins.into_iter().map(i64::from).collect(), counts } + let (bins, counts) = hist.bins_and_counts(); + Self { + bins: bins.into_iter().map(i64::from).collect(), + counts, + min: Some(hist.min() as i64), + max: Some(hist.max() as i64), + sum_of_samples: hist.sum_of_samples(), + squared_mean: hist.squared_mean(), + p50: Some(hist.p50q()), + p90: Some(hist.p90q()), + p99: Some(hist.p99q()), + } } } @@ -1604,13 +1771,23 @@ impl TryFrom<&oximeter::histogram::Histogram> for Distribution { fn try_from( hist: &oximeter::histogram::Histogram, ) -> Result { - let (bins, counts) = hist.to_arrays(); + let (bins, counts) = hist.bins_and_counts(); let bins = bins .into_iter() .map(i64::try_from) .collect::>() .context("Overflow converting u64 to i64")?; - Ok(Self { bins, counts }) + Ok(Self { + bins, + counts, + min: Some(hist.min() as i64), + max: Some(hist.max() as i64), + sum_of_samples: hist.sum_of_samples(), + squared_mean: hist.squared_mean(), + p50: Some(hist.p50q()), + p90: Some(hist.p90q()), + p99: Some(hist.p99q()), + }) } } @@ -1627,8 +1804,18 @@ macro_rules! f64_dist_from { ($t:ty) => { impl From<&oximeter::histogram::Histogram<$t>> for Distribution { fn from(hist: &oximeter::histogram::Histogram<$t>) -> Self { - let (bins, counts) = hist.to_arrays(); - Self { bins: bins.into_iter().map(f64::from).collect(), counts } + let (bins, counts) = hist.bins_and_counts(); + Self { + bins: bins.into_iter().map(f64::from).collect(), + counts, + min: Some(hist.min() as f64), + max: Some(hist.max() as f64), + sum_of_samples: hist.sum_of_samples() as f64, + squared_mean: hist.squared_mean(), + p50: Some(hist.p50q()), + p90: Some(hist.p90q()), + p99: Some(hist.p99q()), + } } } @@ -1645,12 +1832,12 @@ f64_dist_from!(f64); #[cfg(test)] mod tests { - use crate::oxql::point::{DataType, ValueArray}; - use super::{Distribution, MetricType, Points, Values}; + use crate::oxql::point::{DataType, ValueArray}; use chrono::{DateTime, Utc}; - use oximeter::types::Cumulative; - use oximeter::Measurement; + use oximeter::{ + histogram::Record, types::Cumulative, Measurement, Quantile, + }; use std::time::Duration; #[test] @@ -1747,6 +1934,38 @@ mod tests { ); } + #[test] + fn test_sub_between_histogram_distributions() { + let now = Utc::now(); + let current1 = now + Duration::from_secs(1); + let mut hist1 = + oximeter::histogram::Histogram::new(&[0i64, 10, 20]).unwrap(); + hist1.sample(1).unwrap(); + hist1.set_start_time(current1); + let current2 = now + Duration::from_secs(2); + let mut hist2 = + oximeter::histogram::Histogram::new(&[0i64, 10, 20]).unwrap(); + hist2.sample(5).unwrap(); + hist2.sample(10).unwrap(); + hist2.sample(15).unwrap(); + hist2.set_start_time(current2); + let dist1 = Distribution::from(&hist1); + let dist2 = Distribution::from(&hist2); + + let diff = dist2.checked_sub(&dist1).unwrap(); + assert_eq!(diff.bins(), &[i64::MIN, 0, 10, 20]); + assert_eq!(diff.counts(), &[0, 0, 2, 0]); + assert_eq!(diff.n_samples(), 2); + assert!(diff.min().is_none()); + assert!(diff.max().is_none()); + assert_eq!(diff.mean(), 14.5); + assert_eq!(diff.std_dev(), Some(6.363961030678928)); + assert_eq!(diff.sample_std_dev(), Some(9.0)); + assert!(diff.p50.is_none()); + assert!(diff.p90.is_none()); + assert!(diff.p99.is_none()); + } + fn timestamps(n: usize) -> Vec> { let now = Utc::now(); let mut out = Vec::with_capacity(n); @@ -1972,7 +2191,17 @@ mod tests { timestamps: timestamps(1), values: vec![Values { values: ValueArray::IntegerDistribution(vec![Some( - Distribution { bins: vec![0, 1, 2], counts: vec![0; 3] }, + Distribution { + bins: vec![0, 1, 2], + counts: vec![0; 3], + min: Some(0), + max: Some(2), + sum_of_samples: 0, + squared_mean: 0.0, + p50: Some(Quantile::p50()), + p90: Some(Quantile::p90()), + p99: Some(Quantile::p99()), + }, )]), metric_type: MetricType::Gauge, }], @@ -2012,6 +2241,13 @@ mod tests { Distribution { bins: vec![0.0, 1.0, 2.0], counts: vec![0; 3], + min: Some(0.0), + max: Some(2.0), + sum_of_samples: 0.0, + squared_mean: 0.0, + p50: Some(Quantile::p50()), + p90: Some(Quantile::p90()), + p99: Some(Quantile::p99()), }, )]), metric_type: MetricType::Gauge, diff --git a/oximeter/db/src/oxql/query/mod.rs b/oximeter/db/src/oxql/query/mod.rs index 1c4383d68d..40a6c82f93 100644 --- a/oximeter/db/src/oxql/query/mod.rs +++ b/oximeter/db/src/oxql/query/mod.rs @@ -29,13 +29,45 @@ use std::time::Duration; pub mod special_idents { use oximeter::DatumType; + macro_rules! gen_marker { + ($p:expr, $field:expr) => { + concat!("p", $p, "_", $field) + }; + } + pub const TIMESTAMP: &str = "timestamp"; pub const START_TIME: &str = "start_time"; pub const DATUM: &str = "datum"; pub const BINS: &str = "bins"; pub const COUNTS: &str = "counts"; + pub const MIN: &str = "min"; + pub const MAX: &str = "max"; + pub const SUM_OF_SAMPLES: &str = "sum_of_samples"; + pub const SQUARED_MEAN: &str = "squared_mean"; pub const DATETIME64: &str = "DateTime64"; pub const ARRAYU64: &str = "Array[u64]"; + pub const ARRAYFLOAT64: &str = "Array[f64]"; + pub const ARRAYINT64: &str = "Array[i64]"; + pub const FLOAT64: &str = "f64"; + pub const UINT64: &str = "u64"; + + pub const DISTRIBUTION_IDENTS: [&str; 15] = [ + "bins", + "counts", + "min", + "max", + "sum_of_samples", + "squared_mean", + gen_marker!("50", "marker_heights"), + gen_marker!("50", "marker_positions"), + gen_marker!("50", "desired_marker_positions"), + gen_marker!("90", "marker_heights"), + gen_marker!("90", "marker_positions"), + gen_marker!("90", "desired_marker_positions"), + gen_marker!("99", "marker_heights"), + gen_marker!("99", "marker_positions"), + gen_marker!("99", "desired_marker_positions"), + ]; pub fn array_type_name_from_histogram_type( type_: DatumType, diff --git a/oximeter/db/src/sql/mod.rs b/oximeter/db/src/sql/mod.rs index f3082dcaa5..e434608b1c 100644 --- a/oximeter/db/src/sql/mod.rs +++ b/oximeter/db/src/sql/mod.rs @@ -610,12 +610,31 @@ impl RestrictedQuery { // Return the required measurement columns for a specific datum type. // // Scalar measurements have only a timestamp and datum. Cumulative counters - // have those plus a start_time. And histograms have those plus the bins. + // have those plus a start_time. And histograms have those plus the bins, + // counts, min, max, sum of samples, sum of squares, and quantile arrays. fn datum_type_to_columns( datum_type: &DatumType, ) -> &'static [&'static str] { if datum_type.is_histogram() { - &["start_time", "timestamp", "bins", "counts"] + &[ + "start_time", + "timestamp", + "bins", + "counts", + "min", + "max", + "sum_of_samples", + "squared_mean", + "p50_marker_heights", + "p50_marker_positions", + "p50_desired_marker_positions", + "p90_marker_heights", + "p90_marker_positions", + "p90_desired_marker_positions", + "p99_marker_heights", + "p99_marker_positions", + "p99_desired_marker_positions", + ] } else if datum_type.is_cumulative() { &["start_time", "timestamp", "datum"] } else { diff --git a/oximeter/instruments/src/http.rs b/oximeter/instruments/src/http.rs index dcbaf65c06..4bc6cf8677 100644 --- a/oximeter/instruments/src/http.rs +++ b/oximeter/instruments/src/http.rs @@ -12,8 +12,10 @@ use dropshot::{ use futures::Future; use http::StatusCode; use http::Uri; -use oximeter::histogram::Histogram; -use oximeter::{Metric, MetricsError, Producer, Sample, Target}; +use oximeter::{ + histogram::Histogram, histogram::Record, Metric, MetricsError, Producer, + Sample, Target, +}; use std::collections::BTreeMap; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; diff --git a/oximeter/oximeter/Cargo.toml b/oximeter/oximeter/Cargo.toml index 2445e0483a..0fe52bc4ac 100644 --- a/oximeter/oximeter/Cargo.toml +++ b/oximeter/oximeter/Cargo.toml @@ -11,6 +11,7 @@ workspace = true [dependencies] bytes = { workspace = true, features = [ "serde" ] } chrono.workspace = true +float-ord.workspace = true num.workspace = true omicron-common.workspace = true oximeter-macro-impl.workspace = true @@ -25,6 +26,8 @@ omicron-workspace-hack.workspace = true [dev-dependencies] approx.workspace = true +rand = { workspace = true, features = ["std_rng"] } +rand_distr.workspace = true rstest.workspace = true serde_json.workspace = true trybuild.workspace = true diff --git a/oximeter/oximeter/src/histogram.rs b/oximeter/oximeter/src/histogram.rs index 82b9916153..9ce7b65121 100644 --- a/oximeter/oximeter/src/histogram.rs +++ b/oximeter/oximeter/src/histogram.rs @@ -4,23 +4,28 @@ //! Types for managing metrics that are histograms. -// Copyright 2023 Oxide Computer Company +// Copyright 2024 Oxide Computer Company +use super::Quantile; +use super::QuantileError; use chrono::DateTime; use chrono::Utc; use num::traits::Bounded; use num::traits::FromPrimitive; use num::traits::Num; use num::traits::ToPrimitive; +use num::traits::Zero; +use num::CheckedAdd; +use num::CheckedMul; use num::Float; use num::Integer; use num::NumCast; use schemars::JsonSchema; -use serde::de::DeserializeOwned; use serde::Deserialize; use serde::Serialize; use std::cmp::Ordering; use std::num::NonZeroUsize; +use std::ops::AddAssign; use std::ops::Bound; use std::ops::Range; use std::ops::RangeBounds; @@ -37,24 +42,34 @@ pub trait HistogramSupport: + Bounded + JsonSchema + Serialize - + DeserializeOwned + Clone + Num + + Zero + FromPrimitive + ToPrimitive + + AddAssign + NumCast + 'static { type Power; + type Width: HistogramAdditiveWidth; /// Return true if `self` is a finite number, not NAN or infinite. fn is_finite(&self) -> bool; } +/// Used for designating the subset of types that can be used as the width for +/// summing up values in a histogram. +pub trait HistogramAdditiveWidth: HistogramSupport {} + +impl HistogramAdditiveWidth for i64 {} +impl HistogramAdditiveWidth for f64 {} + macro_rules! impl_int_histogram_support { ($($type:ty),+) => { $( impl HistogramSupport for $type { type Power = u16; + type Width = i64; fn is_finite(&self) -> bool { true } @@ -70,6 +85,7 @@ macro_rules! impl_float_histogram_support { $( impl HistogramSupport for $type { type Power = i16; + type Width = f64; fn is_finite(&self) -> bool { <$type>::is_finite(*self) } @@ -93,8 +109,10 @@ pub enum HistogramError { NonmonotonicBins, /// A non-finite was encountered, either as a bin edge or a sample. - #[error("Bin edges and samples must be finite values, found: {0:?}")] - NonFiniteValue(String), + #[error( + "Bin edges and samples must be finite values, not Infinity or NaN" + )] + NonFiniteValue, /// Error returned when two neighboring bins are not adjoining (there's space between them) #[error("Neigboring bins {left} and {right} are not adjoining")] @@ -104,8 +122,13 @@ pub enum HistogramError { #[error("Bin and count arrays must have the same size, found {n_bins} and {n_counts}")] ArraySizeMismatch { n_bins: usize, n_counts: usize }, + /// Error returned when a quantization error occurs. #[error("Quantization error")] Quantization(#[from] QuantizationError), + + /// Error returned when a quantile error occurs. + #[error("Quantile error")] + Quantile(#[from] QuantileError), } /// Errors occurring during quantizated bin generation. @@ -272,6 +295,10 @@ pub struct Bin { pub count: u64, } +/// Internal, creation-specific newtype wrapper around `Vec>` to +/// implement conversion(s). +struct Bins(Vec>); + /// Histogram metric /// /// A histogram maintains the count of any number of samples, over a set of bins. Bins are @@ -333,12 +360,139 @@ pub struct Bin { // `Histogram::with_log_linear_bins()` are exactly the ones expected. #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] #[schemars(rename = "Histogram{T}")] -pub struct Histogram { +pub struct Histogram +where + T: HistogramSupport, +{ + /// The start time of the histogram. start_time: DateTime, + /// The bins of the histogram. bins: Vec>, + /// The total number of samples in the histogram. n_samples: u64, + /// The minimum value of all samples in the histogram. + min: T, + /// The maximum value of all samples in the histogram. + max: T, + /// The sum of all samples in the histogram. + sum_of_samples: T::Width, + /// M2 for Welford's algorithm for variance calculation. + /// + /// Read about [Welford's algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) + /// for more information on the algorithm. + squared_mean: f64, + /// p50 Quantile + p50: Quantile, + /// p95 Quantile + p90: Quantile, + /// p99 Quantile + p99: Quantile, } +/// A trait for recording samples into a histogram. +pub trait Record { + /// Add a new sample into the histogram. + /// + /// This bumps the internal counter at the bin containing `value`. An `Err` is returned if the + /// sample is not within the distribution's support (non-finite). + fn sample(&mut self, value: T) -> Result<(), HistogramError>; +} + +macro_rules! impl_int_sample { + ($($type:ty),+) => { + $( + impl Record<$type> for Histogram<$type> where $type: HistogramSupport + Integer + CheckedAdd + CheckedMul { + fn sample(&mut self, value: $type) -> Result<(), HistogramError> { + ensure_finite(value)?; + + if self.n_samples == 0 { + self.min = <$type>::max_value(); + self.max = <$type>::min_value(); + } + + // For squared mean (M2) calculation, before we update the + // count. + let value_f = value as f64; + let current_mean = self.mean(); + + let index = self + .bins + .binary_search_by(|bin| bin.range.cmp(&value).reverse()) + .unwrap(); // The `ensure_finite` call above catches values that don't end up in a bin + self.bins[index].count += 1; + self.n_samples += 1; + self.min = self.min.min(value); + self.max = self.max.max(value); + self.sum_of_samples = self.sum_of_samples.saturating_add(value as i64); + + let delta = value_f - current_mean; + let updated_mean = current_mean + delta / (self.n_samples as f64); + let delta2 = value_f - updated_mean; + self.squared_mean += (delta * delta2); + + self.p50.append(value)?; + self.p90.append(value)?; + self.p99.append(value)?; + Ok(()) + } + } + )+ + } +} + +impl_int_sample! { i8, u8, i16, u16, i32, u32, i64, u64 } + +macro_rules! impl_float_sample { + ($($type:ty),+) => { + $( + impl Record<$type> for Histogram<$type> where $type: HistogramSupport + Float { + fn sample(&mut self, value: $type) -> Result<(), HistogramError> { + ensure_finite(value)?; + + if self.n_samples == 0 { + self.min = <$type as num::Bounded>::max_value(); + self.max = <$type as num::Bounded>::min_value(); + } + + // For squared mean (M2) calculation, before we update the + // count. + let value_f = value as f64; + let current_mean = self.mean(); + + let index = self + .bins + .binary_search_by(|bin| bin.range.cmp(&value).reverse()) + .unwrap(); // The `ensure_finite` call above catches values that don't end up in a bin + self.bins[index].count += 1; + self.n_samples += 1; + + if value < self.min { + self.min = value; + } + if value > self.max { + self.max = value; + } + + self.sum_of_samples += value_f; + + let delta = value_f - current_mean; + let updated_mean = current_mean + delta / (self.n_samples as f64); + let delta2 = value_f - updated_mean; + self.squared_mean += (delta * delta2); + + self.p50.append(value)?; + self.p90.append(value)?; + self.p99.append(value)?; + + Ok(()) + } + } + )+ + } +} + +impl_float_sample! { f32, f64 } + impl Histogram where T: HistogramSupport, @@ -435,67 +589,82 @@ where if let Bound::Excluded(end) = bins_.last().unwrap().range.end_bound() { ensure_finite(*end)?; } - Ok(Self { start_time: Utc::now(), bins: bins_, n_samples: 0 }) + Ok(Self { + start_time: Utc::now(), + bins: bins_, + n_samples: 0, + min: T::zero(), + max: T::zero(), + sum_of_samples: T::Width::zero(), + squared_mean: 0.0, + p50: Quantile::p50(), + p90: Quantile::p90(), + p99: Quantile::p99(), + }) } /// Construct a new histogram from left bin edges. /// - /// The left edges of the bins must be specified as a non-empty, monotonically increasing - /// slice. An `Err` is returned if either constraint is violated. + /// The left edges of the bins must be specified as a non-empty, + /// monotonically increasing slice. An `Err` is returned if either + /// constraint is violated. pub fn new(left_edges: &[T]) -> Result { - let mut items = left_edges.iter(); - let mut bins = Vec::with_capacity(left_edges.len() + 1); - let mut current = *items.next().ok_or(HistogramError::EmptyBins)?; - ensure_finite(current)?; - let min = ::min_value(); - if current > min { - // Bin greater than the minimum was specified, insert a new one from `MIN..current`. - bins.push(Bin { range: BinRange::range(min, current), count: 0 }); - } else if current == min { - // An edge *at* the minimum was specified. Consume it, and insert a bin from - // `MIN..next`, if one exists. If one does not, or if this is the last item, the - // following loop will not be entered. - let next = - items.next().cloned().unwrap_or_else(::max_value); - bins.push(Bin { range: BinRange::range(min, next), count: 0 }); - current = next; - } - for &next in items { - if current < next { - ensure_finite(next)?; - bins.push(Bin { - range: BinRange::range(current, next), - count: 0, - }); - current = next; - } else if current >= next { - return Err(HistogramError::NonmonotonicBins); - } else { - return Err(HistogramError::NonFiniteValue(format!( - "{:?}", - current - ))); - } + let bins = Bins::try_from(left_edges)?; + Ok(Self { + start_time: Utc::now(), + bins: bins.0, + n_samples: 0, + min: T::zero(), + max: T::zero(), + sum_of_samples: T::Width::zero(), + squared_mean: 0.0, + p50: Quantile::p50(), + p90: Quantile::p90(), + p99: Quantile::p99(), + }) + } + + /// Construct a new histogram with the given struct information, including + /// bins, counts, and quantiles. + #[allow(clippy::too_many_arguments)] + pub fn from_parts( + start_time: DateTime, + bins: Vec, + counts: Vec, + min: T, + max: T, + sum_of_samples: T::Width, + squared_mean: f64, + p50: Quantile, + p90: Quantile, + p99: Quantile, + ) -> Result { + if bins.len() != counts.len() { + return Err(HistogramError::ArraySizeMismatch { + n_bins: bins.len(), + n_counts: counts.len(), + }); } - if current < ::max_value() { - bins.push(Bin { range: BinRange::from(current), count: 0 }); + + let mut bins = Bins::try_from(bins.as_slice())?.0; + let mut n_samples = 0; + for (bin, count) in bins.iter_mut().zip(counts.into_iter()) { + bin.count = count; + n_samples += count; } - Ok(Self { start_time: Utc::now(), bins, n_samples: 0 }) - } - /// Add a new sample into the histogram. - /// - /// This bumps the internal counter at the bin containing `value`. An `Err` is returned if the - /// sample is not within the distribution's support (non-finite). - pub fn sample(&mut self, value: T) -> Result<(), HistogramError> { - ensure_finite(value)?; - let index = self - .bins - .binary_search_by(|bin| bin.range.cmp(&value).reverse()) - .unwrap(); // The `ensure_finite` call above catches values that don't end up in a bin - self.bins[index].count += 1; - self.n_samples += 1; - Ok(()) + Ok(Self { + start_time, + bins, + n_samples, + min, + max, + sum_of_samples, + squared_mean, + p50, + p90, + p99, + }) } /// Return the total number of samples contained in the histogram. @@ -508,32 +677,18 @@ where self.bins.len() } - /// Iterate over the bins of the histogram. - pub fn iter(&self) -> impl Iterator> { - self.bins.iter() - } - - /// Get the bin at the given index. - pub fn get(&self, index: usize) -> Option<&Bin> { - self.bins.get(index) - } - - /// Generate paired arrays with the left bin edges and the counts, for each bin. - /// - /// The returned edges are always left-inclusive, by construction of the histogram. - pub fn to_arrays(&self) -> (Vec, Vec) { + /// Return the bins of the histogram. + pub fn bins_and_counts(&self) -> (Vec, Vec) { let mut bins = Vec::with_capacity(self.n_bins()); let mut counts = Vec::with_capacity(self.n_bins()); - - // The first bin may either be BinRange::To or BinRange::Range. for bin in self.bins.iter() { match bin.range { BinRange::Range { start, .. } => { bins.push(start); - }, - BinRange::RangeFrom{start} => { + } + BinRange::RangeFrom { start} => { bins.push(start); - }, + } _ => unreachable!("No bins in a constructed histogram should be of type RangeTo"), } counts.push(bin.count); @@ -541,33 +696,183 @@ where (bins, counts) } - /// Construct a histogram from a start time and paired arrays with the left bin-edge and counts. - pub fn from_arrays( - start_time: DateTime, - bins: Vec, - counts: Vec, - ) -> Result { - if bins.len() != counts.len() { - return Err(HistogramError::ArraySizeMismatch { - n_bins: bins.len(), - n_counts: counts.len(), - }); + /// Return the minimum value of inputs to the histogram. + pub fn min(&self) -> T { + self.min + } + + /// Return the maximum value of all inputs to the histogram. + pub fn max(&self) -> T { + self.max + } + + /// Return the sum of all inputs to the histogram. + pub fn sum_of_samples(&self) -> T::Width { + self.sum_of_samples + } + + /// Return the squared mean (M2) of all inputs to the histogram. + pub fn squared_mean(&self) -> f64 { + self.squared_mean + } + + /// Return the mean of all inputs/samples in the histogram. + pub fn mean(&self) -> f64 { + if self.n_samples() > 0 { + self.sum_of_samples + .to_f64() + .map(|sum| sum / (self.n_samples() as f64)) + .unwrap() + } else { + 0. } - let mut hist = Self::new(&bins)?; - hist.start_time = start_time; - let mut n_samples = 0; - for (bin, count) in hist.bins.iter_mut().zip(counts.into_iter()) { - bin.count = count; - n_samples += count; + } + + /// Return the variance for inputs to the histogram based on the Welford's + /// algorithm, using the squared mean (M2). + /// + /// Returns `None` if there are fewer than two samples. + pub fn variance(&self) -> Option { + (self.n_samples() > 1) + .then(|| self.squared_mean / (self.n_samples() as f64)) + } + + /// Return the sample variance for inputs to the histogram based on the + /// Welford's algorithm, using the squared mean (M2). + /// + /// Returns `None` if there are fewer than two samples. + pub fn sample_variance(&self) -> Option { + (self.n_samples() > 1) + .then(|| self.squared_mean / ((self.n_samples() - 1) as f64)) + } + + /// Return the standard deviation for inputs to the histogram. + /// + /// This is a biased (as a consequence of Jensen’s inequality), estimate of + /// the population deviation that returns the standard deviation of the + /// samples seen by the histogram. + /// + /// Returns `None` if the variance is `None`, i.e., if there are fewer than + /// two samples. + pub fn std_dev(&self) -> Option { + match self.variance() { + Some(variance) => Some(variance.sqrt()), + None => None, } - hist.n_samples = n_samples; - Ok(hist) } - /// Return the start time for this histogram + /// Return the "corrected" sample standard deviation for inputs to the + /// histogram. + /// + /// This is an unbiased estimate of the population deviation, applying + /// Bessel's correction, which corrects the bias in the estimation of the + /// population variance, and some, but not all of the bias in the estimation + /// of the population standard deviation. + /// + /// Returns `None` if the variance is `None`, i.e., if there are fewer than + /// two samples. + pub fn sample_std_dev(&self) -> Option { + match self.sample_variance() { + Some(variance) => Some(variance.sqrt()), + None => None, + } + } + + /// Iterate over the bins of the histogram. + pub fn iter(&self) -> impl Iterator> { + self.bins.iter() + } + + /// Get the bin at the given index. + pub fn get(&self, index: usize) -> Option<&Bin> { + self.bins.get(index) + } + + /// Return the start time for this histogram. pub fn start_time(&self) -> DateTime { self.start_time } + + /// Set the start time for this histogram. + pub fn set_start_time(&mut self, start_time: DateTime) { + self.start_time = start_time; + } + + /// Return the p50 quantile for the histogram. + pub fn p50q(&self) -> Quantile { + self.p50 + } + + /// Return the p90 quantile for the histogram. + pub fn p90q(&self) -> Quantile { + self.p90 + } + + /// Return the p99 quantile for the histogram. + pub fn p99q(&self) -> Quantile { + self.p99 + } + + /// Return the p50 estimate for the histogram. + pub fn p50(&self) -> Result { + self.p50.estimate() + } + + /// Return the p90 estimate for the histogram. + pub fn p90(&self) -> Result { + self.p90.estimate() + } + + /// Return the p99 estimate for the histogram. + pub fn p99(&self) -> Result { + self.p99.estimate() + } +} + +impl TryFrom<&[T]> for Bins +where + T: HistogramSupport, +{ + type Error = HistogramError; + + fn try_from(left_edges: &[T]) -> Result { + let mut items = left_edges.iter(); + let mut bins: Vec> = Vec::with_capacity(left_edges.len() + 1); + let mut current: T = *items.next().ok_or(HistogramError::EmptyBins)?; + ensure_finite(current)?; + let min: T = ::min_value(); + if current > min { + // Bin greater than the minimum was specified, insert a new one from `MIN..current`. + bins.push(Bin { range: BinRange::range(min, current), count: 0 }); + } else if current == min { + // An edge *at* the minimum was specified. Consume it, and insert a bin from + // `MIN..next`, if one exists. If one does not, or if this is the last item, the + // following loop will not be entered. + let next: T = + items.next().cloned().unwrap_or_else(::max_value); + bins.push(Bin { range: BinRange::range(min, next), count: 0 }); + current = next; + } + for &next in items { + if current < next { + ensure_finite(next)?; + bins.push(Bin { + range: BinRange::range(current, next), + count: 0, + }); + current = next; + } else if current >= next { + return Err(HistogramError::NonmonotonicBins); + } else { + return Err(HistogramError::NonFiniteValue); + } + } + if current < ::max_value() { + bins.push(Bin { range: BinRange::from(current), count: 0 }); + } + + Ok(Bins(bins)) + } } impl Histogram @@ -871,7 +1176,7 @@ where if value.is_finite() { Ok(()) } else { - Err(HistogramError::NonFiniteValue(format!("{:?}", value))) + Err(HistogramError::NonFiniteValue) } } @@ -938,20 +1243,77 @@ mod tests { "Histogram should have 1 more bin than bin edges specified" ); assert_eq!(hist.n_samples(), 0, "Histogram should init with 0 samples"); - - let samples = [-10i64, 0, 1, 10, 50]; + let max_sample = 100; + let min_sample = -10i64; + let samples = [min_sample, 0, 1, 10, max_sample]; let expected_counts = [1u64, 2, 1, 1]; for (i, sample) in samples.iter().enumerate() { hist.sample(*sample).unwrap(); let count = i as u64 + 1; + let current_sum = samples[..=i].iter().sum::() as f64; + let current_mean = current_sum / count as f64; + let current_std_dev = (samples[..=i] + .iter() + .map(|x| (*x as f64 - current_mean).powi(2)) + .sum::() + / count as f64) + .sqrt(); + let current_sample_std_dev = (samples[..=i] + .iter() + .map(|x| (*x as f64 - current_mean).powi(2)) + .sum::() + / (count - 1) as f64) + .sqrt(); assert_eq!( hist.n_samples(), count, "Histogram should have {} sample(s)", count ); + + if count > 0 { + assert_eq!( + hist.mean(), + current_mean, + "Histogram should have a mean of {}", + current_mean + ); + } else { + assert!(hist.mean().is_zero()); + } + + if count > 1 { + assert_eq!( + hist.std_dev().unwrap(), + current_std_dev, + "Histogram should have a sample standard deviation of {}", + current_std_dev + ); + assert_eq!( + hist.sample_std_dev().unwrap(), + current_sample_std_dev, + "Histogram should have a sample standard deviation of {}", + current_sample_std_dev + ); + } else { + assert!(hist.std_dev().is_none()); + assert!(hist.sample_std_dev().is_none()); + } } + assert_eq!( + hist.min(), + min_sample, + "Histogram should have a minimum value of {}", + min_sample + ); + assert_eq!( + hist.max(), + max_sample, + "Histogram should have a maximum value of {}", + max_sample + ); + for (bin, &expected_count) in hist.iter().zip(expected_counts.iter()) { assert_eq!( bin.count, expected_count, @@ -959,6 +1321,15 @@ mod tests { bin.range, expected_count, bin.count ); } + + let p50 = hist.p50().unwrap(); + assert_eq!(p50, 1.0, "P50 should be 1.0, but found {}", p50); + + let p90 = hist.p90().unwrap(); + assert_eq!(p90, 100.0, "P90 should be 100.0, but found {}", p90); + + let p99 = hist.p99().unwrap(); + assert_eq!(p99, 100.0, "P99 should be 100.0, but found {}", p99); } #[test] @@ -972,6 +1343,45 @@ mod tests { assert_eq!(data[2].range, BinRange::from(10)); } + #[test] + fn test_histogram_construct_with() { + let mut hist = Histogram::new(&[0, 10, 20]).unwrap(); + hist.sample(1).unwrap(); + hist.sample(11).unwrap(); + + let (bins, counts) = hist.bins_and_counts(); + assert_eq!( + bins.len(), + counts.len(), + "Bins and counts should have the same size" + ); + assert_eq!( + bins.len(), + hist.n_bins(), + "Paired-array bins should be of the same length as the histogram" + ); + assert_eq!(counts, &[0, 1, 1, 0], "Paired-array counts are incorrect"); + assert_eq!(hist.n_samples(), 2); + + let rebuilt = Histogram::from_parts( + hist.start_time(), + bins, + counts, + hist.min(), + hist.max(), + hist.sum_of_samples(), + hist.squared_mean(), + hist.p50, + hist.p90, + hist.p99, + ) + .unwrap(); + assert_eq!( + hist, rebuilt, + "Histogram reconstructed from paired arrays is not correct" + ); + } + #[test] fn test_histogram_with_overlapping_bins() { let bins = &[(..1_u64).into(), (0..10).into()]; @@ -1082,33 +1492,6 @@ mod tests { ); } - #[test] - fn test_histogram_to_arrays() { - let mut hist = Histogram::new(&[0, 10, 20]).unwrap(); - hist.sample(1).unwrap(); - hist.sample(11).unwrap(); - - let (bins, counts) = hist.to_arrays(); - assert_eq!( - bins.len(), - counts.len(), - "Bins and counts should have the same size" - ); - assert_eq!( - bins.len(), - hist.n_bins(), - "Paired-array bins should be of the same length as the histogram" - ); - assert_eq!(counts, &[0, 1, 1, 0], "Paired-array counts are incorrect"); - - let rebuilt = - Histogram::from_arrays(hist.start_time(), bins, counts).unwrap(); - assert_eq!( - hist, rebuilt, - "Histogram reconstructed from paired arrays is not correct" - ); - } - #[test] fn test_span_decades() { let hist = Histogram::::span_decades(0, 3).unwrap(); diff --git a/oximeter/oximeter/src/lib.rs b/oximeter/oximeter/src/lib.rs index 1855762abe..cd5c5adf8c 100644 --- a/oximeter/oximeter/src/lib.rs +++ b/oximeter/oximeter/src/lib.rs @@ -108,11 +108,14 @@ pub use oximeter_macro_impl::*; extern crate self as oximeter; pub mod histogram; +pub mod quantile; pub mod schema; pub mod test_util; pub mod traits; pub mod types; +pub use quantile::Quantile; +pub use quantile::QuantileError; pub use schema::FieldSchema; pub use schema::TimeseriesName; pub use schema::TimeseriesSchema; diff --git a/oximeter/oximeter/src/quantile.rs b/oximeter/oximeter/src/quantile.rs new file mode 100644 index 0000000000..8bc144bb0a --- /dev/null +++ b/oximeter/oximeter/src/quantile.rs @@ -0,0 +1,592 @@ +// 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/. + +//! Data structure for expressing quantile estimation. +//! This is based on the P² heuristic algorithm for dynamic +//! calculation of the median and other quantiles. The estimates +//! are produced dynamically as the observations are generated. +//! The observations are not stored; therefore, the algorithm has +//! a very small and fixed storage requirement regardless of the +//! number of observations. +//! +//! Read the [paper](https://www.cs.wustl.edu/~jain/papers/ftp/psqr.pdf) +//! for more specifics. + +// Copyright 2024 Oxide Computer Company + +use crate::traits::HistogramSupport; +use schemars::JsonSchema; +use serde::Deserialize; +use serde::Serialize; +use thiserror::Error; + +const FILLED_MARKER_LEN: usize = 5; + +/// Errors related to constructing a `Quantile` instance or estimating the +/// p-quantile. +#[derive( + Debug, Clone, Error, JsonSchema, Serialize, Deserialize, PartialEq, +)] +#[serde(tag = "type", content = "content", rename_all = "snake_case")] +pub enum QuantileError { + /// The p value must be in the range [0, 1]. + #[error("The p value must be in the range [0, 1].")] + InvalidPValue, + /// Quantile estimation is not possible without samples. + #[error("Quantile estimation is not possible without any samples.")] + InsufficientSampleSize, + /// A non-finite was encountered, either as a bin edge or a sample. + #[error("Samples must be finite values, not Infinity or NaN.")] + NonFiniteValue, +} + +/// Structure for estimating the p-quantile of a population. +/// +/// This is based on the P² algorithm for estimating quantiles using +/// constant space. +/// +/// The algorithm consists of maintaining five markers: the +/// minimum, the p/2-, p-, and (1 + p)/2 quantiles, and the maximum. +#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] +pub struct Quantile { + /// The p value for the quantile. + p: f64, + /// The heights of the markers. + marker_heights: [f64; FILLED_MARKER_LEN], + /// The positions of the markers. + /// + /// We track sample size in the 5th position, as useful observations won't + /// start until we've filled the heights at the 6th sample anyway + /// This does deviate from the paper, but it's a more useful representation + /// that works according to the paper's algorithm. + marker_positions: [u64; FILLED_MARKER_LEN], + /// The desired marker positions. + desired_marker_positions: [f64; FILLED_MARKER_LEN], +} + +impl Quantile { + /// Create a new `Quantile` instance. + /// + /// Returns a result containing the `Quantile` instance or an error. + /// + /// # Errors + /// + /// Returns [`QuantileError::InvalidPValue`] if the p value is not in the + /// range [0, 1]. + /// + /// # Examples + /// + /// ``` + /// use oximeter::Quantile; + /// let q = Quantile::new(0.5).unwrap(); + /// + /// assert_eq!(q.p(), 0.5); + /// assert_eq!(q.len(), 0); + /// ``` + pub fn new(p: f64) -> Result { + if p < 0. || p > 1. { + return Err(QuantileError::InvalidPValue); + } + + Ok(Self { + p, + marker_heights: [0.; FILLED_MARKER_LEN], + // We start with a sample size of 0. + marker_positions: [1, 2, 3, 4, 0], + // 1-indexed, which is like the paper, but + // used to keep track of the sample size without + // needing to do a separate count, use a Vec, + // or do any other kind of bookkeeping. + desired_marker_positions: [ + 1., + 1. + 2. * p, + 1. + 4. * p, + 3. + 2. * p, + 5., + ], + }) + } + + /// Create a new `Quantile` instance from the given a p-value, marker + /// heights and positions. + /// + /// # Examples + /// ``` + /// use oximeter::Quantile; + /// let q = Quantile::from_parts( + /// 0.5, + /// [0., 1., 2., 3., 4.], + /// [1, 2, 3, 4, 5], + /// [1., 3., 5., 7., 9.], + /// ); + /// ``` + pub fn from_parts( + p: f64, + marker_heights: [f64; FILLED_MARKER_LEN], + marker_positions: [u64; FILLED_MARKER_LEN], + desired_marker_positions: [f64; FILLED_MARKER_LEN], + ) -> Self { + Self { p, marker_heights, marker_positions, desired_marker_positions } + } + + /// Construct a `Quantile` instance for the 50th/median percentile. + pub fn p50() -> Self { + Self::new(0.5).unwrap() + } + + /// Construct a `Quantile` instance for the 90th percentile. + pub fn p90() -> Self { + Self::new(0.9).unwrap() + } + + /// Construct a `Quantile` instance for the 95th percentile. + pub fn p95() -> Self { + Self::new(0.95).unwrap() + } + + /// Construct a `Quantile` instance for the 99th percentile. + pub fn p99() -> Self { + Self::new(0.99).unwrap() + } + + /// Get the p value as a float. + pub fn p(&self) -> f64 { + self.p + } + + /// Return the sample size. + pub fn len(&self) -> u64 { + self.marker_positions[4] + } + + /// Determine if the number of samples in the population are empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Return the marker heights. + pub fn marker_heights(&self) -> [f64; FILLED_MARKER_LEN] { + self.marker_heights + } + + /// Return the marker positions. + pub fn marker_positions(&self) -> [u64; FILLED_MARKER_LEN] { + self.marker_positions + } + + /// Return the desired marker positions. + pub fn desired_marker_positions(&self) -> [f64; FILLED_MARKER_LEN] { + self.desired_marker_positions + } + + /// Estimate the p-quantile of the population. + /// + /// This is step B.4 in the P² algorithm. + /// + /// Returns a result containing the estimated p-quantile or an error. + /// + /// # Errors + /// + /// Returns [`QuantileError::InsufficientSampleSize`] if the sample size + /// is empty. + /// + /// # Examples + /// + /// ``` + /// use oximeter::Quantile; + /// let mut q = Quantile::new(0.5).unwrap(); + /// for o in 1..=100 { + /// q.append(o).unwrap(); + /// } + /// assert_eq!(q.estimate().unwrap(), 50.0); + /// ``` + pub fn estimate(&self) -> Result { + if self.is_empty() { + return Err(QuantileError::InsufficientSampleSize); + } + + if self.len() >= FILLED_MARKER_LEN as u64 { + return Ok(self.marker_heights[2]); + } + + // Try to find an index in heights that is correlated with the p value + // when we have less than 5 samples, but more than 0. + let mut heights = self.marker_heights; + float_ord::sort(&mut heights); + let idx = (heights.len() as f64 - 1.) * self.p(); + return Ok(heights[idx.round() as usize]); + } + + /// Append a value/observation to the population and adjust the heights. + /// + /// This comprises steps B.1, B.2, B.3 (adjust heights) in the P² algorithm, + /// including finding the cell k containing the input value and updating the + /// current and desired marker positions. + /// + /// Returns an empty result or an error. + /// + /// # Errors + /// + /// Returns [`QuantileError::NonFiniteValue`] if the value is not finite + /// when casting to a float. + /// + /// # Examples + /// + /// ``` + /// use oximeter::Quantile; + /// let mut q = Quantile::new(0.9).unwrap(); + /// q.append(10).unwrap(); + /// assert_eq!(q.len(), 1); + /// ``` + pub fn append(&mut self, value: T) -> Result<(), QuantileError> + where + T: HistogramSupport, + { + if !value.is_finite() { + return Err(QuantileError::NonFiniteValue); + } + // We've already checked that the value is finite. + let value_f = value.to_f64().unwrap(); + + if self.len() < FILLED_MARKER_LEN as u64 { + self.marker_heights[self.len() as usize] = value_f; + self.marker_positions[4] += 1; + if self.len() == FILLED_MARKER_LEN as u64 { + float_ord::sort(&mut self.marker_heights); + self.adaptive_init(); + } + return Ok(()); + } + + // Find the cell k containing the new value. + let k = match self.find_cell(value_f) { + Some(4) => { + self.marker_heights[4] = value_f; + 3 + } + Some(i) => i, + None => { + self.marker_heights[0] = value_f; + 0 + } + }; + + // Handle rounding issues as described in + // . + let count = self.len() as f64; + self.desired_marker_positions[1] = count * (self.p() / 2.) + 1.; + self.desired_marker_positions[2] = count * self.p() + 1.; + self.desired_marker_positions[3] = count * ((1. + self.p()) / 2.) + 1.; + self.desired_marker_positions[4] = count + 1.; + + for i in k + 1..FILLED_MARKER_LEN { + self.marker_positions[i] += 1; + } + + // Adjust height of markers adaptively to be more optimal for + // not just higher quantiles, but also lower ones. + // + // This is a deviation from the paper, taken from + // . + if self.p >= 0.5 { + for i in 1..4 { + self.adjust_heights(i) + } + } else { + for i in (1..4).rev() { + self.adjust_heights(i) + } + } + + Ok(()) + } + + /// Find the higher marker cell whose height is lower than the observation. + /// + /// Returns `None` if the value is less than the initial marker height. + fn find_cell(&mut self, value: f64) -> Option { + if value < self.marker_heights[0] { + None + } else { + Some( + self.marker_heights + .partition_point(|&height| height <= value) + .saturating_sub(1), + ) + } + } + + /// Adjust the heights of the markers if necessary. + /// + /// Step B.3 in the P² algorithm. Should be used within a loop + /// after appending a value to the population. + fn adjust_heights(&mut self, i: usize) { + let d = + self.desired_marker_positions[i] - self.marker_positions[i] as f64; + + if (d >= 1. + && self.marker_positions[i + 1] > self.marker_positions[i] + 1) + || (d <= -1. + && self.marker_positions[i - 1] < self.marker_positions[i] - 1) + { + let d_signum = d.signum(); + let q_prime = self.parabolic(i, d_signum); + if self.marker_heights[i - 1] < q_prime + && q_prime < self.marker_heights[i + 1] + { + self.marker_heights[i] = q_prime; + } else { + let q_prime = self.linear(i, d_signum); + self.marker_heights[i] = q_prime; + } + + // Update marker positions based on the sign of d. + if d_signum < 0. { + self.marker_positions[i] -= 1; + } else { + self.marker_positions[i] += 1; + } + } + } + + /// An implementation to adaptively initialize the marker heights and + /// positions, particularly useful for extreme quantiles (e.g., 0.99) + /// when estimating on a small sample size. + /// + /// Read + /// for more. + fn adaptive_init(&mut self) { + self.desired_marker_positions[..FILLED_MARKER_LEN] + .copy_from_slice(&self.marker_heights[..FILLED_MARKER_LEN]); + + self.marker_positions[1] = (1. + 2. * self.p()).round() as u64; + self.marker_positions[2] = (1. + 4. * self.p()).round() as u64; + self.marker_positions[3] = (3. + 2. * self.p()).round() as u64; + self.marker_heights[1] = self.desired_marker_positions + [self.marker_positions[1] as usize - 1]; + self.marker_heights[2] = self.desired_marker_positions + [self.marker_positions[2] as usize - 1]; + self.marker_heights[3] = self.desired_marker_positions + [self.marker_positions[3] as usize - 1]; + } + + /// Parabolic prediction for marker height. + fn parabolic(&self, i: usize, d_signum: f64) -> f64 { + let pos_diff1 = (self.marker_positions[i + 1] as i64 + - self.marker_positions[i - 1] as i64) + as f64; + + let pos_diff2 = (self.marker_positions[i + 1] as i64 + - self.marker_positions[i] as i64) as f64; + + let pos_diff3 = (self.marker_positions[i] as i64 + - self.marker_positions[i - 1] as i64) + as f64; + + let term1 = d_signum / pos_diff1; + let term2 = ((self.marker_positions[i] - self.marker_positions[i - 1]) + as f64 + + d_signum) + * (self.marker_heights[i + 1] - self.marker_heights[i]) + / pos_diff2; + let term3 = ((self.marker_positions[i + 1] - self.marker_positions[i]) + as f64 + - d_signum) + * (self.marker_heights[i] - self.marker_heights[i - 1]) + / pos_diff3; + + self.marker_heights[i] + term1 * (term2 + term3) + } + + /// Linear prediction for marker height. + fn linear(&self, i: usize, d_signum: f64) -> f64 { + let idx = if d_signum < 0. { i - 1 } else { i + 1 }; + self.marker_heights[i] + + d_signum * (self.marker_heights[idx] - self.marker_heights[i]) + / (self.marker_positions[idx] as i64 + - self.marker_positions[i] as i64) as f64 + } +} + +#[cfg(test)] +mod tests { + use super::*; + use approx::assert_relative_eq; + use rand::{Rng, SeedableRng}; + use rand_distr::{Distribution, Normal}; + + fn test_quantile_impl( + p: f64, + observations: u64, + assert_on: Option, + ) -> Quantile { + let mut q = Quantile::new(p).unwrap(); + for o in 1..=observations { + q.append(o).unwrap(); + } + assert_eq!(q.p(), p); + assert_eq!(q.estimate().unwrap(), assert_on.unwrap_or(p * 100.)); + q + } + + #[test] + fn test_min_p() { + let observations = [3, 6, 7, 8, 8, 10, 13, 15, 16, 20]; + + let mut q = Quantile::new(0.0).unwrap(); + //assert_eq!(q.p(), 0.1); + for &o in observations.iter() { + q.append(o).unwrap(); + } + assert_eq!(q.estimate().unwrap(), 3.); + } + + /// Compared with C# implementation of P² algorithm. + #[test] + fn test_max_p() { + let observations = [3, 6, 7, 8, 8, 10, 13, 15, 16, 20]; + + let mut q = Quantile::new(1.).unwrap(); + assert_eq!(q.p(), 1.); + + for &o in observations.iter() { + q.append(o).unwrap(); + } + + assert_eq!(q.estimate().unwrap(), 11.66543209876543); + } + + /// Example observations from the P² paper. + #[test] + fn test_float_observations() { + let observations = [ + 0.02, 0.5, 0.74, 3.39, 0.83, 22.37, 10.15, 15.43, 38.62, 15.92, + 34.60, 10.28, 1.47, 0.40, 0.05, 11.39, 0.27, 0.42, 0.09, 11.37, + ]; + let mut q = Quantile::p50(); + for &o in observations.iter() { + q.append(o).unwrap(); + } + assert_eq!(q.marker_positions, [1, 6, 10, 16, 20]); + assert_eq!(q.desired_marker_positions, [0.02, 5.75, 10.5, 15.25, 20.0]); + assert_eq!(q.p(), 0.5); + assert_eq!(q.len(), 20); + assert_relative_eq!(q.estimate().unwrap(), 4.2462394088036435,); + } + + #[test] + fn test_rounding() { + let mut rng = rand::rngs::StdRng::seed_from_u64(42); + let mut estimator = Quantile::new(0.6).unwrap(); + + for _ in 0..100 { + let x: f64 = rng.gen(); + estimator.append(x).unwrap(); + } + + assert_relative_eq!( + estimator.estimate().unwrap(), + 0.552428024067269, + epsilon = f64::EPSILON + ); + } + + #[test] + fn test_integer_observations() { + let observations = 1..=100; + let mut q = Quantile::new(0.3).unwrap(); + for o in observations { + q.append(o).unwrap(); + } + assert_eq!(q.marker_positions, [1, 15, 30, 65, 100]); + assert_eq!( + q.desired_marker_positions, + [1.0, 15.85, 30.7, 65.35000000000001, 100.0] + ); + + assert_eq!(q.p(), 0.3); + assert_eq!(q.estimate().unwrap(), 30.0); + } + + #[test] + fn test_empty_observations() { + let q = Quantile::p50(); + assert_eq!( + q.estimate().err().unwrap(), + QuantileError::InsufficientSampleSize + ); + } + + #[test] + fn test_non_filled_observations() { + let mut q = Quantile::p99(); + let observations = [-10., 0., 1., 10.]; + for &o in observations.iter() { + q.append(o).unwrap(); + } + assert_eq!(q.estimate().unwrap(), 10.); + } + + #[test] + fn test_default_percentiles() { + test_quantile_impl(0.5, 100, None); + test_quantile_impl(0.9, 100, None); + test_quantile_impl(0.95, 100, None); + test_quantile_impl(0.99, 100, Some(97.)); + } + + #[test] + fn test_invalid_p_value() { + assert_eq!( + Quantile::new(1.01).err().unwrap(), + QuantileError::InvalidPValue + ); + assert_eq!( + Quantile::new(f64::MAX).err().unwrap(), + QuantileError::InvalidPValue + ); + } + + #[test] + fn test_find_cells() { + let mut q = test_quantile_impl(0.5, 5, Some(3.)); + assert_eq!(q.find_cell(0.), None); + assert_eq!(q.find_cell(7.), Some(4)); + assert_eq!(q.find_cell(4.), Some(3)); + assert_eq!(q.find_cell(3.5), Some(2)); + } + + /// Emulates baseline test in a basic Python implementation of the P² + /// algorithm: + /// . + #[test] + fn test_against_baseline_normal_distribution() { + let mu = 500.; + let sigma = 100.; + let size = 1000; + let p = 0.9; + + let normal = Normal::new(mu, sigma); + let mut observations = (0..size) + .map(|_| normal.unwrap().sample(&mut rand::thread_rng())) + .collect::>(); + float_ord::sort(&mut observations); + let idx = ((f64::from(size) - 1.) * p) as usize; + + let base_p_est = observations[idx]; + + let mut q = Quantile::new(p).unwrap(); + for o in observations.iter() { + q.append(*o).unwrap(); + } + let p_est = q.estimate().unwrap(); + + println!("Base: {}, Est: {}", base_p_est, p_est); + assert!( + (base_p_est - p_est).abs() < 10.0, + "Difference {} is not less than 10", + (base_p_est - p_est).abs() + ); + } +} diff --git a/oximeter/oximeter/src/test_util.rs b/oximeter/oximeter/src/test_util.rs index a9778d03bc..56992623d7 100644 --- a/oximeter/oximeter/src/test_util.rs +++ b/oximeter/oximeter/src/test_util.rs @@ -6,7 +6,7 @@ // Copyright 2021 Oxide Computer Company use crate::histogram; -use crate::histogram::Histogram; +use crate::histogram::{Histogram, Record}; use crate::types::{Cumulative, Sample}; use uuid::Uuid; From 2d419e765985d602d66c351065a0dc22093e3eeb Mon Sep 17 00:00:00 2001 From: "oxide-reflector-bot[bot]" <130185838+oxide-reflector-bot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:55:22 -0700 Subject: [PATCH 24/26] Update dendrite to a262fe7 (#5835) Updated dendrite to commit a262fe7. --------- Co-authored-by: reflector[bot] <130185838+reflector[bot]@users.noreply.github.com> --- package-manifest.toml | 12 ++++++------ tools/dendrite_openapi_version | 2 +- tools/dendrite_stub_checksums | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-manifest.toml b/package-manifest.toml index 27a5397bf1..476926aaf0 100644 --- a/package-manifest.toml +++ b/package-manifest.toml @@ -628,8 +628,8 @@ only_for_targets.image = "standard" # 2. Copy dendrite.tar.gz from dendrite/out to omicron/out source.type = "prebuilt" source.repo = "dendrite" -source.commit = "861c00bacbdf7a6e22471f0dabd8f926409b5292" -source.sha256 = "1db849892c60b22f600fb081d4b0145d8ecd98acce9fad3094499a5d2159d001" +source.commit = "a262fe770c173f7879cd942c98ab28a829890661" +source.sha256 = "6f991dacd72c63d7fcff734b1f5c406c001e4d509f7b36e68b89d8b07f69ed79" output.type = "zone" output.intermediate_only = true @@ -653,8 +653,8 @@ only_for_targets.image = "standard" # 2. Copy the output zone image from dendrite/out to omicron/out source.type = "prebuilt" source.repo = "dendrite" -source.commit = "861c00bacbdf7a6e22471f0dabd8f926409b5292" -source.sha256 = "00b2b9372145bc8974f3c75ba7a59d8f2a8178c67cc1869086d29c7f3a2deb36" +source.commit = "a262fe770c173f7879cd942c98ab28a829890661" +source.sha256 = "66f38e194d4899a18825ec1a28adc9e63b5c3806696ffe9b210a16071d892013" output.type = "zone" output.intermediate_only = true @@ -671,8 +671,8 @@ only_for_targets.image = "standard" # 2. Copy dendrite.tar.gz from dendrite/out to omicron/out/dendrite-softnpu.tar.gz source.type = "prebuilt" source.repo = "dendrite" -source.commit = "861c00bacbdf7a6e22471f0dabd8f926409b5292" -source.sha256 = "b0b62b22c0e781edb0790b8730b99bb6e635c95ad3e83c2afbb2b15956153d66" +source.commit = "a262fe770c173f7879cd942c98ab28a829890661" +source.sha256 = "6d4870275f9119da6bcafd0f57ee3e467aae4ff32c861af9ebf5a81ff304d6ce" output.type = "zone" output.intermediate_only = true diff --git a/tools/dendrite_openapi_version b/tools/dendrite_openapi_version index 0d6d6f810e..811e58346c 100755 --- a/tools/dendrite_openapi_version +++ b/tools/dendrite_openapi_version @@ -1,2 +1,2 @@ -COMMIT="861c00bacbdf7a6e22471f0dabd8f926409b5292" +COMMIT="a262fe770c173f7879cd942c98ab28a829890661" SHA2="12dc61e7c62b2e1ee1cf3c2bf7cdda6bee6ec96925d2fc1c021c6c1a8fdd56cd" diff --git a/tools/dendrite_stub_checksums b/tools/dendrite_stub_checksums index 75c76f3585..a42cdeca2a 100644 --- a/tools/dendrite_stub_checksums +++ b/tools/dendrite_stub_checksums @@ -1,3 +1,3 @@ -CIDL_SHA256_ILLUMOS="1db849892c60b22f600fb081d4b0145d8ecd98acce9fad3094499a5d2159d001" -CIDL_SHA256_LINUX_DPD="4022e8c0de268c4bc38046b29a48d021b3204e6c2dc8371f2de67f42019720c0" +CIDL_SHA256_ILLUMOS="6f991dacd72c63d7fcff734b1f5c406c001e4d509f7b36e68b89d8b07f69ed79" +CIDL_SHA256_LINUX_DPD="d97029a5c2c2f136fc76dbfa941ef0b114135232c6f96948453b5c83f744beb7" CIDL_SHA256_LINUX_SWADM="a1308303fd0d8f8ac272288e801beb913f695dcf820dd53f5c03871e6b8674f7" From 8b2d48aa1f89a1d19faa392b2534c9ed993f8dae Mon Sep 17 00:00:00 2001 From: David Crespo Date: Mon, 24 Jun 2024 17:47:01 -0500 Subject: [PATCH 25/26] Bump web console (combobox) (#5938) https://github.com/oxidecomputer/console/compare/a9b325e9...a06d8521 * [a06d8521](https://github.com/oxidecomputer/console/commit/a06d8521) bump api to latest main * [f1fce1b9](https://github.com/oxidecomputer/console/commit/f1fce1b9) oxidecomputer/console#2267 * [c52d6840](https://github.com/oxidecomputer/console/commit/c52d6840) get rid of isTruthy calls thanks to TS 5.5 * [92494d97](https://github.com/oxidecomputer/console/commit/92494d97) oxidecomputer/console#2281 * [017145c7](https://github.com/oxidecomputer/console/commit/017145c7) oxidecomputer/console#2283 * [cb98aa27](https://github.com/oxidecomputer/console/commit/cb98aa27) oxidecomputer/console#2282 * [e7d7d95d](https://github.com/oxidecomputer/console/commit/e7d7d95d) oxidecomputer/console#2275 * [e6e3e176](https://github.com/oxidecomputer/console/commit/e6e3e176) add deno.lock to gitignore --- tools/console_version | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/console_version b/tools/console_version index 4c720590d5..46621e591d 100644 --- a/tools/console_version +++ b/tools/console_version @@ -1,2 +1,2 @@ -COMMIT="a9b325e94a6bbb309d68cf586298b4f77aa452ab" -SHA2="d41f22b4d575fc622b2749ea9e81eec11d78a4aae46f61b0472a7958b78be7f7" +COMMIT="a06d8521a1e069a9d2c1a387077fa8c3830c0d4e" +SHA2="397985a59de3ac57d97b2b30391197214713a27c0fa135ede9c732f4e2b895cb" From 86e17106f1d4b34c2bfa2226f18f184586c8ade5 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Mon, 24 Jun 2024 19:45:40 -0400 Subject: [PATCH 26/26] RoT v1.0.12 (#5937) --- tools/permslip_production | 2 +- tools/permslip_staging | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/permslip_production b/tools/permslip_production index 1b0f191d5a..5e9b76f980 100644 --- a/tools/permslip_production +++ b/tools/permslip_production @@ -1,2 +1,2 @@ -3feecf35522ecc07a23fbe934c752ecbf248672ce55c29102de485927edc12e6 manifest-oxide-rot-1-v1.0.11.toml +905d38cb8298c72ecac5cf31f792919fbcd69a4ad656c40e53b3ce2d80140111 manifest-oxide-rot-1-v1.0.12.toml 74e754e68705cf6fed4152a92bc1ee9667d1d98a21fc12993a2232dbe34bfccb manifest-bootleby-v1.3.0.toml diff --git a/tools/permslip_staging b/tools/permslip_staging index bc9250ae93..a38bff708e 100644 --- a/tools/permslip_staging +++ b/tools/permslip_staging @@ -1,5 +1,5 @@ c28eaa13638f55100a42916727227242ee02d18cebecb1412d6af5c8aa945b99 manifest-gimlet-v1.0.22.toml -b973cc9feb20f7bba447e7f5291c4070387fa9992deab81301f67f0a3844cd0c manifest-oxide-rot-1-v1.0.11.toml +201ff5580bb4b0b01419d7c5e580af9926103e2b6d3024e6b49cee6fab415519 manifest-oxide-rot-1-v1.0.12.toml 6d53bfbfdd6baa3fc150153a003abfac6d4b46c34f61fa7a8ec2af8af19a7d5a manifest-psc-v1.0.21.toml d608dba3fa5a1fce3592ff3f643319787218b84706134147e5918f5bd1c0345d manifest-sidecar-v1.0.22.toml c0fecaefac7674138337f3bd4ce4ce5b884053dead5ec27b575701471631ea2f manifest-bootleby-v1.3.0.toml