Initial commit.

This commit is contained in:
2018-10-01 17:47:33 +02:00
commit 52fc4b30d9
4 changed files with 410 additions and 0 deletions

133
src/main.rs Normal file
View File

@@ -0,0 +1,133 @@
extern crate chrono;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate structopt;
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 chrono::prelude::*;
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)
}
}
#[derive(StructOpt)]
#[structopt(name = "ips-uptime")]
struct Opt {
#[structopt(parse(from_os_str))]
config: PathBuf
}
#[derive(Debug, Deserialize)]
struct Config {
command: HashMap<String, Command>,
hosts: Vec<Host>,
}
#[derive(Debug, Deserialize)]
struct Command {
command: String,
}
#[derive(Debug, Deserialize)]
struct Host {
name: String,
host: String,
command: String,
}
fn main() {
let opt = Opt::from_args();
let mut buffer = Vec::new();
fs::File::open(&opt.config)
.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");
println!("config: {:#?}", config);
process::exit(0);
// 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
let mut status: Option<DateTime<Utc>> = None;
loop {
let now = Utc::now();
let result = ping("1.1.1.1")
.or_else(|_host| {
// println!("failed to ping {}", host);
ping("1.0.0.1")
})
.or_else(|_host| {
// println!("failed to ping {}", host);
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));
status = None;
}
thread::sleep(Duration::from_secs(5));
} else {
if status.is_none() {
print!("{}", now);
io::stdout().flush().expect("failed to flush stdout");
status = Some(now);
}
}
}
}