Fix Tailscale peer detection by parsing text output
All checks were successful
Build and Release / build-and-release (push) Successful in 1m13s
All checks were successful
Build and Release / build-and-release (push) Successful in 1m13s
Replace JSON parsing with simpler text output parsing from tailscale status command. The text format clearly shows hostname and connection method (direct/relay/idle) making detection more reliable. Fixes issues with incorrect hostname (localhost instead of actual name) and incorrect connection method detection (showing relay when actually using direct connection).
This commit is contained in:
parent
5b1e39cfca
commit
8da4522d85
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
|
||||
|
||||
[[package]]
|
||||
name = "cm-dashboard"
|
||||
version = "0.1.262"
|
||||
version = "0.1.263"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -301,7 +301,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cm-dashboard-agent"
|
||||
version = "0.1.262"
|
||||
version = "0.1.263"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -325,7 +325,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cm-dashboard-shared"
|
||||
version = "0.1.262"
|
||||
version = "0.1.263"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cm-dashboard-agent"
|
||||
version = "0.1.263"
|
||||
version = "0.1.264"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -941,54 +941,52 @@ impl SystemdCollector {
|
||||
/// Returns a list of (device_name, connection_method) tuples
|
||||
fn get_tailscale_peers(&self) -> Vec<(String, String)> {
|
||||
match Command::new("timeout")
|
||||
.args(["2", "tailscale", "status", "--json"])
|
||||
.args(["2", "tailscale", "status"])
|
||||
.output()
|
||||
{
|
||||
Ok(output) if output.status.success() => {
|
||||
let json_str = String::from_utf8_lossy(&output.stdout);
|
||||
let status_output = String::from_utf8_lossy(&output.stdout);
|
||||
let mut peers = Vec::new();
|
||||
|
||||
if let Ok(json_data) = serde_json::from_str::<serde_json::Value>(&json_str) {
|
||||
// Look for the self peer (current node) in the peer list
|
||||
if let Some(peer_map) = json_data["Peer"].as_object() {
|
||||
// Iterate through all peers
|
||||
for (_peer_id, peer_data) in peer_map {
|
||||
// Only include active/online peers
|
||||
if !peer_data["Online"].as_bool().unwrap_or(false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get peer hostname or DNS name
|
||||
let peer_name = peer_data["HostName"]
|
||||
.as_str()
|
||||
.or_else(|| peer_data["DNSName"].as_str())
|
||||
.unwrap_or("unknown")
|
||||
.trim_end_matches('.')
|
||||
.to_string();
|
||||
|
||||
// Determine connection method
|
||||
let connection_method = 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() {
|
||||
"relay"
|
||||
} else if let Some(cur_addr) = peer_data["CurAddr"].as_str() {
|
||||
// Check if using direct connection
|
||||
if !cur_addr.is_empty() {
|
||||
"direct"
|
||||
} else {
|
||||
"unknown"
|
||||
}
|
||||
} else {
|
||||
"unknown"
|
||||
}
|
||||
} else {
|
||||
"idle"
|
||||
};
|
||||
|
||||
peers.push((peer_name, connection_method.to_string()));
|
||||
}
|
||||
// Parse tailscale status output
|
||||
// Format: IP hostname user os status
|
||||
// Example: 100.110.98.3 wslbox cm@ linux active; direct 192.168.30.227:53757
|
||||
for line in status_output.lines() {
|
||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||
if parts.len() < 5 {
|
||||
continue; // Skip invalid lines
|
||||
}
|
||||
|
||||
// parts[0] = IP
|
||||
// parts[1] = hostname
|
||||
// parts[2] = user
|
||||
// parts[3] = OS
|
||||
// parts[4+] = status (e.g., "active;", "direct", "192.168.30.227:53757" or "idle;" or "offline")
|
||||
|
||||
let hostname = parts[1];
|
||||
let status_parts = &parts[4..];
|
||||
|
||||
// Determine connection method from status
|
||||
let connection_method = if status_parts.is_empty() {
|
||||
continue; // Skip if no status
|
||||
} else {
|
||||
let status_str = status_parts.join(" ");
|
||||
if status_str.contains("offline") {
|
||||
continue; // Skip offline peers
|
||||
} else if status_str.contains("direct") {
|
||||
"direct"
|
||||
} else if status_str.contains("relay") {
|
||||
"relay"
|
||||
} else if status_str.contains("idle") {
|
||||
"idle"
|
||||
} else if status_str.contains("active") {
|
||||
"active"
|
||||
} else {
|
||||
continue; // Skip unknown status
|
||||
}
|
||||
};
|
||||
|
||||
peers.push((hostname.to_string(), connection_method.to_string()));
|
||||
}
|
||||
|
||||
peers
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cm-dashboard"
|
||||
version = "0.1.263"
|
||||
version = "0.1.264"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cm-dashboard-shared"
|
||||
version = "0.1.263"
|
||||
version = "0.1.264"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user