monitoring-alerting #30

Merged
wjro merged 12 commits from monitoring-alerting into master 2025-05-06 17:50:57 +00:00
3 changed files with 36 additions and 55 deletions
Showing only changes of commit 2d74c66fc6 - Show all commits

View File

@ -1,5 +1,6 @@
use std::sync::Arc;
use log::warn; use log::warn;
use serde::Serialize;
use tokio::sync::OnceCell; use tokio::sync::OnceCell;
use k8s_openapi::api::core::v1::Pod; use k8s_openapi::api::core::v1::Pod;
@ -18,7 +19,7 @@ use crate::{
score::Score, score::Score,
}; };
use super::{HelmCommand, K8sAnywhereTopology, Topology}; use super::{HelmCommand, K8sAnywhereTopology, Topology, k8s::K8sClient};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct MonitoringState { struct MonitoringState {
@ -28,19 +29,12 @@ struct MonitoringState {
#[derive(Debug)] #[derive(Debug)]
pub struct MonitoringAlertingTopology { pub struct MonitoringAlertingTopology {
monitoring_state: OnceCell<Option<MonitoringState>>, monitoring_state: OnceCell<Option<MonitoringState>>,
namespace: String,
monitoring_stack: Vec<Box<dyn Score<MonitoringAlertingTopology>>>,
} }
impl MonitoringAlertingTopology { impl MonitoringAlertingTopology {
pub fn new( pub fn new() -> Self {
namespace: String,
monitoring_stack: Vec<Box<dyn Score<MonitoringAlertingTopology>>>,
) -> Self {
Self { Self {
monitoring_state: OnceCell::new(), monitoring_state: OnceCell::new(),
namespace,
monitoring_stack,
} }
} }
@ -81,31 +75,8 @@ impl MonitoringAlertingTopology {
Ok(None) Ok(None)
} }
async fn try_install_monitoring_stack(
&self,
) -> Result<Option<MonitoringState>, InterpretError> {
let inventory = Inventory::autoload();
let topology = K8sAnywhereTopology::new();
let mut maestro = match Maestro::initialize(inventory, topology).await {
Ok(m) => m,
Err(e) => {
println!("failed to initialize Maestro: {}", e);
std::process::exit(1);
}
};
maestro.register_all(vec![Box::new(MonitoringAlertingStackScore::new(self.monitoring_stack.clone(), self.namespace.clone()))]);
let state = match self.get_monitoring_state().await {
Ok(_) => MonitoringState {
message: "Monitoring Stack Ready".to_string(),
},
Err(_) => todo!(),
};
Ok(Some(state))
}
} }
impl<T: Topology> Clone for Box<dyn Score<T>> { impl<T: Topology> Clone for Box<dyn Score<T>> {
fn clone(&self) -> Box<dyn Score<T>> { fn clone(&self) -> Box<dyn Score<T>> {
self.clone_box() self.clone_box()
@ -119,15 +90,16 @@ impl Topology for MonitoringAlertingTopology {
} }
async fn ensure_ready(&self) -> Result<Outcome, InterpretError> { async fn ensure_ready(&self) -> Result<Outcome, InterpretError> {
let state = if let Some(state) = self.get_monitoring_state().await? { if let Some(state) = self.get_monitoring_state().await? {
state // Monitoring stack is already ready — stop app.
} else { println!("{}", state.message);
self.try_install_monitoring_stack() std::process::exit(0);
.await? }
.ok_or_else(|| InterpretError::new("Failed to install monitoring stack".into()))?
};
Ok(Outcome::success(state.message)) // Monitoring not found — proceed with installation.
Ok(Outcome::success(
"Monitoring stack installation started.".to_string(),
))
} }
} }

View File

@ -38,5 +38,8 @@ additionalPrometheusRules:
.unwrap(), .unwrap(),
chart_version: None, chart_version: None,
values_overrides: None, values_overrides: None,
values_yaml: Some(values.to_string()),
create_namespace: true,
install_only: true,
} }
} }

View File

