wip: cluster_monitoring almost there, a kink to fix in the yaml handling
All checks were successful
Run Check Script / check (pull_request) Successful in 1m15s
All checks were successful
Run Check Script / check (pull_request) Successful in 1m15s
This commit is contained in:
parent
a12d12aa4f
commit
cf84f2cce8
@ -77,7 +77,7 @@ pub trait AlertReceiver<S: AlertSender>: std::fmt::Debug + Send + Sync {
|
||||
fn name(&self) -> String;
|
||||
fn clone_box(&self) -> Box<dyn AlertReceiver<S>>;
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver;
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@ -10,6 +10,7 @@ use serde::Serialize;
|
||||
use serde_json::json;
|
||||
use serde_yaml::{Mapping, Value};
|
||||
|
||||
use crate::infra::kube::kube_resource_to_dynamic;
|
||||
use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::{
|
||||
AlertmanagerConfig, AlertmanagerConfigSpec, CRDPrometheus,
|
||||
};
|
||||
@ -36,7 +37,7 @@ pub struct DiscordWebhook {
|
||||
}
|
||||
|
||||
impl DiscordWebhook {
|
||||
fn get_receiver_config(&self) -> AlertManagerReceiver {
|
||||
fn get_receiver_config(&self) -> Result<AlertManagerReceiver, String> {
|
||||
let secret_name = format!("{}-secret", self.name.clone());
|
||||
let webhook_key = format!("{}", self.url.clone());
|
||||
|
||||
@ -53,8 +54,8 @@ impl DiscordWebhook {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
AlertManagerReceiver {
|
||||
additional_ressources: vec![],
|
||||
Ok(AlertManagerReceiver {
|
||||
additional_ressources: vec![kube_resource_to_dynamic(&secret)?],
|
||||
|
||||
receiver_config: json!({
|
||||
"name": self.name,
|
||||
@ -69,7 +70,7 @@ impl DiscordWebhook {
|
||||
}
|
||||
]
|
||||
}),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,21 +95,21 @@ impl AlertReceiver<OpenshiftClusterAlertSender> for DiscordWebhook {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
self.get_receiver_config()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AlertReceiver<RHOBObservability> for DiscordWebhook {
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn install(&self, sender: &RHOBObservability) -> Result<Outcome, InterpretError> {
|
||||
let ns = sender.namespace.clone();
|
||||
|
||||
let config = self.get_receiver_config();
|
||||
let config = self.get_receiver_config()?;
|
||||
for resource in config.additional_ressources.iter() {
|
||||
todo!("can I apply a dynamicresource");
|
||||
// sender.client.apply(resource, Some(&ns)).await;
|
||||
@ -171,7 +172,7 @@ impl AlertReceiver<RHOBObservability> for DiscordWebhook {
|
||||
|
||||
#[async_trait]
|
||||
impl AlertReceiver<CRDPrometheus> for DiscordWebhook {
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
todo!()
|
||||
}
|
||||
async fn install(&self, sender: &CRDPrometheus) -> Result<Outcome, InterpretError> {
|
||||
@ -252,7 +253,7 @@ impl AlertReceiver<CRDPrometheus> for DiscordWebhook {
|
||||
|
||||
#[async_trait]
|
||||
impl AlertReceiver<Prometheus> for DiscordWebhook {
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
todo!()
|
||||
}
|
||||
async fn install(&self, sender: &Prometheus) -> Result<Outcome, InterpretError> {
|
||||
@ -281,7 +282,7 @@ impl PrometheusReceiver for DiscordWebhook {
|
||||
|
||||
#[async_trait]
|
||||
impl AlertReceiver<KubePrometheus> for DiscordWebhook {
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
todo!()
|
||||
}
|
||||
async fn install(&self, sender: &KubePrometheus) -> Result<Outcome, InterpretError> {
|
||||
|
||||
@ -31,7 +31,7 @@ pub struct WebhookReceiver {
|
||||
|
||||
#[async_trait]
|
||||
impl AlertReceiver<RHOBObservability> for WebhookReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
todo!()
|
||||
}
|
||||
async fn install(&self, sender: &RHOBObservability) -> Result<Outcome, InterpretError> {
|
||||
@ -100,7 +100,7 @@ impl AlertReceiver<RHOBObservability> for WebhookReceiver {
|
||||
|
||||
#[async_trait]
|
||||
impl AlertReceiver<CRDPrometheus> for WebhookReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
todo!()
|
||||
}
|
||||
async fn install(&self, sender: &CRDPrometheus) -> Result<Outcome, InterpretError> {
|
||||
@ -164,7 +164,7 @@ impl AlertReceiver<CRDPrometheus> for WebhookReceiver {
|
||||
|
||||
#[async_trait]
|
||||
impl AlertReceiver<Prometheus> for WebhookReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
todo!()
|
||||
}
|
||||
async fn install(&self, sender: &Prometheus) -> Result<Outcome, InterpretError> {
|
||||
@ -193,7 +193,7 @@ impl PrometheusReceiver for WebhookReceiver {
|
||||
|
||||
#[async_trait]
|
||||
impl AlertReceiver<KubePrometheus> for WebhookReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> AlertManagerReceiver {
|
||||
fn as_alertmanager_receiver(&self) -> Result<AlertManagerReceiver, String> {
|
||||
todo!()
|
||||
}
|
||||
async fn install(&self, sender: &KubePrometheus) -> Result<Outcome, InterpretError> {
|
||||
|
||||
@ -81,43 +81,76 @@ impl<T: Topology + K8sclient> Interpret<T> for OpenshiftClusterAlertInterpret {
|
||||
trace!("Got secret {secret:?}");
|
||||
|
||||
let data: serde_json::Value = secret.data;
|
||||
trace!("Alertmanager-main secret data {data:#?}");
|
||||
|
||||
// TODO : get config in base64 by drilling into the value
|
||||
let config_b64 = match data.get("alertmanager.yaml") {
|
||||
Some(value) => value.as_str().unwrap_or(""),
|
||||
None => "",
|
||||
// TODO fix this unwrap, handle the option gracefully
|
||||
let config_b64 = match data.get("data") {
|
||||
Some(data_value) => match data_value.get("alertmanager.yaml") {
|
||||
Some(value) => value.as_str().unwrap_or(""),
|
||||
None => {
|
||||
return Err(InterpretError::new(
|
||||
"Missing 'alertmanager.yaml' in alertmanager-main secret".to_string(),
|
||||
));
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(InterpretError::new(
|
||||
"Missing 'data' field in alertmanager-main secret.".to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
trace!("Config base64 {config_b64}");
|
||||
|
||||
// TODO : base64 decode it
|
||||
let config_bytes = BASE64_STANDARD.decode(config_b64).unwrap_or_default();
|
||||
|
||||
// TODO : use serde_yaml to deserialize the string
|
||||
let am_config: serde_yaml::Value =
|
||||
let mut am_config: serde_yaml::Value =
|
||||
serde_yaml::from_str(&String::from_utf8(config_bytes).unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
|
||||
// Merge current alert receivers from this config with self.receivers
|
||||
if let Some(existing_receivers) = am_config.get("receivers") {
|
||||
for receiver in existing_receivers.as_sequence().unwrap_or(&vec![]) {
|
||||
match serde_json::to_string(receiver) {
|
||||
Ok(yaml_str) => {
|
||||
// TODO: validate that each receiver implements to_alertmanager_yaml()
|
||||
// and compare with our receivers
|
||||
info!("Found existing receiver config: {}", yaml_str);
|
||||
}
|
||||
Err(e) => debug!("Failed to serialize receiver: {}", e),
|
||||
debug!("Current alertmanager config {am_config:#?}");
|
||||
|
||||
let existing_receivers = if let Some(receivers) = am_config.get_mut("receivers") {
|
||||
match receivers.as_mapping_mut() {
|
||||
Some(recv) => recv,
|
||||
None => {
|
||||
return Err(InterpretError::new(format!(
|
||||
"Expected alertmanager config receivers to be a mapping, got {receivers:?}"
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
&mut serde_yaml::mapping::Mapping::default()
|
||||
};
|
||||
|
||||
trace!("Existing receivers : {existing_receivers:#?}");
|
||||
|
||||
for custom_receiver in &self.receivers {
|
||||
trace!("Processing custom receiver");
|
||||
let name = &custom_receiver.name();
|
||||
if let Some(recv) = existing_receivers.get(name) {
|
||||
info!(
|
||||
"AlertManager receiver {name} already exists and will be overwritten : {recv:#?}"
|
||||
);
|
||||
}
|
||||
debug!(
|
||||
"Custom receiver YAML output: {:?}",
|
||||
custom_receiver.as_alertmanager_receiver()
|
||||
);
|
||||
|
||||
let json_value = custom_receiver.as_alertmanager_receiver()?.receiver_config;
|
||||
let yaml_string = serde_json::to_string(&json_value).map_err(|e| {
|
||||
InterpretError::new(format!("Failed to serialize receiver config: {}", e))
|
||||
})?;
|
||||
|
||||
let yaml_value: serde_yaml::Value =
|
||||
serde_yaml::from_str(&yaml_string).map_err(|e| {
|
||||
InterpretError::new(format!("Failed to parse receiver config as YAML: {}", e))
|
||||
})?;
|
||||
|
||||
existing_receivers.insert(serde_yaml::Value::from(name.as_str()), yaml_value);
|
||||
}
|
||||
|
||||
debug!("Current alertmanager config {am_config:#?}");
|
||||
|
||||
Ok(Outcome::success(todo!("whats up")))
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user