diff --git a/Cargo.lock b/Cargo.lock index a1cfa80..bbb43a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cm-dashboard" -version = "0.1.259" +version = "0.1.260" dependencies = [ "anyhow", "chrono", @@ -301,7 +301,7 @@ dependencies = [ [[package]] name = "cm-dashboard-agent" -version = "0.1.259" +version = "0.1.260" dependencies = [ "anyhow", "async-trait", @@ -325,7 +325,7 @@ dependencies = [ [[package]] name = "cm-dashboard-shared" -version = "0.1.259" +version = "0.1.260" dependencies = [ "chrono", "serde", diff --git a/agent/Cargo.toml b/agent/Cargo.toml index 5683fbe..8f1a812 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-agent" -version = "0.1.260" +version = "0.1.261" edition = "2021" [dependencies] diff --git a/agent/src/collectors/network.rs b/agent/src/collectors/network.rs index fd4dbe2..8177a7a 100644 --- a/agent/src/collectors/network.rs +++ b/agent/src/collectors/network.rs @@ -181,6 +181,7 @@ impl NetworkCollector { link_status, parent_interface, vlan_id, + connection_method: None, }); } } diff --git a/agent/src/collectors/systemd.rs b/agent/src/collectors/systemd.rs index 487e638..9a30322 100644 --- a/agent/src/collectors/systemd.rs +++ b/agent/src/collectors/systemd.rs @@ -216,6 +216,19 @@ impl SystemdCollector { } } + if service_name == "tailscaled" && status_info.active_state == "active" { + // Add Tailscale connection method as sub-service + if let Some(conn_method) = self.get_tailscale_connection_method() { + let metrics = Vec::new(); + sub_services.push(SubServiceData { + name: format!("Connection: {}", conn_method), + service_status: Status::Info, + metrics, + service_type: "tailscale_connection".to_string(), + }); + } + } + // Create complete service data let service_data = ServiceData { name: service_name.clone(), @@ -923,6 +936,53 @@ impl SystemdCollector { None } + /// Get Tailscale connection method (direct, relay, or proxy) + fn get_tailscale_connection_method(&self) -> Option { + match Command::new("timeout") + .args(["2", "tailscale", "status", "--json"]) + .output() + { + Ok(output) if output.status.success() => { + let json_str = String::from_utf8_lossy(&output.stdout); + + if let Ok(json_data) = serde_json::from_str::(&json_str) { + // Look for the self peer (current node) in the peer list + if let Some(peers) = json_data["Peer"].as_object() { + // Find the first active peer connection to determine connection method + for (_peer_id, peer_data) in peers { + if peer_data["Active"].as_bool().unwrap_or(false) { + // Check if using relay + let relay_node = peer_data["Relay"].as_str().unwrap_or(""); + if !relay_node.is_empty() { + return Some("relay".to_string()); + } + + // Check if using direct connection + if let Some(endpoints) = peer_data["CurAddr"].as_str() { + if !endpoints.is_empty() { + return Some("direct".to_string()); + } + } + } + } + } + + // Check if using proxy from backend state + if let Some(backend_state) = json_data["BackendState"].as_str() { + if backend_state == "Running" { + // If we're running but have no direct or relay, might be proxy + // This is a fallback heuristic + return Some("unknown".to_string()); + } + } + } + + None + } + _ => None, + } + } + /// Get nftables open ports grouped by protocol /// Returns: (tcp_ports_string, udp_ports_string) fn get_nftables_open_ports(&self) -> (String, String) { diff --git a/dashboard/Cargo.toml b/dashboard/Cargo.toml index dd2db54..b069bcb 100644 --- a/dashboard/Cargo.toml +++ b/dashboard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard" -version = "0.1.260" +version = "0.1.261" edition = "2021" [dependencies] diff --git a/shared/Cargo.toml b/shared/Cargo.toml index d31e316..b2293e7 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-shared" -version = "0.1.260" +version = "0.1.261" edition = "2021" [dependencies] diff --git a/shared/src/agent_data.rs b/shared/src/agent_data.rs index 370930d..96e9d36 100644 --- a/shared/src/agent_data.rs +++ b/shared/src/agent_data.rs @@ -38,6 +38,7 @@ pub struct NetworkInterfaceData { pub link_status: Status, pub parent_interface: Option, pub vlan_id: Option, + pub connection_method: Option, // For Tailscale: "direct", "relay", or "proxy" } /// CPU C-state usage information