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 serde::Serialize;
use tokio::sync::OnceCell;
use k8s_openapi::api::core::v1::Pod;
@ -18,7 +19,7 @@ use crate::{
score::Score,
};
use super::{HelmCommand, K8sAnywhereTopology, Topology};
use super::{HelmCommand, K8sAnywhereTopology, Topology, k8s::K8sClient};
#[derive(Clone, Debug)]
struct MonitoringState {
@ -28,19 +29,12 @@ struct MonitoringState {
#[derive(Debug)]
pub struct MonitoringAlertingTopology {
monitoring_state: OnceCell<Option<MonitoringState>>,
namespace: String,
monitoring_stack: Vec<Box<dyn Score<MonitoringAlertingTopology>>>,
}
impl MonitoringAlertingTopology {
pub fn new(
namespace: String,
monitoring_stack: Vec<Box<dyn Score<MonitoringAlertingTopology>>>,
) -> Self {
pub fn new() -> Self {
Self {
monitoring_state: OnceCell::new(),
namespace,
monitoring_stack,
}
}
@ -81,31 +75,8 @@ impl MonitoringAlertingTopology {
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>> {
fn clone(&self) -> Box<dyn Score<T>> {
self.clone_box()
@ -119,15 +90,16 @@ impl Topology for MonitoringAlertingTopology {
}
async fn ensure_ready(&self) -> Result<Outcome, InterpretError> {
let state = if let Some(state) = self.get_monitoring_state().await? {
state
} else {
self.try_install_monitoring_stack()
.await?
.ok_or_else(|| InterpretError::new("Failed to install monitoring stack".into()))?
};
if let Some(state) = self.get_monitoring_state().await? {
// Monitoring stack is already ready — stop app.
println!("{}", state.message);
std::process::exit(0);
}
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(),
chart_version: 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},
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
inventory::Inventory,
maestro::{self, Maestro},
modules::helm::chart::HelmChartScore,
maestro::Maestro,
score::{CloneBoxScore, Score},
topology::{K8sclient, Topology, monitoring_alerting::MonitoringAlertingTopology},
topology::{HelmCommand, Topology, monitoring_alerting::MonitoringAlertingTopology},
};
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 {
pub fn new(monitoring_stack: Vec<Box<dyn Score<MonitoringAlertingTopology>>>, namespace: String) -> Self {
Self { monitoring_stack, namespace }
pub fn new(
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 {
let ns = "monitoring";
Self {
monitoring_stack: vec![
Box::new(kube_prometheus_score(ns)) as Box<dyn Score<MonitoringAlertingTopology>>
],
namespace: ns.to_string()
monitoring_stack: vec![Box::new(kube_prometheus_score(ns))],
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>> {
Box::new(MonitoringAlertingStackInterpret {
score: MonitoringAlertingStackScore {
@ -91,14 +94,14 @@ struct MonitoringAlertingStackInterpret {
}
#[async_trait]
impl<T: Topology> Interpret<T> for MonitoringAlertingStackInterpret {
impl <T: Topology> Interpret<T> for MonitoringAlertingStackInterpret {
async fn execute(
&self,
_inventory: &Inventory,
_topology: &T,
) -> Result<Outcome, InterpretError> {
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 {
Ok(m) => m,
Err(e) => {
@ -106,9 +109,12 @@ impl<T: Topology> Interpret<T> for MonitoringAlertingStackInterpret {
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 {
todo!()