Add Tailscale network support for host connections
All checks were successful
Build and Release / build-and-release (push) Successful in 1m31s
All checks were successful
Build and Release / build-and-release (push) Successful in 1m31s
Implement configurable network routing for both local and Tailscale networks. Dashboard now supports intelligent connection selection with automatic fallback between network types. Add IP configuration fields and connection routing logic for ZMQ and SSH operations. Features: - Host configuration with local and Tailscale IP addresses - Configurable connection types (local/tailscale/auto) - Automatic fallback between network connections - Updated ZMQ connection logic with retry support - SSH command routing through configured IP addresses
This commit is contained in:
@@ -29,6 +29,77 @@ fn default_heartbeat_timeout_seconds() -> u64 {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct HostDetails {
|
||||
pub mac_address: Option<String>,
|
||||
/// Primary IP address (local network)
|
||||
pub ip: Option<String>,
|
||||
/// Tailscale network IP address
|
||||
pub tailscale_ip: Option<String>,
|
||||
/// Preferred connection type: "local", "tailscale", or "auto" (fallback)
|
||||
#[serde(default = "default_connection_type")]
|
||||
pub connection_type: String,
|
||||
}
|
||||
|
||||
fn default_connection_type() -> String {
|
||||
"auto".to_string()
|
||||
}
|
||||
|
||||
impl HostDetails {
|
||||
/// Get the preferred IP address for connection based on connection_type
|
||||
pub fn get_connection_ip(&self, hostname: &str) -> String {
|
||||
match self.connection_type.as_str() {
|
||||
"tailscale" => {
|
||||
if let Some(ref ts_ip) = self.tailscale_ip {
|
||||
ts_ip.clone()
|
||||
} else {
|
||||
// Fallback to local IP or hostname
|
||||
self.ip.as_ref().unwrap_or(&hostname.to_string()).clone()
|
||||
}
|
||||
}
|
||||
"local" => {
|
||||
if let Some(ref local_ip) = self.ip {
|
||||
local_ip.clone()
|
||||
} else {
|
||||
hostname.to_string()
|
||||
}
|
||||
}
|
||||
"auto" | _ => {
|
||||
// Try tailscale first, then local, then hostname
|
||||
if let Some(ref ts_ip) = self.tailscale_ip {
|
||||
ts_ip.clone()
|
||||
} else if let Some(ref local_ip) = self.ip {
|
||||
local_ip.clone()
|
||||
} else {
|
||||
hostname.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get fallback IP addresses for connection retry
|
||||
pub fn get_fallback_ips(&self, hostname: &str) -> Vec<String> {
|
||||
let mut fallbacks = Vec::new();
|
||||
|
||||
// Add all available IPs except the primary one
|
||||
let primary = self.get_connection_ip(hostname);
|
||||
|
||||
if let Some(ref ts_ip) = self.tailscale_ip {
|
||||
if ts_ip != &primary {
|
||||
fallbacks.push(ts_ip.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref local_ip) = self.ip {
|
||||
if local_ip != &primary {
|
||||
fallbacks.push(local_ip.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Always include hostname as final fallback if not already primary
|
||||
if hostname != primary {
|
||||
fallbacks.push(hostname.to_string());
|
||||
}
|
||||
|
||||
fallbacks
|
||||
}
|
||||
}
|
||||
|
||||
/// System configuration
|
||||
|
||||
Reference in New Issue
Block a user