use super::apply_helpers::run_notify;
use super::colors::{green, red};
use crate::core::types;
use crate::tripwire::drift;
pub(super) fn census_json(name: &str, census: &drift::DriftCensus) -> serde_json::Value {
let mut value = census.to_json();
if let Some(obj) = value.as_object_mut() {
obj.insert("machine".to_string(), serde_json::json!(name));
}
value
}
pub(super) fn print_drift_summary(
machines_checked: u32,
total_drift: usize,
all_findings: &[serde_json::Value],
censuses: &[serde_json::Value],
json: bool,
) -> Result<(), String> {
let inspected: u64 = censuses
.iter()
.filter_map(|c| c["inspected"].as_u64())
.sum();
let skipped: u64 = censuses.iter().filter_map(|c| c["skipped"].as_u64()).sum();
if json {
let report = serde_json::json!({
"machines_checked": machines_checked,
"drift_count": total_drift,
"resources_inspected": inspected,
"resources_skipped": skipped,
"census": censuses,
"findings": all_findings,
});
let output =
serde_json::to_string_pretty(&report).map_err(|e| format!("JSON error: {e}"))?;
println!("{output}");
} else if total_drift > 0 {
println!();
println!(
"{}",
red(&format!("Drift detected: {total_drift} resource(s)"))
);
} else {
println!("{}", green("No drift detected."));
println!(" {inspected} resource(s) inspected, {skipped} not inspected.");
}
Ok(())
}
pub(super) fn run_drift_alert(alert_cmd: &str, total_drift: usize) -> Result<(), String> {
let status = std::process::Command::new("sh")
.arg("-c")
.arg(alert_cmd)
.env("FORJAR_DRIFT_COUNT", total_drift.to_string())
.status()
.map_err(|e| format!("alert-cmd failed to execute: {e}"))?;
if !status.success() {
eprintln!("alert-cmd exited with code {}", status.code().unwrap_or(-1));
}
Ok(())
}
pub(super) fn send_drift_notification(
config: &types::ForjarConfig,
total_drift: usize,
machine_filter: Option<&str>,
) {
if let Some(ref cmd) = config.policy.notify.on_drift {
let drift_str = total_drift.to_string();
let machine_str = machine_filter.unwrap_or("all");
run_notify(
cmd,
&[("machine", machine_str), ("drift_count", &drift_str)],
);
}
}