feat/monitoring_alerting #61

Merged
johnride merged 12 commits from feat/monitoring_alerting into master 2025-06-19 14:37:20 +00:00
9 changed files with 119 additions and 37 deletions
Showing only changes of commit 527b88ce3b - Show all commits

18
Cargo.lock generated
View File

@ -1040,6 +1040,15 @@ dependencies = [
"url",
]
[[package]]
name = "example-monitoring"
version = "0.1.0"
dependencies = [
"harmony",
"harmony_cli",
"tokio",
]
[[package]]
name = "example-nanodc"
version = "0.1.0"
@ -2387,15 +2396,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "monitoring"
version = "0.1.0"
dependencies = [
"harmony",
"harmony_cli",
"tokio",
]
[[package]]
name = "native-tls"
version = "0.2.14"

View File

@ -1,5 +1,5 @@
[package]
name = "monitoring"
name = "example-monitoring"
edition = "2024"
version.workspace = true
readme.workspace = true

View File

@ -1,11 +1,11 @@
use harmony::{
inventory::Inventory, maestro::Maestro,
modules::monitoring::monitoring_alerting::{MonitoringAlertingScore, MonitoringSystem},
topology::K8sAnywhereTopology,
modules::monitoring::alert_score::PrometheusAlertingScore, topology::K8sAnywhereTopology,
};
#[tokio::main]
async fn main() {
let alerting_score = PrometheusAlertingScore { receivers: vec![] };
let mut maestro = Maestro::<K8sAnywhereTopology>::initialize(
Inventory::autoload(),
K8sAnywhereTopology::from_env(),
@ -19,5 +19,6 @@ async fn main() {
// scrape_targets: vec![],
//};
//maestro.register_all(vec![Box::new(monitoring)]);
maestro.register_all(vec![Box::new(alerting_score)]);
harmony_cli::init(maestro, None).await.unwrap();
}

View File

@ -17,11 +17,6 @@ use crate::{
use super::{
HelmCommand, K8sclient, Topology,
k8s::K8sClient,
oberservability::{
K8sMonitorConfig,
k8s::K8sMonitor,
monitoring::{AlertChannelConfig, Monitor},
},
tenant::{TenantConfig, TenantManager, k8s::K8sTenantManager},
};

View File

@ -0,0 +1,86 @@
use async_trait::async_trait;
use serde::Serialize;
use crate::{
data::{Id, Version}, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, topology::{HelmCommand, Topology}
};
#[async_trait]
pub trait Installable {
async fn ensure_installed(&self) -> Result<(), InterpretError>;
}
pub trait AlertSender: Send + Sync + std::fmt::Debug + Installable {}
pub trait AlertReceiver<S: AlertSender>: std::fmt::Debug + Send + Sync {
fn install(&self, sender: &S) -> Result<(), InterpretError>;
}
#[derive(Clone, Debug, Serialize)]
pub struct PrometheusAlertingScore {
pub receivers: Vec<Box<dyn AlertReceiver<Prometheus>>>,
}
impl Serialize for Box<dyn AlertReceiver<Prometheus>> {
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
todo!()
}
}
impl Clone for Box<dyn AlertReceiver<Prometheus>> {
fn clone(&self) -> Self {
todo!()
}
}
impl<T: Topology + HelmCommand> Score<T> for PrometheusAlertingScore {
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
Box::new(AlertingInterpret { sender: Prometheus {}, receivers: todo!() })
}
fn name(&self) -> String {
"PrometheusAlertingScore".to_string()
}
}
pub struct Prometheus;
#[derive(Debug)]
pub struct AlertingInterpret<S: AlertSender> {
pub sender: S,
pub receivers: Vec<Box<dyn AlertReceiver<S>>>,
}
#[async_trait]
impl<S: AlertSender, T: Topology> Interpret<T> for AlertingInterpret<S> {
#[must_use]
async fn execute(
&self,
inventory: &Inventory,
topology: &T,
) -> Result<Outcome, InterpretError> {
self.receivers.iter().try_for_each(|r| {
r.install(&self.sender)
})?;
todo!();
}
fn get_name(&self) -> InterpretName {
todo!()
}
fn get_version(&self) -> Version {
todo!()
}
fn get_status(&self) -> InterpretStatus {
todo!()
}
fn get_children(&self) -> Vec<Id> {
todo!()
}
}

View File

@ -1,5 +1,4 @@
use super::config::KubePrometheusConfig;
use log::info;
use non_blank_string_rs::NonBlankString;
use std::str::FromStr;
@ -26,7 +25,7 @@ pub fn kube_prometheus_helm_chart_score() -> HelmChartScore {
let node_exporter = config.node_exporter.to_string();
let prometheus_operator = config.prometheus_operator.to_string();
let prometheus = config.prometheus.to_string();
let mut values = format!(
let values = format!(
r#"
additionalPrometheusRulesMap:
pods-status-alerts:

View File

@ -5,3 +5,4 @@ pub mod kube_prometheus;
pub mod monitoring_alerting;
pub mod prometheus;
pub mod scrape_target;
pub mod alert_score;

View File

@ -27,11 +27,6 @@ pub struct MonitoringAlertingScore<M: MonitoringSystem> {
pub scrape_targets: Vec<Box<dyn ScrapeTarget<M = M>>>,
}
#[derive(Clone)]
struct MonitoringConfig<M: MonitoringSystem> {
receivers: Vec<Box<dyn AlertReceiver<M = M>>>,
}
impl<M: MonitoringSystem> Clone for Box<dyn AlertReceiver<M = M>> {
fn clone(&self) -> Self {
self.clone_box()
@ -49,7 +44,7 @@ impl<M: MonitoringSystem> Clone for Box<dyn ScrapeTarget<M = M>> {
}
impl<M: MonitoringSystem> Serialize for MonitoringAlertingScore<M> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
@ -84,11 +79,21 @@ impl<M: MonitoringSystem + Installable, T: Topology> Interpret<T>
{
async fn execute(
&self,
inventory: &Inventory,
topology: &T,
_inventory: &Inventory,
_topology: &T,
) -> Result<Outcome, InterpretError> {
debug!("score {:#?}", self.score);
monitoring_system.install().await
todo!("Figure out a clean way to have things come together here :
We want Prometheus to be bound like this :
DiscordWebhook (AlertReceiver<Sender = Prometheus>)
|
Prometheus (AlertSender + Scraper + Installable<T: HelmCommand>)
^
MonitoringScore {{ alert_rules, alert_receivers, scrape_endpoints }}
(Interpret<T: Topology + Installer
")
}
fn get_name(&self) -> InterpretName {
@ -108,8 +113,3 @@ impl<M: MonitoringSystem + Installable, T: Topology> Interpret<T>
}
}
impl<M: MonitoringSystem> MonitoringAlertingInterpret<M> {
fn build_config(&self) -> MonitoringConfig<M> {
todo!()
}
}

View File

@ -6,18 +6,18 @@ use crate::{
data::{Id, Version},
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
inventory::Inventory,
topology::{HelmCommand, K8sAnywhereTopology, Topology},
topology::{K8sAnywhereTopology, Topology},
};
use std::fmt::Debug;
use super::monitoring_alerting::{MonitoringSystem, MonitoringSystemInstaller};
use super::monitoring_alerting::MonitoringSystem;
#[derive(Debug, Clone, Serialize)]
pub struct Prometheus {}
impl Prometheus {
pub fn configure_receiver(&self, receiver: Box<&dyn PrometheusReceiver>) -> Result<(), String> {
let receiver_config = receiver.get_prometheus_config();
let _receiver_config = receiver.get_prometheus_config();
todo!()
}
pub fn configure_rule(&self, _rule: Box<&dyn PrometheusRule>) {