From 4d81a5a3451885ba15e1a28a1e5f50e2b4d309cd Mon Sep 17 00:00:00 2001 From: dervoeti Date: Tue, 4 Nov 2025 10:08:49 +0100 Subject: [PATCH 1/6] feat: support OPA with TLS --- rust/operator-binary/src/config/jvm.rs | 24 +++++- rust/operator-binary/src/config/mod.rs | 5 +- rust/operator-binary/src/controller.rs | 83 +++++++++++++++---- .../src/security/authorization.rs | 58 ++++++++++--- .../kuttl/oidc-opa/20-install-opa.yaml.j2 | 15 ++++ 5 files changed, 158 insertions(+), 27 deletions(-) diff --git a/rust/operator-binary/src/config/jvm.rs b/rust/operator-binary/src/config/jvm.rs index 7960a2e9..a39485f0 100644 --- a/rust/operator-binary/src/config/jvm.rs +++ b/rust/operator-binary/src/config/jvm.rs @@ -7,6 +7,10 @@ use stackable_operator::{ use crate::{ config::{JVM_SECURITY_PROPERTIES_FILE, NIFI_CONFIG_DIRECTORY}, crd::{NifiConfig, NifiConfigFragment, NifiNodeRoleConfig}, + security::{ + authentication::{STACKABLE_SERVER_TLS_DIR, STACKABLE_TLS_STORE_PASSWORD}, + authorization::NifiAuthorizationConfig, + }, }; // Part of memory resources allocated for Java heap @@ -31,6 +35,7 @@ pub fn build_merged_jvm_config( merged_config: &NifiConfig, role: &Role, role_group: &str, + authorization_config: Option<&NifiAuthorizationConfig>, ) -> Result { let heap_size = MemoryQuantity::try_from( merged_config @@ -47,7 +52,7 @@ pub fn build_merged_jvm_config( .format_for_java() .context(InvalidMemoryConfigSnafu)?; - let jvm_args = vec![ + let mut jvm_args = vec![ // Heap settings format!("-Xmx{java_heap}"), format!("-Xms{java_heap}"), @@ -79,6 +84,23 @@ pub fn build_merged_jvm_config( ), ]; + // Add JVM truststore properties when OPA TLS is enabled + // This ensures that the OPA authorizer can verify the OPA server's TLS certificate + // + // Note: JVM system properties are currently the correct way to configure TLS for the OPA + // plugin. The NiFi OPA authorizer uses the Styra OPA Java SDK, which internally creates a + // standard Java HttpClient without exposed SSL configuration options, but the HttpClient + // respects these JVM-wide SSL system properties. So there is no plugin-level configuration + // available for truststore settings. This was last checked for version 1.7.0 of the Styra + // OPA Java SDK. + if let Some(authz_config) = authorization_config { + if authz_config.has_opa_tls() { + jvm_args.push(format!("-Djavax.net.ssl.trustStore={STACKABLE_SERVER_TLS_DIR}/truststore.p12")); + jvm_args.push(format!("-Djavax.net.ssl.trustStorePassword={STACKABLE_TLS_STORE_PASSWORD}")); + jvm_args.push("-Djavax.net.ssl.trustStoreType=pkcs12".to_owned()); + } + } + let operator_generated = JvmArgumentOverrides::new_with_only_additions(jvm_args); role.get_merged_jvm_argument_overrides(role_group, &operator_generated) .context(MergeJvmArgumentOverridesSnafu) diff --git a/rust/operator-binary/src/config/mod.rs b/rust/operator-binary/src/config/mod.rs index 3ddfa6da..c674a797 100644 --- a/rust/operator-binary/src/config/mod.rs +++ b/rust/operator-binary/src/config/mod.rs @@ -115,6 +115,7 @@ pub fn build_bootstrap_conf( overrides: BTreeMap, role: &Role, role_group: &str, + authorization_config: Option<&crate::security::authorization::NifiAuthorizationConfig>, ) -> Result { let mut bootstrap = BTreeMap::new(); // Java command to use when running NiFi @@ -129,7 +130,7 @@ pub fn build_bootstrap_conf( bootstrap.extend(graceful_shutdown_config_properties(merged_config)); let merged_jvm_config = - build_merged_jvm_config(merged_config, role, role_group).context(InvalidJVMConfigSnafu)?; + build_merged_jvm_config(merged_config, role, role_group, authorization_config).context(InvalidJVMConfigSnafu)?; for (index, argument) in merged_jvm_config .effective_jvm_config_after_merging() @@ -917,6 +918,6 @@ mod tests { let role = nifi.spec.nodes.as_ref().unwrap(); let merged_config = nifi.merged_config(&nifi_role, "default").unwrap(); - build_bootstrap_conf(&merged_config, BTreeMap::new(), role, "default").unwrap() + build_bootstrap_conf(&merged_config, BTreeMap::new(), role, "default", None).unwrap() } } diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index c7039148..4ccf66fc 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -24,7 +24,10 @@ use stackable_operator::{ container::ContainerBuilder, resources::ResourceRequirementsBuilder, security::PodSecurityContextBuilder, - volume::{ListenerOperatorVolumeSourceBuilderError, SecretFormat}, + volume::{ + ListenerOperatorVolumeSourceBuilderError, SecretFormat, + SecretOperatorVolumeSourceBuilder, VolumeBuilder, + }, }, }, client::Client, @@ -106,7 +109,7 @@ use crate::{ AUTHORIZERS_XML_FILE_NAME, LOGIN_IDENTITY_PROVIDERS_XML_FILE_NAME, NifiAuthenticationConfig, STACKABLE_SERVER_TLS_DIR, STACKABLE_TLS_STORE_PASSWORD, }, - authorization::NifiAuthorizationConfig, + authorization::{NifiAuthorizationConfig, OPA_TLS_MOUNT_PATH, OPA_TLS_VOLUME_NAME}, build_tls_volume, check_or_generate_oidc_admin_password, check_or_generate_sensitive_key, tls::{KEYSTORE_NIFI_CONTAINER_MOUNT, KEYSTORE_VOLUME_NAME, TRUSTSTORE_VOLUME_NAME}, }, @@ -343,6 +346,12 @@ pub enum Error { BuildListenerVolume { source: ListenerOperatorVolumeSourceBuilderError, }, + + #[snafu(display("failed to build OPA TLS certificate volume"))] + OpaTlsCertSecretClassVolumeBuild { + source: stackable_operator::builder::pod::volume::SecretOperatorVolumeSourceBuilderError, + }, + #[snafu(display("failed to apply group listener"))] ApplyGroupListener { source: stackable_operator::cluster_resources::Error, @@ -455,8 +464,16 @@ pub async fn reconcile_nifi( .context(SecuritySnafu)?; } - let authorization_config = - NifiAuthorizationConfig::from(&nifi.spec.cluster_config.authorization); + let authorization_config = NifiAuthorizationConfig::from( + &nifi.spec.cluster_config.authorization, + client, + nifi.metadata + .namespace + .as_deref() + .context(ObjectHasNoNamespaceSnafu)?, + ) + .await + .context(InvalidNifiAuthorizationConfigSnafu)?; let (rbac_sa, rbac_rolebinding) = build_rbac_resources( nifi, @@ -770,6 +787,7 @@ async fn build_node_rolegroup_config_map( .clone(), role, &rolegroup.role_group, + Some(authorization_config), ) .context(BootstrapConfigSnafu)?, ) @@ -978,6 +996,14 @@ async fn build_node_rolegroup_statefulset( .as_slice(), ); + // Add OPA certificate to truststore if OPA TLS is enabled + if authorization_config.has_opa_tls() { + prepare_args.extend(vec![ + "echo Importing OPA CA certificate to truststore".to_string(), + format!("keytool -importcert -file {OPA_TLS_MOUNT_PATH}/ca.crt -keystore {STACKABLE_SERVER_TLS_DIR}/truststore.p12 -storepass {STACKABLE_TLS_STORE_PASSWORD} -alias opa-ca -noprompt"), + ]); + } + prepare_args.extend(vec![ "export LISTENER_DEFAULT_ADDRESS=$(cat /stackable/listener/default-address/address)" .to_string(), @@ -1051,15 +1077,22 @@ async fn build_node_rolegroup_statefulset( .add_volume_mount(TRUSTSTORE_VOLUME_NAME, STACKABLE_SERVER_TLS_DIR) .context(AddVolumeMountSnafu)? .add_volume_mount(LISTENER_VOLUME_NAME, LISTENER_VOLUME_DIR) - .context(AddVolumeMountSnafu)? - .resources( - ResourceRequirementsBuilder::new() - .with_cpu_request("500m") - .with_cpu_limit("2000m") - .with_memory_request("4096Mi") - .with_memory_limit("4096Mi") - .build(), - ); + .context(AddVolumeMountSnafu)?; + + if authorization_config.has_opa_tls() { + container_prepare + .add_volume_mount(OPA_TLS_VOLUME_NAME, OPA_TLS_MOUNT_PATH) + .context(AddVolumeMountSnafu)?; + } + + container_prepare.resources( + ResourceRequirementsBuilder::new() + .with_cpu_request("500m") + .with_cpu_limit("2000m") + .with_memory_request("4096Mi") + .with_memory_limit("4096Mi") + .build(), + ); let nifi_container_name = Container::Nifi.to_string(); let mut container_nifi_builder = @@ -1083,6 +1116,13 @@ async fn build_node_rolegroup_statefulset( create_vector_shutdown_file_command = create_vector_shutdown_file_command(STACKABLE_LOG_DIR), }]; + + if authorization_config.has_opa_tls() { + container_nifi_builder + .add_volume_mount(OPA_TLS_VOLUME_NAME, OPA_TLS_MOUNT_PATH) + .context(AddVolumeMountSnafu)?; + } + let container_nifi = container_nifi_builder .image_from_product_image(resolved_product_image) .command(vec![ @@ -1366,7 +1406,22 @@ async fn build_node_rolegroup_statefulset( ) .context(AddVolumeSnafu)? .add_empty_dir_volume(TRUSTSTORE_VOLUME_NAME, None) - .context(AddVolumeSnafu)? + .context(AddVolumeSnafu)?; + + if let NifiAuthorizationConfig::Opa { secret_class: Some(secret_class), .. } = authorization_config + { + pod_builder + .add_volume(VolumeBuilder::new(OPA_TLS_VOLUME_NAME) + .ephemeral( + SecretOperatorVolumeSourceBuilder::new(secret_class) + .build() + .context(OpaTlsCertSecretClassVolumeBuildSnafu)?, + ) + .build()) + .context(AddVolumeSnafu)?; + } + + pod_builder .add_volume(Volume { name: "sensitiveproperty".to_string(), secret: Some(SecretVolumeSource { diff --git a/rust/operator-binary/src/security/authorization.rs b/rust/operator-binary/src/security/authorization.rs index 8f0575c7..d8122057 100644 --- a/rust/operator-binary/src/security/authorization.rs +++ b/rust/operator-binary/src/security/authorization.rs @@ -1,19 +1,30 @@ use indoc::{formatdoc, indoc}; -use snafu::{OptionExt, Snafu}; +use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ + client::Client, crd::authentication::ldap, - k8s_openapi::api::core::v1::{ConfigMapKeySelector, EnvVar, EnvVarSource}, + k8s_openapi::api::core::v1::{ConfigMap, ConfigMapKeySelector, EnvVar, EnvVarSource}, }; use super::authentication::NifiAuthenticationConfig; use crate::crd::NifiAuthorization; +pub const OPA_TLS_VOLUME_NAME: &str = "opa-tls"; +pub const OPA_TLS_MOUNT_PATH: &str = "/stackable/opa_tls"; + #[derive(Snafu, Debug)] pub enum Error { #[snafu(display( "The LDAP AuthenticationClass is missing the bind credentials. Currently the NiFi operator only supports connecting to LDAP servers using bind credentials" ))] LdapAuthenticationClassMissingBindCredentials {}, + + #[snafu(display("Failed to fetch OPA ConfigMap {configmap_name}"))] + FetchOpaConfigMap { + source: stackable_operator::client::Error, + configmap_name: String, + namespace: String, + }, } pub enum NifiAuthorizationConfig { @@ -21,23 +32,46 @@ pub enum NifiAuthorizationConfig { configmap_name: String, cache_entry_time_to_live_secs: u64, cache_max_entries: u32, + secret_class: Option, }, Default, } impl NifiAuthorizationConfig { - pub fn from(nifi_authorization: &Option) -> Self { - match nifi_authorization { + pub async fn from( + nifi_authorization: &Option, + client: &Client, + namespace: &str, + ) -> Result { + let config = match nifi_authorization { Some(authorization_config) => match authorization_config.opa.clone() { - Some(opa_config) => NifiAuthorizationConfig::Opa { - configmap_name: opa_config.opa.config_map_name, - cache_entry_time_to_live_secs: opa_config.cache.entry_time_to_live.as_secs(), - cache_max_entries: opa_config.cache.max_entries, - }, + Some(opa_config) => { + let configmap_name = opa_config.opa.config_map_name.clone(); + + // Resolve the secret class from the ConfigMap + let secret_class = client + .get::(&configmap_name, namespace) + .await + .with_context(|_| FetchOpaConfigMapSnafu { + configmap_name: configmap_name.clone(), + namespace: namespace.to_string(), + })? + .data + .and_then(|mut data| data.remove("OPA_SECRET_CLASS")); + + NifiAuthorizationConfig::Opa { + configmap_name, + cache_entry_time_to_live_secs: opa_config.cache.entry_time_to_live.as_secs(), + cache_max_entries: opa_config.cache.max_entries, + secret_class, + } + } None => NifiAuthorizationConfig::Default, }, None => NifiAuthorizationConfig::Default, - } + }; + + Ok(config) } pub fn get_authorizers_config( @@ -152,4 +186,8 @@ impl NifiAuthorizationConfig { NifiAuthorizationConfig::Default => vec![], } } + + pub fn has_opa_tls(&self) -> bool { + matches!(self, NifiAuthorizationConfig::Opa { secret_class: Some(_), .. }) + } } diff --git a/tests/templates/kuttl/oidc-opa/20-install-opa.yaml.j2 b/tests/templates/kuttl/oidc-opa/20-install-opa.yaml.j2 index 8b8f9cf5..5febeb1d 100644 --- a/tests/templates/kuttl/oidc-opa/20-install-opa.yaml.j2 +++ b/tests/templates/kuttl/oidc-opa/20-install-opa.yaml.j2 @@ -5,6 +5,19 @@ commands: - script: | kubectl apply -n $NAMESPACE -f - < Date: Tue, 4 Nov 2025 13:49:37 +0100 Subject: [PATCH 2/6] chore: rustfmt --- rust/operator-binary/src/config/jvm.rs | 8 ++++++-- rust/operator-binary/src/config/mod.rs | 3 ++- rust/operator-binary/src/controller.rs | 19 ++++++++++++------- .../src/security/authorization.rs | 13 +++++++++++-- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/rust/operator-binary/src/config/jvm.rs b/rust/operator-binary/src/config/jvm.rs index a39485f0..a570db6d 100644 --- a/rust/operator-binary/src/config/jvm.rs +++ b/rust/operator-binary/src/config/jvm.rs @@ -95,8 +95,12 @@ pub fn build_merged_jvm_config( // OPA Java SDK. if let Some(authz_config) = authorization_config { if authz_config.has_opa_tls() { - jvm_args.push(format!("-Djavax.net.ssl.trustStore={STACKABLE_SERVER_TLS_DIR}/truststore.p12")); - jvm_args.push(format!("-Djavax.net.ssl.trustStorePassword={STACKABLE_TLS_STORE_PASSWORD}")); + jvm_args.push(format!( + "-Djavax.net.ssl.trustStore={STACKABLE_SERVER_TLS_DIR}/truststore.p12" + )); + jvm_args.push(format!( + "-Djavax.net.ssl.trustStorePassword={STACKABLE_TLS_STORE_PASSWORD}" + )); jvm_args.push("-Djavax.net.ssl.trustStoreType=pkcs12".to_owned()); } } diff --git a/rust/operator-binary/src/config/mod.rs b/rust/operator-binary/src/config/mod.rs index c674a797..1c3ed4be 100644 --- a/rust/operator-binary/src/config/mod.rs +++ b/rust/operator-binary/src/config/mod.rs @@ -130,7 +130,8 @@ pub fn build_bootstrap_conf( bootstrap.extend(graceful_shutdown_config_properties(merged_config)); let merged_jvm_config = - build_merged_jvm_config(merged_config, role, role_group, authorization_config).context(InvalidJVMConfigSnafu)?; + build_merged_jvm_config(merged_config, role, role_group, authorization_config) + .context(InvalidJVMConfigSnafu)?; for (index, argument) in merged_jvm_config .effective_jvm_config_after_merging() diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 4ccf66fc..917895f3 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -1408,16 +1408,21 @@ async fn build_node_rolegroup_statefulset( .add_empty_dir_volume(TRUSTSTORE_VOLUME_NAME, None) .context(AddVolumeSnafu)?; - if let NifiAuthorizationConfig::Opa { secret_class: Some(secret_class), .. } = authorization_config + if let NifiAuthorizationConfig::Opa { + secret_class: Some(secret_class), + .. + } = authorization_config { pod_builder - .add_volume(VolumeBuilder::new(OPA_TLS_VOLUME_NAME) - .ephemeral( - SecretOperatorVolumeSourceBuilder::new(secret_class) - .build() - .context(OpaTlsCertSecretClassVolumeBuildSnafu)?, + .add_volume( + VolumeBuilder::new(OPA_TLS_VOLUME_NAME) + .ephemeral( + SecretOperatorVolumeSourceBuilder::new(secret_class) + .build() + .context(OpaTlsCertSecretClassVolumeBuildSnafu)?, + ) + .build(), ) - .build()) .context(AddVolumeSnafu)?; } diff --git a/rust/operator-binary/src/security/authorization.rs b/rust/operator-binary/src/security/authorization.rs index d8122057..6c46f942 100644 --- a/rust/operator-binary/src/security/authorization.rs +++ b/rust/operator-binary/src/security/authorization.rs @@ -61,7 +61,10 @@ impl NifiAuthorizationConfig { NifiAuthorizationConfig::Opa { configmap_name, - cache_entry_time_to_live_secs: opa_config.cache.entry_time_to_live.as_secs(), + cache_entry_time_to_live_secs: opa_config + .cache + .entry_time_to_live + .as_secs(), cache_max_entries: opa_config.cache.max_entries, secret_class, } @@ -188,6 +191,12 @@ impl NifiAuthorizationConfig { } pub fn has_opa_tls(&self) -> bool { - matches!(self, NifiAuthorizationConfig::Opa { secret_class: Some(_), .. }) + matches!( + self, + NifiAuthorizationConfig::Opa { + secret_class: Some(_), + .. + } + ) } } From 82bc9697c75f83a2b4226b6e606d16e64cccf11c Mon Sep 17 00:00:00 2001 From: dervoeti Date: Tue, 4 Nov 2025 14:06:52 +0100 Subject: [PATCH 3/6] chore: changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d3047cf..f5750da3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. - `EOS_CHECK_MODE` (`--eos-check-mode`) to set the EoS check mode. Currently, only "offline" is supported. - `EOS_INTERVAL` (`--eos-interval`) to set the interval in which the operator checks if it is EoS. - `EOS_DISABLED` (`--eos-disabled`) to disable the EoS checker completely. +- Add support for OPA with TLS enabled ([#863]). ### Changed @@ -33,6 +34,7 @@ All notable changes to this project will be documented in this file. [#855]: https://github.com/stackabletech/nifi-operator/pull/855 [#859]: https://github.com/stackabletech/nifi-operator/pull/859 [#860]: https://github.com/stackabletech/nifi-operator/pull/860 +[#863]: https://github.com/stackabletech/nifi-operator/pull/863 ## [25.7.0] - 2025-07-23 From ee3eaaaf48901106cf07aba32380f475547ce4f5 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 4 Nov 2025 16:25:00 +0100 Subject: [PATCH 4/6] improve opa rules and fix reporting task access --- .../templates/kuttl/oidc-opa/25-opa-rego.yaml | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/tests/templates/kuttl/oidc-opa/25-opa-rego.yaml b/tests/templates/kuttl/oidc-opa/25-opa-rego.yaml index 43f58fd6..57c90e7e 100644 --- a/tests/templates/kuttl/oidc-opa/25-opa-rego.yaml +++ b/tests/templates/kuttl/oidc-opa/25-opa-rego.yaml @@ -9,6 +9,9 @@ data: nifi.rego: | package nifi + nifi_node_proxy := "CN=generated certificate for pod" + nifi_reporting_task_user := "admin" + # Setting "resourceNotFound" to true results in the parent resource beingevaluated for authorization, # e.g. the parent of a processor is the processor-group. # If a resource is matched by a rego rule that is not the default the parent resource will be ignored. @@ -61,15 +64,47 @@ data: group == "nifi-user" } + ### Reporting Task permissions (NiFi 1.x.x) + + # Allow the reporting task user + allow := { + "allowed": true, + "dumpCache": true + } if { + input.identity.name == nifi_reporting_task_user + } + + ### NiFi Node permissions + + # NiFi Nodes need this permission to communicate with each other allow := { "allowed": true, "dumpCache": true } if { - input.identity.name == "CN=generated certificate for pod" + input.identity.name == nifi_node_proxy input.resource.id == "/proxy" } - user_groups := user_groups if { - user_group_paths := data.stackable.opa.userinfo.v1.userInfoByUsername(input.identity.name).groups - user_groups := [ trim(user_group,"/") | user_group := user_group_paths[_] ] + # Check processor queues + allow := { + "allowed": true, + "dumpCache": true + } if { + input.identity.name == nifi_node_proxy + startswith(input.resource.id, "/data/processors/") + } + + ### Helper functions + + user_groups := get_user_groups(input.identity.name) + + get_user_groups(name) = groups if { + not startswith(name, nifi_node_proxy) + groups_raw := data.stackable.opa.userinfo.v1.userInfoByUsername(name).groups + groups := [trim(g, "/") | g := groups_raw[_]] + } + + # filter nifi_node_proxy calls to UIF + get_user_groups(name) := [] if { + startswith(name, nifi_node_proxy) } From 1a4d88eeacc45f3e7c5c31279c369b4d50efd236 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 4 Nov 2025 16:26:26 +0100 Subject: [PATCH 5/6] remove obsolete errors --- rust/operator-binary/src/controller.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 917895f3..c98330fe 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -24,10 +24,7 @@ use stackable_operator::{ container::ContainerBuilder, resources::ResourceRequirementsBuilder, security::PodSecurityContextBuilder, - volume::{ - ListenerOperatorVolumeSourceBuilderError, SecretFormat, - SecretOperatorVolumeSourceBuilder, VolumeBuilder, - }, + volume::{SecretFormat, SecretOperatorVolumeSourceBuilder, VolumeBuilder}, }, }, client::Client, @@ -155,11 +152,6 @@ pub enum Error { source: stackable_operator::cluster_resources::Error, }, - #[snafu(display("failed to fetch deployed StatefulSets"))] - FetchStatefulsets { - source: stackable_operator::client::Error, - }, - #[snafu(display("failed to update status"))] StatusUpdate { source: stackable_operator::client::Error, @@ -342,11 +334,6 @@ pub enum Error { #[snafu(display("Failed to determine the state of the version upgrade procedure"))] ClusterVersionUpdateState { source: upgrade::Error }, - #[snafu(display("failed to build listener volume"))] - BuildListenerVolume { - source: ListenerOperatorVolumeSourceBuilderError, - }, - #[snafu(display("failed to build OPA TLS certificate volume"))] OpaTlsCertSecretClassVolumeBuild { source: stackable_operator::builder::pod::volume::SecretOperatorVolumeSourceBuilderError, From 7e9dfc5ccbf4624c5be5108e5199d360fd020cbf Mon Sep 17 00:00:00 2001 From: Lukas Krug Date: Tue, 4 Nov 2025 17:46:02 +0100 Subject: [PATCH 6/6] Update rust/operator-binary/src/controller.rs Co-authored-by: Malte Sander --- rust/operator-binary/src/controller.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index c98330fe..124f83db 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -1064,7 +1064,15 @@ async fn build_node_rolegroup_statefulset( .add_volume_mount(TRUSTSTORE_VOLUME_NAME, STACKABLE_SERVER_TLS_DIR) .context(AddVolumeMountSnafu)? .add_volume_mount(LISTENER_VOLUME_NAME, LISTENER_VOLUME_DIR) - .context(AddVolumeMountSnafu)?; + .context(AddVolumeMountSnafu)? + .resources( + ResourceRequirementsBuilder::new() + .with_cpu_request("500m") + .with_cpu_limit("2000m") + .with_memory_request("4096Mi") + .with_memory_limit("4096Mi") + .build(), + ); if authorization_config.has_opa_tls() { container_prepare @@ -1072,15 +1080,6 @@ async fn build_node_rolegroup_statefulset( .context(AddVolumeMountSnafu)?; } - container_prepare.resources( - ResourceRequirementsBuilder::new() - .with_cpu_request("500m") - .with_cpu_limit("2000m") - .with_memory_request("4096Mi") - .with_memory_limit("4096Mi") - .build(), - ); - let nifi_container_name = Container::Nifi.to_string(); let mut container_nifi_builder = ContainerBuilder::new(&nifi_container_name).with_context(|_| {