@ -5,10 +5,9 @@ use crate::{
data::{Id, Version}, data::{Id, Version},
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
inventory::Inventory, inventory::Inventory,
maestro::{self, Maestro}, maestro::Maestro,
modules::helm::chart::HelmChartScore,
score::{CloneBoxScore, Score}, score::{CloneBoxScore, Score},
topology::{K8sclient, Topology, monitoring_alerting::MonitoringAlertingTopology}, topology::{HelmCommand, Topology, monitoring_alerting::MonitoringAlertingTopology},
}; };
use super::kube_prometheus::kube_prometheus_score; use super::kube_prometheus::kube_prometheus_score;
@ -20,8 +19,14 @@ pub struct MonitoringAlertingStackScore {
} }
Outdated
Review

Why does the MonitoringAlertingStackScore need a Vec<Box<dyn Score<MonitoringAlertingTopology>>>? It seems like it's never used for anything.

A score's variables should be what is needed to set it up, i.e. any values, rules, etc you want to pass in for the interpret to use to spin up the score

Why does the `MonitoringAlertingStackScore` need a `Vec<Box<dyn Score<MonitoringAlertingTopology>>>`? It seems like it's never used for anything. A score's variables should be what is needed to set it up, i.e. any values, rules, etc you want to pass in for the interpret to use to spin up the score
impl MonitoringAlertingStackScore { impl MonitoringAlertingStackScore {
pub fn new(monitoring_stack: Vec<Box<dyn Score<MonitoringAlertingTopology>>>, namespace: String) -> Self { pub fn new(
Self { monitoring_stack, namespace } monitoring_stack: Vec<Box<dyn Score<MonitoringAlertingTopology>>>,
namespace: String,
) -> Self {
Self {
monitoring_stack,
namespace,
}
} }
} }
@ -29,10 +34,8 @@ impl Default for MonitoringAlertingStackScore {
fn default() -> Self { fn default() -> Self {
let ns = "monitoring"; let ns = "monitoring";
Self { Self {
monitoring_stack: vec![ monitoring_stack: vec![Box::new(kube_prometheus_score(ns))],
Box::new(kube_prometheus_score(ns)) as Box<dyn Score<MonitoringAlertingTopology>> namespace: ns.to_string(),
],
namespace: ns.to_string()
} }
} }
} }
@ -66,7 +69,7 @@ impl Serialize for MonitoringAlertingStackScore {
} }
} }
impl<T: Topology> Score<T> for MonitoringAlertingStackScore { impl<T:Topology> Score<T> for MonitoringAlertingStackScore {
fn create_interpret(&self) -> Box<dyn Interpret<T>> { fn create_interpret(&self) -> Box<dyn Interpret<T>> {
Box::new(MonitoringAlertingStackInterpret { Box::new(MonitoringAlertingStackInterpret {
score: MonitoringAlertingStackScore { score: MonitoringAlertingStackScore {
@ -91,14 +94,14 @@ struct MonitoringAlertingStackInterpret {
} }
#[async_trait] #[async_trait]
impl<T: Topology> Interpret<T> for MonitoringAlertingStackInterpret { impl <T: Topology> Interpret<T> for MonitoringAlertingStackInterpret {
async fn execute( async fn execute(
&self, &self,
_inventory: &Inventory, _inventory: &Inventory,
_topology: &T, _topology: &T,
) -> Result<Outcome, InterpretError> { ) -> Result<Outcome, InterpretError> {
let inventory = Inventory::autoload(); let inventory = Inventory::autoload();
let topology = MonitoringAlertingTopology::new(self.score.namespace.clone(), self.score.monitoring_stack.clone()); let topology = MonitoringAlertingTopology::new();
let mut maestro = match Maestro::initialize(inventory, topology).await { let mut maestro = match Maestro::initialize(inventory, topology).await {
Ok(m) => m, Ok(m) => m,
Err(e) => { Err(e) => {
@ -106,10 +109,13 @@ impl<T: Topology> Interpret<T> for MonitoringAlertingStackInterpret {
std::process::exit(1); std::process::exit(1);
} }
}; };
Ok(Outcome::success(format!("monitoring stack installed in {} namespace",self.score.namespace ))) maestro.register_all(self.score.monitoring_stack.clone());
Ok(Outcome::success(format!(
"monitoring stack installed in {} namespace",
self.score.namespace
)))
} }
fn get_name(&self) -> InterpretName { fn get_name(&self) -> InterpretName {
todo!() todo!()
} }