pub mod client;
pub mod transport;
use std::fmt;
use anyhow::Result;
use async_trait::async_trait;
use bstr::ByteSlice;
use enum_dispatch::enum_dispatch;
use crate::resolve::Target;
#[async_trait]
#[enum_dispatch]
pub trait Client {
async fn connect(&mut self) -> Result<()>;
async fn ping(&mut self) -> Result<Vec<u8>>;
async fn auth(&mut self, auth_type: &AuthType) -> Result<()>;
async fn exec(&mut self, command: &str) -> Result<ExecOutput>;
}
#[enum_dispatch(Client)]
pub enum ClientImpl {
Tcp(client::TcpClient),
Ssh(client::SshClient),
}
#[enum_dispatch]
pub trait ClientFactory {
fn client(&self, target: &Target) -> Option<ClientImpl>;
}
#[enum_dispatch(ClientFactory)]
#[derive(Debug, Clone)]
pub enum ClientFactoryImpl {
Tcp(client::TcpClientFactory),
Ssh(client::SshClientFactory),
}
#[derive(Debug, Clone)]
pub enum AuthType {
User(String),
Password(String),
SshKey(String),
SshCert { key: String, cert: String },
SshAgent { socket: String },
}
#[derive(Clone)]
pub struct ExecOutput {
pub exit_status: u32,
pub stdout: Vec<u8>,
pub stderr: Vec<u8>,
}
impl fmt::Debug for ExecOutput {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ExecOutput")
.field("exit_status", &self.exit_status)
.field("stdout", &self.stdout.as_bstr())
.field("stderr", &self.stderr.as_bstr())
.finish()
}
}