diff --git a/harmony/Cargo.toml b/harmony/Cargo.toml index 5bc88b1..fcf69cf 100644 --- a/harmony/Cargo.toml +++ b/harmony/Cargo.toml @@ -49,3 +49,4 @@ fqdn = { version = "0.4.6", features = [ "serde", ] } temp-dir = "0.1.14" +dyn-clone = "1.0.19" diff --git a/harmony/src/domain/topology/k8s_anywhere.rs b/harmony/src/domain/topology/k8s_anywhere.rs index 369f030..ef11f36 100644 --- a/harmony/src/domain/topology/k8s_anywhere.rs +++ b/harmony/src/domain/topology/k8s_anywhere.rs @@ -1,4 +1,4 @@ -use std::{io::Error, process::Command, sync::Arc}; +use std::{process::Command, sync::Arc}; use async_trait::async_trait; use inquire::Confirm; diff --git a/harmony/src/domain/topology/mod.rs b/harmony/src/domain/topology/mod.rs index abf317d..faa7fee 100644 --- a/harmony/src/domain/topology/mod.rs +++ b/harmony/src/domain/topology/mod.rs @@ -3,6 +3,7 @@ mod host_binding; mod http; mod k8s_anywhere; mod localhost; +pub mod oberservability; pub mod tenant; pub use k8s_anywhere::*; pub use localhost::*; diff --git a/harmony/src/domain/topology/oberservability/mod.rs b/harmony/src/domain/topology/oberservability/mod.rs new file mode 100644 index 0000000..7f2ac95 --- /dev/null +++ b/harmony/src/domain/topology/oberservability/mod.rs @@ -0,0 +1 @@ +pub mod monitoring; diff --git a/harmony/src/domain/topology/oberservability/monitoring.rs b/harmony/src/domain/topology/oberservability/monitoring.rs new file mode 100644 index 0000000..4603eba --- /dev/null +++ b/harmony/src/domain/topology/oberservability/monitoring.rs @@ -0,0 +1,31 @@ +use async_trait::async_trait; + +use std::fmt::Debug; +use url::Url; + +use crate::interpret::InterpretError; + +use crate::{interpret::Outcome, topology::Topology}; + +/// Represents an entity responsible for collecting and organizing observability data +/// from various telemetry sources +/// A `Monitor` abstracts the logic required to scrape, aggregate, and structure +/// monitoring data, enabling consistent processing regardless of the underlying data source. +#[async_trait] +pub trait Monitor: Debug + Send + Sync { + async fn deploy_monitor( + &self, + topology: &T, + alert_receivers: Vec, + ) -> Result; + + async fn delete_monitor( + &self, + topolgy: &T, + alert_receivers: Vec, + ) -> Result; +} + +pub struct AlertReceiver { + pub receiver_id: String, +} diff --git a/harmony/src/modules/monitoring/discord_alert_manager.rs b/harmony/src/modules/monitoring/discord_alert_manager.rs index a3519e8..7765505 100644 --- a/harmony/src/modules/monitoring/discord_alert_manager.rs +++ b/harmony/src/modules/monitoring/discord_alert_manager.rs @@ -1,30 +1,25 @@ use std::str::FromStr; use non_blank_string_rs::NonBlankString; +use url::Url; use crate::modules::helm::chart::HelmChartScore; -use super::{config::KubePrometheusConfig, monitoring_alerting::AlertChannel}; - -fn get_discord_alert_manager_score(config: &KubePrometheusConfig) -> Option { - let (url, name) = config.alert_channel.iter().find_map(|channel| { - if let AlertChannel::Discord { webhook_url, name } = channel { - Some((webhook_url, name)) - } else { - None - } - })?; - +pub fn discord_alert_manager_score( + webhook_url: Url, + namespace: String, + name: String, +) -> HelmChartScore { let values = format!( r#" environment: - name: "DISCORD_WEBHOOK" - value: "{url}" + value: "{webhook_url}" "#, ); - Some(HelmChartScore { - namespace: Some(NonBlankString::from_str(&config.namespace).unwrap()), + HelmChartScore { + namespace: Some(NonBlankString::from_str(&namespace).unwrap()), release_name: NonBlankString::from_str(&name).unwrap(), chart_name: NonBlankString::from_str( "oci://hub.nationtech.io/library/alertmanager-discord", @@ -36,13 +31,5 @@ environment: create_namespace: true, install_only: true, repository: None, - }) -} - -pub fn discord_alert_manager_score(config: &KubePrometheusConfig) -> HelmChartScore { - if let Some(chart) = get_discord_alert_manager_score(config) { - chart - } else { - panic!("Expected discord alert manager helm chart"); } } diff --git a/harmony/src/modules/monitoring/discord_webhook_sender.rs b/harmony/src/modules/monitoring/discord_webhook_sender.rs new file mode 100644 index 0000000..bad6402 --- /dev/null +++ b/harmony/src/modules/monitoring/discord_webhook_sender.rs @@ -0,0 +1,55 @@ +use async_trait::async_trait; +use serde_json::Value; +use url::Url; + +use crate::{ + interpret::{InterpretError, Outcome}, + topology::K8sAnywhereTopology, +}; + +#[derive(Debug, Clone)] +pub struct DiscordWebhookConfig { + pub webhook_url: Url, + pub name: String, + pub send_resolved_notifications: bool, +} + +pub trait DiscordWebhookReceiver { + fn deploy_discord_webhook_receiver( + &self, + _notification_adapter_id: &str, + ) -> Result; + + fn delete_discord_webhook_receiver( + &self, + _notification_adapter_id: &str, + ) -> Result; +} + +// trait used to generate alert manager config values impl Monitor for KubePrometheus +pub trait AlertManagerConfig { + fn get_alert_manager_config(&self) -> Result; +} + +#[async_trait] +impl AlertManagerConfig for DiscordWebhookConfig { + fn get_alert_manager_config(&self) -> Result { + todo!() + } +} + +#[async_trait] +impl DiscordWebhookReceiver for K8sAnywhereTopology { + fn deploy_discord_webhook_receiver( + &self, + _notification_adapter_id: &str, + ) -> Result { + todo!() + } + fn delete_discord_webhook_receiver( + &self, + _notification_adapter_id: &str, + ) -> Result { + todo!() + } +} diff --git a/harmony/src/modules/monitoring/mod.rs b/harmony/src/modules/monitoring/mod.rs index 914ae07..d3eb288 100644 --- a/harmony/src/modules/monitoring/mod.rs +++ b/harmony/src/modules/monitoring/mod.rs @@ -1,4 +1,5 @@ mod config; mod discord_alert_manager; +pub mod discord_webhook_sender; mod kube_prometheus; pub mod monitoring_alerting; diff --git a/harmony/src/modules/monitoring/monitoring_alerting.rs b/harmony/src/modules/monitoring/monitoring_alerting.rs index 325f9d3..6d2db38 100644 --- a/harmony/src/modules/monitoring/monitoring_alerting.rs +++ b/harmony/src/modules/monitoring/monitoring_alerting.rs @@ -96,28 +96,28 @@ impl MonitoringAlertingStackInterpret { topology: &T, config: &KubePrometheusConfig, ) -> Result { - let mut outcomes = vec![]; + //let mut outcomes = vec![]; - for channel in &self.score.alert_channel { - let outcome = match channel { - AlertChannel::Discord { .. } => { - discord_alert_manager_score(config) - .create_interpret() - .execute(inventory, topology) - .await - } - AlertChannel::Slack { .. } => Ok(Outcome::success( - "No extra configs for slack alerting".to_string(), - )), - AlertChannel::Smpt { .. } => { - todo!() - } - }; - outcomes.push(outcome); - } - for result in outcomes { - result?; - } + //for channel in &self.score.alert_channel { + // let outcome = match channel { + // AlertChannel::Discord { .. } => { + // discord_alert_manager_score(config) + // .create_interpret() + // .execute(inventory, topology) + // .await + // } + // AlertChannel::Slack { .. } => Ok(Outcome::success( + // "No extra configs for slack alerting".to_string(), + // )), + // AlertChannel::Smpt { .. } => { + // todo!() + // } + // }; + // outcomes.push(outcome); + //} + //for result in outcomes { + // result?; + //} Ok(Outcome::success("All alert channels deployed".to_string())) }