From 43cac4a82182eea79da24a2bd3542e41575f53e5 Mon Sep 17 00:00:00 2001 From: Paul Lecuq Date: Mon, 29 Nov 2021 15:37:32 +0100 Subject: [PATCH] updated config management --- src/config/mod.rs | 59 ++++++++++++++++++++--------------------------- src/zabbix/api.rs | 37 +++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 39 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 28559bf..8817870 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,9 +1,10 @@ use crate::zabbix::api::get_zabbix_authtoken; use crate::zabbix::problems::DataMatrix; -use clap::{App, ArgMatches}; +use clap::App; use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify}; use serde::{Deserialize, Serialize}; use serde_json::Error as JsonError; +use serde_json::Value as JsonValue; use std::fs::File; use std::io::Read; use std::string::String; @@ -93,37 +94,16 @@ pub struct Config { impl<'a> Config { pub fn new() -> Self { Self { - server: String::from("https://zabbix.acme.com/api_jsonrpc.php"), - username: String::from("bob"), - password: String::from("password"), - authtoken: Some(String::from("token")), + server: "https://zabbix.acme.com/api_jsonrpc.php".to_string(), + username: "bob".to_string(), + password: "password".to_string(), + authtoken: Some("token".to_string()), sloweffect: Some(true), refresh: Some(5u64), limit: Some(20u64), } } - fn feed_missing(&mut self) -> bool { - let mut res = false; - if self.authtoken.is_none() { - self.authtoken = Some(String::from("")); - res = true; - } - if self.sloweffect.is_none() { - self.sloweffect = Some(true); - res = true; - } - if self.refresh.is_none() { - self.refresh = Some(5u64); - res = true; - } - if self.limit.is_none() { - self.limit = Some(20u64); - res = true; - } - res - } - pub fn load(&'a mut self, configfile: &str) { let fileopen: Result; let filemeta = std::fs::metadata(configfile); @@ -145,15 +125,26 @@ impl<'a> Config { }; let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); - let parse: Result = serde_json::from_str(contents.as_str()); - let cfg = match parse { - Ok(cfg) => cfg, - Err(_) => Config::new(), - }; - *self = cfg; - if self.feed_missing() { - self.save(&configfile); + let parse: Result = serde_json::from_str(contents.as_str()); + *self = match parse { + Ok(cfg) => { + let tmpcfg = Config::new(); + Config { + server: cfg["server"].as_str().unwrap_or(tmpcfg.server.as_str()).to_string(), + username: cfg["username"].as_str().unwrap_or(tmpcfg.username.as_str()).to_string(), + password: cfg["password"].as_str().unwrap_or(tmpcfg.password.as_str()).to_string(), + authtoken: Some(cfg["authtoken"].as_str().unwrap_or(tmpcfg.authtoken.unwrap().as_str()).to_string()), + sloweffect: Some(cfg["sloweffect"].as_bool().unwrap_or(tmpcfg.sloweffect.unwrap())), + refresh: Some(cfg["refresh"].as_u64().unwrap_or(tmpcfg.refresh.unwrap())), + limit: Some(cfg["limit"].as_u64().unwrap_or(tmpcfg.limit.unwrap())), + } + }, + Err(err) => { + println!("error occured: '{}'", err); + Config::new() + } }; + self.save(&configfile); } pub fn save(&self, configfile: &str) { diff --git a/src/zabbix/api.rs b/src/zabbix/api.rs index f7ac7ea..23eea28 100644 --- a/src/zabbix/api.rs +++ b/src/zabbix/api.rs @@ -1,11 +1,14 @@ +use std::time::Duration; +use std::thread::sleep; use crate::config::Config; use serde_json::{json, Value}; pub const ZABBIX_API_VERSION: &'static str = "2.0"; pub const ZABBIX_API_ID: i32 = 1; +/// Refresh the user token pub fn get_zabbix_authtoken(cfg: &mut Config) { - let body = query_auth_token(&cfg.username, &cfg.password); + let body = build_query_auth_token(&cfg.username, &cfg.password); let resp = reqwest::blocking::Client::new() .post(&cfg.server) .json(&body) @@ -16,8 +19,9 @@ pub fn get_zabbix_authtoken(cfg: &mut Config) { cfg.authtoken = Some(values["result"].as_str().unwrap().to_string()); } +/// Fetch Zabbix problems pub fn get_zabbix_problems(cfg: &Config) -> Result { - let body = query_triggers(&cfg.authtoken.as_ref().unwrap_or(&String::from(""))); + let body = build_query_triggers(&cfg.authtoken.as_ref().unwrap_or(&String::from(""))); let resp = reqwest::blocking::Client::new() .post(&cfg.server) .json(&body) @@ -26,7 +30,28 @@ pub fn get_zabbix_problems(cfg: &Config) -> Result { Ok(resp.unwrap().json().unwrap()) } -pub fn query_auth_token(zabbix_username: &String, zabbix_password: &String) -> Value { +/// Check if Zabbix is operational +/// Undefinitely check that Zabbix works +fn check_zabbix_connection(cfg: &Config) -> bool { + let mut res: bool = false; + let delay = 5; + let timeout = 10; + while !res { + let req = reqwest::blocking::Client::builder().timeout(Duration::from_secs(timeout)).build().unwrap(); + let resp = req.get(&cfg.server) + .send(); + match resp { + Ok(_) => res = true, + Err(_) => res = false + } + println!("Waiting for {delay}", delay=delay); + sleep(Duration::from_secs(delay)); + } + res +} + +/// Build the query that fetchs the token +fn build_query_auth_token(zabbix_username: &String, zabbix_password: &String) -> Value { let zabbix_api_function = "user.login"; json!({ "jsonrpc": ZABBIX_API_VERSION, @@ -39,7 +64,8 @@ pub fn query_auth_token(zabbix_username: &String, zabbix_password: &String) -> V }) } -fn _query_problems(zabbix_token: &String, zabbix_limit: i64) -> Value { +/// Build the query that fetchs problems +fn build_query_problems(zabbix_token: &String, zabbix_limit: i64) -> Value { let zabbix_api_function = "problem.get"; json!({ "jsonrpc": ZABBIX_API_VERSION, @@ -61,7 +87,8 @@ fn _query_problems(zabbix_token: &String, zabbix_limit: i64) -> Value { }) } -pub fn query_triggers(zabbix_token: &String) -> Value { +/// Build the query that fetchs triggers +fn build_query_triggers(zabbix_token: &String) -> Value { let zabbix_api_function = "trigger.get"; json!({ "jsonrpc": ZABBIX_API_VERSION,