diff --git a/CHANGELOG.md b/CHANGELOG.md index 958124b9..8e02b39f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - Helm: Allow Pod `priorityClassName` to be configured ([#633]). +- Add `prometheus.io/path|port|scheme` annotations to metrics service ([#641]). ### Fixed @@ -18,6 +19,7 @@ All notable changes to this project will be documented in this file. [#633]: https://github.com/stackabletech/hive-operator/pull/633 [#636]: https://github.com/stackabletech/hive-operator/pull/636 +[#641]: https://github.com/stackabletech/hive-operator/pull/641 ## [25.7.0] - 2025-07-23 diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index e9f0237d..96cdc955 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -103,10 +103,7 @@ use crate::{ listener::{LISTENER_VOLUME_DIR, LISTENER_VOLUME_NAME, build_role_listener}, operations::{graceful_shutdown::add_graceful_shutdown_config, pdb::add_pdbs}, product_logging::extend_role_group_config_map, - service::{ - build_rolegroup_headless_service, build_rolegroup_metrics_service, - rolegroup_headless_service_name, - }, + service::{build_rolegroup_headless_service, build_rolegroup_metrics_service}, }; pub const HIVE_CONTROLLER_NAME: &str = "hivecluster"; @@ -1085,8 +1082,7 @@ fn build_metastore_rolegroup_statefulset( ), ..LabelSelector::default() }, - // TODO: Use method on RoleGroupRef once op-rs is released - service_name: Some(rolegroup_headless_service_name(rolegroup_ref)), + service_name: Some(rolegroup_ref.rolegroup_headless_service_name()), template: pod_template, volume_claim_templates: Some(vec![pvc]), ..StatefulSetSpec::default() diff --git a/rust/operator-binary/src/service.rs b/rust/operator-binary/src/service.rs index 77086ba3..231a589b 100644 --- a/rust/operator-binary/src/service.rs +++ b/rust/operator-binary/src/service.rs @@ -3,7 +3,7 @@ use stackable_operator::{ builder::meta::ObjectMetaBuilder, commons::product_image_selection::ResolvedProductImage, k8s_openapi::api::core::v1::{Service, ServicePort, ServiceSpec}, - kvp::{Label, Labels}, + kvp::{Annotations, Labels}, role_utils::RoleGroupRef, }; @@ -39,8 +39,7 @@ pub fn build_rolegroup_headless_service( let headless_service = Service { metadata: ObjectMetaBuilder::new() .name_and_namespace(hive) - // TODO: Use method on RoleGroupRef once op-rs is released - .name(rolegroup_headless_service_name(rolegroup)) + .name(rolegroup.rolegroup_headless_service_name()) .ownerreference_from_resource(hive, None, Some(true)) .context(ObjectMissingMetadataForOwnerRefSnafu)? .with_recommended_labels(build_recommended_labels( @@ -79,8 +78,7 @@ pub fn build_rolegroup_metrics_service( let metrics_service = Service { metadata: ObjectMetaBuilder::new() .name_and_namespace(hive) - // TODO: Use method on RoleGroupRef once op-rs is released - .name(rolegroup_metrics_service_name(rolegroup)) + .name(rolegroup.rolegroup_metrics_service_name()) .ownerreference_from_resource(hive, None, Some(true)) .context(ObjectMissingMetadataForOwnerRefSnafu)? .with_recommended_labels(build_recommended_labels( @@ -90,7 +88,8 @@ pub fn build_rolegroup_metrics_service( &rolegroup.role_group, )) .context(MetadataBuildSnafu)? - .with_label(Label::try_from(("prometheus.io/scrape", "true")).context(LabelBuildSnafu)?) + .with_labels(prometheus_labels()) + .with_annotations(prometheus_annotations()) .build(), spec: Some(ServiceSpec { // Internal communication does not need to be exposed @@ -110,18 +109,6 @@ pub fn build_rolegroup_metrics_service( Ok(metrics_service) } -/// Headless service for cluster internal purposes only. -// TODO: Move to operator-rs -pub fn rolegroup_headless_service_name(rolegroup: &RoleGroupRef) -> String { - format!("{name}-headless", name = rolegroup.object_name()) -} - -/// Headless metrics service exposes Prometheus endpoint only -// TODO: Move to operator-rs -pub fn rolegroup_metrics_service_name(rolegroup: &RoleGroupRef) -> String { - format!("{name}-metrics", name = rolegroup.object_name()) -} - fn metrics_ports() -> Vec { vec![ServicePort { name: Some(METRICS_PORT_NAME.to_string()), @@ -139,3 +126,23 @@ fn service_ports() -> Vec { ..ServicePort::default() }] } + +/// Common labels for Prometheus +fn prometheus_labels() -> Labels { + Labels::try_from([("prometheus.io/scrape", "true")]).expect("should be a valid label") +} + +/// Common annotations for Prometheus +/// +/// These annotations can be used in a ServiceMonitor. +/// +/// see also +fn prometheus_annotations() -> Annotations { + Annotations::try_from([ + ("prometheus.io/path".to_owned(), "/metrics".to_owned()), + ("prometheus.io/port".to_owned(), METRICS_PORT.to_string()), + ("prometheus.io/scheme".to_owned(), "http".to_owned()), + ("prometheus.io/scrape".to_owned(), "true".to_owned()), + ]) + .expect("should be valid annotations") +}