fix: deploys by default in the application name namespace

This commit is contained in:
Willem 2025-07-07 13:24:21 -04:00
parent 1a6d72dc17
commit 2c208df143
5 changed files with 58 additions and 23 deletions

View File

@ -1,3 +1,5 @@
use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use log::info; use log::info;
@ -7,29 +9,30 @@ use crate::{
application::{Application, ApplicationFeature}, application::{Application, ApplicationFeature},
monitoring::{ monitoring::{
application_monitoring::k8s_application_monitoring_score::ApplicationPrometheusMonitoringScore, application_monitoring::k8s_application_monitoring_score::ApplicationPrometheusMonitoringScore,
kube_prometheus::{ kube_prometheus::types::{NamespaceSelector, ServiceMonitor},
helm_prometheus_alert_score::HelmPrometheusAlertingScore,
types::{NamespaceSelector, ServiceMonitor},
},
}, },
}, },
score::Score, score::Score,
topology::{HelmCommand, Topology, tenant::TenantManager}, topology::{HelmCommand, Topology, tenant::TenantManager},
}; };
#[derive(Debug, Default, Clone)] #[derive(Debug, Clone)]
pub struct Monitoring {} pub struct Monitoring {
pub application: Arc<dyn Application>,
}
#[async_trait] #[async_trait]
impl<T: Topology + HelmCommand + 'static + TenantManager> ApplicationFeature<T> for Monitoring { impl<T: Topology + HelmCommand + 'static + TenantManager> ApplicationFeature<T> for Monitoring {
async fn ensure_installed(&self, topology: &T) -> Result<(), String> { async fn ensure_installed(&self, topology: &T) -> Result<(), String> {
info!("Ensuring monitoring is available for application"); info!("Ensuring monitoring is available for application");
let ns = self.application.name();
let mut service_monitor = ServiceMonitor::default(); let mut service_monitor = ServiceMonitor::default();
service_monitor.namespace_selector = Some(NamespaceSelector { service_monitor.namespace_selector = Some(NamespaceSelector {
any: true, any: true,
match_names: vec![], match_names: vec![ns.clone()],
}); });
let alerting_score = ApplicationPrometheusMonitoringScore { let alerting_score = ApplicationPrometheusMonitoringScore {
namespace: ns,
receivers: vec![], receivers: vec![],
rules: vec![], rules: vec![],
service_monitors: vec![service_monitor], service_monitors: vec![service_monitor],

View File

@ -1,5 +1,6 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use log::debug;
use serde::Serialize; use serde::Serialize;
use crate::{ use crate::{
@ -17,6 +18,7 @@ use crate::{
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]
pub struct ApplicationPrometheusMonitoringScore { pub struct ApplicationPrometheusMonitoringScore {
pub namespace: String,
pub receivers: Vec<Box<dyn AlertReceiver<Prometheus>>>, pub receivers: Vec<Box<dyn AlertReceiver<Prometheus>>>,
pub rules: Vec<Box<dyn AlertRule<Prometheus>>>, pub rules: Vec<Box<dyn AlertRule<Prometheus>>>,
pub service_monitors: Vec<ServiceMonitor>, pub service_monitors: Vec<ServiceMonitor>,
@ -29,8 +31,12 @@ impl<T: Topology + HelmCommand + TenantManager> Score<T> for ApplicationPromethe
.try_lock() .try_lock()
.expect("couldn't lock config") .expect("couldn't lock config")
.additional_service_monitors = self.service_monitors.clone(); .additional_service_monitors = self.service_monitors.clone();
let ns = self.namespace.clone();
config.try_lock().expect("couldn't lock config").namespace = Some(ns.clone());
debug!("set namespace to {}", ns);
Box::new(AlertingInterpret { Box::new(AlertingInterpret {
sender: Prometheus::new(), sender: Prometheus { config },
receivers: self.receivers.clone(), receivers: self.receivers.clone(),
rules: self.rules.clone(), rules: self.rules.clone(),
}) })

View File

@ -8,9 +8,34 @@ pub fn grafana_helm_chart_score(ns: &str) -> HelmChartScore {
r#" r#"
rbac: rbac:
namespaced: true namespaced: true
sidecar: datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus-server.{ns}.svc.cluster.local
isDefault: true
downloadDashboards:
dashboards: dashboards:
enabled: true - url: https://raw.githubusercontent.com/grafana/grafana/main/devenv/dev-dashboards/node-exporter-full_rev1.json
file: node-exporter-full.json
- url: https://grafana.com/api/dashboards/7685/revisions/1/download
file: kubernetes-pvs-usage.json
# Namespace resource usage vs quotas
- url: https://grafana.com/api/dashboards/17044/revisions/1/download
file: namespace-resources-vs-quotas.json
# Kubernetes namespace resources (CPU, RAM, network)
- url: https://grafana.com/api/dashboards/9809/revisions/1/download
file: kubernetes-namespace-resources.json
# Top 10 namespaces by memory usage
- url: https://grafana.com/api/dashboards/10678/revisions/1/download
file: top10-namespace-memory.json
"# "#
); );
@ -22,7 +47,7 @@ sidecar:
values_overrides: None, values_overrides: None,
values_yaml: Some(values.to_string()), values_yaml: Some(values.to_string()),
create_namespace: true, create_namespace: true,
install_only: true, install_only: false,
repository: None, repository: None,
} }
} }

View File

@ -12,21 +12,23 @@ pub fn prometheus_helm_chart_score(config: Arc<Mutex<PrometheusConfig>>) -> Helm
let ns = config.namespace.clone().unwrap(); let ns = config.namespace.clone().unwrap();
let values = format!( let values = format!(
r#" r#"
releaseNamespace: true
rbac: rbac:
create: true create: true
namespaced: true
kube-state-metrics: kube-state-metrics:
enabled: false enabled: false
nodeExporter: prometheus-node-exporter:
enabled: false enabled: false
alertmanager: alertmanager:
enabled: false enabled: true
pushgateway: pushgateway:
enabled: false enabled: false
server: server:
serviceAccount: serviceAccount:
create: false
rbac:
create: true create: true
rbac:
create: false
fullnameOverride: prometheus-{ns} fullnameOverride: prometheus-{ns}
"# "#
); );
@ -41,7 +43,7 @@ fullnameOverride: prometheus-{ns}
values_overrides: None, values_overrides: None,
values_yaml: Some(values.to_string()), values_yaml: Some(values.to_string()),
create_namespace: true, create_namespace: true,
install_only: true, install_only: false,
repository: None, repository: None,
} }
} }

View File

@ -44,14 +44,13 @@ impl Prometheus {
} }
} }
pub async fn configure_with_topology<T: TenantManager>(&self, topology: &T) { pub async fn configure_with_topology<T: TenantManager>(&self, topology: &T) {
let ns = topology if let Some(cfg) = topology.get_tenant_config().await {
.get_tenant_config() debug!("Overriding namespace with tenant config: {}", cfg.name);
.await self.config.lock().unwrap().namespace = Some(cfg.name.clone());
.map(|cfg| cfg.name.clone()) } else {
.unwrap_or_else(|| "monitoring".to_string()); debug!("No tenant config found; keeping existing namespace.");
}
error!("This must be refactored, see comments in pr #74"); error!("This must be refactored, see comments in pr #74");
debug!("NS: {}", ns);
self.config.lock().unwrap().namespace = Some(ns);
} }
pub async fn install_receiver( pub async fn install_receiver(