All checks were successful
Run Check Script / check (pull_request) Successful in 1m15s
308 lines
9.2 KiB
Rust
308 lines
9.2 KiB
Rust
use std::any::Any;
|
|
|
|
use async_trait::async_trait;
|
|
use kube::api::ObjectMeta;
|
|
use log::debug;
|
|
use serde::Serialize;
|
|
use serde_json::json;
|
|
use serde_yaml::{Mapping, Value};
|
|
|
|
use crate::{
|
|
interpret::{InterpretError, Outcome},
|
|
modules::monitoring::{
|
|
kube_prometheus::{
|
|
crd::{
|
|
crd_alertmanager_config::CRDPrometheus, rhob_alertmanager_config::RHOBObservability,
|
|
},
|
|
prometheus::{KubePrometheus, KubePrometheusReceiver},
|
|
types::{AlertChannelConfig, AlertManagerChannelConfig},
|
|
},
|
|
prometheus::prometheus::{Prometheus, PrometheusReceiver},
|
|
},
|
|
topology::oberservability::monitoring::{AlertManagerReceiver, AlertReceiver},
|
|
};
|
|
use harmony_types::net::Url;
|
|
|
|
#[derive(Debug, Clone, Serialize)]
|
|
pub struct WebhookReceiver {
|
|
pub name: String,
|
|
pub url: Url,
|
|
}
|
|
|
|
#[async_trait]
|
|
impl AlertReceiver<RHOBObservability> for WebhookReceiver {
|
|
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
|
todo!()
|
|
}
|
|
async fn install(&self, sender: &RHOBObservability) -> Result<Outcome, InterpretError> {
|
|
let spec = crate::modules::monitoring::kube_prometheus::crd::rhob_alertmanager_config::AlertmanagerConfigSpec {
|
|
data: json!({
|
|
"route": {
|
|
"receiver": self.name,
|
|
},
|
|
"receivers": [
|
|
{
|
|
"name": self.name,
|
|
"webhookConfigs": [
|
|
{
|
|
"url": self.url,
|
|
"httpConfig": {
|
|
"tlsConfig": {
|
|
"insecureSkipVerify": true
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}),
|
|
};
|
|
|
|
let alertmanager_configs = crate::modules::monitoring::kube_prometheus::crd::rhob_alertmanager_config::AlertmanagerConfig {
|
|
metadata: ObjectMeta {
|
|
name: Some(self.name.clone()),
|
|
labels: Some(std::collections::BTreeMap::from([(
|
|
"alertmanagerConfig".to_string(),
|
|
"enabled".to_string(),
|
|
)])),
|
|
namespace: Some(sender.namespace.clone()),
|
|
..Default::default()
|
|
},
|
|
spec,
|
|
};
|
|
debug!(
|
|
"alert manager configs: \n{:#?}",
|
|
alertmanager_configs.clone()
|
|
);
|
|
|
|
sender
|
|
.client
|
|
.apply(&alertmanager_configs, Some(&sender.namespace))
|
|
.await?;
|
|
Ok(Outcome::success(format!(
|
|
"installed rhob-alertmanagerconfigs for {}",
|
|
self.name
|
|
)))
|
|
}
|
|
|
|
fn name(&self) -> String {
|
|
"webhook-receiver".to_string()
|
|
}
|
|
|
|
fn clone_box(&self) -> Box<dyn AlertReceiver<RHOBObservability>> {
|
|
Box::new(self.clone())
|
|
}
|
|
|
|
fn as_any(&self) -> &dyn Any {
|
|
self
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl AlertReceiver<CRDPrometheus> for WebhookReceiver {
|
|
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
|
todo!()
|
|
}
|
|
async fn install(&self, sender: &CRDPrometheus) -> Result<Outcome, InterpretError> {
|
|
let spec = crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::AlertmanagerConfigSpec {
|
|
data: json!({
|
|
"route": {
|
|
"receiver": self.name,
|
|
},
|
|
"receivers": [
|
|
{
|
|
"name": self.name,
|
|
"webhookConfigs": [
|
|
{
|
|
"url": self.url,
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}),
|
|
};
|
|
|
|
let alertmanager_configs = crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::AlertmanagerConfig {
|
|
metadata: ObjectMeta {
|
|
name: Some(self.name.clone()),
|
|
labels: Some(std::collections::BTreeMap::from([(
|
|
"alertmanagerConfig".to_string(),
|
|
"enabled".to_string(),
|
|
)])),
|
|
namespace: Some(sender.namespace.clone()),
|
|
..Default::default()
|
|
},
|
|
spec,
|
|
};
|
|
debug!(
|
|
"alert manager configs: \n{:#?}",
|
|
alertmanager_configs.clone()
|
|
);
|
|
|
|
sender
|
|
.client
|
|
.apply(&alertmanager_configs, Some(&sender.namespace))
|
|
.await?;
|
|
Ok(Outcome::success(format!(
|
|
"installed crd-alertmanagerconfigs for {}",
|
|
self.name
|
|
)))
|
|
}
|
|
|
|
fn name(&self) -> String {
|
|
"webhook-receiver".to_string()
|
|
}
|
|
|
|
fn clone_box(&self) -> Box<dyn AlertReceiver<CRDPrometheus>> {
|
|
Box::new(self.clone())
|
|
}
|
|
|
|
fn as_any(&self) -> &dyn Any {
|
|
self
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl AlertReceiver<Prometheus> for WebhookReceiver {
|
|
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
|
todo!()
|
|
}
|
|
async fn install(&self, sender: &Prometheus) -> Result<Outcome, InterpretError> {
|
|
sender.install_receiver(self).await
|
|
}
|
|
fn name(&self) -> String {
|
|
"webhook-receiver".to_string()
|
|
}
|
|
fn clone_box(&self) -> Box<dyn AlertReceiver<Prometheus>> {
|
|
Box::new(self.clone())
|
|
}
|
|
fn as_any(&self) -> &dyn Any {
|
|
self
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl PrometheusReceiver for WebhookReceiver {
|
|
fn name(&self) -> String {
|
|
self.name.clone()
|
|
}
|
|
async fn configure_receiver(&self) -> AlertManagerChannelConfig {
|
|
self.get_config().await
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl AlertReceiver<KubePrometheus> for WebhookReceiver {
|
|
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
|
todo!()
|
|
}
|
|
async fn install(&self, sender: &KubePrometheus) -> Result<Outcome, InterpretError> {
|
|
sender.install_receiver(self).await
|
|
}
|
|
fn name(&self) -> String {
|
|
"webhook-receiver".to_string()
|
|
}
|
|
fn clone_box(&self) -> Box<dyn AlertReceiver<KubePrometheus>> {
|
|
Box::new(self.clone())
|
|
}
|
|
fn as_any(&self) -> &dyn Any {
|
|
self
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl KubePrometheusReceiver for WebhookReceiver {
|
|
fn name(&self) -> String {
|
|
self.name.clone()
|
|
}
|
|
async fn configure_receiver(&self) -> AlertManagerChannelConfig {
|
|
self.get_config().await
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl AlertChannelConfig for WebhookReceiver {
|
|
async fn get_config(&self) -> AlertManagerChannelConfig {
|
|
let channel_global_config = None;
|
|
let channel_receiver = self.alert_channel_receiver().await;
|
|
let channel_route = self.alert_channel_route().await;
|
|
|
|
AlertManagerChannelConfig {
|
|
channel_global_config,
|
|
channel_receiver,
|
|
channel_route,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl WebhookReceiver {
|
|
async fn alert_channel_route(&self) -> serde_yaml::Value {
|
|
let mut route = Mapping::new();
|
|
route.insert(
|
|
Value::String("receiver".to_string()),
|
|
Value::String(self.name.clone()),
|
|
);
|
|
route.insert(
|
|
Value::String("matchers".to_string()),
|
|
Value::Sequence(vec![Value::String("alertname!=Watchdog".to_string())]),
|
|
);
|
|
route.insert(Value::String("continue".to_string()), Value::Bool(true));
|
|
Value::Mapping(route)
|
|
}
|
|
|
|
async fn alert_channel_receiver(&self) -> serde_yaml::Value {
|
|
let mut receiver = Mapping::new();
|
|
receiver.insert(
|
|
Value::String("name".to_string()),
|
|
Value::String(self.name.clone()),
|
|
);
|
|
|
|
let mut webhook_config = Mapping::new();
|
|
webhook_config.insert(
|
|
Value::String("url".to_string()),
|
|
Value::String(self.url.to_string()),
|
|
);
|
|
|
|
receiver.insert(
|
|
Value::String("webhook_configs".to_string()),
|
|
Value::Sequence(vec![Value::Mapping(webhook_config)]),
|
|
);
|
|
|
|
Value::Mapping(receiver)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
#[tokio::test]
|
|
async fn webhook_serialize_should_match() {
|
|
let webhook_receiver = WebhookReceiver {
|
|
name: "test-webhook".to_string(),
|
|
url: Url::Url(url::Url::parse("https://webhook.i.dont.exist.com").unwrap()),
|
|
};
|
|
|
|
let webhook_receiver_receiver =
|
|
serde_yaml::to_string(&webhook_receiver.alert_channel_receiver().await).unwrap();
|
|
println!("receiver \n{:#}", webhook_receiver_receiver);
|
|
let webhook_receiver_receiver_yaml = r#"name: test-webhook
|
|
webhook_configs:
|
|
- url: https://webhook.i.dont.exist.com/
|
|
"#
|
|
.to_string();
|
|
|
|
let webhook_receiver_route =
|
|
serde_yaml::to_string(&webhook_receiver.alert_channel_route().await).unwrap();
|
|
println!("route \n{:#}", webhook_receiver_route);
|
|
let webhook_receiver_route_yaml = r#"receiver: test-webhook
|
|
matchers:
|
|
- alertname!=Watchdog
|
|
continue: true
|
|
"#
|
|
.to_string();
|
|
|
|
assert_eq!(webhook_receiver_receiver, webhook_receiver_receiver_yaml);
|
|
assert_eq!(webhook_receiver_route, webhook_receiver_route_yaml);
|
|
}
|
|
}
|