From fd8bf505fcf1136794aac264fef07539815323a3 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Mon, 14 Jul 2025 12:08:12 +0200 Subject: [PATCH 1/4] add metrics service for nifi v2 --- rust/operator-binary/src/controller.rs | 42 +++++++++++-------- rust/operator-binary/src/service.rs | 7 ++-- .../kuttl/external-access/30-assert.yaml | 15 ++++++- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index c16a591a..66a72d83 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -108,8 +108,8 @@ use crate::{ tls::{KEYSTORE_NIFI_CONTAINER_MOUNT, KEYSTORE_VOLUME_NAME, TRUSTSTORE_VOLUME_NAME}, }, service::{ - build_rolegroup_headless_service, build_rolegroup_metrics_service, - rolegroup_headless_service_name, + build_rolegroup_headless_service, build_rolegroup_metrics_service, headless_service_ports, + metrics_service_ports, rolegroup_headless_service_name, }, }; @@ -562,22 +562,30 @@ pub async fn reconcile_nifi( ) .await?; - if resolved_product_image.product_version.starts_with("1.") { - let rg_metrics_service = build_rolegroup_metrics_service( - nifi, - &rolegroup, - role_group_service_recommended_labels, - role_group_service_selector.into(), - ) - .context(ServiceConfigurationSnafu)?; + // Determine the service ports to expose + // 1.X.X: extra metrics ports + // 2.X.X: via NiFi HTTP(s) port + let service_ports = if resolved_product_image.product_version.starts_with("1.") { + metrics_service_ports() + } else { + headless_service_ports() + }; - cluster_resources - .add(client, rg_metrics_service) - .await - .with_context(|_| ApplyRoleGroupServiceSnafu { - rolegroup: rolegroup.clone(), - })?; - } + let rg_metrics_service = build_rolegroup_metrics_service( + nifi, + &rolegroup, + role_group_service_recommended_labels, + role_group_service_selector.into(), + service_ports, + ) + .context(ServiceConfigurationSnafu)?; + + cluster_resources + .add(client, rg_metrics_service) + .await + .with_context(|_| ApplyRoleGroupServiceSnafu { + rolegroup: rolegroup.clone(), + })?; cluster_resources .add(client, rg_headless_service) diff --git a/rust/operator-binary/src/service.rs b/rust/operator-binary/src/service.rs index 2e0e9a79..4a83f1af 100644 --- a/rust/operator-binary/src/service.rs +++ b/rust/operator-binary/src/service.rs @@ -69,6 +69,7 @@ pub fn build_rolegroup_metrics_service( role_group_ref: &RoleGroupRef, object_labels: ObjectLabels, selector: BTreeMap, + ports: Vec, ) -> Result { Ok(Service { metadata: ObjectMetaBuilder::new() @@ -86,7 +87,7 @@ pub fn build_rolegroup_metrics_service( // Internal communication does not need to be exposed type_: Some("ClusterIP".to_string()), cluster_ip: Some("None".to_string()), - ports: Some(metrics_service_ports()), + ports: Some(ports), selector: Some(selector), publish_not_ready_addresses: Some(true), ..ServiceSpec::default() @@ -95,7 +96,7 @@ pub fn build_rolegroup_metrics_service( }) } -fn headless_service_ports() -> Vec { +pub fn headless_service_ports() -> Vec { vec![ServicePort { name: Some(HTTPS_PORT_NAME.into()), port: HTTPS_PORT.into(), @@ -104,7 +105,7 @@ fn headless_service_ports() -> Vec { }] } -fn metrics_service_ports() -> Vec { +pub fn metrics_service_ports() -> Vec { vec![ServicePort { name: Some(METRICS_PORT_NAME.to_string()), port: METRICS_PORT.into(), diff --git a/tests/templates/kuttl/external-access/30-assert.yaml b/tests/templates/kuttl/external-access/30-assert.yaml index 25907e6a..c8122146 100644 --- a/tests/templates/kuttl/external-access/30-assert.yaml +++ b/tests/templates/kuttl/external-access/30-assert.yaml @@ -15,7 +15,6 @@ status: readyReplicas: 2 replicas: 2 --- ---- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: @@ -25,7 +24,6 @@ status: currentHealthy: 2 disruptionsAllowed: 1 --- ---- apiVersion: v1 kind: Service metadata: @@ -33,3 +31,16 @@ metadata: spec: type: NodePort # external-unstable --- +apiVersion: v1 +kind: Service +metadata: + name: test-nifi-node-default-headless +spec: + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + name: test-nifi-node-default-metrics +spec: + type: ClusterIP From 0dca79087c1d3bd94c4d9a1253d18df2f0ce6dd0 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Mon, 14 Jul 2025 12:10:12 +0200 Subject: [PATCH 2/4] adapted changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ac884ca..6954e254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ All notable changes to this project will be documented in this file. - Fix a bug where changes to ConfigMaps that are referenced in the NifiCluster spec didn't trigger a reconciliation ([#772]). - The operator now emits a warning (1.x.x) or errors out (2.x.x) if a deprecated or unsupported sensitive properties algorithm is used ([#799]). - Allow uppercase characters in domain names ([#817]). +- NiFi v2 now exposes a metrics service (pointing to the same port as the headless service) ([#819]). ### Removed @@ -69,6 +70,7 @@ All notable changes to this project will be documented in this file. [#801]: https://github.com/stackabletech/nifi-operator/pull/801 [#808]: https://github.com/stackabletech/nifi-operator/pull/808 [#817]: https://github.com/stackabletech/nifi-operator/pull/817 +[#819]: https://github.com/stackabletech/nifi-operator/pull/819 ## [25.3.0] - 2025-03-21 From a2226e7dd09ccbe767352376a2fc48d796503c2a Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Mon, 14 Jul 2025 12:19:04 +0200 Subject: [PATCH 3/4] add changelog entry to listener entry --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6954e254..dcf5d670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - Add rolling upgrade support for upgrades between NiFi 2 versions ([#771]). -- Added Listener support for NiFi ([#784]). +- BREAKING: Added Listener support for NiFi ([#784], [#819]). - Adds new telemetry CLI arguments and environment variables ([#782]). - Use `--file-log-max-files` (or `FILE_LOG_MAX_FILES`) to limit the number of log files kept. - Use `--file-log-rotation-period` (or `FILE_LOG_ROTATION_PERIOD`) to configure the frequency of rotation. @@ -45,7 +45,6 @@ All notable changes to this project will be documented in this file. - Fix a bug where changes to ConfigMaps that are referenced in the NifiCluster spec didn't trigger a reconciliation ([#772]). - The operator now emits a warning (1.x.x) or errors out (2.x.x) if a deprecated or unsupported sensitive properties algorithm is used ([#799]). - Allow uppercase characters in domain names ([#817]). -- NiFi v2 now exposes a metrics service (pointing to the same port as the headless service) ([#819]). ### Removed From 530f16c61c367ca937b64cc7efaa8e538f1d9eeb Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Mon, 14 Jul 2025 12:24:37 +0200 Subject: [PATCH 4/4] adapt to review --- rust/operator-binary/src/controller.rs | 17 +++++----------- rust/operator-binary/src/service.rs | 28 ++++++++++++++++++-------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 66a72d83..4e74afc6 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -108,8 +108,8 @@ use crate::{ tls::{KEYSTORE_NIFI_CONTAINER_MOUNT, KEYSTORE_VOLUME_NAME, TRUSTSTORE_VOLUME_NAME}, }, service::{ - build_rolegroup_headless_service, build_rolegroup_metrics_service, headless_service_ports, - metrics_service_ports, rolegroup_headless_service_name, + build_rolegroup_headless_service, build_rolegroup_metrics_service, metrics_service_port, + rolegroup_headless_service_name, }, }; @@ -562,21 +562,14 @@ pub async fn reconcile_nifi( ) .await?; - // Determine the service ports to expose - // 1.X.X: extra metrics ports - // 2.X.X: via NiFi HTTP(s) port - let service_ports = if resolved_product_image.product_version.starts_with("1.") { - metrics_service_ports() - } else { - headless_service_ports() - }; - let rg_metrics_service = build_rolegroup_metrics_service( nifi, &rolegroup, role_group_service_recommended_labels, role_group_service_selector.into(), - service_ports, + vec![metrics_service_port( + &resolved_product_image.product_version, + )], ) .context(ServiceConfigurationSnafu)?; diff --git a/rust/operator-binary/src/service.rs b/rust/operator-binary/src/service.rs index 4a83f1af..b217953c 100644 --- a/rust/operator-binary/src/service.rs +++ b/rust/operator-binary/src/service.rs @@ -96,7 +96,7 @@ pub fn build_rolegroup_metrics_service( }) } -pub fn headless_service_ports() -> Vec { +fn headless_service_ports() -> Vec { vec![ServicePort { name: Some(HTTPS_PORT_NAME.into()), port: HTTPS_PORT.into(), @@ -105,13 +105,25 @@ pub fn headless_service_ports() -> Vec { }] } -pub fn metrics_service_ports() -> Vec { - vec![ServicePort { - name: Some(METRICS_PORT_NAME.to_string()), - port: METRICS_PORT.into(), - protocol: Some("TCP".to_string()), - ..ServicePort::default() - }] +/// Returns the metrics port based on the NiFi version +/// V1: Uses extra port via JMX exporter +/// V2: Uses NiFi HTTP(S) port for metrics +pub fn metrics_service_port(product_version: &str) -> ServicePort { + if product_version.starts_with("1.") { + ServicePort { + name: Some(METRICS_PORT_NAME.to_string()), + port: METRICS_PORT.into(), + protocol: Some("TCP".to_string()), + ..ServicePort::default() + } + } else { + ServicePort { + name: Some(HTTPS_PORT_NAME.into()), + port: HTTPS_PORT.into(), + protocol: Some("TCP".to_string()), + ..ServicePort::default() + } + } } /// Returns the metrics rolegroup service name `---`.