refactor: convert to workspace
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
52
lnvps_api/src/ssh_client.rs
Normal file
52
lnvps_api/src/ssh_client.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use log::info;
|
||||
use ssh2::Channel;
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::net::{TcpStream, ToSocketAddrs};
|
||||
|
||||
pub struct SshClient {
|
||||
session: ssh2::Session,
|
||||
}
|
||||
|
||||
impl SshClient {
|
||||
pub fn new() -> Result<SshClient> {
|
||||
let session = ssh2::Session::new()?;
|
||||
Ok(SshClient { session })
|
||||
}
|
||||
|
||||
pub async fn connect(
|
||||
&mut self,
|
||||
host: impl ToSocketAddrs,
|
||||
username: &str,
|
||||
key: &PathBuf,
|
||||
) -> Result<()> {
|
||||
let tcp = TcpStream::connect(host).await?;
|
||||
self.session.set_tcp_stream(tcp);
|
||||
self.session.handshake()?;
|
||||
self.session
|
||||
.userauth_pubkey_file(username, None, key, None)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn open_channel(&mut self) -> Result<Channel> {
|
||||
let channel = self.session.channel_session()?;
|
||||
Ok(channel)
|
||||
}
|
||||
|
||||
pub fn tunnel_unix_socket(&mut self, remote_path: &Path) -> Result<Channel> {
|
||||
self.session
|
||||
.channel_direct_streamlocal(remote_path.to_str().unwrap(), None)
|
||||
.map_err(|e| anyhow!(e))
|
||||
}
|
||||
|
||||
pub async fn execute(&mut self, command: &str) -> Result<(i32, String)> {
|
||||
info!("Executing command: {}", command);
|
||||
let mut channel = self.session.channel_session()?;
|
||||
channel.exec(command)?;
|
||||
let mut s = String::new();
|
||||
channel.read_to_string(&mut s)?;
|
||||
channel.wait_close()?;
|
||||
Ok((channel.exit_status()?, s))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user