wip: impl k8sMonitor
This commit is contained in:
parent
dbc66f3d0c
commit
238d1f85e2
@ -10,13 +10,18 @@ use crate::{
|
|||||||
interpret::{InterpretError, Outcome},
|
interpret::{InterpretError, Outcome},
|
||||||
inventory::Inventory,
|
inventory::Inventory,
|
||||||
maestro::Maestro,
|
maestro::Maestro,
|
||||||
modules::k3d::K3DInstallationScore,
|
modules::{k3d::K3DInstallationScore, monitoring::kube_prometheus::kube_prometheus_helm_chart_score::kube_prometheus_helm_chart_score},
|
||||||
topology::LocalhostTopology,
|
topology::LocalhostTopology,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
HelmCommand, K8sclient, Topology,
|
HelmCommand, K8sclient, Topology,
|
||||||
k8s::K8sClient,
|
k8s::K8sClient,
|
||||||
|
oberservability::{
|
||||||
|
K8sMonitorConfig,
|
||||||
|
k8s::K8sMonitor,
|
||||||
|
monitoring::{AlertChannel, AlertChannelConfig, Monitor},
|
||||||
|
},
|
||||||
tenant::{
|
tenant::{
|
||||||
ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy, k8s::K8sTenantManager,
|
ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy, k8s::K8sTenantManager,
|
||||||
},
|
},
|
||||||
@ -37,6 +42,7 @@ enum K8sSource {
|
|||||||
pub struct K8sAnywhereTopology {
|
pub struct K8sAnywhereTopology {
|
||||||
k8s_state: OnceCell<Option<K8sState>>,
|
k8s_state: OnceCell<Option<K8sState>>,
|
||||||
tenant_manager: OnceCell<K8sTenantManager>,
|
tenant_manager: OnceCell<K8sTenantManager>,
|
||||||
|
k8s_monitor: OnceCell<K8sMonitor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@ -61,6 +67,7 @@ impl K8sAnywhereTopology {
|
|||||||
Self {
|
Self {
|
||||||
k8s_state: OnceCell::new(),
|
k8s_state: OnceCell::new(),
|
||||||
tenant_manager: OnceCell::new(),
|
tenant_manager: OnceCell::new(),
|
||||||
|
k8s_monitor: OnceCell::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +185,32 @@ impl K8sAnywhereTopology {
|
|||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn ensure_k8s_monitor(&self) -> Result<(), String> {
|
||||||
|
if let Some(_) = self.k8s_monitor.get() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.k8s_monitor
|
||||||
|
.get_or_try_init(async || -> Result<K8sMonitor, String> {
|
||||||
|
let config = K8sMonitorConfig {
|
||||||
|
chart: kube_prometheus_helm_chart_score(),
|
||||||
|
};
|
||||||
|
Ok(K8sMonitor { config })
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_k8s_monitor(&self) -> Result<&K8sMonitor, ExecutorError> {
|
||||||
|
match self.k8s_monitor.get() {
|
||||||
|
Some(k) => Ok(k),
|
||||||
|
None => Err(ExecutorError::UnexpectedError(
|
||||||
|
"K8sMonitor not available".to_string(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct K8sAnywhereConfig {
|
struct K8sAnywhereConfig {
|
||||||
@ -217,6 +250,10 @@ impl Topology for K8sAnywhereTopology {
|
|||||||
"No K8s client could be found or installed".to_string(),
|
"No K8s client could be found or installed".to_string(),
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
|
self.ensure_k8s_monitor()
|
||||||
|
.await
|
||||||
|
.map_err(|e| InterpretError::new(e))?;
|
||||||
|
|
||||||
match self.is_helm_available() {
|
match self.is_helm_available() {
|
||||||
Ok(()) => Ok(Outcome::success(format!(
|
Ok(()) => Ok(Outcome::success(format!(
|
||||||
"{} + helm available",
|
"{} + helm available",
|
||||||
@ -263,3 +300,18 @@ impl TenantManager for K8sAnywhereTopology {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[async_trait]
|
||||||
|
impl Monitor for K8sAnywhereTopology {
|
||||||
|
async fn provision_monitor(
|
||||||
|
&self,
|
||||||
|
alert_receivers: Option<Vec<Box<dyn AlertChannelConfig>>>,
|
||||||
|
) -> Result<Outcome, InterpretError> {
|
||||||
|
self.get_k8s_monitor()?
|
||||||
|
.provision_monitor(alert_receivers)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_monitor(&self) -> Result<Outcome, InterpretError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
68
harmony/src/domain/topology/oberservability/k8s.rs
Normal file
68
harmony/src/domain/topology/oberservability/k8s.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
interpret::{InterpretError, Outcome},
|
||||||
|
inventory::Inventory,
|
||||||
|
modules::{helm::chart::HelmChartInterpret, monitoring::kube_prometheus::{
|
||||||
|
config::KubePrometheusConfig,
|
||||||
|
kube_prometheus_helm_chart_score::kube_prometheus_helm_chart_score,
|
||||||
|
}},
|
||||||
|
topology::{K8sAnywhereTopology, Topology},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
K8sMonitorConfig,
|
||||||
|
monitoring::{AlertChannel, AlertChannelConfig, Monitor},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct K8sMonitor {
|
||||||
|
pub config: K8sMonitorConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Monitor for K8sMonitor {
|
||||||
|
async fn provision_monitor(
|
||||||
|
&self,
|
||||||
|
alert_receivers: Option<Vec<Box<dyn AlertChannelConfig>>>,
|
||||||
|
) -> Result<Outcome, InterpretError> {
|
||||||
|
if let Some(receivers) = alert_receivers {
|
||||||
|
let alert_channels = self.build_alert_channels(receivers).await?;
|
||||||
|
for channel in alert_channels {
|
||||||
|
channel.register_alert_channel().await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let chart = self.config.chart.clone();
|
||||||
|
//
|
||||||
|
chart.create_interpret();
|
||||||
|
Ok(Outcome::success("installed monitor".to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_monitor(&self) -> Result<Outcome, InterpretError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl AlertChannelConfig for K8sMonitor {
|
||||||
|
async fn build_alert_channel(&self) -> Result<Box<dyn AlertChannel>, InterpretError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl K8sMonitor {
|
||||||
|
pub async fn build_alert_channels(
|
||||||
|
&self,
|
||||||
|
alert_channel_configs: Vec<Box<dyn AlertChannelConfig>>,
|
||||||
|
) -> Result<Vec<Box<dyn AlertChannel>>, InterpretError> {
|
||||||
|
let mut alert_channels = Vec::new();
|
||||||
|
for config in alert_channel_configs {
|
||||||
|
let channel = config.build_alert_channel().await?;
|
||||||
|
alert_channels.push(channel)
|
||||||
|
}
|
||||||
|
Ok(alert_channels)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1 +1,12 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::modules::helm::chart::HelmChartScore;
|
||||||
|
|
||||||
pub mod monitoring;
|
pub mod monitoring;
|
||||||
|
pub mod k8s;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct K8sMonitorConfig {
|
||||||
|
//probably need to do something better here
|
||||||
|
pub chart: HelmChartScore,
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use dyn_clone::DynClone;
|
||||||
|
use serde::Serialize;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::executors::ExecutorError;
|
||||||
use crate::interpret::InterpretError;
|
use crate::interpret::InterpretError;
|
||||||
|
|
||||||
|
use crate::inventory::Inventory;
|
||||||
use crate::{interpret::Outcome, topology::Topology};
|
use crate::{interpret::Outcome, topology::Topology};
|
||||||
|
|
||||||
/// Represents an entity responsible for collecting and organizing observability data
|
/// Represents an entity responsible for collecting and organizing observability data
|
||||||
@ -10,29 +15,24 @@ use crate::{interpret::Outcome, topology::Topology};
|
|||||||
/// A `Monitor` abstracts the logic required to scrape, aggregate, and structure
|
/// A `Monitor` abstracts the logic required to scrape, aggregate, and structure
|
||||||
/// monitoring data, enabling consistent processing regardless of the underlying data source.
|
/// monitoring data, enabling consistent processing regardless of the underlying data source.
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Monitor<T: Topology>: Debug + Send + Sync {
|
pub trait Monitor {
|
||||||
async fn deploy_monitor(
|
async fn provision_monitor(
|
||||||
&self,
|
&self,
|
||||||
topology: &T,
|
alert_receivers: Option<Vec<Box<dyn AlertChannelConfig>>>,
|
||||||
alert_receivers: Vec<Box<dyn AlertChannel>>,
|
|
||||||
) -> Result<Outcome, InterpretError>;
|
) -> Result<Outcome, InterpretError>;
|
||||||
|
|
||||||
fn delete_monitor(
|
fn delete_monitor(&self) -> Result<Outcome, InterpretError>;
|
||||||
&self,
|
|
||||||
topolgy: &T,
|
|
||||||
alert_receivers: Vec<Box<dyn AlertChannel>>,
|
|
||||||
) -> Result<Outcome, InterpretError>;
|
|
||||||
}
|
|
||||||
pub trait MonitorConfig<T: Topology>: Debug + Send + Sync {
|
|
||||||
fn build_monitor(&self) -> Box<dyn Monitor<T>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait AlertChannelConfig: std::fmt::Debug + Send + Sync {
|
|
||||||
fn build_alert_channel(&self) -> Box<dyn AlertChannel>;
|
|
||||||
fn channel_type(&self) -> String;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait AlertChannel: Debug + Send + Sync {
|
pub trait AlertChannel: Debug + Send + Sync {
|
||||||
async fn get_channel_id(&self) -> String;
|
async fn register_alert_channel(&self) -> Result<Outcome, ExecutorError>;
|
||||||
|
//async fn get_channel_id(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait AlertChannelConfig: Debug + Send + Sync + DynClone {
|
||||||
|
async fn build_alert_channel(&self) -> Result<Box<dyn AlertChannel>, InterpretError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
dyn_clone::clone_trait_object!(AlertChannelConfig);
|
||||||
|
|||||||
@ -1,14 +1,6 @@
|
|||||||
use async_trait::async_trait;
|
|
||||||
use serde::Serialize;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
modules::monitoring::kube_prometheus::{
|
|
||||||
kube_prometheus_monitor::PrometheusAlertChannel,
|
|
||||||
types::{AlertManagerGlobalConfigs, AlertManagerReceiver, AlertManagerRoute},
|
|
||||||
},
|
|
||||||
topology::oberservability::monitoring::{AlertChannel, AlertChannelConfig},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DiscordWebhookAlertChannel {
|
pub struct DiscordWebhookAlertChannel {
|
||||||
@ -17,36 +9,36 @@ pub struct DiscordWebhookAlertChannel {
|
|||||||
pub send_resolved_notifications: bool,
|
pub send_resolved_notifications: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AlertChannelConfig for DiscordWebhookAlertChannel {
|
//impl AlertChannelConfig for DiscordWebhookAlertChannel {
|
||||||
fn build_alert_channel(&self) -> Box<dyn AlertChannel> {
|
// fn build_alert_channel(&self) -> Box<dyn AlertChannel> {
|
||||||
Box::new(DiscordWebhookAlertChannel {
|
// Box::new(DiscordWebhookAlertChannel {
|
||||||
webhook_url: self.webhook_url.clone(),
|
// webhook_url: self.webhook_url.clone(),
|
||||||
name: self.name.clone(),
|
// name: self.name.clone(),
|
||||||
send_resolved_notifications: self.send_resolved_notifications.clone(),
|
// send_resolved_notifications: self.send_resolved_notifications.clone(),
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
fn channel_type(&self) -> String {
|
// fn channel_type(&self) -> String {
|
||||||
"discord".to_string()
|
// "discord".to_string()
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
#[async_trait]
|
//#[async_trait]
|
||||||
impl AlertChannel for DiscordWebhookAlertChannel {
|
//impl AlertChannel for DiscordWebhookAlertChannel {
|
||||||
async fn get_channel_id(&self) -> String {
|
// async fn get_channel_id(&self) -> String {
|
||||||
self.name.clone()
|
// self.name.clone()
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
impl PrometheusAlertChannel for DiscordWebhookAlertChannel {
|
//impl PrometheusAlertChannel for DiscordWebhookAlertChannel {
|
||||||
fn get_alert_channel_global_settings(&self) -> Option<AlertManagerGlobalConfigs> {
|
// fn get_alert_channel_global_settings(&self) -> Option<AlertManagerChannelGlobalConfigs> {
|
||||||
None
|
// None
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn get_alert_channel_route(&self) -> AlertManagerRoute {
|
// fn get_alert_channel_route(&self) -> AlertManagerChannelRoute {
|
||||||
todo!()
|
// todo!()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn get_alert_channel_receiver(&self) -> AlertManagerReceiver {
|
// fn get_alert_channel_receiver(&self) -> AlertManagerChannelReceiver {
|
||||||
todo!()
|
// todo!()
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use super::types::AlertManagerChannelConfig;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct KubePrometheusConfig {
|
pub struct KubePrometheusConfig {
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
@ -19,6 +21,7 @@ pub struct KubePrometheusConfig {
|
|||||||
pub kube_proxy: bool,
|
pub kube_proxy: bool,
|
||||||
pub kube_state_metrics: bool,
|
pub kube_state_metrics: bool,
|
||||||
pub prometheus_operator: bool,
|
pub prometheus_operator: bool,
|
||||||
|
pub alert_channels: Vec<AlertManagerChannelConfig>,
|
||||||
}
|
}
|
||||||
impl KubePrometheusConfig {
|
impl KubePrometheusConfig {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -40,6 +43,7 @@ impl KubePrometheusConfig {
|
|||||||
prometheus_operator: true,
|
prometheus_operator: true,
|
||||||
core_dns: false,
|
core_dns: false,
|
||||||
kube_scheduler: false,
|
kube_scheduler: false,
|
||||||
|
alert_channels: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,9 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use crate::modules::helm::chart::HelmChartScore;
|
use crate::modules::helm::chart::HelmChartScore;
|
||||||
|
|
||||||
pub fn kube_prometheus_helm_chart_score(config: &KubePrometheusConfig) -> HelmChartScore {
|
pub fn kube_prometheus_helm_chart_score() -> 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();
|
||||||
@ -143,7 +145,21 @@ prometheus:
|
|||||||
enabled: {prometheus}
|
enabled: {prometheus}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
HelmChartScore {
|
||||||
|
namespace: Some(NonBlankString::from_str(&config.namespace).unwrap()),
|
||||||
|
release_name: NonBlankString::from_str("kube-prometheus").unwrap(),
|
||||||
|
chart_name: NonBlankString::from_str(
|
||||||
|
"oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack",
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
chart_version: None,
|
||||||
|
values_overrides: None,
|
||||||
|
values_yaml: Some(values.to_string()),
|
||||||
|
create_namespace: true,
|
||||||
|
install_only: true,
|
||||||
|
repository: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
// let alertmanager_config = alert_manager_yaml_builder(&config);
|
// let alertmanager_config = alert_manager_yaml_builder(&config);
|
||||||
// values.push_str(&alertmanager_config);
|
// values.push_str(&alertmanager_config);
|
||||||
//
|
//
|
||||||
@ -204,58 +220,44 @@ prometheus:
|
|||||||
// alertmanager_config
|
// alertmanager_config
|
||||||
// }
|
// }
|
||||||
|
|
||||||
HelmChartScore {
|
|
||||||
namespace: Some(NonBlankString::from_str(&config.namespace).unwrap()),
|
|
||||||
release_name: NonBlankString::from_str("kube-prometheus").unwrap(),
|
|
||||||
chart_name: NonBlankString::from_str(
|
|
||||||
"oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack",
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
chart_version: None,
|
|
||||||
values_overrides: None,
|
|
||||||
values_yaml: Some(values.to_string()),
|
|
||||||
create_namespace: true,
|
|
||||||
install_only: true,
|
|
||||||
repository: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn discord_alert_builder(release_name: &String) -> (String, String) {
|
|
||||||
let discord_receiver_name = format!("Discord-{}", release_name);
|
|
||||||
let receiver = format!(
|
|
||||||
r#"
|
|
||||||
- name: '{discord_receiver_name}'
|
|
||||||
webhook_configs:
|
|
||||||
- url: 'http://{release_name}-alertmanager-discord:9094'
|
|
||||||
send_resolved: true"#,
|
|
||||||
);
|
|
||||||
let route = format!(
|
|
||||||
r#"
|
|
||||||
- receiver: '{discord_receiver_name}'
|
|
||||||
matchers:
|
|
||||||
- alertname!=Watchdog
|
|
||||||
continue: true"#,
|
|
||||||
);
|
|
||||||
(receiver, route)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slack_alert_builder(slack_channel: &String) -> (String, String) {
|
//fn discord_alert_builder(release_name: &String) -> (String, String) {
|
||||||
let slack_receiver_name = format!("Slack-{}", slack_channel);
|
// let discord_receiver_name = format!("Discord-{}", release_name);
|
||||||
let receiver = format!(
|
// let receiver = format!(
|
||||||
r#"
|
// r#"
|
||||||
- name: '{slack_receiver_name}'
|
// - name: '{discord_receiver_name}'
|
||||||
slack_configs:
|
// webhook_configs:
|
||||||
- channel: '{slack_channel}'
|
// - url: 'http://{release_name}-alertmanager-discord:9094'
|
||||||
send_resolved: true
|
// send_resolved: true"#,
|
||||||
title: '{{{{ .CommonAnnotations.title }}}}'
|
// );
|
||||||
text: '{{{{ .CommonAnnotations.description }}}}'"#,
|
// let route = format!(
|
||||||
);
|
// r#"
|
||||||
let route = format!(
|
// - receiver: '{discord_receiver_name}'
|
||||||
r#"
|
// matchers:
|
||||||
- receiver: '{slack_receiver_name}'
|
// - alertname!=Watchdog
|
||||||
matchers:
|
// continue: true"#,
|
||||||
- alertname!=Watchdog
|
// );
|
||||||
continue: true"#,
|
// (receiver, route)
|
||||||
);
|
//}
|
||||||
(receiver, route)
|
//
|
||||||
}
|
//fn slack_alert_builder(slack_channel: &String) -> (String, String) {
|
||||||
|
// let slack_receiver_name = format!("Slack-{}", slack_channel);
|
||||||
|
// let receiver = format!(
|
||||||
|
// r#"
|
||||||
|
// - name: '{slack_receiver_name}'
|
||||||
|
// slack_configs:
|
||||||
|
// - channel: '{slack_channel}'
|
||||||
|
// send_resolved: true
|
||||||
|
// title: '{{{{ .CommonAnnotations.title }}}}'
|
||||||
|
// text: '{{{{ .CommonAnnotations.description }}}}'"#,
|
||||||
|
// );
|
||||||
|
// let route = format!(
|
||||||
|
// r#"
|
||||||
|
// - receiver: '{slack_receiver_name}'
|
||||||
|
// matchers:
|
||||||
|
// - alertname!=Watchdog
|
||||||
|
// continue: true"#,
|
||||||
|
// );
|
||||||
|
// (receiver, route)
|
||||||
|
//}
|
||||||
|
|||||||
@ -1,51 +1,87 @@
|
|||||||
use async_trait::async_trait;
|
//#[derive(Debug, Clone, Serialize)]
|
||||||
use serde::Serialize;
|
//pub struct KubePrometheusMonitorScore {
|
||||||
|
// pub kube_prometheus_config: KubePrometheusConfig,
|
||||||
|
// pub alert_channel_configs: Vec<dyn AlertChannelConfig>,
|
||||||
|
//}
|
||||||
|
|
||||||
use crate::{
|
//impl<T: Topology + Debug + HelmCommand + Monitor<T>> MonitorConfig<T>
|
||||||
interpret::{InterpretError, Outcome},
|
// for KubePrometheusMonitorScore
|
||||||
topology::{
|
//{
|
||||||
Topology,
|
// fn build_monitor(&self) -> Box<dyn Monitor<T>> {
|
||||||
oberservability::monitoring::{AlertChannel, Monitor, MonitorConfig},
|
// Box::new(self.clone())
|
||||||
},
|
// }
|
||||||
};
|
//}
|
||||||
|
|
||||||
use super::{
|
//impl<T: Topology + HelmCommand + Debug + Clone + 'static + Monitor<T>> Score<T>
|
||||||
config::KubePrometheusConfig,
|
// for KubePrometheusMonitorScore
|
||||||
types::{AlertManagerGlobalConfigs, AlertManagerReceiver, AlertManagerRoute},
|
//{
|
||||||
};
|
// fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||||
|
// Box::new(KubePrometheusMonitorInterpret {
|
||||||
|
// score: self.clone(),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn name(&self) -> String {
|
||||||
|
// "KubePrometheusMonitorScore".to_string()
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
//#[derive(Debug, Clone)]
|
||||||
pub struct KubePrometheusMonitor {
|
//pub struct KubePrometheusMonitorInterpret {
|
||||||
pub kube_prometheus_config: KubePrometheusConfig,
|
// score: KubePrometheusMonitorScore,
|
||||||
}
|
//}
|
||||||
|
|
||||||
impl<T: Topology> MonitorConfig<T> for KubePrometheusMonitor {
|
//#[async_trait]
|
||||||
fn build_monitor(&self) -> Box<dyn Monitor<T>> {
|
//impl AlertChannelConfig for KubePrometheusMonitorInterpret {
|
||||||
Box::new(self.clone())
|
// async fn build_alert_channel(
|
||||||
}
|
// &self,
|
||||||
}
|
// ) -> Box<dyn AlertChannel> {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//#[async_trait]
|
||||||
|
//impl<T: Topology + HelmCommand + Debug + Monitor<T>> Interpret<T>
|
||||||
|
// for KubePrometheusMonitorInterpret
|
||||||
|
//{
|
||||||
|
// async fn execute(
|
||||||
|
// &self,
|
||||||
|
// inventory: &Inventory,
|
||||||
|
// topology: &T,
|
||||||
|
// ) -> Result<Outcome, InterpretError> {
|
||||||
|
// let monitor = self.score.build_monitor();
|
||||||
|
//
|
||||||
|
// let mut alert_channels = Vec::new();
|
||||||
|
// //for config in self.score.alert_channel_configs {
|
||||||
|
// // alert_channels.push(self.build_alert_channel());
|
||||||
|
// //}
|
||||||
|
//
|
||||||
|
// monitor
|
||||||
|
// .deploy_monitor(inventory, topology, alert_channels)
|
||||||
|
// .await
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 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!()
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
pub trait PrometheusAlertChannel: AlertChannel {
|
|
||||||
fn get_alert_channel_global_settings(&self) -> Option<AlertManagerGlobalConfigs>;
|
|
||||||
fn get_alert_channel_route(&self) -> AlertManagerRoute;
|
|
||||||
fn get_alert_channel_receiver(&self) -> AlertManagerReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
//#[async_trait]
|
||||||
impl<T: Topology> Monitor<T> for KubePrometheusMonitor {
|
//pub trait PrometheusAlertChannel {
|
||||||
async fn deploy_monitor(
|
// fn get_alert_channel_global_settings(&self) -> Option<AlertManagerChannelGlobalConfigs>;
|
||||||
&self,
|
// fn get_alert_channel_route(&self) -> AlertManagerChannelRoute;
|
||||||
_topology: &T,
|
// fn get_alert_channel_receiver(&self) -> AlertManagerChannelReceiver;
|
||||||
_alert_channels: Vec<Box<dyn AlertChannel>>,
|
//}
|
||||||
) -> Result<Outcome, InterpretError> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
fn delete_monitor(
|
|
||||||
&self,
|
|
||||||
_topology: &T,
|
|
||||||
_alert_channels: Vec<Box<dyn AlertChannel>>,
|
|
||||||
) -> Result<Outcome, InterpretError> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,3 +1,14 @@
|
|||||||
pub struct AlertManagerGlobalConfigs {}
|
use serde::Serialize;
|
||||||
pub struct AlertManagerReceiver {}
|
|
||||||
pub struct AlertManagerRoute {}
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct AlertManagerChannelConfig {
|
||||||
|
pub global_configs: AlertManagerChannelGlobalConfigs,
|
||||||
|
pub route: AlertManagerChannelRoute,
|
||||||
|
pub receiver: AlertManagerChannelReceiver,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct AlertManagerChannelGlobalConfigs {}
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct AlertManagerChannelReceiver {}
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct AlertManagerChannelRoute {}
|
||||||
|
|||||||
@ -2,41 +2,18 @@ use async_trait::async_trait;
|
|||||||
use serde::{Serialize, Serializer, ser::SerializeStruct};
|
use serde::{Serialize, Serializer, ser::SerializeStruct};
|
||||||
use std::{fmt::Debug, sync::Arc};
|
use std::{fmt::Debug, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{data::{Id, Version}, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, inventory::Inventory, score::Score, topology::{
|
||||||
data::{Id, Version},
|
oberservability::monitoring::{AlertChannelConfig, Monitor},HelmCommand, Topology
|
||||||
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
}};
|
||||||
inventory::Inventory,
|
|
||||||
score::Score,
|
|
||||||
topology::{
|
|
||||||
HelmCommand, Topology,
|
|
||||||
oberservability::monitoring::{AlertChannelConfig, MonitorConfig},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::kube_prometheus::{
|
|
||||||
config::KubePrometheusConfig, kube_prometheus_monitor::KubePrometheusMonitor,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct MonitoringAlertingScore<T: Topology> {
|
pub struct MonitoringAlertingScore {
|
||||||
pub monitor_config: Arc<dyn MonitorConfig<T>>,
|
#[serde(skip)]
|
||||||
pub alert_channel_configs: Vec<Arc<dyn AlertChannelConfig>>,
|
pub alert_channel_configs: Option<Vec<Box<dyn AlertChannelConfig>>>,
|
||||||
pub namespace: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Topology> MonitoringAlertingScore<T> {
|
impl<T: Topology + HelmCommand + Monitor> Score<T> for MonitoringAlertingScore {
|
||||||
pub fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
monitor_config: Arc::new(KubePrometheusMonitor {
|
|
||||||
kube_prometheus_config: KubePrometheusConfig::new(),
|
|
||||||
}),
|
|
||||||
alert_channel_configs: Vec::new(),
|
|
||||||
namespace: Some("monitoring".to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Topology + HelmCommand + Debug + Clone + 'static> Score<T> for MonitoringAlertingScore<T> {
|
|
||||||
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||||
Box::new(MonitoringAlertingInterpret {
|
Box::new(MonitoringAlertingInterpret {
|
||||||
score: self.clone(),
|
score: self.clone(),
|
||||||
@ -44,30 +21,23 @@ impl<T: Topology + HelmCommand + Debug + Clone + 'static> Score<T> for Monitorin
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
todo!()
|
"MonitoringAlertingScore".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct MonitoringAlertingInterpret<T: Topology> {
|
struct MonitoringAlertingInterpret {
|
||||||
score: MonitoringAlertingScore<T>,
|
score: MonitoringAlertingScore,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: Topology + HelmCommand + Debug> Interpret<T> for MonitoringAlertingInterpret<T> {
|
impl<T: Topology + HelmCommand + Monitor> Interpret<T> for MonitoringAlertingInterpret {
|
||||||
async fn execute(
|
async fn execute(
|
||||||
&self,
|
&self,
|
||||||
_inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
topology: &T,
|
topology: &T,
|
||||||
) -> Result<Outcome, InterpretError> {
|
) -> Result<Outcome, InterpretError> {
|
||||||
let monitor = self.score.monitor_config.build_monitor();
|
topology.provision_monitor(self.score.alert_channel_configs.clone()).await
|
||||||
|
|
||||||
let mut alert_channels = Vec::new();
|
|
||||||
for config in &self.score.alert_channel_configs {
|
|
||||||
alert_channels.push(config.build_alert_channel());
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor.deploy_monitor(topology, alert_channels).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_name(&self) -> InterpretName {
|
fn get_name(&self) -> InterpretName {
|
||||||
@ -87,20 +57,4 @@ impl<T: Topology + HelmCommand + Debug> Interpret<T> for MonitoringAlertingInter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Topology> Serialize for MonitoringAlertingScore<T> {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
let mut state = serializer.serialize_struct("MonitoringAlertingScore", 3)?;
|
|
||||||
|
|
||||||
// For now, just serialize basic info
|
|
||||||
state.serialize_field("monitor_type", "monitoring_system")?;
|
|
||||||
|
|
||||||
let channel_count = self.alert_channel_configs.len();
|
|
||||||
state.serialize_field("alert_channel_count", &channel_count)?;
|
|
||||||
|
|
||||||
state.serialize_field("namespace", &self.namespace)?;
|
|
||||||
state.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user