feat: added the steps to install discord-webhook-receiver for k8s anywhere topology if not already installed #50

Closed
wjro wants to merge 6 commits from feat/discord-webhook-receiver into master
Showing only changes of commit 2ca732cecd - Show all commits

View File

@ -1,32 +1,43 @@
use super::discord_alert_manager::discord_alert_manager_score;
use async_trait::async_trait;
use serde_json::Value;
use serde::Serialize;
use serde_yaml::Value;
use tokio::sync::OnceCell;
use url::Url;
use crate::{
interpret::{InterpretError, Outcome},
topology::K8sAnywhereTopology,
data::{Id, Version},
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
inventory::Inventory,
score::Score,
topology::{HelmCommand, K8sAnywhereTopology, Topology},
};
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize)]
pub struct DiscordWebhookConfig {
pub webhook_url: Url,
pub name: String,
pub send_resolved_notifications: bool,
}
pub trait DiscordWebhookReceiver {
fn deploy_discord_webhook_receiver(
&self,
_notification_adapter_id: &str,
) -> Result<Outcome, InterpretError>;
#[derive(Debug, Clone)]
pub struct DiscordWebhookReceiverState {
installed: OnceCell<Outcome>,
}
#[async_trait]
pub trait DiscordWebhookReceiver {
async fn deploy_discord_webhook_receiver(
&self,
config: DiscordWebhookConfig,
state: DiscordWebhookReceiverState,
) -> Result<Outcome, InterpretError>;
fn delete_discord_webhook_receiver(
&self,
_notification_adapter_id: &str,
config: DiscordWebhookConfig,
) -> Result<Outcome, InterpretError>;
}
// trait used to generate alert manager config values impl<T: Topology + AlertManagerConfig> Monitor for KubePrometheus
pub trait AlertManagerConfig<T> {
fn get_alert_manager_config(&self) -> Result<Value, InterpretError>;
}
@ -40,16 +51,81 @@ impl<T: DiscordWebhookReceiver> AlertManagerConfig<T> for DiscordWebhookConfig {
#[async_trait]
johnride marked this conversation as resolved Outdated

This should not be called deploy as this will not deploy every time it is called. We use "ensure" for this behavior.

This should not be called deploy as this will not deploy every time it is called. We use "ensure" for this behavior.
impl DiscordWebhookReceiver for K8sAnywhereTopology {
fn deploy_discord_webhook_receiver(
async fn deploy_discord_webhook_receiver(
&self,
_notification_adapter_id: &str,
config: DiscordWebhookConfig,
state: DiscordWebhookReceiverState,
) -> Result<Outcome, InterpretError> {
todo!()
let discord_webhook_receiver_score = DiscordWebhookReceiverScore { config };
let state = state
.installed
.get_or_try_init(|| {
let inventory = Inventory::autoload();
let interpret = discord_webhook_receiver_score.create_interpret();
async move { interpret.execute(&inventory, self).await }
})
.await?;
Ok(state.clone())
}
fn delete_discord_webhook_receiver(
&self,
_notification_adapter_id: &str,
_config: DiscordWebhookConfig,
) -> Result<Outcome, InterpretError> {
todo!()
}
}
#[derive(Debug, Clone, Serialize)]
struct DiscordWebhookReceiverScore {
config: DiscordWebhookConfig,
}
impl<T: Topology + HelmCommand> Score<T> for DiscordWebhookReceiverScore {
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
Box::new(DiscordWebhookReceiverScoreInterpret {
config: self.config.clone(),
})
}
fn name(&self) -> String {
johnride marked this conversation as resolved Outdated

This function looks really weird, I feel like this is a hack to link the config and the dependency together.

The need to link them makes sense, I guess the webhook sender needs to know the webhook config when it is being deployed. But I am sure there can be a cleaner way than this.

This function looks really weird, I feel like this is a hack to link the config and the dependency together. The need to link them makes sense, I guess the webhook sender needs to know the webhook config when it is being deployed. But I am sure there can be a cleaner way than this.
"DiscordWebhookReceiverScore".to_string()
}
}
#[derive(Debug)]
struct DiscordWebhookReceiverScoreInterpret {
config: DiscordWebhookConfig,
}
#[async_trait]
impl<T: Topology + HelmCommand> Interpret<T> for DiscordWebhookReceiverScoreInterpret {
async fn execute(
johnride marked this conversation as resolved Outdated

autoloading inventory here is a big smell, you should avoid this as much as possible. What if the used built a custom Inventory and now you're autoloading his production inventory and you start wiping operating systems and network configurations?

Always use the inventory that is passed down from the main Maestro.

autoloading inventory here is a big smell, you should avoid this as much as possible. What if the used built a custom Inventory and now you're autoloading his production inventory and you start wiping operating systems and network configurations? Always use the inventory that is passed down from the main Maestro.
&self,
inventory: &Inventory,
topology: &T,
) -> Result<Outcome, InterpretError> {
discord_alert_manager_score(
self.config.webhook_url.clone(),
self.config.name.clone(),
self.config.name.clone(),
)
.create_interpret()
.execute(inventory, topology)
.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!()
}
}