mirror of
https://github.com/centreon/centreon-plugins.git
synced 2025-07-30 09:05:19 +02:00
fix(generic-snmp): unwrap from main() removed and errors better handled
This commit is contained in:
parent
2736a097ce
commit
d18a18a20d
@ -1,5 +1,5 @@
|
||||
use snafu::prelude::Snafu;
|
||||
use std::path::PathBuf;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
#[snafu(visibility(pub))]
|
||||
@ -21,14 +21,22 @@ pub enum Error {
|
||||
#[snafu(display("Threshold: The threshold syntax must follow '[@]start:end'"))]
|
||||
BadThreshold,
|
||||
|
||||
#[snafu(display("Json: Failed to parse JSON: {}", message))]
|
||||
JsonParse { message: String },
|
||||
#[snafu(transparent)]
|
||||
Io { source: io::Error },
|
||||
#[snafu(transparent)]
|
||||
Lexopt { source: lexopt::Error },
|
||||
|
||||
#[snafu(display("Json: Unable to read the JSON file '{}'", path.display()))]
|
||||
JsonRead {
|
||||
source: std::io::Error,
|
||||
path: PathBuf,
|
||||
},
|
||||
#[snafu(transparent)]
|
||||
SerdeJson { source: serde_json::Error },
|
||||
}
|
||||
|
||||
impl From<std::ffi::OsString> for Error {
|
||||
fn from(value: std::ffi::OsString) -> Self {
|
||||
//let val = value.into_string().unwrap_or_else(|_| "Invalid UTF-8".to_string());
|
||||
Error::Lexopt {
|
||||
source: lexopt::Error::NonUnicodeValue(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
@ -1,3 +1,4 @@
|
||||
extern crate regex;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
@ -8,6 +9,7 @@ use crate::compute::{Compute, Parser, ast::ExprResult, threshold::Threshold};
|
||||
use crate::output::{Output, OutputFormatter};
|
||||
use crate::snmp::{snmp_bulk_get, snmp_bulk_walk, snmp_bulk_walk_with_labels};
|
||||
use log::{debug, trace};
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
@ -207,13 +209,33 @@ impl Command {
|
||||
collect
|
||||
}
|
||||
|
||||
pub fn execute(&self, target: &str, version: &str, community: &str) -> Result<CmdResult> {
|
||||
pub fn execute(
|
||||
&self,
|
||||
target: &str,
|
||||
version: &str,
|
||||
community: &str,
|
||||
filter_in: &Option<String>,
|
||||
filter_out: &Option<String>,
|
||||
) -> Result<CmdResult> {
|
||||
let mut collect = self.execute_snmp_collect(target, version, community);
|
||||
|
||||
let mut idx: u32 = 0;
|
||||
let mut metrics = vec![];
|
||||
let mut my_res = SnmpResult::new(HashMap::new());
|
||||
let mut status = Status::Ok;
|
||||
|
||||
// Prepare filters
|
||||
let re_in = if let Some(filter_in) = filter_in {
|
||||
Some(Regex::new(filter_in).unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let re_out: Option<Regex> = if let Some(filter_out) = filter_out {
|
||||
Some(Regex::new(filter_out).unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
for metric in self.compute.metrics.iter() {
|
||||
let value = &metric.value;
|
||||
let parser = Parser::new(&collect);
|
||||
@ -256,6 +278,16 @@ impl Command {
|
||||
panic!("A label must be a string");
|
||||
}
|
||||
};
|
||||
if let Some(ref re) = re_in {
|
||||
if !re.is_match(&name) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(ref re) = re_out {
|
||||
if re.is_match(&name) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let current_status =
|
||||
compute_status(item, &metric.warning, &metric.critical)?;
|
||||
status = worst(status, current_status);
|
||||
@ -291,6 +323,16 @@ impl Command {
|
||||
res
|
||||
}
|
||||
};
|
||||
if let Some(ref re) = re_in {
|
||||
if !re.is_match(&name) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(ref re) = re_out {
|
||||
if re.is_match(&name) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let current_status = compute_status(s, &metric.warning, &metric.critical)?;
|
||||
status = worst(status, current_status);
|
||||
let w = match metric.warning {
|
||||
|
@ -21,26 +21,18 @@ use generic::error::*;
|
||||
use lalrpop_util::lalrpop_mod;
|
||||
use lexopt::Arg;
|
||||
use log::trace;
|
||||
use snafu::ResultExt;
|
||||
use std::fs;
|
||||
|
||||
lalrpop_mod!(grammar);
|
||||
|
||||
fn json_to_command(file_name: &str) -> Result<Command, Error> {
|
||||
// Transform content of the file into a string
|
||||
let contents = fs::read_to_string(file_name).context(JsonReadSnafu { path: file_name })?;
|
||||
|
||||
let content = contents.as_str();
|
||||
|
||||
let module: serde_json::Result<Command> = serde_json::from_str(content);
|
||||
match module {
|
||||
Ok(c) => Ok(c),
|
||||
Err(err) => Err(Error::JsonParse {
|
||||
message: err.to_string(),
|
||||
}),
|
||||
}
|
||||
let configuration = fs::read_to_string(file_name)?;
|
||||
let command = serde_json::from_str(&configuration)?;
|
||||
Ok(command)
|
||||
}
|
||||
|
||||
#[snafu::report]
|
||||
fn main() -> Result<(), Error> {
|
||||
env_logger::Builder::from_env(
|
||||
Env::default()
|
||||
@ -57,6 +49,8 @@ fn main() -> Result<(), Error> {
|
||||
let mut port = 161;
|
||||
let mut snmp_version = "2c".to_string();
|
||||
let mut snmp_community = "public".to_string();
|
||||
let mut filter_in = None;
|
||||
let mut filter_out = None;
|
||||
let mut cmd: Option<Command> = None;
|
||||
loop {
|
||||
let arg = parser.next();
|
||||
@ -64,32 +58,43 @@ fn main() -> Result<(), Error> {
|
||||
Ok(arg) => match arg {
|
||||
Some(arg) => match arg {
|
||||
Short('H') | Long("hostname") => {
|
||||
hostname = parser.value().unwrap().into_string().unwrap();
|
||||
hostname = parser.value()?.into_string()?;
|
||||
trace!("hostname: {:}", hostname);
|
||||
}
|
||||
Short('p') | Long("port") => {
|
||||
port = parser.value().unwrap().parse::<u16>().unwrap();
|
||||
port = parser.value()?.parse::<u16>()?;
|
||||
trace!("port: {}", port);
|
||||
}
|
||||
Short('j') | Long("json") => {
|
||||
let json = Some(parser.value().unwrap().into_string().unwrap());
|
||||
let json = json.unwrap();
|
||||
let json = parser.value()?.into_string()?;
|
||||
trace!("json: {:?}", json);
|
||||
cmd = Some(json_to_command(&json)?);
|
||||
}
|
||||
Short('v') | Long("snmp-version") => {
|
||||
snmp_version = parser.value().unwrap().into_string().unwrap();
|
||||
snmp_version = parser.value()?.into_string()?;
|
||||
trace!("snmp_version: {}", snmp_version);
|
||||
}
|
||||
Short('c') | Long("snmp-community") => {
|
||||
snmp_community = parser.value().unwrap().into_string().unwrap();
|
||||
snmp_community = parser.value()?.into_string()?;
|
||||
trace!("snmp_community: {}", snmp_community);
|
||||
}
|
||||
Short('i') | Long("filter-in") => {
|
||||
filter_in = Some(parser.value()?.into_string()?);
|
||||
if let Some(ref filter) = filter_in {
|
||||
trace!("filter_in: {}", filter);
|
||||
}
|
||||
}
|
||||
Short('o') | Long("filter-out") => {
|
||||
filter_out = Some(parser.value()?.into_string()?);
|
||||
if let Some(ref filter) = filter_out {
|
||||
trace!("filter_out: {}", filter);
|
||||
}
|
||||
}
|
||||
t => {
|
||||
if let Arg::Long(name) = t {
|
||||
if name.starts_with("warning-") {
|
||||
let wmetric = name[8..].to_string();
|
||||
let value = parser.value().unwrap().into_string().unwrap();
|
||||
let value = parser.value()?.into_string()?;
|
||||
match cmd.as_mut() {
|
||||
Some(ref mut cmd) => {
|
||||
if !value.is_empty() {
|
||||
@ -105,7 +110,7 @@ fn main() -> Result<(), Error> {
|
||||
}
|
||||
} else if name.starts_with("critical-") {
|
||||
let cmetric = name[9..].to_string();
|
||||
let value = parser.value().unwrap().into_string().unwrap();
|
||||
let value = parser.value()?.into_string()?;
|
||||
match cmd.as_mut() {
|
||||
Some(ref mut cmd) => {
|
||||
if !value.is_empty() {
|
||||
@ -136,7 +141,13 @@ fn main() -> Result<(), Error> {
|
||||
let url = format!("{}:{}", hostname, port);
|
||||
|
||||
let result = match cmd {
|
||||
Some(ref cmd) => cmd.execute(&url, &snmp_version, &snmp_community)?,
|
||||
Some(ref cmd) => cmd.execute(
|
||||
&url,
|
||||
&snmp_version,
|
||||
&snmp_community,
|
||||
&filter_in,
|
||||
&filter_out,
|
||||
)?,
|
||||
None => {
|
||||
println!("json is empty");
|
||||
std::process::exit(3);
|
||||
@ -144,5 +155,5 @@ fn main() -> Result<(), Error> {
|
||||
};
|
||||
|
||||
println!("{}", result.output);
|
||||
std::process::exit(result.status as i32);
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user