use super::types::{JumpConnection, JumpInfo};
use crate::jump::rate_limiter::ConnectionRateLimiter;
use crate::ssh::known_hosts::StrictHostKeyChecking;
use crate::ssh::tokio_client::{AuthMethod, Client, SshConnectionConfig};
use anyhow::{Context, Result};
use tracing::{debug, info};
#[allow(clippy::too_many_arguments)]
pub(super) async fn connect_direct(
host: &str,
port: u16,
username: &str,
auth_method: AuthMethod,
strict_mode: Option<StrictHostKeyChecking>,
connect_timeout: std::time::Duration,
rate_limiter: &ConnectionRateLimiter,
ssh_connection_config: &SshConnectionConfig,
) -> Result<JumpConnection> {
debug!("Establishing direct connection to {}:{}", host, port);
rate_limiter
.try_acquire(&host.to_string())
.await
.with_context(|| format!("Rate limited for host {host}"))?;
let check_method = strict_mode.map_or_else(
|| crate::ssh::known_hosts::get_check_method(StrictHostKeyChecking::AcceptNew),
crate::ssh::known_hosts::get_check_method,
);
let client = tokio::time::timeout(
connect_timeout,
Client::connect_with_ssh_config(
(host, port),
username,
auth_method,
check_method,
ssh_connection_config,
),
)
.await
.with_context(|| {
format!(
"Connection timeout: Failed to connect to {}:{} after {}s",
host,
port,
connect_timeout.as_secs()
)
})?
.with_context(|| format!("Failed to establish direct connection to {host}:{port}"))?;
info!("Direct connection established to {}:{}", host, port);
Ok(JumpConnection {
client,
jump_info: JumpInfo::Direct {
host: host.to_string(),
port,
},
})
}