feat: added impl for Discordwebhook receiver to receive application alerts from namespaces from application feature
Some checks failed
Run Check Script / check (pull_request) Failing after 49s
Some checks failed
Run Check Script / check (pull_request) Failing after 49s
This commit is contained in:
parent
819f4a32fd
commit
e61ec015ab
@ -1,10 +1,17 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use k8s_openapi::api::core::v1::Secret;
|
||||||
use kube::api::ObjectMeta;
|
use kube::api::ObjectMeta;
|
||||||
|
use kube::{Api, Client, ResourceExt};
|
||||||
|
use log::{debug, info};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use serde_yaml::{Mapping, Value};
|
use serde_yaml::{Mapping, Value};
|
||||||
|
|
||||||
use crate::modules::monitoring::kube_prometheus::alert_manager_config::AlertmanagerConfigSpec;
|
use crate::modules::monitoring::kube_prometheus::alert_manager_config::AlertmanagerConfigSpec;
|
||||||
|
use crate::topology::k8s::K8sClient;
|
||||||
use crate::{
|
use crate::{
|
||||||
interpret::{InterpretError, Outcome},
|
interpret::{InterpretError, Outcome},
|
||||||
modules::monitoring::{
|
modules::monitoring::{
|
||||||
@ -30,35 +37,65 @@ impl CRDAlertManagerReceiver for DiscordWebhook {
|
|||||||
self.name.clone()
|
self.name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn configure_receiver(&self) -> AlertmanagerConfig {
|
async fn configure_receiver(&self, client: &Arc<K8sClient>, ns: String) -> AlertmanagerConfig {
|
||||||
let spec = AlertmanagerConfigSpec {
|
let secret_name = format!("{}-secret", self.name.clone());
|
||||||
route: Some(json!({
|
let webhook_key = format!("{}", self.url.clone());
|
||||||
"group_by": ["alertname"],
|
|
||||||
"receiver": self.name,
|
let mut string_data = BTreeMap::new();
|
||||||
})),
|
string_data.insert("webhook-url".to_string(), webhook_key.clone());
|
||||||
receivers: Some(json!([
|
|
||||||
{
|
let secret = Secret {
|
||||||
"name": self.name,
|
metadata: kube::core::ObjectMeta {
|
||||||
"webhook_configs": [
|
name: Some(secret_name.clone()),
|
||||||
{
|
..Default::default()
|
||||||
"url": self.url
|
},
|
||||||
}
|
string_data: Some(string_data),
|
||||||
]
|
type_: Some("Opaque".to_string()),
|
||||||
}
|
..Default::default()
|
||||||
])),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AlertmanagerConfig {
|
let _ = client.apply(&secret, Some(&ns)).await;
|
||||||
|
|
||||||
|
let spec = AlertmanagerConfigSpec {
|
||||||
|
data: json!({
|
||||||
|
"route": {
|
||||||
|
"receiver": self.name,
|
||||||
|
},
|
||||||
|
"receivers": [
|
||||||
|
{
|
||||||
|
"name": self.name,
|
||||||
|
"discordConfigs": [
|
||||||
|
{
|
||||||
|
"apiURL": {
|
||||||
|
"name": secret_name,
|
||||||
|
"key": "webhook-url",
|
||||||
|
},
|
||||||
|
"title": "{{ template \"discord.default.title\" . }}",
|
||||||
|
"message": "{{ template \"discord.default.message\" . }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
let am = AlertmanagerConfig {
|
||||||
metadata: ObjectMeta {
|
metadata: ObjectMeta {
|
||||||
name: Some(self.name.clone()),
|
name: Some(self.name.clone()),
|
||||||
//TODO this cant be hardcoded
|
labels: Some(std::collections::BTreeMap::from([(
|
||||||
namespace: Some("monitoring".into()),
|
"alertmanagerConfig".to_string(),
|
||||||
|
"enabled".to_string(),
|
||||||
|
)])),
|
||||||
|
namespace: Some(ns),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
spec,
|
spec,
|
||||||
}
|
};
|
||||||
|
debug!(" am: \n{:#?}", am.clone());
|
||||||
|
|
||||||
|
am
|
||||||
}
|
}
|
||||||
fn clone_box(&self) -> Box<dyn CRDAlertManagerReceiver> {
|
fn clone_box(&self) -> Box<dyn CRDAlertManagerReceiver> {
|
||||||
Box::new(self.clone())
|
Box::new(self.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,27 +211,6 @@ impl DiscordWebhook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DiscordWebhook> for AlertmanagerConfigSpec {
|
|
||||||
fn from(dw: DiscordWebhook) -> Self {
|
|
||||||
AlertmanagerConfigSpec {
|
|
||||||
route: Some(json!({
|
|
||||||
"group_by": ["alertname"],
|
|
||||||
"receiver": dw.name,
|
|
||||||
})),
|
|
||||||
receivers: Some(json!([
|
|
||||||
{
|
|
||||||
"name": dw.name,
|
|
||||||
"webhook_configs": [
|
|
||||||
{
|
|
||||||
"url": dw.url
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@ -99,12 +99,11 @@ use crate::{
|
|||||||
plural = "alertmanagerconfigs",
|
plural = "alertmanagerconfigs",
|
||||||
namespaced
|
namespaced
|
||||||
)]
|
)]
|
||||||
|
|
||||||
pub struct AlertmanagerConfigSpec {
|
pub struct AlertmanagerConfigSpec {
|
||||||
// Define the spec fields here, or use serde's `flatten` if you want to store arbitrary data
|
// Define the spec fields here, or use serde's `flatten` if you want to store arbitrary data
|
||||||
// Example placeholder:
|
// Example placeholder:
|
||||||
pub route: Option<serde_json::Value>,
|
#[serde(flatten)]
|
||||||
pub receivers: Option<serde_json::Value>,
|
pub data: serde_json::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -139,7 +138,7 @@ pub trait CRDAlertManagerReceiver:
|
|||||||
AlertReceiver<CRDAlertManager> + Send + Sync + std::fmt::Debug
|
AlertReceiver<CRDAlertManager> + Send + Sync + std::fmt::Debug
|
||||||
{
|
{
|
||||||
fn name(&self) -> String;
|
fn name(&self) -> String;
|
||||||
async fn configure_receiver(&self) -> AlertmanagerConfig;
|
async fn configure_receiver(&self, client: &Arc<K8sClient>, ns: String) -> AlertmanagerConfig;
|
||||||
// This new method is for cloning the trait object
|
// This new method is for cloning the trait object
|
||||||
fn clone_box(&self) -> Box<dyn CRDAlertManagerReceiver>;
|
fn clone_box(&self) -> Box<dyn CRDAlertManagerReceiver>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,9 +48,9 @@ impl<T: Topology + K8sclient> Interpret<T> for HelmPrometheusApplicationAlerting
|
|||||||
inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
topology: &T,
|
topology: &T,
|
||||||
) -> Result<Outcome, InterpretError> {
|
) -> Result<Outcome, InterpretError> {
|
||||||
|
let client = topology.k8s_client().await.unwrap();
|
||||||
for receiver in self.receivers.iter() {
|
for receiver in self.receivers.iter() {
|
||||||
let alertmanager_config: AlertmanagerConfig = receiver.configure_receiver().await;
|
let alertmanager_config: AlertmanagerConfig = receiver.configure_receiver(&client, self.namespace.clone()).await;
|
||||||
let client = topology.k8s_client().await.unwrap();
|
|
||||||
client
|
client
|
||||||
.apply(&alertmanager_config, Some(&self.namespace))
|
.apply(&alertmanager_config, Some(&self.namespace))
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user