Use a config file instead.

This commit is contained in:
2018-10-02 09:37:05 +02:00
parent 52fc4b30d9
commit 8006a798b6
4 changed files with 307 additions and 63 deletions

View File

@@ -1,43 +1,31 @@
extern crate chrono;
extern crate handlebars;
extern crate humantime;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate structopt;
extern crate subprocess;
extern crate toml;
use std::process;
use std::time::Duration;
use std::thread;
use std::collections::HashMap;
use std::path::PathBuf;
use std::fs;
use std::io::{self, Read, Write};
use std::path::PathBuf;
use std::thread;
use std::time::Duration;
use chrono::prelude::*;
use handlebars::Handlebars;
use humantime::format_duration;
use structopt::StructOpt;
fn ping(host: &str) -> Result<&str, &str> {
let result = process::Command::new("ping")
.args(&["-c", "1"])
.args(&["-t", "3"]) // Should be -w on linux
.arg(host)
.stdout(process::Stdio::null())
.stderr(process::Stdio::null())
.status()
.map_err(|_| host)?;
if result.success() {
Ok(host)
} else {
Err(host)
}
}
use subprocess::{Exec, NullFile};
#[derive(StructOpt)]
#[structopt(name = "ips-uptime")]
struct Opt {
#[structopt(parse(from_os_str))]
config: PathBuf
config: PathBuf,
}
#[derive(Debug, Deserialize)]
@@ -54,8 +42,23 @@ struct Command {
#[derive(Debug, Deserialize)]
struct Host {
name: String,
host: String,
command: String,
#[serde(flatten)]
args: HashMap<String, String>,
#[serde(skip)]
cmd: String,
}
impl Host {
fn status(&self) -> bool {
let result = Exec::shell(&self.cmd)
.stdout(NullFile)
.stderr(NullFile)
.join()
.expect("failed to execute command");
result.success()
}
}
fn main() {
@@ -67,55 +70,46 @@ fn main() {
.and_then(|mut file| file.read_to_end(&mut buffer))
.expect("failed to read config");
let config: Config = toml::from_slice(&buffer).expect("failed to parse config");
let mut config: Config = toml::from_slice(&buffer).expect("failed to parse config");
println!("config: {:#?}", config);
let mut handlebars = Handlebars::new();
process::exit(0);
handlebars.set_strict_mode(true);
// Cloudflare/APNIC DNS (primary): 1.1.1.1
// Cloudflare/APNIC DNS (secondary): 1.0.0.1
// Google DNS (primary): 8.8.8.8
// Google DNS (secondary): 8.8.4.4
for host in &mut config.hosts {
let command = config
.command
.get(&host.command)
.map(|command| &command.command)
.unwrap_or(&host.command);
let mut status: Option<DateTime<Utc>> = None;
host.cmd = handlebars
.render_template(command, &host.args)
.expect("failed to register template");
}
let config = config;
let mut status: Option<DateTime<Local>> = None;
loop {
let now = Utc::now();
let now = Local::now();
let result = ping("1.1.1.1")
.or_else(|_host| {
// println!("failed to ping {}", host);
let result = config
.hosts
.iter()
// .inspect(|host| println!("{}", host.name))
.find(|host| host.status());
ping("1.0.0.1")
})
.or_else(|_host| {
// println!("failed to ping {}", host);
if result.is_some() {
if let Some(down) = status {
let now = Local::now();
ping("8.8.8.8")
})
.or_else(|_host| {
// println!("failed to ping {}", host);
ping("8.8.4.4")
})
.or_else(|host| {
// println!("failed to ping {}", host);
Err(host)
})
.and_then(|host| {
// println!("success to ping {}", host);
Ok(host)
});
if result.is_ok() {
if let Some(down) = status {
let now = Utc::now();
println!(" - {}, duration: {}", now, (now - down));
println!(
" -- {} ({})",
now,
format_duration((now - down).to_std().unwrap())
);
status = None;
}