From 591e2e9ef83f0f8fb78046069f1db8d24a899174 Mon Sep 17 00:00:00 2001 From: "Andrew J. Stone" Date: Fri, 20 Dec 2024 20:54:16 -0500 Subject: [PATCH] Support diffing blueprints via Diffus (#7261) This is the second step in https://github.com/oxidecomputer/omicron/issues/7240. The next steps will use this support to replace our handrolled code for generating diffs and generate output from the diffus based diffs. --- Cargo.lock | 35 +++++++++++++++-- Cargo.toml | 3 +- clickhouse-admin/types/Cargo.toml | 3 +- clickhouse-admin/types/src/lib.rs | 3 ++ common/Cargo.toml | 1 + common/src/api/external/mod.rs | 16 ++++++++ common/src/api/internal/shared.rs | 8 +++- common/src/disk.rs | 4 ++ common/src/zpool_name.rs | 5 ++- nexus-sled-agent-shared/Cargo.toml | 1 + nexus-sled-agent-shared/src/inventory.rs | 2 + nexus/reconfigurator/planning/Cargo.toml | 1 + nexus/types/Cargo.toml | 1 + nexus/types/src/deployment.rs | 39 ++++++++++++++++--- nexus/types/src/deployment/clickhouse.rs | 5 ++- .../types/src/deployment/network_resources.rs | 4 ++ nexus/types/src/deployment/planning_input.rs | 12 +++++- nexus/types/src/deployment/zone_type.rs | 15 +++++++ nexus/types/src/external_api/views.rs | 2 + uuid-kinds/Cargo.toml | 1 + uuid-kinds/src/lib.rs | 2 + workspace-hack/Cargo.toml | 6 ++- 22 files changed, 152 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1aec1ccc89..fe8ac9704f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1437,6 +1437,7 @@ dependencies = [ "camino-tempfile", "chrono", "derive_more", + "diffus", "expectorate", "itertools 0.13.0", "omicron-common", @@ -2392,6 +2393,28 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" +[[package]] +name = "diffus" +version = "0.10.0" +source = "git+https://github.com/oxidecomputer/diffus?branch=oxide/main#f6abe39bffd875b5fb1ebabf8144da15e3effe16" +dependencies = [ + "diffus-derive", + "itertools 0.10.5", + "newtype-uuid", + "oxnet", + "uuid", +] + +[[package]] +name = "diffus-derive" +version = "0.10.0" +source = "git+https://github.com/oxidecomputer/diffus?branch=oxide/main#f6abe39bffd875b5fb1ebabf8144da15e3effe16" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.10.7" @@ -6104,6 +6127,7 @@ dependencies = [ "chrono", "clickhouse-admin-types", "debug-ignore", + "diffus", "expectorate", "gateway-client", "illumos-utils", @@ -6206,6 +6230,7 @@ dependencies = [ name = "nexus-sled-agent-shared" version = "0.1.0" dependencies = [ + "diffus", "illumos-utils", "omicron-common", "omicron-passwords", @@ -6308,6 +6333,7 @@ dependencies = [ "cookie", "derive-where", "derive_more", + "diffus", "dropshot 0.13.0", "futures", "gateway-client", @@ -6732,6 +6758,7 @@ dependencies = [ "camino", "camino-tempfile", "chrono", + "diffus", "dropshot 0.13.0", "expectorate", "futures", @@ -7383,6 +7410,7 @@ dependencies = [ name = "omicron-uuid-kinds" version = "0.1.0" dependencies = [ + "diffus", "newtype-uuid", "paste", "schemars", @@ -7459,6 +7487,7 @@ dependencies = [ "managed", "memchr", "mio", + "newtype-uuid", "nom", "num-bigint-dig", "num-integer", @@ -10423,9 +10452,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -13280,7 +13309,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8906ab4d70..535afb94b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -369,6 +369,7 @@ derive-where = "1.2.7" # Having the i-implement-... feature here makes diesel go away from the workspace-hack diesel = { version = "2.2.4", features = ["i-implement-a-third-party-backend-and-opt-into-breaking-changes", "postgres", "r2d2", "chrono", "serde_json", "network-address", "uuid"] } diesel-dtrace = "0.4.2" +diffus = { git = "https://github.com/oxidecomputer/diffus", branch = "oxide/main", features = ["uuid-impl", "derive", "newtype-uuid-impl", "oxnet-impl"] } dns-server = { path = "dns-server" } dns-server-api = { path = "dns-server-api" } dns-service-client = { path = "clients/dns-service-client" } @@ -582,7 +583,7 @@ secrecy = "0.8.0" semver = { version = "1.0.23", features = ["std", "serde"] } serde = { version = "1.0", default-features = false, features = [ "derive", "rc" ] } serde_human_bytes = { git = "https://github.com/oxidecomputer/serde_human_bytes", branch = "main" } -serde_json = "1.0.132" +serde_json = "1.0.133" serde_path_to_error = "0.1.16" serde_tokenstream = "0.2" serde_urlencoded = "0.7.1" diff --git a/clickhouse-admin/types/Cargo.toml b/clickhouse-admin/types/Cargo.toml index f57b1c5052..c8ee984abe 100644 --- a/clickhouse-admin/types/Cargo.toml +++ b/clickhouse-admin/types/Cargo.toml @@ -14,6 +14,7 @@ camino.workspace = true camino-tempfile.workspace = true chrono.workspace = true derive_more.workspace = true +diffus.workspace = true itertools.workspace = true omicron-common.workspace = true omicron-workspace-hack.workspace = true @@ -25,4 +26,4 @@ expectorate.workspace = true [dev-dependencies] slog-async.workspace = true -slog-term.workspace = true \ No newline at end of file +slog-term.workspace = true diff --git a/clickhouse-admin/types/src/lib.rs b/clickhouse-admin/types/src/lib.rs index aa1437bedc..b4dd21652c 100644 --- a/clickhouse-admin/types/src/lib.rs +++ b/clickhouse-admin/types/src/lib.rs @@ -7,6 +7,7 @@ use atomicwrites::AtomicFile; use camino::Utf8PathBuf; use chrono::{DateTime, Utc}; use derive_more::{Add, AddAssign, Display, From}; +use diffus::Diffus; use itertools::Itertools; use omicron_common::api::external::Generation; use schemars::{ @@ -56,6 +57,7 @@ pub const OXIMETER_CLUSTER: &str = "oximeter_cluster"; JsonSchema, Serialize, Deserialize, + Diffus, )] pub struct KeeperId(pub u64); @@ -75,6 +77,7 @@ pub struct KeeperId(pub u64); JsonSchema, Serialize, Deserialize, + Diffus, )] pub struct ServerId(pub u64); diff --git a/common/Cargo.toml b/common/Cargo.toml index 0d122e602b..f2797ed2b4 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -20,6 +20,7 @@ async-trait.workspace = true backoff.workspace = true camino.workspace = true chrono.workspace = true +diffus.workspace = true dropshot.workspace = true futures.workspace = true hex.workspace = true diff --git a/common/src/api/external/mod.rs b/common/src/api/external/mod.rs index ab46f9f7f6..4c8f032fcb 100644 --- a/common/src/api/external/mod.rs +++ b/common/src/api/external/mod.rs @@ -18,6 +18,7 @@ use anyhow::Context; use api_identity::ObjectIdentity; use chrono::DateTime; use chrono::Utc; +use diffus::{edit, Diffable, Diffus}; use dropshot::HttpError; pub use dropshot::PaginationOrder; pub use error::*; @@ -211,6 +212,7 @@ impl<'a> TryFrom<&DataPageParams<'a, NameOrId>> for DataPageParams<'a, Uuid> { )] #[display("{0}")] #[serde(try_from = "String")] +#[derive(Diffus)] pub struct Name(String); /// `Name::try_from(String)` is the primary method for constructing an Name @@ -614,6 +616,7 @@ impl JsonSchema for RoleName { Eq, PartialOrd, Ord, + Diffus, )] pub struct ByteCount(u64); @@ -748,6 +751,7 @@ impl From for i64 { PartialEq, PartialOrd, Serialize, + Diffus, )] pub struct Generation(u64); @@ -1937,6 +1941,17 @@ impl JsonSchema for L4PortRange { )] pub struct MacAddr(pub macaddr::MacAddr6); +impl<'a> Diffable<'a> for MacAddr { + type Diff = (&'a Self, &'a Self); + fn diff(&'a self, other: &'a Self) -> edit::Edit<'a, Self> { + if self == other { + edit::Edit::Copy(self) + } else { + edit::Edit::Change((self, other)) + } + } +} + impl MacAddr { // Guest MAC addresses begin with the Oxide OUI A8:40:25. Further, guest // address are constrained to be in the virtual address range @@ -2100,6 +2115,7 @@ impl JsonSchema for MacAddr { Deserialize, Serialize, JsonSchema, + Diffus, )] pub struct Vni(u32); diff --git a/common/src/api/internal/shared.rs b/common/src/api/internal/shared.rs index a3f28a258a..588117c71c 100644 --- a/common/src/api/internal/shared.rs +++ b/common/src/api/internal/shared.rs @@ -8,6 +8,7 @@ use crate::{ address::NUM_SOURCE_NAT_PORTS, api::external::{self, BfdMode, ImportExportPolicy, Name, Vni}, }; +use diffus::Diffus; use oxnet::{IpNet, Ipv4Net, Ipv6Net}; use schemars::JsonSchema; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; @@ -35,6 +36,7 @@ use super::nexus::HostIdentifier; Serialize, JsonSchema, Hash, + Diffus, )] #[serde(tag = "type", rename_all = "snake_case")] pub enum NetworkInterfaceKind { @@ -58,6 +60,7 @@ pub enum NetworkInterfaceKind { PartialOrd, Ord, Hash, + Diffus, )] pub struct NetworkInterface { pub id: Uuid, @@ -88,6 +91,7 @@ pub struct NetworkInterface { PartialOrd, Ord, Hash, + Diffus, )] pub struct SourceNatConfig { /// The external address provided to the instance or service. @@ -891,7 +895,9 @@ pub struct ExternalIpGatewayMap { } /// Describes the purpose of the dataset. -#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, EnumCount)] +#[derive( + Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, EnumCount, Diffus, +)] #[cfg_attr(feature = "testing", derive(test_strategy::Arbitrary))] pub enum DatasetKind { // Durable datasets for zones diff --git a/common/src/disk.rs b/common/src/disk.rs index 99c2b2db7b..df6efe3196 100644 --- a/common/src/disk.rs +++ b/common/src/disk.rs @@ -6,6 +6,7 @@ use anyhow::bail; use camino::{Utf8Path, Utf8PathBuf}; +use diffus::Diffus; use omicron_uuid_kinds::DatasetUuid; use omicron_uuid_kinds::PhysicalDiskUuid; use omicron_uuid_kinds::ZpoolUuid; @@ -176,6 +177,7 @@ impl DatasetName { Hash, PartialOrd, Ord, + Diffus, )] pub struct GzipLevel(u8); @@ -218,6 +220,7 @@ impl FromStr for GzipLevel { Hash, PartialOrd, Ord, + Diffus, )] #[serde(tag = "type", rename_all = "snake_case")] pub enum CompressionAlgorithm { @@ -412,6 +415,7 @@ impl DatasetsManagementResult { Serialize, Deserialize, JsonSchema, + Diffus, )] pub struct DiskIdentity { pub vendor: String, diff --git a/common/src/zpool_name.rs b/common/src/zpool_name.rs index df5ca8ea31..9852b46120 100644 --- a/common/src/zpool_name.rs +++ b/common/src/zpool_name.rs @@ -5,6 +5,7 @@ //! Zpool labels and kinds shared between Nexus and Sled Agents use camino::{Utf8Path, Utf8PathBuf}; +use diffus::Diffus; use omicron_uuid_kinds::ZpoolUuid; use schemars::JsonSchema; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -15,7 +16,7 @@ pub const ZPOOL_INTERNAL_PREFIX: &str = "oxi_"; /// Describes the different classes of Zpools. #[derive( - Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, JsonSchema, + Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, JsonSchema, Diffus, )] #[serde(rename_all = "snake_case")] pub enum ZpoolKind { @@ -29,7 +30,7 @@ pub enum ZpoolKind { /// /// This expects that the format will be: `ox{i,p}_` - we parse the prefix /// when reading the structure, and validate that the UUID can be utilized. -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Diffus)] pub struct ZpoolName { id: ZpoolUuid, kind: ZpoolKind, diff --git a/nexus-sled-agent-shared/Cargo.toml b/nexus-sled-agent-shared/Cargo.toml index 504cd92c37..ea83cb67ae 100644 --- a/nexus-sled-agent-shared/Cargo.toml +++ b/nexus-sled-agent-shared/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" workspace = true [dependencies] +diffus.workspace = true illumos-utils.workspace = true omicron-common.workspace = true omicron-passwords.workspace = true diff --git a/nexus-sled-agent-shared/src/inventory.rs b/nexus-sled-agent-shared/src/inventory.rs index 3b9daf583e..b2b1001f9b 100644 --- a/nexus-sled-agent-shared/src/inventory.rs +++ b/nexus-sled-agent-shared/src/inventory.rs @@ -6,6 +6,7 @@ use std::net::{IpAddr, Ipv6Addr, SocketAddr, SocketAddrV6}; +use diffus::Diffus; use omicron_common::{ api::{ external::{ByteCount, Generation}, @@ -183,6 +184,7 @@ impl OmicronZoneConfig { PartialOrd, Ord, Hash, + Diffus, )] pub struct OmicronZoneDataset { pub pool_name: ZpoolName, diff --git a/nexus/reconfigurator/planning/Cargo.toml b/nexus/reconfigurator/planning/Cargo.toml index 6656693a90..c7d978b387 100644 --- a/nexus/reconfigurator/planning/Cargo.toml +++ b/nexus/reconfigurator/planning/Cargo.toml @@ -11,6 +11,7 @@ anyhow.workspace = true clickhouse-admin-types.workspace = true chrono.workspace = true debug-ignore.workspace = true +diffus.workspace = true gateway-client.workspace = true illumos-utils.workspace = true indexmap.workspace = true diff --git a/nexus/types/Cargo.toml b/nexus/types/Cargo.toml index 8990b0b83b..edf22679ef 100644 --- a/nexus/types/Cargo.toml +++ b/nexus/types/Cargo.toml @@ -17,6 +17,7 @@ clickhouse-admin-types.workspace = true cookie.workspace = true derive-where.workspace = true derive_more.workspace = true +diffus.workspace = true dropshot.workspace = true futures.workspace = true http.workspace = true diff --git a/nexus/types/src/deployment.rs b/nexus/types/src/deployment.rs index afe906e781..8915ac8746 100644 --- a/nexus/types/src/deployment.rs +++ b/nexus/types/src/deployment.rs @@ -18,6 +18,7 @@ use crate::inventory::Collection; pub use crate::inventory::SourceNatConfig; pub use crate::inventory::ZpoolName; use blueprint_diff::ClickhouseClusterConfigDiffTablesForSingleBlueprint; +use diffus::Diffus; use nexus_sled_agent_shared::inventory::OmicronZoneConfig; use nexus_sled_agent_shared::inventory::OmicronZonesConfig; use nexus_sled_agent_shared::inventory::ZoneKind; @@ -137,7 +138,9 @@ pub use blueprint_diff::BlueprintDiff; // zones deployed on each host and some supporting configuration (e.g., DNS). // This is aimed at supporting add/remove sleds. The plan is to grow this to // include more of the system as we support more use cases. -#[derive(Clone, Debug, Eq, PartialEq, JsonSchema, Deserialize, Serialize)] +#[derive( + Clone, Debug, Eq, PartialEq, JsonSchema, Deserialize, Serialize, Diffus, +)] pub struct Blueprint { /// unique identifier for this blueprint pub id: Uuid, @@ -187,6 +190,7 @@ pub struct Blueprint { pub clickhouse_cluster_config: Option, /// when this blueprint was generated (for debugging) + #[diffus(ignore)] pub time_created: chrono::DateTime, /// identity of the component that generated the blueprint (for debugging) /// This would generally be the Uuid of a Nexus instance. @@ -538,7 +542,9 @@ impl<'a> fmt::Display for BlueprintDisplay<'a> { /// per-zone [`BlueprintZoneDisposition`]. /// /// Part of [`Blueprint`]. -#[derive(Debug, Clone, Eq, PartialEq, JsonSchema, Deserialize, Serialize)] +#[derive( + Debug, Clone, Eq, PartialEq, JsonSchema, Deserialize, Serialize, Diffus, +)] pub struct BlueprintZonesConfig { /// Generation number of this configuration. /// @@ -642,6 +648,7 @@ fn zone_sort_key(z: &T) -> impl Ord { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct BlueprintZoneConfig { /// The disposition (desired state) of this zone recorded in the blueprint. @@ -653,6 +660,12 @@ pub struct BlueprintZoneConfig { pub zone_type: BlueprintZoneType, } +impl diffus::Same for BlueprintZoneConfig { + fn same(&self, other: &Self) -> bool { + self == other + } +} + impl BlueprintZoneConfig { /// Returns the underlay IP address associated with this zone. /// @@ -704,6 +717,7 @@ impl From for OmicronZoneConfig { Deserialize, Serialize, EnumIter, + Diffus, )] #[serde(rename_all = "snake_case")] pub enum BlueprintZoneDisposition { @@ -847,6 +861,7 @@ pub enum BlueprintDatasetFilter { Deserialize, Serialize, EnumIter, + Diffus, )] #[serde(rename_all = "snake_case")] pub enum BlueprintPhysicalDiskDisposition { @@ -878,7 +893,9 @@ impl BlueprintPhysicalDiskDisposition { } /// Information about an Omicron physical disk as recorded in a bluerprint. -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Diffus, +)] pub struct BlueprintPhysicalDiskConfig { pub disposition: BlueprintPhysicalDiskDisposition, pub identity: DiskIdentity, @@ -889,12 +906,20 @@ pub struct BlueprintPhysicalDiskConfig { /// Information about Omicron physical disks as recorded in a blueprint. /// /// Part of [`Blueprint`]. -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] +#[derive( + Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Diffus, +)] pub struct BlueprintPhysicalDisksConfig { pub generation: Generation, pub disks: Vec, } +impl diffus::Same for BlueprintPhysicalDiskConfig { + fn same(&self, other: &Self) -> bool { + self == other + } +} + // Required by RSS impl Default for BlueprintPhysicalDisksConfig { fn default() -> Self { @@ -929,7 +954,9 @@ impl From for OmicronPhysicalDisksConfig { } /// Information about Omicron datasets as recorded in a blueprint. -#[derive(Debug, Clone, Eq, PartialEq, JsonSchema, Deserialize, Serialize)] +#[derive( + Debug, Clone, Eq, PartialEq, JsonSchema, Deserialize, Serialize, Diffus, +)] pub struct BlueprintDatasetsConfig { pub generation: Generation, pub datasets: BTreeMap, @@ -964,6 +991,7 @@ impl From for DatasetsConfig { Deserialize, Serialize, EnumIter, + Diffus, )] #[serde(rename_all = "snake_case")] pub enum BlueprintDatasetDisposition { @@ -1002,6 +1030,7 @@ impl BlueprintDatasetDisposition { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct BlueprintDatasetConfig { // TODO: Display this in diffs - leave for now, for backwards compat diff --git a/nexus/types/src/deployment/clickhouse.rs b/nexus/types/src/deployment/clickhouse.rs index d0612e2ddf..f8443c6afe 100644 --- a/nexus/types/src/deployment/clickhouse.rs +++ b/nexus/types/src/deployment/clickhouse.rs @@ -5,6 +5,7 @@ //! Types used in blueprints related to clickhouse configuration use clickhouse_admin_types::{KeeperId, ServerId}; +use diffus::Diffus; use omicron_common::api::external::Generation; use omicron_uuid_kinds::OmicronZoneUuid; use schemars::JsonSchema; @@ -12,7 +13,9 @@ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; /// Global configuration for all clickhouse servers (replicas) and keepers -#[derive(Clone, Debug, Eq, PartialEq, JsonSchema, Deserialize, Serialize)] +#[derive( + Clone, Debug, Eq, PartialEq, JsonSchema, Deserialize, Serialize, Diffus, +)] pub struct ClickhouseClusterConfig { /// The last update to the clickhouse cluster configuration /// diff --git a/nexus/types/src/deployment/network_resources.rs b/nexus/types/src/deployment/network_resources.rs index f11d739d03..b08e5a2582 100644 --- a/nexus/types/src/deployment/network_resources.rs +++ b/nexus/types/src/deployment/network_resources.rs @@ -5,6 +5,7 @@ use super::tri_map::TriMap; use super::tri_map::TriMapEntry; use anyhow::anyhow; +use diffus::Diffus; use omicron_common::api::external::MacAddr; use omicron_common::api::internal::shared::SourceNatConfig; use omicron_uuid_kinds::ExternalIpUuid; @@ -221,6 +222,7 @@ pub enum OmicronZoneExternalIpKey { JsonSchema, Serialize, Deserialize, + Diffus, )] pub struct OmicronZoneExternalFloatingIp { pub id: ExternalIpUuid, @@ -239,6 +241,7 @@ pub struct OmicronZoneExternalFloatingIp { JsonSchema, Serialize, Deserialize, + Diffus, )] pub struct OmicronZoneExternalFloatingAddr { pub id: ExternalIpUuid, @@ -268,6 +271,7 @@ impl OmicronZoneExternalFloatingAddr { JsonSchema, Serialize, Deserialize, + Diffus, )] pub struct OmicronZoneExternalSnatIp { pub id: ExternalIpUuid, diff --git a/nexus/types/src/deployment/planning_input.rs b/nexus/types/src/deployment/planning_input.rs index 0dda916509..1876440d47 100644 --- a/nexus/types/src/deployment/planning_input.rs +++ b/nexus/types/src/deployment/planning_input.rs @@ -17,6 +17,7 @@ use crate::external_api::views::SledState; use chrono::DateTime; use chrono::Utc; use clap::ValueEnum; +use diffus::Diffus; use ipnetwork::IpNetwork; use omicron_common::address::IpRange; use omicron_common::address::Ipv6Subnet; @@ -376,6 +377,7 @@ impl CockroachDbSettings { Deserialize, Serialize, JsonSchema, + Diffus, )] pub enum CockroachDbClusterVersion { #[display("22.1")] @@ -408,7 +410,15 @@ impl CockroachDbClusterVersion { /// Whether to set `cluster.preserve_downgrade_option` and what to set it to. #[derive( - Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize, JsonSchema, + Clone, + Copy, + Debug, + Eq, + PartialEq, + Deserialize, + Serialize, + JsonSchema, + Diffus, )] #[serde(tag = "action", content = "data", rename_all = "snake_case")] pub enum CockroachDbPreserveDowngrade { diff --git a/nexus/types/src/deployment/zone_type.rs b/nexus/types/src/deployment/zone_type.rs index ffb4bd5a17..c1ecd18158 100644 --- a/nexus/types/src/deployment/zone_type.rs +++ b/nexus/types/src/deployment/zone_type.rs @@ -9,6 +9,7 @@ //! that is not needed by sled-agent. use super::OmicronZoneExternalIp; +use diffus::Diffus; use nexus_sled_agent_shared::inventory::OmicronZoneDataset; use nexus_sled_agent_shared::inventory::OmicronZoneType; use nexus_sled_agent_shared::inventory::ZoneKind; @@ -31,6 +32,7 @@ use std::net::SocketAddrV6; JsonSchema, Deserialize, Serialize, + Diffus, )] #[serde(tag = "type", rename_all = "snake_case")] pub enum BlueprintZoneType { @@ -335,6 +337,7 @@ pub mod blueprint_zone_type { use crate::deployment::OmicronZoneExternalFloatingAddr; use crate::deployment::OmicronZoneExternalFloatingIp; use crate::deployment::OmicronZoneExternalSnatIp; + use diffus::Diffus; use nexus_sled_agent_shared::inventory::OmicronZoneDataset; use omicron_common::api::internal::shared::NetworkInterface; use schemars::JsonSchema; @@ -354,6 +357,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct BoundaryNtp { pub address: SocketAddrV6, @@ -376,6 +380,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct Clickhouse { pub address: SocketAddrV6, @@ -392,6 +397,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct ClickhouseKeeper { pub address: SocketAddrV6, @@ -409,6 +415,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct ClickhouseServer { pub address: SocketAddrV6, @@ -425,6 +432,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct CockroachDb { pub address: SocketAddrV6, @@ -441,6 +449,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct Crucible { pub address: SocketAddrV6, @@ -457,6 +466,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct CruciblePantry { pub address: SocketAddrV6, @@ -472,6 +482,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct ExternalDns { pub dataset: OmicronZoneDataset, @@ -493,6 +504,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct InternalDns { pub dataset: OmicronZoneDataset, @@ -521,6 +533,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct InternalNtp { pub address: SocketAddrV6, @@ -536,6 +549,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct Nexus { /// The address at which the internal nexus server is reachable. @@ -560,6 +574,7 @@ pub mod blueprint_zone_type { JsonSchema, Deserialize, Serialize, + Diffus, )] pub struct Oximeter { pub address: SocketAddrV6, diff --git a/nexus/types/src/external_api/views.rs b/nexus/types/src/external_api/views.rs index 0fd45c0666..94b2279906 100644 --- a/nexus/types/src/external_api/views.rs +++ b/nexus/types/src/external_api/views.rs @@ -11,6 +11,7 @@ use crate::identity::AssetIdentityMetadata; use api_identity::ObjectIdentity; use chrono::DateTime; use chrono::Utc; +use diffus::Diffus; use omicron_common::api::external::{ AllowedSourceIps as ExternalAllowedSourceIps, ByteCount, Digest, Error, IdentityMetadata, InstanceState, Name, ObjectIdentity, RoleName, @@ -704,6 +705,7 @@ impl fmt::Display for SledPolicy { PartialEq, Eq, EnumIter, + Diffus, )] #[serde(rename_all = "snake_case")] pub enum SledState { diff --git a/uuid-kinds/Cargo.toml b/uuid-kinds/Cargo.toml index 9ea2f8223c..0a80fab9c9 100644 --- a/uuid-kinds/Cargo.toml +++ b/uuid-kinds/Cargo.toml @@ -12,6 +12,7 @@ workspace = true # within omicron. [dependencies] +diffus.workspace = true newtype-uuid.workspace = true schemars = { workspace = true, optional = true } paste.workspace = true diff --git a/uuid-kinds/src/lib.rs b/uuid-kinds/src/lib.rs index 42c50379ce..e4f65d7039 100644 --- a/uuid-kinds/src/lib.rs +++ b/uuid-kinds/src/lib.rs @@ -14,6 +14,7 @@ pub use newtype_uuid::{ GenericUuid, ParseError, TagError, TypedUuid, TypedUuidKind, TypedUuidTag, }; +use diffus::Diffus; #[cfg(feature = "schemars08")] use schemars::JsonSchema; @@ -22,6 +23,7 @@ macro_rules! impl_typed_uuid_kind { $( paste::paste! { #[cfg_attr(feature = "schemars08", derive(JsonSchema))] + #[derive(Diffus)] pub enum [< $kind Kind>] {} impl TypedUuidKind for [< $kind Kind >] { diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index 678170b25e..9b5de946f9 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -77,6 +77,7 @@ libc = { version = "0.2.162", features = ["extra_traits"] } log = { version = "0.4.22", default-features = false, features = ["kv_unstable", "std"] } managed = { version = "0.8.0", default-features = false, features = ["alloc", "map"] } memchr = { version = "2.7.4" } +newtype-uuid = { version = "1.1.3" } nom = { version = "7.1.3" } num-bigint-dig = { version = "0.8.4", default-features = false, features = ["i128", "prime", "serde", "u64_digit", "zeroize"] } num-integer = { version = "0.1.46", features = ["i128"] } @@ -107,7 +108,7 @@ schemars = { version = "0.8.21", features = ["bytes", "chrono", "uuid1"] } scopeguard = { version = "1.2.0" } semver = { version = "1.0.23", features = ["serde"] } serde = { version = "1.0.215", features = ["alloc", "derive", "rc"] } -serde_json = { version = "1.0.132", features = ["raw_value", "unbounded_depth"] } +serde_json = { version = "1.0.133", features = ["raw_value", "unbounded_depth"] } sha1 = { version = "0.10.6", features = ["oid"] } sha2 = { version = "0.10.8", features = ["oid"] } similar = { version = "2.6.0", features = ["bytes", "inline", "unicode"] } @@ -197,6 +198,7 @@ libc = { version = "0.2.162", features = ["extra_traits"] } log = { version = "0.4.22", default-features = false, features = ["kv_unstable", "std"] } managed = { version = "0.8.0", default-features = false, features = ["alloc", "map"] } memchr = { version = "2.7.4" } +newtype-uuid = { version = "1.1.3" } nom = { version = "7.1.3" } num-bigint-dig = { version = "0.8.4", default-features = false, features = ["i128", "prime", "serde", "u64_digit", "zeroize"] } num-integer = { version = "0.1.46", features = ["i128"] } @@ -227,7 +229,7 @@ schemars = { version = "0.8.21", features = ["bytes", "chrono", "uuid1"] } scopeguard = { version = "1.2.0" } semver = { version = "1.0.23", features = ["serde"] } serde = { version = "1.0.215", features = ["alloc", "derive", "rc"] } -serde_json = { version = "1.0.132", features = ["raw_value", "unbounded_depth"] } +serde_json = { version = "1.0.133", features = ["raw_value", "unbounded_depth"] } sha1 = { version = "0.10.6", features = ["oid"] } sha2 = { version = "0.10.8", features = ["oid"] } similar = { version = "2.6.0", features = ["bytes", "inline", "unicode"] }