From 75fb0249e073af46dadf7dbd31d265771ba9d03e Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 14 Oct 2025 13:27:22 +0200 Subject: [PATCH 1/3] add prometheus annotations to metrics service --- rust/operator-binary/src/controller.rs | 17 +++------ rust/operator-binary/src/service.rs | 52 ++++++++++++++------------ 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 02e0d292..c7039148 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -110,10 +110,7 @@ use crate::{ 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}, }, - service::{ - build_rolegroup_headless_service, build_rolegroup_metrics_service, metrics_service_port, - rolegroup_headless_service_name, rolegroup_metrics_service_name, - }, + service::{build_rolegroup_headless_service, build_rolegroup_metrics_service}, }; pub const NIFI_CONTROLLER_NAME: &str = "nificluster"; @@ -576,9 +573,7 @@ pub async fn reconcile_nifi( &rolegroup, role_group_service_recommended_labels, role_group_service_selector.into(), - vec![metrics_service_port( - &resolved_product_image.product_version, - )], + &resolved_product_image.product_version, ) .context(ServiceConfigurationSnafu)?; @@ -926,7 +921,7 @@ async fn build_node_rolegroup_statefulset( let node_address = format!( "$POD_NAME.{service_name}.{namespace}.svc.{cluster_domain}", - service_name = rolegroup_headless_service_name(&rolegroup_ref.object_name()), + service_name = rolegroup_ref.rolegroup_headless_service_name(), namespace = &nifi .metadata .namespace @@ -1360,7 +1355,7 @@ async fn build_node_rolegroup_statefulset( nifi, KEYSTORE_VOLUME_NAME, [ - rolegroup_metrics_service_name(rolegroup_ref.object_name()), + rolegroup_ref.rolegroup_metrics_service_name(), build_reporting_task_service_name(&nifi_cluster_name), ], SecretFormat::TlsPkcs12, @@ -1434,9 +1429,7 @@ async fn build_node_rolegroup_statefulset( ), ..LabelSelector::default() }, - service_name: Some(rolegroup_headless_service_name( - &rolegroup_ref.object_name(), - )), + service_name: Some(rolegroup_ref.rolegroup_headless_service_name()), template: pod_template, update_strategy: Some(StatefulSetUpdateStrategy { type_: if rolling_update_supported { diff --git a/rust/operator-binary/src/service.rs b/rust/operator-binary/src/service.rs index a403d3a2..c0acc305 100644 --- a/rust/operator-binary/src/service.rs +++ b/rust/operator-binary/src/service.rs @@ -4,15 +4,12 @@ use snafu::{ResultExt, Snafu}; use stackable_operator::{ builder::meta::ObjectMetaBuilder, k8s_openapi::api::core::v1::{Service, ServicePort, ServiceSpec}, - kvp::{Label, ObjectLabels}, + kvp::{Annotations, Labels, ObjectLabels}, role_utils::RoleGroupRef, }; use crate::crd::{HTTPS_PORT, HTTPS_PORT_NAME, METRICS_PORT, METRICS_PORT_NAME, v1alpha1}; -const METRICS_SERVICE_SUFFIX: &str = "metrics"; -const HEADLESS_SERVICE_SUFFIX: &str = "headless"; - #[derive(Snafu, Debug)] pub enum Error { #[snafu(display("object is missing metadata to build owner reference"))] @@ -24,11 +21,6 @@ pub enum Error { MetadataBuild { source: stackable_operator::builder::meta::Error, }, - - #[snafu(display("failed to build Labels"))] - LabelBuild { - source: stackable_operator::kvp::LabelError, - }, } /// The rolegroup headless [`Service`] is a service that allows direct access to the instances of a certain rolegroup @@ -42,9 +34,7 @@ pub fn build_rolegroup_headless_service( Ok(Service { metadata: ObjectMetaBuilder::new() .name_and_namespace(nifi) - .name(rolegroup_headless_service_name( - &role_group_ref.object_name(), - )) + .name(role_group_ref.rolegroup_headless_service_name()) .ownerreference_from_resource(nifi, None, Some(true)) .context(ObjectMissingMetadataForOwnerRefSnafu)? .with_recommended_labels(object_labels) @@ -69,23 +59,24 @@ pub fn build_rolegroup_metrics_service( role_group_ref: &RoleGroupRef, object_labels: ObjectLabels, selector: BTreeMap, - ports: Vec, + product_version: &str, ) -> Result { Ok(Service { metadata: ObjectMetaBuilder::new() .name_and_namespace(nifi) - .name(rolegroup_metrics_service_name(role_group_ref.object_name())) + .name(role_group_ref.rolegroup_metrics_service_name()) .ownerreference_from_resource(nifi, None, Some(true)) .context(ObjectMissingMetadataForOwnerRefSnafu)? .with_recommended_labels(object_labels) .context(MetadataBuildSnafu)? - .with_label(Label::try_from(("prometheus.io/scrape", "true")).context(LabelBuildSnafu)?) + .with_labels(prometheus_labels()) + .with_annotations(prometheus_annotations(product_version)) .build(), spec: Some(ServiceSpec { // Internal communication does not need to be exposed type_: Some("ClusterIP".to_string()), cluster_ip: Some("None".to_string()), - ports: Some(ports), + ports: Some(vec![metrics_service_port(product_version)]), selector: Some(selector), publish_not_ready_addresses: Some(true), ..ServiceSpec::default() @@ -124,13 +115,28 @@ pub fn metrics_service_port(product_version: &str) -> ServicePort { } } -/// Returns the metrics rolegroup service name `---`. -pub fn rolegroup_metrics_service_name(role_group_ref_object_name: impl AsRef) -> String { - let role_group_ref_object_name = role_group_ref_object_name.as_ref(); - format!("{role_group_ref_object_name}-{METRICS_SERVICE_SUFFIX}") +/// Common labels for Prometheus +fn prometheus_labels() -> Labels { + Labels::try_from([("prometheus.io/scrape", "true")]).expect("should be a valid label") } -/// Returns the headless rolegroup service name `---`. -pub fn rolegroup_headless_service_name(role_group_ref_object_name: &str) -> String { - format!("{role_group_ref_object_name}-{HEADLESS_SERVICE_SUFFIX}") +/// Common annotations for Prometheus +/// +/// These annotations can be used in a ServiceMonitor. +/// +/// see also +fn prometheus_annotations(product_version: &str) -> Annotations { + let port = if product_version.starts_with("1.") { + METRICS_PORT + } else { + HTTPS_PORT + }; + + Annotations::try_from([ + ("prometheus.io/path".to_owned(), "/metrics".to_owned()), + ("prometheus.io/port".to_owned(), port.to_string()), + ("prometheus.io/scheme".to_owned(), "http".to_owned()), + ("prometheus.io/scrape".to_owned(), "true".to_owned()), + ]) + .expect("should be valid annotations") } From 0d9a5f96a9d4a4f6377ce6e6df5c693335d50c29 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 14 Oct 2025 13:43:50 +0200 Subject: [PATCH 2/3] improve annotations --- rust/operator-binary/src/service.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/operator-binary/src/service.rs b/rust/operator-binary/src/service.rs index c0acc305..a276f581 100644 --- a/rust/operator-binary/src/service.rs +++ b/rust/operator-binary/src/service.rs @@ -126,16 +126,16 @@ fn prometheus_labels() -> Labels { /// /// see also fn prometheus_annotations(product_version: &str) -> Annotations { - let port = if product_version.starts_with("1.") { - METRICS_PORT + let (path, port, scheme) = if product_version.starts_with("1.") { + ("/metrics", METRICS_PORT, "http") } else { - HTTPS_PORT + ("/nifi-api/flow/metrics/prometheus", HTTPS_PORT, "https") }; Annotations::try_from([ - ("prometheus.io/path".to_owned(), "/metrics".to_owned()), + ("prometheus.io/path".to_owned(), path.to_owned()), ("prometheus.io/port".to_owned(), port.to_string()), - ("prometheus.io/scheme".to_owned(), "http".to_owned()), + ("prometheus.io/scheme".to_owned(), scheme.to_owned()), ("prometheus.io/scrape".to_owned(), "true".to_owned()), ]) .expect("should be valid annotations") From 9dec4f87e6814192c62ab092d0312d561e883ddc Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 14 Oct 2025 13:47:53 +0200 Subject: [PATCH 3/3] adapted changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 236f40c1..77cf3ae5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - Helm: Allow Pod `priorityClassName` to be configured ([#840]). - Add support for `2.6.0` ([#849]). +- Add `prometheus.io/path|port|scheme` annotations to metrics service ([#855]). ### Changed @@ -24,6 +25,7 @@ All notable changes to this project will be documented in this file. [#840]: https://github.com/stackabletech/nifi-operator/pull/840 [#844]: https://github.com/stackabletech/nifi-operator/pull/844 [#849]: https://github.com/stackabletech/nifi-operator/pull/849 +[#855]: https://github.com/stackabletech/nifi-operator/pull/855 ## [25.7.0] - 2025-07-23