wip: setting up base for monitoring
This commit is contained in:
parent
c16276b62b
commit
f6c146b14b
@ -40,7 +40,6 @@ enum K8sSource {
|
||||
pub struct K8sAnywhereTopology {
|
||||
k8s_state: OnceCell<Option<K8sState>>,
|
||||
tenant_manager: OnceCell<K8sTenantManager>,
|
||||
k8s_monitor: OnceCell<K8sMonitor>,
|
||||
config: K8sAnywhereConfig,
|
||||
}
|
||||
|
||||
@ -66,7 +65,6 @@ impl K8sAnywhereTopology {
|
||||
Self {
|
||||
k8s_state: OnceCell::new(),
|
||||
tenant_manager: OnceCell::new(),
|
||||
k8s_monitor: OnceCell::new(),
|
||||
config: K8sAnywhereConfig::from_env(),
|
||||
}
|
||||
}
|
||||
@ -75,7 +73,6 @@ impl K8sAnywhereTopology {
|
||||
Self {
|
||||
k8s_state: OnceCell::new(),
|
||||
tenant_manager: OnceCell::new(),
|
||||
k8s_monitor: OnceCell::new(),
|
||||
config,
|
||||
}
|
||||
}
|
||||
@ -206,30 +203,6 @@ 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::cluster_monitor();
|
||||
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(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct K8sAnywhereConfig {
|
||||
@ -281,10 +254,6 @@ impl Topology for K8sAnywhereTopology {
|
||||
"No K8s client could be found or installed".to_string(),
|
||||
))?;
|
||||
|
||||
self.ensure_k8s_monitor()
|
||||
.await
|
||||
.map_err(|e| InterpretError::new(e))?;
|
||||
|
||||
self.ensure_k8s_tenant_manager()
|
||||
.await
|
||||
.map_err(|e| InterpretError::new(e))?;
|
||||
@ -309,20 +278,3 @@ impl TenantManager for K8sAnywhereTopology {
|
||||
.await
|
||||
}
|
||||
}
|
||||
#[async_trait]
|
||||
impl Monitor for K8sAnywhereTopology {
|
||||
async fn provision_monitor<T: Topology + HelmCommand>(
|
||||
&self,
|
||||
inventory: &Inventory,
|
||||
topology: &T,
|
||||
alert_receivers: Option<Vec<Box<dyn AlertChannelConfig>>>,
|
||||
) -> Result<Outcome, InterpretError> {
|
||||
self.get_k8s_monitor()?
|
||||
.provision_monitor(inventory, topology, alert_receivers)
|
||||
.await
|
||||
}
|
||||
|
||||
fn delete_monitor(&self) -> Result<Outcome, InterpretError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,76 @@
|
||||
use url::Url;
|
||||
//#[derive(Debug, Clone)]
|
||||
//pub struct DiscordWebhookAlertChannel {
|
||||
// pub webhook_url: Url,
|
||||
// pub name: String,
|
||||
// pub send_resolved_notifications: bool,
|
||||
//}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DiscordWebhookAlertChannel {
|
||||
pub webhook_url: Url,
|
||||
pub name: String,
|
||||
pub send_resolved_notifications: bool,
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{interpret::Interpret, modules::monitoring::{alert_receiver::{AlertReceiver, AlertReceiverInterpret}, alert_rule::AlertRule, prometheus::{Prometheus, PrometheusReceiver, PrometheusRule, PrometheusScrapeTarget}, scrape_target::ScrapeTarget}, score::Score, topology::Topology};
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
struct DiscordWebhook;
|
||||
|
||||
impl DiscordWebhook {
|
||||
fn as_prometheus_receiver(&self) -> PrometheusReceiver {
|
||||
PrometheusReceiver {}
|
||||
}
|
||||
}
|
||||
|
||||
impl AlertReceiver for DiscordWebhook {
|
||||
type Sender = Prometheus;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) -> Result<(), String> {
|
||||
sender.configure_receiver(self.as_prometheus_receiver())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct DiscordWebhookScore {
|
||||
pub config: DiscordWebhook,
|
||||
}
|
||||
|
||||
impl<T: Topology> Score<T> for DiscordWebhookScore {
|
||||
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||
Box::new(AlertReceiverInterpret {
|
||||
receiver: Box::new(self.config.clone()),
|
||||
})
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl ScrapeTarget for DiscordWebhook {
|
||||
type Sender = Prometheus;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) {
|
||||
sender.configure_scrape_target(self.as_prometheus_scrape_target())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl DiscordWebhook {
|
||||
fn as_prometheus_scrape_target(&self) -> PrometheusScrapeTarget {
|
||||
PrometheusScrapeTarget { definition: todo!() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl AlertRule for DiscordWebhook {
|
||||
type Sender = Prometheus;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) {
|
||||
sender.configure_rule(self.as_prometheus_rule())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl DiscordWebhook {
|
||||
fn as_prometheus_rule(&self) -> PrometheusRule {
|
||||
PrometheusRule { definition: todo!() }
|
||||
}
|
||||
}
|
||||
|
55
harmony/src/modules/monitoring/alert_receiver.rs
Normal file
55
harmony/src/modules/monitoring/alert_receiver.rs
Normal file
@ -0,0 +1,55 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::{
|
||||
data::{Id, Version},
|
||||
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
||||
inventory::Inventory,
|
||||
topology::Topology,
|
||||
};
|
||||
|
||||
use super::prometheus::AlertSender;
|
||||
|
||||
pub trait AlertReceiver: Debug + Send + Sync {
|
||||
type Sender: AlertSender;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) -> Result<(), String>;
|
||||
}
|
||||
|
||||
struct AlertReceiverConfig<S: AlertSender> {
|
||||
config: String, // Or whatever
|
||||
sender: S,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AlertReceiverInterpret {
|
||||
pub receiver: Box<dyn AlertReceiver<Sender = dyn AlertSender>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T: Topology> Interpret<T> for AlertReceiverInterpret {
|
||||
async fn execute(
|
||||
&self,
|
||||
inventory: &Inventory,
|
||||
topology: &T,
|
||||
) -> Result<Outcome, InterpretError> {
|
||||
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!()
|
||||
}
|
||||
}
|
11
harmony/src/modules/monitoring/alert_rule.rs
Normal file
11
harmony/src/modules/monitoring/alert_rule.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::prometheus::AlertSender;
|
||||
|
||||
pub trait AlertRule: Debug {
|
||||
type Sender: AlertSender;
|
||||
|
||||
fn install(&self, sender: &Self::Sender);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
pub mod alert_channel;
|
||||
pub mod kube_prometheus;
|
||||
pub mod monitoring_alerting;
|
||||
mod monitoring_2;
|
||||
pub mod prometheus;
|
||||
pub mod alert_receiver;
|
||||
pub mod alert_rule;
|
||||
pub mod scrape_target;
|
||||
|
@ -1,59 +0,0 @@
|
||||
use crate::{score::Score, topology::Topology};
|
||||
|
||||
pub trait AlertSender {}
|
||||
|
||||
struct Prometheus {}
|
||||
|
||||
impl Prometheus {
|
||||
fn configure_receiver(&self, receiver: PrometheusReceiver) -> Result<(), String> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl AlertSender for Prometheus {}
|
||||
|
||||
struct DiscordWebhook;
|
||||
struct PrometheusReceiver;
|
||||
|
||||
impl DiscordWebhook {
|
||||
fn as_prometheus_receiver(&self) -> PrometheusReceiver {
|
||||
PrometheusReceiver {}
|
||||
}
|
||||
}
|
||||
|
||||
impl AlertReceiver for DiscordWebhook {
|
||||
type Sender = Prometheus;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) -> Result<(), String> {
|
||||
sender.configure_receiver(self.as_prometheus_receiver())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AlertReceiver {
|
||||
type Sender: AlertSender;
|
||||
|
||||
fn install(&self) -> Result<(), String>;
|
||||
}
|
||||
|
||||
struct AlertReceiverConfig<S: AlertSender> {
|
||||
config: String, // Or whatever
|
||||
sender: S,
|
||||
}
|
||||
|
||||
struct DiscordWebhookScore {
|
||||
config: DiscordWebhook,
|
||||
}
|
||||
|
||||
impl<T: Topology> Score<T> for DiscordWebhookScore {
|
||||
fn create_interpret(&self) -> Box<AlertReceiverInterpret> {
|
||||
AlertReceiverInterpret { receiver: Box::new(self.config.clone())}
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct AlertReceiverInterpret {
|
||||
receiver: Box<dyn AlertReceiver>,
|
||||
}
|
@ -11,74 +11,22 @@ use crate::{
|
||||
topology::{HelmCommand, Topology},
|
||||
};
|
||||
|
||||
use super::alert_receiver::AlertReceiver;
|
||||
use super::alert_rule::AlertRule;
|
||||
use super::scrape_target::ScrapeTarget;
|
||||
|
||||
|
||||
pub trait MonitoringSystem {}
|
||||
|
||||
trait PrometheusReceiver {
|
||||
fn get_config(&self) -> PrometheusReceiverConfig;
|
||||
}
|
||||
|
||||
struct PrometheusReceiverConfig {
|
||||
config: Value, // either a serde Value or a more specific type that understands prometheus
|
||||
// config
|
||||
}
|
||||
|
||||
struct PrometheusRule {
|
||||
definition: String, // Not a string but an actual prometheus rule config
|
||||
}
|
||||
|
||||
struct PrometheusScrapeTarget {
|
||||
definition: String, // Not a string but an actual prometheus scraping config
|
||||
}
|
||||
|
||||
pub struct PrometheusMonitoringScore {
|
||||
alert_receivers: Vec<Box<dyn PrometheusReceiver>>,
|
||||
alert_rules: Vec<Box<PrometheusRule>>,
|
||||
scrape_targets: Vec<Box<PrometheusScrapeTarget>>,
|
||||
}
|
||||
|
||||
pub struct PrometheusMonitoringInterpret {}
|
||||
|
||||
#[async_trait]
|
||||
impl<T: Topology + PrometheusCapability> Interpret<T> for PrometheusMonitoringInterpret {
|
||||
async fn execute(
|
||||
&self,
|
||||
inventory: &Inventory,
|
||||
topology: &T,
|
||||
) -> Result<Outcome, InterpretError> {
|
||||
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!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PrometheusCapability {
|
||||
fn install_alert_receivers(&self, receivers: Vec<Box<dyn PrometheusReceiver>>);
|
||||
fn install_alert_rules(&self, rules: Vec<Box<PrometheusRule>>);
|
||||
fn install_scrape_targets(&self, receivers: Vec<Box<PrometheusScrapeTarget>>);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct MonitoringAlertingScore<M: MonitoringSystem> {
|
||||
alert_receivers: Vec<Box<dyn AlertReceiver<M>>>,
|
||||
alert_rules: Vec<Box<dyn AlertRules<M>>>,
|
||||
monitoring_targets: Vec<Box<dyn MonitoringTarget<M>>>,
|
||||
alert_receivers: Vec<Box<dyn AlertReceiver<Sender = M>>>,
|
||||
alert_rules: Vec<Box<dyn AlertRule<Sender = M>>>,
|
||||
scrape_targets: Vec<Box<dyn ScrapeTarget<Sender = M>>>,
|
||||
}
|
||||
|
||||
impl<T: Topology + Monitor> Score<T> for MonitoringAlertingScore {
|
||||
impl<T: Topology, M: MonitoringSystem> Score<T> for MonitoringAlertingScore<M> {
|
||||
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||
Box::new(MonitoringAlertingInterpret {
|
||||
score: self.clone(),
|
||||
@ -96,7 +44,7 @@ struct MonitoringAlertingInterpret {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T: Topology + HelmCommand + Monitor> Interpret<T> for MonitoringAlertingInterpret {
|
||||
impl<T: Topology> Interpret<T> for MonitoringAlertingInterpret {
|
||||
async fn execute(
|
||||
&self,
|
||||
inventory: &Inventory,
|
||||
@ -127,4 +75,3 @@ impl<T: Topology + HelmCommand + Monitor> Interpret<T> for MonitoringAlertingInt
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
99
harmony/src/modules/monitoring/prometheus.rs
Normal file
99
harmony/src/modules/monitoring/prometheus.rs
Normal file
@ -0,0 +1,99 @@
|
||||
use async_trait::async_trait;
|
||||
use serde::Serialize;
|
||||
use serde_value::Value;
|
||||
|
||||
use crate::{
|
||||
data::{Id, Version},
|
||||
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
||||
inventory::Inventory,
|
||||
score::Score,
|
||||
topology::Topology,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait AlertSender {}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct Prometheus {}
|
||||
|
||||
impl Prometheus {
|
||||
pub fn configure_receiver(&self, receiver: PrometheusReceiver) -> Result<(), String> {
|
||||
todo!()
|
||||
}
|
||||
pub fn configure_rule(&self, rule: PrometheusRule) {
|
||||
todo!()
|
||||
}
|
||||
pub fn configure_scrape_target(&self, target: PrometheusScrapeTarget) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PrometheusCapability {
|
||||
fn install_alert_receivers(&self, receivers: Vec<Box<dyn PrometheusReceiver>>);
|
||||
fn install_alert_rules(&self, rules: Vec<Box<dyn PrometheusRule>>);
|
||||
fn install_scrape_targets(&self, receivers: Vec<Box<dyn PrometheusScrapeTarget>>);
|
||||
}
|
||||
|
||||
impl AlertSender for Prometheus {}
|
||||
|
||||
pub trait PrometheusReceiver{
|
||||
fn get_prometheus_config(&self) -> PrometheusReceiverConfig;
|
||||
}
|
||||
|
||||
pub struct PrometheusReceiverConfig {
|
||||
config: Value, // either a serde Value or a more specific type that understands prometheus
|
||||
// config
|
||||
}
|
||||
|
||||
pub trait PrometheusRule{
|
||||
fn get_prometheus_config(&self) -> PrometheusRuleConfig;
|
||||
}
|
||||
|
||||
pub struct PrometheusRuleConfig {
|
||||
pub definition: String, // Not a string but an actual prometheus rule config
|
||||
}
|
||||
|
||||
pub trait PrometheusScrapeTarget {
|
||||
fn get_prometheus_config(&self) -> PrometheusScrapeTargetConfig;
|
||||
}
|
||||
|
||||
pub struct PrometheusScrapeTargetConfig {
|
||||
pub definition: String, // Not a string but an actual prometheus scraping config
|
||||
}
|
||||
|
||||
pub struct PrometheusMonitoringScore {
|
||||
alert_receivers: Vec<Box<PrometheusReceiverConfig>>,
|
||||
alert_rules: Vec<Box<PrometheusRuleConfig>>,
|
||||
scrape_targets: Vec<Box<PrometheusScrapeTargetConfig>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrometheusMonitoringInterpret {}
|
||||
|
||||
#[async_trait]
|
||||
impl<T: Topology + PrometheusCapability> Interpret<T> for PrometheusMonitoringInterpret {
|
||||
async fn execute(
|
||||
&self,
|
||||
inventory: &Inventory,
|
||||
topology: &T,
|
||||
) -> Result<Outcome, InterpretError> {
|
||||
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!()
|
||||
}
|
||||
}
|
||||
|
9
harmony/src/modules/monitoring/scrape_target.rs
Normal file
9
harmony/src/modules/monitoring/scrape_target.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::prometheus::AlertSender;
|
||||
|
||||
pub trait ScrapeTarget: Debug {
|
||||
type Sender: AlertSender;
|
||||
|
||||
fn install(&self, sender: &Self::Sender);
|
||||
}
|
Loading…
Reference in New Issue
Block a user