diff --git a/CHANGELOG.md b/CHANGELOG.md index 60e24fb2..6462cd1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ the new labels ([#799]). - Environment variable overrides (`envOverrides`) are now applied after all environment variables set by the operator ([#799]). +- Make operations infallible where dependent on static inputs ([#803]). ### Fixed @@ -41,6 +42,7 @@ [#795]: https://github.com/stackabletech/hbase-operator/pull/795 [#797]: https://github.com/stackabletech/hbase-operator/pull/797 [#799]: https://github.com/stackabletech/hbase-operator/pull/799 +[#803]: https://github.com/stackabletech/hbase-operator/pull/803 ## [26.7.0] - 2026-07-21 diff --git a/rust/operator-binary/src/controller/build/kerberos.rs b/rust/operator-binary/src/controller/build/kerberos.rs index 002aa432..17f9ca7c 100644 --- a/rust/operator-binary/src/controller/build/kerberos.rs +++ b/rust/operator-binary/src/controller/build/kerberos.rs @@ -39,23 +39,18 @@ const PROTECTION_PRIVACY: &str = "privacy"; #[derive(Snafu, Debug)] pub enum Error { - #[snafu(display("failed to build Kerberos secret volume"))] - BuildKerberosSecretVolume { + #[snafu(display("failed to build Kerberos secret volume source"))] + BuildKerberosSecretVolumeSource { source: stackable_operator::builder::pod::volume::SecretOperatorVolumeSourceBuilderError, }, - #[snafu(display("failed to build TLS secret volume"))] - BuildTlsSecretVolume { + #[snafu(display("failed to build TLS secret volume source"))] + BuildTlsSecretVolumeSource { source: stackable_operator::builder::pod::volume::SecretOperatorVolumeSourceBuilderError, }, #[snafu(display("failed to add needed volume"))] AddVolume { source: builder::pod::Error }, - - #[snafu(display("failed to add needed volumeMount"))] - AddVolumeMount { - source: builder::pod::container::Error, - }, } /// The `hbase-site.xml` Kerberos properties for `cluster`, gated on Kerberos being enabled @@ -229,6 +224,13 @@ pub fn kerberos_ssl_client_settings() -> BTreeMap { truststore_settings("client") } +/// Adds the Kerberos keytab and TLS keystore volumes to the [`PodBuilder`] and their mounts to the +/// [`ContainerBuilder`], for whichever of the two secret classes are configured. +/// +/// # Panics +/// +/// Panics if the volume mounts cannot be added to the container builder. Only call this on a +/// container builder whose mount paths are still distinct from the ones added here. pub fn add_kerberos_pod_config( cluster: &ValidatedCluster, metrics_service_name: &str, @@ -247,7 +249,7 @@ pub fn add_kerberos_pod_config( .with_kerberos_service_name(kerberos_service_name()) .with_kerberos_service_name("HTTP") .build() - .context(BuildKerberosSecretVolumeSnafu)?; + .context(BuildKerberosSecretVolumeSourceSnafu)?; pb.add_volume( VolumeBuilder::new(&*KERBEROS_VOLUME_NAME) .ephemeral(kerberos_secret_operator_volume) @@ -255,7 +257,7 @@ pub fn add_kerberos_pod_config( ) .context(AddVolumeSnafu)?; cb.add_volume_mount(&*KERBEROS_VOLUME_NAME, STACKABLE_KERBEROS_DIR) - .context(AddVolumeMountSnafu)?; + .expect("The mount paths are statically defined and there should be no duplicates."); } if let Some(https_secret_class) = &cluster.cluster_config.https_secret_class { @@ -277,13 +279,13 @@ pub fn add_kerberos_pod_config( .with_tls_pkcs12_password(TLS_STORE_PASSWORD) .with_auto_tls_cert_lifetime(requested_secret_lifetime) .build() - .context(BuildTlsSecretVolumeSnafu)?, + .context(BuildTlsSecretVolumeSourceSnafu)?, ) .build(), ) .context(AddVolumeSnafu)?; cb.add_volume_mount(&*TLS_STORE_VOLUME_NAME, TLS_STORE_DIR) - .context(AddVolumeMountSnafu)?; + .expect("The mount paths are statically defined and there should be no duplicates."); } Ok(()) } diff --git a/rust/operator-binary/src/controller/build/resource/listener.rs b/rust/operator-binary/src/controller/build/resource/listener.rs index 873a8103..deb9c6fa 100644 --- a/rust/operator-binary/src/controller/build/resource/listener.rs +++ b/rust/operator-binary/src/controller/build/resource/listener.rs @@ -1,6 +1,6 @@ //! Build the listener `Volume`/`PersistentVolumeClaim` exposing a rolegroup. -use std::{str::FromStr, sync::LazyLock}; +use std::str::FromStr; use snafu::{ResultExt, Snafu}; use stackable_operator::{ @@ -8,6 +8,7 @@ use stackable_operator::{ ListenerOperatorVolumeSourceBuilder, ListenerOperatorVolumeSourceBuilderError, ListenerReference, VolumeBuilder, }, + constant, k8s_openapi::api::core::v1::{PersistentVolumeClaim, Volume}, kvp::Labels, v2::{ @@ -21,12 +22,7 @@ use stackable_operator::{ use crate::crd::{AnyServiceConfig, HbaseRole, LISTENER_VOLUME_NAME}; -/// The rest servers' listener `PersistentVolumeClaim` reuses the listener volume name -/// ([`LISTENER_VOLUME_NAME`]); the claim and the volume must share a name. -static LISTENER_PVC_NAME: LazyLock = LazyLock::new(|| { - PersistentVolumeClaimName::from_str(LISTENER_VOLUME_NAME) - .expect("LISTENER_VOLUME_NAME is a valid PersistentVolumeClaim name") -}); +constant!(LISTENER_PVC_NAME: PersistentVolumeClaimName = LISTENER_VOLUME_NAME); #[derive(Snafu, Debug)] pub enum Error { @@ -89,3 +85,14 @@ pub fn build_listener_pvc( )]), } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_constants() { + // Test that dereferencing the constants does not panic. + let _ = *LISTENER_PVC_NAME; + } +} diff --git a/rust/operator-binary/src/controller/build/resource/statefulset.rs b/rust/operator-binary/src/controller/build/resource/statefulset.rs index 144f4235..3d50b39c 100644 --- a/rust/operator-binary/src/controller/build/resource/statefulset.rs +++ b/rust/operator-binary/src/controller/build/resource/statefulset.rs @@ -88,11 +88,6 @@ pub enum Error { #[snafu(display("failed to add needed volume"))] AddVolume { source: builder::pod::Error }, - #[snafu(display("failed to add needed volumeMount"))] - AddVolumeMount { - source: builder::pod::container::Error, - }, - #[snafu(display("failed to build listener volume"))] ListenerVolume { source: super::listener::Error }, } @@ -192,15 +187,15 @@ pub fn build_rolegroup_statefulset( }]) .add_env_vars(merged_env) .add_volume_mount(&*HBASE_CONFIG_VOLUME_NAME, HBASE_CONFIG_TMP_DIR) - .context(AddVolumeMountSnafu)? + .expect("The mount paths are statically defined and there should be no duplicates.") .add_volume_mount(&*HDFS_DISCOVERY_VOLUME_NAME, HDFS_DISCOVERY_TMP_DIR) - .context(AddVolumeMountSnafu)? + .expect("The mount paths are statically defined and there should be no duplicates.") .add_volume_mount(&*LOG_CONFIG_VOLUME_NAME, HBASE_LOG_CONFIG_TMP_DIR) - .context(AddVolumeMountSnafu)? + .expect("The mount paths are statically defined and there should be no duplicates.") .add_volume_mount(&*LOG_VOLUME_NAME, STACKABLE_LOG_DIR) - .context(AddVolumeMountSnafu)? + .expect("The mount paths are statically defined and there should be no duplicates.") .add_volume_mount(LISTENER_VOLUME_NAME, LISTENER_VOLUME_DIR) - .context(AddVolumeMountSnafu)? + .expect("The mount paths are statically defined and there should be no duplicates.") .add_container_ports(ports) .resources(merged_config.resources().clone().into()) .startup_probe(startup_probe)