wip: implentation for kube prometheus monitoring alert sender

This commit is contained in:
Willem 2025-06-19 11:06:20 -04:00 committed by tahahawa
parent e06548ac44
commit ec1df0413a
6 changed files with 127 additions and 19 deletions

View File

@ -0,0 +1,18 @@
FROM php:8.4-apache
ENV PHP_MEMORY_LIMIT=256M
ENV PHP_MAX_EXECUTION_TIME=30
ENV PHP_ERROR_REPORTING="E_ERROR | E_WARNING | E_PARSE"
RUN apt-get update && apt-get install -y --no-install-recommends libfreetype6-dev libjpeg62-turbo-dev libpng-dev libzip-dev unzip && apt-get clean && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd --with-freetype --with-jpeg && docker-php-ext-install -j$(nproc) gd mysqli pdo_mysql zip opcache
RUN sed -i 's/VirtualHost \*:80/VirtualHost *:8080/' /etc/apache2/sites-available/000-default.conf && \
sed -i 's/^Listen 80$/Listen 8080/' /etc/apache2/ports.conf
RUN mkdir -p /usr/local/etc/php/conf.d/
COPY docker-php.ini /usr/local/etc/php/conf.d/docker-php.ini
RUN a2enmod headers && a2enmod rewrite && sed -i 's/ServerTokens OS/ServerTokens Prod/' /etc/apache2/conf-enabled/security.conf && sed -i 's/ServerSignature On/ServerSignature Off/' /etc/apache2/conf-enabled/security.conf
RUN echo 'PassEnv MYSQL_PASSWORD' >> /etc/apache2/sites-available/000-default.conf && echo 'PassEnv MYSQL_USER' >> /etc/apache2/sites-available/000-default.conf && echo 'PassEnv MYSQL_HOST' >> /etc/apache2/sites-available/000-default.conf
RUN groupadd -g 1000 appuser && useradd -u 1000 -g appuser -m -s /bin/bash appuser && chown -R appuser:appuser /var/www/html
WORKDIR /var/www/html
COPY . /var/www/html
RUN chown -R appuser:appuser /var/www/html
EXPOSE 8080/tcp
CMD apache2-foreground

View File

@ -0,0 +1,16 @@
memory_limit = ${PHP_MEMORY_LIMIT}
max_execution_time = ${PHP_MAX_EXECUTION_TIME}
error_reporting = ${PHP_ERROR_REPORTING}
display_errors = Off
log_errors = On
error_log = /dev/stderr
date.timezone = UTC
; Opcache configuration for production
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=2
opcache.fast_shutdown=1

View File

@ -2,10 +2,7 @@ use harmony::{
data::Version,
inventory::Inventory,
maestro::Maestro,
modules::{
lamp::{LAMPConfig, LAMPScore},
monitoring::alert_channel::discord_alert_channel::DiscordWebhook,
},
modules::lamp::{LAMPConfig, LAMPScore},
topology::{K8sAnywhereTopology, Url},
};

View File

@ -1,8 +1,12 @@
use async_trait::async_trait;
use serde_yaml::{Mapping, Value};
use crate::{
interpret::InterpretError,
modules::monitoring::kube_prometheus::prometheus::{Prometheus, PrometheusReceiver},
modules::monitoring::kube_prometheus::{
prometheus::{Prometheus, PrometheusReceiver},
types::AlertChannelConfig,
},
topology::{Url, oberservability::monitoring::AlertReceiver},
};
@ -18,3 +22,84 @@ impl AlertReceiver<Prometheus> for DiscordWebhook {
sender.install_receiver(PrometheusReceiver {}).await
}
}
impl AlertChannelConfig for DiscordWebhook {
fn alert_channel_global_config(&self) -> Option<serde_yaml::Value> {
None
}
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)
}
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 discord_config = Mapping::new();
discord_config.insert(
Value::String("webhook_url".to_string()),
Value::String(self.url.to_string()),
);
receiver.insert(
Value::String("discord_configs".to_string()),
Value::Sequence(vec![Value::Mapping(discord_config)]),
);
Value::Mapping(receiver)
}
}
#[cfg(test)]
mod tests {
use log::debug;
use super::*;
#[test]
fn discord_serialize_should_match() {
let discord_receiver = DiscordWebhook {
name: "test-discord".to_string(),
url: Url::Url(url::Url::parse("https://discord.i.dont.exist.com").unwrap()),
};
let discord_receiver_global =
serde_yaml::to_string(&discord_receiver.alert_channel_global_config()).unwrap();
println!("global receiver \n{:#}", discord_receiver_global);
let discord_receiver_global_yaml = "".to_string();
let discord_receiver_receiver =
serde_yaml::to_string(&discord_receiver.alert_channel_receiver()).unwrap();
println!("receiver \n{:#}", discord_receiver_receiver);
let discord_receiver_receiver_yaml = r#"name: test-discord
discord_configs:
- webhook_url: https://discord.i.dont.exist.com/"#
.to_string();
let discord_receiver_route =
serde_yaml::to_string(&discord_receiver.alert_channel_route()).unwrap();
println!("route \n{:#}", discord_receiver_route);
let discord_receiver_route_yaml = r#"receiver: test-discord
matchers:
- alertname!=Watchdog
continue: true"#
.to_string();
assert_eq!(discord_receiver_receiver, discord_receiver_receiver_yaml);
assert_eq!(discord_receiver_route, discord_receiver_route_yaml);
}
}

View File

@ -20,10 +20,7 @@ impl<T: Topology + HelmCommand> Score<T> for HelmPrometheusAlertingScore {
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
Box::new(AlertingInterpret {
sender: Prometheus {},
receivers: vec![Box::new(DiscordWebhook {
url: todo!(),
name: todo!(),
})],
receivers: self.receivers.clone(),
})
}

View File

@ -1,12 +1,7 @@
use serde::Serialize;
use serde_yaml::Value;
#[derive(Serialize)]
pub struct AlertReceiverRoute {
pub receiver: String,
pub matchers: Vec<String>,
#[serde(default)]
pub r#continue: bool,
}
pub struct AlertChannelReceiver {
pub name: String,
pub trait AlertChannelConfig {
fn alert_channel_global_config(&self) -> Option<Value>;
fn alert_channel_route(&self) -> Value;
fn alert_channel_receiver(&self) -> Value;
}