mirror of
https://github.com/centreon/centreon-plugins.git
synced 2025-07-30 00:55:18 +02:00
enh(generic-snmp): the best version to work with new-disk.json
We have to rewrite the plugin to work also with others json files.
This commit is contained in:
parent
1e69310f40
commit
65f386159b
@ -18,7 +18,7 @@
|
|||||||
"metrics": [
|
"metrics": [
|
||||||
{
|
{
|
||||||
"prefix": "{disk.label}", // par défaut "{idx}"
|
"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}",
|
"value": "100 * {disk.used} / {disk.size}",
|
||||||
"uom": "%", // optional
|
"uom": "%", // optional
|
||||||
"min": 0, // optional
|
"min": 0, // optional
|
||||||
|
17
experimental/src/compute/mod.rs
Normal file
17
experimental/src/compute/mod.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct Metric {
|
||||||
|
pub name: String,
|
||||||
|
pub prefix: Option<String>,
|
||||||
|
value: String,
|
||||||
|
uom: Option<String>,
|
||||||
|
min: Option<f32>,
|
||||||
|
max: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct Compute {
|
||||||
|
pub metrics: Vec<Metric>,
|
||||||
|
pub aggregations: Option<Vec<Metric>>,
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
|
use compute::Compute;
|
||||||
use serde::Deserialize;
|
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)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum Status {
|
pub enum Status {
|
||||||
@ -51,21 +52,6 @@ enum QueryType {
|
|||||||
Walk,
|
Walk,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
|
||||||
struct Metric {
|
|
||||||
name: String,
|
|
||||||
value: String,
|
|
||||||
uom: Option<String>,
|
|
||||||
min: Option<f32>,
|
|
||||||
max: Option<f32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
|
||||||
pub struct Compute {
|
|
||||||
metrics: Vec<Metric>,
|
|
||||||
aggregations: Option<Vec<Metric>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct Snmp {
|
pub struct Snmp {
|
||||||
name: String,
|
name: String,
|
||||||
@ -182,29 +168,36 @@ impl Command {
|
|||||||
community: &str,
|
community: &str,
|
||||||
//ext: &CommandExt,
|
//ext: &CommandExt,
|
||||||
) -> CmdResult {
|
) -> CmdResult {
|
||||||
let mut res: BTreeMap<String, i64> = BTreeMap::new();
|
|
||||||
let mut to_get = Vec::new();
|
let mut to_get = Vec::new();
|
||||||
let mut get_name = Vec::new();
|
let mut get_name = Vec::new();
|
||||||
|
let mut collect = Vec::new();
|
||||||
|
|
||||||
for s in self.collect.snmp.iter() {
|
for s in self.collect.snmp.iter() {
|
||||||
match s.query {
|
match s.query {
|
||||||
QueryType::Walk => {
|
QueryType::Walk => {
|
||||||
let r = snmp_bulk_walk(target, version, community, &s.oid);
|
if let Some(lab) = &s.labels {
|
||||||
match r.variables.len() {
|
let r = snmp_bulk_walk_with_labels(
|
||||||
1 => {
|
target, version, community, &s.oid, &s.name, &lab,
|
||||||
let result = r.variables.get(0).unwrap();
|
);
|
||||||
if let SnmpValue::Integer(v) = result.value {
|
collect.push(r);
|
||||||
res.insert(s.name.clone(), v);
|
} else {
|
||||||
}
|
let r = snmp_bulk_walk(target, version, community, &s.oid);
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
for (idx, result) in r.variables.iter().enumerate() {
|
|
||||||
if let SnmpValue::Integer(v) = result.value {
|
|
||||||
res.insert(format!("{}_{}", &s.name, idx), v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 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 => {
|
QueryType::Get => {
|
||||||
to_get.push(s.oid.as_str());
|
to_get.push(s.oid.as_str());
|
||||||
@ -212,15 +205,24 @@ impl Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !to_get.is_empty() {
|
println!("{:#?}", collect);
|
||||||
let r = snmp_bulk_get(target, version, community, 1, 1, &to_get);
|
//let mut variables = HashMap::new();
|
||||||
for (idx, result) in r.variables.iter().enumerate() {
|
//for res in collect.iter_mut() {
|
||||||
if let SnmpValue::Integer(v) = result.value {
|
// variables.extend(res.get_variables());
|
||||||
res.insert(get_name[idx].to_string(), v);
|
//}
|
||||||
}
|
|
||||||
}
|
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 aggregation = ("", 0, Operation::None);
|
||||||
// let mut res: Option<(&str, SnmpResult)> = None;
|
// let mut res: Option<(&str, SnmpResult)> = None;
|
||||||
// for (idx, entry) in self.leaf.entries.iter().enumerate() {
|
// for (idx, entry) in self.leaf.entries.iter().enumerate() {
|
||||||
|
@ -8,14 +8,14 @@ extern crate regex;
|
|||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
|
mod compute;
|
||||||
mod generic;
|
mod generic;
|
||||||
mod snmp;
|
mod snmp;
|
||||||
|
|
||||||
use generic::{Command, CommandExt};
|
use generic::{Command, CommandExt};
|
||||||
use lalrpop_util::lalrpop_mod;
|
use lalrpop_util::lalrpop_mod;
|
||||||
use serde_json::Result;
|
use serde_json::Result;
|
||||||
use snmp::r_snmp_get;
|
//use snmp::snmp_get;
|
||||||
use std::ffi::{OsStr, OsString};
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
lalrpop_mod!(grammar);
|
lalrpop_mod!(grammar);
|
||||||
|
@ -11,22 +11,42 @@ use rasn_snmp::v2::VarBindValue;
|
|||||||
use rasn_snmp::v2::{BulkPdu, Pdu};
|
use rasn_snmp::v2::{BulkPdu, Pdu};
|
||||||
use rasn_snmp::v2::{GetBulkRequest, GetNextRequest, GetRequest};
|
use rasn_snmp::v2::{GetBulkRequest, GetNextRequest, GetRequest};
|
||||||
use rasn_snmp::v2c::Message;
|
use rasn_snmp::v2c::Message;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::net::UdpSocket;
|
use std::net::UdpSocket;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
pub enum ValueType {
|
||||||
pub struct SnmpSubResult<'a> {
|
None(()),
|
||||||
pub label: &'a str,
|
Integer(i64),
|
||||||
pub value: &'a str,
|
Float(f32),
|
||||||
pub variables: Vec<SnmpVariable>,
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct SnmpResult<'a> {
|
pub enum SnmpItem {
|
||||||
pub labels: Vec<SnmpSubResult<'a>>,
|
Nbr(Vec<f32>),
|
||||||
|
Str(Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SnmpResult {
|
||||||
|
items: BTreeMap<String, SnmpItem>,
|
||||||
|
last_oid: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
//#[derive(Debug, PartialEq)]
|
||||||
|
//pub struct SnmpSubResult<'a> {
|
||||||
|
// pub label: &'a str,
|
||||||
|
// pub value: &'a str,
|
||||||
|
// pub variables: Vec<SnmpVariable>,
|
||||||
|
//}
|
||||||
|
|
||||||
|
//#[derive(Debug, PartialEq)]
|
||||||
|
//pub struct SnmpResult<'a> {
|
||||||
|
// pub labels: Vec<SnmpSubResult<'a>>,
|
||||||
|
// last_oid: Vec<u32>,
|
||||||
|
//}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum SnmpValue {
|
pub enum SnmpValue {
|
||||||
Integer(i64),
|
Integer(i64),
|
||||||
@ -39,58 +59,79 @@ pub struct SnmpVariable {
|
|||||||
pub value: SnmpValue,
|
pub value: SnmpValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SnmpVariable {
|
//impl<'a> SnmpResult<'a> {
|
||||||
fn new(name: String, value: SnmpValue) -> SnmpVariable {
|
// fn new(labels: &'a BTreeMap<String, String>) -> SnmpResult<'a> {
|
||||||
SnmpVariable { name, value }
|
// let mut retval: Vec<SnmpSubResult> = Vec::new();
|
||||||
}
|
// retval.reserve(labels.len());
|
||||||
}
|
// for (label, value) in labels.iter() {
|
||||||
|
// let item = SnmpSubResult {
|
||||||
impl<'a> SnmpResult<'a> {
|
// label: &label,
|
||||||
fn new(labels: &'a BTreeMap<String, String>) -> SnmpResult<'a> {
|
// value: &value,
|
||||||
let mut retval: Vec<SnmpSubResult> = Vec::new();
|
// variables: Vec::new(),
|
||||||
retval.reserve(labels.len());
|
// };
|
||||||
for (label, value) in labels.iter() {
|
// retval.push(item);
|
||||||
let item = SnmpSubResult {
|
// }
|
||||||
label: &label,
|
// SnmpResult {
|
||||||
value: &value,
|
// labels: retval,
|
||||||
variables: Vec::new(),
|
// last_oid: Vec::new(),
|
||||||
};
|
// }
|
||||||
retval.push(item);
|
// }
|
||||||
}
|
//
|
||||||
SnmpResult { labels: retval }
|
// fn new_simple() -> SnmpResult<'a> {
|
||||||
}
|
// let label = SnmpSubResult {
|
||||||
|
// label: "",
|
||||||
fn new_simple() -> SnmpResult<'a> {
|
// value: "",
|
||||||
let label = SnmpSubResult{label: "", value: "", variables: Vec::new() };
|
// variables: Vec::new(),
|
||||||
SnmpResult { labels: vec![label], }
|
// };
|
||||||
}
|
// SnmpResult {
|
||||||
|
// labels: vec![label],
|
||||||
fn add_variable(&mut self, idx: usize, name: String, value: SnmpValue) {
|
// last_oid: Vec::new(),
|
||||||
self.labels[idx].variables.push(SnmpVariable::new(name, value));
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn get_last_oid(&self, idx: usize) -> &str {
|
// fn add_variable(&mut self, idx: usize, name: String, value: SnmpValue) {
|
||||||
if self.labels.is_empty() {
|
// self.labels[idx]
|
||||||
return "";
|
// .variables
|
||||||
}
|
// .push(SnmpVariable { name, value });
|
||||||
let last = self.labels[idx].variables.iter().last().unwrap();
|
// }
|
||||||
if last.name.is_empty() {
|
//
|
||||||
return "";
|
// fn get_last_oid(&self, idx: usize) -> &str {
|
||||||
}
|
// if self.labels.is_empty() {
|
||||||
last.name.as_str()
|
// return "";
|
||||||
}
|
// }
|
||||||
|
// let last = self.labels[idx].variables.iter().last().unwrap();
|
||||||
fn concat(&mut self, mut other: SnmpResult) {
|
// if last.name.is_empty() {
|
||||||
for v in other.labels.iter_mut() {
|
// return "";
|
||||||
for vv in self.labels.iter_mut() {
|
// }
|
||||||
if v.label == vv.label {
|
// last.name.as_str()
|
||||||
vv.variables.extend(v.variables);
|
// }
|
||||||
break;
|
//
|
||||||
}
|
// 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<String, SnmpValue> {
|
||||||
|
// 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 {
|
//pub fn snmp_get(target: &str, oid: &str, community: &str) -> SnmpResult {
|
||||||
// let oid_tab = oid
|
// let oid_tab = oid
|
||||||
@ -196,7 +237,7 @@ impl<'a> SnmpResult<'a> {
|
|||||||
// }
|
// }
|
||||||
// message = create_next_request(request_id, &resp_oid);
|
// 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;
|
// request_id += 1;
|
||||||
// }
|
// }
|
||||||
// retval
|
// retval
|
||||||
@ -218,69 +259,72 @@ impl<'a> SnmpResult<'a> {
|
|||||||
/// use snmp_rust::r_snmp_bulk_get;
|
/// 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");
|
/// 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(
|
pub fn snmp_bulk_get<'a>(
|
||||||
// target: &str,
|
target: &str,
|
||||||
// _version: &str,
|
_version: &str,
|
||||||
// community: &str,
|
community: &str,
|
||||||
// non_repeaters: u32,
|
non_repeaters: u32,
|
||||||
// max_repetitions: u32,
|
max_repetitions: u32,
|
||||||
// oid: &Vec<&str>,
|
oid: &Vec<&str>,
|
||||||
//) -> SnmpResult {
|
) -> SnmpResult {
|
||||||
// let mut oids_tab = oid
|
// let mut oids_tab = oid
|
||||||
// .iter()
|
// .iter()
|
||||||
// .map(|x| {
|
// .map(|x| {
|
||||||
// x.split('.')
|
// x.split('.')
|
||||||
// .map(|x| x.parse::<u32>().unwrap())
|
// .map(|x| x.parse::<u32>().unwrap())
|
||||||
// .collect::<Vec<u32>>()
|
// .collect::<Vec<u32>>()
|
||||||
// })
|
// })
|
||||||
// .collect::<Vec<Vec<u32>>>();
|
// .collect::<Vec<Vec<u32>>>();
|
||||||
//
|
//
|
||||||
// let mut retval = SnmpResult::new();
|
let mut retval = SnmpResult {
|
||||||
// let mut request_id: i32 = 1;
|
items: BTreeMap::new(),
|
||||||
//
|
last_oid: Vec::new(),
|
||||||
// let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
};
|
||||||
// socket.connect(target).expect("connect function failed");
|
// let mut request_id: i32 = 1;
|
||||||
// let duration = std::time::Duration::from_millis(1000);
|
//
|
||||||
// socket.set_read_timeout(Some(duration)).unwrap();
|
// let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||||
//
|
// socket.connect(target).expect("connect function failed");
|
||||||
// let variable_bindings = oids_tab
|
// let duration = std::time::Duration::from_millis(1000);
|
||||||
// .iter()
|
// socket.set_read_timeout(Some(duration)).unwrap();
|
||||||
// .map(|x| VarBind {
|
//
|
||||||
// name: ObjectIdentifier::new_unchecked(x.to_vec().into()),
|
// let variable_bindings = oids_tab
|
||||||
// value: VarBindValue::Unspecified,
|
// .iter()
|
||||||
// })
|
// .map(|x| VarBind {
|
||||||
// .collect::<Vec<VarBind>>();
|
// name: ObjectIdentifier::new_unchecked(x.to_vec().into()),
|
||||||
//
|
// value: VarBindValue::Unspecified,
|
||||||
// let pdu = BulkPdu {
|
// })
|
||||||
// request_id,
|
// .collect::<Vec<VarBind>>();
|
||||||
// non_repeaters,
|
//
|
||||||
// max_repetitions,
|
// let pdu = BulkPdu {
|
||||||
// variable_bindings,
|
// request_id,
|
||||||
// };
|
// non_repeaters,
|
||||||
//
|
// max_repetitions,
|
||||||
// let get_request: GetBulkRequest = GetBulkRequest(pdu);
|
// variable_bindings,
|
||||||
//
|
// };
|
||||||
// let message: Message<GetBulkRequest> = Message {
|
//
|
||||||
// version: 1.into(),
|
// let get_request: GetBulkRequest = GetBulkRequest(pdu);
|
||||||
// community: community.to_string().into(),
|
//
|
||||||
// data: get_request.into(),
|
// let message: Message<GetBulkRequest> = Message {
|
||||||
// };
|
// version: 1.into(),
|
||||||
//
|
// community: community.to_string().into(),
|
||||||
// // Send the message through an UDP socket
|
// data: get_request.into(),
|
||||||
// let encoded: Vec<u8> = rasn::der::encode(&message).unwrap();
|
// };
|
||||||
// let res: usize = socket.send(&encoded).unwrap();
|
//
|
||||||
// assert!(res == encoded.len());
|
// // Send the message through an UDP socket
|
||||||
//
|
// let encoded: Vec<u8> = rasn::der::encode(&message).unwrap();
|
||||||
// let mut buf: [u8; 1024] = [0; 1024];
|
// let res: usize = socket.send(&encoded).unwrap();
|
||||||
// let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap();
|
// assert!(res == encoded.len());
|
||||||
//
|
//
|
||||||
// trace!("Received {} bytes", resp.0);
|
// let mut buf: [u8; 1024] = [0; 1024];
|
||||||
// assert!(resp.0 > 0);
|
// let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap();
|
||||||
// let decoded: Message<Pdus> = rasn::ber::decode(&buf[0..resp.0]).unwrap();
|
//
|
||||||
// let (result, _completed) = build_response(decoded, "", false);
|
// trace!("Received {} bytes", resp.0);
|
||||||
// retval.concat(result);
|
// assert!(resp.0 > 0);
|
||||||
// retval
|
// let decoded: Message<Pdus> = rasn::ber::decode(&buf[0..resp.0]).unwrap();
|
||||||
//}
|
// let (result, _completed) = build_response(decoded, "", false);
|
||||||
|
// retval.merge(result);
|
||||||
|
retval
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Bulk walk
|
/// Bulk walk
|
||||||
@ -298,88 +342,96 @@ impl<'a> SnmpResult<'a> {
|
|||||||
/// use snmp_rust::snmp_bulk_walk;
|
/// 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");
|
/// 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 {
|
pub fn snmp_bulk_walk<'a>(target: &str, _version: &str, community: &str, oid: &str) -> SnmpResult {
|
||||||
// let mut oid_tab = oid
|
let mut oid_tab = oid
|
||||||
// .split('.')
|
.split('.')
|
||||||
// .map(|x| x.parse::<u32>().unwrap())
|
.map(|x| x.parse::<u32>().unwrap())
|
||||||
// .collect::<Vec<u32>>();
|
.collect::<Vec<u32>>();
|
||||||
//
|
|
||||||
// let mut retval = SnmpResult::new_simple();
|
let mut retval = SnmpResult {
|
||||||
// let mut request_id: i32 = 1;
|
items: BTreeMap::new(),
|
||||||
//
|
last_oid: Vec::new(),
|
||||||
// let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
};
|
||||||
// socket.connect(target).expect("connect function failed");
|
// let mut request_id: i32 = 1;
|
||||||
// let duration = std::time::Duration::from_millis(1000);
|
//
|
||||||
// socket.set_read_timeout(Some(duration)).unwrap();
|
// let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||||
//
|
// socket.connect(target).expect("connect function failed");
|
||||||
// loop {
|
// let duration = std::time::Duration::from_millis(1000);
|
||||||
// let variable_bindings = vec![VarBind {
|
// socket.set_read_timeout(Some(duration)).unwrap();
|
||||||
// name: ObjectIdentifier::new_unchecked(oid_tab.to_vec().into()),
|
//
|
||||||
// value: VarBindValue::Unspecified,
|
// loop {
|
||||||
// }];
|
// let variable_bindings = vec![VarBind {
|
||||||
//
|
// name: ObjectIdentifier::new_unchecked(oid_tab.to_vec().into()),
|
||||||
// let pdu = BulkPdu {
|
// value: VarBindValue::Unspecified,
|
||||||
// request_id,
|
// }];
|
||||||
// non_repeaters: 0,
|
//
|
||||||
// max_repetitions: 10,
|
// let pdu = BulkPdu {
|
||||||
// variable_bindings,
|
// request_id,
|
||||||
// };
|
// non_repeaters: 0,
|
||||||
//
|
// max_repetitions: 10,
|
||||||
// let get_request: GetBulkRequest = GetBulkRequest(pdu);
|
// variable_bindings,
|
||||||
//
|
// };
|
||||||
// let message: Message<GetBulkRequest> = Message {
|
//
|
||||||
// version: 1.into(),
|
// let get_request: GetBulkRequest = GetBulkRequest(pdu);
|
||||||
// community: community.to_string().into(),
|
//
|
||||||
// data: get_request.into(),
|
// let message: Message<GetBulkRequest> = Message {
|
||||||
// };
|
// version: 1.into(),
|
||||||
//
|
// community: community.to_string().into(),
|
||||||
// // Send the message through an UDP socket
|
// data: get_request.into(),
|
||||||
// let encoded: Vec<u8> = rasn::der::encode(&message).unwrap();
|
// };
|
||||||
// let res: usize = socket.send(&encoded).unwrap();
|
//
|
||||||
// assert!(res == encoded.len());
|
// // Send the message through an UDP socket
|
||||||
//
|
// let encoded: Vec<u8> = rasn::der::encode(&message).unwrap();
|
||||||
// let mut buf: [u8; 1024] = [0; 1024];
|
// let res: usize = socket.send(&encoded).unwrap();
|
||||||
// let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap();
|
// assert!(res == encoded.len());
|
||||||
//
|
//
|
||||||
// trace!("Received {} bytes", resp.0);
|
// let mut buf: [u8; 1024] = [0; 1024];
|
||||||
// assert!(resp.0 > 0);
|
// let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap();
|
||||||
// let decoded: Message<Pdus> = rasn::ber::decode(&buf[0..resp.0]).unwrap();
|
//
|
||||||
// if let Pdus::Response(resp) = &decoded.data {
|
// trace!("Received {} bytes", resp.0);
|
||||||
// let resp_oid = &resp.0.variable_bindings[0].name;
|
// assert!(resp.0 > 0);
|
||||||
// let n = resp_oid.len() - 1;
|
// let decoded: Message<Pdus> = rasn::ber::decode(&buf[0..resp.0]).unwrap();
|
||||||
// }
|
// if let Pdus::Response(resp) = &decoded.data {
|
||||||
// let (result, completed) = build_response(decoded, &oid, true);
|
// let resp_oid = &resp.0.variable_bindings[0].name;
|
||||||
// retval.concat(result);
|
// let n = resp_oid.len() - 1;
|
||||||
// if completed {
|
// }
|
||||||
// break;
|
// let (result, completed) = build_response(decoded, &oid, true);
|
||||||
// }
|
// retval.merge(result);
|
||||||
// if !retval.variables.is_empty() {
|
// if completed {
|
||||||
// oid_tab = retval
|
// break;
|
||||||
// .variables
|
// }
|
||||||
// .last()
|
// if !retval.variables.is_empty() {
|
||||||
// .unwrap()
|
// oid_tab = retval
|
||||||
// .name
|
// .variables
|
||||||
// .split('.')
|
// .last()
|
||||||
// .map(|x| x.parse::<u32>().unwrap())
|
// .unwrap()
|
||||||
// .collect::<Vec<u32>>();
|
// .name
|
||||||
// }
|
// .split('.')
|
||||||
// }
|
// .map(|x| x.parse::<u32>().unwrap())
|
||||||
// retval
|
// .collect::<Vec<u32>>();
|
||||||
//}
|
// }
|
||||||
|
// }
|
||||||
|
retval
|
||||||
|
}
|
||||||
|
|
||||||
pub fn snmp_bulk_walk_with_labels<'a>(
|
pub fn snmp_bulk_walk_with_labels<'a>(
|
||||||
target: &str,
|
target: &str,
|
||||||
_version: &str,
|
_version: &str,
|
||||||
community: &str,
|
community: &str,
|
||||||
oid: &str,
|
oid: &str,
|
||||||
|
snmp_name: &str,
|
||||||
labels: &'a BTreeMap<String, String>,
|
labels: &'a BTreeMap<String, String>,
|
||||||
) -> SnmpResult<'a> {
|
) -> SnmpResult {
|
||||||
let mut oid_tab = oid
|
let oid_init = oid
|
||||||
.split('.')
|
.split('.')
|
||||||
.map(|x| x.parse::<u32>().unwrap())
|
.map(|x| x.parse::<u32>().unwrap())
|
||||||
.collect::<Vec<u32>>();
|
.collect::<Vec<u32>>();
|
||||||
|
|
||||||
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 request_id: i32 = 1;
|
||||||
|
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
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);
|
trace!("Received {} bytes", resp.0);
|
||||||
assert!(resp.0 > 0);
|
assert!(resp.0 > 0);
|
||||||
let decoded: Message<Pdus> = rasn::ber::decode(&buf[0..resp.0]).unwrap();
|
let decoded: Message<Pdus> = rasn::ber::decode(&buf[0..resp.0]).unwrap();
|
||||||
if let Pdus::Response(resp) = &decoded.data {
|
//if let Pdus::Response(resp) = &decoded.data {
|
||||||
let resp_oid = &resp.0.variable_bindings[0].name;
|
// let resp_oid = &resp.0.variable_bindings[0].name;
|
||||||
let n = resp_oid.len() - 1;
|
// let oid_tab = &resp.0.variable_bindings.last().unwrap().name;
|
||||||
oid_tab = resp.0.variable_bindings[n - 1].name.to_string().split('.')
|
//}
|
||||||
.map(|x| x.parse::<u32>().unwrap())
|
let completed = retval.build_response_with_labels(decoded, &oid, snmp_name, labels, true);
|
||||||
.collect::<Vec<u32>>();
|
|
||||||
}
|
|
||||||
let (result, completed) = build_response_with_labels(decoded, &oid, labels, true);
|
|
||||||
retval.concat(result);
|
|
||||||
if completed {
|
if completed {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
oid_tab = &retval.last_oid;
|
||||||
}
|
}
|
||||||
retval
|
retval
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response_with_labels<'a>(
|
impl SnmpResult {
|
||||||
decoded: Message<Pdus>,
|
fn build_response_with_labels<'a>(
|
||||||
oid: &str,
|
&mut self,
|
||||||
labels: &'a BTreeMap<String, String>,
|
decoded: Message<Pdus>,
|
||||||
walk: bool,
|
oid: &str,
|
||||||
) -> (SnmpResult<'a>, bool) {
|
snmp_name: &str,
|
||||||
let mut retval = SnmpResult::new(labels);
|
labels: &'a BTreeMap<String, String>,
|
||||||
let mut completed = false;
|
walk: bool,
|
||||||
let mut last_oid: &str = "";
|
) -> bool {
|
||||||
|
let mut completed = false;
|
||||||
|
|
||||||
if let Pdus::Response(resp) = &decoded.data {
|
if let Pdus::Response(resp) = &decoded.data {
|
||||||
let vars = &resp.0.variable_bindings;
|
let vars = &resp.0.variable_bindings;
|
||||||
for var in vars {
|
for var in vars {
|
||||||
let name = var.name.to_string();
|
let name = var.name.to_string();
|
||||||
if walk {
|
self.last_oid = name
|
||||||
if !name.starts_with(oid) {
|
.split('.')
|
||||||
completed = true;
|
.map(|x| x.parse::<u32>().unwrap())
|
||||||
last_oid = "";
|
.collect::<Vec<u32>>();
|
||||||
break;
|
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>(
|
//fn build_response<'a>(decoded: Message<Pdus>, oid: &str, walk: bool) -> (SnmpResult, bool) {
|
||||||
decoded: Message<Pdus>,
|
// let mut retval = SnmpResult{items: BTreeMap::new(), last_oid: Vec::new()};
|
||||||
oid: &str,
|
// let mut completed = false;
|
||||||
walk: bool,
|
// let mut last_oid: &str = "";
|
||||||
) -> (SnmpResult<'a>, bool) {
|
//
|
||||||
let mut retval = SnmpResult::new_simple();
|
// if let Pdus::Response(resp) = &decoded.data {
|
||||||
let mut completed = false;
|
// let vars = &resp.0.variable_bindings;
|
||||||
let mut last_oid: &str = "";
|
// for var in vars {
|
||||||
|
// let name = var.name.to_string();
|
||||||
if let Pdus::Response(resp) = &decoded.data {
|
// if walk {
|
||||||
let vars = &resp.0.variable_bindings;
|
// if !name.starts_with(oid) {
|
||||||
for var in vars {
|
// completed = true;
|
||||||
let name = var.name.to_string();
|
// last_oid = "";
|
||||||
if walk {
|
// break;
|
||||||
if !name.starts_with(oid) {
|
// }
|
||||||
completed = true;
|
// }
|
||||||
last_oid = "";
|
// let mut idx: i32 = -1;
|
||||||
break;
|
// retval.labels.iter().enumerate().for_each(|label| {
|
||||||
}
|
// if name.ends_with(label.1.label) {
|
||||||
}
|
// idx = label.0 as i32;
|
||||||
let mut idx: i32 = -1;
|
// return;
|
||||||
retval.labels.iter().enumerate().for_each(|label| {
|
// }
|
||||||
if name.ends_with(label.1.label) {
|
// });
|
||||||
idx = label.0 as i32;
|
// if idx == -1 {
|
||||||
return;
|
// continue;
|
||||||
}
|
// }
|
||||||
});
|
// match &var.value {
|
||||||
if idx == -1 {
|
// VarBindValue::Unspecified => {
|
||||||
continue;
|
// warn!("Unspecified");
|
||||||
}
|
// }
|
||||||
match &var.value {
|
// VarBindValue::NoSuchObject => {
|
||||||
VarBindValue::Unspecified => {
|
// warn!("NoSuchObject");
|
||||||
warn!("Unspecified");
|
// }
|
||||||
}
|
// VarBindValue::NoSuchInstance => {
|
||||||
VarBindValue::NoSuchObject => {
|
// warn!("NoSuchInstance");
|
||||||
warn!("NoSuchObject");
|
// }
|
||||||
}
|
// VarBindValue::EndOfMibView => {
|
||||||
VarBindValue::NoSuchInstance => {
|
// warn!("EndOfMibView");
|
||||||
warn!("NoSuchInstance");
|
// }
|
||||||
}
|
// VarBindValue::Value(value) => {
|
||||||
VarBindValue::EndOfMibView => {
|
// warn!("Value {:?}", &value);
|
||||||
warn!("EndOfMibView");
|
// match value {
|
||||||
}
|
// rasn_smi::v2::ObjectSyntax::Simple(value) => {
|
||||||
VarBindValue::Value(value) => {
|
// info!("Simple {:?}", value);
|
||||||
warn!("Value {:?}", &value);
|
// match value {
|
||||||
match value {
|
// rasn_smi::v2::SimpleSyntax::Integer(value) => {
|
||||||
rasn_smi::v2::ObjectSyntax::Simple(value) => {
|
// let v = value.try_into().unwrap();
|
||||||
info!("Simple {:?}", value);
|
// retval.add_variable(idx as usize, name, SnmpValue::Integer(v));
|
||||||
match value {
|
// last_oid = retval.get_last_oid(idx as usize);
|
||||||
rasn_smi::v2::SimpleSyntax::Integer(value) => {
|
// }
|
||||||
let v = value.try_into().unwrap();
|
// rasn_smi::v2::SimpleSyntax::String(value) => {
|
||||||
retval.add_variable(idx as usize, name, SnmpValue::Integer(v));
|
// // We transform the value into a rust String
|
||||||
last_oid = retval.get_last_oid(idx as usize);
|
// retval.add_variable(
|
||||||
}
|
// idx as usize,
|
||||||
rasn_smi::v2::SimpleSyntax::String(value) => {
|
// name,
|
||||||
// We transform the value into a rust String
|
// SnmpValue::String(
|
||||||
retval.add_variable(idx as usize,
|
// String::from_utf8(value.to_vec()).unwrap(),
|
||||||
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) => {
|
||||||
last_oid = retval.get_last_oid(idx as usize);
|
// let oid: String =
|
||||||
}
|
// value.iter().map(|&id| id.to_string() + ".").collect();
|
||||||
rasn_smi::v2::SimpleSyntax::ObjectId(value) => {
|
// retval.add_variable(idx as usize, name, SnmpValue::String(oid));
|
||||||
let oid: String =
|
// last_oid = retval.get_last_oid(idx as usize);
|
||||||
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,
|
||||||
retval
|
// SnmpValue::String("Other".to_string()),
|
||||||
.add_variable(idx as usize, name, SnmpValue::String("Other".to_string()));
|
// );
|
||||||
last_oid = retval.get_last_oid(idx as usize);
|
// last_oid = retval.get_last_oid(idx as usize);
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
rasn_smi::v2::ObjectSyntax::ApplicationWide(value) => {
|
// rasn_smi::v2::ObjectSyntax::ApplicationWide(value) => {
|
||||||
info!("Application {:?}", value);
|
// info!("Application {:?}", value);
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
(retval, completed)
|
// (retval, completed)
|
||||||
}
|
//}
|
||||||
//mod tests {
|
//mod tests {
|
||||||
// use super::*;
|
// use super::*;
|
||||||
//
|
//
|
||||||
@ -619,9 +696,9 @@ fn build_response<'a>(
|
|||||||
// fn test_snmp_get() {
|
// 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 result = r_snmp_get("127.0.0.1:161", "1.3.6.1.2.1.1.1.0", "public");
|
||||||
// let expected = SnmpResult {
|
// let expected = SnmpResult {
|
||||||
// variables: vec![SnmpVariable::new(
|
// variables: vec![SnmpVariable{
|
||||||
// "1.3.6.1.2.1.1.1.0".to_string(),
|
// "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);
|
// assert_eq!(result, expected);
|
||||||
// }
|
// }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user