use super::{host_id::HostId, host_tag::HostTag};
use crate::prelude::Result;
use serde_derive::{Deserialize, Serialize};
use serde_json::Value;
use ssh2::Session;
use std::{collections::HashMap, net::TcpStream};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Host {
pub id: HostId,
pub address: String,
#[serde(default = "default_user")]
pub user: String,
#[serde(default = "default_tags")]
pub tags: Vec<HostTag>,
#[serde(default = "default_vars")]
pub vars: HashMap<String, Value>,
}
impl Host {
pub fn id(src: &str) -> Result<HostId> {
HostId::new(src)
}
pub fn tag(src: &str) -> Result<HostTag> {
HostTag::new(src)
}
pub fn new(id: HostId, 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: HostTag) -> &mut Self {
self.tags.push(tag);
self
}
pub fn remove_tag(&mut self, tag: HostTag) -> &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<HostTag> {
vec![]
}
fn default_vars() -> HashMap<String, Value> {
HashMap::new()
}