use super::Result;
use ssh2::Session;
use serde_json::Value;
use serde_derive::{Serialize, Deserialize};
use std::{
collections::HashMap,
net::TcpStream,
};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Host {
pub id: String,
pub address: String,
#[serde(default = "default_user")]
pub user: String,
#[serde(default = "default_tags")]
pub tags: Vec<String>,
#[serde(default = "default_vars")]
pub vars: HashMap<String, Value>,
}
impl Host {
pub fn new(id: String, address: String) -> Self {
Self {
id,
address,
user: default_user(),
tags: default_tags(),
vars: default_vars(),
}
}
pub fn set_user(&mut self, user: String) -> &mut Self {
self.user = user;
self
}
pub fn add_tag(&mut self, tag: String) -> &mut Self {
self.tags.push(tag);
self
}
pub fn remove_tag(&mut self, tag: String) -> &mut Self {
self.tags.retain(|current_tag| *current_tag != tag);
self
}
pub fn set_var(&mut self, key: String, val: Value) -> &mut Self {
self.vars.insert(key, val);
self
}
pub fn remove_var(&mut self, key: String) -> &mut Self {
self.vars.remove(&key);
self
}
pub fn get_session(&self) -> Result<Session> {
let sock = TcpStream::connect(self.address.clone())?;
let mut sess = Session::new()?;
sess.set_tcp_stream(sock);
sess.handshake()?;
sess.userauth_agent(&self.user)?;
Ok(sess)
}
}
fn default_user() -> String {
String::from("root")
}
fn default_tags() -> Vec<String> {
vec![]
}
fn default_vars() -> HashMap<String, Value> {
HashMap::new()
}