added a monitoring stack that works with openshift/okd. Okd needs to use the cluster observability operator in order to deploy namespaced prometheuses and alertmanagers #134

Merged
letian merged 5 commits from feat/monitoring_cluster_observability into master 2025-09-08 14:22:06 +00:00
6 changed files with 103 additions and 64 deletions
Showing only changes of commit 24401b95a9 - Show all commits

View File

@ -65,6 +65,10 @@ impl AlertReceiver<RHOBObservability> for DiscordWebhook {
},
spec,
};
debug!(
"alertmanager_configs yaml:\n{:#?}",
serde_yaml::to_string(&alertmanager_configs)
);
debug!(
"alert manager configs: \n{:#?}",
alertmanager_configs.clone()

View File

@ -16,5 +16,6 @@ pub mod rhob_monitoring_stack;
pub mod rhob_prometheus_rules;
pub mod rhob_prometheuses;
pub mod rhob_role;
pub mod rhob_service_monitor;
pub mod role;
pub mod service_monitor;

View File

@ -12,7 +12,7 @@ use crate::topology::{
#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[kube(
group = "monitoring.rhobs",
version = "v1alpha",
version = "v1alpha1",
kind = "AlertmanagerConfig",
plural = "alertmanagerconfigs",
namespaced

View File

@ -8,7 +8,7 @@ use crate::modules::monitoring::alert_rule::prometheus_alert_rule::PrometheusAle
#[derive(CustomResource, Debug, Serialize, Deserialize, Clone, JsonSchema)]
#[kube(
group = "monitoring.rhobs.com",
group = "monitoring.rhobs",
version = "v1",
kind = "PrometheusRule",
plural = "prometheusrules",

View File

@ -0,0 +1,87 @@
use std::collections::HashMap;
use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::modules::monitoring::kube_prometheus::types::{
HTTPScheme, MatchExpression, NamespaceSelector, Operator, Selector,
ServiceMonitor as KubeServiceMonitor, ServiceMonitorEndpoint,
};
/// This is the top-level struct for the ServiceMonitor Custom Resource.
/// The `#[derive(CustomResource)]` macro handles all the boilerplate for you,
/// including the `impl Resource`.
#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[kube(
group = "monitoring.rhobs",
version = "v1",
kind = "ServiceMonitor",
plural = "servicemonitors",
namespaced
)]
#[serde(rename_all = "camelCase")]
pub struct ServiceMonitorSpec {
/// A label selector to select services to monitor.
pub selector: Selector,
/// A list of endpoints on the selected services to be monitored.
pub endpoints: Vec<ServiceMonitorEndpoint>,
/// Selector to select which namespaces the Kubernetes Endpoints objects
/// are discovered from.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub namespace_selector: Option<NamespaceSelector>,
/// The label to use to retrieve the job name from.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub job_label: Option<String>,
/// Pod-based target labels to transfer from the Kubernetes Pod onto the target.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub pod_target_labels: Vec<String>,
/// TargetLabels transfers labels on the Kubernetes Service object to the target.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub target_labels: Vec<String>,
}
impl Default for ServiceMonitorSpec {
fn default() -> Self {
let labels = HashMap::new();
Self {
selector: Selector {
match_labels: { labels },
match_expressions: vec![MatchExpression {
key: "app.kubernetes.io/name".into(),
operator: Operator::Exists,
values: vec![],
}],
},
endpoints: vec![ServiceMonitorEndpoint {
port: Some("http".to_string()),
path: Some("/metrics".into()),
interval: Some("30s".into()),
scheme: Some(HTTPScheme::HTTP),
..Default::default()
}],
namespace_selector: None, // only the same namespace
job_label: Some("app".into()),
pod_target_labels: vec![],
target_labels: vec![],
}
}
}
impl From<KubeServiceMonitor> for ServiceMonitorSpec {
fn from(value: KubeServiceMonitor) -> Self {
Self {
selector: value.selector,
endpoints: value.endpoints,
namespace_selector: value.namespace_selector,
job_label: value.job_label,
pod_target_labels: value.pod_target_labels,
target_labels: value.target_labels,
}
}
}

