From d5dc440c8f89e46589b5791c94ec3988c8206460 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Tue, 7 Nov 2023 04:28:35 +0000 Subject: [PATCH 01/44] WIP: updated HTTP, params, and sled agent layer; about to wade into service manager --- sled-agent/src/http_entrypoints.rs | 57 +++++------ sled-agent/src/params.rs | 146 +++++++++++++++++++++++++++++ sled-agent/src/services.rs | 79 ++++++++++++---- sled-agent/src/sled_agent.rs | 39 ++++---- 4 files changed, 251 insertions(+), 70 deletions(-) diff --git a/sled-agent/src/http_entrypoints.rs b/sled-agent/src/http_entrypoints.rs index 68330d0c0e..2bbe517062 100644 --- a/sled-agent/src/http_entrypoints.rs +++ b/sled-agent/src/http_entrypoints.rs @@ -9,9 +9,9 @@ use crate::bootstrap::early_networking::EarlyNetworkConfig; use crate::params::{ CleanupContextUpdate, DiskEnsureBody, InstanceEnsureBody, InstancePutMigrationIdsBody, InstancePutStateBody, - InstancePutStateResponse, InstanceUnregisterResponse, ServiceEnsureBody, - SledRole, TimeSync, VpcFirewallRulesEnsureBody, ZoneBundleId, - ZoneBundleMetadata, Zpool, + InstancePutStateResponse, InstanceUnregisterResponse, OmicronZonesConfig, + ServiceEnsureBody, SledRole, TimeSync, VpcFirewallRulesEnsureBody, + ZoneBundleId, ZoneBundleMetadata, Zpool, }; use crate::sled_agent::Error as SledAgentError; use crate::zone_bundle; @@ -47,7 +47,8 @@ pub fn api() -> SledApiDescription { api.register(instance_put_state)?; api.register(instance_register)?; api.register(instance_unregister)?; - api.register(services_put)?; + api.register(omicron_zones_get)?; + api.register(omicron_zones_put)?; api.register(zones_list)?; api.register(zone_bundle_list)?; api.register(zone_bundle_list_all)?; @@ -309,44 +310,28 @@ async fn zones_list( sa.zones_list().await.map(HttpResponseOk).map_err(HttpError::from) } +#[endpoint { + method = GET, + path = "/omicron_zones", +}] +async fn omicron_zones_put( + rqctx: RequestContext, +) -> Result, HttpError> { + let sa = rqctx.context(); + Ok(sa.omicron_zones_list().await?) +} + #[endpoint { method = PUT, - path = "/services", + path = "/omicron_zones", }] -async fn services_put( +async fn omicron_zones_put( rqctx: RequestContext, - body: TypedBody, + body: TypedBody, ) -> Result { - let sa = rqctx.context().clone(); + let sa = rqctx.context(); let body_args = body.into_inner(); - - // Spawn a separate task to run `services_ensure`: cancellation of this - // endpoint's future (as might happen if the client abandons the request or - // times out) could result in leaving zones partially configured and the - // in-memory state of the service manager invalid. See: - // oxidecomputer/omicron#3098. - let handler = async move { - match sa.services_ensure(body_args).await { - Ok(()) => Ok(()), - Err(e) => { - // Log the error here to make things clear even if the client - // has already disconnected. - error!(sa.logger(), "failed to initialize services: {e}"); - Err(e) - } - } - }; - match tokio::spawn(handler).await { - Ok(result) => result.map_err(|e| Error::from(e))?, - - Err(e) => { - return Err(HttpError::for_internal_error(format!( - "unexpected failure awaiting \"services_ensure\": {:#}", - e - ))); - } - } - + sa.omicron_zones_ensure(body_args).await?; Ok(HttpResponseUpdatedNoContent()) } diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index cd84c9acd4..6f8daa308b 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -2,6 +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/. +use crate::storage::dataset::DatasetName; use crate::zone_bundle::PriorityOrder; pub use crate::zone_bundle::ZoneBundleCause; pub use crate::zone_bundle::ZoneBundleId; @@ -25,6 +26,7 @@ use std::net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6}; use std::time::Duration; use thiserror::Error; use uuid::Uuid; +use illumos_utils::zpool::ZpoolName; /// Used to request a Disk state change #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, JsonSchema)] @@ -864,6 +866,150 @@ pub struct ServiceEnsureBody { pub services: Vec, } +/// Describes the set of Omicron zones running on a sled +#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] +pub struct OmicronZonesConfig { + // XXX-dap generation number + pub zones: Vec, +} + +/// Describes one Omicron zone running on a sled +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, +)] +pub struct OmicronZoneConfig { + pub id: Uuid, + pub underlay_address: Ipv6Addr, + pub zone_type: OmicronZoneType, +} + +impl OmicronZoneConfig { + // XXX-dap should the caller (RSS) should specify this directly? That + // eliminates one reason why Sled Agent needs to know about what kind of + // dataset it's looking at. + pub fn dataset_name(&self) -> Option { + let (dataset, dataset_kind) = match &self.zone_type { + OmicronZoneType::BoundaryNtp { .. } + | OmicronZoneType::InternalNtp { .. } + | OmicronZoneType::Nexus { .. } + | OmicronZoneType::Oximeter { .. } + | OmicronZoneType::CruciblePantry { .. } => None, + OmicronZoneType::Clickhouse { dataset, .. } => { + Some((dataset, DatasetKind::Clickhouse)) + } + OmicronZoneType::ClickhouseKeeper { dataset, .. } => { + Some((dataset, DatasetKind::ClickhouseKeeper)) + } + OmicronZoneType::CockroachDb { dataset, .. } => { + Some((dataset, DatasetKind::CockroachDb)) + } + OmicronZoneType::Crucible { dataset, .. } => { + Some((dataset, DatasetKind::Crucible)) + } + OmicronZoneType::ExternalDns { dataset, .. } => { + Some((dataset, DatasetKind::ExternalDns)) + } + OmicronZoneType::InternalDns { dataset, .. } => { + Some((dataset, DatasetKind::InternalDns)) + } + }?; + + DatasetName::new(dataset.pool_name, dataset_kind) + } +} + +/// Describes a persistent ZFS dataset associated with an Omicron zone +pub struct OmicronZoneDataset { + pool_name: ZpoolName, +} + +/// Describes what component is running in this zone and its associated +/// type-specific configuration +/// +/// XXX-dap ideally this would not be necessary at all! Sled Agent shouldn't +/// have to know about the things running on it, I think? +/// XXX-dap commonize with ServiceType (well, probably remove ServiceType) +pub enum OmicronZoneType { + 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, + }, + + Clickhouse { + address: SocketAddrV6, + dataset: OmicronZoneDataset, + }, + + ClickhouseKeeper { + address: SocketAddrV6, + dataset: OmicronZoneDataset, + }, + CockroachDb { + address: SocketAddrV6, + dataset: OmicronZoneDataset, + }, + + Crucible { + address: SocketAddrV6, + dataset: OmicronZoneDataset, + }, + CruciblePantry { + address: SocketAddrV6, + }, + ExternalDns { + dataset: OmicronZoneDataset, + /// 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 { + dataset: OmicronZoneDataset, + 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, + }, + InternalNtp { + address: SocketAddrV6, + ntp_servers: Vec, + dns_servers: Vec, + domain: Option, + }, + 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, + }, + Oximeter { + address: SocketAddrV6, + }, +} + #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] pub struct TimeSync { /// The synchronization state of the sled, true when the system clock diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index d1d8dbfff0..c5bdea5803 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -274,24 +274,25 @@ impl Config { } // The filename of the ledger, within the provided directory. -const SERVICES_LEDGER_FILENAME: &str = "services.json"; +const SERVICES_LEDGER_FILENAME_V1: &str = "services.json"; // A wrapper around `ZoneRequest`, which allows it to be serialized // to a JSON file. +// XXX-dap TODO-doc #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -struct AllZoneRequests { +struct OldZoneRequests { generation: Generation, requests: Vec, } -impl Default for AllZoneRequests { +impl Default for OldZoneRequests { fn default() -> Self { Self { generation: Generation::new(), requests: vec![] } } } -impl Ledgerable for AllZoneRequests { - fn is_newer_than(&self, other: &AllZoneRequests) -> bool { +impl Ledgerable for OldZoneRequests { + fn is_newer_than(&self, other: &OldZoneRequests) -> bool { self.generation >= other.generation } @@ -474,14 +475,14 @@ impl ServiceManager { async fn all_service_ledgers(&self) -> Vec { if let Some(dir) = self.inner.ledger_directory_override.get() { - return vec![dir.join(SERVICES_LEDGER_FILENAME)]; + return vec![dir.join(SERVICES_LEDGER_FILENAME_V1)]; } self.inner .storage .all_m2_mountpoints(sled_hardware::disk::CONFIG_DATASET) .await .into_iter() - .map(|p| p.join(SERVICES_LEDGER_FILENAME)) + .map(|p| p.join(SERVICES_LEDGER_FILENAME_V1)) .collect() } @@ -500,7 +501,7 @@ impl ServiceManager { let mut existing_zones = self.inner.zones.lock().await; let Some(mut ledger) = - Ledger::::new(log, ledger_paths).await + Ledger::::new(log, ledger_paths).await else { info!(log, "Loading services - No services detected"); return Ok(()); @@ -515,7 +516,7 @@ impl ServiceManager { let all_zones_request = self .ensure_all_services( &mut existing_zones, - &AllZoneRequests::default(), + &OldZoneRequests::default(), ServiceEnsureBody { services: services .requests @@ -2151,6 +2152,50 @@ impl ServiceManager { Err(BundleError::NoSuchZone { name: name.to_string() }) } + /// Ensures that particular Omicron zones are running + /// + /// These services will be instantiated by this function, and will be + /// recorded to a local file to ensure they start automatically on next + /// boot. + pub async fn ensure_all_omicron_zones_persistent( + &self, + request: OmicronZonesConfig, + ) -> Result<(), Error> { + let log = &self.inner.log; + + let mut existing_zones = self.inner.zones.lock().await; + + // Read the existing set of services from the ledger. + let service_paths = self.all_service_ledgers().await; + let mut ledger = + match Ledger::::new(log, service_paths.clone()) + .await + { + Some(ledger) => ledger, + None => Ledger::::new_with( + log, + service_paths.clone(), + OldZoneRequests::default(), + ), + }; + let ledger_zone_requests = ledger.data_mut(); + + let mut zone_requests = self + .ensure_all_services( + &mut existing_zones, + ledger_zone_requests, + request, + ) + .await?; + + // Update the services in the ledger and write it back to both M.2s + ledger_zone_requests.requests.clear(); + ledger_zone_requests.requests.append(&mut zone_requests.requests); + ledger.commit().await?; + + Ok(()) + } + /// Ensures that particular services should be initialized. /// /// These services will be instantiated by this function, and will be @@ -2167,14 +2212,14 @@ impl ServiceManager { // Read the existing set of services from the ledger. let service_paths = self.all_service_ledgers().await; let mut ledger = - match Ledger::::new(log, service_paths.clone()) + match Ledger::::new(log, service_paths.clone()) .await { Some(ledger) => ledger, - None => Ledger::::new_with( + None => Ledger::::new_with( log, service_paths.clone(), - AllZoneRequests::default(), + OldZoneRequests::default(), ), }; let ledger_zone_requests = ledger.data_mut(); @@ -2202,9 +2247,9 @@ impl ServiceManager { async fn ensure_all_services( &self, existing_zones: &mut MutexGuard<'_, BTreeMap>, - old_request: &AllZoneRequests, + old_request: &OldZoneRequests, request: ServiceEnsureBody, - ) -> Result { + ) -> Result { let log = &self.inner.log; // Do some data-normalization to ensure we can compare the "requested @@ -2251,7 +2296,7 @@ impl ServiceManager { } // Create zones that should be running - let mut zone_requests = AllZoneRequests::default(); + let mut zone_requests = OldZoneRequests::default(); let all_u2_roots = self.inner.storage.all_u2_mountpoints(ZONE_DATASET).await; for zone in zones_to_be_added { @@ -3499,7 +3544,7 @@ mod test { // Next, delete the ledger. This means the service we just created will // not be remembered on the next initialization. std::fs::remove_file( - test_config.config_dir.path().join(SERVICES_LEDGER_FILENAME), + test_config.config_dir.path().join(SERVICES_LEDGER_FILENAME_V1), ) .unwrap(); @@ -3550,7 +3595,7 @@ mod test { #[test] fn test_all_zone_requests_schema() { - let schema = schemars::schema_for!(AllZoneRequests); + let schema = schemars::schema_for!(OldZoneRequests); expectorate::assert_contents( "../schema/all-zone-requests.json", &serde_json::to_string_pretty(&schema).unwrap(), diff --git a/sled-agent/src/sled_agent.rs b/sled-agent/src/sled_agent.rs index 6655a732a0..7628b51b54 100644 --- a/sled-agent/src/sled_agent.rs +++ b/sled-agent/src/sled_agent.rs @@ -14,8 +14,8 @@ use crate::nexus::{NexusClientWithResolver, NexusRequestQueue}; use crate::params::{ DiskStateRequested, InstanceHardware, InstanceMigrationSourceParams, InstancePutStateResponse, InstanceStateRequested, - InstanceUnregisterResponse, ServiceEnsureBody, SledRole, TimeSync, - VpcFirewallRule, ZoneBundleMetadata, Zpool, + InstanceUnregisterResponse, OmicronZonesConfig, ServiceEnsureBody, + SledRole, TimeSync, VpcFirewallRule, ZoneBundleMetadata, Zpool, }; use crate::services::{self, ServiceManager}; use crate::storage_manager::{self, StorageManager}; @@ -57,6 +57,7 @@ use std::net::{Ipv6Addr, SocketAddr, SocketAddrV6}; use std::sync::Arc; use uuid::Uuid; +use crate::storage::dataset::DatasetName; #[cfg(not(test))] use illumos_utils::{dladm::Dladm, zone::Zones}; #[cfg(test)] @@ -719,36 +720,40 @@ impl SledAgent { self.inner.zone_bundler.cleanup().await.map_err(Error::from) } - /// Ensures that particular services should be initialized. - /// - /// These services will be instantiated by this function, will be recorded - /// to a local file to ensure they start automatically on next boot. - pub async fn services_ensure( + /// List the Omicron zone configuration that's currently running + pub async fn omicron_zones_list( &self, - requested_services: ServiceEnsureBody, - ) -> Result<(), Error> { - let datasets: Vec<_> = requested_services - .services - .iter() - .filter_map(|service| service.dataset.clone()) - .collect(); + ) -> Result { + Ok(self.inner.services.omicron_zones_list(requested_services).await?) + } + /// Ensures that the specific set of Omicron zones are running as configured + /// (and that no other zones are running) + pub async fn omicron_zones_ensure( + &self, + requested_zones: OmicronZonesConfig, + ) -> Result<(), Error> { // TODO: // - If these are the set of filesystems, we should also consider // removing the ones which are not listed here. // - It's probably worth sending a bulk request to the storage system, // rather than requesting individual datasets. - for dataset in &datasets { + for zone in &requested_zones.zones { + let Some(dataset_name) = zone.dataset_name() else { + continue; + }; + // First, ensure the dataset exists + let dataset_id = zone.id; self.inner .storage - .upsert_filesystem(dataset.id, dataset.name.clone()) + .upsert_filesystem(dataset_id, dataset_name) .await?; } self.inner .services - .ensure_all_services_persistent(requested_services) + .ensure_all_omicron_zones_persistent(requested_services) .await?; Ok(()) } From 4536ec9db0094be6bb296755922155e3c1d76e82 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Tue, 7 Nov 2023 20:01:21 +0000 Subject: [PATCH 02/44] WIP: initial updates to service manager; next need to dig into initialize_zone() --- sled-agent/src/http_entrypoints.rs | 8 +- sled-agent/src/params.rs | 43 +++- sled-agent/src/services.rs | 374 +++++++++++++++++++++++------ sled-agent/src/sled_agent.rs | 9 +- 4 files changed, 351 insertions(+), 83 deletions(-) diff --git a/sled-agent/src/http_entrypoints.rs b/sled-agent/src/http_entrypoints.rs index 2bbe517062..b6a60ad521 100644 --- a/sled-agent/src/http_entrypoints.rs +++ b/sled-agent/src/http_entrypoints.rs @@ -10,8 +10,8 @@ use crate::params::{ CleanupContextUpdate, DiskEnsureBody, InstanceEnsureBody, InstancePutMigrationIdsBody, InstancePutStateBody, InstancePutStateResponse, InstanceUnregisterResponse, OmicronZonesConfig, - ServiceEnsureBody, SledRole, TimeSync, VpcFirewallRulesEnsureBody, - ZoneBundleId, ZoneBundleMetadata, Zpool, + SledRole, TimeSync, VpcFirewallRulesEnsureBody, ZoneBundleId, + ZoneBundleMetadata, Zpool, }; use crate::sled_agent::Error as SledAgentError; use crate::zone_bundle; @@ -314,11 +314,11 @@ async fn zones_list( method = GET, path = "/omicron_zones", }] -async fn omicron_zones_put( +async fn omicron_zones_get( rqctx: RequestContext, ) -> Result, HttpError> { let sa = rqctx.context(); - Ok(sa.omicron_zones_list().await?) + Ok(HttpResponseOk(sa.omicron_zones_list().await?)) } #[endpoint { diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 6f8daa308b..1966227264 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -10,6 +10,8 @@ pub use crate::zone_bundle::ZoneBundleMetadata; pub use illumos_utils::opte::params::DhcpConfig; pub use illumos_utils::opte::params::VpcFirewallRule; pub use illumos_utils::opte::params::VpcFirewallRulesEnsureBody; +use illumos_utils::zpool::ZpoolName; +use omicron_common::api::external::Generation; use omicron_common::api::internal::nexus::{ DiskRuntimeState, InstanceProperties, InstanceRuntimeState, SledInstanceState, VmmRuntimeState, @@ -26,7 +28,6 @@ use std::net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6}; use std::time::Duration; use thiserror::Error; use uuid::Uuid; -use illumos_utils::zpool::ZpoolName; /// Used to request a Disk state change #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, JsonSchema)] @@ -867,9 +868,11 @@ pub struct ServiceEnsureBody { } /// Describes the set of Omicron zones running on a sled -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, +)] pub struct OmicronZonesConfig { - // XXX-dap generation number + pub generation: Generation, pub zones: Vec, } @@ -916,9 +919,20 @@ impl OmicronZoneConfig { DatasetName::new(dataset.pool_name, dataset_kind) } + + // XXX-dap TODO-doc + pub fn zone_name(&self) -> String { + illumos_utils::running_zone::InstalledZone::get_zone_name( + self.zone_type.zone_type_str(), + self.id, + ) + } } /// Describes a persistent ZFS dataset associated with an Omicron zone +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, +)] pub struct OmicronZoneDataset { pool_name: ZpoolName, } @@ -929,6 +943,9 @@ pub struct OmicronZoneDataset { /// XXX-dap ideally this would not be necessary at all! Sled Agent shouldn't /// have to know about the things running on it, I think? /// XXX-dap commonize with ServiceType (well, probably remove ServiceType) +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, +)] pub enum OmicronZoneType { BoundaryNtp { address: SocketAddrV6, @@ -1010,6 +1027,26 @@ pub enum OmicronZoneType { }, } +impl OmicronZoneType { + // XXX-dap TODO-doc must match ZoneType + fn zone_type_str(&self) -> &str { + match self { + OmicronZoneType::BoundaryNtp { .. } => "ntp", + OmicronZoneType::InternalNtp { .. } => "ntp", + + OmicronZoneType::Clickhouse { .. } => "clickhouse", + OmicronZoneType::ClickhouseKeeper { .. } => "clickhouse_keeper", + OmicronZoneType::CockroachDb { .. } => "cockroachdb", + OmicronZoneType::Crucible { .. } => "crucible", + OmicronZoneType::CruciblePantry { .. } => "crucible_pantry", + OmicronZoneType::ExternalDns { .. } => "external_dns", + OmicronZoneType::InternalDns { .. } => "internal_dns", + OmicronZoneType::Nexus { .. } => "nexus", + OmicronZoneType::Oximeter { .. } => "oximeter", + } + } +} + #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] pub struct TimeSync { /// The synchronization state of the sled, true when the system clock diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index c5bdea5803..5aa8f0b5a7 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -20,10 +20,10 @@ //! of what other services Nexus wants to have executing on the sled. //! //! To accomplish this, the following interfaces are exposed: -//! - [ServiceManager::ensure_all_services_persistent] exposes an API to request -//! a set of services that should persist beyond reboot. +//! - [ServiceManager::ensure_all_omicron_zones_persistent] exposes an API to +//! request a set of Omicron zones that should persist beyond reboot. //! - [ServiceManager::activate_switch] exposes an API to specifically enable -//! or disable (via [ServiceManager::deactivate_switch]) the switch zone. +//! or disable (via [ServiceManager::deactivate_switch]) the switch zone. use crate::bootstrap::early_networking::{ EarlyNetworkSetup, EarlyNetworkSetupError, @@ -31,9 +31,9 @@ use crate::bootstrap::early_networking::{ use crate::bootstrap::BootstrapNetworking; use crate::config::SidecarRevision; use crate::params::{ - DendriteAsic, ServiceEnsureBody, ServiceType, ServiceZoneRequest, - ServiceZoneService, TimeSync, ZoneBundleCause, ZoneBundleMetadata, - ZoneType, + DendriteAsic, OmicronZoneConfig, OmicronZonesConfig, ServiceEnsureBody, + ServiceType, ServiceZoneRequest, ServiceZoneService, TimeSync, + ZoneBundleCause, ZoneBundleMetadata, ZoneType, }; use crate::profile::*; use crate::smf_helper::Service; @@ -274,25 +274,25 @@ impl Config { } // The filename of the ledger, within the provided directory. -const SERVICES_LEDGER_FILENAME_V1: &str = "services.json"; +const SERVICES_LEDGER_FILENAME: &str = "services.json"; // A wrapper around `ZoneRequest`, which allows it to be serialized // to a JSON file. // XXX-dap TODO-doc #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -struct OldZoneRequests { +struct AllZoneRequestsV1 { generation: Generation, - requests: Vec, + requests: Vec, } -impl Default for OldZoneRequests { +impl Default for AllZoneRequestsV1 { fn default() -> Self { Self { generation: Generation::new(), requests: vec![] } } } -impl Ledgerable for OldZoneRequests { - fn is_newer_than(&self, other: &OldZoneRequests) -> bool { +impl Ledgerable for AllZoneRequestsV1 { + fn is_newer_than(&self, other: &AllZoneRequestsV1) -> bool { self.generation >= other.generation } @@ -304,13 +304,42 @@ impl Ledgerable for OldZoneRequests { // 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 { +struct ZoneRequestV1 { zone: ServiceZoneRequest, // TODO: Consider collapsing "root" into ServiceZoneRequest #[schemars(with = "String")] root: Utf8PathBuf, } +// XXX-dap TODO-doc and maybe rename it? +#[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] +struct ZoneConfig { + zone: OmicronZoneConfig, + // TODO: Consider collapsing "root" into OmicronZoneConfig? + #[schemars(with = "String")] + root: Utf8PathBuf, +} + +// The filename of the ledger, within the provided directory. +const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; + +// XXX-dap TODO-doc +#[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] +struct ZonesConfig { + generation: Generation, + zones: Vec, +} + +impl Ledgerable for ZonesConfig { + fn is_newer_than(&self, other: &ZonesConfig) -> bool { + self.generation >= other.generation + } + + fn generation_bump(&mut self) { + self.generation = self.generation.next(); + } +} + struct Task { // A signal for the initializer task to terminate exit_tx: oneshot::Sender<()>, @@ -475,14 +504,27 @@ impl ServiceManager { async fn all_service_ledgers(&self) -> Vec { if let Some(dir) = self.inner.ledger_directory_override.get() { - return vec![dir.join(SERVICES_LEDGER_FILENAME_V1)]; + return vec![dir.join(SERVICES_LEDGER_FILENAME)]; + } + self.inner + .storage + .all_m2_mountpoints(sled_hardware::disk::CONFIG_DATASET) + .await + .into_iter() + .map(|p| p.join(SERVICES_LEDGER_FILENAME)) + .collect() + } + + async fn all_omicron_zone_ledgers(&self) -> Vec { + if let Some(dir) = self.inner.ledger_directory_override.get() { + return vec![dir.join(ZONES_LEDGER_FILENAME)]; } self.inner .storage .all_m2_mountpoints(sled_hardware::disk::CONFIG_DATASET) .await .into_iter() - .map(|p| p.join(SERVICES_LEDGER_FILENAME_V1)) + .map(|p| p.join(ZONES_LEDGER_FILENAME)) .collect() } @@ -501,7 +543,7 @@ impl ServiceManager { let mut existing_zones = self.inner.zones.lock().await; let Some(mut ledger) = - Ledger::::new(log, ledger_paths).await + Ledger::::new(log, ledger_paths).await else { info!(log, "Loading services - No services detected"); return Ok(()); @@ -516,7 +558,7 @@ impl ServiceManager { let all_zones_request = self .ensure_all_services( &mut existing_zones, - &OldZoneRequests::default(), + &AllZoneRequestsV1::default(), ServiceEnsureBody { services: services .requests @@ -1047,9 +1089,11 @@ impl ServiceManager { .add_instance(ServiceInstanceBuilder::new("default"))) } + // XXX-dap need to update this thing to take some enum that's either the + // switch zone or one of the other zones async fn initialize_zone( &self, - request: &ZoneRequest, + request: &ZoneConfig, filesystems: &[zone::Fs], data_links: &[String], ) -> Result { @@ -2077,7 +2121,59 @@ impl ServiceManager { async fn initialize_services_locked( &self, existing_zones: &mut BTreeMap, - requests: &Vec, + requests: &Vec, + ) -> Result<(), Error> { + if let Some(name) = requests + .iter() + .map(|request| request.zone.zone_name()) + .duplicates() + .next() + { + return Err(Error::BadServiceRequest { + service: name, + message: "Should not initialize zone twice".to_string(), + }); + } + + let futures = requests.iter().map(|request| { + async move { + self.initialize_zone( + request, + // filesystems= + &[], + // data_links= + &[], + ) + .await + .map_err(|error| (request.zone.zone_name(), error)) + } + }); + let results = futures::future::join_all(futures).await; + + let mut errors = Vec::new(); + for result in results { + match result { + Ok(zone) => { + existing_zones.insert(zone.name().to_string(), zone); + } + Err((zone_name, error)) => { + errors.push((zone_name, Box::new(error))); + } + } + } + + if !errors.is_empty() { + return Err(Error::ZoneInitialize(errors)); + } + + Ok(()) + } + + // Populates `existing_zones` according to the requests in `services`. + async fn initialize_omicron_zones_locked( + &self, + existing_zones: &mut BTreeMap, + requests: &Vec, ) -> Result<(), Error> { if let Some(name) = requests .iter() @@ -2152,104 +2248,238 @@ impl ServiceManager { Err(BundleError::NoSuchZone { name: name.to_string() }) } - /// Ensures that particular Omicron zones are running - /// - /// These services will be instantiated by this function, and will be - /// recorded to a local file to ensure they start automatically on next - /// boot. - pub async fn ensure_all_omicron_zones_persistent( + /// Returns the current Omicron zone configuration + pub async fn omicron_zones_list( &self, - request: OmicronZonesConfig, - ) -> Result<(), Error> { + ) -> Result { let log = &self.inner.log; - let mut existing_zones = self.inner.zones.lock().await; + // We need to take the lock in order for the information in the ledger + // to be up-to-date. + let _existing_zones = self.inner.zones.lock().await; // Read the existing set of services from the ledger. - let service_paths = self.all_service_ledgers().await; - let mut ledger = - match Ledger::::new(log, service_paths.clone()) + let zone_ledger_paths = self.all_omicron_zone_ledgers().await; + let ledger = + match Ledger::::new(log, zone_ledger_paths.clone()) .await { Some(ledger) => ledger, - None => Ledger::::new_with( + None => Ledger::::new_with( log, - service_paths.clone(), - OldZoneRequests::default(), + zone_ledger_paths.clone(), + ZonesConfig { + // XXX-dap this means Nexus must use a newer generation + // for its first one + generation: Generation::new(), + zones: vec![], + }, ), }; - let ledger_zone_requests = ledger.data_mut(); - let mut zone_requests = self - .ensure_all_services( - &mut existing_zones, - ledger_zone_requests, - request, - ) - .await?; - - // Update the services in the ledger and write it back to both M.2s - ledger_zone_requests.requests.clear(); - ledger_zone_requests.requests.append(&mut zone_requests.requests); - ledger.commit().await?; - - Ok(()) + let ledger_zone_config = ledger.data(); + Ok(OmicronZonesConfig { + generation: ledger_zone_config.generation, + zones: ledger_zone_config + .zones + .iter() + .map(|z| z.zone.clone()) + .collect(), + }) } - /// Ensures that particular services should be initialized. + /// Ensures that particular Omicron zones are running /// /// These services will be instantiated by this function, and will be /// recorded to a local file to ensure they start automatically on next /// boot. - pub async fn ensure_all_services_persistent( + pub async fn ensure_all_omicron_zones_persistent( &self, - request: ServiceEnsureBody, + request: OmicronZonesConfig, ) -> Result<(), Error> { let log = &self.inner.log; let mut existing_zones = self.inner.zones.lock().await; // Read the existing set of services from the ledger. - let service_paths = self.all_service_ledgers().await; + let zone_ledger_paths = self.all_omicron_zone_ledgers().await; let mut ledger = - match Ledger::::new(log, service_paths.clone()) + match Ledger::::new(log, zone_ledger_paths.clone()) .await { Some(ledger) => ledger, - None => Ledger::::new_with( + None => Ledger::::new_with( log, - service_paths.clone(), - OldZoneRequests::default(), + zone_ledger_paths.clone(), + ZonesConfig { + // XXX-dap this means Nexus must use a newer generation + // for its first one + generation: Generation::new(), + zones: vec![], + }, ), }; - let ledger_zone_requests = ledger.data_mut(); - let mut zone_requests = self - .ensure_all_services( + let ledger_zone_config = ledger.data_mut(); + + let new_config = self + .ensure_all_omicron_zones( &mut existing_zones, - ledger_zone_requests, + ledger_zone_config, request, ) .await?; - // Update the services in the ledger and write it back to both M.2s - ledger_zone_requests.requests.clear(); - ledger_zone_requests.requests.append(&mut zone_requests.requests); + // Update the zones in the ledger and write it back to both M.2s + *ledger_zone_config = new_config; ledger.commit().await?; Ok(()) } + // Ensures that only the following Omicron zones are running. + // + // Does not record any information such that these services are + // re-instantiated on boot. + async fn ensure_all_omicron_zones( + &self, + // XXX-dap drop MutexGuard part + existing_zones: &mut MutexGuard<'_, BTreeMap>, + old_config: &ZonesConfig, + new_request: OmicronZonesConfig, + ) -> Result { + let log = &self.inner.log; + + // Do some data-normalization to ensure we can compare the "requested + // set" vs the "existing set" as HashSets. + // XXX-dap can we not skip this clone? + let old_zones_set: HashSet = + HashSet::from_iter(old_config.zones.iter().map(|z| z.zone.clone())); + let requested_zones_set = + HashSet::from_iter(new_request.zones.into_iter()); + + let zones_to_be_removed = + old_zones_set.difference(&requested_zones_set); + let zones_to_be_added = requested_zones_set.difference(&old_zones_set); + + // Destroy zones that should not be running + for zone in zones_to_be_removed { + let expected_zone_name = zone.zone_name(); + if let Some(mut zone) = existing_zones.remove(&expected_zone_name) { + debug!( + log, + "removing an existing zone"; + "zone_name" => &expected_zone_name, + ); + if let Err(e) = self + .inner + .zone_bundler + .create(&zone, ZoneBundleCause::UnexpectedZone) + .await + { + error!( + log, + "Failed to take bundle of unexpected zone"; + "zone_name" => &expected_zone_name, + "reason" => ?e, + ); + } + if let Err(e) = zone.stop().await { + error!(log, "Failed to stop zone {}: {e}", zone.name()); + } + } else { + warn!(log, "Expected to remove zone, but could not find it"); + } + } + + // Create zones that should be running + let all_u2_roots = + self.inner.storage.all_u2_mountpoints(ZONE_DATASET).await; + let mut new_zones = Vec::new(); + for zone in zones_to_be_added { + // Check if we think the zone should already be running + let name = zone.zone_name(); + if existing_zones.contains_key(&name) { + // Make sure the zone actually exists in the right state too + match Zones::find(&name).await { + Ok(Some(zone)) if zone.state() == zone::State::Running => { + info!(log, "skipping running zone"; "zone" => &name); + continue; + } + _ => { + // Mismatch between SA's view and reality, let's try to + // clean up any remanants and try initialize it again + warn!( + log, + "expected to find existing zone in running state"; + "zone" => &name, + ); + if let Err(e) = + existing_zones.remove(&name).unwrap().stop().await + { + error!( + log, + "Failed to stop zone"; + "zone" => &name, + "error" => %e, + ); + } + } + } + } + + // For each new zone request, we pick an arbitrary U.2 to store + // the zone filesystem. Note: This isn't known to Nexus right now, + // so it's a local-to-sled decision. + // + // This is (currently) intentional, as the zone filesystem should + // be destroyed between reboots. + let mut rng = rand::thread_rng(); + let root = all_u2_roots + .choose(&mut rng) + .ok_or_else(|| Error::U2NotFound)? + .clone(); + + // XXX-dap XXX XXX XXX working here + // So: the current problem is: how to store the root we choose? + // (and maybe: is this the right place to choose it?) I opted not + // to put this into the ledger structure because I hoped I wouldn't + // need it. But I think we might need it because: + // - we need to tear down this filesystem on sled agent startup when + // we wipe everything (I assume this is how we do this -- haven't + // verified it) + // XXX-dap another thing I noticed here is that the old code + // instantiated a whole AllZoneRequestsV1 only for the "requests" + // field (I think). We return the whole thing but the caller only + // uses "requests". We also pass only "requests" down to + // initialize_services_locked(). + // XXX-dap next step will be to update initialize_services_locked(). + new_zones.push(ZoneConfig { zone: zone.clone(), root }); + } + + self.initialize_omicron_zones_locked(existing_zones, &new_zones) + .await?; + + for old_zone in &old_config.zones { + if requested_zones_set.contains(&old_zone.zone) { + new_zones.push(old_zone.clone()); + } + } + + Ok(ZonesConfig { generation: new_request.generation, zones: new_zones }) + } + // Ensures that only the following services are running. // // Does not record any information such that these services are // re-instantiated on boot. + // XXX-dap remove me (change callers to use ensure_all_omicron_zones()) async fn ensure_all_services( &self, existing_zones: &mut MutexGuard<'_, BTreeMap>, - old_request: &OldZoneRequests, + old_request: &AllZoneRequestsV1, request: ServiceEnsureBody, - ) -> Result { + ) -> Result { let log = &self.inner.log; // Do some data-normalization to ensure we can compare the "requested @@ -2296,7 +2526,7 @@ impl ServiceManager { } // Create zones that should be running - let mut zone_requests = OldZoneRequests::default(); + let mut zone_requests = AllZoneRequestsV1::default(); let all_u2_roots = self.inner.storage.all_u2_mountpoints(ZONE_DATASET).await; for zone in zones_to_be_added { @@ -2344,7 +2574,7 @@ impl ServiceManager { zone_requests .requests - .push(ZoneRequest { zone: zone.clone(), root }); + .push(ZoneRequestV1 { zone: zone.clone(), root }); } self.initialize_services_locked( existing_zones, @@ -3033,7 +3263,7 @@ impl ServiceManager { .clone() }; - let request = ZoneRequest { zone: request.clone(), root }; + let request = ZoneRequestV1 { zone: request.clone(), root }; let zone = self.initialize_zone(&request, filesystems, data_links).await?; *sled_zone = @@ -3190,6 +3420,7 @@ mod test { async fn ensure_new_service(mgr: &ServiceManager, id: Uuid) { let _expectations = expect_new_service(); + // XXX-dap replace with call to ensure_all_omicron_zones_persistent mgr.ensure_all_services_persistent(ServiceEnsureBody { services: vec![ServiceZoneRequest { id, @@ -3216,6 +3447,7 @@ mod test { // Prepare to call "ensure" for a service which already exists. We should // return the service without actually installing a new zone. async fn ensure_existing_service(mgr: &ServiceManager, id: Uuid) { + // XXX-dap replace with call to ensure_all_omicron_zones_persistent mgr.ensure_all_services_persistent(ServiceEnsureBody { services: vec![ServiceZoneRequest { id, @@ -3544,7 +3776,7 @@ mod test { // Next, delete the ledger. This means the service we just created will // not be remembered on the next initialization. std::fs::remove_file( - test_config.config_dir.path().join(SERVICES_LEDGER_FILENAME_V1), + test_config.config_dir.path().join(SERVICES_LEDGER_FILENAME), ) .unwrap(); @@ -3595,7 +3827,7 @@ mod test { #[test] fn test_all_zone_requests_schema() { - let schema = schemars::schema_for!(OldZoneRequests); + let schema = schemars::schema_for!(AllZoneRequestsV1); expectorate::assert_contents( "../schema/all-zone-requests.json", &serde_json::to_string_pretty(&schema).unwrap(), diff --git a/sled-agent/src/sled_agent.rs b/sled-agent/src/sled_agent.rs index 7628b51b54..3890d63077 100644 --- a/sled-agent/src/sled_agent.rs +++ b/sled-agent/src/sled_agent.rs @@ -14,8 +14,8 @@ use crate::nexus::{NexusClientWithResolver, NexusRequestQueue}; use crate::params::{ DiskStateRequested, InstanceHardware, InstanceMigrationSourceParams, InstancePutStateResponse, InstanceStateRequested, - InstanceUnregisterResponse, OmicronZonesConfig, ServiceEnsureBody, - SledRole, TimeSync, VpcFirewallRule, ZoneBundleMetadata, Zpool, + InstanceUnregisterResponse, OmicronZonesConfig, SledRole, TimeSync, + VpcFirewallRule, ZoneBundleMetadata, Zpool, }; use crate::services::{self, ServiceManager}; use crate::storage_manager::{self, StorageManager}; @@ -57,7 +57,6 @@ use std::net::{Ipv6Addr, SocketAddr, SocketAddrV6}; use std::sync::Arc; use uuid::Uuid; -use crate::storage::dataset::DatasetName; #[cfg(not(test))] use illumos_utils::{dladm::Dladm, zone::Zones}; #[cfg(test)] @@ -724,7 +723,7 @@ impl SledAgent { pub async fn omicron_zones_list( &self, ) -> Result { - Ok(self.inner.services.omicron_zones_list(requested_services).await?) + Ok(self.inner.services.omicron_zones_list().await?) } /// Ensures that the specific set of Omicron zones are running as configured @@ -753,7 +752,7 @@ impl SledAgent { self.inner .services - .ensure_all_omicron_zones_persistent(requested_services) + .ensure_all_omicron_zones_persistent(requested_zones) .await?; Ok(()) } From 50ffbe4b479028442ae7c1d4538c552e75cb7910 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 8 Nov 2023 04:15:58 +0000 Subject: [PATCH 03/44] WIP: it compiles --- common/src/api/external/mod.rs | 1 + sled-agent/src/params.rs | 18 +- sled-agent/src/services.rs | 1868 ++++++++++++++++---------------- 3 files changed, 947 insertions(+), 940 deletions(-) diff --git a/common/src/api/external/mod.rs b/common/src/api/external/mod.rs index fcea57220d..da08060c9f 100644 --- a/common/src/api/external/mod.rs +++ b/common/src/api/external/mod.rs @@ -622,6 +622,7 @@ impl From for i64 { Debug, Deserialize, Eq, + Hash, JsonSchema, Ord, PartialEq, diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 1966227264..9da60a40ad 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -917,14 +917,14 @@ impl OmicronZoneConfig { } }?; - DatasetName::new(dataset.pool_name, dataset_kind) + Some(DatasetName::new(dataset.pool_name.clone(), dataset_kind)) } // XXX-dap TODO-doc pub fn zone_name(&self) -> String { illumos_utils::running_zone::InstalledZone::get_zone_name( self.zone_type.zone_type_str(), - self.id, + Some(self.id), ) } } @@ -1029,7 +1029,7 @@ pub enum OmicronZoneType { impl OmicronZoneType { // XXX-dap TODO-doc must match ZoneType - fn zone_type_str(&self) -> &str { + pub fn zone_type_str(&self) -> &str { match self { OmicronZoneType::BoundaryNtp { .. } => "ntp", OmicronZoneType::InternalNtp { .. } => "ntp", @@ -1047,6 +1047,18 @@ impl OmicronZoneType { } } +impl crate::smf_helper::Service for OmicronZoneType { + fn service_name(&self) -> String { + self.zone_type_str().to_owned() + } + fn smf_name(&self) -> String { + format!("svc:/oxide/{}", self.service_name()) + } + fn should_import(&self) -> bool { + true + } +} + #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] pub struct TimeSync { /// The synchronization state of the sled, true when the system clock diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 5aa8f0b5a7..8a6ffc2e32 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -31,7 +31,7 @@ use crate::bootstrap::early_networking::{ use crate::bootstrap::BootstrapNetworking; use crate::config::SidecarRevision; use crate::params::{ - DendriteAsic, OmicronZoneConfig, OmicronZonesConfig, ServiceEnsureBody, + DendriteAsic, OmicronZoneConfig, OmicronZoneType, OmicronZonesConfig, ServiceType, ServiceZoneRequest, ServiceZoneService, TimeSync, ZoneBundleCause, ZoneBundleMetadata, ZoneType, }; @@ -336,10 +336,55 @@ impl Ledgerable for ZonesConfig { } fn generation_bump(&mut self) { + // XXX-dap what do we do here? this is not right. self.generation = self.generation.next(); } } +impl ZonesConfig { + pub fn to_omicron_zones_config(self) -> OmicronZonesConfig { + OmicronZonesConfig { + generation: self.generation, + zones: self.zones.into_iter().map(|z| z.zone).collect(), + } + } +} + +// XXX-dap TODO-doc +enum ZoneArgs<'a> { + Omicron(&'a ZoneConfig), + + // XXX-dap make this a more specific struct + SledLocal(&'a ZoneRequestV1), +} + +impl<'a> ZoneArgs<'a> { + pub fn omicron_type(&self) -> Option<&'a OmicronZoneType> { + match self { + ZoneArgs::Omicron(zone_config) => Some(&zone_config.zone.zone_type), + ZoneArgs::SledLocal(_) => None, + } + } + + pub fn sled_local_services( + &self, + ) -> Box + 'a> { + match self { + ZoneArgs::Omicron(_) => Box::new(std::iter::empty()), + ZoneArgs::SledLocal(request) => { + Box::new(request.zone.services.iter().map(|s| &s.details)) + } + } + } + + pub fn root(&self) -> &Utf8Path { + match self { + ZoneArgs::Omicron(zone_config) => &zone_config.root, + ZoneArgs::SledLocal(zone_request) => &zone_request.root, + } + } +} + struct Task { // A signal for the initializer task to terminate exit_tx: oneshot::Sender<()>, @@ -538,65 +583,60 @@ impl ServiceManager { // more clearly. pub async fn load_services(&self) -> Result<(), Error> { let log = &self.inner.log; - let ledger_paths = self.all_service_ledgers().await; + // XXX-dap look for legacy service ledger if this isn't present + let ledger_paths = self.all_omicron_zone_ledgers().await; info!(log, "Loading services from: {ledger_paths:?}"); let mut existing_zones = self.inner.zones.lock().await; let Some(mut ledger) = - Ledger::::new(log, ledger_paths).await + Ledger::::new(log, ledger_paths).await else { info!(log, "Loading services - No services detected"); return Ok(()); }; - let services = ledger.data_mut(); + let zones_config = ledger.data_mut(); + let omicron_zones_config = + zones_config.clone().to_omicron_zones_config(); // Initialize internal DNS only first: we need it to look up the // boundary switch addresses. This dependency is implicit: when we call - // `ensure_all_services` below, we eventually land in + // `ensure_all_omicron_zones` below, we eventually land in // `opte_ports_needed()`, which for some service types (including Ntp // but _not_ including InternalDns), we perform internal DNS lookups. let all_zones_request = self - .ensure_all_services( + .ensure_all_omicron_zones( &mut existing_zones, - &AllZoneRequestsV1::default(), - ServiceEnsureBody { - services: services - .requests - .clone() - .into_iter() - .filter(|svc| { - matches!( - svc.zone.zone_type, - ZoneType::InternalDns | ZoneType::Ntp - ) - }) - .map(|zone_request| zone_request.zone) - .collect(), + None, + omicron_zones_config.clone(), + |z: &OmicronZoneConfig| { + matches!( + z.zone_type, + OmicronZoneType::InternalDns { .. } + | OmicronZoneType::BoundaryNtp { .. } + | OmicronZoneType::InternalNtp { .. } + ) }, ) .await?; // Initialize NTP services next as they are required for time // synchronization, which is a pre-requisite for the other services. We - // keep `ZoneType::InternalDns` because `ensure_all_services` is + // keep `ZoneType::InternalDns` because `ensure_all_omicron_zones` is // additive. + // XXX-dap This looks like a duplicate of the block above -- why do we + // do this? let all_zones_request = self - .ensure_all_services( + .ensure_all_omicron_zones( &mut existing_zones, - &all_zones_request, - ServiceEnsureBody { - services: services - .requests - .clone() - .into_iter() - .filter(|svc| { - matches!( - svc.zone.zone_type, - ZoneType::InternalDns | ZoneType::Ntp - ) - }) - .map(|zone_request| zone_request.zone) - .collect(), + Some(&all_zones_request), + omicron_zones_config.clone(), + |z: &OmicronZoneConfig| { + matches!( + z.zone_type, + OmicronZoneType::InternalDns { .. } + | OmicronZoneType::BoundaryNtp { .. } + | OmicronZoneType::InternalNtp { .. } + ) }, ) .await?; @@ -638,17 +678,11 @@ impl ServiceManager { let mut existing_zones = self.inner.zones.lock().await; // Initialize all remaining services - self.ensure_all_services( + self.ensure_all_omicron_zones( &mut existing_zones, - &all_zones_request, - ServiceEnsureBody { - services: services - .requests - .clone() - .into_iter() - .map(|zone_request| zone_request.zone) - .collect(), - }, + Some(&all_zones_request), + omicron_zones_config, + |_| true, ) .await?; Ok(()) @@ -704,10 +738,10 @@ impl ServiceManager { // Check the services intended to run in the zone to determine whether any // physical devices need to be mapped into the zone when it is created. - fn devices_needed(req: &ServiceZoneRequest) -> Result, Error> { + fn devices_needed(zone_args: &ZoneArgs<'_>) -> Result, Error> { let mut devices = vec![]; - for svc in &req.services { - match &svc.details { + for svc_details in zone_args.sled_local_services() { + match svc_details { ServiceType::Dendrite { asic: DendriteAsic::TofinoAsic } => { if let Ok(Some(n)) = tofino::get_tofino() { if let Ok(device_path) = n.device_path() { @@ -743,18 +777,22 @@ impl ServiceManager { // bootstrap address. fn bootstrap_address_needed( &self, - req: &ServiceZoneRequest, + zone_args: &ZoneArgs<'_>, ) -> Result, Error> { - match req.zone_type { - ZoneType::Switch => { - let link = self - .inner - .bootstrap_vnic_allocator - .new_bootstrap() - .map_err(Error::SledLocalVnicCreation)?; - Ok(Some((link, self.inner.switch_zone_bootstrap_address))) + if let ZoneArgs::SledLocal(req) = zone_args { + match req.zone.zone_type { + ZoneType::Switch => { + let link = self + .inner + .bootstrap_vnic_allocator + .new_bootstrap() + .map_err(Error::SledLocalVnicCreation)?; + Ok(Some((link, self.inner.switch_zone_bootstrap_address))) + } + _ => Ok(None), } - _ => Ok(None), + } else { + Ok(None) } } @@ -779,7 +817,7 @@ impl ServiceManager { // local addresses in the zone. fn links_needed( &self, - req: &ServiceZoneRequest, + zone_args: &ZoneArgs<'_>, ) -> Result, Error> { let mut links: Vec<(Link, bool)> = Vec::new(); @@ -787,8 +825,8 @@ impl ServiceManager { Error::Underlay(underlay::Error::SystemDetection(e)) })?; - for svc in &req.services { - match &svc.details { + for svc_details in zone_args.sled_local_services() { + match &svc_details { ServiceType::Tfport { pkt_source, asic: _ } => { // The tfport service requires a MAC device to/from which sidecar // packets may be multiplexed. If the link isn't present, don't @@ -842,12 +880,14 @@ impl ServiceManager { // OPTE ports need to be created and mapped into the zone when it is created. async fn opte_ports_needed( &self, - req: &ServiceZoneRequest, + zone_args: &ZoneArgs<'_>, ) -> Result, Error> { // Only some services currently need OPTE ports if !matches!( - req.zone_type, - ZoneType::ExternalDns | ZoneType::Nexus | ZoneType::Ntp + zone_args.omicron_type(), + Some(OmicronZoneType::ExternalDns { .. }) + | Some(OmicronZoneType::Nexus { .. }) + | Some(OmicronZoneType::BoundaryNtp { .. }) ) { return Ok(vec![]); } @@ -894,94 +934,108 @@ impl ServiceManager { }) .collect(); - let mut ports = vec![]; - for svc in &req.services { - let external_ip; - let (nic, snat, external_ips) = match &svc.details { - ServiceType::Nexus { external_ip, nic, .. } => { - (nic, None, std::slice::from_ref(external_ip)) - } - ServiceType::ExternalDns { dns_address, nic, .. } => { - external_ip = dns_address.ip(); - (nic, None, std::slice::from_ref(&external_ip)) - } - ServiceType::BoundaryNtp { nic, snat_cfg, .. } => { - (nic, Some(*snat_cfg), &[][..]) - } - _ => continue, - }; - - // Create the OPTE port for the service. - // Note we don't plumb any firewall rules at this point, - // Nexus will plumb them down later but the default OPTE - // config allows outbound access which is enough for - // Boundary NTP which needs to come up before Nexus. - let port = port_manager - .create_port(nic, snat, external_ips, &[], DhcpCfg::default()) - .map_err(|err| Error::ServicePortCreation { - service: svc.details.to_string(), - err: Box::new(err), - })?; + let external_ip; + let (zone_type_str, nic, snat, external_ips) = match &zone_args + .omicron_type() + { + Some( + zone_type @ OmicronZoneType::Nexus { external_ip, nic, .. }, + ) => ( + zone_type.zone_type_str(), + nic, + None, + std::slice::from_ref(external_ip), + ), + Some( + zone_type @ OmicronZoneType::ExternalDns { + dns_address, + nic, + .. + }, + ) => { + external_ip = dns_address.ip(); + ( + zone_type.zone_type_str(), + nic, + None, + std::slice::from_ref(&external_ip), + ) + } + Some( + zone_type @ OmicronZoneType::BoundaryNtp { + nic, snat_cfg, .. + }, + ) => (zone_type.zone_type_str(), nic, Some(*snat_cfg), &[][..]), + _ => panic!("unexpected zone type"), + }; - // We also need to update the switch with the NAT mappings - let (target_ip, first_port, last_port) = match snat { - Some(s) => (s.ip, s.first_port, s.last_port), - None => (external_ips[0], 0, u16::MAX), - }; + // Create the OPTE port for the service. + // Note we don't plumb any firewall rules at this point, + // Nexus will plumb them down later but the default OPTE + // config allows outbound access which is enough for + // Boundary NTP which needs to come up before Nexus. + let port = port_manager + .create_port(nic, snat, external_ips, &[], DhcpCfg::default()) + .map_err(|err| Error::ServicePortCreation { + service: zone_type_str.to_owned(), + err: Box::new(err), + })?; - for dpd_client in &dpd_clients { - // TODO-correctness(#2933): If we fail part-way we need to - // clean up previous entries instead of leaking them. - let nat_create = || async { - info!( - self.inner.log, "creating NAT entry for service"; - "service" => ?svc, - ); + // We also need to update the switch with the NAT mappings + let (target_ip, first_port, last_port) = match snat { + Some(s) => (s.ip, s.first_port, s.last_port), + None => (external_ips[0], 0, u16::MAX), + }; - dpd_client - .ensure_nat_entry( - &self.inner.log, - target_ip.into(), - dpd_client::types::MacAddr { - a: port.0.mac().into_array(), - }, - first_port, - last_port, - port.0.vni().as_u32(), - underlay_address, - ) - .await - .map_err(BackoffError::transient)?; + for dpd_client in &dpd_clients { + // TODO-correctness(#2933): If we fail part-way we need to + // clean up previous entries instead of leaking them. + let nat_create = || async { + info!( + self.inner.log, "creating NAT entry for service"; + "zone_type" => zone_type_str.to_owned(), + ); - Ok::<(), BackoffError>>(()) - }; - let log_failure = |error, _| { - warn!( - self.inner.log, "failed to create NAT entry for service"; - "error" => ?error, - "service" => ?svc, - ); - }; - retry_notify( - retry_policy_internal_service_aggressive(), - nat_create, - log_failure, - ) - .await?; - } + dpd_client + .ensure_nat_entry( + &self.inner.log, + target_ip.into(), + dpd_client::types::MacAddr { + a: port.0.mac().into_array(), + }, + first_port, + last_port, + port.0.vni().as_u32(), + underlay_address, + ) + .await + .map_err(BackoffError::transient)?; - ports.push(port); + Ok::<(), BackoffError>>(()) + }; + let log_failure = |error, _| { + warn!( + self.inner.log, "failed to create NAT entry for service"; + "error" => ?error, + "zone_type" => zone_type_str.to_owned(), + ); + }; + retry_notify( + retry_policy_internal_service_aggressive(), + nat_create, + log_failure, + ) + .await?; } - - Ok(ports) + Ok(vec![port]) } // Check the services intended to run in the zone to determine whether any // additional privileges need to be enabled for the zone. - fn privs_needed(req: &ServiceZoneRequest) -> Vec { + fn privs_needed(zone_args: &ZoneArgs<'_>) -> Vec { let mut needed = Vec::new(); - for svc in &req.services { - match &svc.details { + for svc_details in zone_args.sled_local_services() { + match svc_details { ServiceType::Tfport { .. } => { needed.push("default".to_string()); needed.push("sys_dl_config".to_string()); @@ -1089,17 +1143,15 @@ impl ServiceManager { .add_instance(ServiceInstanceBuilder::new("default"))) } - // XXX-dap need to update this thing to take some enum that's either the - // switch zone or one of the other zones async fn initialize_zone( &self, - request: &ZoneConfig, + request: ZoneArgs<'_>, filesystems: &[zone::Fs], data_links: &[String], ) -> Result { - let device_names = Self::devices_needed(&request.zone)?; + let device_names = Self::devices_needed(&request)?; let (bootstrap_vnic, bootstrap_name_and_address) = - match self.bootstrap_address_needed(&request.zone)? { + match self.bootstrap_address_needed(&request)? { Some((vnic, address)) => { let name = vnic.name().to_string(); (Some(vnic), Some((name, address))) @@ -1112,20 +1164,26 @@ impl ServiceManager { let links: Vec; let links_need_link_local: Vec; (links, links_need_link_local) = - self.links_needed(&request.zone)?.into_iter().unzip(); - let opte_ports = self.opte_ports_needed(&request.zone).await?; - let limit_priv = Self::privs_needed(&request.zone); + self.links_needed(&request)?.into_iter().unzip(); + let opte_ports = self.opte_ports_needed(&request).await?; + let limit_priv = Self::privs_needed(&request); // If the zone is managing a particular dataset, plumb that // dataset into the zone. Additionally, construct a "unique enough" name // so we can create multiple zones of this type without collision. - let unique_name = request.zone.zone_name_unique_identifier(); - let datasets = request - .zone - .dataset - .iter() - .map(|d| zone::Dataset { name: d.name.full() }) - .collect::>(); + let unique_name = match &request { + ZoneArgs::Omicron(zone_config) => Some(zone_config.zone.id), + ZoneArgs::SledLocal(_) => None, + }; + let datasets: Vec<_> = match &request { + ZoneArgs::Omicron(zone_config) => zone_config + .zone + .dataset_name() + .map(|n| zone::Dataset { name: n.full() }) + .into_iter() + .collect(), + ZoneArgs::SledLocal(_) => vec![], + }; let devices: Vec = device_names .iter() @@ -1148,12 +1206,18 @@ impl ServiceManager { ); } + let zone_type_str = match &request { + ZoneArgs::Omicron(zone_config) => { + zone_config.zone.zone_type.zone_type_str().to_owned() + } + ZoneArgs::SledLocal(req) => req.zone.zone_type.to_string(), + }; let installed_zone = InstalledZone::install( &self.inner.log, &self.inner.underlay_vnic_allocator, - &request.root, + &request.root(), zone_image_paths.as_slice(), - &request.zone.zone_type.to_string(), + &zone_type_str, unique_name, datasets.as_slice(), &filesystems, @@ -1170,8 +1234,16 @@ impl ServiceManager { // // These zones are self-assembling -- after they boot, there should // be no "zlogin" necessary to initialize. - match request.zone.zone_type { - ZoneType::Clickhouse => { + match &request { + ZoneArgs::Omicron(ZoneConfig { + zone: + OmicronZoneConfig { + zone_type: OmicronZoneType::Clickhouse { .. }, + underlay_address, + .. + }, + .. + }) => { let Some(info) = self.inner.sled_info.get() else { return Err(Error::SledAgentNotReady); }; @@ -1180,8 +1252,7 @@ impl ServiceManager { let datalink = installed_zone.get_control_vnic_name(); let gateway = &info.underlay_address.to_string(); - assert_eq!(request.zone.addresses.len(), 1); - let listen_addr = &request.zone.addresses[0].to_string(); + let listen_addr = &underlay_address.to_string(); let listen_port = &CLICKHOUSE_PORT.to_string(); let config = PropertyGroupBuilder::new("config") @@ -1207,7 +1278,16 @@ impl ServiceManager { })?; return Ok(RunningZone::boot(installed_zone).await?); } - ZoneType::ClickhouseKeeper => { + + ZoneArgs::Omicron(ZoneConfig { + zone: + OmicronZoneConfig { + zone_type: OmicronZoneType::ClickhouseKeeper { .. }, + underlay_address, + .. + }, + .. + }) => { let Some(info) = self.inner.sled_info.get() else { return Err(Error::SledAgentNotReady); }; @@ -1216,8 +1296,7 @@ impl ServiceManager { let datalink = installed_zone.get_control_vnic_name(); let gateway = &info.underlay_address.to_string(); - assert_eq!(request.zone.addresses.len(), 1); - let listen_addr = &request.zone.addresses[0].to_string(); + let listen_addr = &underlay_address.to_string(); let listen_port = &CLICKHOUSE_KEEPER_PORT.to_string(); let config = PropertyGroupBuilder::new("config") @@ -1246,7 +1325,16 @@ impl ServiceManager { })?; return Ok(RunningZone::boot(installed_zone).await?); } - ZoneType::CockroachDb => { + + ZoneArgs::Omicron(ZoneConfig { + zone: + OmicronZoneConfig { + zone_type: OmicronZoneType::CockroachDb { .. }, + underlay_address, + .. + }, + .. + }) => { let Some(info) = self.inner.sled_info.get() else { return Err(Error::SledAgentNotReady); }; @@ -1256,9 +1344,8 @@ impl ServiceManager { // Configure the CockroachDB service. let datalink = installed_zone.get_control_vnic_name(); let gateway = &info.underlay_address.to_string(); - assert_eq!(request.zone.addresses.len(), 1); let address = SocketAddr::new( - IpAddr::V6(request.zone.addresses[0]), + IpAddr::V6(*underlay_address), COCKROACH_PORT, ); let listen_addr = &address.ip().to_string(); @@ -1287,22 +1374,25 @@ impl ServiceManager { })?; return Ok(RunningZone::boot(installed_zone).await?); } - ZoneType::Crucible => { + + ZoneArgs::Omicron(ZoneConfig { + zone: + zone @ OmicronZoneConfig { + zone_type: OmicronZoneType::Crucible { .. }, + underlay_address, + .. + }, + .. + }) => { let Some(info) = self.inner.sled_info.get() else { return Err(Error::SledAgentNotReady); }; let datalink = installed_zone.get_control_vnic_name(); let gateway = &info.underlay_address.to_string(); - assert_eq!(request.zone.addresses.len(), 1); - let listen_addr = &request.zone.addresses[0].to_string(); + let listen_addr = &underlay_address.to_string(); let listen_port = &CRUCIBLE_PORT.to_string(); - let dataset_name = request - .zone - .dataset - .as_ref() - .map(|d| d.name.full()) - .expect("Crucible requires dataset"); + let dataset_name = zone.dataset_name().unwrap().full(); let uuid = &Uuid::new_v4().to_string(); let config = PropertyGroupBuilder::new("config") .add_property("datalink", "astring", datalink) @@ -1327,15 +1417,23 @@ impl ServiceManager { })?; return Ok(RunningZone::boot(installed_zone).await?); } - ZoneType::CruciblePantry => { + + ZoneArgs::Omicron(ZoneConfig { + zone: + OmicronZoneConfig { + zone_type: OmicronZoneType::CruciblePantry { .. }, + underlay_address, + .. + }, + .. + }) => { let Some(info) = self.inner.sled_info.get() else { return Err(Error::SledAgentNotReady); }; let datalink = installed_zone.get_control_vnic_name(); let gateway = &info.underlay_address.to_string(); - assert_eq!(request.zone.addresses.len(), 1); - let listen_addr = &request.zone.addresses[0].to_string(); + let listen_addr = &underlay_address.to_string(); let listen_port = &CRUCIBLE_PANTRY_PORT.to_string(); let config = PropertyGroupBuilder::new("config") @@ -1357,6 +1455,7 @@ impl ServiceManager { let running_zone = RunningZone::boot(installed_zone).await?; return Ok(running_zone); } + _ => {} } @@ -1387,7 +1486,7 @@ impl ServiceManager { self.inner.log, "Ensuring bootstrap address {} exists in {} zone", bootstrap_address.to_string(), - request.zone.zone_type.to_string() + zone_type_str, ); running_zone.ensure_bootstrap_address(*bootstrap_address).await?; info!( @@ -1408,7 +1507,14 @@ impl ServiceManager { })?; } - for addr in &request.zone.addresses { + let addresses = match &request { + ZoneArgs::Omicron(ZoneConfig { + zone: OmicronZoneConfig { underlay_address, .. }, + .. + }) => vec![*underlay_address], + ZoneArgs::SledLocal(req) => req.zone.addresses.clone(), + }; + for addr in &addresses { if *addr == Ipv6Addr::LOCALHOST { continue; } @@ -1433,9 +1539,7 @@ impl ServiceManager { let sled_underlay_subnet = Ipv6Subnet::::new(info.underlay_address); - if request - .zone - .addresses + if addresses .iter() .any(|ip| sled_underlay_subnet.net().contains(*ip)) { @@ -1467,370 +1571,496 @@ impl ServiceManager { })?; } - for service in &request.zone.services { - // TODO: Related to - // https://github.com/oxidecomputer/omicron/pull/1124 , should we - // avoid importing this manifest? - debug!(self.inner.log, "importing manifest"); - - let smfh = SmfHelper::new(&running_zone, &service.details); - smfh.import_manifest()?; - - match &service.details { - ServiceType::Nexus { - internal_address, - external_tls, - external_dns_servers, - .. - } => { - info!(self.inner.log, "Setting up Nexus service"); - - let sled_info = self - .inner - .sled_info - .get() - .ok_or(Error::SledAgentNotReady)?; - - // While Nexus will be reachable via `external_ip`, it communicates - // atop an OPTE port which operates on a VPC private IP. OPTE will - // map the private IP to the external IP automatically. - let port_ip = running_zone - .ensure_address_for_port("public", 0) - .await? - .ip(); - - // Nexus takes a separate config file for parameters which - // cannot be known at packaging time. - let nexus_port = if *external_tls { 443 } else { 80 }; - let deployment_config = NexusDeploymentConfig { - id: request.zone.id, - rack_id: sled_info.rack_id, - techport_external_server_port: - NEXUS_TECHPORT_EXTERNAL_PORT, - - dropshot_external: ConfigDropshotWithTls { - tls: *external_tls, - dropshot: dropshot::ConfigDropshot { - bind_address: SocketAddr::new( - port_ip, nexus_port, - ), - // This has to be large enough to support: - // - bulk writes to disks - request_body_max_bytes: 8192 * 1024, + match &request { + ZoneArgs::Omicron(zone_config) => { + // TODO: Related to + // https://github.com/oxidecomputer/omicron/pull/1124 , should we + // avoid importing this manifest? + debug!(self.inner.log, "importing manifest"); + + let smfh = + SmfHelper::new(&running_zone, &zone_config.zone.zone_type); + smfh.import_manifest()?; + + match &zone_config.zone.zone_type { + OmicronZoneType::Nexus { + internal_address, + external_tls, + external_dns_servers, + .. + } => { + info!(self.inner.log, "Setting up Nexus service"); + + let sled_info = self + .inner + .sled_info + .get() + .ok_or(Error::SledAgentNotReady)?; + + // While Nexus will be reachable via `external_ip`, it communicates + // atop an OPTE port which operates on a VPC private IP. OPTE will + // map the private IP to the external IP automatically. + let port_ip = running_zone + .ensure_address_for_port("public", 0) + .await? + .ip(); + + // Nexus takes a separate config file for parameters which + // cannot be known at packaging time. + let nexus_port = if *external_tls { 443 } else { 80 }; + let deployment_config = NexusDeploymentConfig { + id: zone_config.zone.id, + rack_id: sled_info.rack_id, + techport_external_server_port: + NEXUS_TECHPORT_EXTERNAL_PORT, + + dropshot_external: ConfigDropshotWithTls { + tls: *external_tls, + dropshot: dropshot::ConfigDropshot { + bind_address: SocketAddr::new( + port_ip, nexus_port, + ), + // This has to be large enough to support: + // - bulk writes to disks + request_body_max_bytes: 8192 * 1024, + default_handler_task_mode: + HandlerTaskMode::Detached, + }, + }, + dropshot_internal: dropshot::ConfigDropshot { + bind_address: (*internal_address).into(), + // This has to be large enough to support, among + // other things, the initial list of TLS + // certificates provided by the customer during rack + // setup. + request_body_max_bytes: 10 * 1024 * 1024, default_handler_task_mode: HandlerTaskMode::Detached, }, - }, - dropshot_internal: dropshot::ConfigDropshot { - bind_address: (*internal_address).into(), - // This has to be large enough to support, among - // other things, the initial list of TLS - // certificates provided by the customer during rack - // setup. - request_body_max_bytes: 10 * 1024 * 1024, - default_handler_task_mode: - HandlerTaskMode::Detached, - }, - internal_dns: nexus_config::InternalDns::FromSubnet { - subnet: Ipv6Subnet::::new( - sled_info.underlay_address, + internal_dns: + nexus_config::InternalDns::FromSubnet { + subnet: Ipv6Subnet::::new( + sled_info.underlay_address, + ), + }, + database: nexus_config::Database::FromDns, + external_dns_servers: external_dns_servers.clone(), + }; + + // Copy the partial config file to the expected location. + let config_dir = Utf8PathBuf::from(format!( + "{}/var/svc/manifest/site/nexus", + running_zone.root() + )); + // The filename of a half-completed config, in need of parameters supplied at + // runtime. + const PARTIAL_LEDGER_FILENAME: &str = + "config-partial.toml"; + // The filename of a completed config, merging the partial config with + // additional appended parameters known at runtime. + const COMPLETE_LEDGER_FILENAME: &str = "config.toml"; + let partial_config_path = + config_dir.join(PARTIAL_LEDGER_FILENAME); + let config_path = + config_dir.join(COMPLETE_LEDGER_FILENAME); + tokio::fs::copy(partial_config_path, &config_path) + .await + .map_err(|err| Error::io_path(&config_path, err))?; + + // Serialize the configuration and append it into the file. + let serialized_cfg = + toml::Value::try_from(&deployment_config) + .expect("Cannot serialize config"); + let mut map = toml::map::Map::new(); + map.insert("deployment".to_string(), serialized_cfg); + let config_str = + toml::to_string(&map).map_err(|err| { + Error::TomlSerialize { + path: config_path.clone(), + err, + } + })?; + let mut file = tokio::fs::OpenOptions::new() + .append(true) + .open(&config_path) + .await + .map_err(|err| Error::io_path(&config_path, err))?; + file.write_all(b"\n\n") + .await + .map_err(|err| Error::io_path(&config_path, err))?; + file.write_all(config_str.as_bytes()) + .await + .map_err(|err| Error::io_path(&config_path, err))?; + } + + OmicronZoneType::ExternalDns { + http_address, + dns_address, + .. + } => { + info!( + self.inner.log, + "Setting up external-dns service" + ); + + // Like Nexus, we need to be reachable externally via + // `dns_address` but we don't listen on that address + // directly but instead on a VPC private IP. OPTE will + // en/decapsulate as appropriate. + let port_ip = running_zone + .ensure_address_for_port("public", 0) + .await? + .ip(); + let dns_address = + SocketAddr::new(port_ip, dns_address.port()); + + smfh.setprop( + "config/http_address", + format!( + "[{}]:{}", + http_address.ip(), + http_address.port(), ), - }, - database: nexus_config::Database::FromDns, - external_dns_servers: external_dns_servers.clone(), - }; + )?; + smfh.setprop( + "config/dns_address", + dns_address.to_string(), + )?; - // Copy the partial config file to the expected location. - let config_dir = Utf8PathBuf::from(format!( - "{}/var/svc/manifest/site/nexus", - running_zone.root() - )); - // The filename of a half-completed config, in need of parameters supplied at - // runtime. - const PARTIAL_LEDGER_FILENAME: &str = "config-partial.toml"; - // The filename of a completed config, merging the partial config with - // additional appended parameters known at runtime. - const COMPLETE_LEDGER_FILENAME: &str = "config.toml"; - let partial_config_path = - config_dir.join(PARTIAL_LEDGER_FILENAME); - let config_path = config_dir.join(COMPLETE_LEDGER_FILENAME); - tokio::fs::copy(partial_config_path, &config_path) - .await - .map_err(|err| Error::io_path(&config_path, err))?; - - // Serialize the configuration and append it into the file. - let serialized_cfg = - toml::Value::try_from(&deployment_config) - .expect("Cannot serialize config"); - let mut map = toml::map::Map::new(); - map.insert("deployment".to_string(), serialized_cfg); - let config_str = toml::to_string(&map).map_err(|err| { - Error::TomlSerialize { path: config_path.clone(), err } - })?; - let mut file = tokio::fs::OpenOptions::new() - .append(true) - .open(&config_path) - .await - .map_err(|err| Error::io_path(&config_path, err))?; - file.write_all(b"\n\n") - .await - .map_err(|err| Error::io_path(&config_path, err))?; - file.write_all(config_str.as_bytes()) - .await - .map_err(|err| Error::io_path(&config_path, err))?; - } - ServiceType::ExternalDns { - http_address, dns_address, .. - } => { - info!(self.inner.log, "Setting up external-dns service"); - - // Like Nexus, we need to be reachable externally via - // `dns_address` but we don't listen on that address - // directly but instead on a VPC private IP. OPTE will - // en/decapsulate as appropriate. - let port_ip = running_zone - .ensure_address_for_port("public", 0) - .await? - .ip(); - let dns_address = - SocketAddr::new(port_ip, dns_address.port()); - - smfh.setprop( - "config/http_address", - format!( - "[{}]:{}", - http_address.ip(), - http_address.port(), - ), - )?; - smfh.setprop( - "config/dns_address", - dns_address.to_string(), - )?; + // Refresh the manifest with the new properties we set, so + // they become "effective" properties when the service is + // enabled. + smfh.refresh()?; + } - // Refresh the manifest with the new properties we set, so - // they become "effective" properties when the service is - // enabled. - smfh.refresh()?; - } - ServiceType::InternalDns { - http_address, - dns_address, - gz_address, - gz_address_index, - } => { - info!(self.inner.log, "Setting up internal-dns service"); - - // Internal DNS zones require a special route through the - // global zone, since they are not on the same part of the - // underlay as most other services on this sled (the sled's - // subnet). - // - // We create an IP address in the dedicated portion of the - // underlay used for internal DNS servers, but we *also* - // add a number ("which DNS server is this") to ensure - // these addresses are given unique names. In the unlikely - // case that two internal DNS servers end up on the same - // machine (which is effectively a developer-only - // environment -- we wouldn't want this in prod!), they need - // to be given distinct names. - let addr_name = format!("internaldns{gz_address_index}"); - Zones::ensure_has_global_zone_v6_address( - self.inner.underlay_vnic.clone(), - *gz_address, - &addr_name, - ) - .map_err(|err| Error::GzAddress { - message: format!( + OmicronZoneType::InternalDns { + http_address, + dns_address, + gz_address, + gz_address_index, + .. + } => { + info!( + self.inner.log, + "Setting up internal-dns service" + ); + + // Internal DNS zones require a special route through the + // global zone, since they are not on the same part of the + // underlay as most other services on this sled (the sled's + // subnet). + // + // We create an IP address in the dedicated portion of the + // underlay used for internal DNS servers, but we *also* + // add a number ("which DNS server is this") to ensure + // these addresses are given unique names. In the unlikely + // case that two internal DNS servers end up on the same + // machine (which is effectively a developer-only + // environment -- we wouldn't want this in prod!), they need + // to be given distinct names. + let addr_name = + format!("internaldns{gz_address_index}"); + Zones::ensure_has_global_zone_v6_address( + self.inner.underlay_vnic.clone(), + *gz_address, + &addr_name, + ) + .map_err(|err| { + Error::GzAddress { + message: format!( "Failed to create address {} for Internal DNS zone", addr_name ), - err, - })?; - // If this address is in a new ipv6 prefix, notify maghemite so - // it can advertise it to other sleds. - self.advertise_prefix_of_address(*gz_address).await; + err, + } + })?; + // If this address is in a new ipv6 prefix, notify maghemite so + // it can advertise it to other sleds. + self.advertise_prefix_of_address(*gz_address).await; + + running_zone.add_default_route(*gz_address).map_err( + |err| Error::ZoneCommand { + intent: "Adding Route".to_string(), + err, + }, + )?; - running_zone.add_default_route(*gz_address).map_err( - |err| Error::ZoneCommand { - intent: "Adding Route".to_string(), - err, - }, - )?; + smfh.setprop( + "config/http_address", + format!( + "[{}]:{}", + http_address.ip(), + http_address.port(), + ), + )?; + smfh.setprop( + "config/dns_address", + &format!( + "[{}]:{}", + dns_address.ip(), + dns_address.port(), + ), + )?; - smfh.setprop( - "config/http_address", - format!( - "[{}]:{}", - http_address.ip(), - http_address.port(), - ), - )?; - smfh.setprop( - "config/dns_address", - &format!( - "[{}]:{}", - dns_address.ip(), - dns_address.port(), - ), - )?; + // Refresh the manifest with the new properties we set, so + // they become "effective" properties when the service is + // enabled. + smfh.refresh()?; + } - // Refresh the manifest with the new properties we set, so - // they become "effective" properties when the service is - // enabled. - smfh.refresh()?; - } - ServiceType::Oximeter { address } => { - info!(self.inner.log, "Setting up oximeter service"); - smfh.setprop("config/id", request.zone.id)?; - smfh.setprop("config/address", address.to_string())?; - smfh.refresh()?; - } - ServiceType::ManagementGatewayService => { - info!(self.inner.log, "Setting up MGS service"); - smfh.setprop("config/id", request.zone.id)?; - - // Always tell MGS to listen on localhost so wicketd can - // contact it even before we have an underlay network. - smfh.addpropvalue( - "config/address", - &format!("[::1]:{MGS_PORT}"), - )?; + OmicronZoneType::Oximeter { address } => { + info!(self.inner.log, "Setting up oximeter service"); + smfh.setprop("config/id", zone_config.zone.id)?; + smfh.setprop("config/address", address.to_string())?; + smfh.refresh()?; + } + + OmicronZoneType::BoundaryNtp { + ntp_servers, + dns_servers, + domain, + .. + } + | OmicronZoneType::InternalNtp { + ntp_servers, + dns_servers, + domain, + .. + } => { + let boundary = matches!( + &zone_config.zone.zone_type, + OmicronZoneType::BoundaryNtp { .. } + ); + info!( + self.inner.log, + "Set up NTP service boundary={}, Servers={:?}", + boundary, + ntp_servers + ); + + let sled_info = + if let Some(info) = self.inner.sled_info.get() { + info + } else { + return Err(Error::SledAgentNotReady); + }; + + let rack_net = Ipv6Subnet::::new( + sled_info.underlay_address, + ) + .net(); + + smfh.setprop("config/allow", &format!("{}", rack_net))?; + smfh.setprop( + "config/boundary", + if boundary { "true" } else { "false" }, + )?; + + if boundary { + // Configure OPTE port for boundary NTP + running_zone + .ensure_address_for_port("public", 0) + .await?; + } + + smfh.delpropvalue("config/server", "*")?; + for server in ntp_servers { + smfh.addpropvalue("config/server", server)?; + } + self.configure_dns_client( + &running_zone, + &dns_servers, + &domain, + ) + .await?; + + smfh.refresh()?; + } + OmicronZoneType::Clickhouse { .. } + | OmicronZoneType::ClickhouseKeeper { .. } + | OmicronZoneType::CockroachDb { .. } + | OmicronZoneType::Crucible { .. } + | OmicronZoneType::CruciblePantry { .. } => { + panic!( + "{} is a service which exists as part of a \ + self-assembling zone", + zone_config.zone.zone_type.zone_type_str(), + ) + } + }; + + debug!(self.inner.log, "enabling service"); + smfh.enable()?; + } + ZoneArgs::SledLocal(request) => { + for service in &request.zone.services { + // TODO: Related to + // https://github.com/oxidecomputer/omicron/pull/1124 , should we + // avoid importing this manifest? + debug!(self.inner.log, "importing manifest"); - if let Some(address) = request.zone.addresses.get(0) { - // Don't use localhost twice - if *address != Ipv6Addr::LOCALHOST { + let smfh = SmfHelper::new(&running_zone, &service.details); + smfh.import_manifest()?; + + match &service.details { + ServiceType::ManagementGatewayService => { + info!(self.inner.log, "Setting up MGS service"); + smfh.setprop("config/id", request.zone.id)?; + + // Always tell MGS to listen on localhost so wicketd can + // contact it even before we have an underlay network. smfh.addpropvalue( "config/address", - &format!("[{address}]:{MGS_PORT}"), + &format!("[::1]:{MGS_PORT}"), )?; - } - } - if let Some(info) = self.inner.sled_info.get() { - smfh.setprop("config/rack_id", info.rack_id)?; - } + if let Some(address) = request.zone.addresses.get(0) + { + // Don't use localhost twice + if *address != Ipv6Addr::LOCALHOST { + smfh.addpropvalue( + "config/address", + &format!("[{address}]:{MGS_PORT}"), + )?; + } + } - smfh.refresh()?; - } - ServiceType::SpSim => { - info!(self.inner.log, "Setting up Simulated SP service"); - } - ServiceType::Wicketd { baseboard } => { - info!(self.inner.log, "Setting up wicketd service"); + if let Some(info) = self.inner.sled_info.get() { + smfh.setprop("config/rack_id", info.rack_id)?; + } - smfh.setprop( - "config/address", - &format!("[::1]:{WICKETD_PORT}"), - )?; + smfh.refresh()?; + } + ServiceType::SpSim => { + info!( + self.inner.log, + "Setting up Simulated SP service" + ); + } + ServiceType::Wicketd { baseboard } => { + info!(self.inner.log, "Setting up wicketd service"); - // If we're launching the switch zone, we'll have a - // bootstrap_address based on our call to - // `self.bootstrap_address_needed` (which always gives us an - // address for the switch zone. If we _don't_ have a - // bootstrap address, someone has requested wicketd in a - // non-switch zone; return an error. - let Some((_, bootstrap_address)) = - bootstrap_name_and_address - else { - return Err(Error::BadServiceRequest { - service: "wicketd".to_string(), - message: concat!( - "missing bootstrap address: ", - "wicketd can only be started in the ", - "switch zone", - ) - .to_string(), - }); - }; - smfh.setprop( - "config/artifact-address", - &format!( + smfh.setprop( + "config/address", + &format!("[::1]:{WICKETD_PORT}"), + )?; + + // If we're launching the switch zone, we'll have a + // bootstrap_address based on our call to + // `self.bootstrap_address_needed` (which always gives us an + // address for the switch zone. If we _don't_ have a + // bootstrap address, someone has requested wicketd in a + // non-switch zone; return an error. + let Some((_, bootstrap_address)) = + bootstrap_name_and_address + else { + return Err(Error::BadServiceRequest { + service: "wicketd".to_string(), + message: concat!( + "missing bootstrap address: ", + "wicketd can only be started in the ", + "switch zone", + ) + .to_string(), + }); + }; + smfh.setprop( + "config/artifact-address", + &format!( "[{bootstrap_address}]:{BOOTSTRAP_ARTIFACT_PORT}" ), - )?; + )?; - smfh.setprop( - "config/mgs-address", - &format!("[::1]:{MGS_PORT}"), - )?; + smfh.setprop( + "config/mgs-address", + &format!("[::1]:{MGS_PORT}"), + )?; - // We intentionally bind `nexus-proxy-address` to `::` so - // wicketd will serve this on all interfaces, particularly - // the tech port interfaces, allowing external clients to - // connect to this Nexus proxy. - smfh.setprop( - "config/nexus-proxy-address", - &format!("[::]:{WICKETD_NEXUS_PROXY_PORT}"), - )?; - if let Some(underlay_address) = self - .inner - .sled_info - .get() - .map(|info| info.underlay_address) - { - let rack_subnet = - Ipv6Subnet::::new(underlay_address); - smfh.setprop( - "config/rack-subnet", - &rack_subnet.net().ip().to_string(), - )?; - } + // We intentionally bind `nexus-proxy-address` to `::` so + // wicketd will serve this on all interfaces, particularly + // the tech port interfaces, allowing external clients to + // connect to this Nexus proxy. + smfh.setprop( + "config/nexus-proxy-address", + &format!("[::]:{WICKETD_NEXUS_PROXY_PORT}"), + )?; + if let Some(underlay_address) = self + .inner + .sled_info + .get() + .map(|info| info.underlay_address) + { + let rack_subnet = Ipv6Subnet::::new( + underlay_address, + ); + smfh.setprop( + "config/rack-subnet", + &rack_subnet.net().ip().to_string(), + )?; + } - let serialized_baseboard = - serde_json::to_string_pretty(&baseboard)?; - let serialized_baseboard_path = Utf8PathBuf::from(format!( - "{}/opt/oxide/baseboard.json", - running_zone.root() - )); - tokio::fs::write( - &serialized_baseboard_path, - &serialized_baseboard, - ) - .await - .map_err(|err| { - Error::io_path(&serialized_baseboard_path, err) - })?; - smfh.setprop( - "config/baseboard-file", - String::from("/opt/oxide/baseboard.json"), - )?; + let serialized_baseboard = + serde_json::to_string_pretty(&baseboard)?; + let serialized_baseboard_path = + Utf8PathBuf::from(format!( + "{}/opt/oxide/baseboard.json", + running_zone.root() + )); + tokio::fs::write( + &serialized_baseboard_path, + &serialized_baseboard, + ) + .await + .map_err(|err| { + Error::io_path(&serialized_baseboard_path, err) + })?; + smfh.setprop( + "config/baseboard-file", + String::from("/opt/oxide/baseboard.json"), + )?; - smfh.refresh()?; - } - ServiceType::Dendrite { asic } => { - info!(self.inner.log, "Setting up dendrite service"); + smfh.refresh()?; + } + ServiceType::Dendrite { asic } => { + info!( + self.inner.log, + "Setting up dendrite service" + ); - if let Some(info) = self.inner.sled_info.get() { - smfh.setprop("config/rack_id", info.rack_id)?; - smfh.setprop("config/sled_id", info.config.sled_id)?; - } else { - info!( - self.inner.log, - "no rack_id/sled_id available yet" - ); - } + if let Some(info) = self.inner.sled_info.get() { + smfh.setprop("config/rack_id", info.rack_id)?; + smfh.setprop( + "config/sled_id", + info.config.sled_id, + )?; + } else { + info!( + self.inner.log, + "no rack_id/sled_id available yet" + ); + } - smfh.delpropvalue("config/address", "*")?; - smfh.delpropvalue("config/dns_server", "*")?; - for address in &request.zone.addresses { - smfh.addpropvalue( - "config/address", - &format!("[{}]:{}", address, DENDRITE_PORT), - )?; - if *address != Ipv6Addr::LOCALHOST { - let az_prefix = - Ipv6Subnet::::new(*address); - for addr in Resolver::servers_from_subnet(az_prefix) - { + smfh.delpropvalue("config/address", "*")?; + smfh.delpropvalue("config/dns_server", "*")?; + for address in &request.zone.addresses { smfh.addpropvalue( - "config/dns_server", - &format!("{addr}"), + "config/address", + &format!("[{}]:{}", address, DENDRITE_PORT), )?; + if *address != Ipv6Addr::LOCALHOST { + let az_prefix = + Ipv6Subnet::::new(*address); + for addr in + Resolver::servers_from_subnet(az_prefix) + { + smfh.addpropvalue( + "config/dns_server", + &format!("{addr}"), + )?; + } + } } - } - } - match asic { + match asic { DendriteAsic::TofinoAsic => { // There should be exactly one device_name // associated with this zone: the /dev path for @@ -1906,18 +2136,20 @@ impl ServiceManager { )? } }; - smfh.refresh()?; - } - ServiceType::Tfport { pkt_source, asic } => { - info!(self.inner.log, "Setting up tfport service"); + smfh.refresh()?; + } + ServiceType::Tfport { pkt_source, asic } => { + info!(self.inner.log, "Setting up tfport service"); - let is_gimlet = is_gimlet().map_err(|e| { - Error::Underlay(underlay::Error::SystemDetection(e)) - })?; + let is_gimlet = is_gimlet().map_err(|e| { + Error::Underlay( + underlay::Error::SystemDetection(e), + ) + })?; - if is_gimlet { - // Collect the prefixes for each techport. - let techport_prefixes = match bootstrap_name_and_address + if is_gimlet { + // Collect the prefixes for each techport. + let techport_prefixes = match bootstrap_name_and_address .as_ref() { Some((_, addr)) => { @@ -1931,244 +2163,150 @@ impl ServiceManager { } }; - for (i, prefix) in - techport_prefixes.into_iter().enumerate() - { - // Each `prefix` is an `Ipv6Subnet` including a netmask. - // Stringify just the network address, without the mask. + for (i, prefix) in + techport_prefixes.into_iter().enumerate() + { + // Each `prefix` is an `Ipv6Subnet` including a netmask. + // Stringify just the network address, without the mask. + smfh.setprop( + format!("config/techport{i}_prefix"), + prefix.net().network().to_string(), + )?; + } + smfh.setprop("config/pkt_source", pkt_source)?; + } + if asic == &DendriteAsic::SoftNpuZone { + smfh.setprop("config/flags", "--sync-only")?; + } + if asic == &DendriteAsic::SoftNpuPropolisDevice { + smfh.setprop("config/pkt_source", pkt_source)?; + } smfh.setprop( - format!("config/techport{i}_prefix"), - prefix.net().network().to_string(), + "config/host", + &format!("[{}]", Ipv6Addr::LOCALHOST), + )?; + smfh.setprop( + "config/port", + &format!("{}", DENDRITE_PORT), )?; - } - smfh.setprop("config/pkt_source", pkt_source)?; - } - if asic == &DendriteAsic::SoftNpuZone { - smfh.setprop("config/flags", "--sync-only")?; - } - if asic == &DendriteAsic::SoftNpuPropolisDevice { - smfh.setprop("config/pkt_source", pkt_source)?; - } - smfh.setprop( - "config/host", - &format!("[{}]", Ipv6Addr::LOCALHOST), - )?; - smfh.setprop("config/port", &format!("{}", DENDRITE_PORT))?; - - smfh.refresh()?; - } - ServiceType::BoundaryNtp { - ntp_servers, - dns_servers, - domain, - .. - } - | ServiceType::InternalNtp { - ntp_servers, - dns_servers, - domain, - .. - } => { - let boundary = matches!( - service.details, - ServiceType::BoundaryNtp { .. } - ); - info!( - self.inner.log, - "Set up NTP service boundary={}, Servers={:?}", - boundary, - ntp_servers - ); - - let sled_info = - if let Some(info) = self.inner.sled_info.get() { - info - } else { - return Err(Error::SledAgentNotReady); - }; - - let rack_net = Ipv6Subnet::::new( - sled_info.underlay_address, - ) - .net(); - - smfh.setprop("config/allow", &format!("{}", rack_net))?; - smfh.setprop( - "config/boundary", - if boundary { "true" } else { "false" }, - )?; - - if boundary { - // Configure OPTE port for boundary NTP - running_zone - .ensure_address_for_port("public", 0) - .await?; - } - smfh.delpropvalue("config/server", "*")?; - for server in ntp_servers { - smfh.addpropvalue("config/server", server)?; - } - self.configure_dns_client( - &running_zone, - dns_servers, - &domain, - ) - .await?; + smfh.refresh()?; + } + ServiceType::Uplink => { + // Nothing to do here - this service is special and + // configured in `ensure_switch_zone_uplinks_configured` + } + ServiceType::Mgd => { + info!(self.inner.log, "Setting up mgd service"); + smfh.setprop("config/admin_host", "::")?; + smfh.refresh()?; + } + ServiceType::MgDdm { mode } => { + info!(self.inner.log, "Setting up mg-ddm service"); - smfh.refresh()?; - } - ServiceType::Uplink => { - // Nothing to do here - this service is special and - // configured in `ensure_switch_zone_uplinks_configured` - } - ServiceType::Mgd => { - info!(self.inner.log, "Setting up mgd service"); - smfh.setprop("config/admin_host", "::")?; - smfh.refresh()?; - } - ServiceType::MgDdm { mode } => { - info!(self.inner.log, "Setting up mg-ddm service"); + smfh.setprop("config/mode", &mode)?; + smfh.setprop("config/admin_host", "::")?; - smfh.setprop("config/mode", &mode)?; - smfh.setprop("config/admin_host", "::")?; + let is_gimlet = is_gimlet().map_err(|e| { + Error::Underlay( + underlay::Error::SystemDetection(e), + ) + })?; + + let maghemite_interfaces: Vec = + if is_gimlet { + (0..32) + .map(|i| { + // See the `tfport_name` function for how + // tfportd names the addrconf it creates. + // Right now, that's `tfportrear[0-31]_0` + // for all rear ports, which is what we're + // directing ddmd to listen for + // advertisements on. + // + // This may grow in a multi-rack future to + // include a subset of "front" ports too, + // when racks are cabled together. + AddrObject::new( + &format!("tfportrear{}_0", i), + IPV6_LINK_LOCAL_NAME, + ) + .unwrap() + }) + .collect() + } else { + self.inner + .switch_zone_maghemite_links + .iter() + .map(|i| { + AddrObject::new( + &i.to_string(), + IPV6_LINK_LOCAL_NAME, + ) + .unwrap() + }) + .collect() + }; - let is_gimlet = is_gimlet().map_err(|e| { - Error::Underlay(underlay::Error::SystemDetection(e)) - })?; + smfh.setprop( + "config/interfaces", + // `svccfg setprop` requires a list of values to be + // enclosed in `()`, and each string value to be + // enclosed in `""`. Note that we do _not_ need to + // escape the parentheses, since this is not passed + // through a shell, but directly to `exec(2)` in the + // zone. + format!( + "({})", + maghemite_interfaces + .iter() + .map(|interface| format!( + r#""{}""#, + interface + )) + .join(" "), + ), + )?; - let maghemite_interfaces: Vec = if is_gimlet { - (0..32) - .map(|i| { - // See the `tfport_name` function for how - // tfportd names the addrconf it creates. - // Right now, that's `tfportrear[0-31]_0` - // for all rear ports, which is what we're - // directing ddmd to listen for - // advertisements on. - // - // This may grow in a multi-rack future to - // include a subset of "front" ports too, - // when racks are cabled together. - AddrObject::new( - &format!("tfportrear{}_0", i), - IPV6_LINK_LOCAL_NAME, - ) - .unwrap() - }) - .collect() - } else { - self.inner - .switch_zone_maghemite_links - .iter() - .map(|i| { - AddrObject::new( - &i.to_string(), - IPV6_LINK_LOCAL_NAME, - ) - .unwrap() - }) - .collect() - }; + if is_gimlet { + // Ddm for a scrimlet needs to be configured to talk to + // dendrite + smfh.setprop("config/dpd_host", "[::1]")?; + smfh.setprop("config/dpd_port", DENDRITE_PORT)?; + } + smfh.setprop("config/dendrite", "true")?; - smfh.setprop( - "config/interfaces", - // `svccfg setprop` requires a list of values to be - // enclosed in `()`, and each string value to be - // enclosed in `""`. Note that we do _not_ need to - // escape the parentheses, since this is not passed - // through a shell, but directly to `exec(2)` in the - // zone. - format!( - "({})", - maghemite_interfaces - .iter() - .map(|interface| format!(r#""{}""#, interface)) - .join(" "), - ), - )?; + smfh.refresh()?; + } - if is_gimlet { - // Ddm for a scrimlet needs to be configured to talk to - // dendrite - smfh.setprop("config/dpd_host", "[::1]")?; - smfh.setprop("config/dpd_port", DENDRITE_PORT)?; + ServiceType::Nexus { .. } + | ServiceType::Oximeter { .. } + | ServiceType::BoundaryNtp { .. } + | ServiceType::InternalNtp { .. } + | ServiceType::ExternalDns { .. } + | ServiceType::InternalDns { .. } + | ServiceType::CockroachDb { .. } + | ServiceType::Crucible { .. } + | ServiceType::CruciblePantry { .. } + | ServiceType::Clickhouse { .. } + | ServiceType::ClickhouseKeeper { .. } => { + panic!( + "unexpected service type for sled-local \ + zone: {:?}", + service.details + ); + } } - smfh.setprop("config/dendrite", "true")?; - smfh.refresh()?; - } - ServiceType::Crucible { .. } - | ServiceType::CruciblePantry { .. } - | ServiceType::CockroachDb { .. } - | ServiceType::Clickhouse { .. } - | ServiceType::ClickhouseKeeper { .. } => { - panic!( - "{} is a service which exists as part of a self-assembling zone", - service.details, - ) + debug!(self.inner.log, "enabling service"); + smfh.enable()?; } } - - debug!(self.inner.log, "enabling service"); - smfh.enable()?; - } + }; Ok(running_zone) } - // Populates `existing_zones` according to the requests in `services`. - async fn initialize_services_locked( - &self, - existing_zones: &mut BTreeMap, - requests: &Vec, - ) -> Result<(), Error> { - if let Some(name) = requests - .iter() - .map(|request| request.zone.zone_name()) - .duplicates() - .next() - { - return Err(Error::BadServiceRequest { - service: name, - message: "Should not initialize zone twice".to_string(), - }); - } - - let futures = requests.iter().map(|request| { - async move { - self.initialize_zone( - request, - // filesystems= - &[], - // data_links= - &[], - ) - .await - .map_err(|error| (request.zone.zone_name(), error)) - } - }); - let results = futures::future::join_all(futures).await; - - let mut errors = Vec::new(); - for result in results { - match result { - Ok(zone) => { - existing_zones.insert(zone.name().to_string(), zone); - } - Err((zone_name, error)) => { - errors.push((zone_name, Box::new(error))); - } - } - } - - if !errors.is_empty() { - return Err(Error::ZoneInitialize(errors)); - } - - Ok(()) - } - // Populates `existing_zones` according to the requests in `services`. async fn initialize_omicron_zones_locked( &self, @@ -2190,7 +2328,7 @@ impl ServiceManager { let futures = requests.iter().map(|request| { async move { self.initialize_zone( - request, + ZoneArgs::Omicron(request), // filesystems= &[], // data_links= @@ -2313,7 +2451,8 @@ impl ServiceManager { zone_ledger_paths.clone(), ZonesConfig { // XXX-dap this means Nexus must use a newer generation - // for its first one + // for its first one. Even better would be if this + // whole object could be `None` generation: Generation::new(), zones: vec![], }, @@ -2325,8 +2464,9 @@ impl ServiceManager { let new_config = self .ensure_all_omicron_zones( &mut existing_zones, - ledger_zone_config, + Some(ledger_zone_config), request, + |_| true, ) .await?; @@ -2341,22 +2481,31 @@ impl ServiceManager { // // Does not record any information such that these services are // re-instantiated on boot. - async fn ensure_all_omicron_zones( + async fn ensure_all_omicron_zones( &self, // XXX-dap drop MutexGuard part existing_zones: &mut MutexGuard<'_, BTreeMap>, - old_config: &ZonesConfig, + old_config: Option<&ZonesConfig>, new_request: OmicronZonesConfig, - ) -> Result { + filter: F, + ) -> Result + where + F: Fn(&OmicronZoneConfig) -> bool, + { let log = &self.inner.log; // Do some data-normalization to ensure we can compare the "requested // set" vs the "existing set" as HashSets. // XXX-dap can we not skip this clone? - let old_zones_set: HashSet = - HashSet::from_iter(old_config.zones.iter().map(|z| z.zone.clone())); + let old_zones_set: HashSet = old_config + .map(|old_config| { + HashSet::from_iter( + old_config.zones.iter().map(|z| z.zone.clone()), + ) + }) + .unwrap_or_else(HashSet::new); let requested_zones_set = - HashSet::from_iter(new_request.zones.into_iter()); + HashSet::from_iter(new_request.zones.into_iter().filter(filter)); let zones_to_be_removed = old_zones_set.difference(&requested_zones_set); @@ -2440,154 +2589,21 @@ impl ServiceManager { .ok_or_else(|| Error::U2NotFound)? .clone(); - // XXX-dap XXX XXX XXX working here - // So: the current problem is: how to store the root we choose? - // (and maybe: is this the right place to choose it?) I opted not - // to put this into the ledger structure because I hoped I wouldn't - // need it. But I think we might need it because: - // - we need to tear down this filesystem on sled agent startup when - // we wipe everything (I assume this is how we do this -- haven't - // verified it) - // XXX-dap another thing I noticed here is that the old code - // instantiated a whole AllZoneRequestsV1 only for the "requests" - // field (I think). We return the whole thing but the caller only - // uses "requests". We also pass only "requests" down to - // initialize_services_locked(). - // XXX-dap next step will be to update initialize_services_locked(). new_zones.push(ZoneConfig { zone: zone.clone(), root }); } self.initialize_omicron_zones_locked(existing_zones, &new_zones) .await?; - for old_zone in &old_config.zones { - if requested_zones_set.contains(&old_zone.zone) { - new_zones.push(old_zone.clone()); - } - } - - Ok(ZonesConfig { generation: new_request.generation, zones: new_zones }) - } - - // Ensures that only the following services are running. - // - // Does not record any information such that these services are - // re-instantiated on boot. - // XXX-dap remove me (change callers to use ensure_all_omicron_zones()) - async fn ensure_all_services( - &self, - existing_zones: &mut MutexGuard<'_, BTreeMap>, - old_request: &AllZoneRequestsV1, - request: ServiceEnsureBody, - ) -> Result { - let log = &self.inner.log; - - // Do some data-normalization to ensure we can compare the "requested - // set" vs the "existing set" as HashSets. - let old_services_set: HashSet = HashSet::from_iter( - old_request.requests.iter().map(|r| r.zone.clone()), - ); - let requested_services_set = - HashSet::from_iter(request.services.into_iter()); - - let zones_to_be_removed = - old_services_set.difference(&requested_services_set); - let zones_to_be_added = - requested_services_set.difference(&old_services_set); - - // Destroy zones that should not be running - for zone in zones_to_be_removed { - let expected_zone_name = zone.zone_name(); - if let Some(mut zone) = existing_zones.remove(&expected_zone_name) { - debug!( - log, - "removing an existing zone"; - "zone_name" => &expected_zone_name, - ); - if let Err(e) = self - .inner - .zone_bundler - .create(&zone, ZoneBundleCause::UnexpectedZone) - .await - { - error!( - log, - "Failed to take bundle of unexpected zone"; - "zone_name" => &expected_zone_name, - "reason" => ?e, - ); - } - if let Err(e) = zone.stop().await { - error!(log, "Failed to stop zone {}: {e}", zone.name()); - } - } else { - warn!(log, "Expected to remove zone, but could not find it"); - } - } - - // Create zones that should be running - let mut zone_requests = AllZoneRequestsV1::default(); - let all_u2_roots = - self.inner.storage.all_u2_mountpoints(ZONE_DATASET).await; - for zone in zones_to_be_added { - // Check if we think the zone should already be running - let name = zone.zone_name(); - if existing_zones.contains_key(&name) { - // Make sure the zone actually exists in the right state too - match Zones::find(&name).await { - Ok(Some(zone)) if zone.state() == zone::State::Running => { - info!(log, "skipping running zone"; "zone" => &name); - continue; - } - _ => { - // Mismatch between SA's view and reality, let's try to - // clean up any remanants and try initialize it again - warn!( - log, - "expected to find existing zone in running state"; - "zone" => &name, - ); - if let Err(e) = - existing_zones.remove(&name).unwrap().stop().await - { - error!( - log, - "Failed to stop zone"; - "zone" => &name, - "error" => %e, - ); - } - } + if let Some(old_config) = old_config { + for old_zone in &old_config.zones { + if requested_zones_set.contains(&old_zone.zone) { + new_zones.push(old_zone.clone()); } } - // For each new zone request, we pick an arbitrary U.2 to store - // the zone filesystem. Note: This isn't known to Nexus right now, - // so it's a local-to-sled decision. - // - // This is (currently) intentional, as the zone filesystem should - // be destroyed between reboots. - let mut rng = rand::thread_rng(); - let root = all_u2_roots - .choose(&mut rng) - .ok_or_else(|| Error::U2NotFound)? - .clone(); - - zone_requests - .requests - .push(ZoneRequestV1 { zone: zone.clone(), root }); } - self.initialize_services_locked( - existing_zones, - &zone_requests.requests, - ) - .await?; - for old_zone in &old_request.requests { - if requested_services_set.contains(&old_zone.zone) { - zone_requests.requests.push(old_zone.clone()); - } - } - Ok(zone_requests) + Ok(ZonesConfig { generation: new_request.generation, zones: new_zones }) } pub async fn cockroachdb_initialize(&self) -> Result<(), Error> { @@ -3263,11 +3279,11 @@ impl ServiceManager { .clone() }; - let request = ZoneRequestV1 { zone: request.clone(), root }; + let zone_request = ZoneRequestV1 { root, zone: request.clone() }; + let zone_args = ZoneArgs::SledLocal(&zone_request); let zone = - self.initialize_zone(&request, filesystems, data_links).await?; - *sled_zone = - SledLocalZone::Running { request: request.zone.clone(), zone }; + self.initialize_zone(zone_args, filesystems, data_links).await?; + *sled_zone = SledLocalZone::Running { request: request.clone(), zone }; Ok(()) } @@ -3312,7 +3328,6 @@ impl ServiceManager { #[cfg(test)] mod test { use super::*; - use crate::params::{ServiceZoneService, ZoneType}; use async_trait::async_trait; use illumos_utils::{ dladm::{ @@ -3419,25 +3434,14 @@ mod test { // Prepare to call "ensure" for a new service, then actually call "ensure". async fn ensure_new_service(mgr: &ServiceManager, id: Uuid) { let _expectations = expect_new_service(); - - // XXX-dap replace with call to ensure_all_omicron_zones_persistent - mgr.ensure_all_services_persistent(ServiceEnsureBody { - services: vec![ServiceZoneRequest { + let address = + SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); + mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { + generation: Generation::new().next(), + zones: vec![OmicronZoneConfig { id, - zone_type: ZoneType::Oximeter, - addresses: vec![Ipv6Addr::LOCALHOST], - dataset: None, - services: vec![ServiceZoneService { - id, - details: ServiceType::Oximeter { - address: SocketAddrV6::new( - Ipv6Addr::LOCALHOST, - OXIMETER_PORT, - 0, - 0, - ), - }, - }], + underlay_address: Ipv6Addr::LOCALHOST, + zone_type: OmicronZoneType::Oximeter { address }, }], }) .await @@ -3447,24 +3451,14 @@ mod test { // Prepare to call "ensure" for a service which already exists. We should // return the service without actually installing a new zone. async fn ensure_existing_service(mgr: &ServiceManager, id: Uuid) { - // XXX-dap replace with call to ensure_all_omicron_zones_persistent - mgr.ensure_all_services_persistent(ServiceEnsureBody { - services: vec![ServiceZoneRequest { + let address = + SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); + mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { + generation: Generation::new().next(), + zones: vec![OmicronZoneConfig { id, - zone_type: ZoneType::Oximeter, - addresses: vec![Ipv6Addr::LOCALHOST], - dataset: None, - services: vec![ServiceZoneService { - id, - details: ServiceType::Oximeter { - address: SocketAddrV6::new( - Ipv6Addr::LOCALHOST, - OXIMETER_PORT, - 0, - 0, - ), - }, - }], + underlay_address: Ipv6Addr::LOCALHOST, + zone_type: OmicronZoneType::Oximeter { address }, }], }) .await From 23bc12ca817091507df7541cf2e88655808bcd39 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 8 Nov 2023 05:14:57 +0000 Subject: [PATCH 04/44] WIP: update API spec --- openapi/sled-agent.json | 837 +++++++++++++---------------- sled-agent/src/http_entrypoints.rs | 4 +- sled-agent/src/params.rs | 1 + 3 files changed, 363 insertions(+), 479 deletions(-) diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index 486662853c..2342806c4d 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -338,14 +338,35 @@ } } }, - "/services": { + "/omicron-zones": { + "get": { + "operationId": "omicron_zones_get", + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OmicronZonesConfig" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + }, "put": { - "operationId": "services_put", + "operationId": "omicron_zones_put", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServiceEnsureBody" + "$ref": "#/components/schemas/OmicronZonesConfig" } } }, @@ -1168,131 +1189,6 @@ "target" ] }, - "DatasetKind": { - "description": "The type of a dataset, and an auxiliary information necessary to successfully launch a zone managing the associated data.", - "oneOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "cockroach_db" - ] - } - }, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "crucible" - ] - } - }, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "clickhouse" - ] - } - }, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "clickhouse_keeper" - ] - } - }, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "external_dns" - ] - } - }, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "internal_dns" - ] - } - }, - "required": [ - "type" - ] - } - ] - }, - "DatasetName": { - "type": "object", - "properties": { - "kind": { - "$ref": "#/components/schemas/DatasetKind" - }, - "pool_name": { - "$ref": "#/components/schemas/ZpoolName" - } - }, - "required": [ - "kind", - "pool_name" - ] - }, - "DatasetRequest": { - "description": "Describes a request to provision a specific dataset", - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "$ref": "#/components/schemas/DatasetName" - }, - "service_address": { - "type": "string" - } - }, - "required": [ - "id", - "name", - "service_address" - ] - }, "DeleteVirtualNetworkInterfaceHost": { "description": "The data needed to identify a virtual IP for which a sled maintains an OPTE virtual-to-physical mapping such that that mapping can be deleted.", "type": "object", @@ -2499,318 +2395,161 @@ } ] }, - "PortConfigV1": { + "OmicronZoneConfig": { + "description": "Describes one Omicron zone running on a sled", "type": "object", "properties": { - "addresses": { - "description": "This port's addresses.", - "type": "array", - "items": { - "$ref": "#/components/schemas/IpNetwork" - } - }, - "bgp_peers": { - "description": "BGP peers on this port", - "type": "array", - "items": { - "$ref": "#/components/schemas/BgpPeerConfig" - } - }, - "port": { - "description": "Nmae of the port this config applies to.", - "type": "string" - }, - "routes": { - "description": "The set of routes associated with this port.", - "type": "array", - "items": { - "$ref": "#/components/schemas/RouteConfig" - } - }, - "switch": { - "description": "Switch the port belongs to.", - "allOf": [ - { - "$ref": "#/components/schemas/SwitchLocation" - } - ] + "id": { + "type": "string", + "format": "uuid" }, - "uplink_port_fec": { - "description": "Port forward error correction type.", - "allOf": [ - { - "$ref": "#/components/schemas/PortFec" - } - ] + "underlay_address": { + "type": "string", + "format": "ipv6" }, - "uplink_port_speed": { - "description": "Port speed.", - "allOf": [ - { - "$ref": "#/components/schemas/PortSpeed" - } - ] + "zone_type": { + "$ref": "#/components/schemas/OmicronZoneType" } }, "required": [ - "addresses", - "bgp_peers", - "port", - "routes", - "switch", - "uplink_port_fec", - "uplink_port_speed" - ] - }, - "PortFec": { - "description": "Switchport FEC options", - "type": "string", - "enum": [ - "firecode", - "none", - "rs" + "id", + "underlay_address", + "zone_type" ] }, - "PortSpeed": { - "description": "Switchport Speed options", - "type": "string", - "enum": [ - "speed0_g", - "speed1_g", - "speed10_g", - "speed25_g", - "speed40_g", - "speed50_g", - "speed100_g", - "speed200_g", - "speed400_g" + "OmicronZoneDataset": { + "description": "Describes a persistent ZFS dataset associated with an Omicron zone", + "type": "object", + "properties": { + "pool_name": { + "$ref": "#/components/schemas/ZpoolName" + } + }, + "required": [ + "pool_name" ] }, - "PriorityDimension": { - "description": "A dimension along with bundles can be sorted, to determine priority.", - "oneOf": [ - { - "description": "Sorting by time, with older bundles with lower priority.", - "type": "string", - "enum": [ - "time" - ] - }, - { - "description": "Sorting by the cause for creating the bundle.", - "type": "string", - "enum": [ - "cause" - ] - } - ] - }, - "PriorityOrder": { - "description": "The priority order for bundles during cleanup.\n\nBundles are sorted along the dimensions in [`PriorityDimension`], with each dimension appearing exactly once. During cleanup, lesser-priority bundles are pruned first, to maintain the dataset quota. Note that bundles are sorted by each dimension in the order in which they appear, with each dimension having higher priority than the next.", - "type": "array", - "items": { - "$ref": "#/components/schemas/PriorityDimension" - }, - "minItems": 2, - "maxItems": 2 - }, - "RackNetworkConfigV1": { - "description": "Initial network configuration", - "type": "object", - "properties": { - "bgp": { - "description": "BGP configurations for connecting the rack to external networks", - "type": "array", - "items": { - "$ref": "#/components/schemas/BgpConfig" - } - }, - "infra_ip_first": { - "description": "First ip address to be used for configuring network infrastructure", - "type": "string", - "format": "ipv4" - }, - "infra_ip_last": { - "description": "Last ip address to be used for configuring network infrastructure", - "type": "string", - "format": "ipv4" - }, - "ports": { - "description": "Uplinks for connecting the rack to external networks", - "type": "array", - "items": { - "$ref": "#/components/schemas/PortConfigV1" - } - }, - "rack_subnet": { - "$ref": "#/components/schemas/Ipv6Network" - } - }, - "required": [ - "bgp", - "infra_ip_first", - "infra_ip_last", - "ports", - "rack_subnet" - ] - }, - "RouteConfig": { - "type": "object", - "properties": { - "destination": { - "description": "The destination of the route.", - "allOf": [ - { - "$ref": "#/components/schemas/IpNetwork" - } - ] - }, - "nexthop": { - "description": "The nexthop/gateway address.", - "type": "string", - "format": "ip" - } - }, - "required": [ - "destination", - "nexthop" - ] - }, - "SemverVersion": { - "type": "string", - "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" - }, - "ServiceEnsureBody": { - "description": "Used to request that the Sled initialize multiple services.", - "type": "object", - "properties": { - "services": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ServiceZoneRequest" - } - } - }, - "required": [ - "services" - ] - }, - "ServiceType": { - "description": "Describes service-specific parameters.", + "OmicronZoneType": { + "description": "Describes what component is running in this zone and its associated type-specific configuration\n\nXXX-dap ideally this would not be necessary at all! Sled Agent shouldn't have to know about the things running on it, I think? XXX-dap commonize with ServiceType (well, probably remove ServiceType)", "oneOf": [ { "type": "object", "properties": { - "external_dns_servers": { - "description": "External DNS servers Nexus can use to resolve external hosts.", + "address": { + "type": "string" + }, + "dns_servers": { "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.", + "domain": { + "nullable": true, "type": "string" }, "nic": { - "description": "The service vNIC providing external connectivity using OPTE.", + "description": "The service vNIC providing outbound connectivity using OPTE.", "allOf": [ { "$ref": "#/components/schemas/NetworkInterface" } ] }, + "ntp_servers": { + "type": "array", + "items": { + "type": "string" + } + }, + "snat_cfg": { + "description": "The SNAT configuration for outbound connections.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceNatConfig" + } + ] + }, "type": { "type": "string", "enum": [ - "nexus" + "boundary_ntp" ] } }, "required": [ - "external_dns_servers", - "external_ip", - "external_tls", - "internal_address", + "address", + "dns_servers", "nic", + "ntp_servers", + "snat_cfg", "type" ] }, { "type": "object", "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.", + "address": { "type": "string" }, - "nic": { - "description": "The service vNIC providing external connectivity using OPTE.", - "allOf": [ - { - "$ref": "#/components/schemas/NetworkInterface" - } - ] + "dataset": { + "$ref": "#/components/schemas/OmicronZoneDataset" }, "type": { "type": "string", "enum": [ - "external_dns" + "clickhouse" ] } }, "required": [ - "dns_address", - "http_address", - "nic", + "address", + "dataset", "type" ] }, { "type": "object", "properties": { - "dns_address": { + "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" + "dataset": { + "$ref": "#/components/schemas/OmicronZoneDataset" }, - "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 - }, - "http_address": { + "type": { + "type": "string", + "enum": [ + "clickhouse_keeper" + ] + } + }, + "required": [ + "address", + "dataset", + "type" + ] + }, + { + "type": "object", + "properties": { + "address": { "type": "string" }, + "dataset": { + "$ref": "#/components/schemas/OmicronZoneDataset" + }, "type": { "type": "string", "enum": [ - "internal_dns" + "cockroach_db" ] } }, "required": [ - "dns_address", - "gz_address", - "gz_address_index", - "http_address", + "address", + "dataset", "type" ] }, @@ -2820,15 +2559,19 @@ "address": { "type": "string" }, + "dataset": { + "$ref": "#/components/schemas/OmicronZoneDataset" + }, "type": { "type": "string", "enum": [ - "oximeter" + "crucible" ] } }, "required": [ "address", + "dataset", "type" ] }, @@ -2853,55 +2596,76 @@ { "type": "object", "properties": { - "address": { - "type": "string" + "dataset": { + "$ref": "#/components/schemas/OmicronZoneDataset" }, - "dns_servers": { - "type": "array", - "items": { - "type": "string", - "format": "ip" - } + "dns_address": { + "description": "The address at which the external DNS server is reachable.", + "type": "string" }, - "domain": { - "nullable": true, + "http_address": { + "description": "The address at which the external DNS server API is reachable.", "type": "string" }, "nic": { - "description": "The service vNIC providing outbound connectivity using OPTE.", + "description": "The service vNIC providing external connectivity using OPTE.", "allOf": [ { "$ref": "#/components/schemas/NetworkInterface" } ] }, - "ntp_servers": { - "type": "array", - "items": { - "type": "string" - } - }, - "snat_cfg": { - "description": "The SNAT configuration for outbound connections.", - "allOf": [ - { - "$ref": "#/components/schemas/SourceNatConfig" - } + "type": { + "type": "string", + "enum": [ + "external_dns" ] + } + }, + "required": [ + "dataset", + "dns_address", + "http_address", + "nic", + "type" + ] + }, + { + "type": "object", + "properties": { + "dataset": { + "$ref": "#/components/schemas/OmicronZoneDataset" + }, + "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 + }, + "http_address": { + "type": "string" }, "type": { "type": "string", "enum": [ - "boundary_ntp" + "internal_dns" ] } }, "required": [ - "address", - "dns_servers", - "nic", - "ntp_servers", - "snat_cfg", + "dataset", + "dns_address", + "gz_address", + "gz_address_index", + "http_address", "type" ] }, @@ -2945,54 +2709,48 @@ { "type": "object", "properties": { - "address": { - "type": "string" + "external_dns_servers": { + "description": "External DNS servers Nexus can use to resolve external hosts.", + "type": "array", + "items": { + "type": "string", + "format": "ip" + } }, - "type": { + "external_ip": { + "description": "The address at which the external nexus server is reachable.", "type": "string", - "enum": [ - "clickhouse" - ] - } - }, - "required": [ - "address", - "type" - ] - }, - { - "type": "object", - "properties": { - "address": { + "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" }, - "type": { - "type": "string", - "enum": [ - "clickhouse_keeper" + "nic": { + "description": "The service vNIC providing external connectivity using OPTE.", + "allOf": [ + { + "$ref": "#/components/schemas/NetworkInterface" + } ] - } - }, - "required": [ - "address", - "type" - ] - }, - { - "type": "object", - "properties": { - "address": { - "type": "string" }, "type": { "type": "string", "enum": [ - "cockroach_db" + "nexus" ] } }, "required": [ - "address", + "external_dns_servers", + "external_ip", + "external_tls", + "internal_address", + "nic", "type" ] }, @@ -3005,7 +2763,7 @@ "type": { "type": "string", "enum": [ - "crucible" + "oximeter" ] } }, @@ -3016,64 +2774,206 @@ } ] }, - "ServiceZoneRequest": { - "description": "Describes a request to create a zone running one or more services.", + "OmicronZonesConfig": { + "description": "Describes the set of Omicron zones running on a sled", + "type": "object", + "properties": { + "generation": { + "$ref": "#/components/schemas/Generation" + }, + "zones": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OmicronZoneConfig" + } + } + }, + "required": [ + "generation", + "zones" + ] + }, + "PortConfigV1": { "type": "object", "properties": { "addresses": { + "description": "This port's addresses.", "type": "array", "items": { - "type": "string", - "format": "ipv6" + "$ref": "#/components/schemas/IpNetwork" } }, - "dataset": { - "nullable": true, - "default": null, + "bgp_peers": { + "description": "BGP peers on this port", + "type": "array", + "items": { + "$ref": "#/components/schemas/BgpPeerConfig" + } + }, + "port": { + "description": "Nmae of the port this config applies to.", + "type": "string" + }, + "routes": { + "description": "The set of routes associated with this port.", + "type": "array", + "items": { + "$ref": "#/components/schemas/RouteConfig" + } + }, + "switch": { + "description": "Switch the port belongs to.", "allOf": [ { - "$ref": "#/components/schemas/DatasetRequest" + "$ref": "#/components/schemas/SwitchLocation" } ] }, - "id": { + "uplink_port_fec": { + "description": "Port forward error correction type.", + "allOf": [ + { + "$ref": "#/components/schemas/PortFec" + } + ] + }, + "uplink_port_speed": { + "description": "Port speed.", + "allOf": [ + { + "$ref": "#/components/schemas/PortSpeed" + } + ] + } + }, + "required": [ + "addresses", + "bgp_peers", + "port", + "routes", + "switch", + "uplink_port_fec", + "uplink_port_speed" + ] + }, + "PortFec": { + "description": "Switchport FEC options", + "type": "string", + "enum": [ + "firecode", + "none", + "rs" + ] + }, + "PortSpeed": { + "description": "Switchport Speed options", + "type": "string", + "enum": [ + "speed0_g", + "speed1_g", + "speed10_g", + "speed25_g", + "speed40_g", + "speed50_g", + "speed100_g", + "speed200_g", + "speed400_g" + ] + }, + "PriorityDimension": { + "description": "A dimension along with bundles can be sorted, to determine priority.", + "oneOf": [ + { + "description": "Sorting by time, with older bundles with lower priority.", "type": "string", - "format": "uuid" + "enum": [ + "time" + ] + }, + { + "description": "Sorting by the cause for creating the bundle.", + "type": "string", + "enum": [ + "cause" + ] + } + ] + }, + "PriorityOrder": { + "description": "The priority order for bundles during cleanup.\n\nBundles are sorted along the dimensions in [`PriorityDimension`], with each dimension appearing exactly once. During cleanup, lesser-priority bundles are pruned first, to maintain the dataset quota. Note that bundles are sorted by each dimension in the order in which they appear, with each dimension having higher priority than the next.", + "type": "array", + "items": { + "$ref": "#/components/schemas/PriorityDimension" + }, + "minItems": 2, + "maxItems": 2 + }, + "RackNetworkConfigV1": { + "description": "Initial network configuration", + "type": "object", + "properties": { + "bgp": { + "description": "BGP configurations for connecting the rack to external networks", + "type": "array", + "items": { + "$ref": "#/components/schemas/BgpConfig" + } }, - "services": { + "infra_ip_first": { + "description": "First ip address to be used for configuring network infrastructure", + "type": "string", + "format": "ipv4" + }, + "infra_ip_last": { + "description": "Last ip address to be used for configuring network infrastructure", + "type": "string", + "format": "ipv4" + }, + "ports": { + "description": "Uplinks for connecting the rack to external networks", "type": "array", "items": { - "$ref": "#/components/schemas/ServiceZoneService" + "$ref": "#/components/schemas/PortConfigV1" } }, - "zone_type": { - "$ref": "#/components/schemas/ZoneType" + "rack_subnet": { + "$ref": "#/components/schemas/Ipv6Network" } }, "required": [ - "addresses", - "id", - "services", - "zone_type" + "bgp", + "infra_ip_first", + "infra_ip_last", + "ports", + "rack_subnet" ] }, - "ServiceZoneService": { - "description": "Used to request that the Sled initialize a single service.", + "RouteConfig": { "type": "object", "properties": { - "details": { - "$ref": "#/components/schemas/ServiceType" + "destination": { + "description": "The destination of the route.", + "allOf": [ + { + "$ref": "#/components/schemas/IpNetwork" + } + ] }, - "id": { + "nexthop": { + "description": "The nexthop/gateway address.", "type": "string", - "format": "uuid" + "format": "ip" } }, "required": [ - "details", - "id" + "destination", + "nexthop" ] }, + "SemverVersion": { + "type": "string", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" + }, "SetVirtualNetworkInterfaceHost": { "description": "A mapping from a virtual NIC to a physical host", "type": "object", @@ -3675,23 +3575,6 @@ "version" ] }, - "ZoneType": { - "description": "The type of zone which may be requested from Sled Agent", - "type": "string", - "enum": [ - "clickhouse", - "clickhouse_keeper", - "cockroach_db", - "crucible_pantry", - "crucible", - "external_dns", - "internal_dns", - "nexus", - "ntp", - "oximeter", - "switch" - ] - }, "Zpool": { "type": "object", "properties": { diff --git a/sled-agent/src/http_entrypoints.rs b/sled-agent/src/http_entrypoints.rs index b6a60ad521..6b4236278f 100644 --- a/sled-agent/src/http_entrypoints.rs +++ b/sled-agent/src/http_entrypoints.rs @@ -312,7 +312,7 @@ async fn zones_list( #[endpoint { method = GET, - path = "/omicron_zones", + path = "/omicron-zones", }] async fn omicron_zones_get( rqctx: RequestContext, @@ -323,7 +323,7 @@ async fn omicron_zones_get( #[endpoint { method = PUT, - path = "/omicron_zones", + path = "/omicron-zones", }] async fn omicron_zones_put( rqctx: RequestContext, diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 9da60a40ad..a6c71e2f00 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -946,6 +946,7 @@ pub struct OmicronZoneDataset { #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] +#[serde(tag = "type", rename_all = "snake_case")] pub enum OmicronZoneType { BoundaryNtp { address: SocketAddrV6, From 1eb19c8fead37ef06ce1a6cb1e96dea5ea9cf234 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 9 Nov 2023 21:37:30 +0000 Subject: [PATCH 05/44] WIP: a bunch of stuff is no longer part of the sled agent API --- sled-agent/src/params.rs | 172 +----------------------------- sled-agent/src/storage/dataset.rs | 12 --- 2 files changed, 4 insertions(+), 180 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index a6c71e2f00..a933516190 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -246,20 +246,6 @@ pub enum DatasetKind { InternalDns, } -impl From for sled_agent_client::types::DatasetKind { - fn from(k: DatasetKind) -> Self { - use DatasetKind::*; - match k { - CockroachDb => Self::CockroachDb, - Crucible => Self::Crucible, - Clickhouse => Self::Clickhouse, - ClickhouseKeeper => Self::ClickhouseKeeper, - ExternalDns => Self::ExternalDns, - InternalDns => Self::InternalDns, - } - } -} - impl From for nexus_client::types::DatasetKind { fn from(k: DatasetKind) -> Self { use DatasetKind::*; @@ -436,104 +422,14 @@ impl crate::smf_helper::Service for ServiceType { } /// Error returned by attempting to convert an internal service (i.e., a service -/// started autonomously by sled-agent) into a -/// `sled_agent_client::types::ServiceType` to be sent to a remote sled-agent. +/// started autonomously by sled-agent) into an externally-visible service type +// XXX-dap feels like this should be removable #[derive(Debug, Clone, Copy, Error)] #[error("This service may only be started autonomously by sled-agent")] pub struct AutonomousServiceOnlyError; -impl TryFrom for sled_agent_client::types::ServiceType { - type Error = AutonomousServiceOnlyError; - - fn try_from(s: ServiceType) -> Result { - use sled_agent_client::types::ServiceType as AutoSt; - use ServiceType as St; - - match s { - St::Nexus { - internal_address, - external_ip, - nic, - external_tls, - external_dns_servers, - } => Ok(AutoSt::Nexus { - internal_address: internal_address.to_string(), - external_ip, - nic: nic.into(), - external_tls, - external_dns_servers, - }), - St::ExternalDns { http_address, dns_address, nic } => { - Ok(AutoSt::ExternalDns { - http_address: http_address.to_string(), - dns_address: dns_address.to_string(), - nic: nic.into(), - }) - } - St::InternalDns { - http_address, - dns_address, - gz_address, - gz_address_index, - } => Ok(AutoSt::InternalDns { - http_address: http_address.to_string(), - dns_address: dns_address.to_string(), - gz_address, - gz_address_index, - }), - St::Oximeter { address } => { - Ok(AutoSt::Oximeter { address: address.to_string() }) - } - St::CruciblePantry { address } => { - Ok(AutoSt::CruciblePantry { address: address.to_string() }) - } - St::BoundaryNtp { - address, - ntp_servers, - dns_servers, - domain, - nic, - snat_cfg, - } => Ok(AutoSt::BoundaryNtp { - address: address.to_string(), - ntp_servers, - dns_servers, - domain, - nic: nic.into(), - snat_cfg: snat_cfg.into(), - }), - St::InternalNtp { address, ntp_servers, dns_servers, domain } => { - Ok(AutoSt::InternalNtp { - address: address.to_string(), - ntp_servers, - dns_servers, - domain, - }) - } - St::Clickhouse { address } => { - Ok(AutoSt::Clickhouse { address: address.to_string() }) - } - St::ClickhouseKeeper { address } => { - Ok(AutoSt::ClickhouseKeeper { address: address.to_string() }) - } - St::CockroachDb { address } => { - Ok(AutoSt::CockroachDb { address: address.to_string() }) - } - St::Crucible { address } => { - Ok(AutoSt::Crucible { address: address.to_string() }) - } - St::ManagementGatewayService - | St::SpSim - | St::Wicketd { .. } - | St::Dendrite { .. } - | St::Tfport { .. } - | St::Uplink - | St::Mgd - | St::MgDdm { .. } => Err(AutonomousServiceOnlyError), - } - } -} - +// XXX-dap do a pass over this file to see which of these types can be removed +// altogether. Those only needed for migration could go into a separate module. /// The type of zone which may be requested from Sled Agent #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, @@ -553,24 +449,6 @@ pub enum ZoneType { Switch, } -impl From for sled_agent_client::types::ZoneType { - fn from(zt: ZoneType) -> Self { - match zt { - ZoneType::Clickhouse => Self::Clickhouse, - ZoneType::ClickhouseKeeper => Self::ClickhouseKeeper, - ZoneType::CockroachDb => Self::CockroachDb, - ZoneType::Crucible => Self::Crucible, - ZoneType::CruciblePantry => Self::CruciblePantry, - ZoneType::InternalDns => Self::InternalDns, - ZoneType::ExternalDns => Self::ExternalDns, - ZoneType::Nexus => Self::Nexus, - ZoneType::Ntp => Self::Ntp, - ZoneType::Oximeter => Self::Oximeter, - ZoneType::Switch => Self::Switch, - } - } -} - impl std::fmt::Display for ZoneType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use ZoneType::*; @@ -601,16 +479,6 @@ pub struct DatasetRequest { pub service_address: SocketAddrV6, } -impl From for sled_agent_client::types::DatasetRequest { - fn from(d: DatasetRequest) -> Self { - Self { - id: d.id, - name: d.name.into(), - service_address: d.service_address.to_string(), - } - } -} - /// Describes a request to create a zone running one or more services. #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, @@ -660,27 +528,6 @@ impl ServiceZoneRequest { } } -impl TryFrom - for sled_agent_client::types::ServiceZoneRequest -{ - type Error = AutonomousServiceOnlyError; - - fn try_from(s: ServiceZoneRequest) -> Result { - let mut services = Vec::with_capacity(s.services.len()); - for service in s.services { - services.push(service.try_into()?); - } - - Ok(Self { - id: s.id, - zone_type: s.zone_type.into(), - addresses: s.addresses, - dataset: s.dataset.map(|d| d.into()), - services, - }) - } -} - impl ServiceZoneRequest { pub fn into_nexus_service_req( &self, @@ -850,17 +697,6 @@ pub struct ServiceZoneService { pub details: ServiceType, } -impl TryFrom - for sled_agent_client::types::ServiceZoneService -{ - type Error = AutonomousServiceOnlyError; - - fn try_from(s: ServiceZoneService) -> Result { - let details = s.details.try_into()?; - Ok(Self { id: s.id, details }) - } -} - /// Used to request that the Sled initialize multiple services. #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] pub struct ServiceEnsureBody { diff --git a/sled-agent/src/storage/dataset.rs b/sled-agent/src/storage/dataset.rs index 4efc0f320a..8f763fac14 100644 --- a/sled-agent/src/storage/dataset.rs +++ b/sled-agent/src/storage/dataset.rs @@ -36,18 +36,6 @@ impl DatasetName { } } -impl From for sled_agent_client::types::DatasetName { - fn from(n: DatasetName) -> Self { - Self { - pool_name: sled_agent_client::types::ZpoolName::from_str( - &n.pool().to_string(), - ) - .unwrap(), - kind: n.dataset().clone().into(), - } - } -} - #[cfg(test)] mod test { use super::*; From ccb85bf2cff4486e62e7274810b0d551d0d1f998 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 9 Nov 2023 21:59:26 +0000 Subject: [PATCH 06/44] WIP: inches ahead: starting to fix RSS --- Cargo.lock | 1 + clients/sled-agent-client/Cargo.toml | 1 + clients/sled-agent-client/src/lib.rs | 1 + sled-agent/src/rack_setup/plan/service.rs | 29 ++++++++++++++--------- sled-agent/src/rack_setup/service.rs | 27 ++++++++++----------- sled-agent/src/storage/dataset.rs | 1 - 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc10947083..c1956dee93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8203,6 +8203,7 @@ dependencies = [ "progenitor", "regress", "reqwest", + "schemars", "serde", "slog", "uuid", diff --git a/clients/sled-agent-client/Cargo.toml b/clients/sled-agent-client/Cargo.toml index b2ed07caba..8630030b24 100644 --- a/clients/sled-agent-client/Cargo.toml +++ b/clients/sled-agent-client/Cargo.toml @@ -12,6 +12,7 @@ progenitor.workspace = true ipnetwork.workspace = true regress.workspace = true reqwest = { workspace = true, features = [ "json", "rustls-tls", "stream" ] } +schemars.workspace = true serde.workspace = true slog.workspace = true uuid.workspace = true diff --git a/clients/sled-agent-client/src/lib.rs b/clients/sled-agent-client/src/lib.rs index 0df21d894e..0bbd27cf3e 100644 --- a/clients/sled-agent-client/src/lib.rs +++ b/clients/sled-agent-client/src/lib.rs @@ -10,6 +10,7 @@ use uuid::Uuid; progenitor::generate_api!( spec = "../../openapi/sled-agent.json", + derives = [ schemars::JsonSchema ], inner_type = slog::Logger, pre_hook = (|log: &slog::Logger, request: &reqwest::Request| { slog::debug!(log, "client request"; diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index 3dac5d7d1e..6c6aaacbb4 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -22,7 +22,7 @@ use omicron_common::address::{ MGD_PORT, MGS_PORT, NTP_PORT, NUM_SOURCE_NAT_PORTS, RSS_RESERVED_ADDRESSES, SLED_PREFIX, }; -use omicron_common::api::external::{MacAddr, Vni}; +use omicron_common::api::external::{Generation, MacAddr, Vni}; use omicron_common::api::internal::shared::SwitchLocation; use omicron_common::api::internal::shared::{ NetworkInterface, NetworkInterfaceKind, SourceNatConfig, @@ -99,18 +99,25 @@ pub enum PlanError { NotEnoughSleds, } -#[derive( - Clone, Debug, Default, Deserialize, Serialize, PartialEq, JsonSchema, -)] -pub struct SledRequest { - /// Services to be instantiated. - #[serde(default, rename = "service")] - pub services: Vec, +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +struct SledConfig { + /// generation number to use the next time we try to configure zones on this + /// sled + next_generation: Generation, + + /// zones configured for this sled + zones: Vec, +} + +impl Default for SledConfig { + fn default() -> Self { + SledConfig { next_generation: Generation::new(), zones: Vec::new() } + } } #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct Plan { - pub services: HashMap, + pub services: HashMap, pub dns_config: DnsConfigParams, } @@ -787,8 +794,8 @@ struct SledInfo { is_scrimlet: bool, /// allocator for addresses in this Sled's subnet addr_alloc: AddressBumpAllocator, - /// under-construction list of services being deployed to a Sled - request: SledRequest, + /// under-construction list of Omicron zones being deployed to a Sled + request: SledConfig, } impl SledInfo { diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 7f6469d2c0..f7ba555eb5 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -259,7 +259,7 @@ impl ServiceInner { async fn initialize_services_on_sled( &self, sled_address: SocketAddrV6, - services: &Vec, + zones_config: &SledAgentTypes::OmicronZonesConfig, ) -> Result<(), SetupServiceError> { let dur = std::time::Duration::from_secs(60); let client = reqwest::ClientBuilder::new() @@ -272,21 +272,13 @@ impl ServiceInner { self.log.new(o!("SledAgentClient" => sled_address.to_string())), ); - let services = services - .iter() - .map(|s| s.clone().try_into()) - .collect::, AutonomousServiceOnlyError>>() - .map_err(|err| { - SetupServiceError::SledInitialization(err.to_string()) - })?; - - info!(self.log, "sending service requests..."); let services_put = || async { - info!(self.log, "initializing sled services: {:?}", services); + info!( + self.log, + "attempting to set up sled's Omicron zones: {:?}", zones_config + ); client - .services_put(&SledAgentTypes::ServiceEnsureBody { - services: services.clone(), - }) + .omicron_zones_put(zones_config) .await .map_err(BackoffError::transient)?; Ok::<(), BackoffError>>(()) @@ -294,7 +286,7 @@ impl ServiceInner { let log_failure = |error, delay| { warn!( self.log, - "failed to initialize services"; + "failed to initialize Omicron zones"; "error" => ?error, "retry_after" => ?delay, ); @@ -316,6 +308,11 @@ impl ServiceInner { // // Note that after first-time setup, the initialization order of // services should not matter. + // XXX-dap revisit me -- I think we probably need to store a few different + // OmicronZoneConfig objects rather than this approach of slicing only part + // of it. Or else we store the last generation used and all the zones in + // one place and use a filter function here and then generate an + // OmicronZonesConfig on the fly -- maybe that's a better idea. async fn ensure_all_services_of_type( &self, service_plan: &ServicePlan, diff --git a/sled-agent/src/storage/dataset.rs b/sled-agent/src/storage/dataset.rs index 8f763fac14..eda78cec06 100644 --- a/sled-agent/src/storage/dataset.rs +++ b/sled-agent/src/storage/dataset.rs @@ -6,7 +6,6 @@ use crate::params::DatasetKind; use illumos_utils::zpool::ZpoolName; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::str::FromStr; #[derive( Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Clone, JsonSchema, From a1827df43a4b1d121e863ccd60654d87be2cdf8a Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 9 Nov 2023 23:50:33 +0000 Subject: [PATCH 07/44] WIP: compiles again --- sled-agent/src/params.rs | 478 +++++++++++++--------- sled-agent/src/rack_setup/plan/service.rs | 274 +++++-------- sled-agent/src/rack_setup/service.rs | 184 +++++---- 3 files changed, 501 insertions(+), 435 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index a933516190..cf761df60c 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -25,8 +25,8 @@ use sled_hardware::Baseboard; pub use sled_hardware::DendriteAsic; use std::fmt::{Debug, Display, Formatter, Result as FormatResult}; use std::net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6}; +use std::str::FromStr; use std::time::Duration; -use thiserror::Error; use uuid::Uuid; /// Used to request a Disk state change @@ -421,13 +421,6 @@ impl crate::smf_helper::Service for ServiceType { } } -/// Error returned by attempting to convert an internal service (i.e., a service -/// started autonomously by sled-agent) into an externally-visible service type -// XXX-dap feels like this should be removable -#[derive(Debug, Clone, Copy, Error)] -#[error("This service may only be started autonomously by sled-agent")] -pub struct AutonomousServiceOnlyError; - // XXX-dap do a pass over this file to see which of these types can be removed // altogether. Those only needed for migration could go into a separate module. /// The type of zone which may be requested from Sled Agent @@ -528,166 +521,6 @@ impl ServiceZoneRequest { } } -impl ServiceZoneRequest { - pub fn into_nexus_service_req( - &self, - sled_id: Uuid, - ) -> Result< - Vec, - AutonomousServiceOnlyError, - > { - use nexus_client::types as NexusTypes; - - let mut services = vec![]; - for svc in &self.services { - let service_id = svc.id; - let zone_id = Some(self.id); - match &svc.details { - ServiceType::Nexus { - external_ip, - internal_address, - nic, - .. - } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: internal_address.to_string(), - kind: NexusTypes::ServiceKind::Nexus { - external_address: *external_ip, - nic: NexusTypes::ServiceNic { - id: nic.id, - name: nic.name.clone(), - ip: nic.ip, - mac: nic.mac, - }, - }, - }); - } - ServiceType::ExternalDns { http_address, dns_address, nic } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: http_address.to_string(), - kind: NexusTypes::ServiceKind::ExternalDns { - external_address: dns_address.ip(), - nic: NexusTypes::ServiceNic { - id: nic.id, - name: nic.name.clone(), - ip: nic.ip, - mac: nic.mac, - }, - }, - }); - } - ServiceType::InternalDns { http_address, .. } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: http_address.to_string(), - kind: NexusTypes::ServiceKind::InternalDns, - }); - } - ServiceType::Oximeter { address } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: address.to_string(), - kind: NexusTypes::ServiceKind::Oximeter, - }); - } - ServiceType::CruciblePantry { address } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: address.to_string(), - kind: NexusTypes::ServiceKind::CruciblePantry, - }); - } - ServiceType::BoundaryNtp { address, snat_cfg, nic, .. } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: address.to_string(), - kind: NexusTypes::ServiceKind::BoundaryNtp { - snat: snat_cfg.into(), - nic: NexusTypes::ServiceNic { - id: nic.id, - name: nic.name.clone(), - ip: nic.ip, - mac: nic.mac, - }, - }, - }); - } - ServiceType::InternalNtp { address, .. } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: address.to_string(), - kind: NexusTypes::ServiceKind::InternalNtp, - }); - } - ServiceType::Clickhouse { address } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: address.to_string(), - kind: NexusTypes::ServiceKind::Clickhouse, - }); - } - ServiceType::ClickhouseKeeper { address } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: address.to_string(), - kind: NexusTypes::ServiceKind::ClickhouseKeeper, - }); - } - ServiceType::Crucible { address } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: address.to_string(), - kind: NexusTypes::ServiceKind::Crucible, - }); - } - ServiceType::CockroachDb { address } => { - services.push(NexusTypes::ServicePutRequest { - service_id, - zone_id, - sled_id, - address: address.to_string(), - kind: NexusTypes::ServiceKind::Cockroach, - }); - } - ServiceType::ManagementGatewayService - | ServiceType::SpSim - | ServiceType::Wicketd { .. } - | ServiceType::Dendrite { .. } - | ServiceType::MgDdm { .. } - | ServiceType::Mgd - | ServiceType::Tfport { .. } - | ServiceType::Uplink => { - return Err(AutonomousServiceOnlyError); - } - } - } - - Ok(services) - } -} - /// Used to request that the Sled initialize a single service. #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, @@ -712,6 +545,15 @@ pub struct OmicronZonesConfig { pub zones: Vec, } +impl From for sled_agent_client::types::OmicronZonesConfig { + fn from(local: OmicronZonesConfig) -> Self { + Self { + generation: local.generation.into(), + zones: local.zones.into_iter().map(|s| s.into()).collect(), + } + } +} + /// Describes one Omicron zone running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, @@ -722,38 +564,57 @@ pub struct OmicronZoneConfig { pub zone_type: OmicronZoneType, } +impl From for sled_agent_client::types::OmicronZoneConfig { + fn from(local: OmicronZoneConfig) -> Self { + Self { + id: local.id, + underlay_address: local.underlay_address.into(), + zone_type: local.zone_type.into(), + } + } +} + impl OmicronZoneConfig { // XXX-dap should the caller (RSS) should specify this directly? That // eliminates one reason why Sled Agent needs to know about what kind of // dataset it's looking at. pub fn dataset_name(&self) -> Option { - let (dataset, dataset_kind) = match &self.zone_type { + self.dataset_name_and_address().map(|d| d.0) + } + + pub fn dataset_name_and_address( + &self, + ) -> Option<(DatasetName, SocketAddrV6)> { + let (dataset, dataset_kind, address) = match &self.zone_type { OmicronZoneType::BoundaryNtp { .. } | OmicronZoneType::InternalNtp { .. } | OmicronZoneType::Nexus { .. } | OmicronZoneType::Oximeter { .. } | OmicronZoneType::CruciblePantry { .. } => None, - OmicronZoneType::Clickhouse { dataset, .. } => { - Some((dataset, DatasetKind::Clickhouse)) + OmicronZoneType::Clickhouse { dataset, address, .. } => { + Some((dataset, DatasetKind::Clickhouse, address)) } - OmicronZoneType::ClickhouseKeeper { dataset, .. } => { - Some((dataset, DatasetKind::ClickhouseKeeper)) + OmicronZoneType::ClickhouseKeeper { dataset, address, .. } => { + Some((dataset, DatasetKind::ClickhouseKeeper, address)) } - OmicronZoneType::CockroachDb { dataset, .. } => { - Some((dataset, DatasetKind::CockroachDb)) + OmicronZoneType::CockroachDb { dataset, address, .. } => { + Some((dataset, DatasetKind::CockroachDb, address)) } - OmicronZoneType::Crucible { dataset, .. } => { - Some((dataset, DatasetKind::Crucible)) + OmicronZoneType::Crucible { dataset, address, .. } => { + Some((dataset, DatasetKind::Crucible, address)) } - OmicronZoneType::ExternalDns { dataset, .. } => { - Some((dataset, DatasetKind::ExternalDns)) + OmicronZoneType::ExternalDns { dataset, http_address, .. } => { + Some((dataset, DatasetKind::ExternalDns, http_address)) } - OmicronZoneType::InternalDns { dataset, .. } => { - Some((dataset, DatasetKind::InternalDns)) + OmicronZoneType::InternalDns { dataset, http_address, .. } => { + Some((dataset, DatasetKind::InternalDns, http_address)) } }?; - Some(DatasetName::new(dataset.pool_name.clone(), dataset_kind)) + Some(( + DatasetName::new(dataset.pool_name.clone(), dataset_kind), + *address, + )) } // XXX-dap TODO-doc @@ -763,6 +624,147 @@ impl OmicronZoneConfig { Some(self.id), ) } + + pub fn into_nexus_service_req( + &self, + sled_id: Uuid, + ) -> nexus_client::types::ServicePutRequest { + use nexus_client::types as NexusTypes; + + let service_id = self.id; + let zone_id = Some(self.id); + match &self.zone_type { + OmicronZoneType::Nexus { + external_ip, + internal_address, + nic, + .. + } => NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: internal_address.to_string(), + kind: NexusTypes::ServiceKind::Nexus { + external_address: *external_ip, + nic: NexusTypes::ServiceNic { + id: nic.id, + name: nic.name.clone(), + ip: nic.ip, + mac: nic.mac, + }, + }, + }, + OmicronZoneType::ExternalDns { + http_address, + dns_address, + nic, + .. + } => NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: http_address.to_string(), + kind: NexusTypes::ServiceKind::ExternalDns { + external_address: dns_address.ip(), + nic: NexusTypes::ServiceNic { + id: nic.id, + name: nic.name.clone(), + ip: nic.ip, + mac: nic.mac, + }, + }, + }, + OmicronZoneType::InternalDns { http_address, .. } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: http_address.to_string(), + kind: NexusTypes::ServiceKind::InternalDns, + } + } + OmicronZoneType::Oximeter { address } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: address.to_string(), + kind: NexusTypes::ServiceKind::Oximeter, + } + } + OmicronZoneType::CruciblePantry { address } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: address.to_string(), + kind: NexusTypes::ServiceKind::CruciblePantry, + } + } + OmicronZoneType::BoundaryNtp { address, snat_cfg, nic, .. } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: address.to_string(), + kind: NexusTypes::ServiceKind::BoundaryNtp { + snat: snat_cfg.into(), + nic: NexusTypes::ServiceNic { + id: nic.id, + name: nic.name.clone(), + ip: nic.ip, + mac: nic.mac, + }, + }, + } + } + OmicronZoneType::InternalNtp { address, .. } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: address.to_string(), + kind: NexusTypes::ServiceKind::InternalNtp, + } + } + OmicronZoneType::Clickhouse { address, .. } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: address.to_string(), + kind: NexusTypes::ServiceKind::Clickhouse, + } + } + OmicronZoneType::ClickhouseKeeper { address, .. } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: address.to_string(), + kind: NexusTypes::ServiceKind::ClickhouseKeeper, + } + } + OmicronZoneType::Crucible { address, .. } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: address.to_string(), + kind: NexusTypes::ServiceKind::Crucible, + } + } + OmicronZoneType::CockroachDb { address, .. } => { + NexusTypes::ServicePutRequest { + service_id, + zone_id, + sled_id, + address: address.to_string(), + kind: NexusTypes::ServiceKind::Cockroach, + } + } + } + } } /// Describes a persistent ZFS dataset associated with an Omicron zone @@ -770,7 +772,18 @@ impl OmicronZoneConfig { Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] pub struct OmicronZoneDataset { - pool_name: ZpoolName, + pub pool_name: ZpoolName, +} + +impl From for sled_agent_client::types::OmicronZoneDataset { + fn from(local: OmicronZoneDataset) -> Self { + Self { + pool_name: sled_agent_client::types::ZpoolName::from_str( + &local.pool_name.to_string(), + ) + .unwrap(), + } + } } /// Describes what component is running in this zone and its associated @@ -896,6 +909,105 @@ impl crate::smf_helper::Service for OmicronZoneType { } } +impl From for sled_agent_client::types::OmicronZoneType { + fn from(local: OmicronZoneType) -> Self { + use sled_agent_client::types::OmicronZoneType as Other; + match local { + OmicronZoneType::BoundaryNtp { + address, + ntp_servers, + dns_servers, + domain, + nic, + snat_cfg, + } => Other::BoundaryNtp { + address: address.to_string(), + dns_servers, + domain, + ntp_servers, + snat_cfg: snat_cfg.into(), + nic: nic.into(), + }, + OmicronZoneType::Clickhouse { address, dataset } => { + Other::Clickhouse { + address: address.to_string(), + dataset: dataset.into(), + } + } + OmicronZoneType::ClickhouseKeeper { address, dataset } => { + Other::ClickhouseKeeper { + address: address.to_string(), + dataset: dataset.into(), + } + } + OmicronZoneType::CockroachDb { address, dataset } => { + Other::CockroachDb { + address: address.to_string(), + dataset: dataset.into(), + } + } + OmicronZoneType::Crucible { address, dataset } => Other::Crucible { + address: address.to_string(), + dataset: dataset.into(), + }, + OmicronZoneType::CruciblePantry { address } => { + Other::CruciblePantry { address: address.to_string() } + } + OmicronZoneType::ExternalDns { + dataset, + http_address, + dns_address, + nic, + } => Other::ExternalDns { + dataset: dataset.into(), + http_address: http_address.to_string(), + dns_address: dns_address.to_string(), + nic: nic.into(), + }, + OmicronZoneType::InternalDns { + dataset, + http_address, + dns_address, + gz_address, + gz_address_index, + } => Other::InternalDns { + dataset: dataset.into(), + http_address: http_address.to_string(), + dns_address: dns_address.to_string(), + gz_address, + gz_address_index, + }, + OmicronZoneType::InternalNtp { + address, + ntp_servers, + dns_servers, + domain, + } => Other::InternalNtp { + address: address.to_string(), + ntp_servers, + dns_servers, + domain, + }, + OmicronZoneType::Nexus { + internal_address, + external_ip, + nic, + external_tls, + external_dns_servers, + } => Other::Nexus { + external_dns_servers, + external_ip, + external_tls, + internal_address: internal_address.to_string(), + nic: nic.into(), + }, + OmicronZoneType::Oximeter { address } => { + Other::Oximeter { address: address.to_string() } + } + } + } +} + #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] pub struct TimeSync { /// The synchronization state of the sled, true when the system clock diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index 6c6aaacbb4..f754640e44 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -6,8 +6,7 @@ use crate::bootstrap::params::StartSledAgentRequest; use crate::params::{ - DatasetKind, DatasetRequest, ServiceType, ServiceZoneRequest, - ServiceZoneService, ZoneType, + DatasetKind, OmicronZoneConfig, OmicronZoneDataset, OmicronZoneType, }; use crate::rack_setup::config::SetupServiceConfig as Config; use crate::storage::dataset::DatasetName; @@ -100,13 +99,13 @@ pub enum PlanError { } #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] -struct SledConfig { +pub struct SledConfig { /// generation number to use the next time we try to configure zones on this /// sled - next_generation: Generation, + pub next_generation: Generation, /// zones configured for this sled - zones: Vec, + pub zones: Vec, } impl Default for SledConfig { @@ -354,24 +353,18 @@ impl Plan { let dataset_name = sled.alloc_from_u2_zpool(DatasetKind::InternalDns)?; - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::InternalDns, - addresses: vec![ip], - dataset: Some(DatasetRequest { - id, - name: dataset_name, - service_address: http_address, - }), - services: vec![ServiceZoneService { - id, - details: ServiceType::InternalDns { - http_address, - dns_address, - gz_address: dns_subnet.gz_address().ip(), - gz_address_index: i.try_into().expect("Giant indices?"), + underlay_address: ip, + zone_type: OmicronZoneType::InternalDns { + dataset: OmicronZoneDataset { + pool_name: dataset_name.pool().clone(), }, - }], + http_address: http_address, + dns_address: dns_address, + gz_address: dns_subnet.gz_address().ip(), + gz_address_index: i.try_into().expect("Giant indices?"), + }, }); } @@ -392,19 +385,15 @@ impl Plan { .unwrap(); let dataset_name = sled.alloc_from_u2_zpool(DatasetKind::CockroachDb)?; - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::CockroachDb, - addresses: vec![ip], - dataset: Some(DatasetRequest { - id, - name: dataset_name, - service_address: address, - }), - services: vec![ServiceZoneService { - id, - details: ServiceType::CockroachDb { address }, - }], + underlay_address: ip, + zone_type: OmicronZoneType::CockroachDb { + dataset: OmicronZoneDataset { + pool_name: dataset_name.pool().clone(), + }, + address, + }, }); } @@ -439,23 +428,17 @@ impl Plan { let dataset_kind = DatasetKind::ExternalDns; let dataset_name = sled.alloc_from_u2_zpool(dataset_kind)?; - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::ExternalDns, - addresses: vec![*http_address.ip()], - dataset: Some(DatasetRequest { - id, - name: dataset_name, - service_address: http_address, - }), - services: vec![ServiceZoneService { - id, - details: ServiceType::ExternalDns { - http_address, - dns_address, - nic, + underlay_address: *http_address.ip(), + zone_type: OmicronZoneType::ExternalDns { + dataset: OmicronZoneDataset { + pool_name: dataset_name.pool().clone(), }, - }], + http_address, + dns_address, + nic, + }, }); } @@ -477,33 +460,28 @@ impl Plan { ) .unwrap(); let (nic, external_ip) = svc_port_builder.next_nexus(id)?; - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::Nexus, - addresses: vec![address], - dataset: None, - services: vec![ServiceZoneService { - id, - details: ServiceType::Nexus { - internal_address: SocketAddrV6::new( - address, - omicron_common::address::NEXUS_INTERNAL_PORT, - 0, - 0, - ), - external_ip, - nic, - // Tell Nexus to use TLS if and only if the caller - // provided TLS certificates. This effectively - // determines the status of TLS for the lifetime of - // the rack. In production-like deployments, we'd - // always expect TLS to be enabled. It's only in - // development that it might not be. - external_tls: !config.external_certificates.is_empty(), - external_dns_servers: config.dns_servers.clone(), - }, - }], - }) + underlay_address: address, + zone_type: OmicronZoneType::Nexus { + internal_address: SocketAddrV6::new( + address, + omicron_common::address::NEXUS_INTERNAL_PORT, + 0, + 0, + ), + external_ip, + nic, + // Tell Nexus to use TLS if and only if the caller + // provided TLS certificates. This effectively + // determines the status of TLS for the lifetime of + // the rack. In production-like deployments, we'd + // always expect TLS to be enabled. It's only in + // development that it might not be. + external_tls: !config.external_certificates.is_empty(), + external_dns_servers: config.dns_servers.clone(), + }, + }); } // Provision Oximeter zones, continuing to stripe across sleds. @@ -524,22 +502,17 @@ impl Plan { omicron_common::address::OXIMETER_PORT, ) .unwrap(); - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::Oximeter, - addresses: vec![address], - dataset: None, - services: vec![ServiceZoneService { - id, - details: ServiceType::Oximeter { - address: SocketAddrV6::new( - address, - omicron_common::address::OXIMETER_PORT, - 0, - 0, - ), - }, - }], + underlay_address: address, + zone_type: OmicronZoneType::Oximeter { + address: SocketAddrV6::new( + address, + omicron_common::address::OXIMETER_PORT, + 0, + 0, + ), + }, }) } @@ -561,19 +534,15 @@ impl Plan { .unwrap(); let dataset_name = sled.alloc_from_u2_zpool(DatasetKind::Clickhouse)?; - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::Clickhouse, - addresses: vec![ip], - dataset: Some(DatasetRequest { - id, - name: dataset_name, - service_address: address, - }), - services: vec![ServiceZoneService { - id, - details: ServiceType::Clickhouse { address }, - }], + underlay_address: ip, + zone_type: OmicronZoneType::Clickhouse { + address, + dataset: OmicronZoneDataset { + pool_name: dataset_name.pool().clone(), + }, + }, }); } @@ -601,19 +570,15 @@ impl Plan { .unwrap(); let dataset_name = sled.alloc_from_u2_zpool(DatasetKind::ClickhouseKeeper)?; - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::ClickhouseKeeper, - addresses: vec![ip], - dataset: Some(DatasetRequest { - id, - name: dataset_name, - service_address: address, - }), - services: vec![ServiceZoneService { - id, - details: ServiceType::ClickhouseKeeper { address }, - }], + underlay_address: ip, + zone_type: OmicronZoneType::ClickhouseKeeper { + address, + dataset: OmicronZoneDataset { + pool_name: dataset_name.pool().clone(), + }, + }, }); } @@ -632,18 +597,13 @@ impl Plan { dns_builder .service_backend_zone(ServiceName::CruciblePantry, &zone, port) .unwrap(); - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::CruciblePantry, - addresses: vec![address], - dataset: None, - services: vec![ServiceZoneService { - id, - details: ServiceType::CruciblePantry { - address: SocketAddrV6::new(address, port, 0, 0), - }, - }], - }) + underlay_address: address, + zone_type: OmicronZoneType::CruciblePantry { + address: SocketAddrV6::new(address, port, 0, 0), + }, + }); } // Provision a Crucible zone on every zpool on every Sled. @@ -663,22 +623,13 @@ impl Plan { ) .unwrap(); - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::Crucible, - addresses: vec![ip], - dataset: Some(DatasetRequest { - id, - name: DatasetName::new( - pool.clone(), - DatasetKind::Crucible, - ), - service_address: address, - }), - services: vec![ServiceZoneService { - id, - details: ServiceType::Crucible { address }, - }], + underlay_address: ip, + zone_type: OmicronZoneType::Crucible { + address, + dataset: OmicronZoneDataset { pool_name: pool.clone() }, + }, }); } } @@ -691,47 +642,40 @@ impl Plan { let id = Uuid::new_v4(); let address = sled.addr_alloc.next().expect("Not enough addrs"); let zone = dns_builder.host_zone(id, address).unwrap(); + let ntp_address = SocketAddrV6::new(address, NTP_PORT, 0, 0); - let (services, svcname) = if idx < BOUNDARY_NTP_COUNT { + let (zone_type, svcname) = if idx < BOUNDARY_NTP_COUNT { boundary_ntp_servers.push(format!("{}.host.{}", id, DNS_ZONE)); let (nic, snat_cfg) = svc_port_builder.next_snat(id)?; ( - vec![ServiceZoneService { - id, - details: ServiceType::BoundaryNtp { - address: SocketAddrV6::new(address, NTP_PORT, 0, 0), - ntp_servers: config.ntp_servers.clone(), - dns_servers: config.dns_servers.clone(), - domain: None, - nic, - snat_cfg, - }, - }], + OmicronZoneType::BoundaryNtp { + address: ntp_address, + ntp_servers: config.ntp_servers.clone(), + dns_servers: config.dns_servers.clone(), + domain: None, + nic, + snat_cfg, + }, ServiceName::BoundaryNtp, ) } else { ( - vec![ServiceZoneService { - id, - details: ServiceType::InternalNtp { - address: SocketAddrV6::new(address, NTP_PORT, 0, 0), - ntp_servers: boundary_ntp_servers.clone(), - dns_servers: rack_dns_servers.clone(), - domain: None, - }, - }], + OmicronZoneType::InternalNtp { + address: ntp_address, + ntp_servers: boundary_ntp_servers.clone(), + dns_servers: rack_dns_servers.clone(), + domain: None, + }, ServiceName::InternalNtp, ) }; dns_builder.service_backend_zone(svcname, &zone, NTP_PORT).unwrap(); - sled.request.services.push(ServiceZoneRequest { + sled.request.zones.push(OmicronZoneConfig { id, - zone_type: ZoneType::Ntp, - addresses: vec![address], - dataset: None, - services, + underlay_address: address, + zone_type, }); } diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index f7ba555eb5..a30c36ffe1 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -65,8 +65,7 @@ use crate::bootstrap::params::StartSledAgentRequest; use crate::bootstrap::rss_handle::BootstrapAgentHandle; use crate::nexus::d2n_params; use crate::params::{ - AutonomousServiceOnlyError, ServiceType, ServiceZoneRequest, - ServiceZoneService, TimeSync, ZoneType, + OmicronZoneConfig, OmicronZoneType, OmicronZonesConfig, TimeSync, }; use crate::rack_setup::plan::service::{ Plan as ServicePlan, PlanError as ServicePlanError, @@ -256,10 +255,10 @@ impl ServiceInner { ServiceInner { log } } - async fn initialize_services_on_sled( + async fn initialize_zones_on_sled( &self, sled_address: SocketAddrV6, - zones_config: &SledAgentTypes::OmicronZonesConfig, + zones_config: &OmicronZonesConfig, ) -> Result<(), SetupServiceError> { let dur = std::time::Duration::from_secs(60); let client = reqwest::ClientBuilder::new() @@ -278,7 +277,7 @@ impl ServiceInner { "attempting to set up sled's Omicron zones: {:?}", zones_config ); client - .omicron_zones_put(zones_config) + .omicron_zones_put(&zones_config.clone().into()) .await .map_err(BackoffError::transient)?; Ok::<(), BackoffError>>(()) @@ -308,33 +307,27 @@ impl ServiceInner { // // Note that after first-time setup, the initialization order of // services should not matter. - // XXX-dap revisit me -- I think we probably need to store a few different - // OmicronZoneConfig objects rather than this approach of slicing only part - // of it. Or else we store the last generation used and all the zones in - // one place and use a filter function here and then generate an - // OmicronZonesConfig on the fly -- maybe that's a better idea. - async fn ensure_all_services_of_type( + async fn ensure_zones_of_type( &self, - service_plan: &ServicePlan, - zone_types: &HashSet, + service_plan: &mut ServicePlan, + // XXX-dap better way to deal with this filtering that doesn't require a + // box and also doesn't require that the caller has done this correctly + zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), ) -> Result<(), SetupServiceError> { - futures::future::join_all(service_plan.services.iter().map( - |(sled_address, services_request)| async move { - let services: Vec<_> = services_request - .services + futures::future::join_all(service_plan.services.iter_mut().map( + |(sled_address, sled_config)| async move { + let zones: Vec<_> = sled_config + .zones .iter() - .filter_map(|service| { - if zone_types.contains(&service.zone_type) { - Some(service.clone()) - } else { - None - } - }) + .filter(|z| zone_filter(&z.zone_type)) + .cloned() .collect(); - if !services.is_empty() { - self.initialize_services_on_sled(*sled_address, &services) - .await?; - } + let generation = sled_config.next_generation; + sled_config.next_generation = + sled_config.next_generation.next(); + let zones_config = OmicronZonesConfig { generation, zones }; + self.initialize_zones_on_sled(*sled_address, &zones_config) + .await?; Ok(()) }, )) @@ -356,17 +349,15 @@ impl ServiceInner { let dns_server_ips = // iterate sleds service_plan.services.iter().filter_map( - |(_, services_request)| { - // iterate services for this sled - let dns_addrs: Vec = services_request - .services + |(_, sled_config)| { + // iterate zones for this sled + let dns_addrs: Vec = sled_config + .zones .iter() - .filter_map(|service| { - match &service.services[0] { - ServiceZoneService { - details: ServiceType::InternalDns { http_address, .. }, - .. - } => { + .filter_map(|zone_config| { + match &zone_config.zone_type { + OmicronZoneType::InternalDns { http_address, .. } + => { Some(*http_address) }, _ => None, @@ -540,25 +531,28 @@ impl ServiceInner { // a format which can be processed by Nexus. let mut services: Vec = vec![]; let mut datasets: Vec = vec![]; - for (addr, service_request) in service_plan.services.iter() { + for (addr, sled_config) in service_plan.services.iter() { let sled_id = *id_map .get(addr) .expect("Sled address in service plan, but not sled plan"); - for zone in &service_request.services { - services.extend(zone.into_nexus_service_req(sled_id).map_err( - |err| SetupServiceError::BadConfig(err.to_string()), - )?); + for zone in &sled_config.zones { + services.push(zone.into_nexus_service_req(sled_id)); } - for service in service_request.services.iter() { - if let Some(dataset) = &service.dataset { + for zone in &sled_config.zones { + // XXX-dap TODO-cleanup kind of a cheating way to use the + // existing implementation + let native_zone_config = OmicronZoneConfig::from(zone.clone()); + if let Some((dataset_name, dataset_address)) = + native_zone_config.dataset_name_and_address() + { datasets.push(NexusTypes::DatasetCreateRequest { - zpool_id: dataset.name.pool().id(), - dataset_id: dataset.id, + zpool_id: dataset_name.pool().id(), + dataset_id: zone.id, request: NexusTypes::DatasetPutRequest { - address: dataset.service_address.to_string(), - kind: dataset.name.dataset().clone().into(), + address: dataset_address.to_string(), + kind: dataset_name.dataset().clone().into(), }, }) } @@ -694,20 +688,22 @@ impl ServiceInner { ) -> Result<(), SetupServiceError> { // Now that datasets and zones have started for CockroachDB, // perform one-time initialization of the cluster. - let sled_address = - service_plan - .services - .iter() - .find_map(|(sled_address, sled_request)| { - if sled_request.services.iter().any(|service| { - service.zone_type == ZoneType::CockroachDb - }) { - Some(sled_address) - } else { - None - } - }) - .expect("Should not create service plans without CockroachDb"); + let sled_address = service_plan + .services + .iter() + .find_map(|(sled_address, sled_config)| { + if sled_config.zones.iter().any(|zone_config| { + matches!( + &zone_config.zone_type, + OmicronZoneType::CockroachDb { .. } + ) + }) { + Some(sled_address) + } else { + None + } + }) + .expect("Should not create service plans without CockroachDb"); let dur = std::time::Duration::from_secs(60); let client = reqwest::ClientBuilder::new() .connect_timeout(dur) @@ -925,7 +921,11 @@ impl ServiceInner { get_sled_address(initialization_request.subnet) }) .collect(); - let service_plan = if let Some(plan) = + // XXX-dap annoying that we need a `mut` service plan. it's just to + // update the generation numbers. It'd maybe better not to store those? + // XXX-dap will this work if we make it partway through and then + // crash? The next time we may try to put an earlier generation first + let mut service_plan = if let Some(plan) = ServicePlan::load(&self.log, storage_resources).await? { plan @@ -941,9 +941,11 @@ impl ServiceInner { // Set up internal DNS services first and write the initial // DNS configuration to the internal DNS servers. - let mut zone_types = HashSet::new(); - zone_types.insert(ZoneType::InternalDns); - self.ensure_all_services_of_type(&service_plan, &zone_types).await?; + let zone_filter1 = |zone_type: &OmicronZoneType| { + matches!(zone_type, OmicronZoneType::InternalDns { .. }) + }; + self.ensure_zones_of_type(&mut service_plan, &(zone_filter1.clone())) + .await?; self.initialize_internal_dns_records(&service_plan).await?; // Ask MGS in each switch zone which switch it is. @@ -954,8 +956,16 @@ impl ServiceInner { // Next start up the NTP services. // Note we also specify internal DNS services again because it // can ony be additive. - zone_types.insert(ZoneType::Ntp); - self.ensure_all_services_of_type(&service_plan, &zone_types).await?; + let zone_filter2 = |zone_type: &OmicronZoneType| { + zone_filter1(zone_type) + || matches!( + zone_type, + OmicronZoneType::BoundaryNtp { .. } + | OmicronZoneType::InternalNtp { .. } + ) + }; + self.ensure_zones_of_type(&mut service_plan, &(zone_filter2.clone())) + .await?; // Wait until time is synchronized on all sleds before proceeding. self.wait_for_timesync(&sled_addresses).await?; @@ -963,29 +973,29 @@ impl ServiceInner { info!(self.log, "Finished setting up Internal DNS and NTP"); // Wait until Cockroach has been initialized before running Nexus. - zone_types.insert(ZoneType::CockroachDb); - self.ensure_all_services_of_type(&service_plan, &zone_types).await?; + let zone_filter3 = |zone_type: &OmicronZoneType| { + zone_filter2(zone_type) + || matches!(zone_type, OmicronZoneType::CockroachDb { .. }) + }; + self.ensure_zones_of_type(&mut service_plan, &(zone_filter3.clone())) + .await?; // Now that datasets and zones have started for CockroachDB, // perform one-time initialization of the cluster. self.initialize_cockroach(&service_plan).await?; - // Issue service initialization requests. - futures::future::join_all(service_plan.services.iter().map( - |(sled_address, services_request)| async move { - // With the current implementation of "initialize_services_on_sled", - // we must provide the set of *all* services that should be - // executing on a sled. - // - // This means re-requesting the DNS and NTP services, even if - // they are already running - this is fine, however, as the - // receiving sled agent doesn't modify the already-running - // service. - self.initialize_services_on_sled( - *sled_address, - &services_request.services, - ) - .await?; + // Issue the rest of the zone initialization requests. + futures::future::join_all(service_plan.services.iter_mut().map( + |(sled_address, sled_config)| async move { + let generation = sled_config.next_generation; + sled_config.next_generation = + sled_config.next_generation.next(); + let zones_config = OmicronZonesConfig { + generation, + zones: sled_config.zones.clone(), + }; + self.initialize_zones_on_sled(*sled_address, &zones_config) + .await?; Ok(()) }, )) From 8ef6eb32c1b4ee7fc49e9917c10b0ff4d44ab888 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 9 Nov 2023 23:58:05 +0000 Subject: [PATCH 08/44] add XXX-dap --- sled-agent/src/rack_setup/plan/service.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index f754640e44..ee6b6a739e 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -1157,6 +1157,8 @@ mod tests { assert_eq!(internal_service_ips, expected_internal_service_ips); } + // XXX-dap I think we should remove this test? Do we really consider the + // RSS service plan stable? #[test] fn test_rss_service_plan_schema() { let schema = schemars::schema_for!(Plan); From c32320a7f5489d6e9ae8efc43148a4183b587f79 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Mon, 13 Nov 2023 22:31:40 +0000 Subject: [PATCH 09/44] fix test --- sled-agent/src/services.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 8a6ffc2e32..6f2d86e002 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -3729,8 +3729,8 @@ mod test { let ddmd_client = DdmAdminClient::localhost(&log).unwrap(); let bootstrap_networking = make_bootstrap_networking_config(); - // First, spin up a ServiceManager, create a new service, and tear it - // down. + // First, spin up a ServiceManager, create a new zone, and then tear + // down the ServiceManager. let resources = StorageResources::new_for_test(); let zone_bundler = ZoneBundler::new( log.clone(), @@ -3767,10 +3767,10 @@ mod test { ensure_new_service(&mgr, id).await; drop_service_manager(mgr); - // Next, delete the ledger. This means the service we just created will - // not be remembered on the next initialization. + // Next, delete the ledger. This means the zone we just created will not + // be remembered on the next initialization. std::fs::remove_file( - test_config.config_dir.path().join(SERVICES_LEDGER_FILENAME), + test_config.config_dir.path().join(ZONES_LEDGER_FILENAME), ) .unwrap(); From 4b040b844ae7faa1dee7416e8db4063e346d8aa4 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Mon, 13 Nov 2023 23:03:41 +0000 Subject: [PATCH 10/44] clippy nits --- sled-agent/src/params.rs | 2 +- sled-agent/src/rack_setup/service.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index cf761df60c..8a5ddcfde0 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -568,7 +568,7 @@ impl From for sled_agent_client::types::OmicronZoneConfig { fn from(local: OmicronZoneConfig) -> Self { Self { id: local.id, - underlay_address: local.underlay_address.into(), + underlay_address: local.underlay_address, zone_type: local.zone_type.into(), } } diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index a30c36ffe1..56d6840b30 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -64,9 +64,7 @@ use crate::bootstrap::params::BootstrapAddressDiscovery; use crate::bootstrap::params::StartSledAgentRequest; use crate::bootstrap::rss_handle::BootstrapAgentHandle; use crate::nexus::d2n_params; -use crate::params::{ - OmicronZoneConfig, OmicronZoneType, OmicronZonesConfig, TimeSync, -}; +use crate::params::{OmicronZoneType, OmicronZonesConfig, TimeSync}; use crate::rack_setup::plan::service::{ Plan as ServicePlan, PlanError as ServicePlanError, }; @@ -543,7 +541,7 @@ impl ServiceInner { for zone in &sled_config.zones { // XXX-dap TODO-cleanup kind of a cheating way to use the // existing implementation - let native_zone_config = OmicronZoneConfig::from(zone.clone()); + let native_zone_config = zone.clone(); if let Some((dataset_name, dataset_address)) = native_zone_config.dataset_name_and_address() { From ad002a38bdfb0fbf097a22277508bcbe8e51caf7 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Mon, 13 Nov 2023 23:58:00 +0000 Subject: [PATCH 11/44] WIP: replacing use of ServiceZoneRequest for switch zone --- sled-agent/src/params.rs | 41 +------- sled-agent/src/services.rs | 189 ++++++++++++++++++------------------- 2 files changed, 93 insertions(+), 137 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 8a5ddcfde0..9f83cd7f15 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -21,7 +21,6 @@ use omicron_common::api::internal::shared::{ }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use sled_hardware::Baseboard; pub use sled_hardware::DendriteAsic; use std::fmt::{Debug, Display, Formatter, Result as FormatResult}; use std::net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6}; @@ -317,37 +316,6 @@ pub enum ServiceType { Oximeter { address: SocketAddrV6, }, - // We should never receive external requests to start wicketd, MGS, sp-sim - // dendrite, tfport, or maghemite: these are all services running in the - // global zone or switch zone that we start autonomously. We tag them with - // `serde(skip)` both to omit them from our OpenAPI definition and to avoid - // needing their contained types to implement `JsonSchema + Deserialize + - // Serialize`. - #[serde(skip)] - ManagementGatewayService, - #[serde(skip)] - Wicketd { - baseboard: Baseboard, - }, - #[serde(skip)] - Dendrite { - asic: DendriteAsic, - }, - #[serde(skip)] - Tfport { - pkt_source: String, - asic: DendriteAsic, - }, - #[serde(skip)] - Uplink, - #[serde(skip)] - MgDdm { - mode: String, - }, - #[serde(skip)] - Mgd, - #[serde(skip)] - SpSim, CruciblePantry { address: SocketAddrV6, }, @@ -388,17 +356,10 @@ impl std::fmt::Display for ServiceType { ServiceType::ExternalDns { .. } => write!(f, "external_dns"), ServiceType::InternalDns { .. } => write!(f, "internal_dns"), ServiceType::Oximeter { .. } => write!(f, "oximeter"), - ServiceType::ManagementGatewayService => write!(f, "mgs"), - ServiceType::Wicketd { .. } => write!(f, "wicketd"), - ServiceType::Dendrite { .. } => write!(f, "dendrite"), - ServiceType::Tfport { .. } => write!(f, "tfport"), - ServiceType::Uplink { .. } => write!(f, "uplink"), ServiceType::CruciblePantry { .. } => write!(f, "crucible/pantry"), ServiceType::BoundaryNtp { .. } | ServiceType::InternalNtp { .. } => write!(f, "ntp"), - ServiceType::MgDdm { .. } => write!(f, "mg-ddm"), - ServiceType::Mgd => write!(f, "mgd"), - ServiceType::SpSim => write!(f, "sp-sim"), + ServiceType::Clickhouse { .. } => write!(f, "clickhouse"), ServiceType::ClickhouseKeeper { .. } => { write!(f, "clickhouse_keeper") diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 6f2d86e002..317f73de14 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -32,8 +32,8 @@ use crate::bootstrap::BootstrapNetworking; use crate::config::SidecarRevision; use crate::params::{ DendriteAsic, OmicronZoneConfig, OmicronZoneType, OmicronZonesConfig, - ServiceType, ServiceZoneRequest, ServiceZoneService, TimeSync, - ZoneBundleCause, ZoneBundleMetadata, ZoneType, + ServiceZoneRequest, TimeSync, ZoneBundleCause, ZoneBundleMetadata, + ZoneType, }; use crate::profile::*; use crate::smf_helper::Service; @@ -90,7 +90,6 @@ use omicron_common::nexus_config::{ }; use once_cell::sync::OnceCell; use rand::prelude::SliceRandom; -use rand::SeedableRng; use sled_hardware::disk::ZONE_DATASET; use sled_hardware::is_gimlet; use sled_hardware::underlay; @@ -350,12 +349,64 @@ impl ZonesConfig { } } +#[derive(Clone)] +struct SwitchZoneConfig { + id: Uuid, + addresses: Vec, + services: Vec, +} + +// XXX-dap towards the end, rename this to SwitchService. Saving it for later +// to avoid having to deal with it more than necessary in merge conflicts. +#[derive(Clone)] +enum ServiceType { + ManagementGatewayService, + Wicketd { baseboard: Baseboard }, + Dendrite { asic: DendriteAsic }, + Tfport { pkt_source: String, asic: DendriteAsic }, + Uplink, + MgDdm { mode: String }, + Mgd, + SpSim, +} + +impl crate::smf_helper::Service for ServiceType { + fn service_name(&self) -> String { + // XXX-dap came from `Display` and could be moved into that if it makes + // sense + match self { + ServiceType::ManagementGatewayService => "mgs", + ServiceType::Wicketd { .. } => "wicketd", + ServiceType::Dendrite { .. } => "dendrite", + ServiceType::Tfport { .. } => "tfport", + ServiceType::Uplink { .. } => "uplink", + ServiceType::MgDdm { .. } => "mg-ddm", + ServiceType::Mgd => "mgd", + ServiceType::SpSim => "sp-sim", + } + .to_owned() + } + fn smf_name(&self) -> String { + format!("svc:/oxide/{}", self.service_name()) + } + fn should_import(&self) -> bool { + true + } +} + +// XXX-dap needs better naming. Maybe we can even combine this with ZoneConfig +// / ZoneArgs? ZoneArgs is only used to differentiate two cases that now have +// either a SwitchZoneState (which is a SwitchZoneConfig + root) or a ZoneConfig +// (which is an OmicronZoneConfig plus a root). +struct SwitchZoneState { + zone: SwitchZoneConfig, + root: Utf8PathBuf, +} + // XXX-dap TODO-doc enum ZoneArgs<'a> { Omicron(&'a ZoneConfig), - - // XXX-dap make this a more specific struct - SledLocal(&'a ZoneRequestV1), + SledLocal(&'a SwitchZoneState), } impl<'a> ZoneArgs<'a> { @@ -372,7 +423,7 @@ impl<'a> ZoneArgs<'a> { match self { ZoneArgs::Omicron(_) => Box::new(std::iter::empty()), ZoneArgs::SledLocal(request) => { - Box::new(request.zone.services.iter().map(|s| &s.details)) + Box::new(request.zone.services.iter()) } } } @@ -410,7 +461,7 @@ enum SledLocalZone { // of certain links. Initializing { // The request for the zone - request: ServiceZoneRequest, + request: SwitchZoneConfig, // A background task which keeps looping until the zone is initialized worker: Option, // Filesystems for the switch zone to mount @@ -423,7 +474,7 @@ enum SledLocalZone { // The Zone is currently running. Running { // The original request for the zone - request: ServiceZoneRequest, + request: SwitchZoneConfig, // The currently running zone zone: RunningZone, }, @@ -779,18 +830,13 @@ impl ServiceManager { &self, zone_args: &ZoneArgs<'_>, ) -> Result, Error> { - if let ZoneArgs::SledLocal(req) = zone_args { - match req.zone.zone_type { - ZoneType::Switch => { - let link = self - .inner - .bootstrap_vnic_allocator - .new_bootstrap() - .map_err(Error::SledLocalVnicCreation)?; - Ok(Some((link, self.inner.switch_zone_bootstrap_address))) - } - _ => Ok(None), - } + if let ZoneArgs::SledLocal(_) = zone_args { + let link = self + .inner + .bootstrap_vnic_allocator + .new_bootstrap() + .map_err(Error::SledLocalVnicCreation)?; + Ok(Some((link, self.inner.switch_zone_bootstrap_address))) } else { Ok(None) } @@ -1040,8 +1086,14 @@ impl ServiceManager { needed.push("default".to_string()); needed.push("sys_dl_config".to_string()); } - ServiceType::BoundaryNtp { .. } - | ServiceType::InternalNtp { .. } => { + _ => (), + } + } + + if let Some(omicron_zone_type) = zone_args.omicron_type() { + match omicron_zone_type { + OmicronZoneType::BoundaryNtp { .. } + | OmicronZoneType::InternalNtp { .. } => { needed.push("default".to_string()); needed.push("sys_time".to_string()); needed.push("proc_priocntl".to_string()); @@ -1210,7 +1262,7 @@ impl ServiceManager { ZoneArgs::Omicron(zone_config) => { zone_config.zone.zone_type.zone_type_str().to_owned() } - ZoneArgs::SledLocal(req) => req.zone.zone_type.to_string(), + ZoneArgs::SledLocal(_) => "switch".to_string(), }; let installed_zone = InstalledZone::install( &self.inner.log, @@ -1899,10 +1951,10 @@ impl ServiceManager { // avoid importing this manifest? debug!(self.inner.log, "importing manifest"); - let smfh = SmfHelper::new(&running_zone, &service.details); + let smfh = SmfHelper::new(&running_zone, service); smfh.import_manifest()?; - match &service.details { + match service { ServiceType::ManagementGatewayService => { info!(self.inner.log, "Setting up MGS service"); smfh.setprop("config/id", request.zone.id)?; @@ -2278,24 +2330,6 @@ impl ServiceManager { smfh.refresh()?; } - - ServiceType::Nexus { .. } - | ServiceType::Oximeter { .. } - | ServiceType::BoundaryNtp { .. } - | ServiceType::InternalNtp { .. } - | ServiceType::ExternalDns { .. } - | ServiceType::InternalDns { .. } - | ServiceType::CockroachDb { .. } - | ServiceType::Crucible { .. } - | ServiceType::CruciblePantry { .. } - | ServiceType::Clickhouse { .. } - | ServiceType::ClickhouseKeeper { .. } => { - panic!( - "unexpected service type for sled-local \ - zone: {:?}", - service.details - ); - } } debug!(self.inner.log, "enabling service"); @@ -2887,19 +2921,10 @@ impl ServiceManager { if let Some((ip, _)) = underlay_info { vec![ip] } else { vec![] }; addresses.push(Ipv6Addr::LOCALHOST); - let request = ServiceZoneRequest { - id: Uuid::new_v4(), - zone_type: ZoneType::Switch, - addresses, - dataset: None, - services: services - .into_iter() - .map(|s| ServiceZoneService { id: Uuid::new_v4(), details: s }) - .collect(), - }; + let request = + SwitchZoneConfig { id: Uuid::new_v4(), addresses, services }; self.ensure_zone( - ZoneType::Switch, // request= Some(request), // filesystems= @@ -2992,7 +3017,6 @@ impl ServiceManager { /// Ensures that no switch zone is active. pub async fn deactivate_switch(&self) -> Result<(), Error> { self.ensure_zone( - ZoneType::Switch, // request= None, // filesystems= @@ -3009,12 +3033,11 @@ impl ServiceManager { fn start_zone( self, zone: &mut SledLocalZone, - request: ServiceZoneRequest, + request: SwitchZoneConfig, filesystems: Vec, data_links: Vec, ) { let (exit_tx, exit_rx) = oneshot::channel(); - let zone_type = request.zone_type.clone(); *zone = SledLocalZone::Initializing { request, filesystems, @@ -3022,7 +3045,7 @@ impl ServiceManager { worker: Some(Task { exit_tx, initializer: tokio::task::spawn(async move { - self.initialize_zone_loop(zone_type, exit_rx).await + self.initialize_zone_loop(exit_rx).await }), }), }; @@ -3031,21 +3054,14 @@ impl ServiceManager { // Moves the current state to align with the "request". async fn ensure_zone( &self, - zone_type: ZoneType, - request: Option, + request: Option, filesystems: Vec, data_links: Vec, ) -> Result<(), Error> { let log = &self.inner.log; - let mut sled_zone; - match zone_type { - ZoneType::Switch => { - sled_zone = self.inner.switch_zone.lock().await; - } - _ => panic!("Unhandled zone type"), - } - let zone_typestr = zone_type.to_string(); + let mut sled_zone = self.inner.switch_zone.lock().await; + let zone_typestr = "switch"; match (&mut *sled_zone, request) { (SledLocalZone::Disabled, Some(request)) => { @@ -3114,9 +3130,9 @@ impl ServiceManager { } for service in &request.services { - let smfh = SmfHelper::new(&zone, &service.details); + let smfh = SmfHelper::new(&zone, service); - match &service.details { + match service { ServiceType::ManagementGatewayService => { // Remove any existing `config/address` values // without deleting the property itself. @@ -3267,19 +3283,8 @@ impl ServiceManager { // switch zone were on a U.2 device we would not be able to run RSS, as // we could not create the U.2 disks due to lack of encryption. To break // the cycle we put the switch zone root fs on the ramdisk. - let root = if request.zone_type == ZoneType::Switch { - Utf8PathBuf::from(ZONE_ZFS_RAMDISK_DATASET_MOUNTPOINT) - } else { - let all_u2_roots = - self.inner.storage.all_u2_mountpoints(ZONE_DATASET).await; - let mut rng = rand::rngs::StdRng::from_entropy(); - all_u2_roots - .choose(&mut rng) - .ok_or_else(|| Error::U2NotFound)? - .clone() - }; - - let zone_request = ZoneRequestV1 { root, zone: request.clone() }; + let root = Utf8PathBuf::from(ZONE_ZFS_RAMDISK_DATASET_MOUNTPOINT); + let zone_request = SwitchZoneState { root, zone: request.clone() }; let zone_args = ZoneArgs::SledLocal(&zone_request); let zone = self.initialize_zone(zone_args, filesystems, data_links).await?; @@ -3289,26 +3294,16 @@ impl ServiceManager { // Body of a tokio task responsible for running until the switch zone is // inititalized, or it has been told to stop. - async fn initialize_zone_loop( - &self, - zone_type: ZoneType, - mut exit_rx: oneshot::Receiver<()>, - ) { + async fn initialize_zone_loop(&self, mut exit_rx: oneshot::Receiver<()>) { loop { { - let mut sled_zone; - match zone_type { - ZoneType::Switch => { - sled_zone = self.inner.switch_zone.lock().await; - } - _ => panic!("Unhandled zone type"), - } + let mut sled_zone = self.inner.switch_zone.lock().await; match self.try_initialize_sled_local_zone(&mut sled_zone).await { Ok(()) => return, Err(e) => warn!( self.inner.log, - "Failed to initialize {zone_type}: {e}" + "Failed to initialize switch zone: {e}" ), } } From cb1c66d82f25a92edb859db9c4f6314595128968 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Tue, 14 Nov 2023 00:00:43 +0000 Subject: [PATCH 12/44] clean up some names --- sled-agent/src/services.rs | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 317f73de14..f37deb95f3 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -312,7 +312,7 @@ struct ZoneRequestV1 { // XXX-dap TODO-doc and maybe rename it? #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -struct ZoneConfig { +struct OmicronZoneConfigComplete { zone: OmicronZoneConfig, // TODO: Consider collapsing "root" into OmicronZoneConfig? #[schemars(with = "String")] @@ -326,7 +326,7 @@ const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] struct ZonesConfig { generation: Generation, - zones: Vec, + zones: Vec, } impl Ledgerable for ZonesConfig { @@ -372,8 +372,6 @@ enum ServiceType { impl crate::smf_helper::Service for ServiceType { fn service_name(&self) -> String { - // XXX-dap came from `Display` and could be moved into that if it makes - // sense match self { ServiceType::ManagementGatewayService => "mgs", ServiceType::Wicketd { .. } => "wicketd", @@ -394,19 +392,15 @@ impl crate::smf_helper::Service for ServiceType { } } -// XXX-dap needs better naming. Maybe we can even combine this with ZoneConfig -// / ZoneArgs? ZoneArgs is only used to differentiate two cases that now have -// either a SwitchZoneState (which is a SwitchZoneConfig + root) or a ZoneConfig -// (which is an OmicronZoneConfig plus a root). -struct SwitchZoneState { +struct SwitchZoneConfigComplete { zone: SwitchZoneConfig, root: Utf8PathBuf, } // XXX-dap TODO-doc enum ZoneArgs<'a> { - Omicron(&'a ZoneConfig), - SledLocal(&'a SwitchZoneState), + Omicron(&'a OmicronZoneConfigComplete), + SledLocal(&'a SwitchZoneConfigComplete), } impl<'a> ZoneArgs<'a> { @@ -1287,7 +1281,7 @@ impl ServiceManager { // These zones are self-assembling -- after they boot, there should // be no "zlogin" necessary to initialize. match &request { - ZoneArgs::Omicron(ZoneConfig { + ZoneArgs::Omicron(OmicronZoneConfigComplete { zone: OmicronZoneConfig { zone_type: OmicronZoneType::Clickhouse { .. }, @@ -1331,7 +1325,7 @@ impl ServiceManager { return Ok(RunningZone::boot(installed_zone).await?); } - ZoneArgs::Omicron(ZoneConfig { + ZoneArgs::Omicron(OmicronZoneConfigComplete { zone: OmicronZoneConfig { zone_type: OmicronZoneType::ClickhouseKeeper { .. }, @@ -1378,7 +1372,7 @@ impl ServiceManager { return Ok(RunningZone::boot(installed_zone).await?); } - ZoneArgs::Omicron(ZoneConfig { + ZoneArgs::Omicron(OmicronZoneConfigComplete { zone: OmicronZoneConfig { zone_type: OmicronZoneType::CockroachDb { .. }, @@ -1427,7 +1421,7 @@ impl ServiceManager { return Ok(RunningZone::boot(installed_zone).await?); } - ZoneArgs::Omicron(ZoneConfig { + ZoneArgs::Omicron(OmicronZoneConfigComplete { zone: zone @ OmicronZoneConfig { zone_type: OmicronZoneType::Crucible { .. }, @@ -1470,7 +1464,7 @@ impl ServiceManager { return Ok(RunningZone::boot(installed_zone).await?); } - ZoneArgs::Omicron(ZoneConfig { + ZoneArgs::Omicron(OmicronZoneConfigComplete { zone: OmicronZoneConfig { zone_type: OmicronZoneType::CruciblePantry { .. }, @@ -1560,7 +1554,7 @@ impl ServiceManager { } let addresses = match &request { - ZoneArgs::Omicron(ZoneConfig { + ZoneArgs::Omicron(OmicronZoneConfigComplete { zone: OmicronZoneConfig { underlay_address, .. }, .. }) => vec![*underlay_address], @@ -2345,7 +2339,7 @@ impl ServiceManager { async fn initialize_omicron_zones_locked( &self, existing_zones: &mut BTreeMap, - requests: &Vec, + requests: &Vec, ) -> Result<(), Error> { if let Some(name) = requests .iter() @@ -2623,7 +2617,7 @@ impl ServiceManager { .ok_or_else(|| Error::U2NotFound)? .clone(); - new_zones.push(ZoneConfig { zone: zone.clone(), root }); + new_zones.push(OmicronZoneConfigComplete { zone: zone.clone(), root }); } self.initialize_omicron_zones_locked(existing_zones, &new_zones) @@ -3284,7 +3278,7 @@ impl ServiceManager { // we could not create the U.2 disks due to lack of encryption. To break // the cycle we put the switch zone root fs on the ramdisk. let root = Utf8PathBuf::from(ZONE_ZFS_RAMDISK_DATASET_MOUNTPOINT); - let zone_request = SwitchZoneState { root, zone: request.clone() }; + let zone_request = SwitchZoneConfigComplete { root, zone: request.clone() }; let zone_args = ZoneArgs::SledLocal(&zone_request); let zone = self.initialize_zone(zone_args, filesystems, data_links).await?; From 1e671b45824677735063495122c1d2b7029d9038 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Tue, 14 Nov 2023 00:07:25 +0000 Subject: [PATCH 13/44] clean up one nit --- sled-agent/src/params.rs | 1 - sled-agent/src/services.rs | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 9f83cd7f15..bb5964700f 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -752,7 +752,6 @@ impl From for sled_agent_client::types::OmicronZoneDataset { /// /// XXX-dap ideally this would not be necessary at all! Sled Agent shouldn't /// have to know about the things running on it, I think? -/// XXX-dap commonize with ServiceType (well, probably remove ServiceType) #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index f37deb95f3..b8af3395c9 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -109,7 +109,6 @@ use std::time::{SystemTime, UNIX_EPOCH}; use tokio::io::AsyncWriteExt; use tokio::sync::oneshot; use tokio::sync::Mutex; -use tokio::sync::MutexGuard; use tokio::task::JoinHandle; use uuid::Uuid; @@ -666,8 +665,8 @@ impl ServiceManager { // Initialize NTP services next as they are required for time // synchronization, which is a pre-requisite for the other services. We - // keep `ZoneType::InternalDns` because `ensure_all_omicron_zones` is - // additive. + // keep `OmicronZoneType::InternalDns` because + // `ensure_all_omicron_zones` is additive. // XXX-dap This looks like a duplicate of the block above -- why do we // do this? let all_zones_request = self @@ -2511,8 +2510,7 @@ impl ServiceManager { // re-instantiated on boot. async fn ensure_all_omicron_zones( &self, - // XXX-dap drop MutexGuard part - existing_zones: &mut MutexGuard<'_, BTreeMap>, + existing_zones: &mut BTreeMap, old_config: Option<&ZonesConfig>, new_request: OmicronZonesConfig, filter: F, @@ -2617,7 +2615,8 @@ impl ServiceManager { .ok_or_else(|| Error::U2NotFound)? .clone(); - new_zones.push(OmicronZoneConfigComplete { zone: zone.clone(), root }); + new_zones + .push(OmicronZoneConfigComplete { zone: zone.clone(), root }); } self.initialize_omicron_zones_locked(existing_zones, &new_zones) @@ -3278,7 +3277,8 @@ impl ServiceManager { // we could not create the U.2 disks due to lack of encryption. To break // the cycle we put the switch zone root fs on the ramdisk. let root = Utf8PathBuf::from(ZONE_ZFS_RAMDISK_DATASET_MOUNTPOINT); - let zone_request = SwitchZoneConfigComplete { root, zone: request.clone() }; + let zone_request = + SwitchZoneConfigComplete { root, zone: request.clone() }; let zone_args = ZoneArgs::SledLocal(&zone_request); let zone = self.initialize_zone(zone_args, filesystems, data_links).await?; From fe72a7d3dbc9a4850ebc4098c296f7cd155c9554 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Tue, 14 Nov 2023 00:21:51 +0000 Subject: [PATCH 14/44] WIP: moving "legacy" service types into a separate module --- sled-agent/src/lib.rs | 1 + sled-agent/src/params.rs | 182 -------------------- sled-agent/src/services.rs | 74 ++------ sled-agent/src/services_migration.rs | 241 +++++++++++++++++++++++++++ 4 files changed, 256 insertions(+), 242 deletions(-) create mode 100644 sled-agent/src/services_migration.rs diff --git a/sled-agent/src/lib.rs b/sled-agent/src/lib.rs index 4e7921c605..b4d2fd4366 100644 --- a/sled-agent/src/lib.rs +++ b/sled-agent/src/lib.rs @@ -29,6 +29,7 @@ mod profile; pub mod rack_setup; pub mod server; mod services; +mod services_migration; mod sled_agent; mod smf_helper; pub(crate) mod storage; diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index bb5964700f..5e62ca20bc 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -274,114 +274,6 @@ impl std::fmt::Display for DatasetKind { } } -/// Describes service-specific parameters. -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -#[serde(tag = "type", rename_all = "snake_case")] -pub 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, - }, -} - -impl std::fmt::Display for ServiceType { - fn fmt(&self, f: &mut Formatter<'_>) -> FormatResult { - match self { - ServiceType::Nexus { .. } => write!(f, "nexus"), - ServiceType::ExternalDns { .. } => write!(f, "external_dns"), - ServiceType::InternalDns { .. } => write!(f, "internal_dns"), - ServiceType::Oximeter { .. } => write!(f, "oximeter"), - ServiceType::CruciblePantry { .. } => write!(f, "crucible/pantry"), - ServiceType::BoundaryNtp { .. } - | ServiceType::InternalNtp { .. } => write!(f, "ntp"), - - ServiceType::Clickhouse { .. } => write!(f, "clickhouse"), - ServiceType::ClickhouseKeeper { .. } => { - write!(f, "clickhouse_keeper") - } - ServiceType::CockroachDb { .. } => write!(f, "cockroachdb"), - ServiceType::Crucible { .. } => write!(f, "crucible"), - } - } -} - -impl crate::smf_helper::Service for ServiceType { - fn service_name(&self) -> String { - self.to_string() - } - fn smf_name(&self) -> String { - format!("svc:/oxide/{}", self.service_name()) - } - fn should_import(&self) -> bool { - true - } -} - // XXX-dap do a pass over this file to see which of these types can be removed // altogether. Those only needed for migration could go into a separate module. /// The type of zone which may be requested from Sled Agent @@ -423,80 +315,6 @@ impl std::fmt::Display for ZoneType { } } -/// Describes a request to provision a specific dataset -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -pub struct DatasetRequest { - pub id: Uuid, - pub name: crate::storage::dataset::DatasetName, - pub service_address: SocketAddrV6, -} - -/// Describes a request to create a zone running one or more services. -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -pub struct ServiceZoneRequest { - // The UUID of the zone to be initialized. - // TODO: Should this be removed? If we have UUIDs on the services, what's - // the point of this? - pub id: Uuid, - // The type of the zone to be created. - pub zone_type: ZoneType, - // The addresses on which the service should listen for requests. - pub addresses: Vec, - // Datasets which should be managed by this service. - #[serde(default)] - pub dataset: Option, - // Services that should be run in the zone - pub services: Vec, -} - -impl ServiceZoneRequest { - // The full name of the zone, if it was to be created as a zone. - pub fn zone_name(&self) -> String { - illumos_utils::running_zone::InstalledZone::get_zone_name( - &self.zone_type.to_string(), - self.zone_name_unique_identifier(), - ) - } - - // The name of a unique identifier for the zone, if one is necessary. - pub fn zone_name_unique_identifier(&self) -> Option { - match &self.zone_type { - // The switch zone is necessarily a singleton. - ZoneType::Switch => None, - // All other zones should be identified by their zone UUID. - ZoneType::Clickhouse - | ZoneType::ClickhouseKeeper - | ZoneType::CockroachDb - | ZoneType::Crucible - | ZoneType::ExternalDns - | ZoneType::InternalDns - | ZoneType::Nexus - | ZoneType::CruciblePantry - | ZoneType::Ntp - | ZoneType::Oximeter => Some(self.id), - } - } -} - -/// Used to request that the Sled initialize a single service. -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -pub struct ServiceZoneService { - pub id: Uuid, - pub details: ServiceType, -} - -/// Used to request that the Sled initialize multiple services. -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] -pub struct ServiceEnsureBody { - pub services: Vec, -} - /// Describes the set of Omicron zones running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index b8af3395c9..542e988c40 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -32,7 +32,7 @@ use crate::bootstrap::BootstrapNetworking; use crate::config::SidecarRevision; use crate::params::{ DendriteAsic, OmicronZoneConfig, OmicronZoneType, OmicronZonesConfig, - ServiceZoneRequest, TimeSync, ZoneBundleCause, ZoneBundleMetadata, + TimeSync, ZoneBundleCause, ZoneBundleMetadata, ZoneType, }; use crate::profile::*; @@ -271,44 +271,6 @@ impl Config { } } -// The filename of the ledger, within the provided directory. -const SERVICES_LEDGER_FILENAME: &str = "services.json"; - -// A wrapper around `ZoneRequest`, which allows it to be serialized -// to a JSON file. -// XXX-dap TODO-doc -#[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -struct AllZoneRequestsV1 { - generation: Generation, - requests: Vec, -} - -impl Default for AllZoneRequestsV1 { - fn default() -> Self { - Self { generation: Generation::new(), requests: vec![] } - } -} - -impl Ledgerable for AllZoneRequestsV1 { - fn is_newer_than(&self, other: &AllZoneRequestsV1) -> bool { - self.generation >= other.generation - } - - fn generation_bump(&mut self) { - self.generation = self.generation.next(); - } -} - -// 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 ZoneRequestV1 { - zone: ServiceZoneRequest, - // TODO: Consider collapsing "root" into ServiceZoneRequest - #[schemars(with = "String")] - root: Utf8PathBuf, -} - // XXX-dap TODO-doc and maybe rename it? #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] struct OmicronZoneConfigComplete { @@ -591,18 +553,19 @@ impl ServiceManager { self.inner.switch_zone_bootstrap_address } - async fn all_service_ledgers(&self) -> Vec { - if let Some(dir) = self.inner.ledger_directory_override.get() { - return vec![dir.join(SERVICES_LEDGER_FILENAME)]; - } - self.inner - .storage - .all_m2_mountpoints(sled_hardware::disk::CONFIG_DATASET) - .await - .into_iter() - .map(|p| p.join(SERVICES_LEDGER_FILENAME)) - .collect() - } + // XXX-dap + // async fn all_service_ledgers(&self) -> Vec { + // if let Some(dir) = self.inner.ledger_directory_override.get() { + // return vec![dir.join(SERVICES_LEDGER_FILENAME)]; + // } + // self.inner + // .storage + // .all_m2_mountpoints(sled_hardware::disk::CONFIG_DATASET) + // .await + // .into_iter() + // .map(|p| p.join(SERVICES_LEDGER_FILENAME)) + // .collect() + // } async fn all_omicron_zone_ledgers(&self) -> Vec { if let Some(dir) = self.inner.ledger_directory_override.get() { @@ -3808,15 +3771,6 @@ mod test { assert_eq!(prefix1.segments()[0], 0xfdb2); } - #[test] - fn test_all_zone_requests_schema() { - let schema = schemars::schema_for!(AllZoneRequestsV1); - expectorate::assert_contents( - "../schema/all-zone-requests.json", - &serde_json::to_string_pretty(&schema).unwrap(), - ); - } - #[test] fn test_zone_bundle_metadata_schema() { let schema = schemars::schema_for!(ZoneBundleMetadata); diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs new file mode 100644 index 0000000000..32fb6637e6 --- /dev/null +++ b/sled-agent/src/services_migration.rs @@ -0,0 +1,241 @@ +// 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/. + +//! XXX-dap TODO-doc this is probably where we could use a big block comment +//! explaining the big picture here + +use crate::params::ZoneType; +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 std::fmt::{Debug, Formatter, Result as FormatResult}; +use std::net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6}; +use uuid::Uuid; + +/// Describes a request to create a zone running one or more services. +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, +)] +pub struct ServiceZoneRequest { + // The UUID of the zone to be initialized. + // TODO: Should this be removed? If we have UUIDs on the services, what's + // the point of this? + pub id: Uuid, + // The type of the zone to be created. + pub zone_type: ZoneType, + // The addresses on which the service should listen for requests. + pub addresses: Vec, + // Datasets which should be managed by this service. + #[serde(default)] + pub dataset: Option, + // Services that should be run in the zone + pub services: Vec, +} + +impl ServiceZoneRequest { + // The full name of the zone, if it was to be created as a zone. + pub fn zone_name(&self) -> String { + illumos_utils::running_zone::InstalledZone::get_zone_name( + &self.zone_type.to_string(), + self.zone_name_unique_identifier(), + ) + } + + // The name of a unique identifier for the zone, if one is necessary. + pub fn zone_name_unique_identifier(&self) -> Option { + match &self.zone_type { + // The switch zone is necessarily a singleton. + ZoneType::Switch => None, + // All other zones should be identified by their zone UUID. + ZoneType::Clickhouse + | ZoneType::ClickhouseKeeper + | ZoneType::CockroachDb + | ZoneType::Crucible + | ZoneType::ExternalDns + | ZoneType::InternalDns + | ZoneType::Nexus + | ZoneType::CruciblePantry + | ZoneType::Ntp + | ZoneType::Oximeter => Some(self.id), + } + } +} + +/// Used to request that the Sled initialize a single service. +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, +)] +pub struct ServiceZoneService { + pub id: Uuid, + pub details: ServiceType, +} + +/// Describes service-specific parameters. +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, +)] +#[serde(tag = "type", rename_all = "snake_case")] +pub 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, + }, +} + +impl std::fmt::Display for ServiceType { + fn fmt(&self, f: &mut Formatter<'_>) -> FormatResult { + match self { + ServiceType::Nexus { .. } => write!(f, "nexus"), + ServiceType::ExternalDns { .. } => write!(f, "external_dns"), + ServiceType::InternalDns { .. } => write!(f, "internal_dns"), + ServiceType::Oximeter { .. } => write!(f, "oximeter"), + ServiceType::CruciblePantry { .. } => write!(f, "crucible/pantry"), + ServiceType::BoundaryNtp { .. } + | ServiceType::InternalNtp { .. } => write!(f, "ntp"), + + ServiceType::Clickhouse { .. } => write!(f, "clickhouse"), + ServiceType::ClickhouseKeeper { .. } => { + write!(f, "clickhouse_keeper") + } + ServiceType::CockroachDb { .. } => write!(f, "cockroachdb"), + ServiceType::Crucible { .. } => write!(f, "crucible"), + } + } +} + +/// Used to request that the Sled initialize multiple services. +#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] +pub struct ServiceEnsureBody { + pub services: Vec, +} + +/// Describes a request to provision a specific dataset +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, +)] +pub struct DatasetRequest { + pub id: Uuid, + pub name: crate::storage::dataset::DatasetName, + pub service_address: SocketAddrV6, +} + +// 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 ZoneRequestV1 { + zone: ServiceZoneRequest, + // TODO: Consider collapsing "root" into ServiceZoneRequest + #[schemars(with = "String")] + root: Utf8PathBuf, +} + +// The filename of the ledger, within the provided directory. +const SERVICES_LEDGER_FILENAME: &str = "services.json"; + +// A wrapper around `ZoneRequest`, which allows it to be serialized +// to a JSON file. +// XXX-dap TODO-doc +#[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] +struct AllZoneRequestsV1 { + generation: Generation, + requests: Vec, +} + +impl Default for AllZoneRequestsV1 { + fn default() -> Self { + Self { generation: Generation::new(), requests: vec![] } + } +} + +impl Ledgerable for AllZoneRequestsV1 { + fn is_newer_than(&self, other: &AllZoneRequestsV1) -> bool { + self.generation >= other.generation + } + + fn generation_bump(&mut self) { + self.generation = self.generation.next(); + } +} + +#[cfg(test)] +mod test { + use super::AllZoneRequestsV1; + + #[test] + fn test_all_zone_requests_schema() { + let schema = schemars::schema_for!(AllZoneRequestsV1); + expectorate::assert_contents( + "../schema/all-zone-requests.json", + &serde_json::to_string_pretty(&schema).unwrap(), + ); + } +} From 7da2d02a5601355bde43b4012016d066b3c169b6 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Tue, 14 Nov 2023 21:38:43 +0000 Subject: [PATCH 15/44] WIP: more legacy migration --- sled-agent/src/params.rs | 75 ++++--- sled-agent/src/services.rs | 49 +++-- sled-agent/src/services_migration.rs | 315 ++++++++++++++++++++++++++- 3 files changed, 375 insertions(+), 64 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 5e62ca20bc..42c4d4c77e 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -358,42 +358,13 @@ impl OmicronZoneConfig { // eliminates one reason why Sled Agent needs to know about what kind of // dataset it's looking at. pub fn dataset_name(&self) -> Option { - self.dataset_name_and_address().map(|d| d.0) + self.zone_type.dataset_name() } pub fn dataset_name_and_address( &self, ) -> Option<(DatasetName, SocketAddrV6)> { - let (dataset, dataset_kind, address) = match &self.zone_type { - OmicronZoneType::BoundaryNtp { .. } - | OmicronZoneType::InternalNtp { .. } - | OmicronZoneType::Nexus { .. } - | OmicronZoneType::Oximeter { .. } - | OmicronZoneType::CruciblePantry { .. } => None, - OmicronZoneType::Clickhouse { dataset, address, .. } => { - Some((dataset, DatasetKind::Clickhouse, address)) - } - OmicronZoneType::ClickhouseKeeper { dataset, address, .. } => { - Some((dataset, DatasetKind::ClickhouseKeeper, address)) - } - OmicronZoneType::CockroachDb { dataset, address, .. } => { - Some((dataset, DatasetKind::CockroachDb, address)) - } - OmicronZoneType::Crucible { dataset, address, .. } => { - Some((dataset, DatasetKind::Crucible, address)) - } - OmicronZoneType::ExternalDns { dataset, http_address, .. } => { - Some((dataset, DatasetKind::ExternalDns, http_address)) - } - OmicronZoneType::InternalDns { dataset, http_address, .. } => { - Some((dataset, DatasetKind::InternalDns, http_address)) - } - }?; - - Some(( - DatasetName::new(dataset.pool_name.clone(), dataset_kind), - *address, - )) + self.zone_type.dataset_name_and_address() } // XXX-dap TODO-doc @@ -673,6 +644,48 @@ impl OmicronZoneType { OmicronZoneType::Oximeter { .. } => "oximeter", } } + + // XXX-dap should the caller (RSS) should specify this directly? That + // eliminates one reason why Sled Agent needs to know about what kind of + // dataset it's looking at. + pub fn dataset_name(&self) -> Option { + self.dataset_name_and_address().map(|d| d.0) + } + + pub fn dataset_name_and_address( + &self, + ) -> Option<(DatasetName, SocketAddrV6)> { + let (dataset, dataset_kind, address) = match self { + OmicronZoneType::BoundaryNtp { .. } + | OmicronZoneType::InternalNtp { .. } + | OmicronZoneType::Nexus { .. } + | OmicronZoneType::Oximeter { .. } + | OmicronZoneType::CruciblePantry { .. } => None, + OmicronZoneType::Clickhouse { dataset, address, .. } => { + Some((dataset, DatasetKind::Clickhouse, address)) + } + OmicronZoneType::ClickhouseKeeper { dataset, address, .. } => { + Some((dataset, DatasetKind::ClickhouseKeeper, address)) + } + OmicronZoneType::CockroachDb { dataset, address, .. } => { + Some((dataset, DatasetKind::CockroachDb, address)) + } + OmicronZoneType::Crucible { dataset, address, .. } => { + Some((dataset, DatasetKind::Crucible, address)) + } + OmicronZoneType::ExternalDns { dataset, http_address, .. } => { + Some((dataset, DatasetKind::ExternalDns, http_address)) + } + OmicronZoneType::InternalDns { dataset, http_address, .. } => { + Some((dataset, DatasetKind::InternalDns, http_address)) + } + }?; + + Some(( + DatasetName::new(dataset.pool_name.clone(), dataset_kind), + *address, + )) + } } impl crate::smf_helper::Service for OmicronZoneType { diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 542e988c40..030d967d3d 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -32,10 +32,10 @@ use crate::bootstrap::BootstrapNetworking; use crate::config::SidecarRevision; use crate::params::{ DendriteAsic, OmicronZoneConfig, OmicronZoneType, OmicronZonesConfig, - TimeSync, ZoneBundleCause, ZoneBundleMetadata, - ZoneType, + TimeSync, ZoneBundleCause, ZoneBundleMetadata, ZoneType, }; use crate::profile::*; +use crate::services_migration::SERVICES_LEDGER_FILENAME; use crate::smf_helper::Service; use crate::smf_helper::SmfHelper; use crate::storage_manager::StorageResources; @@ -273,21 +273,22 @@ impl Config { // XXX-dap TODO-doc and maybe rename it? #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -struct OmicronZoneConfigComplete { - zone: OmicronZoneConfig, +pub struct OmicronZoneConfigComplete { + pub zone: OmicronZoneConfig, // TODO: Consider collapsing "root" into OmicronZoneConfig? #[schemars(with = "String")] - root: Utf8PathBuf, + pub root: Utf8PathBuf, } // The filename of the ledger, within the provided directory. const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; // XXX-dap TODO-doc +// XXX-dap could be OmicronZonesConfigComplete? OmicronZonesConfigLocal? #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -struct ZonesConfig { - generation: Generation, - zones: Vec, +pub struct ZonesConfig { + pub generation: Generation, + pub zones: Vec, } impl Ledgerable for ZonesConfig { @@ -296,7 +297,12 @@ impl Ledgerable for ZonesConfig { } fn generation_bump(&mut self) { - // XXX-dap what do we do here? this is not right. + // XXX-dap what do we do here? this is not right. The only one who + // can bump this is Nexus. Maybe we just keep it as is? + // + // This gets invoked when the ledger is committed. I think we could + // either keep a separate generation number (and use that in + // `is_newer_than()`) or else make this a noop? self.generation = self.generation.next(); } } @@ -553,19 +559,18 @@ impl ServiceManager { self.inner.switch_zone_bootstrap_address } - // XXX-dap - // async fn all_service_ledgers(&self) -> Vec { - // if let Some(dir) = self.inner.ledger_directory_override.get() { - // return vec![dir.join(SERVICES_LEDGER_FILENAME)]; - // } - // self.inner - // .storage - // .all_m2_mountpoints(sled_hardware::disk::CONFIG_DATASET) - // .await - // .into_iter() - // .map(|p| p.join(SERVICES_LEDGER_FILENAME)) - // .collect() - // } + async fn all_service_ledgers(&self) -> Vec { + if let Some(dir) = self.inner.ledger_directory_override.get() { + return vec![dir.join(SERVICES_LEDGER_FILENAME)]; + } + self.inner + .storage + .all_m2_mountpoints(sled_hardware::disk::CONFIG_DATASET) + .await + .into_iter() + .map(|p| p.join(SERVICES_LEDGER_FILENAME)) + .collect() + } async fn all_omicron_zone_ledgers(&self) -> Vec { if let Some(dir) = self.inner.ledger_directory_override.get() { diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index 32fb6637e6..21232f8116 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -5,7 +5,12 @@ //! XXX-dap TODO-doc this is probably where we could use a big block comment //! explaining the big picture here -use crate::params::ZoneType; +use crate::params::{ + DatasetKind, OmicronZoneConfig, OmicronZoneDataset, OmicronZoneType, + ZoneType, +}; +use crate::services::{OmicronZoneConfigComplete, ZonesConfig}; +use anyhow::{anyhow, ensure, Context}; use camino::Utf8PathBuf; use omicron_common::api::external::Generation; use omicron_common::api::internal::shared::{ @@ -188,10 +193,35 @@ pub struct DatasetRequest { pub 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() }) + } +} + // 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 ZoneRequestV1 { +struct ServiceRequest { zone: ServiceZoneRequest, // TODO: Consider collapsing "root" into ServiceZoneRequest #[schemars(with = "String")] @@ -199,25 +229,25 @@ struct ZoneRequestV1 { } // The filename of the ledger, within the provided directory. -const SERVICES_LEDGER_FILENAME: &str = "services.json"; +pub const SERVICES_LEDGER_FILENAME: &str = "services.json"; // A wrapper around `ZoneRequest`, which allows it to be serialized // to a JSON file. // XXX-dap TODO-doc #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -struct AllZoneRequestsV1 { +pub struct AllServiceRequests { generation: Generation, - requests: Vec, + requests: Vec, } -impl Default for AllZoneRequestsV1 { +impl Default for AllServiceRequests { fn default() -> Self { Self { generation: Generation::new(), requests: vec![] } } } -impl Ledgerable for AllZoneRequestsV1 { - fn is_newer_than(&self, other: &AllZoneRequestsV1) -> bool { +impl Ledgerable for AllServiceRequests { + fn is_newer_than(&self, other: &AllServiceRequests) -> bool { self.generation >= other.generation } @@ -226,13 +256,276 @@ impl Ledgerable for AllZoneRequestsV1 { } } +impl TryFrom for ZonesConfig { + type Error = anyhow::Error; + + fn try_from(input: AllServiceRequests) -> Result { + // XXX-dap starting to think that the generation in OmicronZonesConfig + // (at least the one stored on disk) ought to be an Option or something? + // There's no correct value here. Any Nexus one needs to be treated as + // newer. The generation from the ledger does not matter. + // XXX-dap TODO-doc explain why the generation from the ledger does not + // matter here (they _all_ predate the Nexus-provided one). + let zones = input + .requests + .into_iter() + .map(OmicronZoneConfigComplete::try_from) + .collect::, _>>() + .context("mapping `AllServiceRequests` to `ZonesConfig`")?; + Ok(ZonesConfig { generation: Generation::new(), zones }) + } +} + +impl TryFrom for OmicronZoneConfigComplete { + type Error = anyhow::Error; + + fn try_from(input: ServiceRequest) -> Result { + Ok(OmicronZoneConfigComplete { + zone: OmicronZoneConfig::try_from(input.zone)?, + root: input.root, + }) + } +} + +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 has_dataset = input.dataset.is_some(); + if let Some(dataset) = &input.dataset { + if dataset.id != input.id { + return Err(anyhow!( + "expected dataset id ({}) to match id ({})", + dataset.id, + input.id, + )) + .with_context(error_context); + } + } + + let dataset_request = input + .dataset + .ok_or_else(|| anyhow!("missing dataset")) + .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::Clickhouse, + 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 }) + } +} + #[cfg(test)] mod test { - use super::AllZoneRequestsV1; + use super::AllServiceRequests; + // XXX-dap add similar test for new ledger #[test] - fn test_all_zone_requests_schema() { - let schema = schemars::schema_for!(AllZoneRequestsV1); + fn test_all_services_requests_schema() { + let schema = schemars::schema_for!(AllServiceRequests); expectorate::assert_contents( "../schema/all-zone-requests.json", &serde_json::to_string_pretty(&schema).unwrap(), From 0ad239589efa8fa8cf74eea415f427d168674be3 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Tue, 14 Nov 2023 21:50:52 +0000 Subject: [PATCH 16/44] this does not just happen on cold boot --- sled-agent/src/bootstrap/server.rs | 2 +- sled-agent/src/sled_agent.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sled-agent/src/bootstrap/server.rs b/sled-agent/src/bootstrap/server.rs index 9ed3ad582d..c94a0d894f 100644 --- a/sled-agent/src/bootstrap/server.rs +++ b/sled-agent/src/bootstrap/server.rs @@ -326,7 +326,7 @@ impl Server { // notifications. This cannot fail: we retry indefinitely until // we're done loading services. wait_while_handling_hardware_updates( - sled_agent.cold_boot_load_services(), + sled_agent.load_services(), &mut hardware_monitor, &managers, Some(&sled_agent), diff --git a/sled-agent/src/sled_agent.rs b/sled-agent/src/sled_agent.rs index 3890d63077..a4920e4b27 100644 --- a/sled-agent/src/sled_agent.rs +++ b/sled-agent/src/sled_agent.rs @@ -477,12 +477,11 @@ impl SledAgent { Ok(sled_agent) } - /// Load services for which we're responsible; only meaningful to call - /// during a cold boot. + /// Load services for which we're responsible. /// /// Blocks until all services have started, retrying indefinitely on /// failure. - pub(crate) async fn cold_boot_load_services(&self) { + pub(crate) async fn load_services(&self) { retry_notify( retry_policy_internal_service_aggressive(), || async { From 655d9f819438a5ab940521c0992aba268737802c Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 15 Nov 2023 00:45:08 +0000 Subject: [PATCH 17/44] implement migration from old-format ledger --- sled-agent/src/services.rs | 123 +++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 11 deletions(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 030d967d3d..7a9a31762a 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -35,7 +35,7 @@ use crate::params::{ TimeSync, ZoneBundleCause, ZoneBundleMetadata, ZoneType, }; use crate::profile::*; -use crate::services_migration::SERVICES_LEDGER_FILENAME; +use crate::services_migration::{AllServiceRequests, SERVICES_LEDGER_FILENAME}; use crate::smf_helper::Service; use crate::smf_helper::SmfHelper; use crate::storage_manager::StorageResources; @@ -107,8 +107,8 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; use tokio::io::AsyncWriteExt; -use tokio::sync::oneshot; use tokio::sync::Mutex; +use tokio::sync::{oneshot, MutexGuard}; use tokio::task::JoinHandle; use uuid::Uuid; @@ -222,6 +222,9 @@ pub enum Error { #[error("Error querying simnet devices")] Simnet(#[from] GetSimnetError), + + #[error("Error migrating old-format services ledger")] + ServicesMigration(anyhow::Error), } impl Error { @@ -272,7 +275,9 @@ impl Config { } // XXX-dap TODO-doc and maybe rename it? -#[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] +#[derive( + Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, +)] pub struct OmicronZoneConfigComplete { pub zone: OmicronZoneConfig, // TODO: Consider collapsing "root" into OmicronZoneConfig? @@ -285,7 +290,9 @@ const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; // XXX-dap TODO-doc // XXX-dap could be OmicronZonesConfigComplete? OmicronZonesConfigLocal? -#[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] +#[derive( + Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, +)] pub struct ZonesConfig { pub generation: Generation, pub zones: Vec, @@ -585,6 +592,91 @@ impl ServiceManager { .collect() } + // XXX-dap TODO-doc + async fn load_ledgered_zones( + &self, + // This argument attempts to ensure that the caller holds the right + // lock. + _map: &MutexGuard<'_, BTreeMap>, + ) -> Result>, Error> { + // First, try to load the current software's zone ledger. If that + // works, we're done. + let log = &self.inner.log; + 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)); + } + + // 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:?}" + ); + + let Some(ledger) = + Ledger::::new(log, services_ledger_paths).await + else { + return Ok(None); + }; + + let all_services = ledger.into_inner(); + match ZonesConfig::try_from(all_services) { + 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::ServicesMigration(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?; + Ok(Some(ledger)) + } + } + } + // TODO(https://github.com/oxidecomputer/omicron/issues/2973): // // The sled agent retries this function indefinitely at the call-site, but @@ -595,18 +687,25 @@ impl ServiceManager { // more clearly. pub async fn load_services(&self) -> Result<(), Error> { let log = &self.inner.log; - // XXX-dap look for legacy service ledger if this isn't present - let ledger_paths = self.all_omicron_zone_ledgers().await; - info!(log, "Loading services from: {ledger_paths:?}"); - let mut existing_zones = self.inner.zones.lock().await; let Some(mut ledger) = - Ledger::::new(log, ledger_paths).await + self.load_ledgered_zones(&existing_zones).await? else { - info!(log, "Loading services - No services detected"); + // Nothing found -- nothing to do. + info!( + log, + "Loading Omicron zones - \ + no zones nor old-format services found" + ); return Ok(()); }; + let zones_config = ledger.data_mut(); + info!( + log, + "Loaded Omicron zones"; + "zones_config" => ?zones_config + ); let omicron_zones_config = zones_config.clone().to_omicron_zones_config(); @@ -2478,7 +2577,9 @@ impl ServiceManager { // re-instantiated on boot. async fn ensure_all_omicron_zones( &self, - existing_zones: &mut BTreeMap, + // The MutexGuard here attempts to ensure that the caller has the right + // lock held when calling this function. + existing_zones: &mut MutexGuard<'_, BTreeMap>, old_config: Option<&ZonesConfig>, new_request: OmicronZonesConfig, filter: F, From 964c1a7b565117d3887f9f3ea17c505a8b3d05ae Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 15 Nov 2023 01:23:53 +0000 Subject: [PATCH 18/44] add CLI tool to test migration --- .../src/bin/services-ledger-check-migrate.rs | 53 +++++++++++++++++++ sled-agent/src/lib.rs | 4 +- sled-agent/src/services.rs | 43 +++++++++++++++ sled-agent/src/services_migration.rs | 6 --- 4 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 sled-agent/src/bin/services-ledger-check-migrate.rs diff --git a/sled-agent/src/bin/services-ledger-check-migrate.rs b/sled-agent/src/bin/services-ledger-check-migrate.rs new file mode 100644 index 0000000000..e3b87b052b --- /dev/null +++ b/sled-agent/src/bin/services-ledger-check-migrate.rs @@ -0,0 +1,53 @@ +// 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::Parser; +use omicron_common::cmd::fatal; +use omicron_common::cmd::CmdError; +use omicron_sled_agent::services::ZonesConfig; +use omicron_sled_agent::services_migration::AllServiceRequests; + +#[tokio::main] +async fn main() { + if let Err(message) = do_run().await { + fatal(CmdError::Failure(format!("{:#}", message))); + } +} + +// XXX-dap make this two subcommands: +// - `check` does what this does now +// - `show` takes one argument and pretty-prints the converted form + +#[derive(Debug, Parser)] +struct Args { + #[clap(action)] + files: Vec, +} + +async fn do_run() -> Result<(), anyhow::Error> { + let args = Args::parse(); + for file_path in &args.files { + let contents = tokio::fs::read_to_string(file_path) + .await + .with_context(|| format!("read {:?}", &file_path))?; + let parsed: AllServiceRequests = serde_json::from_str(&contents) + .with_context(|| format!("parse {:?}", &file_path))?; + let converted = ZonesConfig::try_from(parsed) + .with_context(|| format!("migrate contents of {:?}", &file_path))?; + // XXX-dap what sanity-checks on the result? + println!( + "{}: converted okay (zones: {})", + file_path, + converted.zones.len() + ); + } + + println!("all files converted okay (files: {})", args.files.len()); + Ok(()) +} diff --git a/sled-agent/src/lib.rs b/sled-agent/src/lib.rs index b4d2fd4366..27a964598f 100644 --- a/sled-agent/src/lib.rs +++ b/sled-agent/src/lib.rs @@ -28,8 +28,8 @@ pub mod params; mod profile; pub mod rack_setup; pub mod server; -mod services; -mod services_migration; +pub mod services; +pub mod services_migration; mod sled_agent; mod smf_helper; pub(crate) mod storage; diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 7a9a31762a..8d82b581f3 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -672,6 +672,49 @@ impl ServiceManager { ); 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)) } } diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index 21232f8116..365cdc3474 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -177,12 +177,6 @@ impl std::fmt::Display for ServiceType { } } -/// Used to request that the Sled initialize multiple services. -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)] -pub struct ServiceEnsureBody { - pub services: Vec, -} - /// Describes a request to provision a specific dataset #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, From 0959fb6cc68b7ea672d1e7381e9e35202f4f0369 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 15 Nov 2023 21:25:40 +0000 Subject: [PATCH 19/44] prune visibility --- sled-agent/src/params.rs | 4 +- sled-agent/src/services_migration.rs | 57 +++++++--------------------- 2 files changed, 15 insertions(+), 46 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 42c4d4c77e..e5f1db6e91 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -274,9 +274,7 @@ impl std::fmt::Display for DatasetKind { } } -// XXX-dap do a pass over this file to see which of these types can be removed -// altogether. Those only needed for migration could go into a separate module. -/// The type of zone which may be requested from Sled Agent +/// The type of zone that Sled Agent may run #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index 365cdc3474..36a7f24cf5 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -27,58 +27,29 @@ use uuid::Uuid; #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] -pub struct ServiceZoneRequest { +struct ServiceZoneRequest { // The UUID of the zone to be initialized. // TODO: Should this be removed? If we have UUIDs on the services, what's // the point of this? - pub id: Uuid, + id: Uuid, // The type of the zone to be created. - pub zone_type: ZoneType, + zone_type: ZoneType, // The addresses on which the service should listen for requests. - pub addresses: Vec, + addresses: Vec, // Datasets which should be managed by this service. #[serde(default)] - pub dataset: Option, + dataset: Option, // Services that should be run in the zone - pub services: Vec, -} - -impl ServiceZoneRequest { - // The full name of the zone, if it was to be created as a zone. - pub fn zone_name(&self) -> String { - illumos_utils::running_zone::InstalledZone::get_zone_name( - &self.zone_type.to_string(), - self.zone_name_unique_identifier(), - ) - } - - // The name of a unique identifier for the zone, if one is necessary. - pub fn zone_name_unique_identifier(&self) -> Option { - match &self.zone_type { - // The switch zone is necessarily a singleton. - ZoneType::Switch => None, - // All other zones should be identified by their zone UUID. - ZoneType::Clickhouse - | ZoneType::ClickhouseKeeper - | ZoneType::CockroachDb - | ZoneType::Crucible - | ZoneType::ExternalDns - | ZoneType::InternalDns - | ZoneType::Nexus - | ZoneType::CruciblePantry - | ZoneType::Ntp - | ZoneType::Oximeter => Some(self.id), - } - } + services: Vec, } /// Used to request that the Sled initialize a single service. #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] -pub struct ServiceZoneService { - pub id: Uuid, - pub details: ServiceType, +struct ServiceZoneService { + id: Uuid, + details: ServiceType, } /// Describes service-specific parameters. @@ -86,7 +57,7 @@ pub struct ServiceZoneService { Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] #[serde(tag = "type", rename_all = "snake_case")] -pub enum ServiceType { +enum ServiceType { Nexus { /// The address at which the internal nexus server is reachable. internal_address: SocketAddrV6, @@ -181,10 +152,10 @@ impl std::fmt::Display for ServiceType { #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] -pub struct DatasetRequest { - pub id: Uuid, - pub name: crate::storage::dataset::DatasetName, - pub service_address: SocketAddrV6, +struct DatasetRequest { + id: Uuid, + name: crate::storage::dataset::DatasetName, + service_address: SocketAddrV6, } impl DatasetRequest { From f58c30a12b76054df88f4eed6e0dd9a6faad6756 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 15 Nov 2023 21:27:51 +0000 Subject: [PATCH 20/44] add test for new format --- sled-agent/src/services.rs | 9 +++++++++ sled-agent/src/services_migration.rs | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 8d82b581f3..3ce64fc143 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -3928,4 +3928,13 @@ mod test { &serde_json::to_string_pretty(&schema).unwrap(), ); } + + #[test] + fn test_all_zones_requests_schema() { + let schema = schemars::schema_for!(ZonesConfig); + expectorate::assert_contents( + "../schema/all-zones-requests.json", + &serde_json::to_string_pretty(&schema).unwrap(), + ); + } } diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index 36a7f24cf5..0fe1e0e1f5 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -487,7 +487,6 @@ impl TryFrom for OmicronZoneConfig { mod test { use super::AllServiceRequests; - // XXX-dap add similar test for new ledger #[test] fn test_all_services_requests_schema() { let schema = schemars::schema_for!(AllServiceRequests); From f5bde3defe575bca5e4aa74d3494496b9fb0aa18 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 15 Nov 2023 22:12:00 +0000 Subject: [PATCH 21/44] rerun tests and fix some stuff --- openapi/sled-agent.json | 2 +- schema/all-zone-requests.json | 2 +- schema/all-zones-requests.json | 616 ++++++++++++++++++ .../src/bin/services-ledger-check-migrate.rs | 4 +- sled-agent/src/services.rs | 4 +- sled-agent/src/services_migration.rs | 24 +- 6 files changed, 634 insertions(+), 18 deletions(-) create mode 100644 schema/all-zones-requests.json diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index 2342806c4d..3e51e7cbd0 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -2430,7 +2430,7 @@ ] }, "OmicronZoneType": { - "description": "Describes what component is running in this zone and its associated type-specific configuration\n\nXXX-dap ideally this would not be necessary at all! Sled Agent shouldn't have to know about the things running on it, I think? XXX-dap commonize with ServiceType (well, probably remove ServiceType)", + "description": "Describes what component is running in this zone and its associated type-specific configuration\n\nXXX-dap ideally this would not be necessary at all! Sled Agent shouldn't have to know about the things running on it, I think?", "oneOf": [ { "type": "object", diff --git a/schema/all-zone-requests.json b/schema/all-zone-requests.json index 468f00ee0c..5c11435db0 100644 --- a/schema/all-zone-requests.json +++ b/schema/all-zone-requests.json @@ -734,7 +734,7 @@ } }, "ZoneType": { - "description": "The type of zone which may be requested from Sled Agent", + "description": "The type of zone that Sled Agent may run", "type": "string", "enum": [ "clickhouse", diff --git a/schema/all-zones-requests.json b/schema/all-zones-requests.json new file mode 100644 index 0000000000..2e1ae21ef7 --- /dev/null +++ b/schema/all-zones-requests.json @@ -0,0 +1,616 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ZonesConfig", + "type": "object", + "required": [ + "generation", + "zones" + ], + "properties": { + "generation": { + "$ref": "#/definitions/Generation" + }, + "zones": { + "type": "array", + "items": { + "$ref": "#/definitions/OmicronZoneConfigComplete" + } + } + }, + "definitions": { + "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" + } + ] + } + ] + }, + "Ipv4Net": { + "title": "An IPv4 subnet", + "description": "An IPv4 subnet, including prefix and subnet mask", + "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])$" + }, + "Ipv6Net": { + "title": "An IPv6 subnet", + "description": "An IPv6 subnet, including prefix and subnet mask", + "examples": [ + "fd12:3456::/64" + ], + "type": "string", + "pattern": "^([fF][dD])[0-9a-fA-F]{2}:(([0-9a-fA-F]{1,4}:){6}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,6}:)([0-9a-fA-F]{1,4})?\\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$" + }, + "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-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" + ] + } + } + } + ] + }, + "OmicronZoneConfig": { + "description": "Describes one Omicron zone running on a sled", + "type": "object", + "required": [ + "id", + "underlay_address", + "zone_type" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "underlay_address": { + "type": "string", + "format": "ipv6" + }, + "zone_type": { + "$ref": "#/definitions/OmicronZoneType" + } + } + }, + "OmicronZoneConfigComplete": { + "type": "object", + "required": [ + "root", + "zone" + ], + "properties": { + "root": { + "type": "string" + }, + "zone": { + "$ref": "#/definitions/OmicronZoneConfig" + } + } + }, + "OmicronZoneDataset": { + "description": "Describes a persistent ZFS dataset associated with an Omicron zone", + "type": "object", + "required": [ + "pool_name" + ], + "properties": { + "pool_name": { + "$ref": "#/definitions/ZpoolName" + } + } + }, + "OmicronZoneType": { + "description": "Describes what component is running in this zone and its associated type-specific configuration\n\nXXX-dap ideally this would not be necessary at all! Sled Agent shouldn't have to know about the things running on it, I think?", + "oneOf": [ + { + "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", + "dataset", + "type" + ], + "properties": { + "address": { + "type": "string" + }, + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, + "type": { + "type": "string", + "enum": [ + "clickhouse" + ] + } + } + }, + { + "type": "object", + "required": [ + "address", + "dataset", + "type" + ], + "properties": { + "address": { + "type": "string" + }, + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, + "type": { + "type": "string", + "enum": [ + "clickhouse_keeper" + ] + } + } + }, + { + "type": "object", + "required": [ + "address", + "dataset", + "type" + ], + "properties": { + "address": { + "type": "string" + }, + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, + "type": { + "type": "string", + "enum": [ + "cockroach_db" + ] + } + } + }, + { + "type": "object", + "required": [ + "address", + "dataset", + "type" + ], + "properties": { + "address": { + "type": "string" + }, + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, + "type": { + "type": "string", + "enum": [ + "crucible" + ] + } + } + }, + { + "type": "object", + "required": [ + "address", + "type" + ], + "properties": { + "address": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "crucible_pantry" + ] + } + } + }, + { + "type": "object", + "required": [ + "dataset", + "dns_address", + "http_address", + "nic", + "type" + ], + "properties": { + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, + "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": [ + "dataset", + "dns_address", + "gz_address", + "gz_address_index", + "http_address", + "type" + ], + "properties": { + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, + "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", + "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": [ + "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": [ + "address", + "type" + ], + "properties": { + "address": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "oximeter" + ] + } + } + } + ] + }, + "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 + }, + "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 index e3b87b052b..1e0882af85 100644 --- a/sled-agent/src/bin/services-ledger-check-migrate.rs +++ b/sled-agent/src/bin/services-ledger-check-migrate.rs @@ -11,7 +11,7 @@ use clap::Parser; use omicron_common::cmd::fatal; use omicron_common::cmd::CmdError; use omicron_sled_agent::services::ZonesConfig; -use omicron_sled_agent::services_migration::AllServiceRequests; +use omicron_sled_agent::services_migration::AllZoneRequests; #[tokio::main] async fn main() { @@ -36,7 +36,7 @@ async fn do_run() -> Result<(), anyhow::Error> { let contents = tokio::fs::read_to_string(file_path) .await .with_context(|| format!("read {:?}", &file_path))?; - let parsed: AllServiceRequests = serde_json::from_str(&contents) + let parsed: AllZoneRequests = serde_json::from_str(&contents) .with_context(|| format!("parse {:?}", &file_path))?; let converted = ZonesConfig::try_from(parsed) .with_context(|| format!("migrate contents of {:?}", &file_path))?; diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 3ce64fc143..3470d2dc70 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -35,7 +35,7 @@ use crate::params::{ TimeSync, ZoneBundleCause, ZoneBundleMetadata, ZoneType, }; use crate::profile::*; -use crate::services_migration::{AllServiceRequests, SERVICES_LEDGER_FILENAME}; +use crate::services_migration::{AllZoneRequests, SERVICES_LEDGER_FILENAME}; use crate::smf_helper::Service; use crate::smf_helper::SmfHelper; use crate::storage_manager::StorageResources; @@ -631,7 +631,7 @@ impl ServiceManager { ); let Some(ledger) = - Ledger::::new(log, services_ledger_paths).await + Ledger::::new(log, services_ledger_paths).await else { return Ok(None); }; diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index 0fe1e0e1f5..fe48d7fc14 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -186,7 +186,7 @@ impl DatasetRequest { // 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 ServiceRequest { +struct ZoneRequest { zone: ServiceZoneRequest, // TODO: Consider collapsing "root" into ServiceZoneRequest #[schemars(with = "String")] @@ -200,19 +200,19 @@ pub const SERVICES_LEDGER_FILENAME: &str = "services.json"; // to a JSON file. // XXX-dap TODO-doc #[derive(Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -pub struct AllServiceRequests { +pub struct AllZoneRequests { generation: Generation, - requests: Vec, + requests: Vec, } -impl Default for AllServiceRequests { +impl Default for AllZoneRequests { fn default() -> Self { Self { generation: Generation::new(), requests: vec![] } } } -impl Ledgerable for AllServiceRequests { - fn is_newer_than(&self, other: &AllServiceRequests) -> bool { +impl Ledgerable for AllZoneRequests { + fn is_newer_than(&self, other: &AllZoneRequests) -> bool { self.generation >= other.generation } @@ -221,10 +221,10 @@ impl Ledgerable for AllServiceRequests { } } -impl TryFrom for ZonesConfig { +impl TryFrom for ZonesConfig { type Error = anyhow::Error; - fn try_from(input: AllServiceRequests) -> Result { + fn try_from(input: AllZoneRequests) -> Result { // XXX-dap starting to think that the generation in OmicronZonesConfig // (at least the one stored on disk) ought to be an Option or something? // There's no correct value here. Any Nexus one needs to be treated as @@ -241,10 +241,10 @@ impl TryFrom for ZonesConfig { } } -impl TryFrom for OmicronZoneConfigComplete { +impl TryFrom for OmicronZoneConfigComplete { type Error = anyhow::Error; - fn try_from(input: ServiceRequest) -> Result { + fn try_from(input: ZoneRequest) -> Result { Ok(OmicronZoneConfigComplete { zone: OmicronZoneConfig::try_from(input.zone)?, root: input.root, @@ -485,11 +485,11 @@ impl TryFrom for OmicronZoneConfig { #[cfg(test)] mod test { - use super::AllServiceRequests; + use super::AllZoneRequests; #[test] fn test_all_services_requests_schema() { - let schema = schemars::schema_for!(AllServiceRequests); + let schema = schemars::schema_for!(AllZoneRequests); expectorate::assert_contents( "../schema/all-zone-requests.json", &serde_json::to_string_pretty(&schema).unwrap(), From 2c9a5653e2bbe6e26b7a2625662567c093f75b16 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 15 Nov 2023 22:36:59 +0000 Subject: [PATCH 22/44] tool could support showing converted form, too --- .../src/bin/services-ledger-check-migrate.rs | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/sled-agent/src/bin/services-ledger-check-migrate.rs b/sled-agent/src/bin/services-ledger-check-migrate.rs index 1e0882af85..18fb2cb7d7 100644 --- a/sled-agent/src/bin/services-ledger-check-migrate.rs +++ b/sled-agent/src/bin/services-ledger-check-migrate.rs @@ -7,6 +7,7 @@ use anyhow::Context; use camino::Utf8PathBuf; +use clap::Args; use clap::Parser; use omicron_common::cmd::fatal; use omicron_common::cmd::CmdError; @@ -20,34 +21,60 @@ async fn main() { } } -// XXX-dap make this two subcommands: -// - `check` does what this does now -// - `show` takes one argument and pretty-prints the converted form - #[derive(Debug, Parser)] -struct Args { +#[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 = Args::parse(); - for file_path in &args.files { + 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 = ZonesConfig::try_from(parsed) - .with_context(|| format!("migrate contents of {:?}", &file_path))?; - // XXX-dap what sanity-checks on the result? - println!( - "{}: converted okay (zones: {})", + .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() ); } - println!("all files converted okay (files: {})", args.files.len()); + eprintln!("all files processed okay (files: {})", files.len()); Ok(()) } From 472698ea86e2f217e6777a6ac5b057c2e3505765 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 15 Nov 2023 23:22:47 +0000 Subject: [PATCH 23/44] clean up some type names --- openapi/sled-agent.json | 2 +- schema/all-zones-requests.json | 8 +- .../src/bin/services-ledger-check-migrate.rs | 4 +- sled-agent/src/params.rs | 6 - sled-agent/src/services.rs | 131 +++++++++--------- sled-agent/src/services_migration.rs | 12 +- 6 files changed, 81 insertions(+), 82 deletions(-) diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index 3e51e7cbd0..f889aa0fa8 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -2430,7 +2430,7 @@ ] }, "OmicronZoneType": { - "description": "Describes what component is running in this zone and its associated type-specific configuration\n\nXXX-dap ideally this would not be necessary at all! Sled Agent shouldn't have to know about the things running on it, I think?", + "description": "Describes what component is running in this zone and its associated type-specific configuration", "oneOf": [ { "type": "object", diff --git a/schema/all-zones-requests.json b/schema/all-zones-requests.json index 2e1ae21ef7..2c2d5225c5 100644 --- a/schema/all-zones-requests.json +++ b/schema/all-zones-requests.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ZonesConfig", + "title": "OmicronZonesConfigLocal", "type": "object", "required": [ "generation", @@ -13,7 +13,7 @@ "zones": { "type": "array", "items": { - "$ref": "#/definitions/OmicronZoneConfigComplete" + "$ref": "#/definitions/OmicronZoneConfigLocal" } } }, @@ -196,7 +196,7 @@ } } }, - "OmicronZoneConfigComplete": { + "OmicronZoneConfigLocal": { "type": "object", "required": [ "root", @@ -224,7 +224,7 @@ } }, "OmicronZoneType": { - "description": "Describes what component is running in this zone and its associated type-specific configuration\n\nXXX-dap ideally this would not be necessary at all! Sled Agent shouldn't have to know about the things running on it, I think?", + "description": "Describes what component is running in this zone and its associated type-specific configuration", "oneOf": [ { "type": "object", diff --git a/sled-agent/src/bin/services-ledger-check-migrate.rs b/sled-agent/src/bin/services-ledger-check-migrate.rs index 18fb2cb7d7..ae9d095c75 100644 --- a/sled-agent/src/bin/services-ledger-check-migrate.rs +++ b/sled-agent/src/bin/services-ledger-check-migrate.rs @@ -11,7 +11,7 @@ use clap::Args; use clap::Parser; use omicron_common::cmd::fatal; use omicron_common::cmd::CmdError; -use omicron_sled_agent::services::ZonesConfig; +use omicron_sled_agent::services::OmicronZonesConfigLocal; use omicron_sled_agent::services_migration::AllZoneRequests; #[tokio::main] @@ -58,7 +58,7 @@ async fn do_run() -> Result<(), anyhow::Error> { .with_context(|| format!("read {:?}", &file_path))?; let parsed: AllZoneRequests = serde_json::from_str(&contents) .with_context(|| format!("parse {:?}", &file_path))?; - let converted = ZonesConfig::try_from(parsed) + let converted = OmicronZonesConfigLocal::try_from(parsed) .with_context(|| format!("convert contents of {:?}", &file_path))?; if do_show { println!( diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index e5f1db6e91..54c0eca73c 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -352,9 +352,6 @@ impl From for sled_agent_client::types::OmicronZoneConfig { } impl OmicronZoneConfig { - // XXX-dap should the caller (RSS) should specify this directly? That - // eliminates one reason why Sled Agent needs to know about what kind of - // dataset it's looking at. pub fn dataset_name(&self) -> Option { self.zone_type.dataset_name() } @@ -536,9 +533,6 @@ impl From for sled_agent_client::types::OmicronZoneDataset { /// Describes what component is running in this zone and its associated /// type-specific configuration -/// -/// XXX-dap ideally this would not be necessary at all! Sled Agent shouldn't -/// have to know about the things running on it, I think? #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 3470d2dc70..ddfe84573b 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -274,11 +274,11 @@ impl Config { } } -// XXX-dap TODO-doc and maybe rename it? +// XXX-dap TODO-doc #[derive( Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, )] -pub struct OmicronZoneConfigComplete { +pub struct OmicronZoneConfigLocal { pub zone: OmicronZoneConfig, // TODO: Consider collapsing "root" into OmicronZoneConfig? #[schemars(with = "String")] @@ -289,17 +289,16 @@ pub struct OmicronZoneConfigComplete { const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; // XXX-dap TODO-doc -// XXX-dap could be OmicronZonesConfigComplete? OmicronZonesConfigLocal? #[derive( Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, )] -pub struct ZonesConfig { +pub struct OmicronZonesConfigLocal { pub generation: Generation, - pub zones: Vec, + pub zones: Vec, } -impl Ledgerable for ZonesConfig { - fn is_newer_than(&self, other: &ZonesConfig) -> bool { +impl Ledgerable for OmicronZonesConfigLocal { + fn is_newer_than(&self, other: &OmicronZonesConfigLocal) -> bool { self.generation >= other.generation } @@ -314,7 +313,7 @@ impl Ledgerable for ZonesConfig { } } -impl ZonesConfig { +impl OmicronZonesConfigLocal { pub fn to_omicron_zones_config(self) -> OmicronZonesConfig { OmicronZonesConfig { generation: self.generation, @@ -366,15 +365,15 @@ impl crate::smf_helper::Service for ServiceType { } } -struct SwitchZoneConfigComplete { +struct SwitchZoneConfigLocal { zone: SwitchZoneConfig, root: Utf8PathBuf, } // XXX-dap TODO-doc enum ZoneArgs<'a> { - Omicron(&'a OmicronZoneConfigComplete), - SledLocal(&'a SwitchZoneConfigComplete), + Omicron(&'a OmicronZoneConfigLocal), + SledLocal(&'a SwitchZoneConfigLocal), } impl<'a> ZoneArgs<'a> { @@ -598,14 +597,15 @@ impl ServiceManager { // This argument attempts to ensure that the caller holds the right // lock. _map: &MutexGuard<'_, BTreeMap>, - ) -> Result>, Error> { + ) -> Result>, Error> { // First, try to load the current software's zone ledger. If that // works, we're done. let log = &self.inner.log; 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; + Ledger::::new(log, ledger_paths.clone()) + .await; if let Some(ledger) = maybe_ledger { info!( @@ -637,7 +637,7 @@ impl ServiceManager { }; let all_services = ledger.into_inner(); - match ZonesConfig::try_from(all_services) { + match OmicronZonesConfigLocal::try_from(all_services) { Err(error) => { // We've tried to test thoroughly so that this should never // happen. If for some reason it does happen, engineering @@ -665,7 +665,7 @@ impl ServiceManager { "Successfully migrated old-format services ledger to \ zones ledger" ); - let mut ledger = Ledger::::new_with( + let mut ledger = Ledger::::new_with( log, ledger_paths.clone(), new_config, @@ -1390,7 +1390,7 @@ impl ServiceManager { // These zones are self-assembling -- after they boot, there should // be no "zlogin" necessary to initialize. match &request { - ZoneArgs::Omicron(OmicronZoneConfigComplete { + ZoneArgs::Omicron(OmicronZoneConfigLocal { zone: OmicronZoneConfig { zone_type: OmicronZoneType::Clickhouse { .. }, @@ -1434,7 +1434,7 @@ impl ServiceManager { return Ok(RunningZone::boot(installed_zone).await?); } - ZoneArgs::Omicron(OmicronZoneConfigComplete { + ZoneArgs::Omicron(OmicronZoneConfigLocal { zone: OmicronZoneConfig { zone_type: OmicronZoneType::ClickhouseKeeper { .. }, @@ -1481,7 +1481,7 @@ impl ServiceManager { return Ok(RunningZone::boot(installed_zone).await?); } - ZoneArgs::Omicron(OmicronZoneConfigComplete { + ZoneArgs::Omicron(OmicronZoneConfigLocal { zone: OmicronZoneConfig { zone_type: OmicronZoneType::CockroachDb { .. }, @@ -1530,7 +1530,7 @@ impl ServiceManager { return Ok(RunningZone::boot(installed_zone).await?); } - ZoneArgs::Omicron(OmicronZoneConfigComplete { + ZoneArgs::Omicron(OmicronZoneConfigLocal { zone: zone @ OmicronZoneConfig { zone_type: OmicronZoneType::Crucible { .. }, @@ -1573,7 +1573,7 @@ impl ServiceManager { return Ok(RunningZone::boot(installed_zone).await?); } - ZoneArgs::Omicron(OmicronZoneConfigComplete { + ZoneArgs::Omicron(OmicronZoneConfigLocal { zone: OmicronZoneConfig { zone_type: OmicronZoneType::CruciblePantry { .. }, @@ -1663,7 +1663,7 @@ impl ServiceManager { } let addresses = match &request { - ZoneArgs::Omicron(OmicronZoneConfigComplete { + ZoneArgs::Omicron(OmicronZoneConfigLocal { zone: OmicronZoneConfig { underlay_address, .. }, .. }) => vec![*underlay_address], @@ -2448,7 +2448,7 @@ impl ServiceManager { async fn initialize_omicron_zones_locked( &self, existing_zones: &mut BTreeMap, - requests: &Vec, + requests: &Vec, ) -> Result<(), Error> { if let Some(name) = requests .iter() @@ -2535,22 +2535,24 @@ impl ServiceManager { // Read the existing set of services from the ledger. let zone_ledger_paths = self.all_omicron_zone_ledgers().await; - let ledger = - match Ledger::::new(log, zone_ledger_paths.clone()) - .await - { - Some(ledger) => ledger, - None => Ledger::::new_with( - log, - zone_ledger_paths.clone(), - ZonesConfig { - // XXX-dap this means Nexus must use a newer generation - // for its first one - generation: Generation::new(), - zones: vec![], - }, - ), - }; + let ledger = match Ledger::::new( + log, + zone_ledger_paths.clone(), + ) + .await + { + Some(ledger) => ledger, + None => Ledger::::new_with( + log, + zone_ledger_paths.clone(), + OmicronZonesConfigLocal { + // XXX-dap this means Nexus must use a newer generation + // for its first one + generation: Generation::new(), + zones: vec![], + }, + ), + }; let ledger_zone_config = ledger.data(); Ok(OmicronZonesConfig { @@ -2578,23 +2580,25 @@ impl ServiceManager { // Read the existing set of services from the ledger. let zone_ledger_paths = self.all_omicron_zone_ledgers().await; - let mut ledger = - match Ledger::::new(log, zone_ledger_paths.clone()) - .await - { - Some(ledger) => ledger, - None => Ledger::::new_with( - log, - zone_ledger_paths.clone(), - ZonesConfig { - // XXX-dap this means Nexus must use a newer generation - // for its first one. Even better would be if this - // whole object could be `None` - generation: Generation::new(), - zones: vec![], - }, - ), - }; + let mut ledger = match Ledger::::new( + log, + zone_ledger_paths.clone(), + ) + .await + { + Some(ledger) => ledger, + None => Ledger::::new_with( + log, + zone_ledger_paths.clone(), + OmicronZonesConfigLocal { + // XXX-dap this means Nexus must use a newer generation + // for its first one. Even better would be if this + // whole object could be `None` + generation: Generation::new(), + zones: vec![], + }, + ), + }; let ledger_zone_config = ledger.data_mut(); @@ -2623,10 +2627,10 @@ impl ServiceManager { // The MutexGuard here attempts to ensure that the caller has the right // lock held when calling this function. existing_zones: &mut MutexGuard<'_, BTreeMap>, - old_config: Option<&ZonesConfig>, + old_config: Option<&OmicronZonesConfigLocal>, new_request: OmicronZonesConfig, filter: F, - ) -> Result + ) -> Result where F: Fn(&OmicronZoneConfig) -> bool, { @@ -2634,7 +2638,6 @@ impl ServiceManager { // Do some data-normalization to ensure we can compare the "requested // set" vs the "existing set" as HashSets. - // XXX-dap can we not skip this clone? let old_zones_set: HashSet = old_config .map(|old_config| { HashSet::from_iter( @@ -2727,8 +2730,7 @@ impl ServiceManager { .ok_or_else(|| Error::U2NotFound)? .clone(); - new_zones - .push(OmicronZoneConfigComplete { zone: zone.clone(), root }); + new_zones.push(OmicronZoneConfigLocal { zone: zone.clone(), root }); } self.initialize_omicron_zones_locked(existing_zones, &new_zones) @@ -2742,7 +2744,10 @@ impl ServiceManager { } } - Ok(ZonesConfig { generation: new_request.generation, zones: new_zones }) + Ok(OmicronZonesConfigLocal { + generation: new_request.generation, + zones: new_zones, + }) } pub async fn cockroachdb_initialize(&self) -> Result<(), Error> { @@ -3390,7 +3395,7 @@ impl ServiceManager { // the cycle we put the switch zone root fs on the ramdisk. let root = Utf8PathBuf::from(ZONE_ZFS_RAMDISK_DATASET_MOUNTPOINT); let zone_request = - SwitchZoneConfigComplete { root, zone: request.clone() }; + SwitchZoneConfigLocal { root, zone: request.clone() }; let zone_args = ZoneArgs::SledLocal(&zone_request); let zone = self.initialize_zone(zone_args, filesystems, data_links).await?; @@ -3931,7 +3936,7 @@ mod test { #[test] fn test_all_zones_requests_schema() { - let schema = schemars::schema_for!(ZonesConfig); + let schema = schemars::schema_for!(OmicronZonesConfigLocal); expectorate::assert_contents( "../schema/all-zones-requests.json", &serde_json::to_string_pretty(&schema).unwrap(), diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index fe48d7fc14..ffb658a7b0 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -9,7 +9,7 @@ use crate::params::{ DatasetKind, OmicronZoneConfig, OmicronZoneDataset, OmicronZoneType, ZoneType, }; -use crate::services::{OmicronZoneConfigComplete, ZonesConfig}; +use crate::services::{OmicronZoneConfigLocal, OmicronZonesConfigLocal}; use anyhow::{anyhow, ensure, Context}; use camino::Utf8PathBuf; use omicron_common::api::external::Generation; @@ -221,7 +221,7 @@ impl Ledgerable for AllZoneRequests { } } -impl TryFrom for ZonesConfig { +impl TryFrom for OmicronZonesConfigLocal { type Error = anyhow::Error; fn try_from(input: AllZoneRequests) -> Result { @@ -234,18 +234,18 @@ impl TryFrom for ZonesConfig { let zones = input .requests .into_iter() - .map(OmicronZoneConfigComplete::try_from) + .map(OmicronZoneConfigLocal::try_from) .collect::, _>>() .context("mapping `AllServiceRequests` to `ZonesConfig`")?; - Ok(ZonesConfig { generation: Generation::new(), zones }) + Ok(OmicronZonesConfigLocal { generation: Generation::new(), zones }) } } -impl TryFrom for OmicronZoneConfigComplete { +impl TryFrom for OmicronZoneConfigLocal { type Error = anyhow::Error; fn try_from(input: ZoneRequest) -> Result { - Ok(OmicronZoneConfigComplete { + Ok(OmicronZoneConfigLocal { zone: OmicronZoneConfig::try_from(input.zone)?, root: input.root, }) From 9c6e8031a41dab43bcc320f18accaa423c327ed4 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 16 Nov 2023 00:34:35 +0000 Subject: [PATCH 24/44] get rid of wonky generation number management in RSS --- sled-agent/src/rack_setup/plan/service.rs | 8 +- sled-agent/src/rack_setup/service.rs | 189 +++++++++++++++------- 2 files changed, 131 insertions(+), 66 deletions(-) diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index ee6b6a739e..7e4bbea4ec 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -21,7 +21,7 @@ use omicron_common::address::{ MGD_PORT, MGS_PORT, NTP_PORT, NUM_SOURCE_NAT_PORTS, RSS_RESERVED_ADDRESSES, SLED_PREFIX, }; -use omicron_common::api::external::{Generation, MacAddr, Vni}; +use omicron_common::api::external::{MacAddr, Vni}; use omicron_common::api::internal::shared::SwitchLocation; use omicron_common::api::internal::shared::{ NetworkInterface, NetworkInterfaceKind, SourceNatConfig, @@ -100,17 +100,13 @@ pub enum PlanError { #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct SledConfig { - /// generation number to use the next time we try to configure zones on this - /// sled - pub next_generation: Generation, - /// zones configured for this sled pub zones: Vec, } impl Default for SledConfig { fn default() -> Self { - SledConfig { next_generation: Generation::new(), zones: Vec::new() } + SledConfig { zones: Vec::new() } } } diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 56d6840b30..460aaa7a87 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -81,6 +81,7 @@ use nexus_client::{ types as NexusTypes, Client as NexusClient, Error as NexusError, }; use omicron_common::address::get_sled_address; +use omicron_common::api::external::Generation; use omicron_common::api::internal::shared::ExternalPortDiscovery; use omicron_common::backoff::{ retry_notify, retry_policy_internal_service_aggressive, BackoffError, @@ -298,33 +299,24 @@ impl ServiceInner { Ok(()) } - // Ensure that all services of a particular type are running. + // Ensure that all services for a particular generation are running. // // This is useful in a rack-setup context, where initial boot ordering // can matter for first-time-setup. // // Note that after first-time setup, the initialization order of // services should not matter. - async fn ensure_zones_of_type( + // + // Further, it's possible that the target sled is already running a newer + // version. That's not an error here. + async fn ensure_zone_config_at_least( &self, - service_plan: &mut ServicePlan, - // XXX-dap better way to deal with this filtering that doesn't require a - // box and also doesn't require that the caller has done this correctly - zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), + configs: &HashMap, ) -> Result<(), SetupServiceError> { - futures::future::join_all(service_plan.services.iter_mut().map( - |(sled_address, sled_config)| async move { - let zones: Vec<_> = sled_config - .zones - .iter() - .filter(|z| zone_filter(&z.zone_type)) - .cloned() - .collect(); - let generation = sled_config.next_generation; - sled_config.next_generation = - sled_config.next_generation.next(); - let zones_config = OmicronZonesConfig { generation, zones }; - self.initialize_zones_on_sled(*sled_address, &zones_config) + futures::future::join_all(configs.iter().map( + |(sled_address, zones_config)| async move { + // XXX-dap check for the error indicating an older generation + self.initialize_zones_on_sled(*sled_address, zones_config) .await?; Ok(()) }, @@ -335,6 +327,68 @@ impl ServiceInner { Ok(()) } + // XXX-dap TODO-doc and mention that this should always be generation 1? + // XXX-dap TODO-coverage + fn generate_omicron_zone_configs_gen1( + service_plan: &ServicePlan, + zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), + ) -> HashMap { + let generation = Generation::new(); + service_plan + .services + .iter() + .map(|(sled_address, sled_config)| { + let zones: Vec<_> = sled_config + .zones + .iter() + .filter(|z| zone_filter(&z.zone_type)) + .cloned() + .collect(); + let config = OmicronZonesConfig { generation, zones }; + (*sled_address, config) + }) + .collect() + } + + // XXX-dap TODO-doc + // XXX-dap TODO-coverage + fn augment_omicron_zone_configs( + generation: Generation, + service_plan: &ServicePlan, + last_configs: &HashMap, + zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), + ) -> HashMap { + service_plan + .services + .iter() + .map(|(sled_address, sled_config)| { + let mut zones = match last_configs.get(sled_address) { + Some(config) => { + assert!(generation > config.generation.next()); + config.zones.clone() + } + None => Vec::new(), + }; + + let zones_already = + zones.iter().map(|z| z.id).collect::>(); + zones.extend( + sled_config + .zones + .iter() + .filter(|z| { + !zones_already.contains(&z.id) + && zone_filter(&z.zone_type) + }) + .cloned(), + ); + + let config = OmicronZonesConfig { generation, zones }; + (*sled_address, config) + }) + .collect() + } + // Configure the internal DNS servers with the initial DNS data async fn initialize_internal_dns_records( &self, @@ -919,11 +973,7 @@ impl ServiceInner { get_sled_address(initialization_request.subnet) }) .collect(); - // XXX-dap annoying that we need a `mut` service plan. it's just to - // update the generation numbers. It'd maybe better not to store those? - // XXX-dap will this work if we make it partway through and then - // crash? The next time we may try to put an earlier generation first - let mut service_plan = if let Some(plan) = + let service_plan = if let Some(plan) = ServicePlan::load(&self.log, storage_resources).await? { plan @@ -937,13 +987,38 @@ impl ServiceInner { .await? }; + // The service plan describes all the zones that we will eventually + // deploy on each sled. But we cannot currently just deploy them all + // concurrently. We'll do it in four stages, each corresponding to a + // "generation" of each sled's configuration. + // + // - generation 1: internal DNS only + // - generation 2: internal DNS + NTP servers + // - generation 3: internal DNS + NTP servers + CockroachDB + // - generation 4: everything + // + // At each stage, we're specifying a complete configuration of what + // should be running on the sled -- including this generation number. + // And Sled Agents will reject requests for generations older than the + // one they're currently running. Thus, the generation number is + // a piece of global, distributed state. + // + // For now, we hardcode the three requests we make to use these three + // generation numbers (1, 2, and 3). + let generation1_dns_only = Generation::new(); + let generation2_dns_and_ntp = generation1_dns_only.next(); + let generation3_cockroachdb = generation2_dns_and_ntp.next(); + let generation4_everything = generation3_cockroachdb.next(); + // Set up internal DNS services first and write the initial // DNS configuration to the internal DNS servers. - let zone_filter1 = |zone_type: &OmicronZoneType| { - matches!(zone_type, OmicronZoneType::InternalDns { .. }) - }; - self.ensure_zones_of_type(&mut service_plan, &(zone_filter1.clone())) - .await?; + let gen1_configs = Self::generate_omicron_zone_configs_gen1( + &service_plan, + &|zone_type: &OmicronZoneType| { + matches!(zone_type, OmicronZoneType::InternalDns { .. }) + }, + ); + self.ensure_zone_config_at_least(&gen1_configs).await?; self.initialize_internal_dns_records(&service_plan).await?; // Ask MGS in each switch zone which switch it is. @@ -952,18 +1027,19 @@ impl ServiceInner { .await; // Next start up the NTP services. - // Note we also specify internal DNS services again because it - // can ony be additive. - let zone_filter2 = |zone_type: &OmicronZoneType| { - zone_filter1(zone_type) - || matches!( + let gen2_configs = Self::augment_omicron_zone_configs( + generation2_dns_and_ntp, + &service_plan, + &gen1_configs, + &|zone_type: &OmicronZoneType| { + matches!( zone_type, OmicronZoneType::BoundaryNtp { .. } | OmicronZoneType::InternalNtp { .. } ) - }; - self.ensure_zones_of_type(&mut service_plan, &(zone_filter2.clone())) - .await?; + }, + ); + self.ensure_zone_config_at_least(&gen2_configs).await?; // Wait until time is synchronized on all sleds before proceeding. self.wait_for_timesync(&sled_addresses).await?; @@ -971,35 +1047,28 @@ impl ServiceInner { info!(self.log, "Finished setting up Internal DNS and NTP"); // Wait until Cockroach has been initialized before running Nexus. - let zone_filter3 = |zone_type: &OmicronZoneType| { - zone_filter2(zone_type) - || matches!(zone_type, OmicronZoneType::CockroachDb { .. }) - }; - self.ensure_zones_of_type(&mut service_plan, &(zone_filter3.clone())) - .await?; + let gen3_configs = Self::augment_omicron_zone_configs( + generation3_cockroachdb, + &service_plan, + &gen2_configs, + &|zone_type: &OmicronZoneType| { + matches!(zone_type, OmicronZoneType::CockroachDb { .. }) + }, + ); + self.ensure_zone_config_at_least(&gen3_configs).await?; // Now that datasets and zones have started for CockroachDB, // perform one-time initialization of the cluster. self.initialize_cockroach(&service_plan).await?; // Issue the rest of the zone initialization requests. - futures::future::join_all(service_plan.services.iter_mut().map( - |(sled_address, sled_config)| async move { - let generation = sled_config.next_generation; - sled_config.next_generation = - sled_config.next_generation.next(); - let zones_config = OmicronZonesConfig { - generation, - zones: sled_config.zones.clone(), - }; - self.initialize_zones_on_sled(*sled_address, &zones_config) - .await?; - Ok(()) - }, - )) - .await - .into_iter() - .collect::, SetupServiceError>>()?; + let gen4_configs = Self::augment_omicron_zone_configs( + generation4_everything, + &service_plan, + &gen3_configs, + &|_| true, + ); + self.ensure_zone_config_at_least(&gen4_configs).await?; info!(self.log, "Finished setting up services"); From 281021f6809e22e1211491ee1490c859777f4442 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 16 Nov 2023 00:36:14 +0000 Subject: [PATCH 25/44] remove gratuitous clone --- sled-agent/src/rack_setup/service.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 460aaa7a87..8c333b4294 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -593,11 +593,8 @@ impl ServiceInner { } for zone in &sled_config.zones { - // XXX-dap TODO-cleanup kind of a cheating way to use the - // existing implementation - let native_zone_config = zone.clone(); if let Some((dataset_name, dataset_address)) = - native_zone_config.dataset_name_and_address() + zone.dataset_name_and_address() { datasets.push(NexusTypes::DatasetCreateRequest { zpool_id: dataset_name.pool().id(), From d76c2f041bcfcd1abfa74ff0fb5224f54df7bed7 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 16 Nov 2023 00:58:32 +0000 Subject: [PATCH 26/44] reject old generations and also ignore that on the client side --- sled-agent/src/rack_setup/service.rs | 27 +++++++++++++++++++++------ sled-agent/src/services.rs | 12 +++++++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 8c333b4294..a4f3cef936 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -275,11 +275,27 @@ impl ServiceInner { self.log, "attempting to set up sled's Omicron zones: {:?}", zones_config ); - client - .omicron_zones_put(&zones_config.clone().into()) - .await - .map_err(BackoffError::transient)?; - Ok::<(), BackoffError>>(()) + let result = + client.omicron_zones_put(&zones_config.clone().into()).await; + let Err(error) = result else { + return Ok::< + (), + BackoffError>, + >(()); + }; + + if let sled_agent_client::Error::ErrorResponse(response) = &error { + if let Some(code) = &response.error_code { + if code == "RequestedConfigOutdated" { + // XXX-dap is this really how to do this? look at what + // nexus does when propagating DNS maybe? or maybe the + // DNS tests? + return Ok(()); + } + } + } + + return Err(BackoffError::transient(error)); }; let log_failure = |error, delay| { warn!( @@ -315,7 +331,6 @@ impl ServiceInner { ) -> Result<(), SetupServiceError> { futures::future::join_all(configs.iter().map( |(sled_address, zones_config)| async move { - // XXX-dap check for the error indicating an older generation self.initialize_zones_on_sled(*sled_address, zones_config) .await?; Ok(()) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index ddfe84573b..7d92d12d3f 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -196,9 +196,6 @@ pub enum Error { #[error("Could not initialize service {service} as requested: {message}")] BadServiceRequest { service: String, message: String }, - #[error("Services already configured for this Sled Agent")] - ServicesAlreadyConfigured, - #[error("Failed to get address: {0}")] GetAddressFailure(#[from] illumos_utils::zone::GetAddressError), @@ -223,6 +220,9 @@ pub enum Error { #[error("Error querying simnet devices")] Simnet(#[from] GetSimnetError), + #[error("Requested generation ({0}) is older than current ({0})")] + RequestedConfigOutdated(Generation, Generation), + #[error("Error migrating old-format services ledger")] ServicesMigration(anyhow::Error), } @@ -2601,6 +2601,12 @@ impl ServiceManager { }; let ledger_zone_config = ledger.data_mut(); + if ledger_zone_config.generation > request.generation { + return Err(Error::RequestedConfigOutdated( + request.generation, + ledger_zone_config.generation, + )); + } let new_config = self .ensure_all_omicron_zones( From 3a1f393830cf3510013188c89c0c6c3e211fc2b9 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 16 Nov 2023 18:23:44 +0000 Subject: [PATCH 27/44] write some docs and do some cleanup --- sled-agent/src/params.rs | 77 ++++-- sled-agent/src/rack_setup/service.rs | 14 +- sled-agent/src/services.rs | 72 ++++-- sled-agent/src/services_migration.rs | 353 +++++++++++++-------------- 4 files changed, 293 insertions(+), 223 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 54c0eca73c..8ec46ec3c6 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -313,12 +313,23 @@ impl std::fmt::Display for ZoneType { } } -/// Describes the set of Omicron zones running on a sled +/// Describes the set of Omicron-managed zones running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] pub struct OmicronZonesConfig { + /// generation number of this configuration + /// + /// This generation number is owned by the control plane (i.e., RSS or + /// Nexus, depending on whether RSS-to-Nexus handoff has happened). It + /// should not be bumped within Sled Agent. + /// + /// Sled Agent rejects attempts to set the configuration to a generation + /// older than the one it's currently running. + // XXX-dap rename this to version pub generation: Generation, + + /// list of running zones pub zones: Vec, } @@ -331,7 +342,7 @@ impl From for sled_agent_client::types::OmicronZonesConfig { } } -/// Describes one Omicron zone running on a sled +/// Describes one Omicron-managed zone running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] @@ -352,24 +363,31 @@ impl From for sled_agent_client::types::OmicronZoneConfig { } impl OmicronZoneConfig { + /// If this kind of zone has an associated dataset, returns the dataset's + /// name. Othrwise, returns `None`. pub fn dataset_name(&self) -> Option { self.zone_type.dataset_name() } + /// If this kind of zone has an associated dataset, return the dataset's + /// name and the associated "service address". Otherwise, returns `None`. pub fn dataset_name_and_address( &self, ) -> Option<(DatasetName, SocketAddrV6)> { self.zone_type.dataset_name_and_address() } - // XXX-dap TODO-doc + /// Returns the name that is (or will be) used for the illumos zone + /// associated with this zone pub fn zone_name(&self) -> String { illumos_utils::running_zone::InstalledZone::get_zone_name( - self.zone_type.zone_type_str(), + &self.zone_type.zone_type_str(), Some(self.id), ) } + /// Returns the structure that describes this zone to Nexus during rack + /// initialization pub fn into_nexus_service_req( &self, sled_id: Uuid, @@ -531,8 +549,8 @@ impl From for sled_agent_client::types::OmicronZoneDataset { } } -/// Describes what component is running in this zone and its associated -/// type-specific configuration +/// Describes what kind of zone this is (i.e., what component is running in it) +/// as well as any type-specific configuration #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] @@ -619,24 +637,31 @@ pub enum OmicronZoneType { } impl OmicronZoneType { - // XXX-dap TODO-doc must match ZoneType - pub fn zone_type_str(&self) -> &str { + /// Returns a canonical string identifying the type of zone this is + /// + /// This is used to construct zone names, SMF service names, etc. + pub fn zone_type_str(&self) -> String { match self { - OmicronZoneType::BoundaryNtp { .. } => "ntp", - OmicronZoneType::InternalNtp { .. } => "ntp", - - OmicronZoneType::Clickhouse { .. } => "clickhouse", - OmicronZoneType::ClickhouseKeeper { .. } => "clickhouse_keeper", - OmicronZoneType::CockroachDb { .. } => "cockroachdb", - OmicronZoneType::Crucible { .. } => "crucible", - OmicronZoneType::CruciblePantry { .. } => "crucible_pantry", - OmicronZoneType::ExternalDns { .. } => "external_dns", - OmicronZoneType::InternalDns { .. } => "internal_dns", - OmicronZoneType::Nexus { .. } => "nexus", - OmicronZoneType::Oximeter { .. } => "oximeter", + OmicronZoneType::BoundaryNtp { .. } + | OmicronZoneType::InternalNtp { .. } => ZoneType::Ntp, + + OmicronZoneType::Clickhouse { .. } => ZoneType::Clickhouse, + OmicronZoneType::ClickhouseKeeper { .. } => { + ZoneType::ClickhouseKeeper + } + OmicronZoneType::CockroachDb { .. } => ZoneType::CockroachDb, + OmicronZoneType::Crucible { .. } => ZoneType::Crucible, + OmicronZoneType::CruciblePantry { .. } => ZoneType::CruciblePantry, + OmicronZoneType::ExternalDns { .. } => ZoneType::ExternalDns, + OmicronZoneType::InternalDns { .. } => ZoneType::InternalDns, + OmicronZoneType::Nexus { .. } => ZoneType::Nexus, + OmicronZoneType::Oximeter { .. } => ZoneType::Oximeter, } + .to_string() } + /// If this kind of zone has an associated dataset, returns the dataset's + /// name. Othrwise, returns `None`. // XXX-dap should the caller (RSS) should specify this directly? That // eliminates one reason why Sled Agent needs to know about what kind of // dataset it's looking at. @@ -644,6 +669,8 @@ impl OmicronZoneType { self.dataset_name_and_address().map(|d| d.0) } + /// If this kind of zone has an associated dataset, return the dataset's + /// name and the associated "service address". Otherwise, returns `None`. pub fn dataset_name_and_address( &self, ) -> Option<(DatasetName, SocketAddrV6)> { @@ -682,7 +709,15 @@ impl OmicronZoneType { impl crate::smf_helper::Service for OmicronZoneType { fn service_name(&self) -> String { - self.zone_type_str().to_owned() + // For historical reasons, crucible-pantry is the only zone type whose + // SMF service does not match the canonical name that we use for the + // zone. + match self { + OmicronZoneType::CruciblePantry { .. } => { + "crucible/pantry".to_owned() + } + _ => self.zone_type_str(), + } } fn smf_name(&self) -> String { format!("svc:/oxide/{}", self.service_name()) diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index a4f3cef936..876db66351 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -342,7 +342,11 @@ impl ServiceInner { Ok(()) } - // XXX-dap TODO-doc and mention that this should always be generation 1? + // Given a service plan (which describes all the zones that we want to + // deploy to all sleds), generate configurations for each sled for the very + // first config version that includes only the zones from the service plan + // matching `zone_filter`. This is used to deploy the Internal DNS zones + // before all the other zones. // XXX-dap TODO-coverage fn generate_omicron_zone_configs_gen1( service_plan: &ServicePlan, @@ -365,7 +369,13 @@ impl ServiceInner { .collect() } - // XXX-dap TODO-doc + // Given a service plan (which describes all the zones that we want to + // deploy to all sleds) and a set of configurations for each sled, generate + // a new configuration for each sled that adds all zones from the service + // plan matching `zone_filter`. The new configurations all have generation + // `generation`, which must be newer than the input configurations. This is + // used to deploy a new round of Omicron zones while leaving existing zones + // intact. See the caller for more context. // XXX-dap TODO-coverage fn augment_omicron_zone_configs( generation: Generation, diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 7d92d12d3f..e057858d4b 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -274,21 +274,12 @@ impl Config { } } -// XXX-dap TODO-doc -#[derive( - Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, -)] -pub struct OmicronZoneConfigLocal { - pub zone: OmicronZoneConfig, - // TODO: Consider collapsing "root" into OmicronZoneConfig? - #[schemars(with = "String")] - pub root: Utf8PathBuf, -} - // The filename of the ledger, within the provided directory. const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; -// XXX-dap TODO-doc +/// Combines the Nexus-provided `OmicronZonesConfig` (which describes what Nexus +/// wants for all of its zones) with the locally-determined configuration for +/// these zones. #[derive( Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, )] @@ -322,6 +313,22 @@ impl OmicronZonesConfigLocal { } } +/// Combines the Nexus-provided `OmicronZoneConfig` (which describes what Nexus +/// wants for this zone) with any locally-determined configuration (like the +/// path to the root filesystem) +#[derive( + Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, +)] +pub struct OmicronZoneConfigLocal { + pub zone: OmicronZoneConfig, + #[schemars(with = "String")] + pub root: Utf8PathBuf, +} + +/// Describes how we want a switch zone to be configured +/// +/// This is analogous to `OmicronZoneConfig`, but for the switch zone (which is +/// operated autonomously by the Sled Agent, not managed by Omicron). #[derive(Clone)] struct SwitchZoneConfig { id: Uuid, @@ -329,6 +336,11 @@ struct SwitchZoneConfig { services: Vec, } +/// Describes one of several services that may be deployed in a switch zone +/// +/// Some of these are only present in certain configurations (e.g., with a real +/// Tofino vs. SoftNPU) or are configured differently depending on the +/// configuration. // XXX-dap towards the end, rename this to SwitchService. Saving it for later // to avoid having to deal with it more than necessary in merge conflicts. #[derive(Clone)] @@ -365,18 +377,24 @@ impl crate::smf_helper::Service for ServiceType { } } +/// Combines the generic `SwitchZoneConfig` with other locally-determined +/// configuration +/// +/// This is analogous to `OmicronZoneConfigLocal`, but for the switch zone. struct SwitchZoneConfigLocal { zone: SwitchZoneConfig, root: Utf8PathBuf, } -// XXX-dap TODO-doc +/// Describes either an Omicron-managed zone or the switch zone, used for +/// functions that operate on either one or the other enum ZoneArgs<'a> { Omicron(&'a OmicronZoneConfigLocal), SledLocal(&'a SwitchZoneConfigLocal), } impl<'a> ZoneArgs<'a> { + /// If this is an Omicron zone, return its type pub fn omicron_type(&self) -> Option<&'a OmicronZoneType> { match self { ZoneArgs::Omicron(zone_config) => Some(&zone_config.zone.zone_type), @@ -384,6 +402,8 @@ impl<'a> ZoneArgs<'a> { } } + /// If this is a sled-local (switch) zone, iterate over the services it's + /// supposed to be running pub fn sled_local_services( &self, ) -> Box + 'a> { @@ -395,6 +415,7 @@ impl<'a> ZoneArgs<'a> { } } + /// Return the root filesystem path for this zone pub fn root(&self) -> &Utf8Path { match self { ZoneArgs::Omicron(zone_config) => &zone_config.root, @@ -591,7 +612,14 @@ impl ServiceManager { .collect() } - // XXX-dap TODO-doc + // 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 @@ -777,8 +805,8 @@ impl ServiceManager { // synchronization, which is a pre-requisite for the other services. We // keep `OmicronZoneType::InternalDns` because // `ensure_all_omicron_zones` is additive. - // XXX-dap This looks like a duplicate of the block above -- why do we - // do this? + // TODO This looks like a duplicate of the block above -- why do we do + // this? let all_zones_request = self .ensure_all_omicron_zones( &mut existing_zones, @@ -1126,7 +1154,7 @@ impl ServiceManager { let port = port_manager .create_port(nic, snat, external_ips, &[], DhcpCfg::default()) .map_err(|err| Error::ServicePortCreation { - service: zone_type_str.to_owned(), + service: zone_type_str.clone(), err: Box::new(err), })?; @@ -1142,7 +1170,7 @@ impl ServiceManager { let nat_create = || async { info!( self.inner.log, "creating NAT entry for service"; - "zone_type" => zone_type_str.to_owned(), + "zone_type" => &zone_type_str, ); dpd_client @@ -1166,7 +1194,7 @@ impl ServiceManager { warn!( self.inner.log, "failed to create NAT entry for service"; "error" => ?error, - "zone_type" => zone_type_str.to_owned(), + "zone_type" => &zone_type_str, ); }; retry_notify( @@ -1363,7 +1391,7 @@ impl ServiceManager { let zone_type_str = match &request { ZoneArgs::Omicron(zone_config) => { - zone_config.zone.zone_type.zone_type_str().to_owned() + zone_config.zone.zone_type.zone_type_str() } ZoneArgs::SledLocal(_) => "switch".to_string(), }; @@ -1641,7 +1669,7 @@ impl ServiceManager { self.inner.log, "Ensuring bootstrap address {} exists in {} zone", bootstrap_address.to_string(), - zone_type_str, + &zone_type_str, ); running_zone.ensure_bootstrap_address(*bootstrap_address).await?; info!( @@ -2039,7 +2067,7 @@ impl ServiceManager { panic!( "{} is a service which exists as part of a \ self-assembling zone", - zone_config.zone.zone_type.zone_type_str(), + &zone_config.zone.zone_type.zone_type_str(), ) } }; diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index ffb658a7b0..19145a2c7d 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -2,14 +2,33 @@ // 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/. -//! XXX-dap TODO-doc this is probably where we could use a big block comment -//! explaining the big picture here +//! 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::{ DatasetKind, OmicronZoneConfig, OmicronZoneDataset, OmicronZoneType, ZoneType, }; use crate::services::{OmicronZoneConfigLocal, OmicronZonesConfigLocal}; +use crate::storage::dataset::DatasetName; use anyhow::{anyhow, ensure, Context}; use camino::Utf8PathBuf; use omicron_common::api::external::Generation; @@ -19,188 +38,18 @@ use omicron_common::api::internal::shared::{ use omicron_common::ledger::Ledgerable; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::fmt::{Debug, Formatter, Result as FormatResult}; +use std::fmt::Debug; use std::net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6}; use uuid::Uuid; -/// 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. - // TODO: Should this be removed? If we have UUIDs on the services, what's - // the point of this? - 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, -} - -/// 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, - }, -} - -impl std::fmt::Display for ServiceType { - fn fmt(&self, f: &mut Formatter<'_>) -> FormatResult { - match self { - ServiceType::Nexus { .. } => write!(f, "nexus"), - ServiceType::ExternalDns { .. } => write!(f, "external_dns"), - ServiceType::InternalDns { .. } => write!(f, "internal_dns"), - ServiceType::Oximeter { .. } => write!(f, "oximeter"), - ServiceType::CruciblePantry { .. } => write!(f, "crucible/pantry"), - ServiceType::BoundaryNtp { .. } - | ServiceType::InternalNtp { .. } => write!(f, "ntp"), - - ServiceType::Clickhouse { .. } => write!(f, "clickhouse"), - ServiceType::ClickhouseKeeper { .. } => { - write!(f, "clickhouse_keeper") - } - ServiceType::CockroachDb { .. } => write!(f, "cockroachdb"), - ServiceType::Crucible { .. } => write!(f, "crucible"), - } - } -} - -/// Describes a request to provision a specific dataset -#[derive( - Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, -)] -struct DatasetRequest { - id: Uuid, - name: crate::storage::dataset::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() }) - } -} - -// 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, - // TODO: Consider collapsing "root" into ServiceZoneRequest - #[schemars(with = "String")] - root: Utf8PathBuf, -} - -// The filename of the ledger, within the provided directory. +/// The filename of the ledger containing this old-format configuration. pub const SERVICES_LEDGER_FILENAME: &str = "services.json"; -// A wrapper around `ZoneRequest`, which allows it to be serialized -// to a JSON file. -// XXX-dap TODO-doc +/// 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, } @@ -236,11 +85,20 @@ impl TryFrom for OmicronZonesConfigLocal { .into_iter() .map(OmicronZoneConfigLocal::try_from) .collect::, _>>() - .context("mapping `AllServiceRequests` to `ZonesConfig`")?; + .context("mapping `AllZonesRequests` to `ZonesConfig`")?; Ok(OmicronZonesConfigLocal { generation: Generation::new(), 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; @@ -252,6 +110,24 @@ impl TryFrom for OmicronZoneConfigLocal { } } +/// 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; @@ -483,6 +359,127 @@ impl TryFrom for OmicronZoneConfig { } } +/// 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; From 98492b50f8eed86aa8e48a217a8af16affc6f06e Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 16 Nov 2023 18:47:15 +0000 Subject: [PATCH 28/44] generation -> version --- openapi/sled-agent.json | 18 ++++--- schema/all-zone-requests.json | 9 +++- schema/all-zones-requests.json | 10 ++-- sled-agent/src/params.rs | 14 ++---- sled-agent/src/rack_setup/service.rs | 72 ++++++++++++++-------------- sled-agent/src/services.rs | 28 +++++------ sled-agent/src/services_migration.rs | 2 +- 7 files changed, 82 insertions(+), 71 deletions(-) diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index f889aa0fa8..bcc44c2d3c 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -2396,7 +2396,7 @@ ] }, "OmicronZoneConfig": { - "description": "Describes one Omicron zone running on a sled", + "description": "Describes one Omicron-managed zone running on a sled", "type": "object", "properties": { "id": { @@ -2430,7 +2430,7 @@ ] }, "OmicronZoneType": { - "description": "Describes what component is running in this zone and its associated type-specific configuration", + "description": "Describes what kind of zone this is (i.e., what component is running in it) as well as any type-specific configuration", "oneOf": [ { "type": "object", @@ -2775,13 +2775,19 @@ ] }, "OmicronZonesConfig": { - "description": "Describes the set of Omicron zones running on a sled", + "description": "Describes the set of Omicron-managed zones running on a sled", "type": "object", "properties": { - "generation": { - "$ref": "#/components/schemas/Generation" + "version": { + "description": "version number of this configuration\n\nThis version number is owned by the control plane (i.e., RSS or Nexus, depending on whether RSS-to-Nexus handoff has happened). It should not be bumped within Sled Agent.\n\nSled Agent rejects attempts to set the configuration to a version older than the one it's currently running.", + "allOf": [ + { + "$ref": "#/components/schemas/Generation" + } + ] }, "zones": { + "description": "list of running zones", "type": "array", "items": { "$ref": "#/components/schemas/OmicronZoneConfig" @@ -2789,7 +2795,7 @@ } }, "required": [ - "generation", + "version", "zones" ] }, diff --git a/schema/all-zone-requests.json b/schema/all-zone-requests.json index 5c11435db0..4eb56d379d 100644 --- a/schema/all-zone-requests.json +++ b/schema/all-zone-requests.json @@ -1,6 +1,7 @@ { "$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", @@ -8,7 +9,12 @@ ], "properties": { "generation": { - "$ref": "#/definitions/Generation" + "description": "ledger generation (not an Omicron-provided generation)", + "allOf": [ + { + "$ref": "#/definitions/Generation" + } + ] }, "requests": { "type": "array", @@ -719,6 +725,7 @@ "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", diff --git a/schema/all-zones-requests.json b/schema/all-zones-requests.json index 2c2d5225c5..84aba2972b 100644 --- a/schema/all-zones-requests.json +++ b/schema/all-zones-requests.json @@ -1,13 +1,14 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "OmicronZonesConfigLocal", + "description": "Combines the Nexus-provided `OmicronZonesConfig` (which describes what Nexus wants for all of its zones) with the locally-determined configuration for these zones.", "type": "object", "required": [ - "generation", + "version", "zones" ], "properties": { - "generation": { + "version": { "$ref": "#/definitions/Generation" }, "zones": { @@ -175,7 +176,7 @@ ] }, "OmicronZoneConfig": { - "description": "Describes one Omicron zone running on a sled", + "description": "Describes one Omicron-managed zone running on a sled", "type": "object", "required": [ "id", @@ -197,6 +198,7 @@ } }, "OmicronZoneConfigLocal": { + "description": "Combines the Nexus-provided `OmicronZoneConfig` (which describes what Nexus wants for this zone) with any locally-determined configuration (like the path to the root filesystem)", "type": "object", "required": [ "root", @@ -224,7 +226,7 @@ } }, "OmicronZoneType": { - "description": "Describes what component is running in this zone and its associated type-specific configuration", + "description": "Describes what kind of zone this is (i.e., what component is running in it) as well as any type-specific configuration", "oneOf": [ { "type": "object", diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 8ec46ec3c6..43e628619f 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -318,16 +318,15 @@ impl std::fmt::Display for ZoneType { Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] pub struct OmicronZonesConfig { - /// generation number of this configuration + /// version number of this configuration /// - /// This generation number is owned by the control plane (i.e., RSS or + /// This version number is owned by the control plane (i.e., RSS or /// Nexus, depending on whether RSS-to-Nexus handoff has happened). It /// should not be bumped within Sled Agent. /// - /// Sled Agent rejects attempts to set the configuration to a generation + /// Sled Agent rejects attempts to set the configuration to a version /// older than the one it's currently running. - // XXX-dap rename this to version - pub generation: Generation, + pub version: Generation, /// list of running zones pub zones: Vec, @@ -336,7 +335,7 @@ pub struct OmicronZonesConfig { impl From for sled_agent_client::types::OmicronZonesConfig { fn from(local: OmicronZonesConfig) -> Self { Self { - generation: local.generation.into(), + version: local.version.into(), zones: local.zones.into_iter().map(|s| s.into()).collect(), } } @@ -662,9 +661,6 @@ impl OmicronZoneType { /// If this kind of zone has an associated dataset, returns the dataset's /// name. Othrwise, returns `None`. - // XXX-dap should the caller (RSS) should specify this directly? That - // eliminates one reason why Sled Agent needs to know about what kind of - // dataset it's looking at. pub fn dataset_name(&self) -> Option { self.dataset_name_and_address().map(|d| d.0) } diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 876db66351..7de8ef9706 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -315,7 +315,7 @@ impl ServiceInner { Ok(()) } - // Ensure that all services for a particular generation are running. + // Ensure that all services for a particular version are running. // // This is useful in a rack-setup context, where initial boot ordering // can matter for first-time-setup. @@ -352,7 +352,7 @@ impl ServiceInner { service_plan: &ServicePlan, zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), ) -> HashMap { - let generation = Generation::new(); + let version = Generation::new(); service_plan .services .iter() @@ -363,7 +363,7 @@ impl ServiceInner { .filter(|z| zone_filter(&z.zone_type)) .cloned() .collect(); - let config = OmicronZonesConfig { generation, zones }; + let config = OmicronZonesConfig { version, zones }; (*sled_address, config) }) .collect() @@ -372,13 +372,13 @@ impl ServiceInner { // Given a service plan (which describes all the zones that we want to // deploy to all sleds) and a set of configurations for each sled, generate // a new configuration for each sled that adds all zones from the service - // plan matching `zone_filter`. The new configurations all have generation - // `generation`, which must be newer than the input configurations. This is + // plan matching `zone_filter`. The new configurations all have version + // `version`, which must be newer than the input configurations. This is // used to deploy a new round of Omicron zones while leaving existing zones // intact. See the caller for more context. // XXX-dap TODO-coverage fn augment_omicron_zone_configs( - generation: Generation, + version: Generation, service_plan: &ServicePlan, last_configs: &HashMap, zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), @@ -389,7 +389,7 @@ impl ServiceInner { .map(|(sled_address, sled_config)| { let mut zones = match last_configs.get(sled_address) { Some(config) => { - assert!(generation > config.generation.next()); + assert!(version > config.version.next()); config.zones.clone() } None => Vec::new(), @@ -408,7 +408,7 @@ impl ServiceInner { .cloned(), ); - let config = OmicronZonesConfig { generation, zones }; + let config = OmicronZonesConfig { version, zones }; (*sled_address, config) }) .collect() @@ -1012,35 +1012,35 @@ impl ServiceInner { // The service plan describes all the zones that we will eventually // deploy on each sled. But we cannot currently just deploy them all // concurrently. We'll do it in four stages, each corresponding to a - // "generation" of each sled's configuration. + // version of each sled's configuration. // - // - generation 1: internal DNS only - // - generation 2: internal DNS + NTP servers - // - generation 3: internal DNS + NTP servers + CockroachDB - // - generation 4: everything + // - version 1: internal DNS only + // - version 2: internal DNS + NTP servers + // - version 3: internal DNS + NTP servers + CockroachDB + // - version 4: everything // // At each stage, we're specifying a complete configuration of what - // should be running on the sled -- including this generation number. - // And Sled Agents will reject requests for generations older than the - // one they're currently running. Thus, the generation number is - // a piece of global, distributed state. + // should be running on the sled -- including this version number. + // And Sled Agents will reject requests for versions older than the + // one they're currently running. Thus, the version number is a piece + // of global, distributed state. // // For now, we hardcode the three requests we make to use these three - // generation numbers (1, 2, and 3). - let generation1_dns_only = Generation::new(); - let generation2_dns_and_ntp = generation1_dns_only.next(); - let generation3_cockroachdb = generation2_dns_and_ntp.next(); - let generation4_everything = generation3_cockroachdb.next(); + // version numbers (1, 2, and 3). + let version1_dns_only = Generation::new(); + let version2_dns_and_ntp = version1_dns_only.next(); + let version3_cockroachdb = version2_dns_and_ntp.next(); + let version4_everything = version3_cockroachdb.next(); // Set up internal DNS services first and write the initial // DNS configuration to the internal DNS servers. - let gen1_configs = Self::generate_omicron_zone_configs_gen1( + let v1_configs = Self::generate_omicron_zone_configs_gen1( &service_plan, &|zone_type: &OmicronZoneType| { matches!(zone_type, OmicronZoneType::InternalDns { .. }) }, ); - self.ensure_zone_config_at_least(&gen1_configs).await?; + self.ensure_zone_config_at_least(&v1_configs).await?; self.initialize_internal_dns_records(&service_plan).await?; // Ask MGS in each switch zone which switch it is. @@ -1049,10 +1049,10 @@ impl ServiceInner { .await; // Next start up the NTP services. - let gen2_configs = Self::augment_omicron_zone_configs( - generation2_dns_and_ntp, + let v2_configs = Self::augment_omicron_zone_configs( + version2_dns_and_ntp, &service_plan, - &gen1_configs, + &v1_configs, &|zone_type: &OmicronZoneType| { matches!( zone_type, @@ -1061,7 +1061,7 @@ impl ServiceInner { ) }, ); - self.ensure_zone_config_at_least(&gen2_configs).await?; + self.ensure_zone_config_at_least(&v2_configs).await?; // Wait until time is synchronized on all sleds before proceeding. self.wait_for_timesync(&sled_addresses).await?; @@ -1069,28 +1069,28 @@ impl ServiceInner { info!(self.log, "Finished setting up Internal DNS and NTP"); // Wait until Cockroach has been initialized before running Nexus. - let gen3_configs = Self::augment_omicron_zone_configs( - generation3_cockroachdb, + let v3_configs = Self::augment_omicron_zone_configs( + version3_cockroachdb, &service_plan, - &gen2_configs, + &v2_configs, &|zone_type: &OmicronZoneType| { matches!(zone_type, OmicronZoneType::CockroachDb { .. }) }, ); - self.ensure_zone_config_at_least(&gen3_configs).await?; + self.ensure_zone_config_at_least(&v3_configs).await?; // Now that datasets and zones have started for CockroachDB, // perform one-time initialization of the cluster. self.initialize_cockroach(&service_plan).await?; // Issue the rest of the zone initialization requests. - let gen4_configs = Self::augment_omicron_zone_configs( - generation4_everything, + let v4_configs = Self::augment_omicron_zone_configs( + version4_everything, &service_plan, - &gen3_configs, + &v3_configs, &|_| true, ); - self.ensure_zone_config_at_least(&gen4_configs).await?; + self.ensure_zone_config_at_least(&v4_configs).await?; info!(self.log, "Finished setting up services"); diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index e057858d4b..6cdf02c477 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -220,7 +220,7 @@ pub enum Error { #[error("Error querying simnet devices")] Simnet(#[from] GetSimnetError), - #[error("Requested generation ({0}) is older than current ({0})")] + #[error("Requested version ({0}) is older than current ({0})")] RequestedConfigOutdated(Generation, Generation), #[error("Error migrating old-format services ledger")] @@ -284,13 +284,13 @@ const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, )] pub struct OmicronZonesConfigLocal { - pub generation: Generation, + pub version: Generation, pub zones: Vec, } impl Ledgerable for OmicronZonesConfigLocal { fn is_newer_than(&self, other: &OmicronZonesConfigLocal) -> bool { - self.generation >= other.generation + self.version >= other.version } fn generation_bump(&mut self) { @@ -300,14 +300,14 @@ impl Ledgerable for OmicronZonesConfigLocal { // This gets invoked when the ledger is committed. I think we could // either keep a separate generation number (and use that in // `is_newer_than()`) or else make this a noop? - self.generation = self.generation.next(); + self.version = self.version.next(); } } impl OmicronZonesConfigLocal { pub fn to_omicron_zones_config(self) -> OmicronZonesConfig { OmicronZonesConfig { - generation: self.generation, + version: self.version, zones: self.zones.into_iter().map(|z| z.zone).collect(), } } @@ -2576,7 +2576,7 @@ impl ServiceManager { OmicronZonesConfigLocal { // XXX-dap this means Nexus must use a newer generation // for its first one - generation: Generation::new(), + version: Generation::new(), zones: vec![], }, ), @@ -2584,7 +2584,7 @@ impl ServiceManager { let ledger_zone_config = ledger.data(); Ok(OmicronZonesConfig { - generation: ledger_zone_config.generation, + version: ledger_zone_config.version, zones: ledger_zone_config .zones .iter() @@ -2622,17 +2622,17 @@ impl ServiceManager { // XXX-dap this means Nexus must use a newer generation // for its first one. Even better would be if this // whole object could be `None` - generation: Generation::new(), + version: Generation::new(), zones: vec![], }, ), }; let ledger_zone_config = ledger.data_mut(); - if ledger_zone_config.generation > request.generation { + if ledger_zone_config.version > request.version { return Err(Error::RequestedConfigOutdated( - request.generation, - ledger_zone_config.generation, + request.version, + ledger_zone_config.version, )); } @@ -2779,7 +2779,7 @@ impl ServiceManager { } Ok(OmicronZonesConfigLocal { - generation: new_request.generation, + version: new_request.version, zones: new_zones, }) } @@ -3577,7 +3577,7 @@ mod test { let address = SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - generation: Generation::new().next(), + version: Generation::new().next(), zones: vec![OmicronZoneConfig { id, underlay_address: Ipv6Addr::LOCALHOST, @@ -3594,7 +3594,7 @@ mod test { let address = SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - generation: Generation::new().next(), + version: Generation::new().next(), zones: vec![OmicronZoneConfig { id, underlay_address: Ipv6Addr::LOCALHOST, diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index 19145a2c7d..79b084bf35 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -86,7 +86,7 @@ impl TryFrom for OmicronZonesConfigLocal { .map(OmicronZoneConfigLocal::try_from) .collect::, _>>() .context("mapping `AllZonesRequests` to `ZonesConfig`")?; - Ok(OmicronZonesConfigLocal { generation: Generation::new(), zones }) + Ok(OmicronZonesConfigLocal { version: Generation::new(), zones }) } } From f5bf93d349118995ba70a019f41915e7c35a3a53 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 16 Nov 2023 20:04:39 +0000 Subject: [PATCH 29/44] clean up version numbers --- sled-agent/src/params.rs | 3 ++ sled-agent/src/rack_setup/service.rs | 58 +++++++++++++++---------- sled-agent/src/services.rs | 65 +++++++++++++++------------- sled-agent/src/services_migration.rs | 50 +++++++++++++++++---- 4 files changed, 114 insertions(+), 62 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 43e628619f..88f567ceed 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -313,6 +313,9 @@ impl std::fmt::Display for ZoneType { } } +/// Version 1 of `OmicronZonesConfig` is always the set of no zones. +pub const OMICRON_ZONES_CONFIG_INITIAL_VERSION: u32 = 1; + /// Describes the set of Omicron-managed zones running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 7de8ef9706..3cbc11b7e6 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -64,7 +64,10 @@ use crate::bootstrap::params::BootstrapAddressDiscovery; use crate::bootstrap::params::StartSledAgentRequest; use crate::bootstrap::rss_handle::BootstrapAgentHandle; use crate::nexus::d2n_params; -use crate::params::{OmicronZoneType, OmicronZonesConfig, TimeSync}; +use crate::params::{ + OmicronZoneType, OmicronZonesConfig, TimeSync, + OMICRON_ZONES_CONFIG_INITIAL_VERSION, +}; use crate::rack_setup::plan::service::{ Plan as ServicePlan, PlanError as ServicePlanError, }; @@ -1011,13 +1014,18 @@ impl ServiceInner { // The service plan describes all the zones that we will eventually // deploy on each sled. But we cannot currently just deploy them all - // concurrently. We'll do it in four stages, each corresponding to a + // concurrently. We'll do it in a few stages, each corresponding to a // version of each sled's configuration. // - // - version 1: internal DNS only - // - version 2: internal DNS + NTP servers - // - version 3: internal DNS + NTP servers + CockroachDB - // - version 4: everything + // - version 1: no services running + // (We don't have to do anything for this. But we do + // reserve this version number for "no services running" so + // that sled agents can begin with an initial, valid + // OmicronZonesConfig before they've got anything running.) + // - version 2: internal DNS only + // - version 3: internal DNS + NTP servers + // - version 4: internal DNS + NTP servers + CockroachDB + // - version 5: everything // // At each stage, we're specifying a complete configuration of what // should be running on the sled -- including this version number. @@ -1027,20 +1035,22 @@ impl ServiceInner { // // For now, we hardcode the three requests we make to use these three // version numbers (1, 2, and 3). - let version1_dns_only = Generation::new(); - let version2_dns_and_ntp = version1_dns_only.next(); - let version3_cockroachdb = version2_dns_and_ntp.next(); - let version4_everything = version3_cockroachdb.next(); + let version1_nothing = + Generation::from(OMICRON_ZONES_CONFIG_INITIAL_VERSION); + let version2_dns_only = version1_nothing.next(); + let version3_dns_and_ntp = version2_dns_only.next(); + let version4_cockroachdb = version3_dns_and_ntp.next(); + let version5_everything = version4_cockroachdb.next(); // Set up internal DNS services first and write the initial // DNS configuration to the internal DNS servers. - let v1_configs = Self::generate_omicron_zone_configs_gen1( + let v2configs = Self::generate_omicron_zone_configs_gen1( &service_plan, &|zone_type: &OmicronZoneType| { matches!(zone_type, OmicronZoneType::InternalDns { .. }) }, ); - self.ensure_zone_config_at_least(&v1_configs).await?; + self.ensure_zone_config_at_least(&v2configs).await?; self.initialize_internal_dns_records(&service_plan).await?; // Ask MGS in each switch zone which switch it is. @@ -1049,10 +1059,10 @@ impl ServiceInner { .await; // Next start up the NTP services. - let v2_configs = Self::augment_omicron_zone_configs( - version2_dns_and_ntp, + let v3configs = Self::augment_omicron_zone_configs( + version3_dns_and_ntp, &service_plan, - &v1_configs, + &v2configs, &|zone_type: &OmicronZoneType| { matches!( zone_type, @@ -1061,7 +1071,7 @@ impl ServiceInner { ) }, ); - self.ensure_zone_config_at_least(&v2_configs).await?; + self.ensure_zone_config_at_least(&v3configs).await?; // Wait until time is synchronized on all sleds before proceeding. self.wait_for_timesync(&sled_addresses).await?; @@ -1069,28 +1079,28 @@ impl ServiceInner { info!(self.log, "Finished setting up Internal DNS and NTP"); // Wait until Cockroach has been initialized before running Nexus. - let v3_configs = Self::augment_omicron_zone_configs( - version3_cockroachdb, + let v4configs = Self::augment_omicron_zone_configs( + version4_cockroachdb, &service_plan, - &v2_configs, + &v3configs, &|zone_type: &OmicronZoneType| { matches!(zone_type, OmicronZoneType::CockroachDb { .. }) }, ); - self.ensure_zone_config_at_least(&v3_configs).await?; + self.ensure_zone_config_at_least(&v4configs).await?; // Now that datasets and zones have started for CockroachDB, // perform one-time initialization of the cluster. self.initialize_cockroach(&service_plan).await?; // Issue the rest of the zone initialization requests. - let v4_configs = Self::augment_omicron_zone_configs( - version4_everything, + let v5configs = Self::augment_omicron_zone_configs( + version5_everything, &service_plan, - &v3_configs, + &v4configs, &|_| true, ); - self.ensure_zone_config_at_least(&v4_configs).await?; + self.ensure_zone_config_at_least(&v5configs).await?; info!(self.log, "Finished setting up services"); diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 6cdf02c477..db87ea8166 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -284,30 +284,45 @@ const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, )] pub struct OmicronZonesConfigLocal { - pub version: Generation, + /// version of the Omicron-provided part of the configuration + /// + /// This version number is outside of Sled Agent's control. We store + /// exactly what we were given and use this number to decide when to + /// fail requests to establish an outdated configuration. + /// + /// You can think of this as a major version number, with `ledger_version` + /// being a minor version number. See `is_newer_than()`. + pub omicron_version: Generation, + + /// ledger-managed version + /// + /// This version is managed by the ledger facility itself. It's bumped + /// whenever we write a new ledger. In practice, we don't currently have + /// any reason to bump this _for a given Omicron version_ so it's somewhat + /// redundant. In principle, if we needed to modify the ledgered + /// configuration due to some event that doesn't change the Omicron config + /// (e.g., if we wanted to move the root filesystem to a different path), we + /// could do that by bumping this version. + pub ledger_version: Generation, pub zones: Vec, } impl Ledgerable for OmicronZonesConfigLocal { fn is_newer_than(&self, other: &OmicronZonesConfigLocal) -> bool { - self.version >= other.version + self.omicron_version > other.omicron_version + || (self.omicron_version == other.omicron_version + && self.ledger_version >= other.ledger_version) } fn generation_bump(&mut self) { - // XXX-dap what do we do here? this is not right. The only one who - // can bump this is Nexus. Maybe we just keep it as is? - // - // This gets invoked when the ledger is committed. I think we could - // either keep a separate generation number (and use that in - // `is_newer_than()`) or else make this a noop? - self.version = self.version.next(); + self.ledger_version = self.ledger_version.next(); } } impl OmicronZonesConfigLocal { pub fn to_omicron_zones_config(self) -> OmicronZonesConfig { OmicronZonesConfig { - version: self.version, + version: self.omicron_version, zones: self.zones.into_iter().map(|z| z.zone).collect(), } } @@ -2574,23 +2589,14 @@ impl ServiceManager { log, zone_ledger_paths.clone(), OmicronZonesConfigLocal { - // XXX-dap this means Nexus must use a newer generation - // for its first one - version: Generation::new(), + omicron_version: Generation::new(), + ledger_version: Generation::new(), zones: vec![], }, ), }; - let ledger_zone_config = ledger.data(); - Ok(OmicronZonesConfig { - version: ledger_zone_config.version, - zones: ledger_zone_config - .zones - .iter() - .map(|z| z.zone.clone()) - .collect(), - }) + Ok(ledger.data().clone().to_omicron_zones_config()) } /// Ensures that particular Omicron zones are running @@ -2619,20 +2625,18 @@ impl ServiceManager { log, zone_ledger_paths.clone(), OmicronZonesConfigLocal { - // XXX-dap this means Nexus must use a newer generation - // for its first one. Even better would be if this - // whole object could be `None` - version: Generation::new(), + omicron_version: request.version, + ledger_version: Generation::new(), zones: vec![], }, ), }; let ledger_zone_config = ledger.data_mut(); - if ledger_zone_config.version > request.version { + if ledger_zone_config.omicron_version > request.version { return Err(Error::RequestedConfigOutdated( request.version, - ledger_zone_config.version, + ledger_zone_config.omicron_version, )); } @@ -2779,7 +2783,10 @@ impl ServiceManager { } Ok(OmicronZonesConfigLocal { - version: new_request.version, + omicron_version: new_request.version, + ledger_version: old_config + .map(|c| c.ledger_version) + .unwrap_or_else(Generation::new), zones: new_zones, }) } diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index 79b084bf35..d61250ebbe 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -25,7 +25,7 @@ use crate::params::{ DatasetKind, OmicronZoneConfig, OmicronZoneDataset, OmicronZoneType, - ZoneType, + ZoneType, OMICRON_ZONES_CONFIG_INITIAL_VERSION, }; use crate::services::{OmicronZoneConfigLocal, OmicronZonesConfigLocal}; use crate::storage::dataset::DatasetName; @@ -74,19 +74,51 @@ impl TryFrom for OmicronZonesConfigLocal { type Error = anyhow::Error; fn try_from(input: AllZoneRequests) -> Result { - // XXX-dap starting to think that the generation in OmicronZonesConfig - // (at least the one stored on disk) ought to be an Option or something? - // There's no correct value here. Any Nexus one needs to be treated as - // newer. The generation from the ledger does not matter. - // XXX-dap TODO-doc explain why the generation from the ledger does not - // matter here (they _all_ predate the Nexus-provided one). + // The Omicron version number that we choose here (2) deserves some + // explanation. + // + // This is supposed to be the control-plane-issued version number for + // this configuration. But any configuration that we're converting here + // predates the point where the control plane issued version numbers at + // all. So what should we assign it? Well, what are the constraints? + // + // - It must be newer than version 1 because version 1 canonically + // represents the initial state of having no zones deployed. If we + // used version 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 version 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 version number is and subsequent configurations should use + // newer version numbers. It's not a great plan for it to assume + // anything about the version 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_version = + Generation::from(OMICRON_ZONES_CONFIG_INITIAL_VERSION).next(); + + // The ledger version doesn't really matter. In case it's useful, we + // pick the version from the ledger that we loaded. + let ledger_version = input.generation; + let zones = input .requests .into_iter() .map(OmicronZoneConfigLocal::try_from) .collect::, _>>() - .context("mapping `AllZonesRequests` to `ZonesConfig`")?; - Ok(OmicronZonesConfigLocal { version: Generation::new(), zones }) + .context( + "mapping `AllZoneRequests` to `OmicronZonesConfigLocal`", + )?; + + Ok(OmicronZonesConfigLocal { omicron_version, ledger_version, zones }) } } From 7a22812b1216c0e3f256e271d714483645443329 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 16 Nov 2023 20:21:10 +0000 Subject: [PATCH 30/44] fix ignore-bad-version code --- sled-agent/src/rack_setup/service.rs | 19 ++++++++++++------- sled-agent/src/services.rs | 12 ++++++++++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 3cbc11b7e6..ff9c76a148 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -288,16 +288,21 @@ impl ServiceInner { }; if let sled_agent_client::Error::ErrorResponse(response) = &error { - if let Some(code) = &response.error_code { - if code == "RequestedConfigOutdated" { - // XXX-dap is this really how to do this? look at what - // nexus does when propagating DNS maybe? or maybe the - // DNS tests? - return Ok(()); - } + if response.status() == http::StatusCode::CONFLICT { + warn!( + self.log, + "ignoring attempt to initialize zones because \ + the server seems to be newer"; + "attempted_version" => i64::from(&zones_config.version), + "req_id" => &response.request_id, + "server_message" => &response.message, + ); + + return Ok(()); } } + // TODO Many other codes here should not be retried. return Err(BackoffError::transient(error)); }; let log_failure = |error, delay| { diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index db87ea8166..cdce151217 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -238,8 +238,16 @@ impl Error { impl From for omicron_common::api::external::Error { fn from(err: Error) -> Self { - omicron_common::api::external::Error::InternalError { - internal_message: err.to_string(), + match err { + err @ Error::RequestedConfigOutdated(_, _) => { + omicron_common::api::external::Error::conflict(&format!( + "{:#}", + err + )) + } + _ => omicron_common::api::external::Error::InternalError { + internal_message: err.to_string(), + }, } } } From 3e2ceb9acef59e15f17043645db0b402dabcc553 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Fri, 17 Nov 2023 03:45:40 +0000 Subject: [PATCH 31/44] fix setup --- sled-agent/src/rack_setup/service.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index ff9c76a148..4e76731d64 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -356,11 +356,11 @@ impl ServiceInner { // matching `zone_filter`. This is used to deploy the Internal DNS zones // before all the other zones. // XXX-dap TODO-coverage - fn generate_omicron_zone_configs_gen1( + fn generate_initial_omicron_zone_configs( + version: Generation, service_plan: &ServicePlan, zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), ) -> HashMap { - let version = Generation::new(); service_plan .services .iter() @@ -397,7 +397,7 @@ impl ServiceInner { .map(|(sled_address, sled_config)| { let mut zones = match last_configs.get(sled_address) { Some(config) => { - assert!(version > config.version.next()); + assert!(version > config.version); config.zones.clone() } None => Vec::new(), @@ -1049,7 +1049,8 @@ impl ServiceInner { // Set up internal DNS services first and write the initial // DNS configuration to the internal DNS servers. - let v2configs = Self::generate_omicron_zone_configs_gen1( + let v2configs = Self::generate_initial_omicron_zone_configs( + version2_dns_only, &service_plan, &|zone_type: &OmicronZoneType| { matches!(zone_type, OmicronZoneType::InternalDns { .. }) From 669e60060877fb594be6a0147209e4b335b7b399 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Fri, 17 Nov 2023 23:22:17 +0000 Subject: [PATCH 32/44] add tests for the phased rollout helpers --- sled-agent/src/bootstrap/params.rs | 11 + sled-agent/src/rack_setup/plan/service.rs | 77 +++-- sled-agent/src/rack_setup/service.rs | 372 ++++++++++++++++------ 3 files changed, 335 insertions(+), 125 deletions(-) diff --git a/sled-agent/src/bootstrap/params.rs b/sled-agent/src/bootstrap/params.rs index 4983383470..75ebdc6272 100644 --- a/sled-agent/src/bootstrap/params.rs +++ b/sled-agent/src/bootstrap/params.rs @@ -232,6 +232,17 @@ pub(super) mod version { pub(crate) const V1: u32 = 1; } +#[cfg(test)] +pub fn test_config() -> RackInitializeRequest { + let manifest = std::env::var("CARGO_MANIFEST_DIR") + .expect("Cannot access manifest directory"); + let manifest = camino::Utf8PathBuf::from(manifest); + let path = manifest.join("../smf/sled-agent/non-gimlet/config-rss.toml"); + let contents = std::fs::read_to_string(&path).unwrap(); + toml::from_str(&contents) + .unwrap_or_else(|e| panic!("failed to parse {:?}: {}", &path, e)) +} + #[cfg(test)] mod tests { use std::net::Ipv6Addr; diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index 7e4bbea4ec..fd7bc9f6fe 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -236,41 +236,13 @@ impl Plan { Ok(u2_zpools) } - pub async fn create( - log: &Logger, + pub fn create_transient( config: &Config, - storage: &StorageResources, - sleds: &HashMap, + mut sled_info: Vec, ) -> Result { let mut dns_builder = internal_dns::DnsConfigBuilder::new(); let mut svc_port_builder = ServicePortBuilder::new(config); - // Load the information we need about each Sled to be able to allocate - // components on it. - let mut sled_info = { - let result: Result, PlanError> = - futures::future::try_join_all(sleds.values().map( - |sled_request| async { - let subnet = sled_request.subnet; - let sled_address = get_sled_address(subnet); - let u2_zpools = - Self::get_u2_zpools_from_sled(log, sled_address) - .await?; - let is_scrimlet = - Self::is_sled_scrimlet(log, sled_address).await?; - Ok(SledInfo::new( - sled_request.id, - subnet, - sled_address, - u2_zpools, - is_scrimlet, - )) - }, - )) - .await; - result? - }; - // Scrimlets get DNS records for running Dendrite. let scrimlets: Vec<_> = sled_info.iter().filter(|s| s.is_scrimlet).collect(); @@ -681,7 +653,42 @@ impl Plan { .collect(); let dns_config = dns_builder.build(); - let plan = Self { services, dns_config }; + Ok(Self { services, dns_config }) + } + + pub async fn create( + log: &Logger, + config: &Config, + storage: &StorageResources, + sleds: &HashMap, + ) -> Result { + // Load the information we need about each Sled to be able to allocate + // components on it. + let sled_info = { + let result: Result, PlanError> = + futures::future::try_join_all(sleds.values().map( + |sled_request| async { + let subnet = sled_request.subnet; + let sled_address = get_sled_address(subnet); + let u2_zpools = + Self::get_u2_zpools_from_sled(log, sled_address) + .await?; + let is_scrimlet = + Self::is_sled_scrimlet(log, sled_address).await?; + Ok(SledInfo::new( + sled_request.id, + subnet, + sled_address, + u2_zpools, + is_scrimlet, + )) + }, + )) + .await; + result? + }; + + let plan = Self::create_transient(config, sled_info)?; // Once we've constructed a plan, write it down to durable storage. let paths: Vec = storage @@ -718,13 +725,13 @@ impl AddressBumpAllocator { } /// Wraps up the information used to allocate components to a Sled -struct SledInfo { +pub struct SledInfo { /// unique id for the sled agent - sled_id: Uuid, + pub sled_id: Uuid, /// the sled's unique IPv6 subnet subnet: Ipv6Subnet, /// the address of the Sled Agent on the sled's subnet - sled_address: SocketAddrV6, + pub sled_address: SocketAddrV6, /// the list of zpools on the Sled u2_zpools: Vec, /// spreads components across a Sled's zpools @@ -739,7 +746,7 @@ struct SledInfo { } impl SledInfo { - fn new( + pub fn new( sled_id: Uuid, subnet: Ipv6Subnet, sled_address: SocketAddrV6, diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 4e76731d64..19ba521154 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -350,78 +350,6 @@ impl ServiceInner { Ok(()) } - // Given a service plan (which describes all the zones that we want to - // deploy to all sleds), generate configurations for each sled for the very - // first config version that includes only the zones from the service plan - // matching `zone_filter`. This is used to deploy the Internal DNS zones - // before all the other zones. - // XXX-dap TODO-coverage - fn generate_initial_omicron_zone_configs( - version: Generation, - service_plan: &ServicePlan, - zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), - ) -> HashMap { - service_plan - .services - .iter() - .map(|(sled_address, sled_config)| { - let zones: Vec<_> = sled_config - .zones - .iter() - .filter(|z| zone_filter(&z.zone_type)) - .cloned() - .collect(); - let config = OmicronZonesConfig { version, zones }; - (*sled_address, config) - }) - .collect() - } - - // Given a service plan (which describes all the zones that we want to - // deploy to all sleds) and a set of configurations for each sled, generate - // a new configuration for each sled that adds all zones from the service - // plan matching `zone_filter`. The new configurations all have version - // `version`, which must be newer than the input configurations. This is - // used to deploy a new round of Omicron zones while leaving existing zones - // intact. See the caller for more context. - // XXX-dap TODO-coverage - fn augment_omicron_zone_configs( - version: Generation, - service_plan: &ServicePlan, - last_configs: &HashMap, - zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), - ) -> HashMap { - service_plan - .services - .iter() - .map(|(sled_address, sled_config)| { - let mut zones = match last_configs.get(sled_address) { - Some(config) => { - assert!(version > config.version); - config.zones.clone() - } - None => Vec::new(), - }; - - let zones_already = - zones.iter().map(|z| z.id).collect::>(); - zones.extend( - sled_config - .zones - .iter() - .filter(|z| { - !zones_already.contains(&z.id) - && zone_filter(&z.zone_type) - }) - .cloned(), - ); - - let config = OmicronZonesConfig { version, zones }; - (*sled_address, config) - }) - .collect() - } - // Configure the internal DNS servers with the initial DNS data async fn initialize_internal_dns_records( &self, @@ -1049,14 +977,17 @@ impl ServiceInner { // Set up internal DNS services first and write the initial // DNS configuration to the internal DNS servers. - let v2configs = Self::generate_initial_omicron_zone_configs( - version2_dns_only, + let v1generator = OmicronZonesConfigGenerator::initial_version( &service_plan, + version1_nothing, + ); + let v2generator = v1generator.new_version_with( + version2_dns_only, &|zone_type: &OmicronZoneType| { matches!(zone_type, OmicronZoneType::InternalDns { .. }) }, ); - self.ensure_zone_config_at_least(&v2configs).await?; + self.ensure_zone_config_at_least(v2generator.sled_configs()).await?; self.initialize_internal_dns_records(&service_plan).await?; // Ask MGS in each switch zone which switch it is. @@ -1065,10 +996,8 @@ impl ServiceInner { .await; // Next start up the NTP services. - let v3configs = Self::augment_omicron_zone_configs( + let v3generator = v2generator.new_version_with( version3_dns_and_ntp, - &service_plan, - &v2configs, &|zone_type: &OmicronZoneType| { matches!( zone_type, @@ -1077,7 +1006,7 @@ impl ServiceInner { ) }, ); - self.ensure_zone_config_at_least(&v3configs).await?; + self.ensure_zone_config_at_least(&v3generator.sled_configs()).await?; // Wait until time is synchronized on all sleds before proceeding. self.wait_for_timesync(&sled_addresses).await?; @@ -1085,28 +1014,22 @@ impl ServiceInner { info!(self.log, "Finished setting up Internal DNS and NTP"); // Wait until Cockroach has been initialized before running Nexus. - let v4configs = Self::augment_omicron_zone_configs( + let v4generator = v3generator.new_version_with( version4_cockroachdb, - &service_plan, - &v3configs, &|zone_type: &OmicronZoneType| { matches!(zone_type, OmicronZoneType::CockroachDb { .. }) }, ); - self.ensure_zone_config_at_least(&v4configs).await?; + self.ensure_zone_config_at_least(&v4generator.sled_configs()).await?; // Now that datasets and zones have started for CockroachDB, // perform one-time initialization of the cluster. self.initialize_cockroach(&service_plan).await?; // Issue the rest of the zone initialization requests. - let v5configs = Self::augment_omicron_zone_configs( - version5_everything, - &service_plan, - &v4configs, - &|_| true, - ); - self.ensure_zone_config_at_least(&v5configs).await?; + let v5generator = + v4generator.new_version_with(version5_everything, &|_| true); + self.ensure_zone_config_at_least(&v5generator.sled_configs()).await?; info!(self.log, "Finished setting up services"); @@ -1139,3 +1062,272 @@ impl ServiceInner { Ok(()) } } + +/// Facilitates creating a sequence of OmicronZonesConfig objects for each sled +/// in a service plan to enable phased rollout of services +/// +/// The service plan itself defines which zones should appear on every sled. +/// However, we want to deploy these zones in phases: first internal DNS, then +/// NTP, then CockroachDB, etc. This interface generates sled configs for each +/// phase and enforces that: +/// +/// - each version includes all zones deployed in the previous iteration +/// - each sled's version number increases with each iteration +/// +struct OmicronZonesConfigGenerator<'a> { + service_plan: &'a ServicePlan, + last_configs: HashMap, +} + +impl<'a> OmicronZonesConfigGenerator<'a> { + /// Make a set of sled configurations for an initial version where each sled + /// has nothing deployed on it + fn initial_version( + service_plan: &'a ServicePlan, + initial_version: Generation, + ) -> Self { + let last_configs = service_plan + .services + .keys() + .map(|sled_address| { + ( + *sled_address, + OmicronZonesConfig { + version: initial_version, + zones: vec![], + }, + ) + }) + .collect(); + Self { service_plan, last_configs } + } + + /// Returns the set of sled configurations produced for this version + fn sled_configs(&self) -> &HashMap { + &self.last_configs + } + + /// Produces a new set of configs for each sled based on the current set of + /// configurations, adding zones from the service plan matching + /// `zone_filter`. + /// + /// # Panics + /// + /// If `version` is not larger than the current version + fn new_version_with( + self, + version: Generation, + zone_filter: &(dyn Fn(&OmicronZoneType) -> bool + Send + Sync), + ) -> OmicronZonesConfigGenerator<'a> { + let last_configs = self + .service_plan + .services + .iter() + .map(|(sled_address, sled_config)| { + let mut zones = match self.last_configs.get(sled_address) { + Some(config) => { + assert!(version > config.version); + config.zones.clone() + } + None => Vec::new(), + }; + + let zones_already = + zones.iter().map(|z| z.id).collect::>(); + zones.extend( + sled_config + .zones + .iter() + .filter(|z| { + !zones_already.contains(&z.id) + && zone_filter(&z.zone_type) + }) + .cloned(), + ); + + let config = OmicronZonesConfig { version, zones }; + (*sled_address, config) + }) + .collect(); + Self { service_plan: self.service_plan, last_configs } + } +} + +#[cfg(test)] +mod test { + use super::OmicronZonesConfigGenerator; + use crate::{ + params::OmicronZoneType, + rack_setup::plan::service::{Plan as ServicePlan, SledInfo}, + }; + use illumos_utils::zpool::ZpoolName; + use omicron_common::{address::Ipv6Subnet, api::external::Generation}; + + fn make_test_service_plan() -> ServicePlan { + let rss_config = crate::bootstrap::params::test_config(); + let fake_sleds = vec![ + SledInfo::new( + "d4ba4bbe-8542-4907-bc8f-48df53eb5089".parse().unwrap(), + Ipv6Subnet::new("fd00:1122:3344:101::1".parse().unwrap()), + "[fd00:1122:3344:101::1]:80".parse().unwrap(), + vec![ + ZpoolName::new_internal( + "c5885278-0ae2-4f1e-9223-07f2ada818e1".parse().unwrap(), + ), + ZpoolName::new_internal( + "57465977-8275-43aa-a320-b6cd5cb20ca6".parse().unwrap(), + ), + ZpoolName::new_external( + "886f9fe7-bf70-4ddd-ae92-764dc3ed14ab".parse().unwrap(), + ), + ZpoolName::new_external( + "4c9061b1-345b-4985-8cbd-a2a899f15b68".parse().unwrap(), + ), + ZpoolName::new_external( + "b2bd488e-b187-42a0-b157-9ab0f70d91a8".parse().unwrap(), + ), + ], + true, + ), + SledInfo::new( + "b4359dea-665d-41ca-a681-f55912f2d5d0".parse().unwrap(), + Ipv6Subnet::new("fd00:1122:3344:102::1".parse().unwrap()), + "[fd00:1122:3344:102::1]:80".parse().unwrap(), + vec![ + ZpoolName::new_internal( + "34d6b5e5-a09f-4e96-a599-fa306ce6d983".parse().unwrap(), + ), + ZpoolName::new_internal( + "e9b8d1ea-da29-4b61-a493-c0ed319098da".parse().unwrap(), + ), + ZpoolName::new_external( + "37f8e903-2adb-4613-b78c-198122c289f0".parse().unwrap(), + ), + ZpoolName::new_external( + "b50f787c-97b3-4b91-a5bd-99d11fc86fb8".parse().unwrap(), + ), + ZpoolName::new_external( + "809e50c8-930e-413a-950c-69a540b688e2".parse().unwrap(), + ), + ], + true, + ), + ]; + let service_plan = + ServicePlan::create_transient(&rss_config, fake_sleds) + .expect("failed to create service plan"); + + service_plan + } + + #[test] + fn test_omicron_zone_configs() { + let service_plan = make_test_service_plan(); + + // Verify the initial state. + let g1 = Generation::new(); + let v1 = + OmicronZonesConfigGenerator::initial_version(&service_plan, g1); + assert_eq!( + service_plan.services.keys().len(), + v1.sled_configs().keys().len() + ); + for (_, configs) in v1.sled_configs() { + assert_eq!(configs.version, g1); + assert!(configs.zones.is_empty()); + } + + // Verify that we can add a bunch of zones of a given type. + let g2 = g1.next(); + let v2 = v1.new_version_with(g2, &|zone_type| { + matches!(zone_type, OmicronZoneType::InternalDns { .. }) + }); + let mut v2_nfound = 0; + for (_, config) in v2.sled_configs() { + assert_eq!(config.version, g2); + v2_nfound += config.zones.len(); + for z in &config.zones { + // The only zones we should find are the Internal DNS ones. + assert!(matches!( + &z.zone_type, + OmicronZoneType::InternalDns { .. } + )); + } + } + // There should have been at least one InternalDns zone. + assert!(v2_nfound > 0); + + // Try again to add zones of the same type. This should be a no-op. + let g3 = g2.next(); + let v3 = v2.new_version_with(g3, &|zone_type| { + matches!(zone_type, OmicronZoneType::InternalDns { .. }) + }); + let mut v3_nfound = 0; + for (_, config) in v3.sled_configs() { + assert_eq!(config.version, g3); + v3_nfound += config.zones.len(); + for z in &config.zones { + // The only zones we should find are the Internal DNS ones. + assert!(matches!( + &z.zone_type, + OmicronZoneType::InternalDns { .. } + )); + } + } + assert_eq!(v2_nfound, v3_nfound); + + // Now try adding zones of a different type. We should still have all + // the Internal DNS ones, plus a few more. + let g4 = g3.next(); + let v4 = v3.new_version_with(g4, &|zone_type| { + matches!(zone_type, OmicronZoneType::Nexus { .. }) + }); + let mut v4_nfound_dns = 0; + let mut v4_nfound = 0; + for (_, config) in v4.sled_configs() { + assert_eq!(config.version, g4); + v4_nfound += config.zones.len(); + for z in &config.zones { + match &z.zone_type { + OmicronZoneType::InternalDns { .. } => v4_nfound_dns += 1, + OmicronZoneType::Nexus { .. } => (), + _ => panic!("unexpectedly found a wrong zone type"), + } + } + } + assert_eq!(v4_nfound_dns, v3_nfound); + assert!(v4_nfound > v3_nfound); + + // Now try adding zones that match no filter. Again, this should be a + // no-op but we should still have all the same zones we had before. + let g5 = g4.next(); + let v5 = v4.new_version_with(g5, &|_| false); + let mut v5_nfound = 0; + for (_, config) in v5.sled_configs() { + assert_eq!(config.version, g5); + v5_nfound += config.zones.len(); + for z in &config.zones { + assert!(matches!( + &z.zone_type, + OmicronZoneType::InternalDns { .. } + | OmicronZoneType::Nexus { .. } + )); + } + } + assert_eq!(v4_nfound, v5_nfound); + + // Finally, try adding the rest of the zones. + let g6 = g5.next(); + let v6 = v5.new_version_with(g6, &|_| true); + let mut v6_nfound = 0; + for (sled_address, config) in v6.sled_configs() { + assert_eq!(config.version, g6); + v6_nfound += config.zones.len(); + assert_eq!( + config.zones.len(), + service_plan.services.get(sled_address).unwrap().zones.len() + ); + } + assert!(v6_nfound > v5_nfound); + } +} From 091f6812444f4c0ee0e4abd0fab9de405d426d40 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Fri, 17 Nov 2023 23:52:47 +0000 Subject: [PATCH 33/44] fix handling of same generation and fix tests after that change --- schema/all-zones-requests.json | 20 +++++++++++-- sled-agent/src/services.rs | 53 +++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/schema/all-zones-requests.json b/schema/all-zones-requests.json index 84aba2972b..25d528ed75 100644 --- a/schema/all-zones-requests.json +++ b/schema/all-zones-requests.json @@ -4,12 +4,26 @@ "description": "Combines the Nexus-provided `OmicronZonesConfig` (which describes what Nexus wants for all of its zones) with the locally-determined configuration for these zones.", "type": "object", "required": [ - "version", + "ledger_version", + "omicron_version", "zones" ], "properties": { - "version": { - "$ref": "#/definitions/Generation" + "ledger_version": { + "description": "ledger-managed version\n\nThis version is managed by the ledger facility itself. It's bumped whenever we write a new ledger. In practice, we don't currently have any reason to bump this _for a given Omicron version_ so it's somewhat redundant. In principle, if we needed to modify the ledgered configuration due to some event that doesn't change the Omicron config (e.g., if we wanted to move the root filesystem to a different path), we could do that by bumping this version.", + "allOf": [ + { + "$ref": "#/definitions/Generation" + } + ] + }, + "omicron_version": { + "description": "version of the Omicron-provided part of the configuration\n\nThis version number is outside of Sled Agent's control. We store exactly what we were given and use this number to decide when to fail requests to establish an outdated configuration.\n\nYou can think of this as a major version number, with `ledger_version` being a minor version number. See `is_newer_than()`.", + "allOf": [ + { + "$ref": "#/definitions/Generation" + } + ] }, "zones": { "type": "array", diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index cdce151217..d3c4ae3041 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -223,6 +223,9 @@ pub enum Error { #[error("Requested version ({0}) is older than current ({0})")] RequestedConfigOutdated(Generation, Generation), + #[error("Requested version {0} with different zones than before")] + RequestedConfigConflicts(Generation), + #[error("Error migrating old-format services ledger")] ServicesMigration(anyhow::Error), } @@ -239,6 +242,12 @@ impl Error { impl From for omicron_common::api::external::Error { fn from(err: Error) -> Self { match err { + err @ Error::RequestedConfigConflicts(_) => { + omicron_common::api::external::Error::invalid_request(&format!( + "{:#}", + err + )) + } err @ Error::RequestedConfigOutdated(_, _) => { omicron_common::api::external::Error::conflict(&format!( "{:#}", @@ -2633,7 +2642,7 @@ impl ServiceManager { log, zone_ledger_paths.clone(), OmicronZonesConfigLocal { - omicron_version: request.version, + omicron_version: Generation::new(), ledger_version: Generation::new(), zones: vec![], }, @@ -2641,6 +2650,12 @@ impl ServiceManager { }; let ledger_zone_config = ledger.data_mut(); + debug!(log, "ensure_all_omicron_zones_persistent"; + "request_version" => request.version.to_string(), + "ledger_version" => ledger_zone_config.omicron_version.to_string(), + ); + + // Absolutely refuse to downgrade the configuration. if ledger_zone_config.omicron_version > request.version { return Err(Error::RequestedConfigOutdated( request.version, @@ -2648,6 +2663,15 @@ impl ServiceManager { )); } + // If the version is the same as what we're running, but the contents + // aren't, that's a problem, too. + if ledger_zone_config.omicron_version == request.version + && ledger_zone_config.clone().to_omicron_zones_config().zones + != request.zones + { + return Err(Error::RequestedConfigConflicts(request.version)); + } + let new_config = self .ensure_all_omicron_zones( &mut existing_zones, @@ -3587,12 +3611,16 @@ mod test { } // Prepare to call "ensure" for a new service, then actually call "ensure". - async fn ensure_new_service(mgr: &ServiceManager, id: Uuid) { + async fn ensure_new_service( + mgr: &ServiceManager, + id: Uuid, + version: Generation, + ) { let _expectations = expect_new_service(); let address = SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version: Generation::new().next(), + version, zones: vec![OmicronZoneConfig { id, underlay_address: Ipv6Addr::LOCALHOST, @@ -3605,11 +3633,15 @@ mod test { // Prepare to call "ensure" for a service which already exists. We should // return the service without actually installing a new zone. - async fn ensure_existing_service(mgr: &ServiceManager, id: Uuid) { + async fn ensure_existing_service( + mgr: &ServiceManager, + id: Uuid, + version: Generation, + ) { let address = SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version: Generation::new().next(), + version, zones: vec![OmicronZoneConfig { id, underlay_address: Ipv6Addr::LOCALHOST, @@ -3735,7 +3767,7 @@ mod test { .unwrap(); let id = Uuid::new_v4(); - ensure_new_service(&mgr, id).await; + ensure_new_service(&mgr, id, Generation::new().next()).await; drop_service_manager(mgr); logctx.cleanup_successful(); @@ -3783,8 +3815,9 @@ mod test { .unwrap(); let id = Uuid::new_v4(); - ensure_new_service(&mgr, id).await; - ensure_existing_service(&mgr, id).await; + let v = Generation::new().next(); + ensure_new_service(&mgr, id, v).await; + ensure_existing_service(&mgr, id, v).await; drop_service_manager(mgr); logctx.cleanup_successful(); @@ -3836,7 +3869,7 @@ mod test { .unwrap(); let id = Uuid::new_v4(); - ensure_new_service(&mgr, id).await; + ensure_new_service(&mgr, id, Generation::new().next()).await; drop_service_manager(mgr); // Before we re-create the service manager - notably, using the same @@ -3919,7 +3952,7 @@ mod test { .unwrap(); let id = Uuid::new_v4(); - ensure_new_service(&mgr, id).await; + ensure_new_service(&mgr, id, Generation::new().next()).await; drop_service_manager(mgr); // Next, delete the ledger. This means the zone we just created will not From 728c1e713b30cc164085ab775f3683186b22dbb6 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Sat, 18 Nov 2023 00:06:52 +0000 Subject: [PATCH 34/44] add tests that read the list of zones --- sled-agent/src/services.rs | 47 +++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index d3c4ae3041..f768376e8c 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -3766,8 +3766,22 @@ mod test { ) .unwrap(); + let v1 = Generation::new(); + let found = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found.version, v1); + assert!(found.zones.is_empty()); + + let v2 = v1.next(); let id = Uuid::new_v4(); - ensure_new_service(&mgr, id, Generation::new().next()).await; + ensure_new_service(&mgr, id, v2).await; + + let found = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found.version, v2); + assert_eq!(found.zones.len(), 1); + assert_eq!(found.zones[0].id, id); + drop_service_manager(mgr); logctx.cleanup_successful(); @@ -3814,10 +3828,17 @@ mod test { ) .unwrap(); + let v2 = Generation::new().next(); let id = Uuid::new_v4(); - let v = Generation::new().next(); - ensure_new_service(&mgr, id, v).await; - ensure_existing_service(&mgr, id, v).await; + ensure_new_service(&mgr, id, v2).await; + let v3 = v2.next(); + ensure_existing_service(&mgr, id, v3).await; + let found = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found.version, v3); + assert_eq!(found.zones.len(), 1); + assert_eq!(found.zones[0].id, id); + drop_service_manager(mgr); logctx.cleanup_successful(); @@ -3868,8 +3889,9 @@ mod test { ) .unwrap(); + let v2 = Generation::new().next(); let id = Uuid::new_v4(); - ensure_new_service(&mgr, id, Generation::new().next()).await; + ensure_new_service(&mgr, id, v2).await; drop_service_manager(mgr); // Before we re-create the service manager - notably, using the same @@ -3901,6 +3923,12 @@ mod test { ) .unwrap(); + let found = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found.version, v2); + assert_eq!(found.zones.len(), 1); + assert_eq!(found.zones[0].id, id); + drop_service_manager(mgr); logctx.cleanup_successful(); @@ -3951,8 +3979,10 @@ mod test { ) .unwrap(); + let v1 = Generation::new(); + let v2 = v1.next(); let id = Uuid::new_v4(); - ensure_new_service(&mgr, id, Generation::new().next()).await; + ensure_new_service(&mgr, id, v2).await; drop_service_manager(mgr); // Next, delete the ledger. This means the zone we just created will not @@ -3989,6 +4019,11 @@ mod test { ) .unwrap(); + let found = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found.version, v1); + assert!(found.zones.is_empty()); + drop_service_manager(mgr); logctx.cleanup_successful(); From 34b88c407f97ca93e8ff75491120029dc7850727 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Sat, 18 Nov 2023 00:45:43 +0000 Subject: [PATCH 35/44] add test for version behavior --- sled-agent/src/services.rs | 209 ++++++++++++++++++++++++++++++++++++- 1 file changed, 208 insertions(+), 1 deletion(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index f768376e8c..c8b8cdfb37 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -220,7 +220,7 @@ pub enum Error { #[error("Error querying simnet devices")] Simnet(#[from] GetSimnetError), - #[error("Requested version ({0}) is older than current ({0})")] + #[error("Requested version ({0}) is older than current ({1})")] RequestedConfigOutdated(Generation, Generation), #[error("Requested version {0} with different zones than before")] @@ -3610,6 +3610,80 @@ mod test { ] } + // Configures our mock implementations to work for cases where we configure + // multiple zones in one `ensure_all_omicron_zones_persistent()` call. + // + // This is looser than the expectations created by ensure_new_service() + // because these functions may return any number of times. + fn expect_new_services() -> Vec> { + // Create a VNIC + let create_vnic_ctx = MockDladm::create_vnic_context(); + create_vnic_ctx.expect().returning( + |physical_link: &Etherstub, _, _, _, _| { + assert_eq!(&physical_link.0, &UNDERLAY_ETHERSTUB_NAME); + Ok(()) + }, + ); + + // Install the Omicron Zone + let install_ctx = MockZones::install_omicron_zone_context(); + install_ctx.expect().returning(|_, _, name, _, _, _, _, _, _| { + assert!(name.starts_with(EXPECTED_ZONE_NAME_PREFIX)); + Ok(()) + }); + + // // Boot the zone. + let boot_ctx = MockZones::boot_context(); + boot_ctx.expect().returning(|name| { + assert!(name.starts_with(EXPECTED_ZONE_NAME_PREFIX)); + Ok(()) + }); + + // After calling `MockZones::boot`, `RunningZone::boot` will then look + // up the zone ID for the booted zone. This goes through + // `MockZone::id` to find the zone and get its ID. + let id_ctx = MockZones::id_context(); + let id = Arc::new(std::sync::Mutex::new(1)); + id_ctx.expect().returning(move |name| { + assert!(name.starts_with(EXPECTED_ZONE_NAME_PREFIX)); + let mut value = id.lock().unwrap(); + let rv = *value; + *value = rv + 1; + Ok(Some(rv)) + }); + + // Ensure the address exists + let ensure_address_ctx = MockZones::ensure_address_context(); + ensure_address_ctx.expect().returning(|_, _, _| { + Ok(ipnetwork::IpNetwork::new(IpAddr::V6(Ipv6Addr::LOCALHOST), 64) + .unwrap()) + }); + + // Wait for the networking service. + let wait_ctx = svc::wait_for_service_context(); + wait_ctx.expect().returning(|_, _, _| Ok(())); + + // Import the manifest, enable the service + let execute_ctx = illumos_utils::execute_context(); + execute_ctx.expect().times(..).returning(|_| { + Ok(std::process::Output { + status: std::process::ExitStatus::from_raw(0), + stdout: vec![], + stderr: vec![], + }) + }); + + vec![ + Box::new(create_vnic_ctx), + Box::new(install_ctx), + Box::new(boot_ctx), + Box::new(id_ctx), + Box::new(ensure_address_ctx), + Box::new(wait_ctx), + Box::new(execute_ctx), + ] + } + // Prepare to call "ensure" for a new service, then actually call "ensure". async fn ensure_new_service( mgr: &ServiceManager, @@ -4029,6 +4103,139 @@ mod test { logctx.cleanup_successful(); } + #[tokio::test] + #[serial_test::serial] + async fn test_bad_versions() { + // Start like the normal tests. + let logctx = + omicron_test_utils::dev::test_setup_log("test_bad_versions"); + let log = logctx.log.clone(); + let test_config = TestConfig::new().await; + + let resources = StorageResources::new_for_test(); + let zone_bundler = ZoneBundler::new( + log.clone(), + resources.clone(), + Default::default(), + ); + let mgr = ServiceManager::new( + &log, + DdmAdminClient::localhost(&log).unwrap(), + make_bootstrap_networking_config(), + SledMode::Auto, + Some(true), + SidecarRevision::Physical("rev-test".to_string()), + vec![], + resources, + zone_bundler, + ); + test_config.override_paths(&mgr); + + let port_manager = PortManager::new( + logctx.log.new(o!("component" => "PortManager")), + Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), + ); + mgr.sled_agent_started( + test_config.make_config(), + port_manager, + Ipv6Addr::LOCALHOST, + Uuid::new_v4(), + None, + ) + .unwrap(); + + // Like the normal tests, set up a generation with one zone in it. + let v1 = Generation::new(); + let v2 = v1.next(); + let id1 = Uuid::new_v4(); + + let _expectations = expect_new_services(); + let address = + SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); + let mut zones = vec![OmicronZoneConfig { + id: id1, + underlay_address: Ipv6Addr::LOCALHOST, + zone_type: OmicronZoneType::Oximeter { address }, + }]; + mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { + version: v2, + zones: zones.clone(), + }) + .await + .unwrap(); + + let found = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found.version, v2); + assert_eq!(found.zones.len(), 1); + assert_eq!(found.zones[0].id, id1); + + // Make a new list of zones that we're going to try with a bunch of + // different generation numbers. + let id2 = Uuid::new_v4(); + zones.push(OmicronZoneConfig { + id: id2, + underlay_address: Ipv6Addr::LOCALHOST, + zone_type: OmicronZoneType::Oximeter { address }, + }); + + // Now try to apply that list with an older version number. This + // shouldn't work and the reported state should be unchanged. + let error = mgr + .ensure_all_omicron_zones_persistent(OmicronZonesConfig { + version: v1, + zones: zones.clone(), + }) + .await + .expect_err("unexpectedly went backwards in zones version"); + assert!(matches!( + error, + Error::RequestedConfigOutdated(vr, vc) if vr == v1 && vc == v2 + )); + let found2 = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found, found2); + + // Now try to apply that list with the same version number that we used + // before. This shouldn't work either. + let error = mgr + .ensure_all_omicron_zones_persistent(OmicronZonesConfig { + version: v2, + zones: zones.clone(), + }) + .await + .expect_err("unexpectedly changed a single zone version"); + assert!(matches!( + error, + Error::RequestedConfigConflicts(vr) if vr == v2 + )); + let found3 = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found, found3); + + // But we should be able to apply this new list of zones as long as we + // advance the version number. + let v3 = v2.next(); + mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { + version: v3, + zones: zones.clone(), + }) + .await + .expect("failed to remove all zones in a new version"); + let found4 = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found4.version, v3); + let mut our_zones = zones; + our_zones.sort_by(|a, b| a.id.cmp(&b.id)); + let mut found_zones = found4.zones; + found_zones.sort_by(|a, b| a.id.cmp(&b.id)); + assert_eq!(our_zones, found_zones); + + drop_service_manager(mgr); + + logctx.cleanup_successful(); + } + #[test] fn test_bootstrap_addr_to_techport_prefixes() { let ba: Ipv6Addr = "fdb0:1122:3344:5566::".parse().unwrap(); From 142e186b21a5dd1b1ea8bc4343cf37db0b0882ba Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Sat, 18 Nov 2023 01:35:55 +0000 Subject: [PATCH 36/44] add some tests for migration --- common/src/ledger.rs | 1 + sled-agent/src/services.rs | 224 +++++++++++++++++- .../old-service-ledgers/rack2-sled10.json | 1 + .../new-zones-ledgers/rack2-sled10.json | 195 +++++++++++++++ 4 files changed, 413 insertions(+), 8 deletions(-) create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled10.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json diff --git a/common/src/ledger.rs b/common/src/ledger.rs index c07fb5e693..4af2b6e7a8 100644 --- a/common/src/ledger.rs +++ b/common/src/ledger.rs @@ -54,6 +54,7 @@ impl From for crate::api::external::Error { /// /// This structure is intended to help with serialization and deserialization /// of configuration information to both M.2s. +#[derive(Debug)] pub struct Ledger { log: Logger, ledger: T, diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index c8b8cdfb37..fbd475d05f 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -226,7 +226,7 @@ pub enum Error { #[error("Requested version {0} with different zones than before")] RequestedConfigConflicts(Generation), - #[error("Error migrating old-format services ledger")] + #[error("Error migrating old-format services ledger: {0:#}")] ServicesMigration(anyhow::Error), } @@ -690,14 +690,33 @@ impl ServiceManager { "Loading old-format services from: {services_ledger_paths:?}" ); - let Some(ledger) = - Ledger::::new(log, services_ledger_paths).await - else { - return Ok(None); + 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) + } }; - let all_services = ledger.into_inner(); - match OmicronZonesConfigLocal::try_from(all_services) { + 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 @@ -715,7 +734,7 @@ impl ServiceManager { {:#}", error ); - return Err(Error::ServicesMigration(error)); + return Err(error); } Ok(new_config) => { // We've successfully converted the old ledger. Write a new @@ -4236,6 +4255,195 @@ mod test { logctx.cleanup_successful(); } + #[tokio::test] + #[serial_test::serial] + async fn test_old_ledger_migration() { + let logctx = omicron_test_utils::dev::test_setup_log( + "test_old_ledger_migration", + ); + let log = logctx.log.clone(); + let test_config = TestConfig::new().await; + let ddmd_client = DdmAdminClient::localhost(&log).unwrap(); + let bootstrap_networking = make_bootstrap_networking_config(); + + let resources = StorageResources::new_for_test(); + let zone_bundler = ZoneBundler::new( + log.clone(), + resources.clone(), + Default::default(), + ); + let mgr = ServiceManager::new( + &log, + ddmd_client.clone(), + bootstrap_networking.clone(), + SledMode::Auto, + Some(true), + SidecarRevision::Physical("rev-test".to_string()), + vec![], + resources.clone(), + zone_bundler.clone(), + ); + test_config.override_paths(&mgr); + + // Before we start things, 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"); + + let port_manager = PortManager::new( + log.new(o!("component" => "PortManager")), + Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), + ); + mgr.sled_agent_started( + test_config.make_config(), + port_manager, + Ipv6Addr::LOCALHOST, + Uuid::new_v4(), + None, + ) + .unwrap(); + + // 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); + + // XXX-dap comonize this copy/pasted block + let mgr = ServiceManager::new( + &log, + ddmd_client, + bootstrap_networking, + SledMode::Auto, + Some(true), + SidecarRevision::Physical("rev-test".to_string()), + vec![], + resources.clone(), + zone_bundler.clone(), + ); + test_config.override_paths(&mgr); + + let port_manager = PortManager::new( + log.new(o!("component" => "PortManager")), + Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), + ); + mgr.sled_agent_started( + test_config.make_config(), + port_manager, + Ipv6Addr::LOCALHOST, + Uuid::new_v4(), + None, + ) + .unwrap(); + + let found = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found, expected_config); + + drop_service_manager(mgr); + logctx.cleanup_successful(); + } + + #[tokio::test] + #[serial_test::serial] + async fn test_old_ledger_migration_bad() { + let logctx = omicron_test_utils::dev::test_setup_log( + "test_old_ledger_migration_bad", + ); + let log = logctx.log.clone(); + let test_config = TestConfig::new().await; + let ddmd_client = DdmAdminClient::localhost(&log).unwrap(); + let bootstrap_networking = make_bootstrap_networking_config(); + + let resources = StorageResources::new_for_test(); + let zone_bundler = ZoneBundler::new( + log.clone(), + resources.clone(), + Default::default(), + ); + let mgr = ServiceManager::new( + &log, + ddmd_client.clone(), + bootstrap_networking.clone(), + SledMode::Auto, + Some(true), + SidecarRevision::Physical("rev-test".to_string()), + vec![], + resources.clone(), + zone_bundler.clone(), + ); + test_config.override_paths(&mgr); + + // 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"); + + let port_manager = PortManager::new( + log.new(o!("component" => "PortManager")), + Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), + ); + mgr.sled_agent_started( + test_config.make_config(), + port_manager, + Ipv6Addr::LOCALHOST, + Uuid::new_v4(), + None, + ) + .unwrap(); + + 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) + ); + + // XXX-dap other test cases to add: + // - what if we change the current ledger after migration? we should + // see the change + // - I feel like there was some other case here but now I can't remember + // it + 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/tests/old-service-ledgers/rack2-sled10.json b/sled-agent/tests/old-service-ledgers/rack2-sled10.json new file mode 100644 index 0000000000..b92a2bf4a0 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled10.json @@ -0,0 +1 @@ +{"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/output/new-zones-ledgers/rack2-sled10.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json new file mode 100644 index 0000000000..58ee3f958c --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json @@ -0,0 +1,195 @@ +{ + "omicron_version": 2, + "ledger_version": 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" + } + ] +} From d56512cdfb25e0c25ce1f90623967bb70f830ecc Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 22 Nov 2023 18:27:53 +0000 Subject: [PATCH 37/44] deal with RSS service plan incompatibility --- ...ice-plan.json => rss-service-plan-v2.json} | 518 +++++++----------- sled-agent/src/rack_setup/plan/service.rs | 62 ++- sled-agent/src/rack_setup/service.rs | 25 +- 3 files changed, 263 insertions(+), 342 deletions(-) rename schema/{rss-service-plan.json => rss-service-plan-v2.json} (80%) diff --git a/schema/rss-service-plan.json b/schema/rss-service-plan-v2.json similarity index 80% rename from schema/rss-service-plan.json rename to schema/rss-service-plan-v2.json index 725caf0900..0bcd27b9cc 100644 --- a/schema/rss-service-plan.json +++ b/schema/rss-service-plan-v2.json @@ -13,136 +13,11 @@ "services": { "type": "object", "additionalProperties": { - "$ref": "#/definitions/SledRequest" + "$ref": "#/definitions/SledConfig" } } }, "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" - } - } - }, "DnsConfigParams": { "type": "object", "required": [ @@ -399,53 +274,96 @@ } ] }, - "ServiceType": { - "description": "Describes service-specific parameters.", + "OmicronZoneConfig": { + "description": "Describes one Omicron-managed zone running on a sled", + "type": "object", + "required": [ + "id", + "underlay_address", + "zone_type" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "underlay_address": { + "type": "string", + "format": "ipv6" + }, + "zone_type": { + "$ref": "#/definitions/OmicronZoneType" + } + } + }, + "OmicronZoneDataset": { + "description": "Describes a persistent ZFS dataset associated with an Omicron zone", + "type": "object", + "required": [ + "pool_name" + ], + "properties": { + "pool_name": { + "$ref": "#/definitions/ZpoolName" + } + } + }, + "OmicronZoneType": { + "description": "Describes what kind of zone this is (i.e., what component is running in it) as well as any type-specific configuration", "oneOf": [ { "type": "object", "required": [ - "external_dns_servers", - "external_ip", - "external_tls", - "internal_address", + "address", + "dns_servers", "nic", + "ntp_servers", + "snat_cfg", "type" ], "properties": { - "external_dns_servers": { - "description": "External DNS servers Nexus can use to resolve external hosts.", + "address": { + "type": "string" + }, + "dns_servers": { "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" + "domain": { + "type": [ + "string", + "null" + ] }, "nic": { - "description": "The service vNIC providing external connectivity using OPTE.", + "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": [ - "nexus" + "boundary_ntp" ] } } @@ -453,32 +371,21 @@ { "type": "object", "required": [ - "dns_address", - "http_address", - "nic", + "address", + "dataset", "type" ], "properties": { - "dns_address": { - "description": "The address at which the external DNS server is reachable.", + "address": { "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" - } - ] + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" }, "type": { "type": "string", "enum": [ - "external_dns" + "clickhouse" ] } } @@ -486,34 +393,43 @@ { "type": "object", "required": [ - "dns_address", - "gz_address", - "gz_address_index", - "http_address", + "address", + "dataset", "type" ], "properties": { - "dns_address": { + "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 + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" }, - "http_address": { + "type": { + "type": "string", + "enum": [ + "clickhouse_keeper" + ] + } + } + }, + { + "type": "object", + "required": [ + "address", + "dataset", + "type" + ], + "properties": { + "address": { "type": "string" }, + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, "type": { "type": "string", "enum": [ - "internal_dns" + "cockroach_db" ] } } @@ -522,16 +438,20 @@ "type": "object", "required": [ "address", + "dataset", "type" ], "properties": { "address": { "type": "string" }, + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, "type": { "type": "string", "enum": [ - "oximeter" + "crucible" ] } } @@ -557,56 +477,75 @@ { "type": "object", "required": [ - "address", - "dns_servers", + "dataset", + "dns_address", + "http_address", "nic", - "ntp_servers", - "snat_cfg", "type" ], "properties": { - "address": { - "type": "string" + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" }, - "dns_servers": { - "type": "array", - "items": { - "type": "string", - "format": "ip" - } + "dns_address": { + "description": "The address at which the external DNS server is reachable.", + "type": "string" }, - "domain": { - "type": [ - "string", - "null" - ] + "http_address": { + "description": "The address at which the external DNS server API is reachable.", + "type": "string" }, "nic": { - "description": "The service vNIC providing outbound connectivity using OPTE.", + "description": "The service vNIC providing external 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": [ + "external_dns" ] + } + } + }, + { + "type": "object", + "required": [ + "dataset", + "dns_address", + "gz_address", + "gz_address_index", + "http_address", + "type" + ], + "properties": { + "dataset": { + "$ref": "#/definitions/OmicronZoneDataset" + }, + "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": [ - "boundary_ntp" + "internal_dns" ] } } @@ -653,53 +592,47 @@ { "type": "object", "required": [ - "address", + "external_dns_servers", + "external_ip", + "external_tls", + "internal_address", + "nic", "type" ], "properties": { - "address": { - "type": "string" + "external_dns_servers": { + "description": "External DNS servers Nexus can use to resolve external hosts.", + "type": "array", + "items": { + "type": "string", + "format": "ip" + } }, - "type": { + "external_ip": { + "description": "The address at which the external nexus server is reachable.", "type": "string", - "enum": [ - "clickhouse" - ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "type" - ], - "properties": { - "address": { + "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" }, - "type": { - "type": "string", - "enum": [ - "clickhouse_keeper" + "nic": { + "description": "The service vNIC providing external connectivity using OPTE.", + "allOf": [ + { + "$ref": "#/definitions/NetworkInterface" + } ] - } - } - }, - { - "type": "object", - "required": [ - "address", - "type" - ], - "properties": { - "address": { - "type": "string" }, "type": { "type": "string", "enum": [ - "cockroach_db" + "nexus" ] } } @@ -717,82 +650,24 @@ "type": { "type": "string", "enum": [ - "crucible" + "oximeter" ] } } } ] }, - "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": { - "default": null, - "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.", + "SledConfig": { "type": "object", "required": [ - "details", - "id" + "zones" ], "properties": { - "details": { - "$ref": "#/definitions/ServiceType" - }, - "id": { - "type": "string", - "format": "uuid" - } - } - }, - "SledRequest": { - "type": "object", - "properties": { - "service": { - "description": "Services to be instantiated.", - "default": [], + "zones": { + "description": "zones configured for this sled", "type": "array", "items": { - "$ref": "#/definitions/ServiceZoneRequest" + "$ref": "#/definitions/OmicronZoneConfig" } } } @@ -860,23 +735,6 @@ "format": "uint32", "minimum": 0.0 }, - "ZoneType": { - "description": "The type of zone which may be requested from Sled Agent", - "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", diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index d1ed372bc9..fea8039725 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -94,6 +94,9 @@ pub enum PlanError { #[error("Ran out of sleds / U2 storage pools")] NotEnoughSleds, + + #[error("Found only v1 service plan")] + FoundV1, } #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] @@ -114,7 +117,8 @@ impl Ledgerable for Plan { } fn generation_bump(&mut self) {} } -const RSS_SERVICE_PLAN_FILENAME: &str = "rss-service-plan.json"; +const RSS_SERVICE_PLAN_V1_FILENAME: &str = "rss-service-plan.json"; +const RSS_SERVICE_PLAN_FILENAME: &str = "rss-service-plan-v2.json"; impl Plan { pub async fn load( @@ -136,11 +140,61 @@ impl Plan { if let Some(ledger) = ledger { info!(log, "RSS plan already created, loading from file"); Ok(Some(ledger.data().clone())) + } else if Self::has_v1(storage_manager).await.map_err(|err| { + PlanError::Io { + message: String::from("looking for v1 RSS plan"), + err, + } + })? { + // If we found no current-version service plan, but we _do_ find + // a v1 plan present, bail out. We do not expect to ever see this + // in practice because that would indicate that: + // + // - We ran RSS previously on this same system using an older + // version of the software that generates v1 service plans and it + // got far enough through RSS to have written the v1 service plan. + // - That means it must have finished initializing all sled agents, + // including itself, causing it to record a + // `StartSledAgentRequest`s in its ledger -- while still running + // the older RSS. + // - But we're currently running software that knows about v2 + // service plans. Thus, this process started some time after that + // ledger was written. + // - But the bootstrap agent refuses to execute RSS if it has a + // local `StartSledAgentRequest` ledgered. So we shouldn't get + // here if all of the above happened. + // + // This sounds like a complicated set of assumptions. If we got + // this wrong, we'll fail spuriously here and we'll have to figure + // out what happened. But the alternative is doing extra work to + // support a condition that we do not believe can ever happen in any + // system. + Err(PlanError::FoundV1) } else { Ok(None) } } + async fn has_v1( + storage_manager: &StorageHandle, + ) -> Result { + let paths: Vec = storage_manager + .get_latest_resources() + .await + .all_m2_mountpoints(CONFIG_DATASET) + .into_iter() + .map(|p| p.join(RSS_SERVICE_PLAN_V1_FILENAME)) + .collect(); + + for p in paths { + if p.try_exists()? { + return Ok(true); + } + } + + Ok(false) + } + async fn is_sled_scrimlet( log: &Logger, address: SocketAddrV6, @@ -1154,13 +1208,11 @@ mod tests { assert_eq!(internal_service_ips, expected_internal_service_ips); } - // XXX-dap I think we should remove this test? Do we really consider the - // RSS service plan stable? #[test] - fn test_rss_service_plan_schema() { + fn test_rss_service_plan_v2_schema() { let schema = schemars::schema_for!(Plan); expectorate::assert_contents( - "../schema/rss-service-plan.json", + "../schema/rss-service-plan-v2.json", &serde_json::to_string_pretty(&schema).unwrap(), ); } diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index b9c9431e0a..3d0840a17e 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -11,15 +11,25 @@ //! - DNS records for those services //! - Handoff to Nexus, for control of Control Plane management //! -//! # Phases and Configuration Files +//! # Phases, state files, and restart behavior //! -//! Rack setup occurs in distinct phases which are denoted by the prescence of -//! configuration files. +//! Rack setup occurs in distinct phases that are denoted by the presence of +//! state files that get generated as RSS executes: //! //! - /pool/int/UUID/config/rss-sled-plan.json (Sled Plan) -//! - /pool/int/UUID/config/rss-service-plan.json (Service Plan) +//! - /pool/int/UUID/config/rss-service-plan-v2.json (Service Plan) //! - /pool/int/UUID/config/rss-plan-completed.marker (Plan Execution Complete) //! +//! These phases are described below. As each phase completes, a corresponding +//! state file is written. This mechanism is designed so that if RSS restarts +//! (e.g., after a crash) then it will resume execution using the same plans. +//! +//! The service plan file has "-v2" in the filename because its structure +//! changed in omicron#4466. It is possible that on startup, RSS finds an +//! older-form service plan. In that case, it fails altogether. We do not +//! expect this condition to happen in practice. See the implementation for +//! details. +//! //! ## Sled Plan //! //! RSS should start as a service executing on a Sidecar-attached Gimlet @@ -761,8 +771,8 @@ impl ServiceInner { // time, it creates an allocation plan to provision subnets to an initial // set of sleds. // - // 2. SLED ALLOCATION PLAN EXECUTION. The RSS then carries out this plan, making - // requests to the sleds enumerated within the "allocation plan". + // 2. SLED ALLOCATION PLAN EXECUTION. The RSS then carries out this plan, + // making requests to the sleds enumerated within the "allocation plan". // // 3. SERVICE ALLOCATION PLAN CREATION. Now that Sled Agents are executing // on their respective subnets, they can be queried to create an @@ -773,7 +783,8 @@ impl ServiceInner { // // 5. MARKING SETUP COMPLETE. Once the RSS has successfully initialized the // rack, a marker file is created at "rss_completed_marker_path()". This - // indicates that the plan executed successfully, and no work remains. + // indicates that the plan executed successfully, and the only work + // remaining is to handoff to Nexus. async fn run( &self, config: &Config, From 925a8c6d863eea65d13314f7f1a0725d8670e6ac Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 22 Nov 2023 23:02:40 +0000 Subject: [PATCH 38/44] add tests for rack2, rack3 services ledgers --- sled-agent/src/services_migration.rs | 93 +++++++ .../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 | 2 +- .../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 ++++++++++++++ 84 files changed, 7668 insertions(+), 1 deletion(-) create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled11.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled12.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled14.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled16.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled17.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled21.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled23.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled25.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled8.json create mode 100644 sled-agent/tests/old-service-ledgers/rack2-sled9.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled0.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled1.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled11.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled12.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled13.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled14.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled15.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled16.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled17.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled18.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled19.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled2.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled20.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled21.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled22.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled23.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled24.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled25.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled26.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled27.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled28.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled29.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled3.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled30.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled31.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled4.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled5.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled6.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled7.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled8.json create mode 100644 sled-agent/tests/old-service-ledgers/rack3-sled9.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json create mode 100644 sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index ac3400a2c6..df674967b1 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -109,6 +109,9 @@ impl TryFrom for OmicronZonesConfigLocal { // pick the version from the ledger that we loaded. let ledger_version = input.generation; + let ndatasets_input = + input.requests.iter().filter(|r| r.zone.dataset.is_some()).count(); + let zones = input .requests .into_iter() @@ -118,6 +121,15 @@ impl TryFrom for OmicronZonesConfigLocal { "mapping `AllZoneRequests` to `OmicronZonesConfigLocal`", )?; + // As a quick check, the number of datasets in the old and new versions + // 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_version, ledger_version, zones }) } } @@ -515,7 +527,13 @@ impl DatasetRequest { #[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); @@ -524,4 +542,79 @@ mod test { &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-sled11.json b/sled-agent/tests/old-service-ledgers/rack2-sled11.json new file mode 100644 index 0000000000..3833bed5c9 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled11.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..5126c007f3 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled12.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..421e21d84d --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled14.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..c928e004b2 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled16.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..93872adf13 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled17.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..78e003f79e --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled21.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..29b8c455d3 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled23.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..e48ef68faa --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled25.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..7d52980d9f --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled8.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..36af68759b --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack2-sled9.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..a853a525bc --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled0.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..bd735e5e64 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled1.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..2918c74c4b --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled11.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..c81f586e01 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled12.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..ab151a828e --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled13.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..89c12a015f --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled14.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..880f29409e --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled15.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..3a1cbeb411 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled16.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..4063fed2e2 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled17.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..f47e912424 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled18.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..c450320a73 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled19.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..6c420c989d --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled2.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..20c9d60624 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled20.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..4f69e01c7f --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled21.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..dc98c0390c --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled22.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..ade2144287 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled23.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..e7bd3050d6 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled24.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..642657bbce --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled25.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..0978cb9e45 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled26.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..0b2db29c4a --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled27.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..ec137c18fa --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled28.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..2618364e4f --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled29.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..6bcb626cf6 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled3.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..e919de3488 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled30.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..d984227227 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled31.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..e9e5ce5569 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled4.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..ea7b5ec40a --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled5.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..2c499813cd --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled6.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..fb701a2bdb --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled7.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..cf96f8ae81 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled8.json @@ -0,0 +1 @@ +{"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 new file mode 100644 index 0000000000..c225f50081 --- /dev/null +++ b/sled-agent/tests/old-service-ledgers/rack3-sled9.json @@ -0,0 +1 @@ +{"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 index 58ee3f958c..9b0a1041b0 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json @@ -192,4 +192,4 @@ "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 new file mode 100644 index 0000000000..b06f7fb11b --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json @@ -0,0 +1,196 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..22d3409330 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json @@ -0,0 +1,232 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..cbb57aa467 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json @@ -0,0 +1,192 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..dc72514214 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json @@ -0,0 +1,192 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..deca9d4701 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json @@ -0,0 +1,181 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..931801ae35 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json @@ -0,0 +1,232 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..cda63747a1 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json @@ -0,0 +1,195 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..a7d133bc7a --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json @@ -0,0 +1,196 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..f08344ce3c --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json @@ -0,0 +1,198 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..ec9169f276 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json @@ -0,0 +1,192 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..8a87e8c0dd --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json @@ -0,0 +1,181 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..2ae8a43e9f --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..9e92579e4e --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json @@ -0,0 +1,201 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..b39fad4765 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json @@ -0,0 +1,181 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..a4b2d416a0 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json @@ -0,0 +1,201 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..7787ac0564 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json @@ -0,0 +1,198 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..af716b7dd0 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json @@ -0,0 +1,196 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..583974a2b0 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..13234a39eb --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..5e933b56cf --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..c39b62741a --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json @@ -0,0 +1,181 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..2a868a10b1 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..5e25895750 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json @@ -0,0 +1,198 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..687137f65c --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..f0e95af8d3 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..c09b7d99e3 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json @@ -0,0 +1,181 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..78c3befff5 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..3255b6b08d --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json @@ -0,0 +1,196 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..c61f9c7a39 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json @@ -0,0 +1,178 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..309f8360ab --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..6a3dc40b7b --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..cce200479f --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json @@ -0,0 +1,184 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..330811ea94 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json @@ -0,0 +1,178 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..8316dca294 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..d4792a4707 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json @@ -0,0 +1,181 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..7d443a74e6 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..2b43a62811 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json @@ -0,0 +1,178 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..a48ccdd6a7 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..9a11795014 --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json @@ -0,0 +1,167 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..da31e8048f --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json @@ -0,0 +1,198 @@ +{ + "omicron_version": 2, + "ledger_version": 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 new file mode 100644 index 0000000000..1b6bd0b2bf --- /dev/null +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json @@ -0,0 +1,178 @@ +{ + "omicron_version": 2, + "ledger_version": 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 73d143a8e3ae1771310c5913df8d2afe9a807104 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 23 Nov 2023 00:26:19 +0000 Subject: [PATCH 39/44] commonize a bunch of test code --- sled-agent/src/services.rs | 438 ++++++++++--------------------------- 1 file changed, 115 insertions(+), 323 deletions(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index a6dc6f72b2..9b58ddf378 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -3818,45 +3818,87 @@ mod test { handle } + #[derive(Clone)] + struct LedgerTestHelper<'a> { + log: slog::Logger, + ddmd_client: DdmAdminClient, + storage_handle: StorageHandle, + zone_bundler: ZoneBundler, + test_config: &'a TestConfig, + } + + impl<'a> LedgerTestHelper<'a> { + async fn new( + log: slog::Logger, + test_config: &'a TestConfig, + ) -> LedgerTestHelper { + let ddmd_client = DdmAdminClient::localhost(&log).unwrap(); + let storage_handle = setup_storage().await; + let zone_bundler = ZoneBundler::new( + log.clone(), + storage_handle.clone(), + Default::default(), + ); + + LedgerTestHelper { + log, + ddmd_client, + storage_handle, + zone_bundler, + test_config, + } + } + + fn new_service_manager(self) -> ServiceManager { + let log = &self.log; + let mgr = ServiceManager::new( + log, + self.ddmd_client, + make_bootstrap_networking_config(), + SledMode::Auto, + Some(true), + SidecarRevision::Physical("rev-test".to_string()), + vec![], + self.storage_handle, + self.zone_bundler, + ); + self.test_config.override_paths(&mgr); + mgr + } + + fn sled_agent_started( + log: &slog::Logger, + test_config: &TestConfig, + mgr: &ServiceManager, + ) { + let port_manager = PortManager::new( + log.new(o!("component" => "PortManager")), + Ipv6Addr::new( + 0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + ), + ); + + mgr.sled_agent_started( + test_config.make_config(), + port_manager, + Ipv6Addr::LOCALHOST, + Uuid::new_v4(), + None, + ) + .unwrap(); + } + } + #[tokio::test] #[serial_test::serial] async fn test_ensure_service() { let logctx = omicron_test_utils::dev::test_setup_log("test_ensure_service"); - let log = logctx.log.clone(); let test_config = TestConfig::new().await; - - let storage_handle = setup_storage().await; - let zone_bundler = ZoneBundler::new( - log.clone(), - storage_handle.clone(), - Default::default(), - ); - let mgr = ServiceManager::new( - &log, - DdmAdminClient::localhost(&log).unwrap(), - make_bootstrap_networking_config(), - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle, - zone_bundler, - ); - test_config.override_paths(&mgr); - - let port_manager = PortManager::new( - logctx.log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + let helper = + LedgerTestHelper::new(logctx.log.clone(), &test_config).await; + let mgr = helper.new_service_manager(); + LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); let v1 = Generation::new(); let found = @@ -3885,40 +3927,11 @@ mod test { let logctx = omicron_test_utils::dev::test_setup_log( "test_ensure_service_which_already_exists", ); - let log = logctx.log.clone(); let test_config = TestConfig::new().await; - - let storage_handle = setup_storage().await; - let zone_bundler = ZoneBundler::new( - log.clone(), - storage_handle.clone(), - Default::default(), - ); - let mgr = ServiceManager::new( - &log, - DdmAdminClient::localhost(&log).unwrap(), - make_bootstrap_networking_config(), - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle, - zone_bundler, - ); - test_config.override_paths(&mgr); - - let port_manager = PortManager::new( - logctx.log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + let helper = + LedgerTestHelper::new(logctx.log.clone(), &test_config).await; + let mgr = helper.new_service_manager(); + LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); let v2 = Generation::new().next(); let id = Uuid::new_v4(); @@ -3942,44 +3955,14 @@ mod test { let logctx = omicron_test_utils::dev::test_setup_log( "test_services_are_recreated_on_reboot", ); - let log = logctx.log.clone(); let test_config = TestConfig::new().await; - let ddmd_client = DdmAdminClient::localhost(&log).unwrap(); - let bootstrap_networking = make_bootstrap_networking_config(); - - // First, spin up a ServiceManager, create a new service, and tear it - // down. - let storage_handle = setup_storage().await; - let zone_bundler = ZoneBundler::new( - log.clone(), - storage_handle.clone(), - Default::default(), - ); - let mgr = ServiceManager::new( - &log, - ddmd_client.clone(), - bootstrap_networking.clone(), - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle.clone(), - zone_bundler.clone(), - ); - test_config.override_paths(&mgr); + let helper = + LedgerTestHelper::new(logctx.log.clone(), &test_config).await; - let port_manager = PortManager::new( - log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + // First, spin up a ServiceManager, create a new zone, and then tear + // down the ServiceManager. + let mgr = helper.clone().new_service_manager(); + LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); let v2 = Generation::new().next(); let id = Uuid::new_v4(); @@ -3989,31 +3972,8 @@ mod test { // Before we re-create the service manager - notably, using the same // config file! - expect that a service gets initialized. let _expectations = expect_new_service(); - let mgr = ServiceManager::new( - &log, - ddmd_client, - bootstrap_networking, - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle.clone(), - zone_bundler.clone(), - ); - test_config.override_paths(&mgr); - - let port_manager = PortManager::new( - log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + 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"); @@ -4032,44 +3992,14 @@ mod test { let logctx = omicron_test_utils::dev::test_setup_log( "test_services_do_not_persist_without_config", ); - let log = logctx.log.clone(); let test_config = TestConfig::new().await; - let ddmd_client = DdmAdminClient::localhost(&log).unwrap(); - let bootstrap_networking = make_bootstrap_networking_config(); + let helper = + LedgerTestHelper::new(logctx.log.clone(), &test_config).await; // First, spin up a ServiceManager, create a new zone, and then tear // down the ServiceManager. - let storage_handle = setup_storage().await; - let zone_bundler = ZoneBundler::new( - log.clone(), - storage_handle.clone(), - Default::default(), - ); - let mgr = ServiceManager::new( - &log, - ddmd_client.clone(), - bootstrap_networking.clone(), - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle.clone(), - zone_bundler.clone(), - ); - test_config.override_paths(&mgr); - - let port_manager = PortManager::new( - log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + let mgr = helper.clone().new_service_manager(); + LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); let v1 = Generation::new(); let v2 = v1.next(); @@ -4085,31 +4015,8 @@ mod test { .unwrap(); // Observe that the old service is not re-initialized. - let mgr = ServiceManager::new( - &log, - ddmd_client, - bootstrap_networking, - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle, - zone_bundler.clone(), - ); - test_config.override_paths(&mgr); - - let port_manager = PortManager::new( - log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + 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"); @@ -4127,40 +4034,11 @@ mod test { // Start like the normal tests. let logctx = omicron_test_utils::dev::test_setup_log("test_bad_versions"); - let log = logctx.log.clone(); let test_config = TestConfig::new().await; - - let storage_handle = setup_storage().await; - let zone_bundler = ZoneBundler::new( - log.clone(), - storage_handle.clone(), - Default::default(), - ); - let mgr = ServiceManager::new( - &log, - DdmAdminClient::localhost(&log).unwrap(), - make_bootstrap_networking_config(), - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle, - zone_bundler, - ); - test_config.override_paths(&mgr); - - let port_manager = PortManager::new( - logctx.log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + let helper = + LedgerTestHelper::new(logctx.log.clone(), &test_config).await; + let mgr = helper.new_service_manager(); + LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); // Like the normal tests, set up a generation with one zone in it. let v1 = Generation::new(); @@ -4260,32 +4138,10 @@ mod test { let logctx = omicron_test_utils::dev::test_setup_log( "test_old_ledger_migration", ); - let log = logctx.log.clone(); let test_config = TestConfig::new().await; - let ddmd_client = DdmAdminClient::localhost(&log).unwrap(); - let bootstrap_networking = make_bootstrap_networking_config(); - - let storage_handle = setup_storage().await; - let zone_bundler = ZoneBundler::new( - log.clone(), - storage_handle.clone(), - Default::default(), - ); - let mgr = ServiceManager::new( - &log, - ddmd_client.clone(), - bootstrap_networking.clone(), - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle.clone(), - zone_bundler.clone(), - ); - test_config.override_paths(&mgr); - // Before we start things, stuff one of our old-format service ledgers - // into place. + // 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( @@ -4294,18 +4150,11 @@ mod test { ) .expect("failed to copy example old-format services ledger into place"); - let port_manager = PortManager::new( - log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + // Now start the service manager. + let helper = + LedgerTestHelper::new(logctx.log.clone(), &test_config).await; + let mgr = helper.clone().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.) @@ -4337,32 +4186,8 @@ mod test { // triggering migration again. It should also report the same zones. drop_service_manager(mgr); - // XXX-dap comonize this copy/pasted block - let mgr = ServiceManager::new( - &log, - ddmd_client, - bootstrap_networking, - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle.clone(), - zone_bundler.clone(), - ); - test_config.override_paths(&mgr); - - let port_manager = PortManager::new( - log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + 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"); @@ -4378,52 +4203,24 @@ mod test { let logctx = omicron_test_utils::dev::test_setup_log( "test_old_ledger_migration_bad", ); - let log = logctx.log.clone(); let test_config = TestConfig::new().await; - let ddmd_client = DdmAdminClient::localhost(&log).unwrap(); - let bootstrap_networking = make_bootstrap_networking_config(); - - let storage_handle = setup_storage().await; - let zone_bundler = ZoneBundler::new( - log.clone(), - storage_handle.clone(), - Default::default(), - ); - let mgr = ServiceManager::new( - &log, - ddmd_client.clone(), - bootstrap_networking.clone(), - SledMode::Auto, - Some(true), - SidecarRevision::Physical("rev-test".to_string()), - vec![], - storage_handle.clone(), - zone_bundler.clone(), - ); - test_config.override_paths(&mgr); + let 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. + // 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"); - let port_manager = PortManager::new( - log.new(o!("component" => "PortManager")), - Ipv6Addr::new(0xfd00, 0x1de, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01), - ); - mgr.sled_agent_started( - test_config.make_config(), - port_manager, - Ipv6Addr::LOCALHOST, - Uuid::new_v4(), - None, - ) - .unwrap(); + // 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) @@ -4435,11 +4232,6 @@ mod test { format!("{:#}", error) ); - // XXX-dap other test cases to add: - // - what if we change the current ledger after migration? we should - // see the change - // - I feel like there was some other case here but now I can't remember - // it logctx.cleanup_successful(); } From b0b0493cc18f7373c9f1745015cc391e4d7015fa Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 23 Nov 2023 00:41:37 +0000 Subject: [PATCH 40/44] add test that we can keep modifying after migration --- sled-agent/src/services.rs | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 9b58ddf378..112e0df3cc 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -4197,6 +4197,84 @@ mod test { logctx.cleanup_successful(); } + #[tokio::test] + #[serial_test::serial] + async fn test_old_ledger_migration_continue() { + // This test is just like "test_old_ledger_migration", except that we + // deploy a new zone after migration and before shutting down the + // service manager. This tests that new changes modify the new, + // migrated config. + let logctx = omicron_test_utils::dev::test_setup_log( + "test_old_ledger_migration_continue", + ); + 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 helper = + LedgerTestHelper::new(logctx.log.clone(), &test_config).await; + let mgr = helper.clone().new_service_manager(); + LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); + + // Trigger the migration code. + let unused = Mutex::new(BTreeMap::new()); + let migrated_ledger = mgr + .load_ledgered_zones(&unused.lock().await) + .await + .expect("failed to load ledgered zones") + .unwrap(); + + // The other test verified that migration has happened normally so let's + // assume it has. Now provision a new zone. + let vv = migrated_ledger.data().omicron_version.next(); + let id = Uuid::new_v4(); + + let _expectations = expect_new_services(); + let address = + SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); + let mut zones = + migrated_ledger.data().clone().to_omicron_zones_config().zones; + zones.push(OmicronZoneConfig { + id, + underlay_address: Ipv6Addr::LOCALHOST, + zone_type: OmicronZoneType::Oximeter { address }, + }); + mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { + version: vv, + zones, + }) + .await + .expect("failed to add new zone after migration"); + let found = + mgr.omicron_zones_list().await.expect("failed to list zones"); + assert_eq!(found.version, vv); + assert_eq!(found.zones.len(), migrated_ledger.data().zones.len() + 1); + + // Just to be sure, shut down the manager and create a new one without + // triggering migration again. It should now report one more zone than + // was migrated earlier. + 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.version, vv); + assert_eq!(found.zones.len(), migrated_ledger.data().zones.len() + 1); + + drop_service_manager(mgr); + logctx.cleanup_successful(); + } + #[tokio::test] #[serial_test::serial] async fn test_old_ledger_migration_bad() { From 929a8d4c8570ed1a8b95dce963ad7e7d09e44e4f Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 23 Nov 2023 00:56:18 +0000 Subject: [PATCH 41/44] rename ServiceType --- sled-agent/src/services.rs | 112 ++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 57 deletions(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 112e0df3cc..3636458d90 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -365,7 +365,7 @@ pub struct OmicronZoneConfigLocal { struct SwitchZoneConfig { id: Uuid, addresses: Vec, - services: Vec, + services: Vec, } /// Describes one of several services that may be deployed in a switch zone @@ -373,10 +373,8 @@ struct SwitchZoneConfig { /// Some of these are only present in certain configurations (e.g., with a real /// Tofino vs. SoftNPU) or are configured differently depending on the /// configuration. -// XXX-dap towards the end, rename this to SwitchService. Saving it for later -// to avoid having to deal with it more than necessary in merge conflicts. #[derive(Clone)] -enum ServiceType { +enum SwitchService { ManagementGatewayService, Wicketd { baseboard: Baseboard }, Dendrite { asic: DendriteAsic }, @@ -387,17 +385,17 @@ enum ServiceType { SpSim, } -impl crate::smf_helper::Service for ServiceType { +impl crate::smf_helper::Service for SwitchService { fn service_name(&self) -> String { match self { - ServiceType::ManagementGatewayService => "mgs", - ServiceType::Wicketd { .. } => "wicketd", - ServiceType::Dendrite { .. } => "dendrite", - ServiceType::Tfport { .. } => "tfport", - ServiceType::Uplink { .. } => "uplink", - ServiceType::MgDdm { .. } => "mg-ddm", - ServiceType::Mgd => "mgd", - ServiceType::SpSim => "sp-sim", + SwitchService::ManagementGatewayService => "mgs", + SwitchService::Wicketd { .. } => "wicketd", + SwitchService::Dendrite { .. } => "dendrite", + SwitchService::Tfport { .. } => "tfport", + SwitchService::Uplink { .. } => "uplink", + SwitchService::MgDdm { .. } => "mg-ddm", + SwitchService::Mgd => "mgd", + SwitchService::SpSim => "sp-sim", } .to_owned() } @@ -438,7 +436,7 @@ impl<'a> ZoneArgs<'a> { /// supposed to be running pub fn sled_local_services( &self, - ) -> Box + 'a> { + ) -> Box + 'a> { match self { ZoneArgs::Omicron(_) => Box::new(std::iter::empty()), ZoneArgs::SledLocal(request) => { @@ -974,7 +972,7 @@ impl ServiceManager { let mut devices = vec![]; for svc_details in zone_args.sled_local_services() { match svc_details { - ServiceType::Dendrite { asic: DendriteAsic::TofinoAsic } => { + SwitchService::Dendrite { asic: DendriteAsic::TofinoAsic } => { if let Ok(Some(n)) = tofino::get_tofino() { if let Ok(device_path) = n.device_path() { devices.push(device_path); @@ -985,7 +983,7 @@ impl ServiceManager { device: "tofino".to_string(), }); } - ServiceType::Dendrite { + SwitchService::Dendrite { asic: DendriteAsic::SoftNpuPropolisDevice, } => { devices.push("/dev/tty03".into()); @@ -1054,7 +1052,7 @@ impl ServiceManager { for svc_details in zone_args.sled_local_services() { match &svc_details { - ServiceType::Tfport { pkt_source, asic: _ } => { + SwitchService::Tfport { pkt_source, asic: _ } => { // The tfport service requires a MAC device to/from which sidecar // packets may be multiplexed. If the link isn't present, don't // bother trying to start the zone. @@ -1073,7 +1071,7 @@ impl ServiceManager { } } } - ServiceType::MgDdm { .. } => { + SwitchService::MgDdm { .. } => { // If on a non-gimlet, sled-agent can be configured to map // links into the switch zone. Validate those links here. for link in &self.inner.switch_zone_maghemite_links { @@ -1263,7 +1261,7 @@ impl ServiceManager { let mut needed = Vec::new(); for svc_details in zone_args.sled_local_services() { match svc_details { - ServiceType::Tfport { .. } => { + SwitchService::Tfport { .. } => { needed.push("default".to_string()); needed.push("sys_dl_config".to_string()); } @@ -2136,7 +2134,7 @@ impl ServiceManager { smfh.import_manifest()?; match service { - ServiceType::ManagementGatewayService => { + SwitchService::ManagementGatewayService => { info!(self.inner.log, "Setting up MGS service"); smfh.setprop("config/id", request.zone.id)?; @@ -2164,13 +2162,13 @@ impl ServiceManager { smfh.refresh()?; } - ServiceType::SpSim => { + SwitchService::SpSim => { info!( self.inner.log, "Setting up Simulated SP service" ); } - ServiceType::Wicketd { baseboard } => { + SwitchService::Wicketd { baseboard } => { info!(self.inner.log, "Setting up wicketd service"); smfh.setprop( @@ -2254,7 +2252,7 @@ impl ServiceManager { smfh.refresh()?; } - ServiceType::Dendrite { asic } => { + SwitchService::Dendrite { asic } => { info!( self.inner.log, "Setting up dendrite service" @@ -2371,7 +2369,7 @@ impl ServiceManager { }; smfh.refresh()?; } - ServiceType::Tfport { pkt_source, asic } => { + SwitchService::Tfport { pkt_source, asic } => { info!(self.inner.log, "Setting up tfport service"); let is_gimlet = is_gimlet().map_err(|e| { @@ -2425,16 +2423,16 @@ impl ServiceManager { smfh.refresh()?; } - ServiceType::Uplink => { + SwitchService::Uplink => { // Nothing to do here - this service is special and // configured in `ensure_switch_zone_uplinks_configured` } - ServiceType::Mgd => { + SwitchService::Mgd => { info!(self.inner.log, "Setting up mgd service"); smfh.setprop("config/admin_host", "::")?; smfh.refresh()?; } - ServiceType::MgDdm { mode } => { + SwitchService::MgDdm { mode } => { info!(self.inner.log, "Setting up mg-ddm service"); smfh.setprop("config/mode", &mode)?; @@ -3059,16 +3057,16 @@ impl ServiceManager { SledMode::Auto | SledMode::Scrimlet { asic: DendriteAsic::TofinoAsic } => { vec![ - ServiceType::Dendrite { asic: DendriteAsic::TofinoAsic }, - ServiceType::ManagementGatewayService, - ServiceType::Tfport { + SwitchService::Dendrite { asic: DendriteAsic::TofinoAsic }, + SwitchService::ManagementGatewayService, + SwitchService::Tfport { pkt_source: "tfpkt0".to_string(), asic: DendriteAsic::TofinoAsic, }, - ServiceType::Uplink, - ServiceType::Wicketd { baseboard }, - ServiceType::Mgd, - ServiceType::MgDdm { mode: "transit".to_string() }, + SwitchService::Uplink, + SwitchService::Wicketd { baseboard }, + SwitchService::Mgd, + SwitchService::MgDdm { mode: "transit".to_string() }, ] } @@ -3077,17 +3075,17 @@ impl ServiceManager { } => { data_links = vec!["vioif0".to_owned()]; vec![ - ServiceType::Dendrite { asic }, - ServiceType::ManagementGatewayService, - ServiceType::Uplink, - ServiceType::Wicketd { baseboard }, - ServiceType::Mgd, - ServiceType::MgDdm { mode: "transit".to_string() }, - ServiceType::Tfport { + SwitchService::Dendrite { asic }, + SwitchService::ManagementGatewayService, + SwitchService::Uplink, + SwitchService::Wicketd { baseboard }, + SwitchService::Mgd, + SwitchService::MgDdm { mode: "transit".to_string() }, + SwitchService::Tfport { pkt_source: "vioif0".to_string(), asic, }, - ServiceType::SpSim, + SwitchService::SpSim, ] } @@ -3107,17 +3105,17 @@ impl ServiceManager { data_links = Dladm::get_simulated_tfports()?; } vec![ - ServiceType::Dendrite { asic }, - ServiceType::ManagementGatewayService, - ServiceType::Uplink, - ServiceType::Wicketd { baseboard }, - ServiceType::Mgd, - ServiceType::MgDdm { mode: "transit".to_string() }, - ServiceType::Tfport { + SwitchService::Dendrite { asic }, + SwitchService::ManagementGatewayService, + SwitchService::Uplink, + SwitchService::Wicketd { baseboard }, + SwitchService::Mgd, + SwitchService::MgDdm { mode: "transit".to_string() }, + SwitchService::Tfport { pkt_source: "tfpkt0".to_string(), asic, }, - ServiceType::SpSim, + SwitchService::SpSim, ] } }; @@ -3197,7 +3195,7 @@ impl ServiceManager { } }; - let smfh = SmfHelper::new(&zone, &ServiceType::Uplink); + let smfh = SmfHelper::new(&zone, &SwitchService::Uplink); // We want to delete all the properties in the `uplinks` group, but we // don't know their names, so instead we'll delete and recreate the @@ -3338,7 +3336,7 @@ impl ServiceManager { let smfh = SmfHelper::new(&zone, service); match service { - ServiceType::ManagementGatewayService => { + SwitchService::ManagementGatewayService => { // Remove any existing `config/address` values // without deleting the property itself. smfh.delpropvalue("config/address", "*")?; @@ -3372,7 +3370,7 @@ impl ServiceManager { smfh.refresh()?; } - ServiceType::Dendrite { .. } => { + SwitchService::Dendrite { .. } => { info!(self.inner.log, "configuring dendrite zone"); if let Some(info) = self.inner.sled_info.get() { smfh.setprop("config/rack_id", info.rack_id)?; @@ -3408,7 +3406,7 @@ impl ServiceManager { } smfh.refresh()?; } - ServiceType::Wicketd { .. } => { + SwitchService::Wicketd { .. } => { if let Some(&address) = first_address { let rack_subnet = Ipv6Subnet::::new(address); @@ -3431,15 +3429,15 @@ impl ServiceManager { ); } } - ServiceType::Tfport { .. } => { + SwitchService::Tfport { .. } => { // Since tfport and dpd communicate using localhost, // the tfport service shouldn't need to be restarted. } - ServiceType::Uplink { .. } => { + SwitchService::Uplink { .. } => { // Only configured in // `ensure_switch_zone_uplinks_configured` } - ServiceType::MgDdm { mode } => { + SwitchService::MgDdm { mode } => { smfh.delpropvalue("config/mode", "*")?; smfh.addpropvalue("config/mode", &mode)?; smfh.refresh()?; From 98c3137ad3600b05ed153fc347c9e8eb2a1245dc Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Wed, 29 Nov 2023 23:57:55 +0000 Subject: [PATCH 42/44] review feedback, part 1 --- sled-agent/src/params.rs | 2 +- sled-agent/src/rack_setup/plan/service.rs | 9 +- sled-agent/src/rack_setup/service.rs | 48 +-- sled-agent/src/services.rs | 344 +++++++++++----------- sled-agent/src/services_migration.rs | 15 +- 5 files changed, 219 insertions(+), 199 deletions(-) diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 1095f6d380..d7b91f7cbe 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -347,7 +347,7 @@ impl OmicronZoneConfig { /// Returns the structure that describes this zone to Nexus during rack /// initialization - pub fn into_nexus_service_req( + pub fn to_nexus_service_req( &self, sled_id: Uuid, ) -> nexus_client::types::ServicePutRequest { diff --git a/sled-agent/src/rack_setup/plan/service.rs b/sled-agent/src/rack_setup/plan/service.rs index fea8039725..441c7fd842 100644 --- a/sled-agent/src/rack_setup/plan/service.rs +++ b/sled-agent/src/rack_setup/plan/service.rs @@ -178,13 +178,12 @@ impl Plan { async fn has_v1( storage_manager: &StorageHandle, ) -> Result { - let paths: Vec = storage_manager + let paths = storage_manager .get_latest_resources() .await .all_m2_mountpoints(CONFIG_DATASET) .into_iter() - .map(|p| p.join(RSS_SERVICE_PLAN_V1_FILENAME)) - .collect(); + .map(|p| p.join(RSS_SERVICE_PLAN_V1_FILENAME)); for p in paths { if p.try_exists()? { @@ -375,8 +374,8 @@ impl Plan { dataset: OmicronZoneDataset { pool_name: dataset_name.pool().clone(), }, - http_address: http_address, - dns_address: dns_address, + http_address, + dns_address, gz_address: dns_subnet.gz_address().ip(), gz_address_index: i.try_into().expect("Giant indices?"), }, diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 3d0840a17e..4a5c0d34eb 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -268,6 +268,16 @@ impl ServiceInner { ServiceInner { log } } + /// Requests that the specified sled configure zones as described by + /// `zones_config` + /// + /// This function succeeds even if the sled fails to apply the configuration + /// if the reason is that the sled is already running a newer configuration. + /// This might sound oddly specific but it's what our sole caller wants. + /// In particular, the caller is going to call this function a few times + /// with successive generation numbers. If we crash and go through the + /// process again, we might run into this case, and it's simplest to just + /// ignore it and proceed. async fn initialize_zones_on_sled( &self, sled_address: SocketAddrV6, @@ -278,15 +288,16 @@ impl ServiceInner { .connect_timeout(dur) .build() .map_err(SetupServiceError::HttpClient)?; + let log = self.log.new(o!("sled_address" => sled_address.to_string())); let client = SledAgentClient::new_with_client( &format!("http://{}", sled_address), client, - self.log.new(o!("SledAgentClient" => sled_address.to_string())), + log.clone(), ); let services_put = || async { info!( - self.log, + log, "attempting to set up sled's Omicron zones: {:?}", zones_config ); let result = @@ -301,7 +312,7 @@ impl ServiceInner { if let sled_agent_client::Error::ErrorResponse(response) = &error { if response.status() == http::StatusCode::CONFLICT { warn!( - self.log, + log, "ignoring attempt to initialize zones because \ the server seems to be newer"; "attempted_version" => i64::from(&zones_config.version), @@ -309,16 +320,21 @@ impl ServiceInner { "server_message" => &response.message, ); + // If we attempt to initialize zones at version X, and the + // server refuses because it's at some generation newer than + // X, then we treat that as success. See the doc comment on + // this function. return Ok(()); } } - // TODO Many other codes here should not be retried. + // TODO Many other codes here should not be retried. See + // omicron#4578. return Err(BackoffError::transient(error)); }; let log_failure = |error, delay| { warn!( - self.log, + log, "failed to initialize Omicron zones"; "error" => ?error, "retry_after" => ?delay, @@ -348,16 +364,12 @@ impl ServiceInner { &self, configs: &HashMap, ) -> Result<(), SetupServiceError> { - futures::future::join_all(configs.iter().map( + cancel_safe_futures::future::join_all_then_try(configs.iter().map( |(sled_address, zones_config)| async move { - self.initialize_zones_on_sled(*sled_address, zones_config) - .await?; - Ok(()) + self.initialize_zones_on_sled(*sled_address, zones_config).await }, )) - .await - .into_iter() - .collect::>()?; + .await?; Ok(()) } @@ -563,7 +575,7 @@ impl ServiceInner { .expect("Sled address in service plan, but not sled plan"); for zone in &sled_config.zones { - services.push(zone.into_nexus_service_req(sled_id)); + services.push(zone.to_nexus_service_req(sled_id)); } for zone in &sled_config.zones { @@ -986,8 +998,8 @@ impl ServiceInner { // one they're currently running. Thus, the version number is a piece // of global, distributed state. // - // For now, we hardcode the three requests we make to use these three - // version numbers (1, 2, and 3). + // For now, we hardcode the requests we make to use specific version + // numbers. let version1_nothing = Generation::from(OMICRON_ZONES_CONFIG_INITIAL_VERSION); let version2_dns_only = version1_nothing.next(); @@ -1026,7 +1038,7 @@ impl ServiceInner { ) }, ); - self.ensure_zone_config_at_least(&v3generator.sled_configs()).await?; + self.ensure_zone_config_at_least(v3generator.sled_configs()).await?; // Wait until time is synchronized on all sleds before proceeding. self.wait_for_timesync(&sled_addresses).await?; @@ -1040,7 +1052,7 @@ impl ServiceInner { matches!(zone_type, OmicronZoneType::CockroachDb { .. }) }, ); - self.ensure_zone_config_at_least(&v4generator.sled_configs()).await?; + self.ensure_zone_config_at_least(v4generator.sled_configs()).await?; // Now that datasets and zones have started for CockroachDB, // perform one-time initialization of the cluster. @@ -1049,7 +1061,7 @@ impl ServiceInner { // Issue the rest of the zone initialization requests. let v5generator = v4generator.new_version_with(version5_everything, &|_| true); - self.ensure_zone_config_at_least(&v5generator.sled_configs()).await?; + self.ensure_zone_config_at_least(v5generator.sled_configs()).await?; info!(self.log, "Finished setting up services"); diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 4599852b9a..4da2e85848 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -94,7 +94,9 @@ use sled_hardware::underlay; use sled_hardware::underlay::BOOTSTRAP_PREFIX; use sled_hardware::Baseboard; use sled_hardware::SledMode; -use sled_storage::dataset::{CONFIG_DATASET, INSTALL_DATASET, ZONE_DATASET}; +use sled_storage::dataset::{ + DatasetKind, DatasetName, CONFIG_DATASET, INSTALL_DATASET, ZONE_DATASET, +}; use sled_storage::manager::StorageHandle; use slog::Logger; use std::collections::BTreeMap; @@ -220,8 +222,10 @@ pub enum Error { #[error("Error querying simnet devices")] Simnet(#[from] GetSimnetError), - #[error("Requested version ({0}) is older than current ({1})")] - RequestedConfigOutdated(Generation, Generation), + #[error( + "Requested version ({requested}) is older than current ({current})" + )] + RequestedConfigOutdated { requested: Generation, current: Generation }, #[error("Requested version {0} with different zones than before")] RequestedConfigConflicts(Generation), @@ -243,16 +247,12 @@ impl From for omicron_common::api::external::Error { fn from(err: Error) -> Self { match err { err @ Error::RequestedConfigConflicts(_) => { - omicron_common::api::external::Error::invalid_request(&format!( - "{:#}", - err - )) + omicron_common::api::external::Error::invalid_request( + &err.to_string(), + ) } - err @ Error::RequestedConfigOutdated(_, _) => { - omicron_common::api::external::Error::conflict(&format!( - "{:#}", - err - )) + err @ Error::RequestedConfigOutdated { .. } => { + omicron_common::api::external::Error::conflict(&err.to_string()) } _ => omicron_common::api::external::Error::InternalError { internal_message: err.to_string(), @@ -337,6 +337,15 @@ impl Ledgerable for OmicronZonesConfigLocal { } impl OmicronZonesConfigLocal { + /// Returns the initial configuration for generation 1, which has no zones + pub fn initial() -> OmicronZonesConfigLocal { + OmicronZonesConfigLocal { + omicron_version: Generation::new(), + ledger_version: Generation::new(), + zones: vec![], + } + } + pub fn to_omicron_zones_config(self) -> OmicronZonesConfig { OmicronZonesConfig { version: self.omicron_version, @@ -420,7 +429,7 @@ struct SwitchZoneConfigLocal { /// functions that operate on either one or the other enum ZoneArgs<'a> { Omicron(&'a OmicronZoneConfigLocal), - SledLocal(&'a SwitchZoneConfigLocal), + Switch(&'a SwitchZoneConfigLocal), } impl<'a> ZoneArgs<'a> { @@ -428,7 +437,7 @@ impl<'a> ZoneArgs<'a> { pub fn omicron_type(&self) -> Option<&'a OmicronZoneType> { match self { ZoneArgs::Omicron(zone_config) => Some(&zone_config.zone.zone_type), - ZoneArgs::SledLocal(_) => None, + ZoneArgs::Switch(_) => None, } } @@ -439,9 +448,7 @@ impl<'a> ZoneArgs<'a> { ) -> Box + 'a> { match self { ZoneArgs::Omicron(_) => Box::new(std::iter::empty()), - ZoneArgs::SledLocal(request) => { - Box::new(request.zone.services.iter()) - } + ZoneArgs::Switch(request) => Box::new(request.zone.services.iter()), } } @@ -449,7 +456,7 @@ impl<'a> ZoneArgs<'a> { pub fn root(&self) -> &Utf8Path { match self { ZoneArgs::Omicron(zone_config) => &zone_config.root, - ZoneArgs::SledLocal(zone_request) => &zone_request.root, + ZoneArgs::Switch(zone_request) => &zone_request.root, } } } @@ -1009,7 +1016,7 @@ impl ServiceManager { &self, zone_args: &ZoneArgs<'_>, ) -> Result, Error> { - if let ZoneArgs::SledLocal(_) = zone_args { + if let ZoneArgs::Switch(_) = zone_args { let link = self .inner .bootstrap_vnic_allocator @@ -1191,7 +1198,7 @@ impl ServiceManager { nic, snat_cfg, .. }, ) => (zone_type.zone_type_str(), nic, Some(*snat_cfg), &[][..]), - _ => panic!("unexpected zone type"), + _ => unreachable!("unexpected zone type"), }; // Create the OPTE port for the service. @@ -1404,7 +1411,7 @@ impl ServiceManager { // so we can create multiple zones of this type without collision. let unique_name = match &request { ZoneArgs::Omicron(zone_config) => Some(zone_config.zone.id), - ZoneArgs::SledLocal(_) => None, + ZoneArgs::Switch(_) => None, }; let datasets: Vec<_> = match &request { ZoneArgs::Omicron(zone_config) => zone_config @@ -1413,7 +1420,7 @@ impl ServiceManager { .map(|n| zone::Dataset { name: n.full() }) .into_iter() .collect(), - ZoneArgs::SledLocal(_) => vec![], + ZoneArgs::Switch(_) => vec![], }; let devices: Vec = device_names @@ -1441,7 +1448,7 @@ impl ServiceManager { ZoneArgs::Omicron(zone_config) => { zone_config.zone.zone_type.zone_type_str() } - ZoneArgs::SledLocal(_) => "switch".to_string(), + ZoneArgs::Switch(_) => "switch".to_string(), }; let mut zone_builder = ZoneBuilderFactory::default().builder(); @@ -1614,8 +1621,8 @@ impl ServiceManager { ZoneArgs::Omicron(OmicronZoneConfigLocal { zone: - zone @ OmicronZoneConfig { - zone_type: OmicronZoneType::Crucible { .. }, + OmicronZoneConfig { + zone_type: OmicronZoneType::Crucible { dataset, .. }, underlay_address, .. }, @@ -1629,7 +1636,11 @@ impl ServiceManager { let listen_addr = &underlay_address.to_string(); let listen_port = &CRUCIBLE_PORT.to_string(); - let dataset_name = zone.dataset_name().unwrap().full(); + let dataset_name = DatasetName::new( + dataset.pool_name.clone(), + DatasetKind::Crucible, + ) + .full(); let uuid = &Uuid::new_v4().to_string(); let config = PropertyGroupBuilder::new("config") .add_property("datalink", "astring", datalink) @@ -1748,10 +1759,10 @@ impl ServiceManager { ZoneArgs::Omicron(OmicronZoneConfigLocal { zone: OmicronZoneConfig { underlay_address, .. }, .. - }) => vec![*underlay_address], - ZoneArgs::SledLocal(req) => req.zone.addresses.clone(), + }) => std::slice::from_ref(underlay_address), + ZoneArgs::Switch(req) => &req.zone.addresses, }; - for addr in &addresses { + for addr in addresses { if *addr == Ipv6Addr::LOCALHOST { continue; } @@ -2129,7 +2140,7 @@ impl ServiceManager { debug!(self.inner.log, "enabling service"); smfh.enable()?; } - ZoneArgs::SledLocal(request) => { + ZoneArgs::Switch(request) => { for service in &request.zone.services { // TODO: Related to // https://github.com/oxidecomputer/omicron/pull/1124 , should we @@ -2184,10 +2195,11 @@ impl ServiceManager { // If we're launching the switch zone, we'll have a // bootstrap_address based on our call to - // `self.bootstrap_address_needed` (which always gives us an - // address for the switch zone. If we _don't_ have a - // bootstrap address, someone has requested wicketd in a - // non-switch zone; return an error. + // `self.bootstrap_address_needed` (which always + // gives us an address for the switch zone. If we + // _don't_ have a bootstrap address, someone has + // requested wicketd in a non-switch zone; return an + // error. let Some((_, bootstrap_address)) = bootstrap_name_and_address else { @@ -2204,8 +2216,8 @@ impl ServiceManager { smfh.setprop( "config/artifact-address", &format!( - "[{bootstrap_address}]:{BOOTSTRAP_ARTIFACT_PORT}" - ), + "[{bootstrap_address}]:{BOOTSTRAP_ARTIFACT_PORT}" + ), )?; smfh.setprop( @@ -2213,10 +2225,11 @@ impl ServiceManager { &format!("[::1]:{MGS_PORT}"), )?; - // We intentionally bind `nexus-proxy-address` to `::` so - // wicketd will serve this on all interfaces, particularly - // the tech port interfaces, allowing external clients to - // connect to this Nexus proxy. + // We intentionally bind `nexus-proxy-address` to + // `::` so wicketd will serve this on all + // interfaces, particularly the tech port + // interfaces, allowing external clients to connect + // to this Nexus proxy. smfh.setprop( "config/nexus-proxy-address", &format!("[::]:{WICKETD_NEXUS_PROXY_PORT}"), @@ -2298,81 +2311,84 @@ impl ServiceManager { } } match asic { - DendriteAsic::TofinoAsic => { - // There should be exactly one device_name - // associated with this zone: the /dev path for - // the tofino ASIC. - let dev_cnt = device_names.len(); - if dev_cnt == 1 { - smfh.setprop( - "config/dev_path", - device_names[0].clone(), - )?; - } else { - return Err(Error::SledLocalZone( - anyhow::anyhow!( - "{dev_cnt} devices needed for tofino asic" - ), - )); - } - smfh.setprop( - "config/port_config", - "/opt/oxide/dendrite/misc/sidecar_config.toml", - )?; - let sidecar_revision = - match self.inner.sidecar_revision { - SidecarRevision::Physical(ref rev) => rev, - _ => { - return Err(Error::SidecarRevision( + DendriteAsic::TofinoAsic => { + // There should be exactly one device_name + // associated with this zone: the /dev path + // for the tofino ASIC. + let dev_cnt = device_names.len(); + if dev_cnt == 1 { + smfh.setprop( + "config/dev_path", + device_names[0].clone(), + )?; + } else { + return Err(Error::SledLocalZone( anyhow::anyhow!( - "expected physical sidecar revision" - ), - )) + "{dev_cnt} devices needed \ + for tofino asic" + ), + )); } - }; - smfh.setprop("config/board_rev", sidecar_revision)?; - } - DendriteAsic::TofinoStub => smfh.setprop( - "config/port_config", - "/opt/oxide/dendrite/misc/model_config.toml", - )?, - asic @ (DendriteAsic::SoftNpuZone - | DendriteAsic::SoftNpuPropolisDevice) => { - if asic == &DendriteAsic::SoftNpuZone { - smfh.setprop("config/mgmt", "uds")?; - smfh.setprop( - "config/uds_path", - "/opt/softnpu/stuff", - )?; - } - if asic == &DendriteAsic::SoftNpuPropolisDevice { - smfh.setprop("config/mgmt", "uart")?; - } - let s = match self.inner.sidecar_revision { - SidecarRevision::SoftZone(ref s) => s, - SidecarRevision::SoftPropolis(ref s) => s, - _ => { - return Err(Error::SidecarRevision( - anyhow::anyhow!( - "expected soft sidecar revision" - ), - )) + smfh.setprop( + "config/port_config", + "/opt/oxide/dendrite/misc/sidecar_config.toml", + )?; + let sidecar_revision = + match self.inner.sidecar_revision { + SidecarRevision::Physical(ref rev) => rev, + _ => { + return Err(Error::SidecarRevision( + anyhow::anyhow!( + "expected physical \ + sidecar revision" + ), + )) + } + }; + smfh.setprop("config/board_rev", sidecar_revision)?; + } + DendriteAsic::TofinoStub => smfh.setprop( + "config/port_config", + "/opt/oxide/dendrite/misc/model_config.toml", + )?, + asic @ (DendriteAsic::SoftNpuZone + | DendriteAsic::SoftNpuPropolisDevice) => { + if asic == &DendriteAsic::SoftNpuZone { + smfh.setprop("config/mgmt", "uds")?; + smfh.setprop( + "config/uds_path", + "/opt/softnpu/stuff", + )?; + } + if asic == &DendriteAsic::SoftNpuPropolisDevice { + smfh.setprop("config/mgmt", "uart")?; + } + let s = match self.inner.sidecar_revision { + SidecarRevision::SoftZone(ref s) => s, + SidecarRevision::SoftPropolis(ref s) => s, + _ => { + return Err(Error::SidecarRevision( + anyhow::anyhow!( + "expected soft sidecar \ + revision" + ), + )) + } + }; + smfh.setprop( + "config/front_ports", + &s.front_port_count.to_string(), + )?; + smfh.setprop( + "config/rear_ports", + &s.rear_port_count.to_string(), + )?; + smfh.setprop( + "config/port_config", + "/opt/oxide/dendrite/misc/softnpu_single_sled_config.toml", + )? } }; - smfh.setprop( - "config/front_ports", - &s.front_port_count.to_string(), - )?; - smfh.setprop( - "config/rear_ports", - &s.rear_port_count.to_string(), - )?; - smfh.setprop( - "config/port_config", - "/opt/oxide/dendrite/misc/softnpu_single_sled_config.toml", - )? - } - }; smfh.refresh()?; } SwitchService::Tfport { pkt_source, asic } => { @@ -2386,25 +2402,27 @@ impl ServiceManager { if is_gimlet { // Collect the prefixes for each techport. - let techport_prefixes = match bootstrap_name_and_address - .as_ref() - { - Some((_, addr)) => { - Self::bootstrap_addr_to_techport_prefixes(addr) - } - None => { - return Err(Error::BadServiceRequest { - service: "tfport".into(), - message: "bootstrap addr missing".into(), - }); - } - }; + let nameaddr = + bootstrap_name_and_address.as_ref(); + let techport_prefixes = match nameaddr { + Some((_, addr)) => { + Self::bootstrap_addr_to_techport_prefixes(addr) + } + None => { + return Err(Error::BadServiceRequest { + service: "tfport".into(), + message: "bootstrap addr missing" + .into(), + }); + } + }; for (i, prefix) in techport_prefixes.into_iter().enumerate() { - // Each `prefix` is an `Ipv6Subnet` including a netmask. - // Stringify just the network address, without the mask. + // Each `prefix` is an `Ipv6Subnet` + // including a netmask. Stringify just the + // network address, without the mask. smfh.setprop( format!("config/techport{i}_prefix"), prefix.net().network().to_string(), @@ -2431,7 +2449,8 @@ impl ServiceManager { } SwitchService::Uplink => { // Nothing to do here - this service is special and - // configured in `ensure_switch_zone_uplinks_configured` + // configured in + // `ensure_switch_zone_uplinks_configured` } SwitchService::Mgd => { info!(self.inner.log, "Setting up mgd service"); @@ -2454,16 +2473,18 @@ impl ServiceManager { if is_gimlet { (0..32) .map(|i| { - // See the `tfport_name` function for how - // tfportd names the addrconf it creates. - // Right now, that's `tfportrear[0-31]_0` - // for all rear ports, which is what we're - // directing ddmd to listen for - // advertisements on. + // See the `tfport_name` function + // for how tfportd names the + // addrconf it creates. Right now, + // that's `tfportrear[0-31]_0` for + // all rear ports, which is what + // we're directing ddmd to listen + // for advertisements on. // - // This may grow in a multi-rack future to - // include a subset of "front" ports too, - // when racks are cabled together. + // This may grow in a multi-rack + // future to include a subset of + // "front" ports too, when racks are + // cabled together. AddrObject::new( &format!("tfportrear{}_0", i), IPV6_LINK_LOCAL_NAME, @@ -2487,12 +2508,12 @@ impl ServiceManager { smfh.setprop( "config/interfaces", - // `svccfg setprop` requires a list of values to be - // enclosed in `()`, and each string value to be - // enclosed in `""`. Note that we do _not_ need to - // escape the parentheses, since this is not passed - // through a shell, but directly to `exec(2)` in the - // zone. + // `svccfg setprop` requires a list of values to + // be enclosed in `()`, and each string value to + // be enclosed in `""`. Note that we do _not_ + // need to escape the parentheses, since this is + // not passed through a shell, but directly to + // `exec(2)` in the zone. format!( "({})", maghemite_interfaces @@ -2506,8 +2527,8 @@ impl ServiceManager { )?; if is_gimlet { - // Ddm for a scrimlet needs to be configured to talk to - // dendrite + // Ddm for a scrimlet needs to be configured to + // talk to dendrite smfh.setprop("config/dpd_host", "[::1]")?; smfh.setprop("config/dpd_port", DENDRITE_PORT)?; } @@ -2617,25 +2638,17 @@ impl ServiceManager { // Read the existing set of services from the ledger. let zone_ledger_paths = self.all_omicron_zone_ledgers().await; - let ledger = match Ledger::::new( + let ledger_data = match Ledger::::new( log, zone_ledger_paths.clone(), ) .await { - Some(ledger) => ledger, - None => Ledger::::new_with( - log, - zone_ledger_paths.clone(), - OmicronZonesConfigLocal { - omicron_version: Generation::new(), - ledger_version: Generation::new(), - zones: vec![], - }, - ), + Some(ledger) => ledger.data().clone(), + None => OmicronZonesConfigLocal::initial(), }; - Ok(ledger.data().clone().to_omicron_zones_config()) + Ok(ledger_data.to_omicron_zones_config()) } /// Ensures that particular Omicron zones are running @@ -2663,11 +2676,7 @@ impl ServiceManager { None => Ledger::::new_with( log, zone_ledger_paths.clone(), - OmicronZonesConfigLocal { - omicron_version: Generation::new(), - ledger_version: Generation::new(), - zones: vec![], - }, + OmicronZonesConfigLocal::initial(), ), }; @@ -2679,10 +2688,10 @@ impl ServiceManager { // Absolutely refuse to downgrade the configuration. if ledger_zone_config.omicron_version > request.version { - return Err(Error::RequestedConfigOutdated( - request.version, - ledger_zone_config.omicron_version, - )); + return Err(Error::RequestedConfigOutdated { + requested: request.version, + current: ledger_zone_config.omicron_version, + }); } // If the version is the same as what we're running, but the contents @@ -3495,7 +3504,7 @@ impl ServiceManager { let root = Utf8PathBuf::from(ZONE_ZFS_RAMDISK_DATASET_MOUNTPOINT); let zone_request = SwitchZoneConfigLocal { root, zone: request.clone() }; - let zone_args = ZoneArgs::SledLocal(&zone_request); + let zone_args = ZoneArgs::Switch(&zone_request); let zone = self.initialize_zone(zone_args, filesystems, data_links).await?; *sled_zone = SledLocalZone::Running { request: request.clone(), zone }; @@ -4090,7 +4099,8 @@ mod test { .expect_err("unexpectedly went backwards in zones version"); assert!(matches!( error, - Error::RequestedConfigOutdated(vr, vc) if vr == v1 && vc == v2 + Error::RequestedConfigOutdated { requested, current } + if requested == v1 && current == v2 )); let found2 = mgr.omicron_zones_list().await.expect("failed to list zones"); diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index df674967b1..0faacfba82 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -267,8 +267,12 @@ impl TryFrom for OmicronZoneConfig { } // If there's a dataset, its id must match the overall request id. - let has_dataset = input.dataset.is_some(); - if let Some(dataset) = &input.dataset { + 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 ({})", @@ -279,11 +283,6 @@ impl TryFrom for OmicronZoneConfig { } } - let dataset_request = input - .dataset - .ok_or_else(|| anyhow!("missing dataset")) - .with_context(error_context); - let zone_type = match service.details { ServiceType::Nexus { internal_address, @@ -369,7 +368,7 @@ impl TryFrom for OmicronZoneConfig { OmicronZoneType::ClickhouseKeeper { address, dataset: dataset_request?.to_omicron_zone_dataset( - DatasetKind::Clickhouse, + DatasetKind::ClickhouseKeeper, address, )?, } From 4274e9d26a05af7c49328fdffff0b9997fcb4029 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 30 Nov 2023 00:25:56 +0000 Subject: [PATCH 43/44] review feedback: rename version -> generation --- openapi/sled-agent.json | 6 +- schema/all-zones-requests.json | 12 +- sled-agent/src/params.rs | 14 +- sled-agent/src/rack_setup/service.rs | 33 +-- sled-agent/src/services.rs | 215 +++++++++--------- sled-agent/src/services_migration.rs | 45 ++-- .../new-zones-ledgers/rack2-sled10.json | 4 +- .../new-zones-ledgers/rack2-sled11.json | 4 +- .../new-zones-ledgers/rack2-sled12.json | 4 +- .../new-zones-ledgers/rack2-sled14.json | 4 +- .../new-zones-ledgers/rack2-sled16.json | 4 +- .../new-zones-ledgers/rack2-sled17.json | 4 +- .../new-zones-ledgers/rack2-sled21.json | 4 +- .../new-zones-ledgers/rack2-sled23.json | 4 +- .../new-zones-ledgers/rack2-sled25.json | 4 +- .../output/new-zones-ledgers/rack2-sled8.json | 4 +- .../output/new-zones-ledgers/rack2-sled9.json | 4 +- .../output/new-zones-ledgers/rack3-sled0.json | 4 +- .../output/new-zones-ledgers/rack3-sled1.json | 4 +- .../new-zones-ledgers/rack3-sled11.json | 4 +- .../new-zones-ledgers/rack3-sled12.json | 4 +- .../new-zones-ledgers/rack3-sled13.json | 4 +- .../new-zones-ledgers/rack3-sled14.json | 4 +- .../new-zones-ledgers/rack3-sled15.json | 4 +- .../new-zones-ledgers/rack3-sled16.json | 4 +- .../new-zones-ledgers/rack3-sled17.json | 4 +- .../new-zones-ledgers/rack3-sled18.json | 4 +- .../new-zones-ledgers/rack3-sled19.json | 4 +- .../output/new-zones-ledgers/rack3-sled2.json | 4 +- .../new-zones-ledgers/rack3-sled20.json | 4 +- .../new-zones-ledgers/rack3-sled21.json | 4 +- .../new-zones-ledgers/rack3-sled22.json | 4 +- .../new-zones-ledgers/rack3-sled23.json | 4 +- .../new-zones-ledgers/rack3-sled24.json | 4 +- .../new-zones-ledgers/rack3-sled25.json | 4 +- .../new-zones-ledgers/rack3-sled26.json | 4 +- .../new-zones-ledgers/rack3-sled27.json | 4 +- .../new-zones-ledgers/rack3-sled28.json | 4 +- .../new-zones-ledgers/rack3-sled29.json | 4 +- .../output/new-zones-ledgers/rack3-sled3.json | 4 +- .../new-zones-ledgers/rack3-sled30.json | 4 +- .../new-zones-ledgers/rack3-sled31.json | 4 +- .../output/new-zones-ledgers/rack3-sled4.json | 4 +- .../output/new-zones-ledgers/rack3-sled5.json | 4 +- .../output/new-zones-ledgers/rack3-sled6.json | 4 +- .../output/new-zones-ledgers/rack3-sled7.json | 4 +- .../output/new-zones-ledgers/rack3-sled8.json | 4 +- .../output/new-zones-ledgers/rack3-sled9.json | 4 +- 48 files changed, 255 insertions(+), 238 deletions(-) diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index e5cc5f4e13..098aee3cb4 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -5306,8 +5306,8 @@ "description": "Describes the set of Omicron-managed zones running on a sled", "type": "object", "properties": { - "version": { - "description": "version number of this configuration\n\nThis version number is owned by the control plane (i.e., RSS or Nexus, depending on whether RSS-to-Nexus handoff has happened). It should not be bumped within Sled Agent.\n\nSled Agent rejects attempts to set the configuration to a version older than the one it's currently running.", + "generation": { + "description": "generation number of this configuration\n\nThis generation number is owned by the control plane (i.e., RSS or Nexus, depending on whether RSS-to-Nexus handoff has happened). It should not be bumped within Sled Agent.\n\nSled Agent rejects attempts to set the configuration to a generation older than the one it's currently running.", "allOf": [ { "$ref": "#/components/schemas/Generation" @@ -5323,7 +5323,7 @@ } }, "required": [ - "version", + "generation", "zones" ] }, diff --git a/schema/all-zones-requests.json b/schema/all-zones-requests.json index 25d528ed75..0e43e9ee21 100644 --- a/schema/all-zones-requests.json +++ b/schema/all-zones-requests.json @@ -4,21 +4,21 @@ "description": "Combines the Nexus-provided `OmicronZonesConfig` (which describes what Nexus wants for all of its zones) with the locally-determined configuration for these zones.", "type": "object", "required": [ - "ledger_version", - "omicron_version", + "ledger_generation", + "omicron_generation", "zones" ], "properties": { - "ledger_version": { - "description": "ledger-managed version\n\nThis version is managed by the ledger facility itself. It's bumped whenever we write a new ledger. In practice, we don't currently have any reason to bump this _for a given Omicron version_ so it's somewhat redundant. In principle, if we needed to modify the ledgered configuration due to some event that doesn't change the Omicron config (e.g., if we wanted to move the root filesystem to a different path), we could do that by bumping this version.", + "ledger_generation": { + "description": "ledger-managed generation number\n\nThis generation is managed by the ledger facility itself. It's bumped whenever we write a new ledger. In practice, we don't currently have any reason to bump this _for a given Omicron generation_ so it's somewhat redundant. In principle, if we needed to modify the ledgered configuration due to some event that doesn't change the Omicron config (e.g., if we wanted to move the root filesystem to a different path), we could do that by bumping this generation.", "allOf": [ { "$ref": "#/definitions/Generation" } ] }, - "omicron_version": { - "description": "version of the Omicron-provided part of the configuration\n\nThis version number is outside of Sled Agent's control. We store exactly what we were given and use this number to decide when to fail requests to establish an outdated configuration.\n\nYou can think of this as a major version number, with `ledger_version` being a minor version number. See `is_newer_than()`.", + "omicron_generation": { + "description": "generation of the Omicron-provided part of the configuration\n\nThis generation number is outside of Sled Agent's control. We store exactly what we were given and use this number to decide when to fail requests to establish an outdated configuration.\n\nYou can think of this as a major version number, with `ledger_generation` being a minor version number. See `is_newer_than()`.", "allOf": [ { "$ref": "#/definitions/Generation" diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index d7b91f7cbe..6be2ceabbd 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -270,23 +270,23 @@ impl std::fmt::Display for ZoneType { } } -/// Version 1 of `OmicronZonesConfig` is always the set of no zones. -pub const OMICRON_ZONES_CONFIG_INITIAL_VERSION: u32 = 1; +/// Generation 1 of `OmicronZonesConfig` is always the set of no zones. +pub const OMICRON_ZONES_CONFIG_INITIAL_GENERATION: u32 = 1; /// Describes the set of Omicron-managed zones running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, )] pub struct OmicronZonesConfig { - /// version number of this configuration + /// generation number of this configuration /// - /// This version number is owned by the control plane (i.e., RSS or + /// This generation number is owned by the control plane (i.e., RSS or /// Nexus, depending on whether RSS-to-Nexus handoff has happened). It /// should not be bumped within Sled Agent. /// - /// Sled Agent rejects attempts to set the configuration to a version + /// Sled Agent rejects attempts to set the configuration to a generation /// older than the one it's currently running. - pub version: Generation, + pub generation: Generation, /// list of running zones pub zones: Vec, @@ -295,7 +295,7 @@ pub struct OmicronZonesConfig { impl From for sled_agent_client::types::OmicronZonesConfig { fn from(local: OmicronZonesConfig) -> Self { Self { - version: local.version.into(), + generation: local.generation.into(), zones: local.zones.into_iter().map(|s| s.into()).collect(), } } diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index 4a5c0d34eb..4b6b4be541 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -76,7 +76,7 @@ use crate::bootstrap::rss_handle::BootstrapAgentHandle; use crate::nexus::{d2n_params, ConvertInto}; use crate::params::{ OmicronZoneType, OmicronZonesConfig, TimeSync, - OMICRON_ZONES_CONFIG_INITIAL_VERSION, + OMICRON_ZONES_CONFIG_INITIAL_GENERATION, }; use crate::rack_setup::plan::service::{ Plan as ServicePlan, PlanError as ServicePlanError, @@ -315,15 +315,16 @@ impl ServiceInner { log, "ignoring attempt to initialize zones because \ the server seems to be newer"; - "attempted_version" => i64::from(&zones_config.version), + "attempted_generation" => + i64::from(&zones_config.generation), "req_id" => &response.request_id, "server_message" => &response.message, ); - // If we attempt to initialize zones at version X, and the - // server refuses because it's at some generation newer than - // X, then we treat that as success. See the doc comment on - // this function. + // If we attempt to initialize zones at generation X, and + // the server refuses because it's at some generation newer + // than X, then we treat that as success. See the doc + // comment on this function. return Ok(()); } } @@ -1001,7 +1002,7 @@ impl ServiceInner { // For now, we hardcode the requests we make to use specific version // numbers. let version1_nothing = - Generation::from(OMICRON_ZONES_CONFIG_INITIAL_VERSION); + Generation::from(OMICRON_ZONES_CONFIG_INITIAL_GENERATION); let version2_dns_only = version1_nothing.next(); let version3_dns_and_ntp = version2_dns_only.next(); let version4_cockroachdb = version3_dns_and_ntp.next(); @@ -1125,7 +1126,7 @@ impl<'a> OmicronZonesConfigGenerator<'a> { ( *sled_address, OmicronZonesConfig { - version: initial_version, + generation: initial_version, zones: vec![], }, ) @@ -1158,7 +1159,7 @@ impl<'a> OmicronZonesConfigGenerator<'a> { .map(|(sled_address, sled_config)| { let mut zones = match self.last_configs.get(sled_address) { Some(config) => { - assert!(version > config.version); + assert!(version > config.generation); config.zones.clone() } None => Vec::new(), @@ -1177,7 +1178,7 @@ impl<'a> OmicronZonesConfigGenerator<'a> { .cloned(), ); - let config = OmicronZonesConfig { version, zones }; + let config = OmicronZonesConfig { generation: version, zones }; (*sled_address, config) }) .collect(); @@ -1265,7 +1266,7 @@ mod test { v1.sled_configs().keys().len() ); for (_, configs) in v1.sled_configs() { - assert_eq!(configs.version, g1); + assert_eq!(configs.generation, g1); assert!(configs.zones.is_empty()); } @@ -1276,7 +1277,7 @@ mod test { }); let mut v2_nfound = 0; for (_, config) in v2.sled_configs() { - assert_eq!(config.version, g2); + assert_eq!(config.generation, g2); v2_nfound += config.zones.len(); for z in &config.zones { // The only zones we should find are the Internal DNS ones. @@ -1296,7 +1297,7 @@ mod test { }); let mut v3_nfound = 0; for (_, config) in v3.sled_configs() { - assert_eq!(config.version, g3); + assert_eq!(config.generation, g3); v3_nfound += config.zones.len(); for z in &config.zones { // The only zones we should find are the Internal DNS ones. @@ -1317,7 +1318,7 @@ mod test { let mut v4_nfound_dns = 0; let mut v4_nfound = 0; for (_, config) in v4.sled_configs() { - assert_eq!(config.version, g4); + assert_eq!(config.generation, g4); v4_nfound += config.zones.len(); for z in &config.zones { match &z.zone_type { @@ -1336,7 +1337,7 @@ mod test { let v5 = v4.new_version_with(g5, &|_| false); let mut v5_nfound = 0; for (_, config) in v5.sled_configs() { - assert_eq!(config.version, g5); + assert_eq!(config.generation, g5); v5_nfound += config.zones.len(); for z in &config.zones { assert!(matches!( @@ -1353,7 +1354,7 @@ mod test { let v6 = v5.new_version_with(g6, &|_| true); let mut v6_nfound = 0; for (sled_address, config) in v6.sled_configs() { - assert_eq!(config.version, g6); + assert_eq!(config.generation, g6); v6_nfound += config.zones.len(); assert_eq!( config.zones.len(), diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 4da2e85848..baefd648e7 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -223,11 +223,11 @@ pub enum Error { Simnet(#[from] GetSimnetError), #[error( - "Requested version ({requested}) is older than current ({current})" + "Requested generation ({requested}) is older than current ({current})" )] RequestedConfigOutdated { requested: Generation, current: Generation }, - #[error("Requested version {0} with different zones than before")] + #[error("Requested generation {0} with different zones than before")] RequestedConfigConflicts(Generation), #[error("Error migrating old-format services ledger: {0:#}")] @@ -301,38 +301,39 @@ const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, )] pub struct OmicronZonesConfigLocal { - /// version of the Omicron-provided part of the configuration + /// generation of the Omicron-provided part of the configuration /// - /// This version number is outside of Sled Agent's control. We store + /// This generation number is outside of Sled Agent's control. We store /// exactly what we were given and use this number to decide when to /// fail requests to establish an outdated configuration. /// - /// You can think of this as a major version number, with `ledger_version` - /// being a minor version number. See `is_newer_than()`. - pub omicron_version: Generation, + /// You can think of this as a major version number, with + /// `ledger_generation` being a minor version number. See + /// `is_newer_than()`. + pub omicron_generation: Generation, - /// ledger-managed version + /// ledger-managed generation number /// - /// This version is managed by the ledger facility itself. It's bumped + /// This generation is managed by the ledger facility itself. It's bumped /// whenever we write a new ledger. In practice, we don't currently have - /// any reason to bump this _for a given Omicron version_ so it's somewhat - /// redundant. In principle, if we needed to modify the ledgered + /// any reason to bump this _for a given Omicron generation_ so it's + /// somewhat redundant. In principle, if we needed to modify the ledgered /// configuration due to some event that doesn't change the Omicron config /// (e.g., if we wanted to move the root filesystem to a different path), we - /// could do that by bumping this version. - pub ledger_version: Generation, + /// could do that by bumping this generation. + pub ledger_generation: Generation, pub zones: Vec, } impl Ledgerable for OmicronZonesConfigLocal { fn is_newer_than(&self, other: &OmicronZonesConfigLocal) -> bool { - self.omicron_version > other.omicron_version - || (self.omicron_version == other.omicron_version - && self.ledger_version >= other.ledger_version) + self.omicron_generation > other.omicron_generation + || (self.omicron_generation == other.omicron_generation + && self.ledger_generation >= other.ledger_generation) } fn generation_bump(&mut self) { - self.ledger_version = self.ledger_version.next(); + self.ledger_generation = self.ledger_generation.next(); } } @@ -340,15 +341,15 @@ impl OmicronZonesConfigLocal { /// Returns the initial configuration for generation 1, which has no zones pub fn initial() -> OmicronZonesConfigLocal { OmicronZonesConfigLocal { - omicron_version: Generation::new(), - ledger_version: Generation::new(), + omicron_generation: Generation::new(), + ledger_generation: Generation::new(), zones: vec![], } } pub fn to_omicron_zones_config(self) -> OmicronZonesConfig { OmicronZonesConfig { - version: self.omicron_version, + generation: self.omicron_generation, zones: self.zones.into_iter().map(|z| z.zone).collect(), } } @@ -1060,9 +1061,9 @@ impl ServiceManager { for svc_details in zone_args.sled_local_services() { match &svc_details { SwitchService::Tfport { pkt_source, asic: _ } => { - // The tfport service requires a MAC device to/from which sidecar - // packets may be multiplexed. If the link isn't present, don't - // bother trying to start the zone. + // The tfport service requires a MAC device to/from which + // sidecar packets may be multiplexed. If the link isn't + // present, don't bother trying to start the zone. match Dladm::verify_link(pkt_source) { Ok(link) => { // It's important that tfpkt does **not** receive a @@ -1109,7 +1110,8 @@ impl ServiceManager { } // Check the services intended to run in the zone to determine whether any - // OPTE ports need to be created and mapped into the zone when it is created. + // OPTE ports need to be created and mapped into the zone when it is + // created. async fn opte_ports_needed( &self, zone_args: &ZoneArgs<'_>, @@ -1845,16 +1847,17 @@ impl ServiceManager { .get() .ok_or(Error::SledAgentNotReady)?; - // While Nexus will be reachable via `external_ip`, it communicates - // atop an OPTE port which operates on a VPC private IP. OPTE will - // map the private IP to the external IP automatically. + // While Nexus will be reachable via `external_ip`, it + // communicates atop an OPTE port which operates on a + // VPC private IP. OPTE will map the private IP to the + // external IP automatically. let port_ip = running_zone .ensure_address_for_port("public", 0) .await? .ip(); - // Nexus takes a separate config file for parameters which - // cannot be known at packaging time. + // Nexus takes a separate config file for parameters + // which cannot be known at packaging time. let nexus_port = if *external_tls { 443 } else { 80 }; let deployment_config = NexusDeploymentConfig { id: zone_config.zone.id, @@ -1879,8 +1882,8 @@ impl ServiceManager { bind_address: (*internal_address).into(), // This has to be large enough to support, among // other things, the initial list of TLS - // certificates provided by the customer during rack - // setup. + // certificates provided by the customer during + // rack setup. request_body_max_bytes: 10 * 1024 * 1024, default_handler_task_mode: HandlerTaskMode::Detached, @@ -1895,17 +1898,19 @@ impl ServiceManager { external_dns_servers: external_dns_servers.clone(), }; - // Copy the partial config file to the expected location. + // Copy the partial config file to the expected + // location. let config_dir = Utf8PathBuf::from(format!( "{}/var/svc/manifest/site/nexus", running_zone.root() )); - // The filename of a half-completed config, in need of parameters supplied at - // runtime. + // The filename of a half-completed config, in need of + // parameters supplied at runtime. const PARTIAL_LEDGER_FILENAME: &str = "config-partial.toml"; - // The filename of a completed config, merging the partial config with - // additional appended parameters known at runtime. + // The filename of a completed config, merging the + // partial config with additional appended parameters + // known at runtime. const COMPLETE_LEDGER_FILENAME: &str = "config.toml"; let partial_config_path = config_dir.join(PARTIAL_LEDGER_FILENAME); @@ -1915,7 +1920,8 @@ impl ServiceManager { .await .map_err(|err| Error::io_path(&config_path, err))?; - // Serialize the configuration and append it into the file. + // Serialize the configuration and append it into the + // file. let serialized_cfg = toml::Value::try_from(&deployment_config) .expect("Cannot serialize config"); @@ -1975,9 +1981,9 @@ impl ServiceManager { dns_address.to_string(), )?; - // Refresh the manifest with the new properties we set, so - // they become "effective" properties when the service is - // enabled. + // Refresh the manifest with the new properties we set, + // so they become "effective" properties when the + // service is enabled. smfh.refresh()?; } @@ -1993,19 +1999,19 @@ impl ServiceManager { "Setting up internal-dns service" ); - // Internal DNS zones require a special route through the - // global zone, since they are not on the same part of the - // underlay as most other services on this sled (the sled's - // subnet). + // Internal DNS zones require a special route through + // the global zone, since they are not on the same part + // of the underlay as most other services on this sled + // (the sled's subnet). // - // We create an IP address in the dedicated portion of the - // underlay used for internal DNS servers, but we *also* - // add a number ("which DNS server is this") to ensure - // these addresses are given unique names. In the unlikely - // case that two internal DNS servers end up on the same - // machine (which is effectively a developer-only - // environment -- we wouldn't want this in prod!), they need - // to be given distinct names. + // We create an IP address in the dedicated portion of + // the underlay used for internal DNS servers, but we + // *also* add a number ("which DNS server is this") to + // ensure these addresses are given unique names. In the + // unlikely case that two internal DNS servers end up on + // the same machine (which is effectively a + // developer-only environment -- we wouldn't want this + // in prod!), they need to be given distinct names. let addr_name = format!("internaldns{gz_address_index}"); Zones::ensure_has_global_zone_v6_address( @@ -2022,8 +2028,8 @@ impl ServiceManager { err, } })?; - // If this address is in a new ipv6 prefix, notify maghemite so - // it can advertise it to other sleds. + // If this address is in a new ipv6 prefix, notify + // maghemite so it can advertise it to other sleds. self.advertise_prefix_of_address(*gz_address).await; running_zone.add_default_route(*gz_address).map_err( @@ -2050,9 +2056,9 @@ impl ServiceManager { ), )?; - // Refresh the manifest with the new properties we set, so - // they become "effective" properties when the service is - // enabled. + // Refresh the manifest with the new properties we set, + // so they become "effective" properties when the + // service is enabled. smfh.refresh()?; } @@ -2155,8 +2161,9 @@ impl ServiceManager { info!(self.inner.log, "Setting up MGS service"); smfh.setprop("config/id", request.zone.id)?; - // Always tell MGS to listen on localhost so wicketd can - // contact it even before we have an underlay network. + // Always tell MGS to listen on localhost so wicketd + // can contact it even before we have an underlay + // network. smfh.addpropvalue( "config/address", &format!("[::1]:{MGS_PORT}"), @@ -2682,25 +2689,26 @@ impl ServiceManager { let ledger_zone_config = ledger.data_mut(); debug!(log, "ensure_all_omicron_zones_persistent"; - "request_version" => request.version.to_string(), - "ledger_version" => ledger_zone_config.omicron_version.to_string(), + "request_generation" => request.generation.to_string(), + "ledger_generation" => + ledger_zone_config.omicron_generation.to_string(), ); // Absolutely refuse to downgrade the configuration. - if ledger_zone_config.omicron_version > request.version { + if ledger_zone_config.omicron_generation > request.generation { return Err(Error::RequestedConfigOutdated { - requested: request.version, - current: ledger_zone_config.omicron_version, + requested: request.generation, + current: ledger_zone_config.omicron_generation, }); } - // If the version is the same as what we're running, but the contents + // If the generation is the same as what we're running, but the contents // aren't, that's a problem, too. - if ledger_zone_config.omicron_version == request.version + if ledger_zone_config.omicron_generation == request.generation && ledger_zone_config.clone().to_omicron_zones_config().zones != request.zones { - return Err(Error::RequestedConfigConflicts(request.version)); + return Err(Error::RequestedConfigConflicts(request.generation)); } let new_config = self @@ -2850,9 +2858,9 @@ impl ServiceManager { } Ok(OmicronZonesConfigLocal { - omicron_version: new_request.version, - ledger_version: old_config - .map(|c| c.ledger_version) + omicron_generation: new_request.generation, + ledger_generation: old_config + .map(|c| c.ledger_generation) .unwrap_or_else(Generation::new), zones: new_zones, }) @@ -3061,7 +3069,8 @@ impl ServiceManager { let mut data_links: Vec = vec![]; let services = match self.inner.sled_mode { - // A pure gimlet sled should not be trying to activate a switch zone. + // A pure gimlet sled should not be trying to activate a switch + // zone. SledMode::Gimlet => { return Err(Error::SledLocalZone(anyhow::anyhow!( "attempted to activate switch zone on non-scrimlet sled" @@ -3369,8 +3378,9 @@ impl ServiceManager { &format!("[{address}]:{MGS_PORT}"), )?; - // It should be impossible for the `sled_info` not to be set here, - // as the underlay is set at the same time. + // It should be impossible for the `sled_info` not + // to be set here, as the underlay is set at the + // same time. if let Some(info) = self.inner.sled_info.get() { smfh.setprop("config/rack_id", info.rack_id)?; } else { @@ -3446,7 +3456,8 @@ impl ServiceManager { } SwitchService::Tfport { .. } => { // Since tfport and dpd communicate using localhost, - // the tfport service shouldn't need to be restarted. + // the tfport service shouldn't need to be + // restarted. } SwitchService::Uplink { .. } => { // Only configured in @@ -3724,13 +3735,13 @@ mod test { async fn ensure_new_service( mgr: &ServiceManager, id: Uuid, - version: Generation, + generation: Generation, ) { let _expectations = expect_new_service(); let address = SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version, + generation, zones: vec![OmicronZoneConfig { id, underlay_address: Ipv6Addr::LOCALHOST, @@ -3746,12 +3757,12 @@ mod test { async fn ensure_existing_service( mgr: &ServiceManager, id: Uuid, - version: Generation, + generation: Generation, ) { let address = SocketAddrV6::new(Ipv6Addr::LOCALHOST, OXIMETER_PORT, 0, 0); mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version, + generation, zones: vec![OmicronZoneConfig { id, underlay_address: Ipv6Addr::LOCALHOST, @@ -3916,7 +3927,7 @@ mod test { let v1 = Generation::new(); let found = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found.version, v1); + assert_eq!(found.generation, v1); assert!(found.zones.is_empty()); let v2 = v1.next(); @@ -3925,7 +3936,7 @@ mod test { let found = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found.version, v2); + assert_eq!(found.generation, v2); assert_eq!(found.zones.len(), 1); assert_eq!(found.zones[0].id, id); @@ -3953,7 +3964,7 @@ mod test { ensure_existing_service(&mgr, id, v3).await; let found = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found.version, v3); + assert_eq!(found.generation, v3); assert_eq!(found.zones.len(), 1); assert_eq!(found.zones[0].id, id); @@ -3990,7 +4001,7 @@ mod test { let found = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found.version, v2); + assert_eq!(found.generation, v2); assert_eq!(found.zones.len(), 1); assert_eq!(found.zones[0].id, id); @@ -4033,7 +4044,7 @@ mod test { let found = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found.version, v1); + assert_eq!(found.generation, v1); assert!(found.zones.is_empty()); drop_service_manager(mgr); @@ -4043,10 +4054,10 @@ mod test { #[tokio::test] #[serial_test::serial] - async fn test_bad_versions() { + async fn test_bad_generations() { // Start like the normal tests. let logctx = - omicron_test_utils::dev::test_setup_log("test_bad_versions"); + omicron_test_utils::dev::test_setup_log("test_bad_generations"); let test_config = TestConfig::new().await; let helper = LedgerTestHelper::new(logctx.log.clone(), &test_config).await; @@ -4067,7 +4078,7 @@ mod test { zone_type: OmicronZoneType::Oximeter { address }, }]; mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version: v2, + generation: v2, zones: zones.clone(), }) .await @@ -4075,7 +4086,7 @@ mod test { let found = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found.version, v2); + assert_eq!(found.generation, v2); assert_eq!(found.zones.len(), 1); assert_eq!(found.zones[0].id, id1); @@ -4088,15 +4099,15 @@ mod test { zone_type: OmicronZoneType::Oximeter { address }, }); - // Now try to apply that list with an older version number. This + // Now try to apply that list with an older generation number. This // shouldn't work and the reported state should be unchanged. let error = mgr .ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version: v1, + generation: v1, zones: zones.clone(), }) .await - .expect_err("unexpectedly went backwards in zones version"); + .expect_err("unexpectedly went backwards in zones generation"); assert!(matches!( error, Error::RequestedConfigOutdated { requested, current } @@ -4106,15 +4117,15 @@ mod test { mgr.omicron_zones_list().await.expect("failed to list zones"); assert_eq!(found, found2); - // Now try to apply that list with the same version number that we used - // before. This shouldn't work either. + // Now try to apply that list with the same generation number that we + // used before. This shouldn't work either. let error = mgr .ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version: v2, + generation: v2, zones: zones.clone(), }) .await - .expect_err("unexpectedly changed a single zone version"); + .expect_err("unexpectedly changed a single zone generation"); assert!(matches!( error, Error::RequestedConfigConflicts(vr) if vr == v2 @@ -4124,17 +4135,17 @@ mod test { assert_eq!(found, found3); // But we should be able to apply this new list of zones as long as we - // advance the version number. + // advance the generation number. let v3 = v2.next(); mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version: v3, + generation: v3, zones: zones.clone(), }) .await - .expect("failed to remove all zones in a new version"); + .expect("failed to remove all zones in a new generation"); let found4 = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found4.version, v3); + assert_eq!(found4.generation, v3); let mut our_zones = zones; our_zones.sort_by(|a, b| a.id.cmp(&b.id)); let mut found_zones = found4.zones; @@ -4249,7 +4260,7 @@ mod test { // The other test verified that migration has happened normally so let's // assume it has. Now provision a new zone. - let vv = migrated_ledger.data().omicron_version.next(); + let vv = migrated_ledger.data().omicron_generation.next(); let id = Uuid::new_v4(); let _expectations = expect_new_services(); @@ -4263,14 +4274,14 @@ mod test { zone_type: OmicronZoneType::Oximeter { address }, }); mgr.ensure_all_omicron_zones_persistent(OmicronZonesConfig { - version: vv, + generation: vv, zones, }) .await .expect("failed to add new zone after migration"); let found = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found.version, vv); + assert_eq!(found.generation, vv); assert_eq!(found.zones.len(), migrated_ledger.data().zones.len() + 1); // Just to be sure, shut down the manager and create a new one without @@ -4282,7 +4293,7 @@ mod test { LedgerTestHelper::sled_agent_started(&logctx.log, &test_config, &mgr); let found = mgr.omicron_zones_list().await.expect("failed to list zones"); - assert_eq!(found.version, vv); + assert_eq!(found.generation, vv); assert_eq!(found.zones.len(), migrated_ledger.data().zones.len() + 1); drop_service_manager(mgr); diff --git a/sled-agent/src/services_migration.rs b/sled-agent/src/services_migration.rs index 0faacfba82..bedd4759c8 100644 --- a/sled-agent/src/services_migration.rs +++ b/sled-agent/src/services_migration.rs @@ -25,7 +25,7 @@ use crate::params::{ OmicronZoneConfig, OmicronZoneDataset, OmicronZoneType, ZoneType, - OMICRON_ZONES_CONFIG_INITIAL_VERSION, + OMICRON_ZONES_CONFIG_INITIAL_GENERATION, }; use crate::services::{OmicronZoneConfigLocal, OmicronZonesConfigLocal}; use anyhow::{anyhow, ensure, Context}; @@ -74,40 +74,41 @@ impl TryFrom for OmicronZonesConfigLocal { type Error = anyhow::Error; fn try_from(input: AllZoneRequests) -> Result { - // The Omicron version number that we choose here (2) deserves some + // The Omicron generation number that we choose here (2) deserves some // explanation. // - // This is supposed to be the control-plane-issued version number for + // 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 version numbers at - // all. So what should we assign it? Well, what are the constraints? + // 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 version 1 because version 1 canonically + // - It must be newer than generation 1 because generation 1 canonically // represents the initial state of having no zones deployed. If we - // used version 1 here, any code could ignore this configuration on + // 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 version are supposed to be immutable.) + // 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 version number is and subsequent configurations should use - // newer version numbers. It's not a great plan for it to assume - // anything about the version numbers deployed on sleds whose - // configurations it's never seen. (In practice, newly deployed + // 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_version = - Generation::from(OMICRON_ZONES_CONFIG_INITIAL_VERSION).next(); + let omicron_generation = + Generation::from(OMICRON_ZONES_CONFIG_INITIAL_GENERATION).next(); - // The ledger version doesn't really matter. In case it's useful, we - // pick the version from the ledger that we loaded. - let ledger_version = input.generation; + // 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(); @@ -121,8 +122,8 @@ impl TryFrom for OmicronZonesConfigLocal { "mapping `AllZoneRequests` to `OmicronZonesConfigLocal`", )?; - // As a quick check, the number of datasets in the old and new versions - // ought to be the same. + // 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!( @@ -130,7 +131,11 @@ impl TryFrom for OmicronZonesConfigLocal { "conversion produced a different number of datasets" ); - Ok(OmicronZonesConfigLocal { omicron_version, ledger_version, zones }) + Ok(OmicronZonesConfigLocal { + omicron_generation, + ledger_generation, + zones, + }) } } diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json index 9b0a1041b0..c00a65e8ea 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled10.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json index b06f7fb11b..79aae3e8c1 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled11.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json index 22d3409330..39ebad3183 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled12.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 5, + "omicron_generation": 2, + "ledger_generation": 5, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json index cbb57aa467..25dfb72a78 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled14.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json index dc72514214..905742e678 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled16.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json index deca9d4701..1cccd0467b 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled17.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json index 931801ae35..35caa638e8 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled21.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 5, + "omicron_generation": 2, + "ledger_generation": 5, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json index cda63747a1..94fcb3a327 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled23.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 5, + "omicron_generation": 2, + "ledger_generation": 5, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json index a7d133bc7a..09a07149cf 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled25.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json index f08344ce3c..669889b3c5 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled8.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json b/sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json index ec9169f276..d4a429f9b0 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack2-sled9.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json index 8a87e8c0dd..db6c55f556 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled0.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json index 2ae8a43e9f..ae3e3d8f4a 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled1.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json index 9e92579e4e..c94417ffb8 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled11.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 5, + "omicron_generation": 2, + "ledger_generation": 5, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json index b39fad4765..bfc30cf160 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled12.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json index a4b2d416a0..66c04be148 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled13.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 5, + "omicron_generation": 2, + "ledger_generation": 5, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json index 7787ac0564..e8d061dbfd 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled14.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json index af716b7dd0..e3b3dba86a 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled15.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json index 583974a2b0..3cd727e1bc 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled16.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json index 13234a39eb..09981ecacc 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled17.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json index 5e933b56cf..708019883e 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled18.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json index c39b62741a..197df304e3 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled19.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json index 2a868a10b1..ba6ab6f915 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled2.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json index 5e25895750..f02f1f05e5 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled20.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json index 687137f65c..d6c19b96ed 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled21.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json index f0e95af8d3..1cd6fed362 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled22.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json index c09b7d99e3..ab171ad8cd 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled23.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json index 78c3befff5..9968abe6d9 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled24.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json index 3255b6b08d..8deca6b56a 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled25.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json index c61f9c7a39..a3c5d97b53 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled26.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json index 309f8360ab..193df7a567 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled27.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json index 6a3dc40b7b..210b388a19 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled28.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json index cce200479f..ccd1bd65be 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled29.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 5, + "omicron_generation": 2, + "ledger_generation": 5, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json index 330811ea94..5da6d95389 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled3.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json index 8316dca294..c92a638b85 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled30.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json index d4792a4707..5e38262740 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled31.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json index 7d443a74e6..7c1d269d61 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled4.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json index 2b43a62811..acbfa17eda 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled5.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json index a48ccdd6a7..ce4b6f03cd 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled6.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json index 9a11795014..62653d0767 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled7.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json index da31e8048f..b848826231 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled8.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { diff --git a/sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json b/sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json index 1b6bd0b2bf..62d45a2f5a 100644 --- a/sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json +++ b/sled-agent/tests/output/new-zones-ledgers/rack3-sled9.json @@ -1,6 +1,6 @@ { - "omicron_version": 2, - "ledger_version": 4, + "omicron_generation": 2, + "ledger_generation": 4, "zones": [ { "zone": { From 5e55c48b008012aa8eb1c95b4db9519026cf27c2 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Thu, 30 Nov 2023 00:26:20 +0000 Subject: [PATCH 44/44] new ledger filename is inconsistent with the others --- sled-agent/src/services.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index baefd648e7..88f79e7064 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -292,7 +292,7 @@ impl Config { } // The filename of the ledger, within the provided directory. -const ZONES_LEDGER_FILENAME: &str = "omicron_zones.json"; +const ZONES_LEDGER_FILENAME: &str = "omicron-zones.json"; /// Combines the Nexus-provided `OmicronZonesConfig` (which describes what Nexus /// wants for all of its zones) with the locally-determined configuration for