From c1a444f3e278f5dda0481b3bda760acf99cb0a60 Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Wed, 8 Apr 2026 13:50:42 +0200 Subject: [PATCH 1/4] fix!: Put clientAuthenticationMethod field behind opt-in --- crates/stackable-operator/CHANGELOG.md | 10 +++++++++ .../src/commons/random_secret_creation.rs | 2 +- .../src/crd/authentication/core/mod.rs | 8 +++++-- .../crd/authentication/core/v1alpha1_impl.rs | 8 +++++-- .../src/crd/authentication/oidc/mod.rs | 21 +++++++++++++------ crates/xtask/src/crd/dummy.rs | 7 ++++--- 6 files changed, 42 insertions(+), 14 deletions(-) diff --git a/crates/stackable-operator/CHANGELOG.md b/crates/stackable-operator/CHANGELOG.md index 5499061e2..b9e2dfe75 100644 --- a/crates/stackable-operator/CHANGELOG.md +++ b/crates/stackable-operator/CHANGELOG.md @@ -13,8 +13,18 @@ All notable changes to this project will be documented in this file. - BREAKING: Change signature of `ContainerBuilder::add_env_vars` from `Vec` to `IntoIterator` ([#1163]). - BREAKING: Remove `EXPERIMENTAL_` prefix in `CONFIG_OVERRIDE_FILE_HEADER_KEY` and `CONFIG_OVERRIDE_FILE_FOOTER_KEY` ([#1191]). +### Fixed + +- BREAKING: In [#1178] the `clientAuthenticationMethod` was added to the `ClientAuthenticationOptions` struct, + resulting it to show up in all product CRDs. even those that don't support configuring the client authentication method. + With this change, operators need to opt-in to the `clientAuthenticationMethod` field by using the new + `ClientAuthenticationMethodOption` struct for the generic type `ProductSpecificClientAuthenticationOptions` on + `ClientAuthenticationOptions`. That way the struct definitions (as well as docs etc.) remain in stackable-operator, + but operators can decide if they want to offer support for this field or not ([#XXXX]). + [#1163]: https://github.com/stackabletech/operator-rs/pull/1163 [#1191]: https://github.com/stackabletech/operator-rs/pull/1191 +[#XXXX]: https://github.com/stackabletech/operator-rs/pull/XXXX ## [0.109.0] - 2026-04-07 diff --git a/crates/stackable-operator/src/commons/random_secret_creation.rs b/crates/stackable-operator/src/commons/random_secret_creation.rs index ee6f8de95..83249294f 100644 --- a/crates/stackable-operator/src/commons/random_secret_creation.rs +++ b/crates/stackable-operator/src/commons/random_secret_creation.rs @@ -34,7 +34,7 @@ pub enum Error { /// /// However, there is one special handling needed: /// -/// We can't mark Secrets as immutable, as this caused problems, see https://github.com/stackabletech/issues/issues/843. +/// We can't mark Secrets as immutable, as this caused problems, see . /// As Secrets have been created as immutable up to SDP release 26.3.0, we need to delete the, to be /// able to re-create them as mutable. This function detects old (immutable) Secrets and re-creates /// them as mutable. The contents of the Secret will be kept to prevent unnecessary Secret content diff --git a/crates/stackable-operator/src/crd/authentication/core/mod.rs b/crates/stackable-operator/src/crd/authentication/core/mod.rs index f466faf5f..ad90a234d 100644 --- a/crates/stackable-operator/src/crd/authentication/core/mod.rs +++ b/crates/stackable-operator/src/crd/authentication/core/mod.rs @@ -128,7 +128,7 @@ pub mod versioned { #[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] #[schemars(description = "")] - pub struct ClientAuthenticationDetails { + pub struct ClientAuthenticationDetails { /// Name of the [`AuthenticationClass`] used to authenticate users. /// /// To get the concrete [`AuthenticationClass`], we must resolve it. This resolution can be @@ -152,6 +152,10 @@ pub mod versioned { #[schemars( description = "This field contains OIDC-specific configuration. It is only required in case OIDC is used." )] - oidc: Option>, + oidc: Option< + oidc::v1alpha1::ClientAuthenticationOptions< + OidcProductSpecificClientAuthenticationOptions, + >, + >, } } diff --git a/crates/stackable-operator/src/crd/authentication/core/v1alpha1_impl.rs b/crates/stackable-operator/src/crd/authentication/core/v1alpha1_impl.rs index 13f1eb922..9dbba0eb9 100644 --- a/crates/stackable-operator/src/crd/authentication/core/v1alpha1_impl.rs +++ b/crates/stackable-operator/src/crd/authentication/core/v1alpha1_impl.rs @@ -30,7 +30,9 @@ impl AuthenticationClass { } } -impl ClientAuthenticationDetails { +impl + ClientAuthenticationDetails +{ /// Resolves this specific [`AuthenticationClass`]. Usually products support /// a list of authentication classes, which individually need to be resolved.crate::client pub async fn resolve_class( @@ -50,7 +52,9 @@ impl ClientAuthenticationDetails { pub fn oidc_or_error( &self, auth_class_name: &str, - ) -> Result<&oidc_v1alpha1::ClientAuthenticationOptions> { + ) -> Result< + &oidc_v1alpha1::ClientAuthenticationOptions, + > { self.oidc .as_ref() .with_context(|| OidcAuthenticationDetailsNotSpecifiedSnafu { diff --git a/crates/stackable-operator/src/crd/authentication/oidc/mod.rs b/crates/stackable-operator/src/crd/authentication/oidc/mod.rs index c818d77b4..79dbaaacb 100644 --- a/crates/stackable-operator/src/crd/authentication/oidc/mod.rs +++ b/crates/stackable-operator/src/crd/authentication/oidc/mod.rs @@ -135,7 +135,7 @@ pub mod versioned { Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize, )] #[serde(rename_all = "camelCase")] - pub struct ClientAuthenticationOptions { + pub struct ClientAuthenticationOptions { /// A reference to the OIDC client credentials secret. The secret contains /// the client id and secret. #[serde(rename = "clientCredentialsSecret")] @@ -151,6 +151,20 @@ pub mod versioned { #[serde(default)] pub extra_scopes: Vec, + /// If desired, operators can add custom fields that are only needed for this specific product. + /// They need to create a struct holding them and pass that as `ProductSpecific`. + /// + /// In case you only need the `clientAuthenticationMethod` field, you can use + /// [`ClientAuthenticationMethodOption`] directly. + #[serde(flatten)] + pub product_specific_fields: ProductSpecificClientAuthenticationOptions, + } + + #[derive( + Clone, Debug, Deserialize, Eq, Hash, JsonSchema, Ord, PartialEq, PartialOrd, Serialize, + )] + #[serde(rename_all = "camelCase")] + pub struct ClientAuthenticationMethodOption { /// The OAuth2 client authentication method to use for token endpoint requests. /// Defaults to [`ClientAuthenticationMethod::ClientSecretBasic`]. /// @@ -169,10 +183,5 @@ pub mod versioned { )] #[serde(default)] pub client_authentication_method: ClientAuthenticationMethod, - - // If desired, operators can add custom fields that are only needed for this specific product. - // They need to create a struct holding them and pass that as `T`. - #[serde(flatten)] - pub product_specific_fields: T, } } diff --git a/crates/xtask/src/crd/dummy.rs b/crates/xtask/src/crd/dummy.rs index 68c15c9f8..bd1698077 100644 --- a/crates/xtask/src/crd/dummy.rs +++ b/crates/xtask/src/crd/dummy.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use stackable_operator::{ commons::resources::{JvmHeapLimits, Resources}, config::fragment::Fragment, - crd::git_sync::v1alpha2::GitSync, + crd::{authentication, authentication::oidc, git_sync::v1alpha2::GitSync}, database_connections::{ databases::{ derby::DerbyConnection, mysql::MysqlConnection, postgresql::PostgresqlConnection, @@ -66,8 +66,9 @@ pub mod versioned { pub object_overrides: ObjectOverrides, // Already versioned - client_authentication_details: - stackable_operator::crd::authentication::core::v1alpha1::ClientAuthenticationDetails, + client_authentication_details: authentication::core::v1alpha1::ClientAuthenticationDetails< + oidc::v1alpha1::ClientAuthenticationMethodOption, + >, } #[derive(Debug, Default, PartialEq, Fragment, JsonSchema)] From 3e00e97fae306396ec5b9fae2d5790ca00310ecb Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Wed, 8 Apr 2026 13:53:48 +0200 Subject: [PATCH 2/4] changelog --- crates/stackable-operator/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/stackable-operator/CHANGELOG.md b/crates/stackable-operator/CHANGELOG.md index b9e2dfe75..696e27229 100644 --- a/crates/stackable-operator/CHANGELOG.md +++ b/crates/stackable-operator/CHANGELOG.md @@ -20,11 +20,11 @@ All notable changes to this project will be documented in this file. With this change, operators need to opt-in to the `clientAuthenticationMethod` field by using the new `ClientAuthenticationMethodOption` struct for the generic type `ProductSpecificClientAuthenticationOptions` on `ClientAuthenticationOptions`. That way the struct definitions (as well as docs etc.) remain in stackable-operator, - but operators can decide if they want to offer support for this field or not ([#XXXX]). + but operators can decide if they want to offer support for this field or not ([#1194]). [#1163]: https://github.com/stackabletech/operator-rs/pull/1163 [#1191]: https://github.com/stackabletech/operator-rs/pull/1191 -[#XXXX]: https://github.com/stackabletech/operator-rs/pull/XXXX +[#1194]: https://github.com/stackabletech/operator-rs/pull/1194 ## [0.109.0] - 2026-04-07 From dbc0599e05e688a23e32c6ca72609cf7ed7fdbb2 Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Wed, 8 Apr 2026 14:08:21 +0200 Subject: [PATCH 3/4] changelog --- crates/stackable-operator/CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/stackable-operator/CHANGELOG.md b/crates/stackable-operator/CHANGELOG.md index 696e27229..d99b48709 100644 --- a/crates/stackable-operator/CHANGELOG.md +++ b/crates/stackable-operator/CHANGELOG.md @@ -12,9 +12,6 @@ All notable changes to this project will be documented in this file. - BREAKING: Change signature of `ContainerBuilder::add_env_vars` from `Vec` to `IntoIterator` ([#1163]). - BREAKING: Remove `EXPERIMENTAL_` prefix in `CONFIG_OVERRIDE_FILE_HEADER_KEY` and `CONFIG_OVERRIDE_FILE_FOOTER_KEY` ([#1191]). - -### Fixed - - BREAKING: In [#1178] the `clientAuthenticationMethod` was added to the `ClientAuthenticationOptions` struct, resulting it to show up in all product CRDs. even those that don't support configuring the client authentication method. With this change, operators need to opt-in to the `clientAuthenticationMethod` field by using the new From 855dde2d40af128fc7b6483c50a8f1c3b8022b2e Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Thu, 9 Apr 2026 08:36:58 +0200 Subject: [PATCH 4/4] Shorten generic name to OidcProductSpecificOptions --- .../stackable-operator/src/crd/authentication/core/mod.rs | 8 ++------ .../src/crd/authentication/core/v1alpha1_impl.rs | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/crates/stackable-operator/src/crd/authentication/core/mod.rs b/crates/stackable-operator/src/crd/authentication/core/mod.rs index ad90a234d..df23fd172 100644 --- a/crates/stackable-operator/src/crd/authentication/core/mod.rs +++ b/crates/stackable-operator/src/crd/authentication/core/mod.rs @@ -128,7 +128,7 @@ pub mod versioned { #[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] #[schemars(description = "")] - pub struct ClientAuthenticationDetails { + pub struct ClientAuthenticationDetails { /// Name of the [`AuthenticationClass`] used to authenticate users. /// /// To get the concrete [`AuthenticationClass`], we must resolve it. This resolution can be @@ -152,10 +152,6 @@ pub mod versioned { #[schemars( description = "This field contains OIDC-specific configuration. It is only required in case OIDC is used." )] - oidc: Option< - oidc::v1alpha1::ClientAuthenticationOptions< - OidcProductSpecificClientAuthenticationOptions, - >, - >, + oidc: Option>, } } diff --git a/crates/stackable-operator/src/crd/authentication/core/v1alpha1_impl.rs b/crates/stackable-operator/src/crd/authentication/core/v1alpha1_impl.rs index 9dbba0eb9..fa095db11 100644 --- a/crates/stackable-operator/src/crd/authentication/core/v1alpha1_impl.rs +++ b/crates/stackable-operator/src/crd/authentication/core/v1alpha1_impl.rs @@ -30,9 +30,7 @@ impl AuthenticationClass { } } -impl - ClientAuthenticationDetails -{ +impl ClientAuthenticationDetails { /// Resolves this specific [`AuthenticationClass`]. Usually products support /// a list of authentication classes, which individually need to be resolved.crate::client pub async fn resolve_class( @@ -52,9 +50,7 @@ impl pub fn oidc_or_error( &self, auth_class_name: &str, - ) -> Result< - &oidc_v1alpha1::ClientAuthenticationOptions, - > { + ) -> Result<&oidc_v1alpha1::ClientAuthenticationOptions> { self.oidc .as_ref() .with_context(|| OidcAuthenticationDetailsNotSpecifiedSnafu {