View File

@ -23,13 +23,9 @@ use crate::modules::monitoring::kube_prometheus::crd::rhob_monitoring_stack::{
use crate::modules::monitoring::kube_prometheus::crd::rhob_prometheus_rules::{
PrometheusRule, PrometheusRuleSpec, RuleGroup,
};
use crate::modules::monitoring::kube_prometheus::crd::rhob_prometheuses::{
AlertmanagerEndpoints, LabelSelector, Prometheus, PrometheusSpec, PrometheusSpecAlerting,
};
use crate::modules::monitoring::kube_prometheus::crd::role::{
build_prom_role, build_prom_rolebinding, build_prom_service_account,
};
use crate::modules::monitoring::kube_prometheus::crd::service_monitor::{
use crate::modules::monitoring::kube_prometheus::crd::rhob_prometheuses::LabelSelector;
use crate::modules::monitoring::kube_prometheus::crd::rhob_service_monitor::{
ServiceMonitor, ServiceMonitorSpec,
};
use crate::score::Score;
@ -90,12 +86,12 @@ impl<T: Topology + K8sclient + PrometheusApplicationMonitoring<RHOBObservability
self.ensure_grafana_operator().await?;
self.install_prometheus(&client).await?;
self.install_client_kube_metrics().await?;
// self.install_grafana(&client).await?;
// self.install_receivers(&self.sender, &self.receivers)
// .await?;
// self.install_rules(&self.prometheus_rules, &client).await?;
// self.install_monitors(self.service_monitors.clone(), &client)
// .await?;
self.install_grafana(&client).await?;
self.install_receivers(&self.sender, &self.receivers)
.await?;
self.install_rules(&self.prometheus_rules, &client).await?;
self.install_monitors(self.service_monitors.clone(), &client)
.await?;
Ok(Outcome::success(
"K8s monitoring components installed".to_string(),
))
@ -275,55 +271,6 @@ impl RHOBAlertingInterpret {
.await
.map_err(|e| InterpretError::new(e.to_string()))?;
info!("installed rhob monitoring stack",);
// let prom = Prometheus {
// metadata: ObjectMeta {
// name: Some(self.sender.namespace.clone()),
// labels: Some(std::collections::BTreeMap::from([
// ("alertmanagerConfig".to_string(), "enabled".to_string()),
// ("client".to_string(), "prometheus".to_string()),
// ])),
// namespace: Some(self.sender.namespace.clone()),
// ..Default::default()
// },
// spec: prom_spec,
// };
// client
// .apply(&role, Some(&self.sender.namespace.clone()))
// .await
// .map_err(|e| InterpretError::new(e.to_string()))?;
// info!(
// "installed prometheus role: {:#?} in ns {:#?}",
// role.metadata.name.unwrap(),
// role.metadata.namespace.unwrap()
// );
// client
// .apply(&rolebinding, Some(&self.sender.namespace.clone()))
// .await
// .map_err(|e| InterpretError::new(e.to_string()))?;
// info!(
// "installed prometheus rolebinding: {:#?} in ns {:#?}",
// rolebinding.metadata.name.unwrap(),
// rolebinding.metadata.namespace.unwrap()
// );
// client
// .apply(&sa, Some(&self.sender.namespace.clone()))
// .await
// .map_err(|e| InterpretError::new(e.to_string()))?;
// info!(
// "installed prometheus service account: {:#?} in ns {:#?}",
// sa.metadata.name.unwrap(),
// sa.metadata.namespace.unwrap()
// );
// client
// .apply(&prom, Some(&self.sender.namespace.clone()))
// .await
// .map_err(|e| InterpretError::new(e.to_string()))?;
// info!(
// "installed prometheus: {:#?} in ns {:#?}",
// &prom.metadata.name.clone().unwrap(),
// &prom.metadata.namespace.clone().unwrap()
// );
//
Ok(Outcome::success(format!(
"successfully deployed rhob-prometheus {:#?}",
stack