1#![forbid(unsafe_code)]
4#![allow(unused_imports)]
5
6use super::*;
7
8#[derive(Debug, Default, Clone)]
9pub struct SftpOptions {
11 pub password: Option<secrecy::SecretString>,
13 pub key: Option<String>,
15 pub key_passphrase: Option<secrecy::SecretString>,
17 pub timeout: Option<crate::domain::TimeoutMs>,
19 pub replace_host_key: bool,
21 pub json: bool,
23 pub use_agent: bool,
25 pub agent_socket: Option<String>,
27 pub recursive: bool,
29}
30
31pub(crate) fn apply_sftp_options(record: &mut crate::vps::model::VpsRecord, opts: &SftpOptions) {
33 if let Some(ref pwd) = opts.password {
34 record.password = pwd.clone();
35 }
36 if let Some(ref k) = opts.key {
37 if let Ok(kp) = crate::domain::KeyPath::try_new(k.as_str()) {
38 record.key_path = Some(kp);
39 }
40 }
41 if let Some(ref kp) = opts.key_passphrase {
42 record.key_passphrase = Some(kp.clone());
43 }
44 if let Some(t) = opts.timeout {
45 record.timeout_ms = t;
46 }
47 if opts.use_agent {
48 record.use_agent = true;
49 }
50 if let Some(ref sock) = opts.agent_socket {
51 record.agent_socket = Some(sock.clone());
52 record.use_agent = true;
53 }
54}
55
56pub(crate) async fn connect_client(
57 vps_key: &str,
58 config_override: Option<&std::path::Path>,
59 opts: &SftpOptions,
60) -> anyhow::Result<SshClient> {
61 let mut record = vps::find_by_name(config_override, vps_key)?
62 .ok_or_else(|| SshCliError::VpsNotFound(vps_key.to_owned()))?;
63 let _ = publish_target(vps_key);
67 apply_sftp_options(&mut record, opts);
68 let path = vps::resolve_config_path(config_override)?;
69 let cfg = vps::build_connection_config(&record, Some(&path), opts.replace_host_key);
70 let client = SshClient::connect(cfg).await?;
71 Ok(client)
72}
73
74pub(crate) fn remote_str(p: &Path) -> String {
75 p.to_string_lossy().into_owned()
76}