use super::census::DriftCensus;
use super::{DriftFinding, DRIFT_QUERY_TIMEOUT_SECS};
use crate::core::types::{Machine, ResourceType};
use crate::transport::ExecOutput;
pub const UNMEASURED: &str = "UNMEASURED";
const SSH_OWN_FAILURE: i32 = 255;
pub(super) enum Reading {
Answered(ExecOutput),
Unmeasured(String),
}
pub(super) fn read(machine: &Machine, script: &str) -> Reading {
let result =
crate::transport::exec_script_timeout(machine, script, Some(DRIFT_QUERY_TIMEOUT_SECS));
classify(machine, result)
}
pub(super) fn classify(machine: &Machine, result: Result<ExecOutput, String>) -> Reading {
match result {
Err(e) => Reading::Unmeasured(format!("transport error: {e}")),
Ok(out)
if out.exit_code == SSH_OWN_FAILURE && crate::transport::is_ssh_transport(machine) =>
{
Reading::Unmeasured(format!(
"ssh to {} failed before the query ran (exit 255): {}",
machine.addr,
out.stderr.trim()
))
}
Ok(out) => Reading::Answered(out),
}
}
impl DriftFinding {
pub fn unmeasured(
resource_id: &str,
resource_type: ResourceType,
expected_hash: &str,
detail: String,
) -> Self {
Self {
resource_id: resource_id.to_string(),
resource_type,
expected_hash: expected_hash.to_string(),
actual_hash: UNMEASURED.to_string(),
detail,
}
}
pub fn is_unmeasured(&self) -> bool {
self.actual_hash == UNMEASURED
}
}
pub(super) fn census_unmeasured(findings: &[DriftFinding], census: &mut DriftCensus) {
for f in findings.iter().filter(|f| f.is_unmeasured()) {
census.unmeasured(&f.resource_id, &f.resource_type);
}
}