refactor(prometheus): modified crd prometheus to impl the installable trait
This commit is contained in:
parent
58b6268989
commit
1f3796f503
@ -3,7 +3,7 @@ use harmony::{
|
|||||||
modules::{
|
modules::{
|
||||||
application::{
|
application::{
|
||||||
ApplicationScore, RustWebFramework, RustWebapp,
|
ApplicationScore, RustWebFramework, RustWebapp,
|
||||||
features::{PackagingDeployment, rhob_monitoring::Monitoring},
|
features::{Monitoring, PackagingDeployment},
|
||||||
},
|
},
|
||||||
monitoring::alert_channel::discord_alert_channel::DiscordWebhook,
|
monitoring::alert_channel::discord_alert_channel::DiscordWebhook,
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::{process::Command, sync::Arc};
|
use std::{collections::BTreeMap, process::Command, sync::Arc};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use kube::api::GroupVersionKind;
|
use kube::api::{GroupVersionKind, ObjectMeta};
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::sync::OnceCell;
|
use tokio::sync::OnceCell;
|
||||||
@ -12,12 +12,20 @@ use crate::{
|
|||||||
inventory::Inventory,
|
inventory::Inventory,
|
||||||
modules::{
|
modules::{
|
||||||
k3d::K3DInstallationScore,
|
k3d::K3DInstallationScore,
|
||||||
|
k8s::ingress::{K8sIngressScore, PathType},
|
||||||
monitoring::{
|
monitoring::{
|
||||||
grafana::{grafana::Grafana, helm::helm_grafana::grafana_helm_chart_score},
|
grafana::{grafana::Grafana, helm::helm_grafana::grafana_helm_chart_score},
|
||||||
kube_prometheus::crd::{
|
kube_prometheus::crd::{
|
||||||
crd_alertmanager_config::CRDPrometheus,
|
crd_alertmanager_config::CRDPrometheus,
|
||||||
|
crd_grafana::{
|
||||||
|
Grafana as GrafanaCRD, GrafanaDashboard, GrafanaDashboardSpec,
|
||||||
|
GrafanaDatasource, GrafanaDatasourceConfig, GrafanaDatasourceSpec, GrafanaSpec,
|
||||||
|
},
|
||||||
|
crd_prometheuses::LabelSelector,
|
||||||
|
grafana_default_dashboard::build_default_dashboard,
|
||||||
prometheus_operator::prometheus_operator_helm_chart_score,
|
prometheus_operator::prometheus_operator_helm_chart_score,
|
||||||
rhob_alertmanager_config::RHOBObservability, service_monitor::ServiceMonitor,
|
rhob_alertmanager_config::RHOBObservability,
|
||||||
|
service_monitor::ServiceMonitor,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
prometheus::{
|
prometheus::{
|
||||||
@ -90,10 +98,11 @@ impl K8sclient for K8sAnywhereTopology {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Grafana for K8sAnywhereTopology {
|
impl Grafana for K8sAnywhereTopology {
|
||||||
async fn ensure_grafana_operator_ready(
|
async fn ensure_grafana_operator(
|
||||||
&self,
|
&self,
|
||||||
inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
) -> Result<PreparationOutcome, PreparationError> {
|
) -> Result<PreparationOutcome, PreparationError> {
|
||||||
|
debug!("ensure grafana operator");
|
||||||
let client = self.k8s_client().await.unwrap();
|
let client = self.k8s_client().await.unwrap();
|
||||||
let grafana_gvk = GroupVersionKind {
|
let grafana_gvk = GroupVersionKind {
|
||||||
group: "grafana.integreatly.org".to_string(),
|
group: "grafana.integreatly.org".to_string(),
|
||||||
@ -112,6 +121,7 @@ impl Grafana for K8sAnywhereTopology {
|
|||||||
details: "Found grafana CRDs in cluster".to_string(),
|
details: "Found grafana CRDs in cluster".to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return self
|
return self
|
||||||
.install_grafana_operator(inventory, Some("grafana"))
|
.install_grafana_operator(inventory, Some("grafana"))
|
||||||
@ -120,7 +130,41 @@ impl Grafana for K8sAnywhereTopology {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
async fn install_grafana(&self) -> Result<PreparationOutcome, PreparationError> {
|
async fn install_grafana(&self) -> Result<PreparationOutcome, PreparationError> {
|
||||||
todo!()
|
debug!("install grafana");
|
||||||
|
let ns = "grafana";
|
||||||
|
|
||||||
|
let mut label = BTreeMap::new();
|
||||||
|
|
||||||
|
label.insert("dashboards".to_string(), "grafana".to_string());
|
||||||
|
let label_selector = LabelSelector {
|
||||||
|
match_labels: label.clone(),
|
||||||
|
match_expressions: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
let client = self.k8s_client().await?;
|
||||||
|
|
||||||
|
let datasource = self.build_grafana_datasource(ns, &label_selector);
|
||||||
|
|
||||||
|
client.apply(&datasource, Some(ns)).await?;
|
||||||
|
|
||||||
|
let dashboard = self.build_grafana_dashboard(ns, &label_selector);
|
||||||
|
|
||||||
|
client.apply(&dashboard, Some(ns)).await?;
|
||||||
|
|
||||||
|
let grafana = self.build_grafana(ns, &label);
|
||||||
|
|
||||||
|
client.apply(&grafana, Some(ns)).await?;
|
||||||
|
|
||||||
|
let grafana_ingress = self.build_grafana_ingress(ns).await;
|
||||||
|
|
||||||
|
grafana_ingress
|
||||||
|
.interpret(&Inventory::empty(), self)
|
||||||
|
.await
|
||||||
|
.map_err(|e| PreparationError::new(e.to_string()))?;
|
||||||
|
|
||||||
|
Ok(PreparationOutcome::Success {
|
||||||
|
details: "Installed grafana composants".to_string(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,49 +173,38 @@ impl PrometheusMonitoring<CRDPrometheus> for K8sAnywhereTopology {
|
|||||||
async fn install_prometheus(
|
async fn install_prometheus(
|
||||||
&self,
|
&self,
|
||||||
sender: &CRDPrometheus,
|
sender: &CRDPrometheus,
|
||||||
inventory: &Inventory,
|
_inventory: &Inventory,
|
||||||
receivers: Option<Vec<Box<dyn AlertReceiver<CRDPrometheus>>>>,
|
_receivers: Option<Vec<Box<dyn AlertReceiver<CRDPrometheus>>>>,
|
||||||
) -> Result<PreparationOutcome, PreparationError> {
|
) -> Result<PreparationOutcome, PreparationError> {
|
||||||
let po_result = self.ensure_prometheus_operator(sender).await?;
|
let client = self.k8s_client().await?;
|
||||||
|
|
||||||
if po_result == PreparationOutcome::Noop {
|
for monitor in sender.service_monitor.iter() {
|
||||||
debug!("Skipping Prometheus CR installation due to missing operator.");
|
client
|
||||||
return Ok(po_result);
|
.apply(monitor, Some(&sender.namespace))
|
||||||
}
|
.await
|
||||||
|
.map_err(|e| PreparationError::new(e.to_string()))?;
|
||||||
let result = self
|
|
||||||
.get_k8s_prometheus_application_score(
|
|
||||||
sender.clone(),
|
|
||||||
receivers,
|
|
||||||
Some(sender.service_monitor.clone()),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.interpret(inventory, self)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(outcome) => match outcome.status {
|
|
||||||
InterpretStatus::SUCCESS => Ok(PreparationOutcome::Success {
|
|
||||||
details: outcome.message,
|
|
||||||
}),
|
|
||||||
InterpretStatus::NOOP => Ok(PreparationOutcome::Noop),
|
|
||||||
_ => Err(PreparationError::new(outcome.message)),
|
|
||||||
},
|
|
||||||
Err(err) => Err(PreparationError::new(err.to_string())),
|
|
||||||
}
|
}
|
||||||
|
Ok(PreparationOutcome::Success {
|
||||||
|
details: "successfuly installed prometheus components".to_string(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn ensure_prometheus_operator(
|
async fn ensure_prometheus_operator(
|
||||||
&self,
|
&self,
|
||||||
sender: &CRDPrometheus,
|
sender: &CRDPrometheus,
|
||||||
inventory: &Inventory,
|
_inventory: &Inventory,
|
||||||
) -> Result<PreparationOutcome, PreparationError> {
|
) -> Result<PreparationOutcome, PreparationError> {
|
||||||
let po_result = self.ensure_prometheus_operator(sender).await?;
|
let po_result = self.ensure_prometheus_operator(sender).await?;
|
||||||
|
|
||||||
if po_result == PreparationOutcome::Noop {
|
match po_result {
|
||||||
debug!("Skipping Prometheus CR installation due to missing operator.");
|
PreparationOutcome::Success { details: _ } => {
|
||||||
return Ok(po_result);
|
debug!("Detected prometheus crds operator present in cluster.");
|
||||||
} else {
|
return Ok(po_result);
|
||||||
todo!()
|
}
|
||||||
|
PreparationOutcome::Noop => {
|
||||||
|
debug!("Skipping Prometheus CR installation due to missing operator.");
|
||||||
|
return Ok(po_result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,6 +244,7 @@ impl PrometheusMonitoring<RHOBObservability> for K8sAnywhereTopology {
|
|||||||
Err(err) => Err(PreparationError::new(err.to_string())),
|
Err(err) => Err(PreparationError::new(err.to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn ensure_prometheus_operator(
|
async fn ensure_prometheus_operator(
|
||||||
&self,
|
&self,
|
||||||
sender: &RHOBObservability,
|
sender: &RHOBObservability,
|
||||||
@ -300,6 +334,95 @@ impl K8sAnywhereTopology {
|
|||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_grafana_datasource(
|
||||||
|
&self,
|
||||||
|
ns: &str,
|
||||||
|
label_selector: &LabelSelector,
|
||||||
|
) -> GrafanaDatasource {
|
||||||
|
let mut json_data = BTreeMap::new();
|
||||||
|
json_data.insert("timeInterval".to_string(), "5s".to_string());
|
||||||
|
|
||||||
|
let graf_data_source = GrafanaDatasource {
|
||||||
|
metadata: ObjectMeta {
|
||||||
|
name: Some(format!("grafana-datasource-{}", ns)),
|
||||||
|
namespace: Some(ns.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
spec: GrafanaDatasourceSpec {
|
||||||
|
instance_selector: label_selector.clone(),
|
||||||
|
allow_cross_namespace_import: Some(false),
|
||||||
|
datasource: GrafanaDatasourceConfig {
|
||||||
|
access: "proxy".to_string(),
|
||||||
|
database: Some("prometheus".to_string()),
|
||||||
|
json_data: Some(json_data),
|
||||||
|
//this is fragile
|
||||||
|
name: format!("prometheus-{}-0", ns),
|
||||||
|
r#type: "prometheus".to_string(),
|
||||||
|
url: format!("http://prometheus-operated.{}.svc.cluster.local:9090", ns),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
graf_data_source
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_grafana_dashboard(
|
||||||
|
&self,
|
||||||
|
ns: &str,
|
||||||
|
label_selector: &LabelSelector,
|
||||||
|
) -> GrafanaDashboard {
|
||||||
|
let json = build_default_dashboard(ns);
|
||||||
|
let graf_dashboard = GrafanaDashboard {
|
||||||
|
metadata: ObjectMeta {
|
||||||
|
name: Some(format!("grafana-dashboard-{}", ns)),
|
||||||
|
namespace: Some(ns.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
spec: GrafanaDashboardSpec {
|
||||||
|
resync_period: Some("30s".to_string()),
|
||||||
|
instance_selector: label_selector.clone(),
|
||||||
|
json,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
graf_dashboard
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_grafana(&self, ns: &str, labels: &BTreeMap<String, String>) -> GrafanaCRD {
|
||||||
|
let grafana = GrafanaCRD {
|
||||||
|
metadata: ObjectMeta {
|
||||||
|
name: Some(format!("grafana-{}", ns)),
|
||||||
|
namespace: Some(ns.to_string()),
|
||||||
|
labels: Some(labels.clone()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
spec: GrafanaSpec {
|
||||||
|
config: None,
|
||||||
|
admin_user: None,
|
||||||
|
admin_password: None,
|
||||||
|
ingress: None,
|
||||||
|
persistence: None,
|
||||||
|
resources: None,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
grafana
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn build_grafana_ingress(&self, ns: &str) -> K8sIngressScore {
|
||||||
|
let domain = self.get_domain(&format!("grafana-{}", ns)).await.unwrap();
|
||||||
|
let name = format!("{}-grafana", ns);
|
||||||
|
let backend_service = format!("grafana-{}-service", ns);
|
||||||
|
|
||||||
|
K8sIngressScore {
|
||||||
|
name: fqdn::fqdn!(&name),
|
||||||
|
host: fqdn::fqdn!(&domain),
|
||||||
|
backend_service: fqdn::fqdn!(&backend_service),
|
||||||
|
port: 3000,
|
||||||
|
path: Some("/".to_string()),
|
||||||
|
path_type: Some(PathType::Prefix),
|
||||||
|
namespace: Some(fqdn::fqdn!(&ns)),
|
||||||
|
ingress_class_name: Some("openshift-default".to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_cluster_observability_operator_prometheus_application_score(
|
async fn get_cluster_observability_operator_prometheus_application_score(
|
||||||
&self,
|
&self,
|
||||||
sender: RHOBObservability,
|
sender: RHOBObservability,
|
||||||
@ -607,7 +730,14 @@ impl K8sAnywhereTopology {
|
|||||||
inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
ns: Option<&str>,
|
ns: Option<&str>,
|
||||||
) -> Result<PreparationOutcome, PreparationError> {
|
) -> Result<PreparationOutcome, PreparationError> {
|
||||||
let _grafana_operator_score = grafana_helm_chart_score(ns.unwrap(), true)
|
let namespace = ns.unwrap_or("grafana");
|
||||||
|
info!("installing grafana operator in ns {namespace}");
|
||||||
|
let tenant = self.get_k8s_tenant_manager()?.get_tenant_config().await;
|
||||||
|
let mut namespace_scope = false;
|
||||||
|
if tenant.is_some() {
|
||||||
|
namespace_scope = true;
|
||||||
|
}
|
||||||
|
let _grafana_operator_score = grafana_helm_chart_score(namespace, namespace_scope)
|
||||||
.interpret(inventory, self)
|
.interpret(inventory, self)
|
||||||
.await;
|
.await;
|
||||||
Ok(PreparationOutcome::Success {
|
Ok(PreparationOutcome::Success {
|
||||||
|
@ -30,6 +30,7 @@ impl<S: AlertSender + Installable<T>, T: Topology> Interpret<T> for AlertingInte
|
|||||||
inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
topology: &T,
|
topology: &T,
|
||||||
) -> Result<Outcome, InterpretError> {
|
) -> Result<Outcome, InterpretError> {
|
||||||
|
debug!("hit sender configure for AlertingInterpret");
|
||||||
self.sender.configure(inventory, topology).await?;
|
self.sender.configure(inventory, topology).await?;
|
||||||
for receiver in self.receivers.iter() {
|
for receiver in self.receivers.iter() {
|
||||||
receiver.install(&self.sender).await?;
|
receiver.install(&self.sender).await?;
|
||||||
@ -38,6 +39,7 @@ impl<S: AlertSender + Installable<T>, T: Topology> Interpret<T> for AlertingInte
|
|||||||
debug!("installing rule: {:#?}", rule);
|
debug!("installing rule: {:#?}", rule);
|
||||||
rule.install(&self.sender).await?;
|
rule.install(&self.sender).await?;
|
||||||
}
|
}
|
||||||
|
debug!("hit sender ensure installed for AlertingInterpret");
|
||||||
self.sender.ensure_installed(inventory, topology).await?;
|
self.sender.ensure_installed(inventory, topology).await?;
|
||||||
Ok(Outcome::success(format!(
|
Ok(Outcome::success(format!(
|
||||||
"successfully installed alert sender {}",
|
"successfully installed alert sender {}",
|
||||||
|
@ -2,7 +2,11 @@ use crate::modules::application::{
|
|||||||
Application, ApplicationFeature, InstallationError, InstallationOutcome,
|
Application, ApplicationFeature, InstallationError, InstallationOutcome,
|
||||||
};
|
};
|
||||||
use crate::modules::monitoring::application_monitoring::application_monitoring_score::ApplicationMonitoringScore;
|
use crate::modules::monitoring::application_monitoring::application_monitoring_score::ApplicationMonitoringScore;
|
||||||
|
use crate::modules::monitoring::grafana::grafana::Grafana;
|
||||||
use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::CRDPrometheus;
|
use crate::modules::monitoring::kube_prometheus::crd::crd_alertmanager_config::CRDPrometheus;
|
||||||
|
use crate::modules::monitoring::kube_prometheus::crd::service_monitor::{
|
||||||
|
ServiceMonitor, ServiceMonitorSpec,
|
||||||
|
};
|
||||||
use crate::topology::MultiTargetTopology;
|
use crate::topology::MultiTargetTopology;
|
||||||
use crate::topology::ingress::Ingress;
|
use crate::topology::ingress::Ingress;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -22,6 +26,7 @@ use base64::{Engine as _, engine::general_purpose};
|
|||||||
use harmony_secret::SecretManager;
|
use harmony_secret::SecretManager;
|
||||||
use harmony_secret_derive::Secret;
|
use harmony_secret_derive::Secret;
|
||||||
use harmony_types::net::Url;
|
use harmony_types::net::Url;
|
||||||
|
use kube::api::ObjectMeta;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -41,6 +46,7 @@ impl<
|
|||||||
+ K8sclient
|
+ K8sclient
|
||||||
+ MultiTargetTopology
|
+ MultiTargetTopology
|
||||||
+ PrometheusMonitoring<CRDPrometheus>
|
+ PrometheusMonitoring<CRDPrometheus>
|
||||||
|
+ Grafana
|
||||||
+ Ingress
|
+ Ingress
|
||||||
+ std::fmt::Debug,
|
+ std::fmt::Debug,
|
||||||
> ApplicationFeature<T> for Monitoring
|
> ApplicationFeature<T> for Monitoring
|
||||||
@ -57,11 +63,20 @@ impl<
|
|||||||
.unwrap_or_else(|| self.application.name());
|
.unwrap_or_else(|| self.application.name());
|
||||||
let domain = topology.get_domain("ntfy").await.unwrap();
|
let domain = topology.get_domain("ntfy").await.unwrap();
|
||||||
|
|
||||||
|
let app_service_monitor = ServiceMonitor {
|
||||||
|
metadata: ObjectMeta {
|
||||||
|
name: Some(self.application.name()),
|
||||||
|
namespace: Some(namespace.clone()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
spec: ServiceMonitorSpec::default(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut alerting_score = ApplicationMonitoringScore {
|
let mut alerting_score = ApplicationMonitoringScore {
|
||||||
sender: CRDPrometheus {
|
sender: CRDPrometheus {
|
||||||
namespace: namespace.clone(),
|
namespace: namespace.clone(),
|
||||||
client: topology.k8s_client().await.unwrap(),
|
client: topology.k8s_client().await.unwrap(),
|
||||||
service_monitor: vec![],
|
service_monitor: vec![app_service_monitor],
|
||||||
},
|
},
|
||||||
application: self.application.clone(),
|
application: self.application.clone(),
|
||||||
receivers: self.alert_receiver.clone(),
|
receivers: self.alert_receiver.clone(),
|
||||||
|
@ -1,21 +1,23 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use log::debug;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data::Version,
|
interpret::Interpret,
|
||||||
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
|
||||||
inventory::Inventory,
|
|
||||||
modules::{
|
modules::{
|
||||||
application::Application,
|
application::Application,
|
||||||
monitoring::kube_prometheus::crd::crd_alertmanager_config::CRDPrometheus,
|
monitoring::{
|
||||||
|
grafana::grafana::Grafana, kube_prometheus::crd::crd_alertmanager_config::CRDPrometheus,
|
||||||
|
},
|
||||||
prometheus::prometheus::PrometheusMonitoring,
|
prometheus::prometheus::PrometheusMonitoring,
|
||||||
},
|
},
|
||||||
score::Score,
|
score::Score,
|
||||||
topology::{PreparationOutcome, Topology, oberservability::monitoring::AlertReceiver},
|
topology::{
|
||||||
|
K8sclient, Topology,
|
||||||
|
oberservability::monitoring::{AlertReceiver, AlertingInterpret},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use harmony_types::id::Id;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct ApplicationMonitoringScore {
|
pub struct ApplicationMonitoringScore {
|
||||||
@ -24,10 +26,15 @@ pub struct ApplicationMonitoringScore {
|
|||||||
pub receivers: Vec<Box<dyn AlertReceiver<CRDPrometheus>>>,
|
pub receivers: Vec<Box<dyn AlertReceiver<CRDPrometheus>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Topology + PrometheusMonitoring<CRDPrometheus>> Score<T> for ApplicationMonitoringScore {
|
impl<T: Topology + PrometheusMonitoring<CRDPrometheus> + K8sclient + Grafana> Score<T>
|
||||||
|
for ApplicationMonitoringScore
|
||||||
|
{
|
||||||
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||||
Box::new(ApplicationMonitoringInterpret {
|
debug!("creating alerting interpret");
|
||||||
score: self.clone(),
|
Box::new(AlertingInterpret {
|
||||||
|
sender: self.sender.clone(),
|
||||||
|
receivers: self.receivers.clone(),
|
||||||
|
rules: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,55 +45,3 @@ impl<T: Topology + PrometheusMonitoring<CRDPrometheus>> Score<T> for Application
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ApplicationMonitoringInterpret {
|
|
||||||
score: ApplicationMonitoringScore,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<T: Topology + PrometheusMonitoring<CRDPrometheus>> Interpret<T>
|
|
||||||
for ApplicationMonitoringInterpret
|
|
||||||
{
|
|
||||||
async fn execute(
|
|
||||||
&self,
|
|
||||||
inventory: &Inventory,
|
|
||||||
topology: &T,
|
|
||||||
) -> Result<Outcome, InterpretError> {
|
|
||||||
let result = topology
|
|
||||||
.install_prometheus(
|
|
||||||
&self.score.sender,
|
|
||||||
inventory,
|
|
||||||
Some(self.score.receivers.clone()),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(outcome) => match outcome {
|
|
||||||
PreparationOutcome::Success { details: _ } => {
|
|
||||||
Ok(Outcome::success("Prometheus installed".into()))
|
|
||||||
}
|
|
||||||
PreparationOutcome::Noop => {
|
|
||||||
Ok(Outcome::noop("Prometheus installation skipped".into()))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(err) => Err(InterpretError::from(err)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_name(&self) -> InterpretName {
|
|
||||||
InterpretName::ApplicationMonitoring
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_version(&self) -> Version {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_status(&self) -> InterpretStatus {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_children(&self) -> Vec<Id> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use k8s_openapi::Resource;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
inventory::Inventory,
|
inventory::Inventory,
|
||||||
@ -7,9 +8,10 @@ use crate::{
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Grafana {
|
pub trait Grafana {
|
||||||
async fn ensure_grafana_operator_ready(
|
async fn ensure_grafana_operator(
|
||||||
&self,
|
&self,
|
||||||
inventory: &Inventory,
|
inventory: &Inventory,
|
||||||
) -> Result<PreparationOutcome, PreparationError>;
|
) -> Result<PreparationOutcome, PreparationError>;
|
||||||
|
|
||||||
async fn install_grafana(&self) -> Result<PreparationOutcome, PreparationError>;
|
async fn install_grafana(&self) -> Result<PreparationOutcome, PreparationError>;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
use non_blank_string_rs::NonBlankString;
|
use non_blank_string_rs::NonBlankString;
|
||||||
use std::{collections::HashMap, str::FromStr};
|
use std::{collections::HashMap, str::FromStr};
|
||||||
|
|
||||||
use crate::modules::helm::chart::HelmChartScore;
|
use crate::modules::helm::chart::{HelmChartScore, HelmRepository};
|
||||||
|
|
||||||
pub fn grafana_helm_chart_score(ns: &str, scope: bool) -> HelmChartScore {
|
pub fn grafana_helm_chart_score(ns: &str, namespace_scope: bool) -> HelmChartScore {
|
||||||
let mut values_overrides = HashMap::new();
|
let mut values_overrides = HashMap::new();
|
||||||
values_overrides.insert(
|
values_overrides.insert(
|
||||||
NonBlankString::from_str("namespaceScope").unwrap(),
|
NonBlankString::from_str("namespaceScope").unwrap(),
|
||||||
scope.to_string(),
|
namespace_scope.to_string(),
|
||||||
);
|
);
|
||||||
HelmChartScore {
|
HelmChartScore {
|
||||||
namespace: Some(NonBlankString::from_str(ns).unwrap()),
|
namespace: Some(NonBlankString::from_str(ns).unwrap()),
|
||||||
release_name: NonBlankString::from_str("grafana").unwrap(),
|
release_name: NonBlankString::from_str("grafana-operator").unwrap(),
|
||||||
chart_name: NonBlankString::from_str("oci://ghcr.io/grafana/helm-charts/grafana-operator")
|
chart_name: NonBlankString::from_str("grafana/grafana-operator").unwrap(),
|
||||||
.unwrap(),
|
|
||||||
chart_version: None,
|
chart_version: None,
|
||||||
values_overrides: Some(values_overrides),
|
values_overrides: Some(values_overrides),
|
||||||
values_yaml: None,
|
values_yaml: None,
|
||||||
create_namespace: true,
|
create_namespace: true,
|
||||||
install_only: true,
|
install_only: true,
|
||||||
repository: None,
|
repository: Some(HelmRepository::new(
|
||||||
|
"grafana".to_string(),
|
||||||
|
url::Url::parse("https://grafana.github.io/helm-charts").unwrap(),
|
||||||
|
true,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ impl<T: Topology + K8sclient + PrometheusMonitoring<CRDPrometheus> + Grafana> In
|
|||||||
for CRDPrometheus
|
for CRDPrometheus
|
||||||
{
|
{
|
||||||
async fn configure(&self, inventory: &Inventory, topology: &T) -> Result<(), InterpretError> {
|
async fn configure(&self, inventory: &Inventory, topology: &T) -> Result<(), InterpretError> {
|
||||||
topology.ensure_grafana_operator_ready(inventory).await?;
|
topology.ensure_grafana_operator(inventory).await?;
|
||||||
topology.ensure_prometheus_operator(self, inventory).await?;
|
topology.ensure_prometheus_operator(self, inventory).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user