Hi,
It is possible to develop a plugin for Microsens G7 please, G6 Plugin is not compatible and i have to monitor more than 450 devices of this kind.
Thanks.
Hi,
It is possible to develop a plugin for Microsens G7 please, G6 Plugin is not compatible and i have to monitor more than 450 devices of this kind.
Thanks.
Hi Guys,
Finally i develop my own script:
#!/usr/bin/env perl
use strict;
use warnings;
use Net::SNMP;
use Getopt::Long;
Getopt::Long::Configure("bundling");
# --- OIDs spécifiques Microsens G7 ---
my %OID = (
uptime => '1.3.6.1.4.1.3181.10.7.1.1.30.101.0',
# Temp sensors
temp_system => '1.3.6.1.4.1.3181.10.7.1.1.30.104.0',
temp_switch => '1.3.6.1.4.1.3181.10.7.1.1.30.105.0',
temp_1gphy => '1.3.6.1.4.1.3181.10.7.1.1.30.106.0',
temp_5gphy => '1.3.6.1.4.1.3181.10.7.1.1.30.107.0',
# Ports
port_status_table => '1.3.6.1.4.1.3181.10.7.1.1.81.102',
port_status_linkup => '1.3.6.1.4.1.3181.10.7.1.1.81.102.1.2',
port_status_linkstate => '1.3.6.1.4.1.3181.10.7.1.1.81.102.1.4',
port_status_speed => '1.3.6.1.4.1.3181.10.7.1.1.81.102.1.8',
port_up => '1.3.6.1.4.1.3181.10.7.1.1.81.102.1.2',
# PoE
poe_total => '1.3.6.1.4.1.3181.10.7.1.1.33.100.0',
poe_perport_power => '1.3.6.1.4.1.3181.10.7.1.1.33.101.1.6',
# G.8032 Ring status
g8032_ring_status => '1.3.6.1.4.1.3181.10.7.1.2.43.7.1.2',
firmware_version => '1.3.6.1.4.1.3181.10.7.1.1.30.109.1.0',
system_mem => '1.3.6.1.4.1.3181.10.7.1.1.30.108.0',
mac_address => '1.3.6.1.4.1.3181.10.7.1.1.30.102.0',
operating_temp => '1.3.6.1.4.1.3181.10.7.1.1.30.104.0',
system_util => '1.3.6.1.4.1.3181.10.7.1.1.30.4.0',
serial_number => '1.3.6.1.4.1.3181.10.7.1.1.32.2.0',
mac_address => '1.3.6.1.4.1.3181.10.7.1.1.30.102.0',
);
# --- CLI ---
my ($host,$community,$version,$port,$timeout,$mode,$warn,$crit,$help);
my ($username,$authproto,$authpass,$privproto,$privpass);
my $debug=0;
$community='public'; $version='2c'; $port=161; $timeout=5;
GetOptions(
"H|host=s" => \$host,
"C|community=s" => \$community,
"v|version=s" => \$version,
"p|port=i" => \$port,
"t|timeout=i" => \$timeout,
"m|mode=s" => \$mode,
"w|warning=s" => \$warn,
"c|critical=s" => \$crit,
"u|username=s" => \$username,
"authproto=s" => \$authproto,
"authpass=s" => \$authpass,
"privproto=s" => \$privproto,
"privpass=s" => \$privpass,
"debug!" => \$debug,
"h|help" => \$help,
) or usage();
usage() if $help || !$host || !$mode;
# --- SNMP Session ---
my ($session,$error);
if ($version =~ /^3$/i) {
my %params = (
-hostname => $host,
-version => '3',
-port => $port,
-timeout => $timeout,
-username => $username,
);
if ($authproto && $authpass) {
$params{-authprotocol} = uc($authproto);
$params{-authpassword} = $authpass;
}
if ($privproto && $privpass) {
$params{-privprotocol} = uc($privproto);
$params{-privpassword} = $privpass;
}
($session,$error) = Net::SNMP->session(%params);
} else {
($session,$error) = Net::SNMP->session(
-hostname => $host,
-community => $community,
-version => $version,
-port => $port,
-timeout => $timeout,
);
}
if (!defined $session) { print "UNKNOWN - SNMP session error: $error\n"; exit 3; }
# --- Mode dispatcher ---
if ($mode eq 'uptime') { check_uptime(); }
elsif ($mode eq 'temperature') { check_temperature(); }
elsif ($mode eq 'ports') { check_ports(); }
elsif ($mode eq 'poe') { check_poe(); }
elsif ($mode eq 'g8032') { check_g8032(); }
elsif ($mode eq 'firmware') { check_firmware(); }
elsif ($mode eq 'system') { check_system(); }
elsif ($mode eq 'info') { check_info(); }
else { print "UNKNOWN - Mode $mode not supported\n"; exit 3; }
$session->close();
exit 0;
# --- Usage ---
sub usage {
print <<"USAGE";
Usage: $0 -H <host> -m <mode> [options]
SNMPv2:
-C <community> -v 2c
SNMPv3:
-v 3 -u <user> --authproto <MD5|SHA> --authpass <authpass> [--privproto <DES|AES>] [--privpass <privpass>]
Modes:
uptime - uptime du switch
temperature - max des 4 capteurs (system/switch/1G/5G)
ports - état détaillé par port
poe - consommation PoE total + par port
g8032 - état du Ring 1 G.8032
firmware - version du firmware actuel
system - cpu, mem, temp, serial num, mac address
USAGE
exit 3;
}
my %port_state = (
0 => 'linkDown',
1 => 'blocking',
2 => 'learning',
3 => 'forwarding',
4 => 'unauthVlan',
);
# --- Checks ---
sub check_system {
my $resp = $session->get_request(
-varbindlist => [
$OID{operating_temp},
$OID{system_util},
$OID{serial_number},
$OID{mac_address},
]
);
unless (defined $resp) {
print "UNKNOWN - Erreur SNMP : " . $session->error() . "\n";
exit 3;
}
# Température
my $temp = $resp->{$OID{operating_temp}} // 0;
# Utilisation CPU/Mem
my $util_raw = $resp->{$OID{system_util}} // "";
my ($cpu, $mem);
if ($util_raw =~ /CPU:\s*([\d.]+)%.*, Mem:\s*([\d.]+)%/i) {
$cpu = $1;
$mem = $2;
} else {
$cpu = 0;
$mem = 0;
}
# Serial & MAC
my $serial = $resp->{$OID{serial_number}} // "N/A";
my $mac = $resp->{$OID{mac_address}} // "N/A";
# Statut
my $status = "OK";
my $exitcode = 0;
print "$status - CPU=${cpu}%, MEM=${mem}%, TEMP=${temp}°C, Serial=$serial, MAC=$mac ".
"| temp=$temp mem=$mem cpu=$cpu serial=\"$serial\" mac=\"$mac\"\n";
exit $exitcode;
}
sub check_uptime {
my $resp = $session->get_request($OID{uptime});
if (!defined $resp) {
print "UNKNOWN - ".$session->error()."\n";
exit 3;
}
my $val = $resp->{$OID{uptime}};
# Nettoyage des espaces
$val =~ s/^\s+|\s+$//g;
my $sec;
if ($val =~ /^\d+$/) {
# déjà en ticks bruts
$sec = int($val/100);
}
elsif ($val =~ /\((\d+)\)/) {
# format "Timeticks: (60080600) ..."
$sec = int($1/100);
}
elsif ($val =~ /(?:(\d+)\s+days?,\s*)?(\d+):(\d+):(\d+)/) {
# format "6 days, 22:56:30.00"
my ($d,$h,$m,$s) = ($1||0,$2,$3,$4);
$sec = $d*86400 + $h*3600 + $m*60 + $s;
}
else {
print "UNKNOWN - unexpected uptime format: '$val'\n";
exit 3;
}
my $days = int($sec/86400);
my $hours = int(($sec%86400)/3600);
my $mins = int(($sec%3600)/60);
print "OK - Uptime ${days}d ${hours}h ${mins}m | uptime=${sec}s\n";
exit 0;
}
sub check_temperature {
my $resp = $session->get_request(
-varbindlist => [$OID{temp_system},$OID{temp_switch},$OID{temp_1gphy},$OID{temp_5gphy}]
);
my @vals = map { int($resp->{$_}) } grep { defined $resp->{$_} } keys %$resp;
my $max = 0;
for my $val (@vals) {
$max = $val if $val > $max;
}
my ($code,$state) = (0,"OK");
if (defined $crit && $max >= $crit) { ($code,$state)=(2,"CRITICAL"); }
elsif (defined $warn && $max >= $warn) { ($code,$state)=(1,"WARNING"); }
print "$state - Max temperature ${max}C | temp=$max;$warn;$crit\n";
exit $code;
}
sub check_ports {
my $oid_state = $OID{port_status_linkstate};
my $oid_link = $OID{port_status_linkup};
my $port_count = 7;
my %port_state = (
0 => 'linkDown',
1 => 'blocking',
2 => 'learning',
3 => 'forwarding',
4 => 'unauthVlan',
);
# Récupération des deux tables
my $table_state = $session->get_table(-baseoid => $oid_state);
my $table_link = $session->get_table(-baseoid => $oid_link);
unless (defined $table_state && defined $table_link) {
print "UNKNOWN - Erreur SNMP : " . $session->error() . "\n";
exit 3;
}
# Debug
if ($debug) {
print "DEBUG - Port state table:\n";
foreach my $k (sort keys %$table_state) { print "$k => $table_state->{$k}\n"; }
print "DEBUG - Port linkUp table:\n";
foreach my $k (sort keys %$table_link) { print "$k => $table_link->{$k}\n"; }
}
my %port_status;
my @crit;
my @warn;
my @info;
my @ok;
foreach my $port (1..$port_count) {
my $s_oid = "$oid_state.$port";
my $l_oid = "$oid_link.$port";
my $status = $table_state->{$s_oid};
my $link_val = $table_link->{$l_oid};
my $state_label = defined $status ? $port_state{$status} // 'unknown' : 'unknown';
my $link_label = defined $link_val ? ($link_val==1 ? "up" : "down") : "unknown";
$port_status{$port} = "$state_label/$link_label";
if ($port == 5 || $port == 6) { # ports critiques
if (!defined $link_val || $link_val == 0) {
push @crit, "P$port=linkDown/$state_label";
}
else {
if ($status == 0 || $status == 1) { push @crit, "P$port=$state_label/$link_label"; }
elsif ($status == 2 || $status == 4) { push @warn, "P$port=$state_label/$link_label"; }
elsif ($status == 3) { push @ok, "P$port=$state_label/$link_label"; }
else { push @crit, "P$port=unknown"; }
}
}
else { # ports non critiques
push @info, "P$port=$state_label/$link_label";
}
}
# état global
my $code = 0;
my $state = "OK";
if (@crit) { $code=2; $state="CRITICAL"; }
elsif (@warn) { $code=1; $state="WARNING"; }
my $summary = sprintf(
"%d critiques, %d warnings, %d ok, %d info",
scalar(@crit), scalar(@warn), scalar(@ok), scalar(@info)
);
my @msg = (@crit, @warn, @ok, @info);
# sortie
print "$state - $summary : " . join(", ", @msg) . " | ";
foreach my $port (1..$port_count) {
my $val = $port_status{$port} // 'unknown';
my $code_val;
if ($val =~ /^linkDown/) { $code_val = 0; }
elsif ($val =~ /^blocking/) { $code_val = 1; }
elsif ($val =~ /^learning/) { $code_val = 2; }
elsif ($val =~ /^forwarding/) { $code_val = 3; }
elsif ($val =~ /^unauthVlan/) { $code_val = 4; }
else { $code_val = -1; }
print "port_${port}=$code_val ";
}
print "\n";
exit $code;
}
sub check_poe {
my $resp = $session->get_request($OID{poe_total});
my $total = $resp->{$OID{poe_total}};
my $table = $session->get_table($OID{poe_perport_power});
my $perf="total=$total "; my $out="Total=$total W; ";
for my $oid (keys %$table) {
if ($oid =~ /\.(\d+)$/) {
my $idx=$1; my $val=$table->{$oid};
$perf.="poe$idx=$val ";
$out.="P$idx=${val}W ";
}
}
my ($code,$state)=(0,"OK");
if (defined $crit && $total >= $crit) {($code,$state)=(2,"CRITICAL");}
elsif (defined $warn && $total >= $warn) {($code,$state)=(1,"WARNING");}
print "$state - $out | $perf\n";
exit $code;
}
sub check_firmware {
my $oid = $OID{firmware_version}; # à définir
my $resp = $session->get_request(-varbindlist => [$oid]);
if (!defined $resp || !exists $resp->{$oid}) {
print "UNKNOWN - SNMP error: " . $session->error() . "\n";
exit 3;
}
my $version = $resp->{$oid};
print "OK - Firmware version: $version | firmware=\"$version\"\n";
exit 0;
}
sub check_g8032 {
my $base = $OID{g8032_ring_status}; # colonne g8032
my $oid1 = $base . ".1"; # ring index 1
# 1) essai direct sur l'instance .1
my $resp = $session->get_request(-varbindlist => [$oid1]);
my $val;
if (defined $resp && exists $resp->{$oid1}) {
$val = $resp->{$oid1};
print "DEBUG: got $oid1 => '$val'\n" if $debug;
} else {
# 2) fallback : récupération de la table entière
my $table = $session->get_table(-baseoid => $base);
if (!defined $table) {
print "UNKNOWN - ".$session->error()."\n";
exit 3;
}
if ($debug) {
print "DEBUG - g8032 table contents:\n";
for my $k (sort keys %$table) { print " $k => ".$table->{$k}."\n"; }
}
# Prefer explicit .1 if present
my $candidate_oid = $base . ".1";
if (exists $table->{$candidate_oid}) {
$val = $table->{$candidate_oid};
} else {
# prendre le premier index dispo
my ($first_oid) = sort keys %$table;
$val = $table->{$first_oid};
print "DEBUG - using $first_oid => '$val'\n" if $debug;
}
}
# Normalisation / extraction numérique
$val = '' unless defined $val;
$val =~ s/^\s+|\s+$//g;
my $numeric;
if ($val =~ /^-?\d+$/) {
$numeric = int($val);
} elsif ($val =~ /(-?\d+)/) {
$numeric = int($1);
} else {
my $lc = lc($val);
if ($lc =~ /idle/) { $numeric = 3; }
elsif ($lc =~ /protect/) { $numeric = 2; }
elsif ($lc =~ /fail/) { $numeric = 5; }
elsif ($lc =~ /unknown/) { $numeric = 0; }
else {
print "UNKNOWN - unrecognized g8032 value: '$val'\n";
exit 3;
}
}
# --- Mapping corrigé ---
my ($code,$state,$label);
if (!defined $numeric || $numeric == 0) {
($code,$state,$label) = (3,"UNKNOWN","unknown");
}
elsif ($numeric == 1 || $numeric == 3) {
($code,$state,$label) = (0,"OK","ok");
}
elsif ($numeric == 2 || $numeric == 4) {
($code,$state,$label) = (1,"WARNING","warning");
}
elsif ($numeric == 5) {
($code,$state,$label) = (2,"CRITICAL","critical");
}
else {
($code,$state,$label) = (3,"UNKNOWN","value=$numeric");
}
print "DEBUG: raw='$val' numeric=$numeric -> mapping $state\n" if $debug;
print "$state - Ring1=$label | ring1=$numeric\n";
exit $code;
}
Last version,
The uptime management is optimized and add the option configuration to display (DNS, NTP, TACACS config with alerts in case of missing config):
#!/usr/bin/env perl
use strict;
use warnings;
use Net::SNMP;
use Getopt::Long;
Getopt::Long::Configure("bundling");
# --- OIDs Microsens G7 ---
my %OID = (
uptime => '1.3.6.1.4.1.3181.10.7.1.1.30.101.0',
# Temp sensors
temp_system => '1.3.6.1.4.1.3181.10.7.1.1.30.104.0',
# System
hostname => '1.3.6.1.4.1.3181.10.7.1.1.22.5.0',
serial => '1.3.6.1.4.1.3181.10.7.1.1.32.2.0',
mac => '1.3.6.1.4.1.3181.10.7.1.1.30.102.0',
cpu_mem => '1.3.6.1.4.1.3181.10.7.1.1.30.4.0',
# Ports
port_status_linkup => '1.3.6.1.4.1.3181.10.7.1.1.81.102.1.2',
port_status_linkstate => '1.3.6.1.4.1.3181.10.7.1.1.81.102.1.4',
# PoE
poe_total => '1.3.6.1.4.1.3181.10.7.1.1.33.100.0',
poe_perport_power => '1.3.6.1.4.1.3181.10.7.1.1.33.101.1.6',
# G.8032 Ring
g8032_ring_status => '1.3.6.1.4.1.3181.10.7.1.2.43.7.1.2',
# Firmware
firmware_version => '1.3.6.1.4.1.3181.10.7.1.1.30.109.1.0',
# Config
dns1 => '1.3.6.1.4.1.3181.10.7.1.1.22.100.5.0',
dns2 => '1.3.6.1.4.1.3181.10.7.1.1.22.100.6.0',
ntp_server => '1.3.6.1.4.1.3181.10.7.1.3.73.4.0',
ntp_server_backup => '1.3.6.1.4.1.3181.10.7.1.3.73.5.0',
access_auth_mode => '1.3.6.1.4.1.3181.10.7.1.3.76.1.1.0',
tacacs_primary => '1.3.6.1.4.1.3181.10.7.1.3.76.1.6.0',
tacacs_fallback => '1.3.6.1.4.1.3181.10.7.1.3.76.1.7.0',
);
# --- CLI ---
my ($host,$community,$version,$port,$timeout,$mode,$warn,$crit,$help);
my ($username,$authproto,$authpass,$privproto,$privpass);
my $debug=0;
$community='public'; $version='2c'; $port=161; $timeout=5;
GetOptions(
"H|host=s" => \$host,
"C|community=s" => \$community,
"v|version=s" => \$version,
"p|port=i" => \$port,
"t|timeout=i" => \$timeout,
"m|mode=s" => \$mode,
"w|warning=s" => \$warn,
"c|critical=s" => \$crit,
"u|username=s" => \$username,
"authproto=s" => \$authproto,
"authpass=s" => \$authpass,
"privproto=s" => \$privproto,
"privpass=s" => \$privpass,
"debug!" => \$debug,
"h|help" => \$help,
) or usage();
usage() if $help || !$host || !$mode;
# --- SNMP Session ---
my ($session,$error);
if ($version =~ /^3$/i) {
my %params = (
-hostname => $host,
-version => '3',
-port => $port,
-timeout => $timeout,
-username => $username,
);
if ($authproto && $authpass) {
$params{-authprotocol} = uc($authproto);
$params{-authpassword} = $authpass;
}
if ($privproto && $privpass) {
$params{-privprotocol} = uc($privproto);
$params{-privpassword} = $privpass;
}
($session,$error) = Net::SNMP->session(%params);
} else {
($session,$error) = Net::SNMP->session(
-hostname => $host,
-community => $community,
-version => $version,
-port => $port,
-timeout => $timeout,
);
}
if (!defined $session) {
print "CRITICAL - SNMP unreachable on $host ($error)\n";
exit 2;
}
# --- Mode dispatcher ---
if ($mode eq 'uptime') { check_uptime(); }
elsif ($mode eq 'temperature') { check_temperature(); }
elsif ($mode eq 'ports') { check_ports(); }
elsif ($mode eq 'poe') { check_poe(); }
elsif ($mode eq 'g8032') { check_g8032(); }
elsif ($mode eq 'firmware') { check_firmware(); }
elsif ($mode eq 'system') { check_system(); }
elsif ($mode eq 'config') { check_config(); }
else { print "UNKNOWN - Mode $mode not supported\n"; exit 3; }
$session->close();
exit 0;
# --- Usage ---
sub usage {
print <<"USAGE";
Usage: $0 -H <host> -m <mode> [options]
Modes:
uptime - uptime du switch
temperature - température système
ports - état des ports (linkstate + linkup)
poe - consommation PoE
g8032 - état du Ring 1 G.8032
firmware - version du firmware
system - hostname, serial, MAC, CPU/MEM/temp
config - config DNS/NTP/TACACS/auth
USAGE
exit 3;
}
# --- Checks ---
sub check_uptime {
my $resp = $session->get_request($OID{uptime});
if (!defined $resp) {
print "UNKNOWN - ".$session->error()."\n";
exit 3;
}
my $val = $resp->{$OID{uptime}};
$val =~ s/^\s+|\s+$//g;
my $sec;
if ($val =~ /^\d+$/) {
$sec = int($val/100);
}
elsif ($val =~ /\((\d+)\)/) {
$sec = int($1/100);
}
elsif ($val =~ /(?:(\d+)\s+days?,\s*)?(\d+):(\d+):(\d+)/) {
my ($d,$h,$m,$s) = ($1||0,$2,$3,$4);
$sec = $d*86400 + $h*3600 + $m*60 + $s;
}
elsif ($val =~ /(\d+)\s+minutes?,\s*(\d+)\.(\d+)/) {
my ($m,$s) = ($1,$2);
$sec = $m*60 + $s;
}
elsif ($val =~ /(\d+)\s+hours?,\s*(\d+):(\d+)\.(\d+)/) {
my ($h,$m,$s) = ($1,$2,$3);
$sec = $h*3600 + $m*60 + $s;
}
else {
print "UNKNOWN - unexpected uptime format: '$val'\n";
exit 3;
}
my $days = int($sec/86400);
my $hours = int(($sec%86400)/3600);
my $mins = int(($sec%3600)/60);
print "OK - Uptime ${days}d ${hours}h ${mins}m | uptime=${sec}s\n";
exit 0;
}
sub check_temperature {
my $resp = $session->get_request($OID{temp_system});
if (!defined $resp) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my $temp = int($resp->{$OID{temp_system}});
my ($code,$state)=(0,"OK");
if (defined $crit && $temp >= $crit) {($code,$state)=(2,"CRITICAL");}
elsif (defined $warn && $temp >= $warn) {($code,$state)=(1,"WARNING");}
print "$state - Température $temp C | temp=$temp;$warn;$crit\n";
exit $code;
}
sub check_ports {
my $base_up = $OID{port_status_linkup};
my $base_state = $OID{port_status_linkstate};
my $port_count = 7;
my $table = $session->get_table(-baseoid => $base_up);
if (!defined $table) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my %status;
foreach my $i (1..$port_count) {
my $up = $table->{"$base_up.$i"};
my $st = $table->{"$base_state.$i"} // "";
$status{$i} = ($up eq "1") ? "up/$st" : "down/$st";
}
print "OK - Ports status | ";
foreach my $i (1..$port_count) {
print "port_$i=\"$status{$i}\" ";
}
print "\n";
exit 0;
}
sub check_poe {
my $resp = $session->get_request($OID{poe_total});
if (!defined $resp) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my $total = $resp->{$OID{poe_total}};
my $table = $session->get_table($OID{poe_perport_power});
my $perf="total=$total "; my $out="Total=$total W; ";
for my $oid (keys %$table) {
if ($oid =~ /\.(\d+)$/) {
my $idx=$1; my $val=$table->{$oid};
$perf.="poe$idx=$val ";
$out.="P$idx=${val}W ";
}
}
my ($code,$state)=(0,"OK");
if (defined $crit && $total >= $crit) {($code,$state)=(2,"CRITICAL");}
elsif (defined $warn && $total >= $warn) {($code,$state)=(1,"WARNING");}
print "$state - $out | $perf\n";
exit $code;
}
sub check_firmware {
my $resp = $session->get_request($OID{firmware_version});
if (!defined $resp) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my $version = $resp->{$OID{firmware_version}};
print "OK - Firmware version: $version | firmware=\"$version\"\n";
exit 0;
}
sub check_system {
my $resp = $session->get_request(
-varbindlist => [$OID{hostname},$OID{serial},$OID{mac},$OID{cpu_mem},$OID{temp_system}]
);
unless (defined $resp) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my $host = $resp->{$OID{hostname}} // "";
my $serial = $resp->{$OID{serial}} // "";
my $mac = $resp->{$OID{mac}} // "";
my $util = $resp->{$OID{cpu_mem}} // "";
my $temp = $resp->{$OID{temp_system}} // "";
my ($cpu,$mem) = (0,0);
if ($util =~ /CPU:\s*(\d+)%.*, Mem:\s*([\d\.]+)%/) {
($cpu,$mem) = ($1,$2);
}
print "OK - Host=$host Serial=$serial MAC=$mac CPU=${cpu}% MEM=${mem}% TEMP=${temp}C ".
"| cpu=$cpu mem=$mem temp=$temp\n";
exit 0;
}
sub check_config {
my $resp = $session->get_request(
-varbindlist => [$OID{dns1},$OID{dns2},$OID{ntp_server},$OID{ntp_server_backup},
$OID{access_auth_mode},$OID{tacacs_primary},$OID{tacacs_fallback}]
);
unless (defined $resp) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my $dns1 = $resp->{$OID{dns1}} // "";
my $dns2 = $resp->{$OID{dns2}} // "";
my $ntp = $resp->{$OID{ntp_server}} // "";
my $ntp2 = $resp->{$OID{ntp_server_backup}} // "";
my $auth = $resp->{$OID{access_auth_mode}} // "";
my $tac1 = $resp->{$OID{tacacs_primary}} // "";
my $tac2 = $resp->{$OID{tacacs_fallback}} // "";
my %auth_map = (0=>"local",1=>"radius",2=>"tacacs+",3=>"ldap");
my $auth_text = exists $auth_map{$auth} ? $auth_map{$auth} : $auth;
my $code=0; my $state="OK"; my @issues;
if ($dns1 eq "" && $dns2 eq "") { ($code,$state)=(2,"CRITICAL"); push @issues,"aucun DNS"; }
elsif ($dns1 eq "" || $dns2 eq "") { ($code,$state)=(1,"WARNING") if $code<2; push @issues,"un seul DNS"; }
if ($ntp eq "" && $ntp2 eq "") { ($code,$state)=(1,"WARNING") if $code<2; push @issues,"aucun NTP"; }
if ($auth_text eq "tacacs+") {
if ($tac1 eq "" && $tac2 eq "") { ($code,$state)=(2,"CRITICAL"); push @issues,"aucun TACACS+"; }
elsif ($tac1 eq "" || $tac2 eq "") { ($code,$state)=(1,"WARNING") if $code<2; push @issues,"un seul TACACS+"; }
}
my $msg = @issues ? join(", ",@issues) : "Config OK";
print "$state - $msg | dns1=\"$dns1\" dns2=\"$dns2\" ntp=\"$ntp\" ntp_backup=\"$ntp2\" auth=\"$auth_text\" tacacs1=\"$tac1\" tacacs2=\"$tac2\"\n";
exit $code;
}
sub check_g8032 {
my $base = $OID{g8032_ring_status};
my $oid1 = $base.".1";
my $resp = $session->get_request(-varbindlist => [$oid1]);
my $val;
if (defined $resp && exists $resp->{$oid1}) { $val=$resp->{$oid1}; }
else {
my $table = $session->get_table(-baseoid => $base);
if (!defined $table) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my ($first_oid) = sort keys %$table;
$val = $table->{$first_oid};
}
my $numeric=int($val);
my ($code,$state,$label);
if ($numeric==1 || $numeric==3) { ($code,$state,$label)=(0,"OK","ok"); }
elsif ($numeric==2 || $numeric==4) { ($code,$state,$label)=(1,"WARNING","warning"); }
elsif ($numeric==5) { ($code,$state,$label)=(2,"CRITICAL","critical"); }
else { ($code,$state,$label)=(3,"UNKNOWN","value=$numeric"); }
print "$state - Ring1=$label | ring1=$numeric\n";
exit $code;
}
For exemple i use this commands below:
Uptime
/usr/lib/centreon/plugins//check_microsens_G7_v3.pl -H 192.168.60.50 -v3 -u 'snmp' --authproto MD5 --authpass '*********' -m uptime
ERP Ring 1 Status:
/usr/lib/centreon/plugins//check_microsens_G7_v3.pl -H 192.168.60.50 -v3 -u 'snmp' --authproto MD5 --authpass '*********' -m g8032
POE utilization per port:
/usr/lib/centreon/plugins//check_microsens_G7_v3.pl -H 192.168.60.50 -v3 -u 'snmp' --authproto MD5 --authpass '*********' -m poe
Firmware version:
/usr/lib/centreon/plugins//check_microsens_G7_v3.pl -H 192.168.60.50 -v3 -u 'snmp' --authproto MD5 --authpass '*********' -m firmware
Check CPU, Memory, temp + display mac address & serial:
/usr/lib/centreon/plugins//check_microsens_G7_v3.pl -H 192.168.60.50 -v3 -u 'snmp' --authproto MD5 --authpass '*********' -m system
Ports Status UP/Down (Critical ports 5 & 6 only)
/usr/lib/centreon/plugins//check_microsens_G7_v3.pl -H 192.168.60.50 -v3 -u 'snmp' --authproto MD5 --authpass '*********' -m ports
Check config (DNS, NTP, TACACS servers:
/usr/lib/centreon/plugins//check_microsens_G7_v3.pl -H 192.168.60.50 -v3 -u 'snmp' --authproto MD5 --authpass '*********' -m config
Final version of the script:
#!/usr/bin/env perl
use strict;
use warnings;
use Net::SNMP;
use Getopt::Long;
Getopt::Long::Configure("bundling");
# --- OIDs spécifiques Microsens G7 ---
my %OID = (
hostname => '1.3.6.1.4.1.3181.10.7.1.1.22.5.0',
uptime => '1.3.6.1.4.1.3181.10.7.1.1.30.101.0',
# Temp sensors
temp_system => '1.3.6.1.4.1.3181.10.7.1.1.30.104.0',
temp_switch => '1.3.6.1.4.1.3181.10.7.1.1.30.105.0',
temp_1gphy => '1.3.6.1.4.1.3181.10.7.1.1.30.106.0',
temp_5gphy => '1.3.6.1.4.1.3181.10.7.1.1.30.107.0',
# Ports
port_status_linkup => '1.3.6.1.4.1.3181.10.7.1.1.81.102.1.2',
port_status_linkstate => '1.3.6.1.4.1.3181.10.7.1.1.81.102.1.4',
# PoE
poe_total => '1.3.6.1.4.1.3181.10.7.1.1.33.100.0',
poe_perport_power => '1.3.6.1.4.1.3181.10.7.1.1.33.101.1.6',
# G.8032 Ring status
g8032_ring_status => '1.3.6.1.4.1.3181.10.7.1.2.43.7.1.2',
# Firmware / infos système
firmware_version => '1.3.6.1.4.1.3181.10.7.1.1.30.109.1.0',
serial_number => '1.3.6.1.4.1.3181.10.7.1.1.32.2.0',
mac_address => '1.3.6.1.4.1.3181.10.7.1.1.30.102.0',
cpu_usage => '1.3.6.1.4.1.3181.10.7.1.1.30.4.0',
mem_usage => '1.3.6.1.4.1.3181.10.7.1.1.30.108.0',
dns1 => '1.3.6.1.4.1.3181.10.7.1.1.22.100.5.0',
dns2 => '1.3.6.1.4.1.3181.10.7.1.1.22.100.6.0',
ntp1 => '1.3.6.1.4.1.3181.10.7.1.3.73.4.0',
ntp2 => '1.3.6.1.4.1.3181.10.7.1.3.73.5.0',
tacacs1 => '1.3.6.1.4.1.3181.10.7.1.3.76.1.6.0',
tacacs2 => '1.3.6.1.4.1.3181.10.7.1.3.76.1.7.0',
auth_mode => '1.3.6.1.4.1.3181.10.7.1.3.76.1.1.0',
);
# Mapping linkstate
my %port_state = (
0 => 'linkDown',
1 => 'blocking',
2 => 'learning',
3 => 'forwarding',
4 => 'unauthVlan',
);
# --- CLI ---
my ($host,$community,$version,$port,$timeout,$mode,$warn,$crit,$help);
my ($username,$authproto,$authpass,$privproto,$privpass);
my $debug=0;
$community='public'; $version='2c'; $port=161; $timeout=5;
GetOptions(
"H|host=s" => \$host,
"C|community=s" => \$community,
"v|version=s" => \$version,
"p|port=i" => \$port,
"t|timeout=i" => \$timeout,
"m|mode=s" => \$mode,
"w|warning=s" => \$warn,
"c|critical=s" => \$crit,
"u|username=s" => \$username,
"authproto=s" => \$authproto,
"authpass=s" => \$authpass,
"privproto=s" => \$privproto,
"privpass=s" => \$privpass,
"debug!" => \$debug,
"h|help" => \$help,
) or usage();
usage() if $help || !$host || !$mode;
# --- SNMP Session ---
my ($session,$error);
if ($version =~ /^3$/i) {
my %params = (
-hostname => $host,
-version => '3',
-port => $port,
-timeout => $timeout,
-username => $username,
);
if ($authproto && $authpass) {
$params{-authprotocol} = uc($authproto);
$params{-authpassword} = $authpass;
}
if ($privproto && $privpass) {
$params{-privprotocol} = uc($privproto);
$params{-privpassword} = $privpass;
}
($session,$error) = Net::SNMP->session(%params);
} else {
($session,$error) = Net::SNMP->session(
-hostname => $host,
-community => $community,
-version => $version,
-port => $port,
-timeout => $timeout,
);
}
if (!defined $session) { print "UNKNOWN - SNMP session error: $error\n"; exit 3; }
# --- Dispatcher ---
if ($mode eq 'ports') { check_ports(); }
elsif ($mode eq 'uptime') { check_uptime(); }
elsif ($mode eq 'temperature') { check_temperature(); }
elsif ($mode eq 'poe') { check_poe(); }
elsif ($mode eq 'g8032') { check_g8032(); }
elsif ($mode eq 'firmware') { check_firmware(); }
elsif ($mode eq 'system') { check_system(); }
elsif ($mode eq 'config') { check_config(); }
else { print "UNKNOWN - Mode $mode not supported\n"; exit 3; }
$session->close();
exit 0;
# --- Usage ---
sub usage {
print <<"USAGE";
Usage: $0 -H <host> -m <mode> [options]
Modes: uptime | temperature | ports | poe | g8032 | firmware | system
USAGE
exit 3;
}
# --- Checks ---
sub check_ports {
my $port_count = 7;
my $table = $session->get_table(-baseoid => $OID{port_status_linkstate});
my $table2 = $session->get_table(-baseoid => $OID{port_status_linkup});
unless (defined $table && defined $table2) {
print "UNKNOWN - Erreur SNMP : " . $session->error() . "\n";
exit 3;
}
my %port_status;
foreach my $port (1..$port_count) {
my $oid_linkup = "$OID{port_status_linkup}.$port";
my $oid_linkstat = "$OID{port_status_linkstate}.$port";
my $linkup_val = $table2->{$oid_linkup};
my $linkstate_val = $table->{$oid_linkstat};
my $linkup = defined $linkup_val ? ($linkup_val == 1 ? "up" : "down") : "unknown";
my $linkstate = defined $linkstate_val ? ($port_state{$linkstate_val} // "unknown") : "unknown";
$port_status{$port} = "$linkup/$linkstate";
}
print "OK - Statut des ports | ";
foreach my $port (1..$port_count) {
print "port_${port}=\"$port_status{$port}\" ";
}
print "\n";
exit 0;
}
sub check_uptime {
my $resp = $session->get_request($OID{uptime});
if (!defined $resp) {
print "UNKNOWN - ".$session->error()."\n";
exit 3;
}
my $val = $resp->{$OID{uptime}};
$val =~ s/^\s+|\s+$//g;
my $sec;
if ($val =~ /^\d+$/) {
$sec = int($val/100);
}
elsif ($val =~ /\((\d+)\)/) {
$sec = int($1/100);
}
elsif ($val =~ /(?:(\d+)\s+days?,\s*)?(\d+):(\d+):(\d+)/) {
my ($d,$h,$m,$s) = ($1||0,$2,$3,$4);
$sec = $d*86400 + $h*3600 + $m*60 + $s;
}
elsif ($val =~ /(\d+)\s+minutes?,\s*(\d+)\.(\d+)/) {
my ($m,$s) = ($1,$2);
$sec = $m*60 + $s;
}
elsif ($val =~ /(\d+)\s+hours?,\s*(\d+):(\d+)\.(\d+)/) {
my ($h,$m,$s) = ($1,$2,$3);
$sec = $h*3600 + $m*60 + $s;
}
else {
print "UNKNOWN - unexpected uptime format: '$val'\n";
exit 3;
}
my $days = int($sec/86400);
my $hours = int(($sec%86400)/3600);
my $mins = int(($sec%3600)/60);
print "OK - Uptime ${days}d ${hours}h ${mins}m | uptime=${sec}s\n";
exit 0;
}
sub check_temperature {
my $resp = $session->get_request($OID{temp_system});
if (!defined $resp) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my $temp = int($resp->{$OID{temp_system}});
my ($code,$state)=(0,"OK");
if (defined $crit && $temp >= $crit) {($code,$state)=(2,"CRITICAL");}
elsif (defined $warn && $temp >= $warn) {($code,$state)=(1,"WARNING");}
print "$state - Température $temp C | temp=$temp;$warn;$crit\n";
exit $code;
}
sub check_poe {
my $resp = $session->get_request($OID{poe_total});
if (!defined $resp) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my $total = $resp->{$OID{poe_total}};
my $table = $session->get_table($OID{poe_perport_power});
my $perf="total=$total "; my $out="Total=$total W; ";
for my $oid (keys %$table) {
if ($oid =~ /\.(\d+)$/) {
my $idx=$1; my $val=$table->{$oid};
$perf.="poe$idx=$val ";
$out.="P$idx=${val}W ";
}
}
my ($code,$state)=(0,"OK");
if (defined $crit && $total >= $crit) {($code,$state)=(2,"CRITICAL");}
elsif (defined $warn && $total >= $warn) {($code,$state)=(1,"WARNING");}
print "$state - $out | $perf\n";
exit $code;
}
sub check_firmware {
my $resp = $session->get_request($OID{firmware_version});
if (!defined $resp) { print "UNKNOWN - ".$session->error()."\n"; exit 3; }
my $version = $resp->{$OID{firmware_version}};
print "OK - Firmware version: $version | firmware=\"$version\"\n";
exit 0;
}
sub check_config {
my @wanted = qw(dns1 dns2 ntp1 ntp2 tacacs1 tacacs2 auth_mode);
my @oids;
my %key_by_oid;
for my $k (@wanted) {
next unless defined $OID{$k} && $OID{$k} ne '';
push @oids, $OID{$k};
$key_by_oid{$OID{$k}} = $k;
}
unless (@oids) {
print "UNKNOWN - aucun OID configuré pour check_config\n";
exit 3;
}
my $resp = $session->get_request(-varbindlist => \@oids);
unless (defined $resp) {
print "UNKNOWN - ".$session->error()."\n";
exit 3;
}
my %res;
for my $oid (@oids) {
my $k = $key_by_oid{$oid};
$res{$k} = $resp->{$oid} // '';
}
# --- logique de vérification ---
my ($code,$state,$msg) = (0,"OK","Config correcte");
# DNS
my $dns_missing = 0;
$dns_missing++ unless $res{dns1};
$dns_missing++ unless $res{dns2};
if ($dns_missing == 1) { ($code,$state,$msg) = (1,"WARNING","Un seul DNS configuré"); }
elsif ($dns_missing == 2) { ($code,$state,$msg) = (2,"CRITICAL","Aucun DNS configuré"); }
# NTP
unless ($res{ntp1} || $res{ntp2}) {
($code,$state,$msg) = (1,"WARNING","Aucun serveur NTP configuré") if $code < 1;
}
# TACACS
my $tacacs_missing = 0;
$tacacs_missing++ unless $res{tacacs1};
$tacacs_missing++ unless $res{tacacs2};
if ($tacacs_missing == 2) { ($code,$state,$msg) = (2,"CRITICAL","Aucun serveur TACACS configuré"); }
elsif ($tacacs_missing == 1 && $code < 2) { ($code,$state,$msg) = (1,"WARNING","Un seul serveur TACACS configuré"); }
print "$state - $msg | dns1=\"$res{dns1}\" dns2=\"$res{dns2}\" ntp1=\"$res{ntp1}\" ntp2=\"$res{ntp2}\" tacacs1=\"$res{tacacs1}\" tacacs2=\"$res{tacacs2}\" auth_mode=\"$res{auth_mode}\"\n";
exit $code;
}
sub check_system {
my $resp = $session->get_request(
-varbindlist => [
$OID{hostname},
$OID{serial_number},
$OID{mac_address},
$OID{cpu_usage},
$OID{mem_usage},
$OID{temp_system}
]
);
unless (defined $resp) {
print "UNKNOWN - ".$session->error()."\n";
exit 3;
}
my $host = $resp->{$OID{hostname}} // "";
my $serial = $resp->{$OID{serial_number}} // "";
my $mac = $resp->{$OID{mac_address}} // "";
my $cpu = $resp->{$OID{cpu_usage}} // 0;
my $mem = $resp->{$OID{mem_usage}} // 0;
my $temp = $resp->{$OID{temp_system}} // 0;
print "OK - Host=$host Serial=$serial MAC=$mac CPU=${cpu}% MEM=${mem}% TEMP=${temp}C ".
"| cpu=$cpu mem=$mem temp=$temp\n";
exit 0;
}
sub check_g8032 {
my $base = $OID{g8032_ring_status};
my $oid1 = $base.".1";
my $resp = $session->get_request(-varbindlist => [$oid1]);
my $val;
if (defined $resp && exists $resp->{$oid1}) {
$val = $resp->{$oid1};
} else {
my $table = $session->get_table(-baseoid => $base);
if (!defined $table) {
print "UNKNOWN - ".$session->error()."\n";
exit 3;
}
my ($first_oid) = sort keys %$table;
$val = $table->{$first_oid};
}
my $numeric = int($val);
my ($code,$state,$label);
if ($numeric == 1 || $numeric == 3) {
($code,$state,$label) = (0,"OK","ok");
}
elsif ($numeric == 2 || $numeric == 4) {
($code,$state,$label) = (1,"WARNING","warning");
}
elsif ($numeric == 5) {
($code,$state,$label) = (2,"CRITICAL","critical");
}
else {
($code,$state,$label) = (3,"UNKNOWN","value=$numeric");
}
print "$state - Ring1=$label | ring1=$numeric\n";
exit $code;
}
Hello :)
Thank you for sharing this solution with us. Do you think you could make a PR on GitHub (it would be more suitable for sharing large segments of code)?
Kind regards.
Hi,
PR sent :)
BR
No account yet? Create an account
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.