5 Commits

Author SHA1 Message Date
Daniel Heule
dfa28457da multipath and bonding bugfixes 2026-01-12 08:39:52 +01:00
Daniel Heule
5aa718e50e Cargo version bump 2026-01-09 10:01:27 +01:00
Daniel Heule
9bd7685dc3 Bugfix for hash generation of non utf8 files 2026-01-09 09:54:52 +01:00
Daniel Heule
95b3076fe2 Informations for generating a rpm 2026-01-08 13:59:08 +01:00
Daniel Heule
c39d04d716 Informations for generating a rpm 2026-01-08 13:58:36 +01:00
7 changed files with 72 additions and 25 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "rsnmpagent" name = "rsnmpagent"
version = "0.4.1" version = "0.4.4"
edition = "2024" edition = "2024"
[profile.release] [profile.release]
@@ -20,3 +20,11 @@ hex = "0.4"
sha3 = "0.10" sha3 = "0.10"
diff = "0.1" diff = "0.1"
glob = "0.3" glob = "0.3"
[package.metadata.generate-rpm]
assets = [
{ source = "target/release/rsnmpagent", dest = "/usr/sbin/rsnmpagent", mode = "750" },
]
license = "GPL-3"
description = "rsnmpagent for extending snmpd"

View File

@@ -75,33 +75,43 @@ pub(crate) fn bonding_status(path: &str, re: Option<&regex::Regex>) -> io::Resul
} }
fn bond_status(d: &Path) -> io::Result<Vec<BondingInfo>> { fn bond_status(d: &Path) -> io::Result<Vec<BondingInfo>> {
trace!("now getting status of bonding {:?}",d);
let mut bl = Vec::new(); let mut bl = Vec::new();
let bond_info = BondingInfo { let bond_info = BondingInfo {
bond: d bond: d
.file_name() .file_name()
.unwrap_or(OsStr::new("unknown")) .unwrap_or(OsStr::new("unknown"))
.to_string_lossy() .to_string_lossy().to_string(),
.to_string(),
master_state: fs::read_to_string(d.join("bonding/mii_status"))?.trim().to_string(), master_state: fs::read_to_string(d.join("bonding/mii_status"))?.trim().to_string(),
slave: "".to_string(), slave: "".to_string(),
slave_state: "".to_string(), slave_state: "".to_string(),
mode: "".to_string(), mode: "".to_string(),
}; };
trace!("now try to read {:?}/bonding/mode",d);
let bond_info_mode = fs::read_to_string(d.join("bonding/mode"))?.trim().to_string();
let bond_info_mode: String = bond_info_mode.chars().take(bond_info_mode.chars().count().saturating_sub(2)).collect();
let slaves = fs::read_to_string(d.join("bonding/slaves"))?.trim().to_string(); let slaves = fs::read_to_string(d.join("bonding/slaves"))?.trim().to_string();
for slave in slaves.split(' ') { for slave in slaves.split(' ') {
trace!("try to read {:?}/lower_{}/bonding_slave/mii_status",d, slave);
let slave_state = fs::read_to_string(d.join(format!("lower_{}/bonding_slave/mii_status", slave)))? let slave_state = fs::read_to_string(d.join(format!("lower_{}/bonding_slave/mii_status", slave)))?
.trim() .trim()
.to_string(); .to_string();
trace!("try to read {:?}/lower_{}/speed",d, slave);
let slave_speed = fs::read_to_string(d.join(format!("lower_{}/speed", slave)))? let slave_speed = fs::read_to_string(d.join(format!("lower_{}/speed", slave)))?
.trim() .trim()
.to_string(); .to_string();
trace!("try to read {:?}/lower_{}/mtu",d, slave);
let slave_mtu = fs::read_to_string(d.join(format!("lower_{}/mtu", slave)))? let slave_mtu = fs::read_to_string(d.join(format!("lower_{}/mtu", slave)))?
.trim() .trim()
.to_string(); .to_string();
trace!("try to read {:?}/lower_{}/bonding_slave/state",d, slave);
let slave_statemode = fs::read_to_string(d.join(format!("lower_{}/bonding_slave/state", slave)))?
.trim()
.to_string();
let mut mpi = bond_info.clone(); let mut mpi = bond_info.clone();
mpi.slave = slave.to_string(); mpi.slave = slave.to_string();
mpi.slave_state = slave_state; mpi.slave_state = slave_state;
mpi.mode = format!("Speed: {}, MTU: {}", slave_speed, slave_mtu); mpi.mode = format!("Mode: {bond_info_mode}, State: {slave_statemode}, Speed: {slave_speed}, MTU: {slave_mtu}");
bl.push(mpi); bl.push(mpi);
} }
Ok(bl) Ok(bl)

View File

@@ -8,9 +8,9 @@ use std::path::Path;
pub(crate) fn filesum_filtered( pub(crate) fn filesum_filtered(
path: &Path, path: &Path,
oldfile: &mut String, oldfile: &mut Vec<u8>,
diff_string: &mut String, diff_string: &mut String,
re: Option<&regex::Regex>, re: Option<&regex::bytes::Regex>,
) -> io::Result<(bool, String)> { ) -> io::Result<(bool, String)> {
// Open file for hashing // Open file for hashing
match re { match re {
@@ -18,30 +18,37 @@ pub(crate) fn filesum_filtered(
None => trace!("try to open file {:?} for hashing", path), None => trace!("try to open file {:?} for hashing", path),
} }
let mut hasher = Sha3_256::new(); let mut hasher = Sha3_256::new();
let mut filedata = String::with_capacity(2048); let mut filedata = Vec::with_capacity(2048);
let mut changed = false; let mut changed = false;
// we read only smal files, so its fast to read the whole file to memory, so we can also du a diff // we read only smal files, so its fast to read the whole file to memory, so we can also du a diff
if let Ok(file_contents) = fs::read_to_string(path) { if let Ok(file_contents) = fs::read(path) {
if let Some(re) = re { if let Some(re) = re {
trace!("Filter lines with regex {:?}", re); trace!("Filter lines with regex {:?}", re);
for line in file_contents.lines() { for line in file_contents.split_inclusive(|&b| b == b'\n') {
if re.is_match(line) { if re.is_match(line) {
trace!("line {} skipped by filter regex", line); trace!("line {} skipped by filter regex", String::from_utf8_lossy(line).trim());
continue; continue;
} }
// Update the hasher with the bytes // Update the hasher with the bytes
filedata.push_str(line); filedata.extend_from_slice(line);
} }
} else { } else {
// we do not have a filter regex, so we could simply paste the file to the hasher // we do not have a filter regex, so we could simply paste the file to the hasher
trace!("Hash file without filter regex"); trace!("Hash file without filter regex");
filedata = file_contents; filedata = file_contents;
} }
hasher.update(format!("{}\n", filedata).as_bytes());
// Debug to find errors
//trace!("Hasher input data {:?}",String::from_utf8_lossy(&filedata));
// Update the hasher with the bytes
hasher.update(&filedata);
if !oldfile.is_empty() && *oldfile != filedata { if !oldfile.is_empty() && *oldfile != filedata {
diff_string.clear(); diff_string.clear();
for diff in diff::lines(oldfile, &filedata) { let ofs = String::from_utf8_lossy(oldfile);
let nfs = String::from_utf8_lossy(&filedata);
for diff in diff::lines(&ofs, &nfs) {
match diff { match diff {
Result::Left(l) => { Result::Left(l) => {
trace!("Diff - {}", l); // Removed line trace!("Diff - {}", l); // Removed line

View File

@@ -1,5 +1,6 @@
use log::{debug, error, info}; use log::{debug, error, info};
use regex::Regex; use regex::Regex;
use regex::bytes::Regex as BRegex;
pub(crate) fn compile_re(regex: Option<String>, name: &str) -> Option<Regex> { pub(crate) fn compile_re(regex: Option<String>, name: &str) -> Option<Regex> {
if let Some(r) = regex { if let Some(r) = regex {
@@ -19,3 +20,22 @@ pub(crate) fn compile_re(regex: Option<String>, name: &str) -> Option<Regex> {
None None
} }
} }
pub(crate) fn compile_re_bin(regex: Option<String>, name: &str) -> Option<BRegex> {
if let Some(r) = regex {
let re = BRegex::new(&r);
match re {
Ok(r) => {
debug!("Sucessfull compiled {} filter regex: {:?}", name, r);
Some(r)
}
Err(e) => {
error!("Error compiling {} filter regex: {:?}", name, e);
None
}
}
} else {
info!("No filter regex for {} supplied", name);
None
}
}

View File

@@ -19,7 +19,7 @@ pub mod snmp;
use bonding::bonding_status; use bonding::bonding_status;
use config::DataFunctionsFilesum; use config::DataFunctionsFilesum;
use filesum::filesum_filtered; use filesum::filesum_filtered;
use helper::compile_re; use helper::{compile_re, compile_re_bin};
use multipath::multipath_status; use multipath::multipath_status;
use processes::Ptypes; use processes::Ptypes;
use snmp::{Oid, OidData, SnmpData}; use snmp::{Oid, OidData, SnmpData};
@@ -189,10 +189,10 @@ fn t_filesum(
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
{ {
// allocate some strings for holding file contents between check runs // allocate some strings for holding file contents between check runs
let mut oldpasswd = String::with_capacity(2048); let mut oldpasswd = Vec::with_capacity(2048);
let mut oldshadow = String::with_capacity(2048); let mut oldshadow = Vec::with_capacity(2048);
let mut oldgroup = String::with_capacity(2048); let mut oldgroup = Vec::with_capacity(2048);
let mut oldauthkey = String::with_capacity(2048); let mut oldauthkey = Vec::with_capacity(2048);
let mut hash_passwd = String::with_capacity(128); let mut hash_passwd = String::with_capacity(128);
let mut diff_passwd = String::with_capacity(2048); let mut diff_passwd = String::with_capacity(2048);
let mut hash_shadow = String::with_capacity(128); let mut hash_shadow = String::with_capacity(128);
@@ -203,10 +203,10 @@ fn t_filesum(
let mut diff_authkey = String::with_capacity(2048); let mut diff_authkey = String::with_capacity(2048);
// allocate Option<Regex> for our regex ... // allocate Option<Regex> for our regex ...
let re_passwd = compile_re(options.passwd, "passwd"); let re_passwd = compile_re_bin(options.passwd, "passwd");
let re_shadow = compile_re(options.shadow, "shadow"); let re_shadow = compile_re_bin(options.shadow, "shadow");
let re_group = compile_re(options.group, "group"); let re_group = compile_re_bin(options.group, "group");
let re_authkey = compile_re(options.authorized_keys, "authorized_keys"); let re_authkey = compile_re_bin(options.authorized_keys, "authorized_keys");
// prepare variables which we use in the whole function // prepare variables which we use in the whole function
let oid_filesum_time = Oid::from_str("6.1.0").unwrap(); let oid_filesum_time = Oid::from_str("6.1.0").unwrap();

View File

@@ -95,6 +95,8 @@ fn mp_status(d: &Path) -> io::Result<MultipathInfo> {
}; };
if !mp_info.uuid.starts_with("mpath-") { if !mp_info.uuid.starts_with("mpath-") {
return Err(std::io::Error::other(format!("Wrong device uuid {}", mp_info.uuid))); return Err(std::io::Error::other(format!("Wrong device uuid {}", mp_info.uuid)));
} else {
mp_info.uuid = mp_info.uuid.strip_prefix("mpath-").unwrap().to_string();
} }
let slglob = format!("{}/slaves/*/device", d.to_string_lossy()); let slglob = format!("{}/slaves/*/device", d.to_string_lossy());
match glob(&slglob) { match glob(&slglob) {