fix: refactor so that the topology installs the MonitoringAlertingStack depending on if it is already present in the cluster
This commit is contained in:
parent
e7cfbf914a
commit
88270ece61
@ -1,9 +1,21 @@
|
|||||||
|
use log::warn;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::sync::OnceCell;
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
|
use k8s_openapi::api::core::v1::Pod;
|
||||||
|
use kube::{
|
||||||
|
Client,
|
||||||
|
api::{Api, ListParams},
|
||||||
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::interpret::{InterpretError, Outcome};
|
use crate::{
|
||||||
|
interpret::{InterpretError, Outcome},
|
||||||
|
inventory::Inventory,
|
||||||
|
maestro::Maestro,
|
||||||
|
modules::monitoring::monitoring_alerting::MonitoringAlertingStackScore,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{HelmCommand, Topology};
|
use super::{HelmCommand, Topology};
|
||||||
|
|
||||||
@ -17,21 +29,75 @@ pub struct MonitoringAlertingTopology {
|
|||||||
monitoring_state: OnceCell<Option<MonitoringState>>,
|
monitoring_state: OnceCell<Option<MonitoringState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl MonitoringAlertingTopology {
|
impl MonitoringAlertingTopology {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
monitoring_state: OnceCell::new(),
|
monitoring_state: OnceCell::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_monitoring_state(&self) -> Result<Option<MonitoringState>, InterpretError> {
|
|
||||||
let state = MonitoringState {
|
async fn get_monitoring_state(&self) -> Result<Option<MonitoringState>, InterpretError> {
|
||||||
message: "monitoring stack not installed".to_string(),
|
let client = Client::try_default()
|
||||||
|
.await
|
||||||
|
.map_err(|e| InterpretError::new(format!("Kubernetes client error: {}", e)))?;
|
||||||
|
|
||||||
|
for ns in &["monitoring", "openshift-monitoring"] {
|
||||||
|
let pods: Api<Pod> = Api::namespaced(client.clone(), ns);
|
||||||
|
let lp = ListParams::default().labels("app.kubernetes.io/name=prometheus");
|
||||||
|
|
||||||
|
match pods.list(&lp).await {
|
||||||
|
Ok(pod_list) => {
|
||||||
|
for p in pod_list.items {
|
||||||
|
if let Some(status) = p.status {
|
||||||
|
if let Some(conditions) = status.conditions {
|
||||||
|
if conditions
|
||||||
|
.iter()
|
||||||
|
.any(|c| c.type_ == "Ready" && c.status == "True")
|
||||||
|
{
|
||||||
|
return Ok(Some(MonitoringState {
|
||||||
|
message: format!(
|
||||||
|
"Prometheus is ready in namespace: {}",
|
||||||
|
ns
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Failed to query pods in ns {}: {}", ns, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn try_install_monitoring_stack(
|
||||||
|
&self,
|
||||||
|
) -> Result<Option<MonitoringState>, InterpretError> {
|
||||||
|
let inventory = Inventory::autoload();
|
||||||
|
let topology = MonitoringAlertingTopology::new();
|
||||||
|
let mut maestro = match Maestro::initialize(inventory, topology).await {
|
||||||
|
Ok(m) => m,
|
||||||
|
Err(e) => {
|
||||||
|
println!("failed to initialize Maestro: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
maestro.register_all(vec![Box::new(MonitoringAlertingStackScore::default())]);
|
||||||
|
let state = match self.get_monitoring_state().await {
|
||||||
|
Ok(_) => MonitoringState {
|
||||||
|
message: "Monitoring Stack Ready".to_string(),
|
||||||
|
},
|
||||||
|
Err(_) => todo!(),
|
||||||
};
|
};
|
||||||
Ok(Some(state))
|
Ok(Some(state))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Topology for MonitoringAlertingTopology {
|
impl Topology for MonitoringAlertingTopology {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
@ -39,20 +105,14 @@ impl Topology for MonitoringAlertingTopology {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn ensure_ready(&self) -> Result<Outcome, InterpretError> {
|
async fn ensure_ready(&self) -> Result<Outcome, InterpretError> {
|
||||||
let monitoring_state = self
|
let state = if let Some(state) = self.get_monitoring_state().await? {
|
||||||
.monitoring_state
|
state
|
||||||
.get_or_try_init(|| async { self.get_monitoring_state() })
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if monitoring_state.is_some() {
|
|
||||||
Ok(Outcome::success(
|
|
||||||
"Monitoring stack already installed".to_string(),
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Outcome::success(
|
self.try_install_monitoring_stack().await?
|
||||||
"Monitoring stack not installed".to_string(),
|
.ok_or_else(|| InterpretError::new("Failed to install monitoring stack".into()))?
|
||||||
))
|
};
|
||||||
}
|
|
||||||
|
Ok(Outcome::success(state.message))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -69,26 +69,6 @@ struct MonitoringAlertingStackInterpret {
|
|||||||
pub score: MonitoringAlertingStackScore,
|
pub score: MonitoringAlertingStackScore,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitoringAlertingStackInterpret {
|
|
||||||
pub async fn build_monitoring_stack(
|
|
||||||
&self,
|
|
||||||
monitoring_stack: MonitoringAlertingStackScore,
|
|
||||||
) -> Result<Outcome, InterpretError> {
|
|
||||||
let inventory = Inventory::autoload();
|
|
||||||
let topology = MonitoringAlertingTopology::new();
|
|
||||||
let mut maestro = match Maestro::initialize(inventory, topology).await {
|
|
||||||
Ok(m) => m,
|
|
||||||
Err(e) => {
|
|
||||||
println!("failed to initialize Maestro: {}", e);
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
maestro.register_all(monitoring_stack.monitoring_stack);
|
|
||||||
Ok(Outcome::success(format!(
|
|
||||||
"installed kube-prometheus monitoring and alerting stack"
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: Topology> Interpret<T> for MonitoringAlertingStackInterpret {
|
impl<T: Topology> Interpret<T> for MonitoringAlertingStackInterpret {
|
||||||
@ -97,7 +77,7 @@ impl<T: Topology> Interpret<T> for MonitoringAlertingStackInterpret {
|
|||||||
_inventory: &Inventory,
|
_inventory: &Inventory,
|
||||||
_topology: &T,
|
_topology: &T,
|
||||||
) -> Result<Outcome, InterpretError> {
|
) -> Result<Outcome, InterpretError> {
|
||||||
self.build_monitoring_stack(self.score.clone()).await
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_name(&self) -> InterpretName {
|
fn get_name(&self) -> InterpretName {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user