fix(generic-snmp): error management improved, I think we can find better

This commit is contained in:
David Boucher 2025-05-14 09:01:52 +02:00
parent b273710cb8
commit b6f8684848
3 changed files with 40 additions and 51 deletions

View File

@ -1,7 +1,9 @@
use serde_json::Error as JsonError;
use snafu::prelude::*;
use std::{fs, io, path::PathBuf};
use std::path::PathBuf;
#[derive(Debug, Snafu)]
#[snafu(visibility(pub))]
pub enum Error {
#[snafu(display(
"Threshold: This syntax is a shortcut of '0:{}', so {} must be greater than 0.",
@ -17,26 +19,17 @@ pub enum Error {
))]
BadThresholdRange { start: f64, end: f64 },
#[snafu(display("Threshold: Unable to read configuration from {}", path.display()))]
ReadConfiguration { source: io::Error, path: PathBuf },
#[snafu(display("Threshold: Threshold not of the form '[@]start:end'"))]
#[snafu(display("Threshold: The threshold syntax must follow '[@]start:end'"))]
BadThreshold,
#[snafu(display("Unable to write result to {}", path.display()))]
WriteResult { source: io::Error, path: PathBuf },
#[snafu(display("Json: Failed to parse JSON: {}", message))]
JsonParse { message: String },
#[snafu(display("Json: Unable to read the JSON file '{}'", path.display()))]
JsonRead {
source: std::io::Error,
path: PathBuf,
},
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
fn process_data() -> Result<()> {
let path = "config.toml";
let configuration = fs::read_to_string(path).context(ReadConfigurationSnafu { path })?;
let path = unpack_config(&configuration);
fs::write(&path, b"My complex calculation").context(WriteResultSnafu { path })?;
Ok(())
}
fn unpack_config(data: &str) -> &str {
"/some/path/that/does/not/exist"
}

View File

@ -176,7 +176,7 @@ impl Command {
version: &str,
community: &str,
//ext: &CommandExt,
) -> CmdResult {
) -> Result<CmdResult> {
let mut to_get = Vec::new();
let mut get_name = Vec::new();
let mut collect = Vec::new();
@ -251,7 +251,7 @@ impl Command {
panic!("A label must be a string");
}
};
let status = compute_status(*item, &metric.warning, &metric.critical);
let status = compute_status(*item, &metric.warning, &metric.critical)?;
let w = match metric.warning {
Some(ref w) => Some(w.as_str()),
None => None,
@ -267,7 +267,7 @@ impl Command {
max: compute_threshold(i, &max),
warning: w,
critical: c,
status: status.unwrap(),
status,
};
trace!("New metric '{}' with value {:?}", m.name, m.value);
metrics.push(m);
@ -284,7 +284,7 @@ impl Command {
res
}
};
let status = compute_status(*s, &metric.warning, &metric.critical);
let status = compute_status(*s, &metric.warning, &metric.critical)?;
let w = match metric.warning {
Some(ref w) => Some(w.as_str()),
None => None,
@ -300,7 +300,7 @@ impl Command {
max: compute_threshold(0, &max),
warning: w,
critical: c,
status: status.unwrap(),
status,
};
trace!("New metric '{}' with value {:?}", m.name, m.value);
metrics.push(m);
@ -360,7 +360,7 @@ impl Command {
res
}
};
let status = compute_status(item, &metric.warning, &metric.critical);
let status = compute_status(item, &metric.warning, &metric.critical)?;
let w = match metric.warning {
Some(ref w) => Some(w.as_str()),
None => None,
@ -376,7 +376,7 @@ impl Command {
max,
warning: w,
critical: c,
status: status.unwrap(),
status,
};
trace!("New metric '{}' with value {:?}", m.name, m.value);
metrics.push(m);
@ -384,7 +384,7 @@ impl Command {
}
ExprResult::Number(s) => {
let name = &metric.name;
let status = compute_status(s, &metric.warning, &metric.critical);
let status = compute_status(s, &metric.warning, &metric.critical)?;
let w = match metric.warning {
Some(ref w) => Some(w.as_str()),
None => None,
@ -400,7 +400,7 @@ impl Command {
max,
warning: w,
critical: c,
status: status.unwrap(),
status,
};
trace!("New metric '{}' with value {:?}", m.name, m.value);
metrics.push(m);
@ -412,9 +412,9 @@ impl Command {
trace!("collect: {:#?}", collect);
println!("metrics: {:#?}", metrics);
CmdResult {
Ok(CmdResult {
status: Status::Unknown,
output: "No result".to_string(),
}
})
}
}

View File

@ -14,30 +14,32 @@ mod compute;
mod generic;
mod snmp;
use generic::error::*;
use generic::Command;
use lalrpop_util::lalrpop_mod;
use lexopt::Arg;
use log::{debug, trace};
use serde_json::Result;
use snafu::ResultExt;
use std::fs;
lalrpop_mod!(grammar);
fn json_to_command(file_name: &str) -> Result<Command> {
fn json_to_command(file_name: &str) -> Result<Command, Error> {
// Transform content of the file into a string
let contents = match fs::read_to_string(file_name) {
Ok(ret) => ret,
Err(err) => {
println!("erreur: {}", err);
std::process::exit(3);
}
};
let contents = fs::read_to_string(file_name).context(JsonReadSnafu { path: file_name })?;
let module: Result<Command> = serde_json::from_str(&contents.as_str());
module
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(),
}),
}
}
fn main() {
fn main() -> Result<(), Error> {
env_logger::init();
use lexopt::prelude::*;
@ -64,14 +66,7 @@ fn main() {
let json = Some(parser.value().unwrap().into_string().unwrap());
let json = json.unwrap();
trace!("json: {:?}", json);
let res_cmd = json_to_command(&json);
cmd = Some(match res_cmd {
Ok(c) => c,
Err(err) => {
println!("json_to_command error: {:?}", err);
std::process::exit(3);
}
});
cmd = Some(json_to_command(&json)?);
}
Short('v') | Long("snmp-version") => {
snmp_version = parser.value().unwrap().into_string().unwrap();
@ -124,7 +119,7 @@ fn main() {
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)?,
None => {
println!("json is empty");
std::process::exit(3);
@ -133,4 +128,5 @@ fn main() {
//println!("{}", result.output);
//std::process::exit(result.status as i32);
Ok(())
}