partition_sim/
peer.rs

1use openssh::{Session, SessionBuilder};
2use std::net::IpAddr;
3use uuid::Uuid;
4
5#[derive(Debug)]
6pub struct Peer {
7    pub id: Uuid,
8    pub ip_addr: IpAddr,
9    // pub hostname: String,
10    pub session: Option<Session>,
11    pub user: String,
12    pub keyfile: Option<String>,
13}
14
15impl Peer {
16    pub fn new(addr: IpAddr, user: Option<&str>, keyfile: Option<&str>) -> Self {
17        Self {
18            id: Uuid::new_v4(),
19            ip_addr: addr,
20            // hostname: hostname.to_string(),
21            session: None,
22            user: user.unwrap_or("root").to_string(),
23            keyfile: keyfile.map(|s| s.to_string()),
24        }
25    }
26
27    pub async fn connect(&mut self) -> crate::Result<()> {
28        if self.session.is_some() {
29            return Ok(());
30        }
31        let mut session_builder = SessionBuilder::default();
32        session_builder
33            .known_hosts_check(openssh::KnownHosts::Accept)
34            .user_known_hosts_file("/dev/null")
35            .user(self.user.clone());
36
37        if let Some(keyfile) = &self.keyfile {
38            session_builder.keyfile(std::path::PathBuf::from(keyfile.to_owned()));
39        }
40        let session = session_builder.connect(self.ip_addr.to_string()).await?;
41        self.session = Some(session);
42
43        Ok(())
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    use std::env;
52
53    #[tokio::test]
54    async fn test_peer_new() {
55        let mut peer = Peer::new(
56            "192.168.1.137".parse().unwrap(),
57            Some("pi"),
58            Some(env::var("SSH_KEYFILE").unwrap().as_str()),
59        );
60        peer.connect().await.unwrap();
61        println!("{:?}", peer);
62    }
63}