Skip to content

Commit c4b869d

Browse files
authored
chore: ensure metrics are correctly exposed (#855)
* add prometheus annotations to metrics service * improve annotations * adapted changelog
1 parent 3569e2c commit c4b869d

3 files changed

Lines changed: 36 additions & 35 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
88

99
- Helm: Allow Pod `priorityClassName` to be configured ([#840]).
1010
- Add support for `2.6.0` ([#849]).
11+
- Add `prometheus.io/path|port|scheme` annotations to metrics service ([#855]).
1112

1213
### Changed
1314

@@ -24,6 +25,7 @@ All notable changes to this project will be documented in this file.
2425
[#840]: https://github.com/stackabletech/nifi-operator/pull/840
2526
[#844]: https://github.com/stackabletech/nifi-operator/pull/844
2627
[#849]: https://github.com/stackabletech/nifi-operator/pull/849
28+
[#855]: https://github.com/stackabletech/nifi-operator/pull/855
2729

2830
## [25.7.0] - 2025-07-23
2931

rust/operator-binary/src/controller.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,7 @@ use crate::{
110110
build_tls_volume, check_or_generate_oidc_admin_password, check_or_generate_sensitive_key,
111111
tls::{KEYSTORE_NIFI_CONTAINER_MOUNT, KEYSTORE_VOLUME_NAME, TRUSTSTORE_VOLUME_NAME},
112112
},
113-
service::{
114-
build_rolegroup_headless_service, build_rolegroup_metrics_service, metrics_service_port,
115-
rolegroup_headless_service_name, rolegroup_metrics_service_name,
116-
},
113+
service::{build_rolegroup_headless_service, build_rolegroup_metrics_service},
117114
};
118115

119116
pub const NIFI_CONTROLLER_NAME: &str = "nificluster";
@@ -576,9 +573,7 @@ pub async fn reconcile_nifi(
576573
&rolegroup,
577574
role_group_service_recommended_labels,
578575
role_group_service_selector.into(),
579-
vec![metrics_service_port(
580-
&resolved_product_image.product_version,
581-
)],
576+
&resolved_product_image.product_version,
582577
)
583578
.context(ServiceConfigurationSnafu)?;
584579

@@ -926,7 +921,7 @@ async fn build_node_rolegroup_statefulset(
926921

927922
let node_address = format!(
928923
"$POD_NAME.{service_name}.{namespace}.svc.{cluster_domain}",
929-
service_name = rolegroup_headless_service_name(&rolegroup_ref.object_name()),
924+
service_name = rolegroup_ref.rolegroup_headless_service_name(),
930925
namespace = &nifi
931926
.metadata
932927
.namespace
@@ -1360,7 +1355,7 @@ async fn build_node_rolegroup_statefulset(
13601355
nifi,
13611356
KEYSTORE_VOLUME_NAME,
13621357
[
1363-
rolegroup_metrics_service_name(rolegroup_ref.object_name()),
1358+
rolegroup_ref.rolegroup_metrics_service_name(),
13641359
build_reporting_task_service_name(&nifi_cluster_name),
13651360
],
13661361
SecretFormat::TlsPkcs12,
@@ -1434,9 +1429,7 @@ async fn build_node_rolegroup_statefulset(
14341429
),
14351430
..LabelSelector::default()
14361431
},
1437-
service_name: Some(rolegroup_headless_service_name(
1438-
&rolegroup_ref.object_name(),
1439-
)),
1432+
service_name: Some(rolegroup_ref.rolegroup_headless_service_name()),
14401433
template: pod_template,
14411434
update_strategy: Some(StatefulSetUpdateStrategy {
14421435
type_: if rolling_update_supported {

rust/operator-binary/src/service.rs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@ use snafu::{ResultExt, Snafu};
44
use stackable_operator::{
55
builder::meta::ObjectMetaBuilder,
66
k8s_openapi::api::core::v1::{Service, ServicePort, ServiceSpec},
7-
kvp::{Label, ObjectLabels},
7+
kvp::{Annotations, Labels, ObjectLabels},
88
role_utils::RoleGroupRef,
99
};
1010

1111
use crate::crd::{HTTPS_PORT, HTTPS_PORT_NAME, METRICS_PORT, METRICS_PORT_NAME, v1alpha1};
1212

13-
const METRICS_SERVICE_SUFFIX: &str = "metrics";
14-
const HEADLESS_SERVICE_SUFFIX: &str = "headless";
15-
1613
#[derive(Snafu, Debug)]
1714
pub enum Error {
1815
#[snafu(display("object is missing metadata to build owner reference"))]
@@ -24,11 +21,6 @@ pub enum Error {
2421
MetadataBuild {
2522
source: stackable_operator::builder::meta::Error,
2623
},
27-
28-
#[snafu(display("failed to build Labels"))]
29-
LabelBuild {
30-
source: stackable_operator::kvp::LabelError,
31-
},
3224
}
3325

3426
/// 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(
4234
Ok(Service {
4335
metadata: ObjectMetaBuilder::new()
4436
.name_and_namespace(nifi)
45-
.name(rolegroup_headless_service_name(
46-
&role_group_ref.object_name(),
47-
))
37+
.name(role_group_ref.rolegroup_headless_service_name())
4838
.ownerreference_from_resource(nifi, None, Some(true))
4939
.context(ObjectMissingMetadataForOwnerRefSnafu)?
5040
.with_recommended_labels(object_labels)
@@ -69,23 +59,24 @@ pub fn build_rolegroup_metrics_service(
6959
role_group_ref: &RoleGroupRef<v1alpha1::NifiCluster>,
7060
object_labels: ObjectLabels<v1alpha1::NifiCluster>,
7161
selector: BTreeMap<String, String>,
72-
ports: Vec<ServicePort>,
62+
product_version: &str,
7363
) -> Result<Service, Error> {
7464
Ok(Service {
7565
metadata: ObjectMetaBuilder::new()
7666
.name_and_namespace(nifi)
77-
.name(rolegroup_metrics_service_name(role_group_ref.object_name()))
67+
.name(role_group_ref.rolegroup_metrics_service_name())
7868
.ownerreference_from_resource(nifi, None, Some(true))
7969
.context(ObjectMissingMetadataForOwnerRefSnafu)?
8070
.with_recommended_labels(object_labels)
8171
.context(MetadataBuildSnafu)?
82-
.with_label(Label::try_from(("prometheus.io/scrape", "true")).context(LabelBuildSnafu)?)
72+
.with_labels(prometheus_labels())
73+
.with_annotations(prometheus_annotations(product_version))
8374
.build(),
8475
spec: Some(ServiceSpec {
8576
// Internal communication does not need to be exposed
8677
type_: Some("ClusterIP".to_string()),
8778
cluster_ip: Some("None".to_string()),
88-
ports: Some(ports),
79+
ports: Some(vec![metrics_service_port(product_version)]),
8980
selector: Some(selector),
9081
publish_not_ready_addresses: Some(true),
9182
..ServiceSpec::default()
@@ -124,13 +115,28 @@ pub fn metrics_service_port(product_version: &str) -> ServicePort {
124115
}
125116
}
126117

127-
/// Returns the metrics rolegroup service name `<cluster>-<role>-<rolegroup>-<METRICS_SERVICE_SUFFIX>`.
128-
pub fn rolegroup_metrics_service_name(role_group_ref_object_name: impl AsRef<str>) -> String {
129-
let role_group_ref_object_name = role_group_ref_object_name.as_ref();
130-
format!("{role_group_ref_object_name}-{METRICS_SERVICE_SUFFIX}")
118+
/// Common labels for Prometheus
119+
fn prometheus_labels() -> Labels {
120+
Labels::try_from([("prometheus.io/scrape", "true")]).expect("should be a valid label")
131121
}
132122

133-
/// Returns the headless rolegroup service name `<cluster>-<role>-<rolegroup>-<HEADLESS_SERVICE_SUFFIX>`.
134-
pub fn rolegroup_headless_service_name(role_group_ref_object_name: &str) -> String {
135-
format!("{role_group_ref_object_name}-{HEADLESS_SERVICE_SUFFIX}")
123+
/// Common annotations for Prometheus
124+
///
125+
/// These annotations can be used in a ServiceMonitor.
126+
///
127+
/// see also <https://github.com/prometheus-community/helm-charts/blob/prometheus-27.32.0/charts/prometheus/values.yaml#L983-L1036>
128+
fn prometheus_annotations(product_version: &str) -> Annotations {
129+
let (path, port, scheme) = if product_version.starts_with("1.") {
130+
("/metrics", METRICS_PORT, "http")
131+
} else {
132+
("/nifi-api/flow/metrics/prometheus", HTTPS_PORT, "https")
133+
};
134+
135+
Annotations::try_from([
136+
("prometheus.io/path".to_owned(), path.to_owned()),
137+
("prometheus.io/port".to_owned(), port.to_string()),
138+
("prometheus.io/scheme".to_owned(), scheme.to_owned()),
139+
("prometheus.io/scrape".to_owned(), "true".to_owned()),
140+
])
141+
.expect("should be valid annotations")
136142
}

0 commit comments

Comments
 (0)