From c0bea04b6ab12157dc6e0f90ba0a6534e7a56d52 Mon Sep 17 00:00:00 2001 From: Razvan-Daniel Mihai <84674+razvan@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:41:19 +0200 Subject: [PATCH] fix: make shared secrets stable across reconcile operations --- CHANGELOG.md | 6 ++++++ rust/operator-binary/src/controller.rs | 29 ++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47d2bf5c..5ade6474 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Changed + +- Make internal shared secrets stable across reconcile operations. This ensures that Trino pods have the same secrets at any time. ([#873]). + +[#873]: https://github.com/stackabletech/trino-operator/pull/873 + ## [26.3.0] - 2026-03-16 ## [26.3.0-rc1] - 2026-03-16 diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 33acaa97..44be4ea0 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -385,6 +385,9 @@ pub enum Error { "client spooling protocol is not supported for Trino version {product_version}" ))] ClientSpoolingProtocolTrinoVersion { product_version: String }, + + #[snafu(display("failed to generate random bytes"))] + GenerateRandomBytes { source: openssl::error::ErrorStack }, } type Result = std::result::Result; @@ -1533,7 +1536,10 @@ async fn create_random_secret( client: &Client, ) -> Result<()> { let mut internal_secret = BTreeMap::new(); - internal_secret.insert(secret_key.to_string(), get_random_base64(secret_byte_size)); + internal_secret.insert( + secret_key.to_string(), + get_random_base64(secret_name.as_bytes(), secret_byte_size)?, + ); let secret = Secret { immutable: Some(true), @@ -1578,10 +1584,17 @@ fn shared_spooling_secret_name(trino: &v1alpha1::TrinoCluster) -> String { // TODO: Maybe switch to something non-openssl. // See https://github.com/stackabletech/airflow-operator/pull/686#discussion_r2348354468 (which is currently under discussion) -fn get_random_base64(byte_size: usize) -> String { +fn get_random_base64(seed: &[u8], byte_size: usize) -> Result { let mut buf: Vec = vec![0; byte_size]; - openssl::rand::rand_bytes(&mut buf).unwrap(); - openssl::base64::encode_block(&buf) + openssl::pkcs5::pbkdf2_hmac( + seed, + b"", + 1, + openssl::hash::MessageDigest::sha256(), + &mut buf, + ) + .context(GenerateRandomBytesSnafu)?; + Ok(openssl::base64::encode_block(&buf)) } fn container_ports(trino: &v1alpha1::TrinoCluster) -> Vec { @@ -1878,6 +1891,14 @@ mod tests { crd::v1alpha1::TrinoCluster, }; + #[test] + fn test_get_random_base64_is_stable() { + let seed = b"my-trino-cluster-internal-secret"; + let result1 = get_random_base64(seed, 32).expect("failed to generate random base64"); + let result2 = get_random_base64(seed, 32).expect("failed to generate random base64"); + assert_eq!(result1, result2); + } + #[tokio::test] async fn test_config_overrides() { let trino_yaml = r#"