146 lines
5.0 KiB
Rust
146 lines
5.0 KiB
Rust
use anyhow::{anyhow,Result};
|
|
use std::str;
|
|
use std::fs; //, io};
|
|
use std::fs::OpenOptions;
|
|
use std::io::{Write};
|
|
// use std::io::prelude::*;
|
|
use std::net::TcpStream;
|
|
use std::path::Path;
|
|
use std::process::{Command};
|
|
|
|
use crate::defs::{SSHAccess,Cntrllr};
|
|
use crate::clouds::defs::{Cloud};
|
|
|
|
pub fn parse_yaml_value(value: serde_yaml::Value, key: String, ctx: &mut tera::Context ) {
|
|
if let Some(v) = value.as_str() {
|
|
ctx.insert(key.to_owned(),&v);
|
|
} else if let Some(v) = value.as_bool() {
|
|
ctx.insert(key.to_owned(),&v);
|
|
} else if value.is_mapping() {
|
|
if let Some(map) = value.as_mapping() {
|
|
ctx.insert(key.to_owned(),&map);
|
|
}
|
|
} else if value.is_sequence() {
|
|
if let Some(seq) = value.as_sequence() {
|
|
// let mut data_seq: Vec<String> = Vec::new();
|
|
// for (line, elem) in seq.iter().enumerate() {
|
|
// if let Some(s) = elem.as_str() {
|
|
// data_seq.push(s.to_owned());
|
|
// } else {
|
|
// println!("Error {} line {}",&key,&line);
|
|
// }
|
|
// }
|
|
// ctx.insert(key.to_owned(),&data_seq);
|
|
ctx.insert(key.to_owned(),&seq);
|
|
}
|
|
} else {
|
|
ctx.insert(key.to_owned(),&value);
|
|
}
|
|
}
|
|
pub async fn write_log(output_path: &str, hostname: &str, name: &str, msg: &str) -> Result<()> {
|
|
let now = chrono::Utc::now().timestamp();
|
|
let out = format!("{}: [{}] {} -> {}\n",&now,&hostname, &name,&msg);
|
|
if Path::new(&output_path).exists() {
|
|
let mut file = OpenOptions::new().append(true).open(&output_path)?;
|
|
// out = out.replace("/", "/");
|
|
file.write(out.as_bytes())?;
|
|
} else {
|
|
if Path::new(&output_path).exists() {
|
|
fs::remove_file(&output_path)?;
|
|
}
|
|
let mut file = OpenOptions::new().write(true).create(true).open(&output_path)?;
|
|
file.write_all(out.as_bytes())?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn source_host() -> String {
|
|
// TODO a better way by finding cntrllr in config definition
|
|
let running_host = envmnt::get_or("HOSTNAME", "localhost");
|
|
let cntrllr_host = envmnt::get_or("CNTRLLR_HOST", "");
|
|
if running_host == cntrllr_host {
|
|
running_host.to_owned()
|
|
} else {
|
|
cntrllr_host.to_owned()
|
|
}
|
|
}
|
|
pub async fn liveness_check(source: &str,cntrllrs: &Vec<Cntrllr>,serverstring: &str,tsk_name: &str) -> Result<()> {
|
|
let debug=envmnt::get_isize("DEBUG",0);
|
|
// let serverstring = format!("{}:22",&hostname);
|
|
let mut check_cntrllr = Cntrllr::default();
|
|
for cntrllr in cntrllrs {
|
|
let serverstring = format!("{}:{}",&cntrllr.sshaccess.host,&cntrllr.sshaccess.port);
|
|
match TcpStream::connect(&serverstring) {
|
|
Ok(_serverstream) => {
|
|
check_cntrllr = cntrllr.to_owned();
|
|
break;
|
|
// handle_input(serverstream);
|
|
},
|
|
Err(e) => {
|
|
println!("Error: {}:{} -> {}",&cntrllr.sshaccess.host,&cntrllr.sshaccess.port,e);
|
|
}
|
|
}
|
|
}
|
|
// Some Ips in serverstring can be private so we need to know from where are we checking ...
|
|
if !check_cntrllr.sshaccess.host.is_empty() && envmnt::get_or("HOSTNAME", "localhost") == check_cntrllr.sshaccess.host {
|
|
if debug > 1 {
|
|
println!("Checking connection to {} for {} -> {}",&serverstring,&source,&tsk_name);
|
|
}
|
|
match TcpStream::connect(&serverstring) {
|
|
Ok(_serverstream) => {
|
|
Ok(())
|
|
// handle_input(serverstream);
|
|
},
|
|
Err(e) => {
|
|
Err(anyhow!("Source {}: Connection to '{}' for tsksrvc '{}' failed: {}",&source,&serverstring,&tsk_name,&e))
|
|
}
|
|
}
|
|
} else {
|
|
if debug > 1 {
|
|
println!("Remote checking connection from {} to {} for {} -> {}",&check_cntrllr.sshaccess.host,&serverstring,&source,&tsk_name);
|
|
}
|
|
let vec_serverstring: Vec<&str> = serverstring.split(':').collect();
|
|
let output = Command::new("ssh")
|
|
.arg("-o")
|
|
.arg("StrictHostKeyChecking=accept-new")
|
|
.arg("-p")
|
|
.arg(format!("{}",check_cntrllr.sshaccess.port))
|
|
.arg(format!("{}@{}",check_cntrllr.sshaccess.user,&check_cntrllr.sshaccess.host))
|
|
.arg("nc")
|
|
.arg("-zv")
|
|
.arg(format!("{}",vec_serverstring[0]))
|
|
.arg(format!("{}",vec_serverstring[1]))
|
|
.output()?;
|
|
match &output.status.code() {
|
|
Some(code) =>
|
|
if format!("{}",code) == "0" {
|
|
Ok(())
|
|
} else {
|
|
let err = str::from_utf8(&output.stderr).unwrap_or_else(|_| "");
|
|
Err(anyhow!("Source {}: Connection to '{}' ({}) for tsksrvc '{}' failed:\n {}",&source,serverstring,&check_cntrllr.sshaccess.host,&tsk_name,&err))
|
|
}
|
|
None => Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn host_ssh_is_alive(cloud: &Cloud, cmd: &str, hostname: &str,tsk_name: &str, ssh_access: &SSHAccess) -> Result<()> {
|
|
let debug=envmnt::get_isize("DEBUG",0);
|
|
if debug > 1 {
|
|
println!("Checking ssh connection to {}@{} on {} for {} -> {}",ssh_access.user,ssh_access.host,ssh_access.port,&cloud.env.source,&tsk_name);
|
|
}
|
|
let output = Command::new("ssh")
|
|
.arg("-o")
|
|
.arg("StrictHostKeyChecking=accept-new")
|
|
.arg("-p")
|
|
.arg(format!("{}",ssh_access.port))
|
|
.arg(format!("{}@{}",ssh_access.user,ssh_access.host))
|
|
.arg("ls")
|
|
.output()?;
|
|
// dbg!(&output);
|
|
if !&output.status.success() {
|
|
let err = str::from_utf8(&output.stderr).unwrap_or_else(|_| "");
|
|
return Err(anyhow!("Source {}: Connection to '{}' for tsksrvc '{}' cmd '{}' failed: {}",&cloud.env.source,&hostname,&tsk_name,&cmd,&err));
|
|
}
|
|
Ok(())
|
|
} |