diff --git a/experimental/examples/new-disk.json.example b/experimental/examples/new-disk.json.example index fbc85a794..2c30de6c1 100644 --- a/experimental/examples/new-disk.json.example +++ b/experimental/examples/new-disk.json.example @@ -18,7 +18,7 @@ "metrics": [ { "prefix": "{disk.label}", // par défaut "{idx}" - "name": "disk.usage.percent", + "name": "disk.usage.percent", // le nom final est `prefix`#`name` "value": "100 * {disk.used} / {disk.size}", "uom": "%", // optional "min": 0, // optional diff --git a/experimental/src/compute/mod.rs b/experimental/src/compute/mod.rs new file mode 100644 index 000000000..80b42909f --- /dev/null +++ b/experimental/src/compute/mod.rs @@ -0,0 +1,17 @@ +use serde::Deserialize; + +#[derive(Deserialize, Debug)] +pub struct Metric { + pub name: String, + pub prefix: Option, + value: String, + uom: Option, + min: Option, + max: Option, +} + +#[derive(Deserialize, Debug)] +pub struct Compute { + pub metrics: Vec, + pub aggregations: Option>, +} diff --git a/experimental/src/generic/mod.rs b/experimental/src/generic/mod.rs index 4db00551b..e890b4a14 100644 --- a/experimental/src/generic/mod.rs +++ b/experimental/src/generic/mod.rs @@ -1,10 +1,11 @@ extern crate serde; extern crate serde_json; +use compute::Compute; use serde::Deserialize; -use snmp::{snmp_bulk_get, snmp_bulk_walk, SnmpResult, SnmpValue}; +use snmp::{snmp_bulk_get, snmp_bulk_walk, snmp_bulk_walk_with_labels, SnmpResult, SnmpValue}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; #[derive(Copy, Clone, PartialEq)] pub enum Status { @@ -51,21 +52,6 @@ enum QueryType { Walk, } -#[derive(Deserialize, Debug)] -struct Metric { - name: String, - value: String, - uom: Option, - min: Option, - max: Option, -} - -#[derive(Deserialize, Debug)] -pub struct Compute { - metrics: Vec, - aggregations: Option>, -} - #[derive(Deserialize, Debug)] pub struct Snmp { name: String, @@ -182,29 +168,36 @@ impl Command { community: &str, //ext: &CommandExt, ) -> CmdResult { - let mut res: BTreeMap = BTreeMap::new(); let mut to_get = Vec::new(); let mut get_name = Vec::new(); + let mut collect = Vec::new(); for s in self.collect.snmp.iter() { match s.query { QueryType::Walk => { - let r = snmp_bulk_walk(target, version, community, &s.oid); - match r.variables.len() { - 1 => { - let result = r.variables.get(0).unwrap(); - if let SnmpValue::Integer(v) = result.value { - res.insert(s.name.clone(), v); - } - } - _ => { - for (idx, result) in r.variables.iter().enumerate() { - if let SnmpValue::Integer(v) = result.value { - res.insert(format!("{}_{}", &s.name, idx), v); - } - } - } + if let Some(lab) = &s.labels { + let r = snmp_bulk_walk_with_labels( + target, version, community, &s.oid, &s.name, &lab, + ); + collect.push(r); + } else { + let r = snmp_bulk_walk(target, version, community, &s.oid); } + // match r.variables.len() { + // 1 => { + // let result = r.variables.get(0).unwrap(); + // if let SnmpValue::Integer(v) = result.value { + // res.insert(s.name.clone(), v); + // } + // } + // _ => { + // for (idx, result) in r.variables.iter().enumerate() { + // if let SnmpValue::Integer(v) = result.value { + // res.insert(format!("{}_{}", &s.name, idx), v); + // } + // } + // } + // } } QueryType::Get => { to_get.push(s.oid.as_str()); @@ -212,15 +205,24 @@ impl Command { } } } - if !to_get.is_empty() { - let r = snmp_bulk_get(target, version, community, 1, 1, &to_get); - for (idx, result) in r.variables.iter().enumerate() { - if let SnmpValue::Integer(v) = result.value { - res.insert(get_name[idx].to_string(), v); - } - } + println!("{:#?}", collect); + //let mut variables = HashMap::new(); + //for res in collect.iter_mut() { + // variables.extend(res.get_variables()); + //} + + for metric in &self.compute.metrics { + if let Some(prefix) = &metric.prefix {} + } + + if !to_get.is_empty() { + // let r = snmp_bulk_get(target, version, community, 1, 1, &to_get); + // for (idx, result) in r.variables.iter().enumerate() { + // if let SnmpValue::Integer(v) = result.value { + // res.insert(get_name[idx].to_string(), v); + // } + // } } - println!("Result variables: {:?}", res); // let mut aggregation = ("", 0, Operation::None); // let mut res: Option<(&str, SnmpResult)> = None; // for (idx, entry) in self.leaf.entries.iter().enumerate() { diff --git a/experimental/src/main.rs b/experimental/src/main.rs index d98dd9052..1adce216e 100644 --- a/experimental/src/main.rs +++ b/experimental/src/main.rs @@ -8,14 +8,14 @@ extern crate regex; extern crate serde; extern crate serde_json; +mod compute; mod generic; mod snmp; use generic::{Command, CommandExt}; use lalrpop_util::lalrpop_mod; use serde_json::Result; -use snmp::r_snmp_get; -use std::ffi::{OsStr, OsString}; +//use snmp::snmp_get; use std::fs; lalrpop_mod!(grammar); diff --git a/experimental/src/snmp/mod.rs b/experimental/src/snmp/mod.rs index 6e327b67e..c2b5792eb 100644 --- a/experimental/src/snmp/mod.rs +++ b/experimental/src/snmp/mod.rs @@ -11,22 +11,42 @@ use rasn_snmp::v2::VarBindValue; use rasn_snmp::v2::{BulkPdu, Pdu}; use rasn_snmp::v2::{GetBulkRequest, GetNextRequest, GetRequest}; use rasn_snmp::v2c::Message; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; use std::convert::TryInto; use std::net::UdpSocket; -#[derive(Debug, PartialEq)] -pub struct SnmpSubResult<'a> { - pub label: &'a str, - pub value: &'a str, - pub variables: Vec, +pub enum ValueType { + None(()), + Integer(i64), + Float(f32), + String(String), } -#[derive(Debug, PartialEq)] -pub struct SnmpResult<'a> { - pub labels: Vec>, +#[derive(Debug)] +pub enum SnmpItem { + Nbr(Vec), + Str(Vec), } +#[derive(Debug)] +pub struct SnmpResult { + items: BTreeMap, + last_oid: Vec, +} + +//#[derive(Debug, PartialEq)] +//pub struct SnmpSubResult<'a> { +// pub label: &'a str, +// pub value: &'a str, +// pub variables: Vec, +//} + +//#[derive(Debug, PartialEq)] +//pub struct SnmpResult<'a> { +// pub labels: Vec>, +// last_oid: Vec, +//} + #[derive(Debug, PartialEq)] pub enum SnmpValue { Integer(i64), @@ -39,58 +59,79 @@ pub struct SnmpVariable { pub value: SnmpValue, } -impl SnmpVariable { - fn new(name: String, value: SnmpValue) -> SnmpVariable { - SnmpVariable { name, value } - } -} - -impl<'a> SnmpResult<'a> { - fn new(labels: &'a BTreeMap) -> SnmpResult<'a> { - let mut retval: Vec = Vec::new(); - retval.reserve(labels.len()); - for (label, value) in labels.iter() { - let item = SnmpSubResult { - label: &label, - value: &value, - variables: Vec::new(), - }; - retval.push(item); - } - SnmpResult { labels: retval } - } - - fn new_simple() -> SnmpResult<'a> { - let label = SnmpSubResult{label: "", value: "", variables: Vec::new() }; - SnmpResult { labels: vec![label], } - } - - fn add_variable(&mut self, idx: usize, name: String, value: SnmpValue) { - self.labels[idx].variables.push(SnmpVariable::new(name, value)); - } - - fn get_last_oid(&self, idx: usize) -> &str { - if self.labels.is_empty() { - return ""; - } - let last = self.labels[idx].variables.iter().last().unwrap(); - if last.name.is_empty() { - return ""; - } - last.name.as_str() - } - - fn concat(&mut self, mut other: SnmpResult) { - for v in other.labels.iter_mut() { - for vv in self.labels.iter_mut() { - if v.label == vv.label { - vv.variables.extend(v.variables); - break; - } - } - } - } -} +//impl<'a> SnmpResult<'a> { +// fn new(labels: &'a BTreeMap) -> SnmpResult<'a> { +// let mut retval: Vec = Vec::new(); +// retval.reserve(labels.len()); +// for (label, value) in labels.iter() { +// let item = SnmpSubResult { +// label: &label, +// value: &value, +// variables: Vec::new(), +// }; +// retval.push(item); +// } +// SnmpResult { +// labels: retval, +// last_oid: Vec::new(), +// } +// } +// +// fn new_simple() -> SnmpResult<'a> { +// let label = SnmpSubResult { +// label: "", +// value: "", +// variables: Vec::new(), +// }; +// SnmpResult { +// labels: vec![label], +// last_oid: Vec::new(), +// } +// } +// +// fn add_variable(&mut self, idx: usize, name: String, value: SnmpValue) { +// self.labels[idx] +// .variables +// .push(SnmpVariable { name, value }); +// } +// +// fn get_last_oid(&self, idx: usize) -> &str { +// if self.labels.is_empty() { +// return ""; +// } +// let last = self.labels[idx].variables.iter().last().unwrap(); +// if last.name.is_empty() { +// return ""; +// } +// last.name.as_str() +// } +// +// fn merge(&mut self, mut other: SnmpResult) { +// for v in other.labels.iter_mut() { +// for vv in self.labels.iter_mut() { +// if v.label == vv.label { +// while !v.variables.is_empty() { +// let last = v.variables.pop().unwrap(); +// vv.variables.push(last); +// } +// break; +// } +// } +// } +// self.last_oid = other.last_oid; +// } +// +// pub fn get_variables(&self) -> HashMap { +// let retval = HashMap::new(); +// // for r in self.labels.iter() { +// // for s in r.variables.iter() { +// // let name = format!("{}.{}", self.name, r.label, s.label); +// // retval.insert(name, s.value); +// // } +// // } +// retval +// } +//} //pub fn snmp_get(target: &str, oid: &str, community: &str) -> SnmpResult { // let oid_tab = oid @@ -196,7 +237,7 @@ impl<'a> SnmpResult<'a> { // } // message = create_next_request(request_id, &resp_oid); // } -// retval.concat(build_response(decoded, &oid, true).0); +// retval.merge(build_response(decoded, &oid, true).0); // request_id += 1; // } // retval @@ -218,69 +259,72 @@ impl<'a> SnmpResult<'a> { /// use snmp_rust::r_snmp_bulk_get; /// let result = snmp_bulk_get("127.0.0.1:161", "2c", "public", "1.3.6.1.2.1.25.3.3.1.2"); /// ``` -//pub fn snmp_bulk_get( -// target: &str, -// _version: &str, -// community: &str, -// non_repeaters: u32, -// max_repetitions: u32, -// oid: &Vec<&str>, -//) -> SnmpResult { -// let mut oids_tab = oid -// .iter() -// .map(|x| { -// x.split('.') -// .map(|x| x.parse::().unwrap()) -// .collect::>() -// }) -// .collect::>>(); -// -// let mut retval = SnmpResult::new(); -// let mut request_id: i32 = 1; -// -// let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); -// socket.connect(target).expect("connect function failed"); -// let duration = std::time::Duration::from_millis(1000); -// socket.set_read_timeout(Some(duration)).unwrap(); -// -// let variable_bindings = oids_tab -// .iter() -// .map(|x| VarBind { -// name: ObjectIdentifier::new_unchecked(x.to_vec().into()), -// value: VarBindValue::Unspecified, -// }) -// .collect::>(); -// -// let pdu = BulkPdu { -// request_id, -// non_repeaters, -// max_repetitions, -// variable_bindings, -// }; -// -// let get_request: GetBulkRequest = GetBulkRequest(pdu); -// -// let message: Message = Message { -// version: 1.into(), -// community: community.to_string().into(), -// data: get_request.into(), -// }; -// -// // Send the message through an UDP socket -// let encoded: Vec = rasn::der::encode(&message).unwrap(); -// let res: usize = socket.send(&encoded).unwrap(); -// assert!(res == encoded.len()); -// -// let mut buf: [u8; 1024] = [0; 1024]; -// let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap(); -// -// trace!("Received {} bytes", resp.0); -// assert!(resp.0 > 0); -// let decoded: Message = rasn::ber::decode(&buf[0..resp.0]).unwrap(); -// let (result, _completed) = build_response(decoded, "", false); -// retval.concat(result); -// retval -//} +pub fn snmp_bulk_get<'a>( + target: &str, + _version: &str, + community: &str, + non_repeaters: u32, + max_repetitions: u32, + oid: &Vec<&str>, +) -> SnmpResult { + // let mut oids_tab = oid + // .iter() + // .map(|x| { + // x.split('.') + // .map(|x| x.parse::().unwrap()) + // .collect::>() + // }) + // .collect::>>(); + // + let mut retval = SnmpResult { + items: BTreeMap::new(), + last_oid: Vec::new(), + }; + // let mut request_id: i32 = 1; + // + // let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + // socket.connect(target).expect("connect function failed"); + // let duration = std::time::Duration::from_millis(1000); + // socket.set_read_timeout(Some(duration)).unwrap(); + // + // let variable_bindings = oids_tab + // .iter() + // .map(|x| VarBind { + // name: ObjectIdentifier::new_unchecked(x.to_vec().into()), + // value: VarBindValue::Unspecified, + // }) + // .collect::>(); + // + // let pdu = BulkPdu { + // request_id, + // non_repeaters, + // max_repetitions, + // variable_bindings, + // }; + // + // let get_request: GetBulkRequest = GetBulkRequest(pdu); + // + // let message: Message = Message { + // version: 1.into(), + // community: community.to_string().into(), + // data: get_request.into(), + // }; + // + // // Send the message through an UDP socket + // let encoded: Vec = rasn::der::encode(&message).unwrap(); + // let res: usize = socket.send(&encoded).unwrap(); + // assert!(res == encoded.len()); + // + // let mut buf: [u8; 1024] = [0; 1024]; + // let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap(); + // + // trace!("Received {} bytes", resp.0); + // assert!(resp.0 > 0); + // let decoded: Message = rasn::ber::decode(&buf[0..resp.0]).unwrap(); + // let (result, _completed) = build_response(decoded, "", false); + // retval.merge(result); + retval +} /// /// Bulk walk @@ -298,88 +342,96 @@ impl<'a> SnmpResult<'a> { /// use snmp_rust::snmp_bulk_walk; /// let result = snmp_bulk_walk("127.0.0.1:161", "2c", "public", "1.3.6.1.2.1.25.3.3.1.2"); /// ``` -//pub fn snmp_bulk_walk(target: &str, _version: &str, community: &str, oid: &str) -> SnmpResult { -// let mut oid_tab = oid -// .split('.') -// .map(|x| x.parse::().unwrap()) -// .collect::>(); -// -// let mut retval = SnmpResult::new_simple(); -// let mut request_id: i32 = 1; -// -// let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); -// socket.connect(target).expect("connect function failed"); -// let duration = std::time::Duration::from_millis(1000); -// socket.set_read_timeout(Some(duration)).unwrap(); -// -// loop { -// let variable_bindings = vec![VarBind { -// name: ObjectIdentifier::new_unchecked(oid_tab.to_vec().into()), -// value: VarBindValue::Unspecified, -// }]; -// -// let pdu = BulkPdu { -// request_id, -// non_repeaters: 0, -// max_repetitions: 10, -// variable_bindings, -// }; -// -// let get_request: GetBulkRequest = GetBulkRequest(pdu); -// -// let message: Message = Message { -// version: 1.into(), -// community: community.to_string().into(), -// data: get_request.into(), -// }; -// -// // Send the message through an UDP socket -// let encoded: Vec = rasn::der::encode(&message).unwrap(); -// let res: usize = socket.send(&encoded).unwrap(); -// assert!(res == encoded.len()); -// -// let mut buf: [u8; 1024] = [0; 1024]; -// let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap(); -// -// trace!("Received {} bytes", resp.0); -// assert!(resp.0 > 0); -// let decoded: Message = rasn::ber::decode(&buf[0..resp.0]).unwrap(); -// if let Pdus::Response(resp) = &decoded.data { -// let resp_oid = &resp.0.variable_bindings[0].name; -// let n = resp_oid.len() - 1; -// } -// let (result, completed) = build_response(decoded, &oid, true); -// retval.concat(result); -// if completed { -// break; -// } -// if !retval.variables.is_empty() { -// oid_tab = retval -// .variables -// .last() -// .unwrap() -// .name -// .split('.') -// .map(|x| x.parse::().unwrap()) -// .collect::>(); -// } -// } -// retval -//} +pub fn snmp_bulk_walk<'a>(target: &str, _version: &str, community: &str, oid: &str) -> SnmpResult { + let mut oid_tab = oid + .split('.') + .map(|x| x.parse::().unwrap()) + .collect::>(); + + let mut retval = SnmpResult { + items: BTreeMap::new(), + last_oid: Vec::new(), + }; + // let mut request_id: i32 = 1; + // + // let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + // socket.connect(target).expect("connect function failed"); + // let duration = std::time::Duration::from_millis(1000); + // socket.set_read_timeout(Some(duration)).unwrap(); + // + // loop { + // let variable_bindings = vec![VarBind { + // name: ObjectIdentifier::new_unchecked(oid_tab.to_vec().into()), + // value: VarBindValue::Unspecified, + // }]; + // + // let pdu = BulkPdu { + // request_id, + // non_repeaters: 0, + // max_repetitions: 10, + // variable_bindings, + // }; + // + // let get_request: GetBulkRequest = GetBulkRequest(pdu); + // + // let message: Message = Message { + // version: 1.into(), + // community: community.to_string().into(), + // data: get_request.into(), + // }; + // + // // Send the message through an UDP socket + // let encoded: Vec = rasn::der::encode(&message).unwrap(); + // let res: usize = socket.send(&encoded).unwrap(); + // assert!(res == encoded.len()); + // + // let mut buf: [u8; 1024] = [0; 1024]; + // let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap(); + // + // trace!("Received {} bytes", resp.0); + // assert!(resp.0 > 0); + // let decoded: Message = rasn::ber::decode(&buf[0..resp.0]).unwrap(); + // if let Pdus::Response(resp) = &decoded.data { + // let resp_oid = &resp.0.variable_bindings[0].name; + // let n = resp_oid.len() - 1; + // } + // let (result, completed) = build_response(decoded, &oid, true); + // retval.merge(result); + // if completed { + // break; + // } + // if !retval.variables.is_empty() { + // oid_tab = retval + // .variables + // .last() + // .unwrap() + // .name + // .split('.') + // .map(|x| x.parse::().unwrap()) + // .collect::>(); + // } + // } + retval +} pub fn snmp_bulk_walk_with_labels<'a>( target: &str, _version: &str, community: &str, oid: &str, + snmp_name: &str, labels: &'a BTreeMap, -) -> SnmpResult<'a> { - let mut oid_tab = oid +) -> SnmpResult { + let oid_init = oid .split('.') .map(|x| x.parse::().unwrap()) .collect::>(); - let mut retval = SnmpResult::new(&labels); + let mut oid_tab = &oid_init; + let mut retval = SnmpResult { + items: BTreeMap::new(), + last_oid: Vec::new(), + }; let request_id: i32 = 1; let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); @@ -419,199 +471,224 @@ pub fn snmp_bulk_walk_with_labels<'a>( trace!("Received {} bytes", resp.0); assert!(resp.0 > 0); let decoded: Message = rasn::ber::decode(&buf[0..resp.0]).unwrap(); - if let Pdus::Response(resp) = &decoded.data { - let resp_oid = &resp.0.variable_bindings[0].name; - let n = resp_oid.len() - 1; - oid_tab = resp.0.variable_bindings[n - 1].name.to_string().split('.') - .map(|x| x.parse::().unwrap()) - .collect::>(); - } - let (result, completed) = build_response_with_labels(decoded, &oid, labels, true); - retval.concat(result); + //if let Pdus::Response(resp) = &decoded.data { + // let resp_oid = &resp.0.variable_bindings[0].name; + // let oid_tab = &resp.0.variable_bindings.last().unwrap().name; + //} + let completed = retval.build_response_with_labels(decoded, &oid, snmp_name, labels, true); if completed { break; } + oid_tab = &retval.last_oid; } retval } -fn build_response_with_labels<'a>( - decoded: Message, - oid: &str, - labels: &'a BTreeMap, - walk: bool, -) -> (SnmpResult<'a>, bool) { - let mut retval = SnmpResult::new(labels); - let mut completed = false; - let mut last_oid: &str = ""; +impl SnmpResult { + fn build_response_with_labels<'a>( + &mut self, + decoded: Message, + oid: &str, + snmp_name: &str, + labels: &'a BTreeMap, + walk: bool, + ) -> bool { + let mut completed = false; - if let Pdus::Response(resp) = &decoded.data { - let vars = &resp.0.variable_bindings; - for var in vars { - let name = var.name.to_string(); - if walk { - if !name.starts_with(oid) { - completed = true; - last_oid = ""; - break; + if let Pdus::Response(resp) = &decoded.data { + let vars = &resp.0.variable_bindings; + for var in vars { + let name = var.name.to_string(); + self.last_oid = name + .split('.') + .map(|x| x.parse::().unwrap()) + .collect::>(); + if walk { + if !name.starts_with(oid) { + completed = true; + break; + } + } + let prefix = &name[..name.rfind('.').unwrap()]; + for l in labels { + if prefix.ends_with(l.0) { + let mut typ = ValueType::None(()); + let value = match &var.value { + VarBindValue::Unspecified => { + warn!("Unspecified"); + } + VarBindValue::NoSuchObject => { + warn!("NoSuchObject"); + } + VarBindValue::NoSuchInstance => { + warn!("NoSuchInstance"); + } + VarBindValue::EndOfMibView => { + warn!("EndOfMibView"); + } + VarBindValue::Value(value) => { + warn!("Value {:?}", &value); + match value { + rasn_smi::v2::ObjectSyntax::Simple(value) => { + info!("Simple {:?}", value); + match value { + rasn_smi::v2::SimpleSyntax::Integer(value) => { + typ = ValueType::Integer(value.try_into().unwrap()); + } + rasn_smi::v2::SimpleSyntax::String(value) => { + // We transform the value into a rust String + typ = ValueType::String( + String::from_utf8(value.to_vec()).unwrap(), + ); + } + rasn_smi::v2::SimpleSyntax::ObjectId(value) => { + let oid: String = value + .iter() + .map(|&id| id.to_string() + ".") + .collect(); + typ = ValueType::String(oid); + } + _ => { + typ = ValueType::String("Other".to_string()); + } + }; + } + rasn_smi::v2::ObjectSyntax::ApplicationWide(value) => { + info!("Application {:?}", value); + } + }; + } + }; + let key = format!("{}.{}", snmp_name, l.1); + self.items + .entry(key) + .and_modify(|e| match e { + SnmpItem::Nbr(v) => v.push(match &typ { + ValueType::Float(f) => *f, + ValueType::None(()) => { + panic!("Should not arrive"); + } + ValueType::String(_) => { + panic!("Value should be a float"); + } + ValueType::Integer(i) => *i as f32, + }), + SnmpItem::Str(v) => v.push(match &typ { + ValueType::Float(_) => { + panic!("Value should be a string"); + } + ValueType::None(()) => { + panic!("Should not arrive"); + } + ValueType::String(s) => s.to_string(), + ValueType::Integer(_) => { + panic!("Value should be a string"); + } + }), + }) + .or_insert(match typ { + ValueType::Float(f) => SnmpItem::Nbr(vec![f]), + ValueType::None(()) => { + panic!("Should not arrive"); + } + ValueType::String(s) => SnmpItem::Str(vec![s]), + ValueType::Integer(i) => SnmpItem::Nbr(vec![i as f32]), + }); + } } } - let mut idx: i32 = -1; - retval.labels.iter().enumerate().for_each(|label| { - if name.ends_with(label.1.label) { - idx = label.0 as i32; - return; - } - }); - if idx == -1 { - continue; - } - match &var.value { - VarBindValue::Unspecified => { - warn!("Unspecified"); - } - VarBindValue::NoSuchObject => { - warn!("NoSuchObject"); - } - VarBindValue::NoSuchInstance => { - warn!("NoSuchInstance"); - } - VarBindValue::EndOfMibView => { - warn!("EndOfMibView"); - } - VarBindValue::Value(value) => { - warn!("Value {:?}", &value); - match value { - rasn_smi::v2::ObjectSyntax::Simple(value) => { - info!("Simple {:?}", value); - match value { - rasn_smi::v2::SimpleSyntax::Integer(value) => { - let v = value.try_into().unwrap(); - retval.add_variable(idx as usize, name, SnmpValue::Integer(v)); - last_oid = retval.get_last_oid(idx as usize); - } - rasn_smi::v2::SimpleSyntax::String(value) => { - // We transform the value into a rust String - retval.add_variable( - idx as usize, - name, - SnmpValue::String( - String::from_utf8(value.to_vec()).unwrap(), - ), - ); - last_oid = retval.get_last_oid(idx as usize); - } - rasn_smi::v2::SimpleSyntax::ObjectId(value) => { - let oid: String = - value.iter().map(|&id| id.to_string() + ".").collect(); - retval.add_variable(idx as usize, name, SnmpValue::String(oid)); - last_oid = retval.get_last_oid(idx as usize); - } - _ => { - retval - .add_variable(idx as usize, name, SnmpValue::String("Other".to_string())); - last_oid = retval.get_last_oid(idx as usize); - } - }; - } - rasn_smi::v2::ObjectSyntax::ApplicationWide(value) => { - info!("Application {:?}", value); - } - }; - } - }; } + completed } - (retval, completed) } -fn build_response<'a>( - decoded: Message, - oid: &str, - walk: bool, -) -> (SnmpResult<'a>, bool) { - let mut retval = SnmpResult::new_simple(); - let mut completed = false; - let mut last_oid: &str = ""; - - if let Pdus::Response(resp) = &decoded.data { - let vars = &resp.0.variable_bindings; - for var in vars { - let name = var.name.to_string(); - if walk { - if !name.starts_with(oid) { - completed = true; - last_oid = ""; - break; - } - } - let mut idx: i32 = -1; - retval.labels.iter().enumerate().for_each(|label| { - if name.ends_with(label.1.label) { - idx = label.0 as i32; - return; - } - }); - if idx == -1 { - continue; - } - match &var.value { - VarBindValue::Unspecified => { - warn!("Unspecified"); - } - VarBindValue::NoSuchObject => { - warn!("NoSuchObject"); - } - VarBindValue::NoSuchInstance => { - warn!("NoSuchInstance"); - } - VarBindValue::EndOfMibView => { - warn!("EndOfMibView"); - } - VarBindValue::Value(value) => { - warn!("Value {:?}", &value); - match value { - rasn_smi::v2::ObjectSyntax::Simple(value) => { - info!("Simple {:?}", value); - match value { - rasn_smi::v2::SimpleSyntax::Integer(value) => { - let v = value.try_into().unwrap(); - retval.add_variable(idx as usize, name, SnmpValue::Integer(v)); - last_oid = retval.get_last_oid(idx as usize); - } - rasn_smi::v2::SimpleSyntax::String(value) => { - // We transform the value into a rust String - retval.add_variable(idx as usize, - name, - SnmpValue::String( - String::from_utf8(value.to_vec()).unwrap(), - ), - ); - last_oid = retval.get_last_oid(idx as usize); - } - rasn_smi::v2::SimpleSyntax::ObjectId(value) => { - let oid: String = - value.iter().map(|&id| id.to_string() + ".").collect(); - retval.add_variable(idx as usize, name, SnmpValue::String(oid)); - last_oid = retval.get_last_oid(idx as usize); - } - _ => { - retval - .add_variable(idx as usize, name, SnmpValue::String("Other".to_string())); - last_oid = retval.get_last_oid(idx as usize); - } - }; - } - rasn_smi::v2::ObjectSyntax::ApplicationWide(value) => { - info!("Application {:?}", value); - } - }; - } - }; - } - } - (retval, completed) -} +//fn build_response<'a>(decoded: Message, oid: &str, walk: bool) -> (SnmpResult, bool) { +// let mut retval = SnmpResult{items: BTreeMap::new(), last_oid: Vec::new()}; +// let mut completed = false; +// let mut last_oid: &str = ""; +// +// if let Pdus::Response(resp) = &decoded.data { +// let vars = &resp.0.variable_bindings; +// for var in vars { +// let name = var.name.to_string(); +// if walk { +// if !name.starts_with(oid) { +// completed = true; +// last_oid = ""; +// break; +// } +// } +// let mut idx: i32 = -1; +// retval.labels.iter().enumerate().for_each(|label| { +// if name.ends_with(label.1.label) { +// idx = label.0 as i32; +// return; +// } +// }); +// if idx == -1 { +// continue; +// } +// match &var.value { +// VarBindValue::Unspecified => { +// warn!("Unspecified"); +// } +// VarBindValue::NoSuchObject => { +// warn!("NoSuchObject"); +// } +// VarBindValue::NoSuchInstance => { +// warn!("NoSuchInstance"); +// } +// VarBindValue::EndOfMibView => { +// warn!("EndOfMibView"); +// } +// VarBindValue::Value(value) => { +// warn!("Value {:?}", &value); +// match value { +// rasn_smi::v2::ObjectSyntax::Simple(value) => { +// info!("Simple {:?}", value); +// match value { +// rasn_smi::v2::SimpleSyntax::Integer(value) => { +// let v = value.try_into().unwrap(); +// retval.add_variable(idx as usize, name, SnmpValue::Integer(v)); +// last_oid = retval.get_last_oid(idx as usize); +// } +// rasn_smi::v2::SimpleSyntax::String(value) => { +// // We transform the value into a rust String +// retval.add_variable( +// idx as usize, +// name, +// SnmpValue::String( +// String::from_utf8(value.to_vec()).unwrap(), +// ), +// ); +// last_oid = retval.get_last_oid(idx as usize); +// } +// rasn_smi::v2::SimpleSyntax::ObjectId(value) => { +// let oid: String = +// value.iter().map(|&id| id.to_string() + ".").collect(); +// retval.add_variable(idx as usize, name, SnmpValue::String(oid)); +// last_oid = retval.get_last_oid(idx as usize); +// } +// _ => { +// retval.add_variable( +// idx as usize, +// name, +// SnmpValue::String("Other".to_string()), +// ); +// last_oid = retval.get_last_oid(idx as usize); +// } +// }; +// } +// rasn_smi::v2::ObjectSyntax::ApplicationWide(value) => { +// info!("Application {:?}", value); +// } +// }; +// } +// }; +// } +// } +// (retval, completed) +//} //mod tests { // use super::*; // @@ -619,9 +696,9 @@ fn build_response<'a>( // fn test_snmp_get() { // let result = r_snmp_get("127.0.0.1:161", "1.3.6.1.2.1.1.1.0", "public"); // let expected = SnmpResult { -// variables: vec![SnmpVariable::new( +// variables: vec![SnmpVariable{ // "1.3.6.1.2.1.1.1.0".to_string(), -// "Linux CNTR-PORT-A104 6.1.0-31-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.128-1 (2025-02-07) x86_64".to_string())], +// "Linux CNTR-PORT-A104 6.1.0-31-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.128-1 (2025-02-07) x86_64".to_string()}], // }; // assert_eq!(result, expected); // }