wip: trying to install the helm chart for HelmKubePrometheus
This commit is contained in:
parent
50e38fed0a
commit
a41230ac7b
@ -1,6 +1,10 @@
|
|||||||
use harmony::{
|
use harmony::{
|
||||||
inventory::Inventory, maestro::Maestro,
|
inventory::Inventory,
|
||||||
modules::monitoring::{alert_channel::discord_alert_channel::DiscordWebhook, kube_prometheus::helm_prometheus_alert_score::HelmPrometheusAlertingScore},
|
maestro::Maestro,
|
||||||
|
modules::monitoring::{
|
||||||
|
alert_channel::discord_alert_channel::DiscordWebhook,
|
||||||
|
kube_prometheus::helm_prometheus_alert_score::HelmPrometheusAlertingScore,
|
||||||
|
},
|
||||||
topology::{K8sAnywhereTopology, Url},
|
topology::{K8sAnywhereTopology, Url},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -10,7 +14,9 @@ async fn main() {
|
|||||||
name: "test-discord".to_string(),
|
name: "test-discord".to_string(),
|
||||||
url: Url::Url(url::Url::parse("https://discord.i.dont.exist.com").unwrap()),
|
url: Url::Url(url::Url::parse("https://discord.i.dont.exist.com").unwrap()),
|
||||||
};
|
};
|
||||||
let alerting_score = HelmPrometheusAlertingScore { receivers: vec![Box::new(discord_receiver)] };
|
let alerting_score = HelmPrometheusAlertingScore {
|
||||||
|
receivers: vec![Box::new(discord_receiver)],
|
||||||
|
};
|
||||||
let mut maestro = Maestro::<K8sAnywhereTopology>::initialize(
|
let mut maestro = Maestro::<K8sAnywhereTopology>::initialize(
|
||||||
Inventory::autoload(),
|
Inventory::autoload(),
|
||||||
K8sAnywhereTopology::from_env(),
|
K8sAnywhereTopology::from_env(),
|
||||||
@ -18,12 +24,6 @@ async fn main() {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
//let monitoring = MonitoringAlertingScore {
|
|
||||||
// alert_receivers: vec![],
|
|
||||||
// alert_rules: vec![],
|
|
||||||
// scrape_targets: vec![],
|
|
||||||
//};
|
|
||||||
//maestro.register_all(vec![Box::new(monitoring)]);
|
|
||||||
maestro.register_all(vec![Box::new(alerting_score)]);
|
maestro.register_all(vec![Box::new(alerting_score)]);
|
||||||
harmony_cli::init(maestro, None).await.unwrap();
|
harmony_cli::init(maestro, None).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@ use async_trait::async_trait;
|
|||||||
|
|
||||||
use crate::interpret::InterpretError;
|
use crate::interpret::InterpretError;
|
||||||
|
|
||||||
|
use super::oberservability::monitoring::AlertSender;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Installable {
|
pub trait Installable {
|
||||||
async fn ensure_installed(&self) -> Result<(), InterpretError>;
|
async fn ensure_installed(&self) -> Result<(), InterpretError>;
|
||||||
|
|||||||
@ -7,7 +7,11 @@ use crate::{
|
|||||||
topology::{Topology, installable::Installable},
|
topology::{Topology, installable::Installable},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait AlertSender: Send + Sync + std::fmt::Debug + Installable {}
|
#[async_trait]
|
||||||
|
pub trait AlertSender: Send + Sync + std::fmt::Debug + Installable {
|
||||||
|
fn name(&self) -> String;
|
||||||
|
async fn install(&self) -> Result<Outcome, InterpretError>;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AlertingInterpret<S: AlertSender> {
|
pub struct AlertingInterpret<S: AlertSender> {
|
||||||
@ -16,7 +20,7 @@ pub struct AlertingInterpret<S: AlertSender> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<S: AlertSender, T: Topology> Interpret<T> for AlertingInterpret<S> {
|
impl<S: AlertSender + Installable, T: Topology> Interpret<T> for AlertingInterpret<S> {
|
||||||
async fn execute(
|
async fn execute(
|
||||||
&self,
|
&self,
|
||||||
inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
@ -25,7 +29,11 @@ impl<S: AlertSender, T: Topology> Interpret<T> for AlertingInterpret<S> {
|
|||||||
for receiver in self.receivers.iter() {
|
for receiver in self.receivers.iter() {
|
||||||
receiver.install(&self.sender).await?;
|
receiver.install(&self.sender).await?;
|
||||||
}
|
}
|
||||||
todo!()
|
self.sender.ensure_installed();
|
||||||
|
Ok(Outcome::success(format!(
|
||||||
|
"successfully installed alert sender {}",
|
||||||
|
self.sender.name()
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_name(&self) -> InterpretName {
|
fn get_name(&self) -> InterpretName {
|
||||||
@ -47,7 +55,7 @@ impl<S: AlertSender, T: Topology> Interpret<T> for AlertingInterpret<S> {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait AlertReceiver<S: AlertSender>: std::fmt::Debug + Send + Sync {
|
pub trait AlertReceiver<S: AlertSender>: std::fmt::Debug + Send + Sync {
|
||||||
async fn install(&self, sender: &S) -> Result<(), InterpretError>;
|
async fn install(&self, sender: &S) -> Result<Outcome, InterpretError>;
|
||||||
fn clone_box(&self) -> Box<dyn AlertReceiver<S>>;
|
fn clone_box(&self) -> Box<dyn AlertReceiver<S>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use async_trait::async_trait;
|
|||||||
use serde_yaml::{Mapping, Value};
|
use serde_yaml::{Mapping, Value};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
interpret::InterpretError,
|
interpret::{InterpretError, Outcome},
|
||||||
modules::monitoring::kube_prometheus::{
|
modules::monitoring::kube_prometheus::{
|
||||||
prometheus::{Prometheus, PrometheusReceiver},
|
prometheus::{Prometheus, PrometheusReceiver},
|
||||||
types::AlertChannelConfig,
|
types::AlertChannelConfig,
|
||||||
@ -18,7 +18,7 @@ pub struct DiscordWebhook {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AlertReceiver<Prometheus> for DiscordWebhook {
|
impl AlertReceiver<Prometheus> for DiscordWebhook {
|
||||||
async fn install(&self, sender: &Prometheus) -> Result<(), InterpretError> {
|
async fn install(&self, sender: &Prometheus) -> Result<Outcome, InterpretError> {
|
||||||
sender.install_receiver(self).await
|
sender.install_receiver(self).await
|
||||||
}
|
}
|
||||||
fn clone_box(&self) -> Box<dyn AlertReceiver<Prometheus>> {
|
fn clone_box(&self) -> Box<dyn AlertReceiver<Prometheus>> {
|
||||||
@ -29,8 +29,11 @@ impl AlertReceiver<Prometheus> for DiscordWebhook {
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl PrometheusReceiver for DiscordWebhook {
|
impl PrometheusReceiver for DiscordWebhook {
|
||||||
//TODO not return a tuple
|
//TODO not return a tuple
|
||||||
async fn receiver_config(&self) -> (Option<Value>, Value, Value) {
|
fn name(&self) -> String {
|
||||||
(self.alert_channel_global_config().await, self.alert_channel_receiver().await, self.alert_channel_route().await)
|
self.name.clone()
|
||||||
|
}
|
||||||
|
async fn receiver_config(&self) -> Value {
|
||||||
|
self.alert_channel_receiver().await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,9 +4,7 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use crate::modules::helm::chart::HelmChartScore;
|
use crate::modules::helm::chart::HelmChartScore;
|
||||||
|
|
||||||
pub fn kube_prometheus_helm_chart_score() -> HelmChartScore {
|
pub fn kube_prometheus_helm_chart_score(config: KubePrometheusConfig) -> HelmChartScore {
|
||||||
let config = KubePrometheusConfig::new();
|
|
||||||
|
|
||||||
//TODO this should be make into a rule with default formatting that can be easily passed as a vec
|
//TODO this should be make into a rule with default formatting that can be easily passed as a vec
|
||||||
//to the overrides or something leaving the user to deal with formatting here seems bad
|
//to the overrides or something leaving the user to deal with formatting here seems bad
|
||||||
let default_rules = config.default_rules.to_string();
|
let default_rules = config.default_rules.to_string();
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
score::Score,
|
score::Score,
|
||||||
topology::{
|
topology::{
|
||||||
HelmCommand, Topology,
|
HelmCommand, Topology,
|
||||||
|
installable::Installable,
|
||||||
oberservability::monitoring::{AlertReceiver, AlertingInterpret},
|
oberservability::monitoring::{AlertReceiver, AlertingInterpret},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -15,13 +18,16 @@ pub struct HelmPrometheusAlertingScore {
|
|||||||
pub receivers: Vec<Box<dyn AlertReceiver<Prometheus>>>,
|
pub receivers: Vec<Box<dyn AlertReceiver<Prometheus>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Topology + HelmCommand> Score<T> for HelmPrometheusAlertingScore {
|
impl<T: Topology + HelmCommand + Installable> Score<T> for HelmPrometheusAlertingScore {
|
||||||
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
|
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
|
||||||
Box::new(AlertingInterpret {
|
Box::new(AlertingInterpret {
|
||||||
sender: Prometheus { config: KubePrometheusConfig::new() },
|
sender: Prometheus {
|
||||||
|
config: Mutex::new(KubePrometheusConfig::new()),
|
||||||
|
},
|
||||||
receivers: self.receivers.clone(),
|
receivers: self.receivers.clone(),
|
||||||
})
|
})
|
||||||
} fn name(&self) -> String {
|
}
|
||||||
|
fn name(&self) -> String {
|
||||||
"HelmPrometheusAlertingScore".to_string()
|
"HelmPrometheusAlertingScore".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,38 @@
|
|||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde_yaml::Value;
|
use serde_yaml::Value;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
interpret::InterpretError,
|
interpret::{InterpretError, Outcome},
|
||||||
topology::{installable::Installable, oberservability::monitoring::AlertSender},
|
inventory::Inventory,
|
||||||
|
score,
|
||||||
|
topology::{
|
||||||
|
HelmCommand, K8sAnywhereTopology, Topology, installable::Installable,
|
||||||
|
oberservability::monitoring::AlertSender,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::helm::config::KubePrometheusConfig;
|
use score::Score;
|
||||||
|
|
||||||
impl AlertSender for Prometheus {}
|
use super::helm::{
|
||||||
|
config::KubePrometheusConfig, kube_prometheus_helm_chart::kube_prometheus_helm_chart_score,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl AlertSender for Prometheus {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"HelmKubePrometheus".to_string()
|
||||||
|
}
|
||||||
|
async fn install(&self) -> Result<Outcome, InterpretError> {
|
||||||
|
self.install_prometheus();
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//im not totally sure what to do in the impl installable
|
||||||
|
//should we have a oncecell that checks insured is true?
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Installable for Prometheus {
|
impl Installable for Prometheus {
|
||||||
@ -18,32 +41,63 @@ impl Installable for Prometheus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//before we talked about having a trait installable and a trait installer for the topology
|
||||||
|
// i feel like that might still be necessary to meet the requirement of inventory and topology on
|
||||||
|
// the score.create_interpret().execute(inventory, topology) method
|
||||||
|
#[async_trait]
|
||||||
|
trait Installer {
|
||||||
|
async fn install(&self, sender: Box<&dyn Installable>) -> Result<(), InterpretError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Installer for K8sAnywhereTopology {
|
||||||
|
async fn install(&self, installable: Box<&dyn Installable>) -> Result<(), InterpretError> {
|
||||||
|
installable.install().await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Prometheus{
|
pub struct Prometheus {
|
||||||
pub config: KubePrometheusConfig,
|
pub config: Mutex<KubePrometheusConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Prometheus {
|
impl Prometheus {
|
||||||
pub async fn install_receiver(
|
pub async fn install_receiver(
|
||||||
&self,
|
&self,
|
||||||
prometheus_receiver: &dyn PrometheusReceiver,
|
prometheus_receiver: &dyn PrometheusReceiver,
|
||||||
) -> Result<(), InterpretError> {
|
) -> Result<Outcome, InterpretError> {
|
||||||
|
let prom_receiver = prometheus_receiver.receiver_config().await;
|
||||||
|
debug!(
|
||||||
|
"adding alert receiver to prometheus config: {:#?}",
|
||||||
|
&prom_receiver
|
||||||
|
);
|
||||||
|
let mut config = self.config.lock().unwrap();
|
||||||
|
|
||||||
|
config.alert_receiver_configs.push(prom_receiver);
|
||||||
debug!("adding alert receiver to prometheus config: {:#?}", prometheus_receiver.receiver_config());
|
let prom_receiver_name = prometheus_receiver.name();
|
||||||
self.config.alert_receiver_configs.push(prometheus_receiver.receiver_config());
|
debug!("installed alert receiver {}", &prom_receiver_name);
|
||||||
todo!()
|
Ok(Outcome::success(format!(
|
||||||
|
"Sucessfully installed receiver {}",
|
||||||
|
prom_receiver_name
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn install_prometheus(&self) -> Result<Outcome, InterpretError> {
|
||||||
|
kube_prometheus_helm_chart_score(self.config.lock().unwrap().clone())
|
||||||
|
.create_interpret()
|
||||||
|
.execute()
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait PrometheusReceiver: Send + Sync + std::fmt::Debug{
|
pub trait PrometheusReceiver: Send + Sync + std::fmt::Debug {
|
||||||
async fn receiver_config(&self) -> (Option<Value>, Value, Value);
|
fn name(&self) -> String;
|
||||||
|
async fn receiver_config(&self) -> Value;
|
||||||
//this probably needs to be a type
|
//this probably needs to be a type
|
||||||
//that
|
//that
|
||||||
//represents
|
//represents
|
||||||
//a
|
//a
|
||||||
//promtheusreceiver
|
//promtheusreceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user