Files
SentinelMesh/agents/agent-scan-network/src/config.rs
T
gilles 57b5fd6b77 feat(agent-scan-network): implémentation Phase 2 — découverte réseau
- Scan ping TCP multi-ports (sans root requis)
- Lecture table ARP Linux (/proc/net/arp)
- Détection 20 services par scan de ports TCP
- Base OUI embarquée (~70 constructeurs courants)
- API JSON locale Axum sur :9100 (GET /devices, GET /health)
- Push automatique vers backend /api/v1/network
- Enregistrement agent au démarrage
- Config YAML (subnet 10.0.0.0/22, concurrence, timeouts)
- ROADMAP Phase 1 et 2 marquées complètes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 06:13:24 +02:00

62 lines
1.6 KiB
Rust

use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Config {
pub backend: BackendConfig,
pub agent: AgentConfig,
pub scan: ScanConfig,
pub api: ApiConfig,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BackendConfig {
pub url: String,
pub token: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AgentConfig {
pub id: String,
pub hostname: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ScanConfig {
pub subnets: Vec<String>,
pub interval_seconds: u64,
pub ping_timeout_ms: u64,
pub service_timeout_ms: u64,
pub concurrency: usize,
pub ports: Vec<u16>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ApiConfig {
pub listen: String,
}
impl Config {
pub fn load(path: &str) -> anyhow::Result<Self> {
let content = std::fs::read_to_string(path)?;
let mut cfg: Config = serde_yaml::from_str(&content)?;
cfg.resolve_defaults();
Ok(cfg)
}
fn resolve_defaults(&mut self) {
if self.agent.hostname.is_empty() {
self.agent.hostname = detect_hostname();
}
if self.agent.id.is_empty() {
self.agent.id = format!("scan-{}", self.agent.hostname);
}
}
}
fn detect_hostname() -> String {
// Lecture directe de /etc/hostname (Linux)
std::fs::read_to_string("/etc/hostname")
.map(|s| s.trim().to_string())
.unwrap_or_else(|_| "unknown".into())
}