diff --git a/harmony/src/domain/topology/k8s_anywhere.rs b/harmony/src/domain/topology/k8s_anywhere.rs index 54472b9..8c12adc 100644 --- a/harmony/src/domain/topology/k8s_anywhere.rs +++ b/harmony/src/domain/topology/k8s_anywhere.rs @@ -5,6 +5,7 @@ use inquire::Confirm; use log::{info, warn}; use tokio::sync::{Mutex, OnceCell}; +use crate::score::Score; use crate::{ executors::ExecutorError, interpret::{InterpretError, Outcome}, @@ -17,7 +18,7 @@ use crate::{ use super::{ HelmCommand, K8sclient, Topology, k8s::K8sClient, - oberservability::monitoring::AlertReceiver, + oberservability::monitoring::{AlertReceiver, AlertReceiverProvision}, tenant::{ ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy, k8s::K8sTenantManager, }, @@ -67,6 +68,25 @@ impl K8sAnywhereTopology { } } + pub async fn initialize_alert_receiver( + &self, + config: &C, + inventory: &Inventory, + ) -> Result + where + Self: Topology + HelmCommand, + C: AlertReceiverProvision + Send + Sync, + { + let score = config.get_deployment_score(); + let interpret = score.create_interpret(); + interpret.execute(inventory, self).await?; + + Ok(AlertReceiver { + receiver_id: config.alert_receiver_id(), + receiver_installed: true, + }) + } + fn is_helm_available(&self) -> Result<(), String> { let version_result = Command::new("helm") .arg("version") diff --git a/harmony/src/domain/topology/oberservability/monitoring.rs b/harmony/src/domain/topology/oberservability/monitoring.rs index e42acb8..8bd3691 100644 --- a/harmony/src/domain/topology/oberservability/monitoring.rs +++ b/harmony/src/domain/topology/oberservability/monitoring.rs @@ -7,10 +7,12 @@ use std::fmt::Debug; use crate::interpret::InterpretError; use crate::inventory::Inventory; +use crate::score::Score; +use crate::topology::HelmCommand; use crate::{interpret::Outcome, topology::Topology}; /// Represents an entity responsible for collecting and organizing observability data -/// from various telemetry sources +/// from various telemetry sources such as Prometheus or Datadog /// A `Monitor` abstracts the logic required to scrape, aggregate, and structure /// monitoring data, enabling consistent processing regardless of the underlying data source. #[async_trait] @@ -44,3 +46,10 @@ pub struct AlertReceiver { pub receiver_id: String, pub receiver_installed: bool, } + +/// Provides the ability to turn an alert config into an executable score +/// for the topology +pub trait AlertReceiverProvision { + fn get_deployment_score(&self) -> Box>; + fn alert_receiver_id(&self) -> String; +} diff --git a/harmony/src/modules/monitoring/discord_webhook_sender.rs b/harmony/src/modules/monitoring/discord_webhook_sender.rs index 70d6084..6fd41a2 100644 --- a/harmony/src/modules/monitoring/discord_webhook_sender.rs +++ b/harmony/src/modules/monitoring/discord_webhook_sender.rs @@ -6,13 +6,12 @@ use tokio::sync::OnceCell; use url::Url; use crate::{ - data::{Id, Version}, - interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, + interpret::{Interpret, InterpretError, Outcome}, inventory::Inventory, score::Score, topology::{ HelmCommand, K8sAnywhereTopology, Topology, - oberservability::monitoring::{AlertReceiver, EnsureAlertReceiver}, + oberservability::monitoring::{AlertReceiverProvision, EnsureAlertReceiver}, }, }; @@ -36,6 +35,18 @@ impl EnsureAlertReceiver for DiscordWeb } } +impl AlertReceiverProvision for DiscordWebhookConfig { + fn get_deployment_score(&self) -> Box> { + Box::new(DiscordWebhookReceiverScore { + config: self.clone(), + }) + } + + fn alert_receiver_id(&self) -> String { + self.name.clone() + } +} + #[async_trait] pub trait DiscordWebhookReceiver { async fn ensure_discord_webhook_receiver( @@ -71,9 +82,7 @@ impl DiscordWebhookReceiver for K8sAnywhereTopology { } let final_state = cell - .get_or_try_init(|| async { - initialize_discord_webhook_receiver(config.clone(), inventory, self).await - }) + .get_or_try_init(|| async { self.initialize_alert_receiver(&config, inventory).await }) .await?; Ok(Outcome::success(format!( @@ -90,28 +99,6 @@ impl DiscordWebhookReceiver for K8sAnywhereTopology { } } -async fn initialize_discord_webhook_receiver( - conf: DiscordWebhookConfig, - inventory: &Inventory, - topology: &K8sAnywhereTopology, -) -> Result { - println!( - "Attempting to initialize Discord adapter for: {}", - conf.name - ); - let score = DiscordWebhookReceiverScore { - config: conf.clone(), - }; - let interpret = score.create_interpret(); - - interpret.execute(&inventory, topology).await?; - - Ok(AlertReceiver { - receiver_id: conf.name, - receiver_installed: true, - }) -} - pub trait AlertManagerConfig { fn get_alert_manager_config(&self) -> Result; }