use crate::error::NodeInfoError;
use crate::model::{Node, NodeSysCap, NodeSysInfo};
use crate::syscap_collector::SysCapCollector;
use crate::sysinfo_collector::SysInfoCollector;
use std::sync::Arc;
pub struct NodeInfoCollector {
sysinfo_collector: Arc<SysInfoCollector>,
syscap_collector: Arc<SysCapCollector>,
}
impl NodeInfoCollector {
#[must_use]
pub fn new() -> Self {
let sysinfo_collector = Arc::new(SysInfoCollector::new());
Self {
syscap_collector: Arc::new(SysCapCollector::new(Arc::clone(&sysinfo_collector))),
sysinfo_collector,
}
}
#[must_use]
pub fn create_current_node() -> Node {
let id = crate::get_hardware_uuid();
let hostname = sysinfo::System::host_name().unwrap_or_else(|| "unknown".to_owned());
let ip_address = Self::detect_local_ip();
let now = chrono::Utc::now();
Node {
id,
hostname,
ip_address,
created_at: now,
updated_at: now,
}
}
fn detect_local_ip() -> Option<String> {
match local_ip_address::local_ip() {
Ok(ip) => {
let ip_str = ip.to_string();
tracing::debug!(ip = %ip_str, "Detected local IP address");
Some(ip_str)
}
Err(e) => {
tracing::warn!(error = %e, "Failed to detect local IP address");
None
}
}
}
pub fn collect_sysinfo(&self, node_id: uuid::Uuid) -> Result<NodeSysInfo, NodeInfoError> {
self.sysinfo_collector
.collect(node_id)
.map_err(|e| NodeInfoError::SysInfoCollectionFailed(e.to_string()))
}
pub fn collect_syscap(&self, node_id: uuid::Uuid) -> Result<NodeSysCap, NodeInfoError> {
self.syscap_collector
.collect(node_id)
.map_err(|e| NodeInfoError::SysCapCollectionFailed(e.to_string()))
}
pub fn collect_all(
&self,
node_id: uuid::Uuid,
) -> Result<(NodeSysInfo, NodeSysCap), NodeInfoError> {
let sysinfo = self.collect_sysinfo(node_id)?;
let syscap = self.collect_syscap(node_id)?;
Ok((sysinfo, syscap))
}
}
impl Default for NodeInfoCollector {
fn default() -> Self {
Self::new()
}
}