115 lines
3.8 KiB
Rust
115 lines
3.8 KiB
Rust
use std::sync::Arc;
|
|
|
|
use crate::modules::application::{Application, ApplicationFeature};
|
|
use crate::modules::monitoring::application_monitoring::application_monitoring_score::ApplicationMonitoringScore;
|
|
use crate::modules::monitoring::application_monitoring::rhobs_application_monitoring_score::ApplicationRHOBMonitoringScore;
|
|
|
|
use crate::modules::monitoring::kube_prometheus::crd::rhob_alertmanager_config::RHOBObservability;
|
|
use crate::topology::MultiTargetTopology;
|
|
use crate::topology::ingress::Ingress;
|
|
use crate::{
|
|
inventory::Inventory,
|
|
modules::monitoring::{
|
|
alert_channel::webhook_receiver::WebhookReceiver, ntfy::ntfy::NtfyScore,
|
|
},
|
|
score::Score,
|
|
topology::{HelmCommand, K8sclient, Topology, tenant::TenantManager},
|
|
};
|
|
use crate::{
|
|
modules::prometheus::prometheus::PrometheusApplicationMonitoring,
|
|
topology::oberservability::monitoring::AlertReceiver,
|
|
};
|
|
use async_trait::async_trait;
|
|
use base64::{Engine as _, engine::general_purpose};
|
|
use harmony_types::net::Url;
|
|
use log::{debug, info};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct RHOBMonitoring {
|
|
pub application: Arc<dyn Application>,
|
|
pub alert_receiver: Vec<Box<dyn AlertReceiver<RHOBObservability>>>,
|
|
}
|
|
|
|
#[async_trait]
|
|
impl<
|
|
T: Topology
|
|
+ HelmCommand
|
|
+ 'static
|
|
+ TenantManager
|
|
+ K8sclient
|
|
+ MultiTargetTopology
|
|
+ Ingress
|
|
+ std::fmt::Debug
|
|
+ PrometheusApplicationMonitoring<RHOBObservability>,
|
|
> ApplicationFeature<T> for RHOBMonitoring
|
|
{
|
|
async fn ensure_installed(&self, topology: &T) -> Result<(), String> {
|
|
info!("Ensuring monitoring is available for application");
|
|
let namespace = topology
|
|
.get_tenant_config()
|
|
.await
|
|
.map(|ns| ns.name.clone())
|
|
.unwrap_or_else(|| self.application.name());
|
|
|
|
let mut alerting_score = ApplicationRHOBMonitoringScore {
|
|
sender: RHOBObservability {
|
|
namespace: namespace.clone(),
|
|
client: topology.k8s_client().await.unwrap(),
|
|
},
|
|
application: self.application.clone(),
|
|
receivers: self.alert_receiver.clone(),
|
|
};
|
|
let ntfy = NtfyScore {
|
|
namespace: namespace.clone(),
|
|
host: topology
|
|
.get_domain("ntfy")
|
|
.await
|
|
.map_err(|e| format!("Could not get domain {e}"))?,
|
|
};
|
|
ntfy.interpret(&Inventory::empty(), topology)
|
|
.await
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
let ntfy_default_auth_username = "harmony";
|
|
let ntfy_default_auth_password = "harmony";
|
|
let ntfy_default_auth_header = format!(
|
|
"Basic {}",
|
|
general_purpose::STANDARD.encode(format!(
|
|
"{ntfy_default_auth_username}:{ntfy_default_auth_password}"
|
|
))
|
|
);
|
|
|
|
debug!("ntfy_default_auth_header: {ntfy_default_auth_header}");
|
|
|
|
let ntfy_default_auth_param = general_purpose::STANDARD
|
|
.encode(ntfy_default_auth_header)
|
|
.replace("=", "");
|
|
|
|
debug!("ntfy_default_auth_param: {ntfy_default_auth_param}");
|
|
|
|
let ntfy_receiver = WebhookReceiver {
|
|
name: "ntfy-webhook".to_string(),
|
|
url: Url::Url(
|
|
url::Url::parse(
|
|
format!(
|
|
"http://ntfy.{}.svc.cluster.local/rust-web-app?auth={ntfy_default_auth_param}",
|
|
namespace.clone()
|
|
)
|
|
.as_str(),
|
|
)
|
|
.unwrap(),
|
|
),
|
|
};
|
|
|
|
alerting_score.receivers.push(Box::new(ntfy_receiver));
|
|
alerting_score
|
|
.interpret(&Inventory::empty(), topology)
|
|
.await
|
|
.map_err(|e| e.to_string())?;
|
|
Ok(())
|
|
}
|
|
fn name(&self) -> String {
|
|
"Monitoring".to_string()
|
|
}
|
|
}
|