diff --git a/nexus/types/src/deployment/blueprint_diff.rs b/nexus/types/src/deployment/blueprint_diff.rs index 9641e740ebe..1aa06c0cae4 100644 --- a/nexus/types/src/deployment/blueprint_diff.rs +++ b/nexus/types/src/deployment/blueprint_diff.rs @@ -857,7 +857,111 @@ impl ClickhouseClusterConfigDiffTables { before: &ClickhouseClusterConfig, after: &ClickhouseClusterConfig, ) -> Self { - todo!() + macro_rules! diff_row { + ($member:ident, $label:expr) => { + if before.$member == after.$member { + KvPair::new( + BpDiffState::Unchanged, + $label, + linear_table_unchanged(&after.$member), + ) + } else { + KvPair::new( + BpDiffState::Modified, + $label, + linear_table_modified(&before.$member, &after.$member), + ) + } + }; + } + + let metadata = KvListWithHeading::new( + CLICKHOUSE_CLUSTER_CONFIG_HEADING, + vec![ + diff_row!(generation, GENERATION), + diff_row!(max_used_server_id, CLICKHOUSE_MAX_USED_SERVER_ID), + diff_row!(max_used_keeper_id, CLICKHOUSE_MAX_USED_KEEPER_ID), + diff_row!(cluster_name, CLICKHOUSE_CLUSTER_NAME), + diff_row!(cluster_secret, CLICKHOUSE_CLUSTER_SECRET), + diff_row!( + highest_seen_keeper_leader_committed_log_index, + CLICKHOUSE_HIGHEST_SEEN_KEEPER_LEADER_COMMITTED_LOG_INDEX + ), + ], + ); + + // Macro used to construct keeper and server tables + macro_rules! diff_table_rows { + ($rows:ident, $collection:ident) => { + for (zone_id, id) in &after.$collection { + if before.$collection.contains_key(zone_id) { + // Unchanged + $rows.push(BpSledSubtableRow::new( + BpDiffState::Unchanged, + vec![ + BpSledSubtableColumn::Value( + zone_id.to_string(), + ), + BpSledSubtableColumn::Value(id.to_string()), + ], + )); + } else { + // Added + $rows.push(BpSledSubtableRow::new( + BpDiffState::Added, + vec![ + BpSledSubtableColumn::Value( + zone_id.to_string(), + ), + BpSledSubtableColumn::Value(id.to_string()), + ], + )); + } + } + + for (zone_id, id) in &before.$collection { + if !after.$collection.contains_key(zone_id) { + // Removed + $rows.push(BpSledSubtableRow::new( + BpDiffState::Removed, + vec![ + BpSledSubtableColumn::Value( + zone_id.to_string(), + ), + BpSledSubtableColumn::Value(id.to_string()), + ], + )); + } + } + }; + } + + // Construct our keeper table + let mut keeper_rows = vec![]; + diff_table_rows!(keeper_rows, keepers); + let keepers = BpSledSubtable::new( + BpClickhouseKeepersSubtableSchema {}, + BpGeneration::Diff { + before: Some(before.generation), + after: Some(after.generation), + }, + keeper_rows, + ); + + // Construct our server table + let mut server_rows = vec![]; + diff_table_rows!(server_rows, servers); + + let servers = Some(BpSledSubtable::new( + BpClickhouseServersSubtableSchema {}, + BpGeneration::Diff { + before: Some(before.generation), + after: Some(after.generation), + }, + server_rows, + )); + + ClickhouseClusterConfigDiffTables { metadata, keepers, servers } } /// We are diffing a `Collection` and `Blueprint` but the latest blueprint