...
This commit is contained in:
@@ -49,6 +49,7 @@ pub mod virt;
|
||||
pub mod vault;
|
||||
pub mod zinit_client;
|
||||
pub mod mycelium;
|
||||
pub mod net;
|
||||
|
||||
// Version information
|
||||
/// Returns the version of the SAL library
|
||||
|
51
src/net/http.rs
Normal file
51
src/net/http.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use reqwest::Client;
|
||||
use std::time::Duration;
|
||||
|
||||
// HTTP Checker
|
||||
pub struct HttpChecker {
|
||||
client: Client,
|
||||
url: String,
|
||||
}
|
||||
|
||||
impl HttpChecker {
|
||||
pub async fn check_url(&self) -> Result<bool, reqwest::Error> {
|
||||
let res = self.client.get(&self.url).send().await?;
|
||||
Ok(res.status().is_success())
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP Checker Builder
|
||||
pub struct HttpCheckerBuilder {
|
||||
url: String,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl HttpCheckerBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
url: "http://localhost".to_string(),
|
||||
timeout: Duration::from_secs(30),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn url<S: Into<String>>(mut self, url: S) -> Self {
|
||||
self.url = url.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> HttpChecker {
|
||||
let client = Client::builder()
|
||||
.timeout(self.timeout)
|
||||
.build()
|
||||
.expect("Failed to build HTTP client");
|
||||
HttpChecker {
|
||||
client,
|
||||
url: self.url,
|
||||
}
|
||||
}
|
||||
}
|
3
src/net/mod.rs
Normal file
3
src/net/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod ssh;
|
||||
pub mod tcp;
|
||||
pub mod http;
|
133
src/net/ssh.rs
Normal file
133
src/net/ssh.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
use russh::client;
|
||||
use russh_keys::key;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
// SSH Connection
|
||||
#[derive(Clone)]
|
||||
pub struct SshConnection {
|
||||
session: Arc<client::Handle<Client>>,
|
||||
}
|
||||
|
||||
impl SshConnection {
|
||||
pub async fn ping(&self) -> Result<(), anyhow::Error> {
|
||||
let mut channel = self.session.channel_open_session().await?;
|
||||
channel.exec(true, "ping -c 1 127.0.0.1").await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// SSH Connection Builder
|
||||
pub struct SshConnectionBuilder {
|
||||
host: String,
|
||||
port: u16,
|
||||
user: String,
|
||||
password: Option<String>,
|
||||
key_path: Option<PathBuf>,
|
||||
use_agent: bool,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl SshConnectionBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
host: "localhost".to_string(),
|
||||
port: 22,
|
||||
user: "root".to_string(),
|
||||
password: None,
|
||||
key_path: None,
|
||||
use_agent: true,
|
||||
timeout: Duration::from_secs(30),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn host<S: Into<String>>(mut self, host: S) -> Self {
|
||||
self.host = host.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn port(mut self, port: u16) -> Self {
|
||||
self.port = port;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn user<S: Into<String>>(mut self, user: S) -> Self {
|
||||
self.user = user.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn password<S: Into<String>>(mut self, password: S) -> Self {
|
||||
self.password = Some(password.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn key_path(mut self, key_path: PathBuf) -> Self {
|
||||
self.key_path = Some(key_path);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn use_agent(mut self, use_agent: bool) -> Self {
|
||||
self.use_agent = use_agent;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn build(self) -> Result<SshConnection, anyhow::Error> {
|
||||
let config = Arc::new(client::Config::default());
|
||||
let sh = Client;
|
||||
|
||||
let mut session = client::connect(config, (self.host.as_str(), self.port), sh).await?;
|
||||
|
||||
let auth_res = if self.use_agent {
|
||||
let mut agent = russh_keys::agent::client::AgentClient::connect_env().await?;
|
||||
let mut keys = agent.request_identities().await?;
|
||||
if keys.is_empty() {
|
||||
return Err(anyhow::anyhow!("No identities found in ssh-agent"));
|
||||
}
|
||||
let key = keys.remove(0);
|
||||
let (_agent, authed) = session
|
||||
.authenticate_future(self.user.as_str(), Arc::new(key), agent)
|
||||
.await;
|
||||
authed?
|
||||
} else if let Some(password) = self.password {
|
||||
session
|
||||
.authenticate_password(self.user.as_str(), &password)
|
||||
.await?
|
||||
} else if let Some(key_path) = self.key_path {
|
||||
let key_pair = russh_keys::load_secret_key(key_path, None)?;
|
||||
session
|
||||
.authenticate_publickey(self.user.as_str(), Arc::new(key_pair))
|
||||
.await?
|
||||
} else {
|
||||
return Err(anyhow::anyhow!(
|
||||
"No authentication method specified"
|
||||
));
|
||||
};
|
||||
|
||||
if !auth_res {
|
||||
return Err(anyhow::anyhow!("Authentication failed"));
|
||||
}
|
||||
|
||||
Ok(SshConnection {
|
||||
session: Arc::new(session),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct Client;
|
||||
|
||||
impl client::Handler for Client {
|
||||
type Error = russh::Error;
|
||||
|
||||
fn check_server_key(
|
||||
&mut self,
|
||||
_server_public_key: &key::PublicKey,
|
||||
) -> std::future::Ready<Result<bool, Self::Error>> {
|
||||
std::future::ready(Ok(true))
|
||||
}
|
||||
}
|
64
src/net/tcp.rs
Normal file
64
src/net/tcp.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
use std::net::{SocketAddr, TcpStream};
|
||||
use std::time::Duration;
|
||||
|
||||
// TCP Checker
|
||||
pub struct TcpChecker {
|
||||
host: String,
|
||||
port: u16,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl TcpChecker {
|
||||
pub fn ping(&self) -> Result<(), std::io::Error> {
|
||||
let addr = format!("{}:{}", self.host, self.port);
|
||||
let socket_addr: SocketAddr = addr.parse().expect("Failed to parse socket address");
|
||||
TcpStream::connect_timeout(&socket_addr, self.timeout)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn check_port(&self) -> bool {
|
||||
let addr = format!("{}:{}", self.host, self.port);
|
||||
let socket_addr: SocketAddr = addr.parse().expect("Failed to parse socket address");
|
||||
TcpStream::connect_timeout(&socket_addr, self.timeout).is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
// TCP Checker Builder
|
||||
pub struct TcpCheckerBuilder {
|
||||
host: String,
|
||||
port: u16,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl TcpCheckerBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
host: "localhost".to_string(),
|
||||
port: 80,
|
||||
timeout: Duration::from_secs(1),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn host<S: Into<String>>(mut self, host: S) -> Self {
|
||||
self.host = host.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn port(mut self, port: u16) -> Self {
|
||||
self.port = port;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> TcpChecker {
|
||||
TcpChecker {
|
||||
host: self.host,
|
||||
port: self.port,
|
||||
timeout: self.timeout,
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user