harmony/harmony/src/modules/monitoring/monitoring_alerting.rs
2025-06-06 16:41:17 -04:00

107 lines
2.9 KiB
Rust

use async_trait::async_trait;
use serde::{Serialize, Serializer, ser::SerializeStruct};
use std::{fmt::Debug, sync::Arc};
use crate::{
data::{Id, Version},
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
inventory::Inventory,
score::Score,
topology::{
HelmCommand, Topology,
oberservability::monitoring::{AlertChannelConfig, MonitorConfig},
},
};
use super::kube_prometheus::{
config::KubePrometheusConfig, kube_prometheus_monitor::KubePrometheusMonitor,
};
#[derive(Debug, Clone)]
pub struct MonitoringAlertingScore<T: Topology> {
pub monitor_config: Arc<dyn MonitorConfig<T>>,
pub alert_channel_configs: Vec<Arc<dyn AlertChannelConfig>>,
pub namespace: Option<String>,
}
impl<T: Topology> MonitoringAlertingScore<T> {
pub fn default() -> Self {
Self {
monitor_config: Arc::new(KubePrometheusMonitor {
kube_prometheus_config: KubePrometheusConfig::new(),
}),
alert_channel_configs: Vec::new(),
namespace: Some("monitoring".to_string()),
}
}
}
impl<T: Topology + HelmCommand + Debug + Clone + 'static> Score<T> for MonitoringAlertingScore<T> {
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
Box::new(MonitoringAlertingInterpret {
score: self.clone(),
})
}
fn name(&self) -> String {
todo!()
}
}
#[derive(Debug)]
struct MonitoringAlertingInterpret<T: Topology> {
score: MonitoringAlertingScore<T>,
}
#[async_trait]
impl<T: Topology + HelmCommand + Debug> Interpret<T> for MonitoringAlertingInterpret<T> {
async fn execute(
&self,
_inventory: &Inventory,
topology: &T,
) -> Result<Outcome, InterpretError> {
let monitor = self.score.monitor_config.build_monitor();
let mut alert_channels = Vec::new();
for config in &self.score.alert_channel_configs {
alert_channels.push(config.build_alert_channel());
}
monitor.deploy_monitor(topology, alert_channels).await
}
fn get_name(&self) -> InterpretName {
todo!()
}
fn get_version(&self) -> Version {
todo!()
}
fn get_status(&self) -> InterpretStatus {
todo!()
}
fn get_children(&self) -> Vec<Id> {
todo!()
}
}
impl<T: Topology> Serialize for MonitoringAlertingScore<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("MonitoringAlertingScore", 3)?;
// For now, just serialize basic info
state.serialize_field("monitor_type", "monitoring_system")?;
let channel_count = self.alert_channel_configs.len();
state.serialize_field("alert_channel_count", &channel_count)?;
state.serialize_field("namespace", &self.namespace)?;
state.end()
}
}