Resolve an SSH host alias to the actual hostname or IP address. Uses `ssh -G ` to query the effective SSH configuration, which resolves `~/.ssh/config` aliases and `HostName` directives. Falls back to the original host string if the command fails.
(host: &str)
| 151 | /// resolves `~/.ssh/config` aliases and `HostName` directives. Falls back |
| 152 | /// to the original host string if the command fails. |
| 153 | pub fn resolve_ssh_hostname(host: &str) -> String { |
| 154 | let output = std::process::Command::new("ssh") |
| 155 | .args(["-G", host]) |
| 156 | .output(); |
| 157 | |
| 158 | match output { |
| 159 | Ok(result) if result.status.success() => { |
| 160 | let stdout = String::from_utf8_lossy(&result.stdout); |
| 161 | for line in stdout.lines() { |
| 162 | if let Some(value) = line.strip_prefix("hostname ") { |
| 163 | let resolved = value.trim(); |
| 164 | if !resolved.is_empty() { |
| 165 | tracing::debug!( |
| 166 | ssh_host = host, |
| 167 | resolved_hostname = resolved, |
| 168 | "resolved SSH host alias" |
| 169 | ); |
| 170 | return resolved.to_string(); |
| 171 | } |
| 172 | } |
| 173 | } |
| 174 | // ssh -G succeeded but no hostname line found; use original |
| 175 | host.to_string() |
| 176 | } |
| 177 | Ok(result) => { |
| 178 | tracing::warn!( |
| 179 | ssh_host = host, |
| 180 | stderr = %String::from_utf8_lossy(&result.stderr).trim(), |
| 181 | "ssh -G failed, using original host" |
| 182 | ); |
| 183 | host.to_string() |
| 184 | } |
| 185 | Err(err) => { |
| 186 | tracing::warn!( |
| 187 | ssh_host = host, |
| 188 | error = %err, |
| 189 | "failed to run ssh -G, using original host" |
| 190 | ); |
| 191 | host.to_string() |
| 192 | } |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | pub fn store_gateway_metadata(name: &str, metadata: &GatewayMetadata) -> Result<()> { |
| 197 | let path = user_gateway_metadata_path(name)?; |
no test coverage detected