use crate::action_factory::{ActionTrait, ActionData};
use log::*;
use simple_error::*;
use crate::action_do::{executor_fail, executor_recover};
use std::process::Command;
pub struct ActionPing {
task:ActionData
}
impl ActionPing {
fn ping_command(&self) -> String {
let task_conf = &self.task.task_action;
let r = if cfg!(target_os = "windows") {
let ping_ms = task_conf.timeout.to_string();
Command::new("cmd")
.args(&["/C", "chcp 437","&&","ping","-w",&ping_ms,
task_conf.target.as_str()])
.output()
} else {
let ping_timeout:f32 = (task_conf.timeout as f32 / 1000f32);
let ping_timeout = ping_timeout.to_string();
Command::new("sh")
.arg("-c")
.args(&["ping","-c4", "-w",&ping_timeout, task_conf.target.as_str()])
.output()
};
match r {
Ok(e) => {
let rutf8 = String::from_utf8_lossy(e.stdout.as_slice());
let to_str = rutf8.to_string();
if cfg!(target_os = "windows") {
if to_str.contains("Request timed out") {
String::from("failed:Request timed out.")
}else {
to_str.replace("Active code page: 437", "")
}
}else {
if to_str.contains("100% packet loss") {
String::from("failed:Request timed out.")
}else {
to_str
}
}
},
Err(e) => {
let error = format!("run command error:{}",e);
error
}
}
}
}
impl ActionTrait for ActionPing {
fn id(&self) -> i32 {
self.task.id
}
fn name(&self) -> &str {
self.task.name.as_str()
}
fn append_data(&mut self, data: ActionData) {
self.task = data;
}
fn executor(&mut self) {
info!("start ping action:{} id:{}...",self.task.id,self.task.name);
let task_conf = &self.task.task_action;
let output = String::from(self.ping_command());
if output.len() >= 0 && task_conf.output_result {
if output.contains("failed") {
warn!("ping task failed,run failed...");
self.task.do_failed();
}else {
info!("ping result:{}",output);
self.task.do_recover();
}
}
}
}
pub fn new_ping(data: ActionData) -> ActionPing {
ActionPing { task:data }
}