wip: monitoring impl

This commit is contained in:
Willem 2025-06-19 12:32:46 -04:00 committed by tahahawa
parent ec1df0413a
commit 50e38fed0a
8 changed files with 69 additions and 36 deletions

View File

@ -9,3 +9,4 @@ license.workspace = true
harmony = { version = "0.1.0", path = "../../harmony" }
harmony_cli = { version = "0.1.0", path = "../../harmony_cli" }
tokio.workspace = true
url.workspace = true

View File

@ -1,12 +1,16 @@
use harmony::{
inventory::Inventory, maestro::Maestro,
modules::monitoring::kube_prometheus::helm_prometheus_alert_score::HelmPrometheusAlertingScore,
topology::K8sAnywhereTopology,
modules::monitoring::{alert_channel::discord_alert_channel::DiscordWebhook, kube_prometheus::helm_prometheus_alert_score::HelmPrometheusAlertingScore},
topology::{K8sAnywhereTopology, Url},
};
#[tokio::main]
async fn main() {
let alerting_score = HelmPrometheusAlertingScore { receivers: vec![] };
let discord_receiver = DiscordWebhook {
name: "test-discord".to_string(),
url: Url::Url(url::Url::parse("https://discord.i.dont.exist.com").unwrap()),
};
let alerting_score = HelmPrometheusAlertingScore { receivers: vec![Box::new(discord_receiver)] };
let mut maestro = Maestro::<K8sAnywhereTopology>::initialize(
Inventory::autoload(),
K8sAnywhereTopology::from_env(),

View File

@ -48,6 +48,7 @@ impl<S: AlertSender, T: Topology> Interpret<T> for AlertingInterpret<S> {
#[async_trait]
pub trait AlertReceiver<S: AlertSender>: std::fmt::Debug + Send + Sync {
async fn install(&self, sender: &S) -> Result<(), InterpretError>;
fn clone_box(&self) -> Box<dyn AlertReceiver<S>>;
}
#[async_trait]

View File

@ -10,7 +10,7 @@ use crate::{
topology::{Url, oberservability::monitoring::AlertReceiver},
};
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct DiscordWebhook {
pub name: String,
pub url: Url,
@ -19,16 +19,28 @@ pub struct DiscordWebhook {
#[async_trait]
impl AlertReceiver<Prometheus> for DiscordWebhook {
async fn install(&self, sender: &Prometheus) -> Result<(), InterpretError> {
sender.install_receiver(PrometheusReceiver {}).await
sender.install_receiver(self).await
}
fn clone_box(&self) -> Box<dyn AlertReceiver<Prometheus>> {
Box::new(self.clone())
}
}
#[async_trait]
impl PrometheusReceiver for DiscordWebhook {
//TODO not return a tuple
async fn receiver_config(&self) -> (Option<Value>, Value, Value) {
(self.alert_channel_global_config().await, self.alert_channel_receiver().await, self.alert_channel_route().await)
}
}
#[async_trait]
impl AlertChannelConfig for DiscordWebhook {
fn alert_channel_global_config(&self) -> Option<serde_yaml::Value> {
async fn alert_channel_global_config(&self) -> Option<serde_yaml::Value> {
None
}
fn alert_channel_route(&self) -> serde_yaml::Value {
async fn alert_channel_route(&self) -> serde_yaml::Value {
let mut route = Mapping::new();
route.insert(
Value::String("receiver".to_string()),
@ -42,7 +54,7 @@ impl AlertChannelConfig for DiscordWebhook {
Value::Mapping(route)
}
fn alert_channel_receiver(&self) -> serde_yaml::Value {
async fn alert_channel_receiver(&self) -> serde_yaml::Value {
let mut receiver = Mapping::new();
receiver.insert(
Value::String("name".to_string()),
@ -66,8 +78,6 @@ impl AlertChannelConfig for DiscordWebhook {
#[cfg(test)]
mod tests {
use log::debug;
use super::*;
#[test]
@ -77,18 +87,14 @@ mod tests {
url: Url::Url(url::Url::parse("https://discord.i.dont.exist.com").unwrap()),
};
let discord_receiver_global =
serde_yaml::to_string(&discord_receiver.alert_channel_global_config()).unwrap();
println!("global receiver \n{:#}", discord_receiver_global);
let discord_receiver_global_yaml = "".to_string();
let discord_receiver_receiver =
serde_yaml::to_string(&discord_receiver.alert_channel_receiver()).unwrap();
println!("receiver \n{:#}", discord_receiver_receiver);
let discord_receiver_receiver_yaml = r#"name: test-discord
discord_configs:
- webhook_url: https://discord.i.dont.exist.com/"#
.to_string();
- webhook_url: https://discord.i.dont.exist.com/
"#
.to_string();
let discord_receiver_route =
serde_yaml::to_string(&discord_receiver.alert_channel_route()).unwrap();
@ -96,8 +102,9 @@ discord_configs:
let discord_receiver_route_yaml = r#"receiver: test-discord
matchers:
- alertname!=Watchdog
continue: true"#
.to_string();
continue: true
"#
.to_string();
assert_eq!(discord_receiver_receiver, discord_receiver_receiver_yaml);
assert_eq!(discord_receiver_route, discord_receiver_route_yaml);

View File

@ -1,4 +1,7 @@
use serde::Serialize;
use serde_yaml::Value;
use crate::modules::monitoring::kube_prometheus::prometheus::PrometheusReceiver;
#[derive(Debug, Clone, Serialize)]
pub struct KubePrometheusConfig {
@ -19,6 +22,7 @@ pub struct KubePrometheusConfig {
pub kube_proxy: bool,
pub kube_state_metrics: bool,
pub prometheus_operator: bool,
pub alert_receiver_configs: Vec<Value>,
}
impl KubePrometheusConfig {
pub fn new() -> Self {
@ -40,6 +44,7 @@ impl KubePrometheusConfig {
prometheus_operator: true,
core_dns: false,
kube_scheduler: false,
alert_receiver_configs: vec![],
}
}
}

View File

@ -1,7 +1,6 @@
use serde::Serialize;
use crate::{
modules::monitoring::alert_channel::discord_alert_channel::DiscordWebhook,
score::Score,
topology::{
HelmCommand, Topology,
@ -9,7 +8,7 @@ use crate::{
},
};
use super::prometheus::Prometheus;
use super::{helm::config::KubePrometheusConfig, prometheus::Prometheus};
#[derive(Clone, Debug, Serialize)]
pub struct HelmPrometheusAlertingScore {
@ -19,12 +18,10 @@ pub struct HelmPrometheusAlertingScore {
impl<T: Topology + HelmCommand> Score<T> for HelmPrometheusAlertingScore {
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
Box::new(AlertingInterpret {
sender: Prometheus {},
sender: Prometheus { config: KubePrometheusConfig::new() },
receivers: self.receivers.clone(),
})
}
fn name(&self) -> String {
} fn name(&self) -> String {
"HelmPrometheusAlertingScore".to_string()
}
}
@ -37,8 +34,9 @@ impl Serialize for Box<dyn AlertReceiver<Prometheus>> {
todo!()
}
}
impl Clone for Box<dyn AlertReceiver<Prometheus>> {
fn clone(&self) -> Self {
todo!()
self.clone_box()
}
}

View File

@ -1,10 +1,14 @@
use async_trait::async_trait;
use log::debug;
use serde_yaml::Value;
use crate::{
interpret::InterpretError,
topology::{installable::Installable, oberservability::monitoring::AlertSender},
};
use super::helm::config::KubePrometheusConfig;
impl AlertSender for Prometheus {}
#[async_trait]
@ -13,22 +17,33 @@ impl Installable for Prometheus {
todo!()
}
}
#[derive(Debug)]
pub struct Prometheus;
pub struct Prometheus{
pub config: KubePrometheusConfig,
}
impl Prometheus {
pub async fn install_receiver(
&self,
prometheus_receiver: PrometheusReceiver,
prometheus_receiver: &dyn PrometheusReceiver,
) -> Result<(), InterpretError> {
debug!("adding alert receiver to prometheus config: {:#?}", prometheus_receiver.receiver_config());
self.config.alert_receiver_configs.push(prometheus_receiver.receiver_config());
todo!()
}
}
pub struct PrometheusReceiver {}
impl PrometheusReceiver {
fn get_prometheus_receiver_config(&self) {}
#[async_trait]
pub trait PrometheusReceiver: Send + Sync + std::fmt::Debug{
async fn receiver_config(&self) -> (Option<Value>, Value, Value);
//this probably needs to be a type
//that
//represents
//a
//promtheusreceiver
}
pub struct AlertChannelGlobalConfig {}

View File

@ -1,7 +1,9 @@
use async_trait::async_trait;
use serde_yaml::Value;
#[async_trait]
pub trait AlertChannelConfig {
fn alert_channel_global_config(&self) -> Option<Value>;
fn alert_channel_route(&self) -> Value;
fn alert_channel_receiver(&self) -> Value;
async fn alert_channel_global_config(&self) -> Option<Value>;
async fn alert_channel_route(&self) -> Value;
async fn alert_channel_receiver(&self) -> Value;
}