cleanup(generic-snmp): SnmpItem merged with compute::ast::ExprResult

This commit is contained in:
David Boucher 2025-04-26 14:47:14 +02:00
parent f9ace6f4c4
commit 6020f9973e
4 changed files with 45 additions and 33 deletions

View File

@ -1,5 +1,4 @@
use log::debug;
use snmp::{SnmpItem, SnmpResult};
use snmp::SnmpResult;
use std::str;
#[derive(Debug)]
@ -24,6 +23,7 @@ pub enum Func {
pub enum ExprResult {
Vector(Vec<f64>),
Scalar(f64),
StrVector(Vec<String>),
}
impl std::ops::Add for ExprResult {
@ -71,6 +71,7 @@ impl std::ops::Add for ExprResult {
}
ExprResult::Vector(result)
}
_ => panic!("Invalid operation"),
}
}
}
@ -120,6 +121,7 @@ impl std::ops::Sub for ExprResult {
}
ExprResult::Vector(result)
}
_ => panic!("Invalid operation"),
}
}
}
@ -169,6 +171,7 @@ impl std::ops::Mul for ExprResult {
}
ExprResult::Vector(result)
}
_ => panic!("Invalid operation"),
}
}
}
@ -218,6 +221,7 @@ impl std::ops::Div for ExprResult {
}
ExprResult::Vector(result)
}
_ => panic!("Invalid operation"),
}
}
}
@ -227,12 +231,12 @@ impl<'input> Expr<'input> {
match self {
Expr::Number(n) => ExprResult::Scalar(*n),
Expr::Id(key) => {
println!("Evaluation of Id '{}'", str::from_utf8(key).unwrap());
let k = str::from_utf8(key).unwrap();
println!("Evaluation of Id '{}'", k);
for result in collect {
let k = str::from_utf8(key).unwrap();
let item = &result.items[k];
match item {
SnmpItem::Nbr(n) => {
ExprResult::Vector(n) => {
if n.len() == 1 {
println!("value {}", n[0]);
return ExprResult::Scalar(n[0]);
@ -259,6 +263,7 @@ impl<'input> Expr<'input> {
let sum = v.iter().sum::<f64>();
ExprResult::Scalar(sum / v.len() as f64)
}
_ => panic!("Invalid operation"),
},
Func::Min => match v {
ExprResult::Scalar(n) => ExprResult::Scalar(n),
@ -266,6 +271,7 @@ impl<'input> Expr<'input> {
let min = v.iter().cloned().fold(f64::INFINITY, f64::min);
ExprResult::Scalar(min)
}
_ => panic!("Invalid operation"),
},
Func::Max => match v {
ExprResult::Scalar(n) => ExprResult::Scalar(n),
@ -273,6 +279,7 @@ impl<'input> Expr<'input> {
let max = v.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
ExprResult::Scalar(max)
}
_ => panic!("Invalid operation"),
},
}
}

View File

@ -58,7 +58,6 @@ impl<'a> Parser<'a> {
mod Test {
use super::*;
use snmp::SnmpItem;
use std::collections::HashMap;
#[test]
@ -198,7 +197,7 @@ mod Test {
let res = grammar::ExprParser::new().parse(lexer);
assert!(res.is_ok());
println!("{:?}", res);
let items = HashMap::from([("abc".to_string(), SnmpItem::Nbr(vec![1_f64]))]);
let items = HashMap::from([("abc".to_string(), ExprResult::Vector(vec![1_f64]))]);
let snmp_result = vec![SnmpResult::new(items)];
let res = res.unwrap().eval(&snmp_result);
match res {
@ -217,8 +216,8 @@ mod Test {
let res = grammar::ExprParser::new().parse(lexer);
assert!(res.is_ok());
let items = HashMap::from([
("free".to_string(), SnmpItem::Nbr(vec![29600_f64])),
("total".to_string(), SnmpItem::Nbr(vec![747712_f64])),
("free".to_string(), ExprResult::Vector(vec![29600_f64])),
("total".to_string(), ExprResult::Vector(vec![747712_f64])),
]);
let snmp_result = vec![SnmpResult::new(items)];
let res = res.unwrap().eval(&snmp_result);
@ -233,7 +232,10 @@ mod Test {
let lexer = lexer::Lexer::new("Average({abc})");
let res = grammar::ExprParser::new().parse(lexer);
assert!(res.is_ok());
let items = HashMap::from([("abc".to_string(), SnmpItem::Nbr(vec![1_f64, 2_f64, 3_f64]))]);
let items = HashMap::from([(
"abc".to_string(),
ExprResult::Vector(vec![1_f64, 2_f64, 3_f64]),
)]);
let snmp_result = vec![SnmpResult::new(items)];
let res = res.unwrap().eval(&snmp_result);
match res {

View File

@ -152,6 +152,7 @@ impl Command {
let max = metric.max;
let parser = Parser::new(&collect);
let value = parser.eval(value).unwrap();
println!("ExprResult: {:?}", value);
match value {
ExprResult::Vector(v) => {
for item in v {
@ -193,6 +194,7 @@ impl Command {
};
metrics.push(m);
}
_ => panic!("Aggregation must be applied to a vector"),
}
println!("perfdata: {:?}", metrics);
}
@ -208,6 +210,7 @@ impl Command {
assert!(v.len() == 1);
v[0]
}
_ => panic!("Aggregation must be applied to a vector"),
})
} else if let Some(max_value) = metric.max {
Some(max_value)
@ -222,6 +225,7 @@ impl Command {
assert!(v.len() == 1);
v[0]
}
_ => panic!("Aggregation must be applied to a vector"),
})
} else if let Some(min_value) = metric.min {
Some(min_value)
@ -261,6 +265,7 @@ impl Command {
};
metrics.push(m);
}
_ => panic!("Aggregation must be applied to a vector"),
}
println!("perfdata: {:?}", metrics);
}

View File

@ -3,6 +3,7 @@ extern crate rasn;
extern crate rasn_smi;
extern crate rasn_snmp;
use compute::ast::ExprResult;
use log::{info, trace, warn};
use rasn::types::ObjectIdentifier;
use rasn_snmp::v2::BulkPdu;
@ -22,20 +23,14 @@ pub enum ValueType {
String(String),
}
#[derive(Debug)]
pub enum SnmpItem {
Nbr(Vec<f64>),
Str(Vec<String>),
}
#[derive(Debug)]
pub struct SnmpResult {
pub items: HashMap<String, SnmpItem>,
pub items: HashMap<String, ExprResult>,
last_oid: Vec<u32>,
}
impl SnmpResult {
pub fn new(items: HashMap<String, SnmpItem>) -> SnmpResult {
pub fn new(items: HashMap<String, ExprResult>) -> SnmpResult {
SnmpResult {
items,
last_oid: Vec::new(),
@ -462,7 +457,8 @@ impl SnmpResult {
self.items
.entry(key)
.and_modify(|e| match e {
SnmpItem::Nbr(v) => v.push(match &typ {
ExprResult::Scalar(_) => panic!("Should not arrive"),
ExprResult::Vector(v) => v.push(match &typ {
ValueType::Float(f) => *f,
ValueType::None(()) => {
panic!("Should not arrive");
@ -472,7 +468,7 @@ impl SnmpResult {
}
ValueType::Integer(i) => *i as f64,
}),
SnmpItem::Str(v) => v.push(match &typ {
ExprResult::StrVector(v) => v.push(match &typ {
ValueType::Float(_) => {
panic!("Value should be a string");
}
@ -486,12 +482,12 @@ impl SnmpResult {
}),
})
.or_insert(match typ {
ValueType::Float(f) => SnmpItem::Nbr(vec![f]),
ValueType::Float(f) => ExprResult::Vector(vec![f]),
ValueType::None(()) => {
panic!("Should not arrive");
}
ValueType::String(s) => SnmpItem::Str(vec![s]),
ValueType::Integer(i) => SnmpItem::Nbr(vec![i as f64]),
ValueType::String(s) => ExprResult::StrVector(vec![s]),
ValueType::Integer(i) => ExprResult::Vector(vec![i as f64]),
});
}
}
@ -573,7 +569,8 @@ impl SnmpResult {
self.items
.entry(key)
.and_modify(|e| match e {
SnmpItem::Nbr(v) => v.push(match &typ {
ExprResult::Scalar(_) => panic!("Should not arrive"),
ExprResult::Vector(v) => v.push(match &typ {
ValueType::Float(f) => *f,
ValueType::None(()) => {
panic!("Should not arrive");
@ -583,7 +580,7 @@ impl SnmpResult {
}
ValueType::Integer(i) => *i as f64,
}),
SnmpItem::Str(v) => v.push(match &typ {
ExprResult::StrVector(v) => v.push(match &typ {
ValueType::Float(_) => {
panic!("Value should be a string");
}
@ -597,12 +594,12 @@ impl SnmpResult {
}),
})
.or_insert(match typ {
ValueType::Float(f) => SnmpItem::Nbr(vec![f]),
ValueType::Float(f) => ExprResult::Vector(vec![f]),
ValueType::None(()) => {
panic!("Should not arrive");
}
ValueType::String(s) => SnmpItem::Str(vec![s]),
ValueType::Integer(i) => SnmpItem::Nbr(vec![i as f64]),
ValueType::String(s) => ExprResult::StrVector(vec![s]),
ValueType::Integer(i) => ExprResult::Vector(vec![i as f64]),
});
}
}
@ -715,7 +712,8 @@ impl SnmpResult {
self.items
.entry(key)
.and_modify(|e| match e {
SnmpItem::Nbr(v) => v.push(match &typ {
ExprResult::Scalar(_) => panic!("Should not arrive"),
ExprResult::Vector(v) => v.push(match &typ {
ValueType::Float(f) => *f,
ValueType::None(()) => {
panic!("Should not arrive");
@ -725,7 +723,7 @@ impl SnmpResult {
}
ValueType::Integer(i) => *i as f64,
}),
SnmpItem::Str(v) => v.push(match &typ {
ExprResult::StrVector(v) => v.push(match &typ {
ValueType::Float(_) => {
panic!("Value should be a string");
}
@ -739,12 +737,12 @@ impl SnmpResult {
}),
})
.or_insert(match typ {
ValueType::Float(f) => SnmpItem::Nbr(vec![f]),
ValueType::Float(f) => ExprResult::Vector(vec![f]),
ValueType::None(()) => {
panic!("Should not arrive");
}
ValueType::String(s) => SnmpItem::Str(vec![s]),
ValueType::Integer(i) => SnmpItem::Nbr(vec![i as f64]),
ValueType::String(s) => ExprResult::StrVector(vec![s]),
ValueType::Integer(i) => ExprResult::Vector(vec![i as f64]),
});
}
}