From b631e8ccbbe97220e5339c271f9d0ada56121375 Mon Sep 17 00:00:00 2001 From: Willem Date: Fri, 30 May 2025 13:21:38 -0400 Subject: [PATCH] feat: Initial setup for monitoring and alerting --- harmony/Cargo.toml | 1 + harmony/src/domain/topology/k8s_anywhere.rs | 24 ++++++-- harmony/src/domain/topology/mod.rs | 1 + .../domain/topology/oberservability/mod.rs | 16 +++++ .../topology/oberservability/monitoring.rs | 60 +++++++++++++++++++ .../notification_adapter_deployer.rs | 12 ++++ 6 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 harmony/src/domain/topology/oberservability/mod.rs create mode 100644 harmony/src/domain/topology/oberservability/monitoring.rs create mode 100644 harmony/src/domain/topology/oberservability/notification_adapter_deployer.rs 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..5df2bc8 100644 --- a/harmony/src/domain/topology/k8s_anywhere.rs +++ b/harmony/src/domain/topology/k8s_anywhere.rs @@ -15,11 +15,9 @@ use crate::{ }; use super::{ - HelmCommand, K8sclient, Topology, - k8s::K8sClient, - tenant::{ - ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy, k8s::K8sTenantManager, - }, + k8s::K8sClient, oberservability::notification_adapter_deployer::NotificationAdapterDeployer, tenant::{ + k8s::K8sTenantManager, ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy + }, HelmCommand, K8sclient, Topology }; struct K8sState { @@ -263,3 +261,19 @@ impl TenantManager for K8sAnywhereTopology { .await } } + +#[async_trait] +impl NotificationAdapterDeployer for K8sAnywhereTopology { + fn deploy_notification_adapter( + &self, + _notification_adapter_id: &str, + ) -> Result { + todo!() + } + fn remove_notification_adapter( + &self, + _notification_adapter_id: &str, + ) -> Result { + todo!() + } +} diff --git a/harmony/src/domain/topology/mod.rs b/harmony/src/domain/topology/mod.rs index abf317d..2dcd501 100644 --- a/harmony/src/domain/topology/mod.rs +++ b/harmony/src/domain/topology/mod.rs @@ -4,6 +4,7 @@ mod http; mod k8s_anywhere; mod localhost; pub mod tenant; +pub mod oberservability; pub use k8s_anywhere::*; pub use localhost::*; pub mod k8s; diff --git a/harmony/src/domain/topology/oberservability/mod.rs b/harmony/src/domain/topology/oberservability/mod.rs new file mode 100644 index 0000000..6ab1b2c --- /dev/null +++ b/harmony/src/domain/topology/oberservability/mod.rs @@ -0,0 +1,16 @@ +use monitoring::AlertChannelConfig; + +pub mod monitoring; +pub mod notification_adapter_deployer; + +pub enum MonitoringBackendType { + KubePrometheus, +} + +pub struct MonitorConfig { + pub backend: MonitoringBackendType, + pub alert_channels: Vec>, +} + + + diff --git a/harmony/src/domain/topology/oberservability/monitoring.rs b/harmony/src/domain/topology/oberservability/monitoring.rs new file mode 100644 index 0000000..8ad88f6 --- /dev/null +++ b/harmony/src/domain/topology/oberservability/monitoring.rs @@ -0,0 +1,60 @@ +use async_trait::async_trait; + +use std::fmt::Debug; +use dyn_clone::DynClone; +use serde_json::Value; + +use crate::interpret::InterpretError; + +use crate::{ + interpret::Outcome, + topology::Topology, +}; + +use super::notification_adapter_deployer::NotificationAdapterDeployer; +use super::{MonitorConfig, MonitoringBackendType}; + +#[async_trait] +pub trait Monitor { + async fn provision_monitor( + &self, + topology: &T, + monitor_config: &MonitorConfig, + ) -> Result; + + async fn delete_monitor( + &self, + topolgy: &T, + monitor_config: &MonitorConfig, + ) -> Result; + + async fn configure_alerting( + &self, + topology: &T, + monitor_config: &MonitorConfig, + ) -> Result; + + async fn ensure_alert_channel_dependencies( + &self, + topology: &T, + monitor_config: &MonitorConfig, + ) -> Result { + for channel in &monitor_config.alert_channels { + if let Some(notification_adapter_id) = + channel.requires_external_alert_channel_adapter(&monitor_config.backend) + { + topology.deploy_notification_adapter( + ¬ification_adapter_id.as_ref(), + )?; + } + + } + Ok(Outcome::success(format!("deployed alert channels {:?}", &monitor_config.alert_channels))) + } +} + +pub trait AlertChannelConfig: Debug + DynClone + Send + Sync { + fn build_backend_integration_config(&self, backend: &MonitoringBackendType) -> Result; + fn requires_external_alert_channel_adapter(&self, backend: &MonitoringBackendType) -> Option; +} + diff --git a/harmony/src/domain/topology/oberservability/notification_adapter_deployer.rs b/harmony/src/domain/topology/oberservability/notification_adapter_deployer.rs new file mode 100644 index 0000000..02786ae --- /dev/null +++ b/harmony/src/domain/topology/oberservability/notification_adapter_deployer.rs @@ -0,0 +1,12 @@ +use crate::interpret::{InterpretError, Outcome}; + +pub trait NotificationAdapterDeployer { + fn deploy_notification_adapter( + &self, + notification_adapter_id: &str, + ) -> Result; + fn remove_notification_adapter( + &self, + notication_adapter_id: &str, + ) -> Result; +}