diff --git a/examples/rust/src/main.rs b/examples/rust/src/main.rs index 917dee2..4227683 100644 --- a/examples/rust/src/main.rs +++ b/examples/rust/src/main.rs @@ -43,9 +43,9 @@ async fn main() { let app = ApplicationScore { features: vec![ - // Box::new(ContinuousDelivery { - // application: application.clone(), - // }), + Box::new(ContinuousDelivery { + application: application.clone(), + }), Box::new(Monitoring { application: application.clone(), alert_receiver: vec![Box::new(discord_receiver), Box::new(webhook_receiver)], diff --git a/harmony/src/domain/topology/k8s_anywhere.rs b/harmony/src/domain/topology/k8s_anywhere.rs index 546ca78..b072373 100644 --- a/harmony/src/domain/topology/k8s_anywhere.rs +++ b/harmony/src/domain/topology/k8s_anywhere.rs @@ -14,7 +14,7 @@ use crate::{ modules::{ k3d::K3DInstallationScore, monitoring::kube_prometheus::crd::{ - crd_alertmanager_config::{CRDAlertManagerReceiver, CRDPrometheus}, + crd_alertmanager_config::CRDPrometheus, prometheus_operator::prometheus_operator_helm_chart_score, }, prometheus::{ @@ -127,10 +127,7 @@ impl K8sAnywhereTopology { ) -> K8sPrometheusCRDAlertingScore { K8sPrometheusCRDAlertingScore { sender, - receivers: self - .configure_receivers(receivers) - .await - .unwrap_or_else(Vec::new), + receivers: receivers.unwrap_or_else(Vec::new), service_monitors: vec![], prometheus_rules: vec![], } @@ -308,17 +305,6 @@ impl K8sAnywhereTopology { "prometheus operator present in cluster".to_string(), )) } - - async fn configure_receivers( - &self, - receivers: Option>>>, - ) -> Option>> { - let Some(receivers) = receivers else { - return None; - }; - - todo!() - } } #[derive(Clone, Debug)] diff --git a/harmony/src/modules/application/features/monitoring.rs b/harmony/src/modules/application/features/monitoring.rs index 85b4e27..4c7632c 100644 --- a/harmony/src/modules/application/features/monitoring.rs +++ b/harmony/src/modules/application/features/monitoring.rs @@ -2,9 +2,7 @@ use std::sync::Arc; use crate::modules::application::{Application, ApplicationFeature}; use crate::modules::monitoring::application_monitoring::application_monitoring_score::ApplicationMonitoringScore; -use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::{ - AlertmanagerConfig, AlertmanagerConfigSpec, CRDPrometheus, -}; +use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::CRDPrometheus; use crate::{ inventory::Inventory, @@ -20,9 +18,7 @@ use crate::{ }; use async_trait::async_trait; use base64::{Engine as _, engine::general_purpose}; -use kube::api::ObjectMeta; use log::{debug, info}; -use serde_json::json; #[derive(Debug, Clone)] pub struct Monitoring { @@ -51,12 +47,6 @@ impl< let mut alerting_score = ApplicationMonitoringScore { sender: CRDPrometheus { - alertmanager_configs: AlertmanagerConfig { - metadata: ObjectMeta { - ..Default::default() - }, - spec: AlertmanagerConfigSpec { data: json! {""} }, - }, namespace: namespace.clone(), client: topology.k8s_client().await.unwrap(), }, diff --git a/harmony/src/modules/monitoring/alert_channel/discord_alert_channel.rs b/harmony/src/modules/monitoring/alert_channel/discord_alert_channel.rs index 0a83d26..1d704a4 100644 --- a/harmony/src/modules/monitoring/alert_channel/discord_alert_channel.rs +++ b/harmony/src/modules/monitoring/alert_channel/discord_alert_channel.rs @@ -1,20 +1,16 @@ use std::any::Any; use std::collections::BTreeMap; -use std::sync::Arc; use async_trait::async_trait; use k8s_openapi::api::core::v1::Secret; use kube::api::ObjectMeta; -use kube::{Api, Client, ResourceExt}; -use log::{debug, info}; use serde::Serialize; use serde_json::json; use serde_yaml::{Mapping, Value}; use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::{ - AlertmanagerConfig, AlertmanagerConfigSpec, CRDAlertManagerReceiver, CRDPrometheus, + AlertmanagerConfig, AlertmanagerConfigSpec, CRDPrometheus, }; -use crate::topology::k8s::K8sClient; use crate::{ interpret::{InterpretError, Outcome}, modules::monitoring::{ @@ -34,12 +30,9 @@ pub struct DiscordWebhook { } #[async_trait] -impl CRDAlertManagerReceiver for DiscordWebhook { - fn name(&self) -> String { - self.name.clone() - } - - async fn configure_receiver(&self, client: &Arc, ns: String) -> AlertmanagerConfig { +impl AlertReceiver for DiscordWebhook { + async fn install(&self, sender: &CRDPrometheus) -> Result { + let ns = sender.namespace.clone(); let secret_name = format!("{}-secret", self.name.clone()); let webhook_key = format!("{}", self.url.clone()); @@ -56,7 +49,7 @@ impl CRDAlertManagerReceiver for DiscordWebhook { ..Default::default() }; - let _ = client.apply(&secret, Some(&ns)).await; + let _ = sender.client.apply(&secret, Some(&ns)).await; let spec = AlertmanagerConfigSpec { data: json!({ @@ -81,7 +74,7 @@ impl CRDAlertManagerReceiver for DiscordWebhook { }), }; - AlertmanagerConfig { + let alertmanager_configs = AlertmanagerConfig { metadata: ObjectMeta { name: Some(self.name.clone()), labels: Some(std::collections::BTreeMap::from([( @@ -92,20 +85,11 @@ impl CRDAlertManagerReceiver for DiscordWebhook { ..Default::default() }, spec, - } - } + }; - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } -} - -#[async_trait] -impl AlertReceiver for DiscordWebhook { - async fn install(&self, sender: &CRDPrometheus) -> Result { sender .client - .apply(&sender.alertmanager_configs, Some(&sender.namespace)) + .apply(&alertmanager_configs, Some(&sender.namespace)) .await?; Ok(Outcome::success(format!( "installed crd-alertmanagerconfigs for {}", diff --git a/harmony/src/modules/monitoring/alert_channel/webhook_receiver.rs b/harmony/src/modules/monitoring/alert_channel/webhook_receiver.rs index a370d8e..9a9d5d2 100644 --- a/harmony/src/modules/monitoring/alert_channel/webhook_receiver.rs +++ b/harmony/src/modules/monitoring/alert_channel/webhook_receiver.rs @@ -1,7 +1,6 @@ -use std::{any::Any, sync::Arc}; +use std::any::Any; use async_trait::async_trait; -use k8s_openapi::api::core::v1::Secret; use kube::api::ObjectMeta; use log::debug; use serde::Serialize; @@ -13,14 +12,14 @@ use crate::{ modules::monitoring::{ kube_prometheus::{ crd::crd_alertmanager_config::{ - AlertmanagerConfig, AlertmanagerConfigSpec, CRDAlertManagerReceiver, CRDPrometheus, + AlertmanagerConfig, AlertmanagerConfigSpec, CRDPrometheus, }, prometheus::{KubePrometheus, KubePrometheusReceiver}, types::{AlertChannelConfig, AlertManagerChannelConfig}, }, prometheus::prometheus::{Prometheus, PrometheusReceiver}, }, - topology::{Url, k8s::K8sClient, oberservability::monitoring::AlertReceiver}, + topology::{Url, oberservability::monitoring::AlertReceiver}, }; #[derive(Debug, Clone, Serialize)] @@ -30,12 +29,8 @@ pub struct WebhookReceiver { } #[async_trait] -impl CRDAlertManagerReceiver for WebhookReceiver { - fn name(&self) -> String { - self.name.clone() - } - - async fn configure_receiver(&self, client: &Arc, ns: String) -> AlertmanagerConfig { +impl AlertReceiver for WebhookReceiver { + async fn install(&self, sender: &CRDPrometheus) -> Result { let spec = AlertmanagerConfigSpec { data: json!({ "route": { @@ -54,45 +49,41 @@ impl CRDAlertManagerReceiver for WebhookReceiver { }), }; - let am = AlertmanagerConfig { + let alertmanager_configs = AlertmanagerConfig { metadata: ObjectMeta { name: Some(self.name.clone()), labels: Some(std::collections::BTreeMap::from([( "alertmanagerConfig".to_string(), "enabled".to_string(), )])), - namespace: Some(ns), + namespace: Some(sender.namespace.clone()), ..Default::default() }, spec, }; - debug!(" am: \n{:#?}", am.clone()); + debug!( + "alert manager configs: \n{:#?}", + alertmanager_configs.clone() + ); - am - } - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } -} - -#[async_trait] -impl AlertReceiver for WebhookReceiver { - async fn install(&self, sender: &CRDPrometheus) -> Result { sender .client - .apply(&sender.alertmanager_configs, Some(&sender.namespace)) + .apply(&alertmanager_configs, Some(&sender.namespace)) .await?; Ok(Outcome::success(format!( "installed crd-alertmanagerconfigs for {}", self.name ))) } + fn name(&self) -> String { "webhook-receiver".to_string() } + fn clone_box(&self) -> Box> { Box::new(self.clone()) } + fn as_any(&self) -> &dyn Any { self } diff --git a/harmony/src/modules/monitoring/application_monitoring/k8s_application_monitoring_score.rs b/harmony/src/modules/monitoring/application_monitoring/k8s_application_monitoring_score.rs deleted file mode 100644 index f4a6c1b..0000000 --- a/harmony/src/modules/monitoring/application_monitoring/k8s_application_monitoring_score.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::sync::{Arc, Mutex}; - -use serde::Serialize; - -use crate::{ - modules::monitoring::{ - kube_prometheus::types::ServiceMonitor, - prometheus::{prometheus::Prometheus, prometheus_config::PrometheusConfig}, - }, - score::Score, - topology::{ - HelmCommand, Topology, - oberservability::monitoring::{AlertReceiver, AlertRule, AlertingInterpret}, - tenant::TenantManager, - }, -}; - -#[derive(Clone, Debug, Serialize)] -pub struct ApplicationPrometheusMonitoringScore { - pub receivers: Vec>>, - pub rules: Vec>>, - pub service_monitors: Vec, -} - -impl Score for ApplicationPrometheusMonitoringScore { - fn create_interpret(&self) -> Box> { - let mut prom_config = PrometheusConfig::new(); - prom_config.alert_manager = true; - - let config = Arc::new(Mutex::new(prom_config)); - config - .try_lock() - .expect("couldn't lock config") - .additional_service_monitors = self.service_monitors.clone(); - Box::new(AlertingInterpret { - sender: Prometheus::new(), - receivers: self.receivers.clone(), - rules: self.rules.clone(), - }) - } - fn name(&self) -> String { - "ApplicationPrometheusMonitoringScore".to_string() - } -} diff --git a/harmony/src/modules/monitoring/application_monitoring/mod.rs b/harmony/src/modules/monitoring/application_monitoring/mod.rs index 11ff468..c243cd7 100644 --- a/harmony/src/modules/monitoring/application_monitoring/mod.rs +++ b/harmony/src/modules/monitoring/application_monitoring/mod.rs @@ -1,2 +1 @@ pub mod application_monitoring_score; -pub mod k8s_application_monitoring_score; diff --git a/harmony/src/modules/monitoring/kube_prometheus/crd/crd_alertmanager_config.rs b/harmony/src/modules/monitoring/kube_prometheus/crd/crd_alertmanager_config.rs index a43a6c2..2165a4a 100644 --- a/harmony/src/modules/monitoring/kube_prometheus/crd/crd_alertmanager_config.rs +++ b/harmony/src/modules/monitoring/kube_prometheus/crd/crd_alertmanager_config.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use async_trait::async_trait; use kube::CustomResource; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -25,7 +24,6 @@ pub struct AlertmanagerConfigSpec { #[derive(Debug, Clone, Serialize)] pub struct CRDPrometheus { - pub alertmanager_configs: AlertmanagerConfig, pub namespace: String, pub client: Arc, } @@ -42,31 +40,6 @@ impl Clone for Box> { } } -#[async_trait] -pub trait CRDAlertManagerReceiver: - AlertReceiver + Send + Sync + std::fmt::Debug -{ - fn name(&self) -> String; - async fn configure_receiver(&self, client: &Arc, ns: String) -> AlertmanagerConfig; - // This new method is for cloning the trait object - fn clone_box(&self) -> Box; -} - -impl Clone for Box { - fn clone(&self) -> Self { - CRDAlertManagerReceiver::clone_box(self.as_ref()) - } -} - -impl Serialize for Box { - fn serialize(&self, _serializer: S) -> Result - where - S: serde::Serializer, - { - todo!() - } -} - impl Serialize for Box> { fn serialize(&self, _serializer: S) -> Result where diff --git a/harmony/src/modules/prometheus/k8s_prometheus_alerting_score.rs b/harmony/src/modules/prometheus/k8s_prometheus_alerting_score.rs index 47ab123..6699c14 100644 --- a/harmony/src/modules/prometheus/k8s_prometheus_alerting_score.rs +++ b/harmony/src/modules/prometheus/k8s_prometheus_alerting_score.rs @@ -8,9 +8,7 @@ use log::{debug, info}; use serde::Serialize; use tokio::process::Command; -use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::{ - AlertmanagerConfig, CRDAlertManagerReceiver, CRDPrometheus, -}; +use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::CRDPrometheus; use crate::modules::monitoring::kube_prometheus::crd::crd_default_rules::build_default_application_rules; use crate::modules::monitoring::kube_prometheus::crd::crd_grafana::{ Grafana, GrafanaDashboard, GrafanaDashboardSpec, GrafanaDatasource, GrafanaDatasourceConfig, @@ -23,6 +21,7 @@ use crate::modules::monitoring::kube_prometheus::crd::grafana_default_dashboard: use crate::modules::monitoring::kube_prometheus::crd::service_monitor::{ ServiceMonitor, ServiceMonitorSpec, }; +use crate::topology::oberservability::monitoring::AlertReceiver; use crate::topology::{K8sclient, Topology, k8s::K8sClient}; use crate::{ data::{Id, Version}, @@ -44,7 +43,7 @@ use super::prometheus::PrometheusApplicationMonitoring; #[derive(Clone, Debug, Serialize)] pub struct K8sPrometheusCRDAlertingScore { pub sender: CRDPrometheus, - pub receivers: Vec>, + pub receivers: Vec>>, pub service_monitors: Vec, pub prometheus_rules: Vec, } @@ -69,7 +68,7 @@ impl> S #[derive(Clone, Debug)] pub struct K8sPrometheusCRDAlertingInterpret { pub sender: CRDPrometheus, - pub receivers: Vec>, + pub receivers: Vec>>, pub service_monitors: Vec, pub prometheus_rules: Vec, } @@ -89,7 +88,8 @@ impl> I self.install_alert_manager(&client).await?; self.install_client_kube_metrics().await?; self.install_grafana(&client).await?; - self.install_receivers(&self.receivers, &client).await?; + self.install_receivers(&self.sender, &self.receivers) + .await?; self.install_rules(&self.prometheus_rules, &client).await?; self.install_monitors(self.service_monitors.clone(), &client) .await?; @@ -246,6 +246,7 @@ impl K8sPrometheusCRDAlertingInterpret { self.sender.namespace.clone().clone() ))) } + async fn install_prometheus(&self, client: &Arc) -> Result { debug!( "installing crd-prometheuses in namespace {}", @@ -559,19 +560,11 @@ impl K8sPrometheusCRDAlertingInterpret { async fn install_receivers( &self, - receivers: &Vec>, - client: &Arc, + sender: &CRDPrometheus, + receivers: &Vec>>, ) -> Result { for receiver in receivers.iter() { - let alertmanager_config: AlertmanagerConfig = receiver - .configure_receiver(client, self.sender.namespace.clone()) - .await; - let sender = CRDPrometheus { - alertmanager_configs: alertmanager_config, - namespace: self.sender.namespace.clone().clone(), - client: self.sender.client.clone(), - }; - receiver.install(&sender).await.map_err(|err| { + receiver.install(sender).await.map_err(|err| { InterpretError::new(format!("failed to install receiver: {}", err)) })?; }