use crate::error::{NucleusError, Result};
use std::collections::BTreeMap;
use std::path::Path;
use tracing::info;
#[derive(Debug, Clone)]
pub struct DnsRecord {
pub name: String,
pub ip: String,
}
pub fn generate_hosts_entries(
topology_name: &str,
service_ips: &BTreeMap<String, String>,
) -> String {
let mut entries = String::new();
entries.push_str("# Nucleus topology DNS entries\n");
for (service_name, ip) in service_ips {
entries.push_str(&format!(
"{}\t{}\t{}-{}\n",
ip, service_name, topology_name, service_name
));
}
entries
}
pub fn inject_hosts(
container_root: &Path,
topology_name: &str,
service_ips: &BTreeMap<String, String>,
) -> Result<()> {
let hosts_path = container_root.join("etc/hosts");
let entries = generate_hosts_entries(topology_name, service_ips);
let existing = std::fs::read_to_string(&hosts_path).unwrap_or_default();
let new_content = format!(
"{}\n127.0.0.1\tlocalhost\n::1\tlocalhost\n{}\n",
existing.trim(),
entries
);
std::fs::write(&hosts_path, new_content).map_err(|e| {
NucleusError::NetworkError(format!(
"Failed to write topology DNS entries to {:?}: {}",
hosts_path, e
))
})?;
info!(
"Injected {} DNS entries for topology '{}'",
service_ips.len(),
topology_name
);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_generate_hosts_entries() {
let mut ips = BTreeMap::new();
ips.insert("postgres".to_string(), "10.42.0.2".to_string());
ips.insert("web".to_string(), "10.42.0.3".to_string());
let entries = generate_hosts_entries("myapp", &ips);
assert!(entries.contains("10.42.0.2\tpostgres\tmyapp-postgres"));
assert!(entries.contains("10.42.0.3\tweb\tmyapp-web"));
}
}