1
0
mirror of https://github.com/opinkerfi/nagios-plugins.git synced 2024-11-13 22:13:44 +01:00
nagios-plugins/check_hpasm/check_hpasm
2012-03-12 16:03:21 +00:00

8391 lines
262 KiB
Perl
Executable File
Raw Blame History

#! /usr/bin/perl -w
package Nagios::MiniPlugin;
use strict;
use Getopt::Long qw(:config no_ignore_case bundling);
our @STATUS_CODES = qw(OK WARNING CRITICAL UNKNOWN DEPENDENT);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = (@STATUS_CODES, qw(nagios_exit nagios_die check_messages));
our @EXPORT_OK = qw(%ERRORS);
use constant OK => 0;
use constant WARNING => 1;
use constant CRITICAL => 2;
use constant UNKNOWN => 3;
use constant DEPENDENT => 4;
our %ERRORS = (
'OK' => OK,
'WARNING' => WARNING,
'CRITICAL' => CRITICAL,
'UNKNOWN' => UNKNOWN,
'DEPENDENT' => DEPENDENT,
);
our %STATUS_TEXT = reverse %ERRORS;
sub new {
my $class = shift;
my %params = @_;
my $self = {
perfdata => [],
messages => {
ok => [],
warning => [],
critical => [],
unknown => [],
},
args => [],
opts => Nagios::MiniPlugin::Getopt->new(%params),
};
foreach (qw(shortname usage version url plugin blurb extra
license timeout)) {
$self->{$_} = $params{$_};
}
bless $self, $class;
}
sub add_arg {
my $self = shift;
$self->{opts}->add_arg(@_);
}
sub getopts {
my $self = shift;
$self->{opts}->getopts();
}
sub opts {
my $self = shift;
return $self->{opts};
}
sub add_message {
my $self = shift;
my ($code, @messages) = @_;
$code = (qw(ok warning critical unknown))[$code] if $code =~ /^\d+$/;
$code = lc $code;
push @{$self->{messages}->{$code}}, @messages;
}
sub add_perfdata {
my ($self, %args) = @_;
my $str = $args{label}.'='.$args{value};
if ($args{uom}) {
$str .= $args{uom};
}
if ($args{warning}) {
$str .= ';'.$args{warning};
}
if ($args{critical}) {
$str .= ';'.$args{critical};
}
push @{$self->{perfdata}}, $str;
}
sub check_messages {
my $self = shift;
my %args = @_;
# Add object messages to any passed in as args
for my $code (qw(critical warning unknown ok)) {
my $messages = $self->{messages}->{$code} || [];
if ($args{$code}) {
unless (ref $args{$code} eq 'ARRAY') {
if ($code eq 'ok') {
$args{$code} = [ $args{$code} ];
}
}
push @{$args{$code}}, @$messages;
} else {
$args{$code} = $messages;
}
}
my %arg = %args;
$arg{join} = ' ' unless defined $arg{join};
# Decide $code
my $code = OK;
$code ||= CRITICAL if @{$arg{critical}};
$code ||= WARNING if @{$arg{warning}};
$code ||= UNKNOWN if @{$arg{unknown}};
return $code unless wantarray;
# Compose message
my $message = '';
if ($arg{join_all}) {
$message = join( $arg{join_all},
map { @$_ ? join( $arg{'join'}, @$_) : () }
$arg{critical},
$arg{warning},
$arg{unknown},
$arg{ok} ? (ref $arg{ok} ? $arg{ok} : [ $arg{ok} ]) : []
);
}
else {
$message ||= join( $arg{'join'}, @{$arg{critical}} )
if $code == CRITICAL;
$message ||= join( $arg{'join'}, @{$arg{warning}} )
if $code == WARNING;
$message ||= join( $arg{'join'}, @{$arg{unknown}} )
if $code == UNKNOWN;
$message ||= ref $arg{ok} ? join( $arg{'join'}, @{$arg{ok}} ) : $arg{ok}
if $arg{ok};
}
return ($code, $message);
}
sub nagios_exit {
my $self = shift;
my ($code, $message, $arg) = @_;
$code = $ERRORS{$code} if defined $code && exists $ERRORS{$code};
$code = UNKNOWN unless defined $code && exists $STATUS_TEXT{$code};
$message = '' unless defined $message;
if (ref $message && ref $message eq 'ARRAY') {
$message = join(' ', map { chomp; $_ } @$message);
} else {
chomp $message;
}
my $output = "$STATUS_TEXT{$code}";
$output .= " - $message" if defined $message && $message ne '';
if (scalar (@{$self->{perfdata}})) {
$output .= " | ".join(" ", @{$self->{perfdata}});
}
$output .= "\n";
print $output;
exit $code;
}
package Nagios::MiniPlugin::Getopt;
use strict;
use File::Basename;
use Data::Dumper;
use Getopt::Long qw(:config no_ignore_case bundling);
# Standard defaults
my %DEFAULT = (
timeout => 15,
verbose => 0,
license =>
"This nagios plugin is free software, and comes with ABSOLUTELY NO WARRANTY.
It may be used, redistributed and/or modified under the terms of the GNU
General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).",
);
# Standard arguments
my @ARGS = ({
spec => 'usage|?',
help => "-?, --usage\n Print usage information",
}, {
spec => 'help|h',
help => "-h, --help\n Print detailed help screen",
}, {
spec => 'version|V',
help => "-V, --version\n Print version information",
}, {
#spec => 'extra-opts:s@',
#help => "--extra-opts=[<section>[@<config_file>]]\n Section and/or config_file from which to load extra options (may repeat)",
}, {
spec => 'timeout|t=i',
help => "-t, --timeout=INTEGER\n Seconds before plugin times out (default: %s)",
default => $DEFAULT{timeout},
}, {
spec => 'verbose|v+',
help => "-v, --verbose\n Show details for command-line debugging (can repeat up to 3 times)",
default => $DEFAULT{verbose},
},
);
# Standard arguments we traditionally display last in the help output
my %DEFER_ARGS = map { $_ => 1 } qw(timeout verbose);
sub _init
{
my $self = shift;
my %params = @_;
# Check params
my $plugin = basename($ENV{NAGIOS_PLUGIN} || $0);
#my %attr = validate( @_, {
my %attr = (
usage => 1,
version => 0,
url => 0,
plugin => { default => $plugin },
blurb => 0,
extra => 0,
'extra-opts' => 0,
license => { default => $DEFAULT{license} },
timeout => { default => $DEFAULT{timeout} },
);
# Add attr to private _attr hash (except timeout)
$self->{timeout} = delete $attr{timeout};
$self->{_attr} = { %attr };
foreach (keys %{$self->{_attr}}) {
if (exists $params{$_}) {
$self->{_attr}->{$_} = $params{$_};
} else {
$self->{_attr}->{$_} = $self->{_attr}->{$_}->{default}
if ref ($self->{_attr}->{$_}) eq 'HASH' &&
exists $self->{_attr}->{$_}->{default};
}
}
# Chomp _attr values
chomp foreach values %{$self->{_attr}};
# Setup initial args list
$self->{_args} = [ grep { exists $_->{spec} } @ARGS ];
$self
}
sub new
{
my $class = shift;
my $self = bless {}, $class;
$self->_init(@_);
}
sub add_arg {
my $self = shift;
my %arg = @_;
push (@{$self->{_args}}, \%arg);
}
sub getopts {
my $self = shift;
my %commandline = ();
my @params = map { $_->{spec} } @{$self->{_args}};
if (! GetOptions(\%commandline, @params)) {
$self->print_help();
exit 0;
} else {
no strict 'refs';
do { $self->print_help(); exit 0; } if $commandline{help};
do { $self->print_version(); exit 0 } if $commandline{version};
do { $self->print_usage(); exit 0 } if $commandline{usage};
foreach (map { $_->{spec} =~ /^([\w\-]+)/; $1; } @{$self->{_args}}) {
my $field = $_;
*{"$field"} = sub {
return $self->{opts}->{$field};
};
}
foreach (grep { exists $_->{default} } @{$self->{_args}}) {
$_->{spec} =~ /^([\w\-]+)/;
my $spec = $1;
$self->{opts}->{$spec} = $_->{default};
}
foreach (keys %commandline) {
$self->{opts}->{$_} = $commandline{$_};
}
}
}
sub get {
my $self = shift;
my $opt = shift;
return $self->{opts}->{$opt};
}
sub print_help {
my $self = shift;
$self->print_version();
printf "\n%s\n", $self->{_attr}->{license};
printf "\n%s\n\n", $self->{_attr}->{blurb};
$self->print_usage();
foreach (@{$self->{_args}}) {
printf " %s\n", $_->{help};
}
exit 0;
}
sub print_usage {
my $self = shift;
printf $self->{_attr}->{usage}, $self->{_attr}->{plugin};
print "\n";
}
sub print_version {
my $self = shift;
printf "%s %s", $self->{_attr}->{plugin}, $self->{_attr}->{version};
printf " [%s]", $self->{_attr}->{url} if $self->{_attr}->{url};
print "\n";
}
sub print_license {
my $self = shift;
printf "%s\n", $self->{_attr}->{license};
print "\n";
}
package SNMP::Utils;
use strict;
{
sub get_indices {
my $oids = shift;
my $entry = shift;
my $numindices = shift;
# find all oids beginning with $entry
# then skip one field for the sequence
# then read the next numindices fields
my $entrypat = $entry;
$entrypat =~ s/\./\\\./g;
my @indices = map {
/^$entrypat\.\d+\.(.*)/ && $1;
} grep {
/^$entrypat/
} keys %{$oids};
my %seen = ();
my @o = map {[split /\./]} sort grep !$seen{$_}++, @indices;
return @o;
}
sub get_size {
my $oids = shift;
my $entry = shift;
my $entrypat = $entry;
$entrypat =~ s/\./\\\./g;
my @entries = grep {
/^$entrypat/
} keys %{$oids};
return scalar(@entries);
}
sub get_object {
my $oids = shift;
my $object = shift;
my @indices = @_;
#my $oid = $object.'.'.join('.', @indices);
my $oid = $object;
$oid .= '.'.join('.', @indices) if (@indices);
return $oids->{$oid};
}
sub get_object_value {
my $oids = shift;
my $object = shift;
my $values = shift;
my @indices = @_;
my $key = get_object($oids, $object, @indices);
if (defined $key) {
return $values->{$key};
} else {
return undef;
}
}
#SNMP::Utils::counter([$idxs1, $idxs2], $idx1, $idx2),
# this flattens a n-dimensional array and returns the absolute position
# of the element at position idx1,idx2,...,idxn
# element 1,2 in table 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2 is at pos 6
sub get_number {
my $indexlists = shift; #, zeiger auf array aus [1, 2]
my @element = @_;
my $dimensions = scalar(@{$indexlists->[0]});
my @sorted = ();
my $number = 0;
if ($dimensions == 1) {
@sorted =
sort { $a->[0] <=> $b->[0] } @{$indexlists};
} elsif ($dimensions == 2) {
@sorted =
sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @{$indexlists};
} elsif ($dimensions == 3) {
@sorted =
sort { $a->[0] <=> $b->[0] ||
$a->[1] <=> $b->[1] ||
$a->[2] <=> $b->[2] } @{$indexlists};
}
foreach (@sorted) {
if ($dimensions == 1) {
if ($_->[0] == $element[0]) {
last;
}
} elsif ($dimensions == 2) {
if ($_->[0] == $element[0] && $_->[1] == $element[1]) {
last;
}
} elsif ($dimensions == 3) {
if ($_->[0] == $element[0] &&
$_->[1] == $element[1] &&
$_->[2] == $element[2]) {
last;
}
}
$number++;
}
return ++$number;
}
}
package HP::Proliant::Component::PowersupplySubsystem;
our @ISA = qw(HP::Proliant::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
condition => $params{condition},
status => $params{status},
powersupplies => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
return HP::Proliant::Component::PowersupplySubsystem::SNMP->new(%params);
} elsif ($self->{method} eq 'cli') {
return HP::Proliant::Component::PowersupplySubsystem::CLI->new(%params);
} else {
die "unknown method";
}
return $self;
}
sub check {
my $self = shift;
my $errorfound = 0;
$self->add_info('checking power supplies');
if (scalar (@{$self->{powersupplies}}) == 0) {
#$self->overall_check();
} else {
foreach (@{$self->{powersupplies}}) {
$_->check();
}
}
}
sub dump {
my $self = shift;
foreach (@{$self->{powersupplies}}) {
$_->dump();
}
}
package HP::Proliant::Component::PowersupplySubsystem::Powersupply;
our @ISA = qw(HP::Proliant::Component::PowersupplySubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqHeFltTolPowerSupplyChassis => $params{cpqHeFltTolPowerSupplyChassis},
cpqHeFltTolPowerSupplyBay => $params{cpqHeFltTolPowerSupplyBay},
cpqHeFltTolPowerSupplyPresent => $params{cpqHeFltTolPowerSupplyPresent},
cpqHeFltTolPowerSupplyCondition => $params{cpqHeFltTolPowerSupplyCondition},
cpqHeFltTolPowerSupplyRedundant => $params{cpqHeFltTolPowerSupplyRedundant},
blacklisted => 0,
info => undef,
extendexinfo => undef,
};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('p', $self->{cpqHeFltTolPowerSupplyBay});
if ($self->{cpqHeFltTolPowerSupplyPresent} eq "present") {
if ($self->{cpqHeFltTolPowerSupplyCondition} ne "ok") {
if ($self->{cpqHeFltTolPowerSupplyCondition} eq "other") {
$self->add_info(sprintf "powersupply %d is missing",
$self->{cpqHeFltTolPowerSupplyBay});
} else {
$self->add_info(sprintf "powersupply %d needs attention (%s)",
$self->{cpqHeFltTolPowerSupplyBay},
$self->{cpqHeFltTolPowerSupplyCondition});
}
$self->add_message(CRITICAL, $self->{info});
} else {
$self->add_info(sprintf "powersupply %d is %s",
$self->{cpqHeFltTolPowerSupplyBay},
$self->{cpqHeFltTolPowerSupplyCondition});
}
$self->add_extendedinfo(sprintf "ps_%s=%s",
$self->{cpqHeFltTolPowerSupplyBay},
$self->{cpqHeFltTolPowerSupplyCondition});
} else {
$self->add_info(sprintf "powersupply %d is %s",
$self->{cpqHeFltTolPowerSupplyBay},
$self->{cpqHeFltTolPowerSupplyPresent});
$self->add_extendedinfo(sprintf "ps_%s=%s",
$self->{cpqHeFltTolPowerSupplyBay},
$self->{cpqHeFltTolPowerSupplyPresent});
}
}
sub dump {
my $self = shift;
printf "[PS_%s]\n", $self->{cpqHeFltTolPowerSupplyBay};
foreach (qw(cpqHeFltTolPowerSupplyBay cpqHeFltTolPowerSupplyChassis
cpqHeFltTolPowerSupplyPresent cpqHeFltTolPowerSupplyCondition
cpqHeFltTolPowerSupplyRedundant)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "info: %s\n\n", $self->{info};
}
package HP::Proliant::Component::PowersupplySubsystem::CLI;
our @ISA = qw(HP::Proliant::Component::PowersupplySubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
powersupplies => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init(%params);
return $self;
}
sub init {
my $self = shift;
my %params = @_;
my %tmpps = (
runtime => $self->{runtime},
cpqHeFltTolPowerSupplyChassis => 1,
);
my $inblock = 0;
foreach (grep(/^powersupply/, split(/\n/, $self->{rawdata}))) {
s/^powersupply\s*//g;
if (/^Power supply #(\d+)/) {
if ($inblock) {
$inblock = 0;
push(@{$self->{powersupplies}},
HP::Proliant::Component::PowersupplySubsystem::Powersupply->new(%tmpps));
%tmpps = (
runtime => $self->{runtime},
cpqHeFltTolPowerSupplyChassis => 1,
);
}
$tmpps{cpqHeFltTolPowerSupplyBay} = $1;
$inblock = 1;
} elsif (/\s*Present\s+:\s+(\w+)/) {
$tmpps{cpqHeFltTolPowerSupplyPresent} = lc $1 eq 'yes' ? 'present' :
lc $1 eq 'no' ? 'absent': 'other';
} elsif (/\s*Redundant\s*:\s+(\w+)/) {
$tmpps{cpqHeFltTolPowerSupplyRedundant} = lc $1 eq 'yes' ? 'redundant' :
lc $1 eq 'no' ? 'notRedundant' : 'other';
} elsif (/\s*Condition\s*:\s+(\w+)/) {
$tmpps{cpqHeFltTolPowerSupplyCondition} = lc $1;
} elsif (/\s*Power Supply not present/) {
$tmpps{cpqHeFltTolPowerSupplyPresent} = "absent";
$tmpps{cpqHeFltTolPowerSupplyCondition} = "other";
$tmpps{cpqHeFltTolPowerSupplyRedundant} = "notRedundant";
} elsif (/^\s*$/) {
if ($inblock) {
$inblock = 0;
push(@{$self->{powersupplies}},
HP::Proliant::Component::PowersupplySubsystem::Powersupply->new(%tmpps));
%tmpps = (
runtime => $self->{runtime},
cpqHeFltTolPowerSupplyChassis => 1,
);
}
}
}
if ($inblock) {
push(@{$self->{powersupplies}},
HP::Proliant::Component::PowersupplySubsystem::Powersupply->new(%tmpps));
%tmpps = (
runtime => $params{runtime},
);
}
}
package HP::Proliant::Component::PowersupplySubsystem::SNMP;
our @ISA = qw(HP::Proliant::Component::PowersupplySubsystem
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
powersupplies => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init(%params);
return $self;
}
sub init {
my $self = shift;
my %params = @_;
my $snmpwalk = $self->{rawdata};
my $oids = {
cpqHeFltTolPowerSupplyEntry => "1.3.6.1.4.1.232.6.2.9.3.1",
cpqHeFltTolPowerSupplyChassis => "1.3.6.1.4.1.232.6.2.9.3.1.1",
cpqHeFltTolPowerSupplyBay => "1.3.6.1.4.1.232.6.2.9.3.1.2",
cpqHeFltTolPowerSupplyPresent => "1.3.6.1.4.1.232.6.2.9.3.1.3",
cpqHeFltTolPowerSupplyCondition => "1.3.6.1.4.1.232.6.2.9.3.1.4",
cpqHeFltTolPowerSupplyRedundant => "1.3.6.1.4.1.232.6.2.9.3.1.9",
cpqHeFltTolPowerSupplyPresentValue => {
1 => "other",
2 => "absent",
3 => "present",
},
cpqHeFltTolPowerSupplyConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqHeFltTolPowerSupplyRedundantValue => {
1 => "other",
2 => "notRedundant",
3 => "redundant",
},
};
# INDEX { cpqHeFltTolPowerSupplyChassis, cpqHeFltTolPowerSupplyBay }
foreach ($self->get_entries($oids, 'cpqHeFltTolPowerSupplyEntry')) {
push(@{$self->{powersupplies}},
HP::Proliant::Component::PowersupplySubsystem::Powersupply->new(%{$_}));
}
$oids = {
cpqHePowerConvEntry => "1.3.6.1.4.1.232.6.2.13.3.1",
cpqHePowerConvChassis => "1.3.6.1.4.1.232.6.2.13.3.1",
cpqHePowerConvIndex => "1.3.6.1.4.1.232.6.2.13.3.1.2",
cpqHePowerConvPresent => "1.3.6.1.4.1.232.6.2.13.3.1.3",
cpqHePowerConvRedundant => "1.3.6.1.4.1.232.6.2.13.3.1.6",
cpqHePowerConvCondition => "1.3.6.1.4.1.232.6.2.13.3.1.8",
cpqHePowerConvPresentValue => {
1 => "other",
2 => "absent",
3 => "present",
},
cpqHePowerConvRedundantValue => {
1 => "other",
2 => "notRedundant",
3 => "redundant",
},
cpqHePowerConvConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqHePowerConvHwLocation => "1.3.6.1.4.1.232.6.2.13.3.1.9",
};
# INDEX { cpqHePowerConvChassis cpqHePowerConvIndex }
#foreach ($self->get_entries($oids, 'cpqHePowerConvEntry')) {
#push(@{$self->{powersupplies}},
# HP::Proliant::Component::PowersupplySubsystem::Powersupply->new(%{$_}));
#}
# keine ahnung, was man damit machen kann
}
package HP::Proliant::Component::TemperatureSubsystem;
our @ISA = qw(HP::Proliant::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
################################## custom_thresholds
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
condition => $params{condition},
status => $params{status},
temperatures => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
if ($params{runtime}->{options}->{customthresholds}) {
if (-f $params{runtime}->{options}->{customthresholds}) {
$params{runtime}->{options}->{customthresholds} =
do { local (@ARGV, $/) =
$params{runtime}->{options}->{customthresholds}; <> };
}
foreach my $ct_items
(split(/\//, $params{runtime}->{options}->{customthresholds})) {
if ($ct_items =~ /^(\d+):(\d+)$/) {
$params{runtime}->{options}->{thresholds}->{$1} = $2;
} else {
die sprintf "invalid threshold %s", $ct_items;
}
}
}
if ($self->{method} eq 'snmp') {
return HP::Proliant::Component::TemperatureSubsystem::SNMP->new(%params);
} elsif ($self->{method} eq 'cli') {
return HP::Proliant::Component::TemperatureSubsystem::CLI->new(%params);
} else {
die "unknown method";
}
return $self;
}
sub check {
my $self = shift;
my $errorfound = 0;
$self->add_info('checking temperatures');
if (scalar (@{$self->{temperatures}}) == 0) {
#$self->overall_check();
$self->add_info('no temperatures found');
} else {
foreach (sort { $a->{cpqHeTemperatureIndex} <=> $b->{cpqHeTemperatureIndex}}
@{$self->{temperatures}}) {
$_->check();
}
}
}
sub dump {
my $self = shift;
foreach (@{$self->{temperatures}}) {
$_->dump();
}
}
package HP::Proliant::Component::TemperatureSubsystem::Temperature;
our @ISA = qw(HP::Proliant::Component::TemperatureSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqHeTemperatureChassis => $params{cpqHeTemperatureChassis},
cpqHeTemperatureIndex => $params{cpqHeTemperatureIndex},
cpqHeTemperatureLocale => $params{cpqHeTemperatureLocale},
cpqHeTemperatureCelsius => $params{cpqHeTemperatureCelsius},
cpqHeTemperatureThresholdCelsius => $params{cpqHeTemperatureThresholdCelsius},
cpqHeTemperatureCondition => $params{cpqHeTemperatureCondition},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
if ($params{runtime}->{options}->{celsius}) {
$self->{cpqHeTemperatureUnits} = 'C';
$self->{cpqHeTemperature} = $self->{cpqHeTemperatureCelsius};
$self->{cpqHeTemperatureThreshold} =
$self->{cpqHeTemperatureThresholdCelsius};
} else {
$self->{cpqHeTemperatureUnits} = 'F';
$self->{cpqHeTemperature} =
(($self->{cpqHeTemperatureCelsius} * 9) / 5) + 32;
$self->{cpqHeTemperatureThreshold} =
(($self->{cpqHeTemperatureThresholdCelsius} * 9) / 5) + 32;
}
my $index = $self->{cpqHeTemperatureIndex};
if (exists $params{runtime}->{options}->{thresholds}->{$index}) {
$self->{cpqHeTemperatureThreshold} =
$params{runtime}->{options}->{thresholds}->{$index};
}
return $self;
}
sub check {
my $self = shift;
$self->blacklist('t', $self->{cpqHeTemperatureIndex});
if ($self->{cpqHeTemperature} > $self->{cpqHeTemperatureThreshold}) {
$self->add_info(sprintf "%d %s temperature too high (%d%s, %d max)",
$self->{cpqHeTemperatureIndex}, $self->{cpqHeTemperatureLocale},
$self->{cpqHeTemperature}, $self->{cpqHeTemperatureUnits},
$self->{cpqHeTemperatureThreshold});
$self->add_message(CRITICAL, $self->{info});
} else {
$self->add_info(sprintf "%d %s temperature is %d%s (%d max)",
$self->{cpqHeTemperatureIndex}, $self->{cpqHeTemperatureLocale},
$self->{cpqHeTemperature}, $self->{cpqHeTemperatureUnits},
$self->{cpqHeTemperatureThreshold});
}
if ($self->{runtime}->{options}->{perfdata} == 2) {
$self->{runtime}->{plugin}->add_perfdata(
label => sprintf('temp_%s', $self->{cpqHeTemperatureIndex}),
value => $self->{cpqHeTemperature},
warning => $self->{cpqHeTemperatureThreshold},
critical => $self->{cpqHeTemperatureThreshold}
);
} elsif ($self->{runtime}->{options}->{perfdata} == 1) {
$self->{runtime}->{plugin}->add_perfdata(
label => sprintf('temp_%s_%s', $self->{cpqHeTemperatureIndex},
$self->{cpqHeTemperatureLocale}),
value => $self->{cpqHeTemperature},
warning => $self->{cpqHeTemperatureThreshold},
critical => $self->{cpqHeTemperatureThreshold}
);
}
$self->add_extendedinfo(sprintf "temp_%s=%d",
$self->{cpqHeTemperatureIndex},
$self->{cpqHeTemperature});
}
sub dump {
my $self = shift;
printf "[TEMP_%s]\n", $self->{cpqHeTemperatureIndex};
foreach (qw(cpqHeTemperatureChassis cpqHeTemperatureIndex
cpqHeTemperatureLocale cpqHeTemperatureCelsius cpqHeTemperatureThreshold
cpqHeTemperatureCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "info: %s\n\n", $self->{info};
}
package HP::Proliant::Component::TemperatureSubsystem::CLI;
our @ISA = qw(HP::Proliant::Component::TemperatureSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
temperatures => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init(%params);
return $self;
}
sub init {
my $self = shift;
my %params = @_;
my $tempcnt = 1;
foreach (grep(/^temp/, split(/\n/, $params{rawdata}))) {
s/^temp\s*//g;
if (/^#(\d+)\s+([\w_\/\-#]+)\s+(\d+)C\/(\d+)F\s+(\d+)C\/(\d+)F/) {
my %params = ();
$params{runtime} = $self->{runtime};
$params{cpqHeTemperatureChassis} = 1;
$params{cpqHeTemperatureIndex} = $1;
$params{cpqHeTemperatureLocale} = lc $2;
$params{cpqHeTemperatureCelsius} = $3;
$params{cpqHeTemperatureThresholdCelsius} = $5;
$params{cpqHeTemperatureCondition} = 'unknown';
push(@{$self->{temperatures}},
HP::Proliant::Component::TemperatureSubsystem::Temperature->new(
%params));
} elsif (/^#(\d+)\s+([\w_\/\-#]+)\s+\-\s+(\d+)C\/(\d+)F/) {
# #3 CPU#2 - 0C/0F
$self->trace(2, sprintf "skipping temperature %s", $_);
} elsif (/^#(\d+)\s+([\w_\/\-#]+)\s+(\d+)C\/(\d+)F\s+\-/) {
# #3 CPU#2 0C/0F -
$self->trace(2, sprintf "skipping temperature %s", $_);
} elsif (/^#(\d+)\s+([\w_\/\-#]+)\s+\-\s+\-/) {
# #3 CPU#2 - -
$self->trace(2, sprintf "skipping temperature %s", $_);
} elsif (/^#(\d+)/) {
$self->trace(0, sprintf "send this to lausser: %s", $_);
}
}
}
package HP::Proliant::Component::TemperatureSubsystem::SNMP;
our @ISA = qw(HP::Proliant::Component::TemperatureSubsystem
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
temperatures => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init(%params);
return $self;
}
sub init {
my $self = shift;
my %params = @_;
my $snmpwalk = $self->{rawdata};
my $oids = {
cpqHeTemperatureEntry => "1.3.6.1.4.1.232.6.2.6.8.1",
cpqHeTemperatureChassis => "1.3.6.1.4.1.232.6.2.6.8.1.1",
cpqHeTemperatureIndex => "1.3.6.1.4.1.232.6.2.6.8.1.2",
cpqHeTemperatureLocale => "1.3.6.1.4.1.232.6.2.6.8.1.3",
cpqHeTemperatureCelsius => "1.3.6.1.4.1.232.6.2.6.8.1.4",
cpqHeTemperatureThresholdCelsius => "1.3.6.1.4.1.232.6.2.6.8.1.5",
cpqHeTemperatureCondition => "1.3.6.1.4.1.232.6.2.6.8.1.6",
cpqHeTemperatureLocaleValue => {
1 => "other",
2 => "unknown",
3 => "system",
4 => "systemBoard",
5 => "ioBoard",
6 => "cpu",
7 => "memory",
8 => "storage",
9 => "removableMedia",
10 => "powerSupply",
11 => "ambient",
12 => "chassis",
13 => "bridgeCard",
},
cpqHeTemperatureConditionValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
}
};
# INDEX { cpqHeTemperatureChassis, cpqHeTemperatureIndex }
foreach ($self->get_entries($oids, 'cpqHeTemperatureEntry')) {
push(@{$self->{temperatures}},
HP::Proliant::Component::TemperatureSubsystem::Temperature->new(%{$_}));
}
}
package HP::Proliant::Component::CpuSubsystem;
our @ISA = qw(HP::Proliant::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
################################## scrapiron ##########
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
condition => $params{condition},
status => $params{status},
cpus => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
return HP::Proliant::Component::CpuSubsystem::SNMP->new(%params);
} elsif ($self->{method} eq 'cli') {
return HP::Proliant::Component::CpuSubsystem::CLI->new(%params);
} else {
die "unknown method";
}
return $self;
}
sub check {
my $self = shift;
my $errorfound = 0;
$self->add_info('checking cpus');
if (scalar (@{$self->{cpus}}) == 0) {
# sachen gibts.....
# $self->overall_check(); # sowas ist mir nur einmal untergekommen
} else {
foreach (@{$self->{cpus}}) {
$_->check();
}
}
}
sub num_cpus {
my $self = shift;
return scalar @{$self->{cpus}};
}
sub dump {
my $self = shift;
foreach (@{$self->{cpus}}) {
$_->dump();
}
}
package HP::Proliant::Component::CpuSubsystem::Cpu;
our @ISA = qw(HP::Proliant::Component::CpuSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqSeCpuSlot => $params{cpqSeCpuSlot},
cpqSeCpuUnitIndex => $params{cpqSeCpuUnitIndex},
cpqSeCpuName => $params{cpqSeCpuName},
cpqSeCpuStatus => $params{cpqSeCpuStatus},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('c', $self->{cpqSeCpuUnitIndex});
if ($self->{cpqSeCpuStatus} ne "ok") {
if ($self->{runtime}->{options}{scrapiron} &&
($self->{cpqSeCpuStatus} eq "unknown")) {
$self->add_info(sprintf "cpu %d probably ok (%s)",
$self->{cpqSeCpuUnitIndex}, $self->{cpqSeCpuStatus});
} else {
$self->add_info(sprintf "cpu %d needs attention (%s)",
$self->{cpqSeCpuUnitIndex}, $self->{cpqSeCpuStatus});
$self->add_message(CRITICAL, $self->{info});
}
} else {
$self->add_info(sprintf "cpu %d is %s",
$self->{cpqSeCpuUnitIndex}, $self->{cpqSeCpuStatus});
}
$self->add_extendedinfo(sprintf "cpu_%s=%s",
$self->{cpqSeCpuUnitIndex}, $self->{cpqSeCpuStatus});
}
sub dump {
my $self = shift;
printf "[CPU_%s]\n", $self->{cpqSeCpuUnitIndex};
foreach (qw(cpqSeCpuSlot cpqSeCpuUnitIndex cpqSeCpuName cpqSeCpuStatus)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "info: %s\n", $self->{info};
printf "\n";
}
package HP::Proliant::Component::CpuSubsystem::CLI;
our @ISA = qw(HP::Proliant::Component::CpuSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
cpus => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init(%params);
return $self;
}
sub init {
my $self = shift;
my %params = @_;
my %tmpcpu = (
runtime => $params{runtime},
);
my $inblock = 0;
foreach (grep(/^server/, split(/\n/, $self->{rawdata}))) {
if (/Processor:\s+(\d+)/) {
$tmpcpu{cpqSeCpuUnitIndex} = $1;
$inblock = 1;
} elsif (/Name\s*:\s+(.+?)\s*$/) {
$tmpcpu{cpqSeCpuName} = $1;
} elsif (/Status\s*:\s+(.+?)\s*$/) {
$tmpcpu{cpqSeCpuStatus} = lc $1;
} elsif (/Socket\s*:\s+(.+?)\s*$/) {
$tmpcpu{cpqSeCpuSlot} = $1;
} elsif (/^server\s*$/) {
if ($inblock) {
$inblock = 0;
push(@{$self->{cpus}},
HP::Proliant::Component::CpuSubsystem::Cpu->new(%tmpcpu));
%tmpcpu = (
runtime => $params{runtime},
);
}
}
}
if ($inblock) {
push(@{$self->{cpus}},
HP::Proliant::Component::CpuSubsystem::Cpu->new(%tmpcpu));
}
}
package HP::Proliant::Component::CpuSubsystem::SNMP;
our @ISA = qw(HP::Proliant::Component::CpuSubsystem
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
cpus => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
# CPQSTDEQ-MIB
my $oids = {
cpqSeCpuEntry => '1.3.6.1.4.1.232.1.2.2.1.1',
cpqSeCpuUnitIndex => '1.3.6.1.4.1.232.1.2.2.1.1.1',
cpqSeCpuSlot => '1.3.6.1.4.1.232.1.2.2.1.1.2',
cpqSeCpuName => '1.3.6.1.4.1.232.1.2.2.1.1.3',
cpqSeCpuStatus => '1.3.6.1.4.1.232.1.2.2.1.1.6',
cpqSeCpuStatusValue => {
1 => "unknown",
2 => "ok",
3 => "degraded",
4 => "failed",
5 => "disabled",
},
};
# INDEX { cpqSeCpuUnitIndex }
foreach ($self->get_entries($oids, 'cpqSeCpuEntry')) {
push(@{$self->{cpus}},
HP::Proliant::Component::CpuSubsystem::Cpu->new(%{$_}));
}
}
package HP::Proliant::Component::FanSubsystem;
our @ISA = qw(HP::Proliant::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
################################## fan_redundancy ##########
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
condition => $params{condition},
status => $params{status},
fans => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
return HP::Proliant::Component::FanSubsystem::SNMP->new(%params);
} elsif ($self->{method} eq 'cli') {
return HP::Proliant::Component::FanSubsystem::CLI->new(%params);
} else {
die 'unknown method';
}
return $self;
}
sub check {
my $self = shift;
my $errorfound = 0;
$self->add_info('checking fans');
$self->blacklist('ff', '');
if (scalar (@{$self->{fans}}) == 0) {
$self->overall_check(); # sowas ist mir nur einmal untergekommen
# die maschine hatte alles in allem nur 2 oids (cpqHeFltTolFanChassis)
# SNMPv2-SMI::enterprises.232.6.2.6.7.1.1.0.1 = INTEGER: 0
# SNMPv2-SMI::enterprises.232.6.2.6.7.1.1.0.2 = INTEGER: 0
} else {
my $overallhealth = $self->overall_check();
foreach (@{$self->{fans}}) {
$_->{overallhealth} = $overallhealth;
$_->check();
}
}
}
sub dump {
my $self = shift;
foreach (@{$self->{fans}}) {
$_->dump();
}
}
sub get_fan_by_index {
my $self = shift;
my $index;
foreach (@{$self->{fans}}) {
return $_ if exists $_->{cpqHeFltTolFanIndex} &&
$_->{cpqHeFltTolFanIndex} == $index;
}
return undef;
}
package HP::Proliant::Component::FanSubsystem::Fan;
our @ISA = qw(HP::Proliant::Component::FanSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
if (exists $params{cpqHeFltTolFanRedundant}) {
return HP::Proliant::Component::FanSubsystem::Fan::FTol->new(%params);
} else {
return HP::Proliant::Component::FanSubsystem::Fan::Thermal->new(%params);
}
}
package HP::Proliant::Component::FanSubsystem::Fan::FTol;
our @ISA = qw(HP::Proliant::Component::FanSubsystem::Fan);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqHeFltTolFanChassis => $params{cpqHeFltTolFanChassis},
cpqHeFltTolFanIndex => $params{cpqHeFltTolFanIndex},
cpqHeFltTolFanLocale => $params{cpqHeFltTolFanLocale},
cpqHeFltTolFanPresent => $params{cpqHeFltTolFanPresent},
cpqHeFltTolFanType => $params{cpqHeFltTolFanType},
cpqHeFltTolFanSpeed => $params{cpqHeFltTolFanSpeed},
cpqHeFltTolFanRedundant => $params{cpqHeFltTolFanRedundant},
cpqHeFltTolFanRedundantPartner => $params{cpqHeFltTolFanRedundantPartner},
cpqHeFltTolFanCondition => $params{cpqHeFltTolFanCondition},
cpqHeFltTolFanPctMax => $params{cpqHeFltTolFanPctMax}, #!!!
cpqHeFltTolFanHotPlug => $params{cpqHeFltTolFanHotPlug}, #!!!
partner => $params{partner},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
if (($self->{cpqHeFltTolFanRedundant} eq 'redundant') &&
((! defined $self->{cpqHeFltTolFanRedundantPartner}) ||
(! $self->{cpqHeFltTolFanRedundantPartner}))) {
$self->{cpqHeFltTolFanRedundant} = 'notRedundant';
# cpqHeFltTolFanRedundantPartner=0: partner not avail
}
return $self;
}
sub check {
my $self = shift;
$self->blacklist('f', $self->{cpqHeFltTolFanIndex});
$self->add_info(sprintf 'fan %d is %s, speed is %s, pctmax is %s%%, '.
'location is %s, redundance is %s, partner is %s',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanPresent},
$self->{cpqHeFltTolFanSpeed}, $self->{cpqHeFltTolFanPctMax},
$self->{cpqHeFltTolFanLocale}, $self->{cpqHeFltTolFanRedundant},
$self->{cpqHeFltTolFanRedundantPartner});
$self->add_extendedinfo(sprintf 'fan_%s=%d%%',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanPctMax});
if ($self->{cpqHeFltTolFanPresent} eq 'present') {
if ($self->{cpqHeFltTolFanSpeed} eq 'high') {
$self->add_info(sprintf 'fan %d (%s) runs at high speed',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanLocale});
$self->add_message(CRITICAL, $self->{info});
} elsif ($self->{cpqHeFltTolFanSpeed} ne 'normal') {
$self->add_info(sprintf 'fan %d (%s) needs attention',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanLocale});
$self->add_message(CRITICAL, $self->{info});
}
if ($self->{cpqHeFltTolFanCondition} eq 'failed') {
$self->add_info(sprintf 'fan %d (%s) failed',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanLocale});
$self->add_message(CRITICAL, $self->{info});
} elsif ($self->{cpqHeFltTolFanCondition} eq 'degraded') {
$self->add_info(sprintf 'fan %d (%s) degraded',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanLocale});
$self->add_message(WARNING, $self->{info});
} elsif ($self->{cpqHeFltTolFanCondition} ne 'ok') {
$self->add_info(sprintf 'fan %d (%s) is not ok',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanLocale});
$self->add_message(WARNING, $self->{info});
}
if ($self->{cpqHeFltTolFanRedundant} eq 'notRedundant') {
# sieht so aus, als waere notRedundant und partner=0 normal z.b. dl360
# das duerfte der fall sein, wenn nur eine cpu verbaut wurde und
# statt einem redundanten paar nur dummies drinstecken.
# "This specifies if the fan is in a redundant configuration"
# notRedundant heisst also sowohl nicht redundant wegen ausfall
# des partners als auch von haus aus nicht redundant ausgelegt
if ($self->{cpqHeFltTolFanRedundantPartner}) {
# nicht redundant, hat aber einen partner. da muss man genauer
# hinschauen
#if (my $partner = $self->{partner}) {
#}
if ($self->{overallhealth}) {
# da ist sogar das system der meinung, dass etwas faul ist
if (! $self->{runtime}->{options}->{ignore_fan_redundancy}) {
$self->add_info(sprintf 'fan %d (%s) is not redundant',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanLocale});
$self->add_message(WARNING, $self->{info});
}
} else {
# das ist wohl so gewollt, dass einzelne fans eingebaut werden,
# obwohl redundante paerchen vorgesehen sind.
# scheint davon abzuhaengen, wieviele cpus geordert wurden.
}
}
} elsif ($self->{cpqHeFltTolFanRedundant} eq 'other') {
#seen on a dl320 g5p with bios from 2008.
# maybe redundancy is not supported at all
}
} elsif ($self->{cpqHeFltTolFanPresent} eq 'failed') { # from cli
$self->add_info(sprintf 'fan %d (%s) failed',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanLocale});
$self->add_message(CRITICAL, $self->{info});
} elsif ($self->{cpqHeFltTolFanPresent} eq 'absent') {
$self->add_info(sprintf 'fan %d (%s) needs attention (is absent)',
$self->{cpqHeFltTolFanIndex}, $self->{cpqHeFltTolFanLocale});
# weiss nicht, ob absent auch kaputt bedeuten kann
# wenn nicht, dann wuerde man sich hier dumm und daemlich blacklisten
#$self->add_message(CRITICAL, $self->{info});
$self->add_message(WARNING, $self->{info}) if $self->{overallhealth};
}
if ($self->{runtime}->{options}->{perfdata}) {
$self->{runtime}->{plugin}->add_perfdata(
label => sprintf('fan_%s', $self->{cpqHeFltTolFanIndex}),
value => $self->{cpqHeFltTolFanPctMax},
uom => '%',
);
}
}
sub dump {
my $self = shift;
printf "[FAN_%s]\n", $self->{cpqHeFltTolFanIndex};
foreach (qw(cpqHeFltTolFanChassis cpqHeFltTolFanIndex cpqHeFltTolFanLocale
cpqHeFltTolFanPresent cpqHeFltTolFanType cpqHeFltTolFanSpeed
cpqHeFltTolFanRedundant cpqHeFltTolFanRedundantPartner
cpqHeFltTolFanCondition cpqHeFltTolFanHotPlug)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "info: %s\n", $self->{info};
printf "\n";
}
package HP::Proliant::Component::FanSubsystem::Fan::Thermal;
our @ISA = qw(HP::Proliant::Component::FanSubsystem::Fan);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqHeThermalFanIndex => $params{cpqHeThermalFanIndex},
cpqHeThermalFanRequired => $params{cpqHeThermalFanRequired},
cpqHeThermalFanPresent => $params{cpqHeThermalFanPresent},
cpqHeThermalFanCpuFan => $params{cpqHeThermalFanCpuFan},
cpqHeThermalFanStatus => $params{cpqHeThermalFanStatus},
cpqHeThermalFanHwLocation => $params{cpqHeThermalFanHwLocation},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
}
sub dump {
my $self = shift;
printf "[FAN_%s]\n", $self->{cpqHeThermalFanIndex};
foreach (qw(cpqHeThermalFanIndex cpqHeThermalFanRequired
cpqHeThermalFanPresent cpqHeThermalFanCpuFan cpqHeThermalFanStatus
cpqHeThermalFanHwLocation)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "info: %s\n", $self->{info};
printf "\n";
}
package HP::Proliant::Component::FanSubsystem::CLI;
our @ISA = qw(HP::Proliant::Component::FanSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
fans => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init(%params);
return $self;
}
# partner not available = cpqHeFltTolFanRedundantPartner=0
# cpqHeFltTolFanTypeValue = other
sub init {
my $self = shift;
my %params = @_;
my %tmpfan = ();
foreach (grep(/^fans/, split(/\n/, $self->{rawdata}))) {
s/^fans //g;
if (/^#(\d+)\s+([\w#_\/\-]+)\s+(\w+)\s+(\w+)\s+(FAILED|[N\/A\d]+)%*\s+([\w\/]+)\s+(FAILED|[N\/A\d]+)\s+(\w+)/) {
%tmpfan = (
cpqHeFltTolFanIndex => $1,
cpqHeFltTolFanLocale => lc $2,
cpqHeFltTolFanPresent => lc $3,
cpqHeFltTolFanSpeed => lc $4,
cpqHeFltTolFanPctMax => lc $5, # (FAILED|[N\/A\d]+)
cpqHeFltTolFanRedundant => lc $6,
cpqHeFltTolFanRedundantPartner => lc $7, # (FAILED|[N\/A\d]+)
cpqHeFltTolFanHotPlug => lc $8,
);
} elsif (/^#(\d+)\s+([\w#_\/\-]+?)(Yes|No|N\/A)\s+(\w+)\s+(FAILED|[N\/A\d]+)%*\s+([\w\/]+)\s+(FAILED|[N\/A\d]+)\s+(\w+)/) {
# #5 SCSI_BACKPLANE_ZONEYes NORMAL N/A ....
%tmpfan = (
cpqHeFltTolFanIndex => $1,
cpqHeFltTolFanLocale => lc $2,
cpqHeFltTolFanPresent => lc $3,
cpqHeFltTolFanSpeed => lc $4,
cpqHeFltTolFanPctMax => lc $5,
cpqHeFltTolFanRedundant => lc $6,
cpqHeFltTolFanRedundantPartner => lc $7,
cpqHeFltTolFanHotPlug => lc $8,
);
} elsif (/^#(\d+)\s+([\w#_\/\-]+)\s+[NOno]+\s/) {
# Fan is not installed. #2 CPU#2 No - - No N/A -
} elsif (/^#(\d+)/) {
main::contact_author("FAN", $_);
}
if (%tmpfan) {
$tmpfan{runtime} = $params{runtime};
$tmpfan{cpqHeFltTolFanChassis} = 1; # geht aus hpasmcli nicht hervor
$tmpfan{cpqHeFltTolFanType} = 'other';
if ($tmpfan{cpqHeFltTolFanPctMax} !~ /^\d+$/) {
if ($tmpfan{cpqHeFltTolFanSpeed} eq 'normal') {
$tmpfan{cpqHeFltTolFanPctMax} = 50;
} elsif ($tmpfan{cpqHeFltTolFanSpeed} eq 'high') {
$tmpfan{cpqHeFltTolFanPctMax} = 100;
} else {
$tmpfan{cpqHeFltTolFanPctMax} = 0;
}
}
if($tmpfan{cpqHeFltTolFanSpeed} eq 'failed') {
$tmpfan{cpqHeFltTolFanCondition} = 'failed';
} elsif($tmpfan{cpqHeFltTolFanSpeed} eq 'n/a') {
$tmpfan{cpqHeFltTolFanCondition} = 'other';
} else {
$tmpfan{cpqHeFltTolFanCondition} = 'ok';
}
$tmpfan{cpqHeFltTolFanRedundant} =
$tmpfan{cpqHeFltTolFanRedundant} eq 'yes' ? 'redundant' :
$tmpfan{cpqHeFltTolFanRedundant} eq 'no' ? 'notRedundant' : 'other';
$tmpfan{cpqHeFltTolFanPresent} =
$tmpfan{cpqHeFltTolFanPresent} eq 'yes' ? 'present' :
$tmpfan{cpqHeFltTolFanPresent} eq 'failed' ? 'present' :
$tmpfan{cpqHeFltTolFanPresent} eq 'no' ? 'absent' : 'other';
$tmpfan{cpqHeFltTolFanHotPlug} =
$tmpfan{cpqHeFltTolFanHotPlug} eq 'yes' ? 'hotPluggable' :
$tmpfan{cpqHeFltTolFanHotPlug} eq 'no' ? 'nonHotPluggable' : 'other';
push(@{$self->{fans}},
HP::Proliant::Component::FanSubsystem::Fan->new(%tmpfan));
%tmpfan = ();
}
}
}
sub overall_check {
my $self = shift;
# nix. nur wegen der gleichheit mit snmp
return 0;
}
package HP::Proliant::Component::FanSubsystem::SNMP;
our @ISA = qw(HP::Proliant::Component::FanSubsystem
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
fans => [],
he_fans => [],
th_fans => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->overall_init(%params);
$self->he_init(%params);
$self->te_init(%params);
$self->unite();
return $self;
}
sub overall_init {
my $self = shift;
my %params = @_;
my $snmpwalk = $params{rawdata};
# overall
my $cpqHeThermalSystemFanStatus = '1.3.6.1.4.1.232.6.2.6.4.0';
my $cpqHeThermalSystemFanStatusValue = {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
};
my $cpqHeThermalCpuFanStatus = '1.3.6.1.4.1.232.6.2.6.5.0';
my $cpqHeThermalCpuFanStatusValue = {
1 => 'other',
2 => 'ok',
4 => 'failed', # shutdown
};
$self->{sysstatus} = lc SNMP::Utils::get_object_value(
$snmpwalk, $cpqHeThermalSystemFanStatus,
$cpqHeThermalSystemFanStatusValue);
$self->{cpustatus} = lc SNMP::Utils::get_object_value(
$snmpwalk, $cpqHeThermalCpuFanStatus,
$cpqHeThermalCpuFanStatusValue);
}
sub te_init {
my $self = shift;
my %params = @_;
my $snmpwalk = $params{rawdata};
my $ignore_redundancy = $params{ignore_redundancy};
# cpqHeThermalFanTable
my $oids = {
cpqHeThermalFanEntry => '1.3.6.1.4.1.232.6.2.6.6.1',
cpqHeThermalFanIndex => '1.3.6.1.4.1.232.6.2.6.6.1.1',
cpqHeThermalFanRequired => '1.3.6.1.4.1.232.6.2.6.6.1.2',
cpqHeThermalFanPresent => '1.3.6.1.4.1.232.6.2.6.6.1.3',
cpqHeThermalFanCpuFan => '1.3.6.1.4.1.232.6.2.6.6.1.4',
cpqHeThermalFanStatus => '1.3.6.1.4.1.232.6.2.6.6.1.5',
cpqHeThermalFanHwLocation => '1.3.6.1.4.1.232.6.2.6.6.1.6',
cpqHeThermalFanRequiredValue => {
1 => 'other',
2 => 'nonRequired',
3 => 'required',
},
cpqHeThermalFanPresentValue => {
1 => 'other',
2 => 'absent',
3 => 'present',
},
cpqHeThermalFanCpuFanValue => {
1 => 'other',
2 => 'systemFan',
3 => 'cpuFan',
},
cpqHeThermalFanStatusValue => {
1 => 'other',
2 => 'ok',
4 => 'failed',
},
};
# INDEX { cpqHeThermalFanIndex }
foreach ($self->get_entries($oids, 'cpqHeThermalFanEntry')) {
next if ! $_->{cpqHeThermalFanPresent};
push(@{$self->{th_fans}},
HP::Proliant::Component::FanSubsystem::Fan->new(%{$_}));
}
}
sub he_init {
my $self = shift;
my %params = @_;
my $snmpwalk = $params{rawdata};
my $ignore_redundancy = $params{ignore_redundancy};
# cpqHeFltTolFanTable
my $oids = {
cpqHeFltTolFanEntry => '1.3.6.1.4.1.232.6.2.6.7.1',
cpqHeFltTolFanChassis => '1.3.6.1.4.1.232.6.2.6.7.1.1',
cpqHeFltTolFanIndex => '1.3.6.1.4.1.232.6.2.6.7.1.2',
cpqHeFltTolFanLocale => '1.3.6.1.4.1.232.6.2.6.7.1.3',
cpqHeFltTolFanPresent => '1.3.6.1.4.1.232.6.2.6.7.1.4',
cpqHeFltTolFanType => '1.3.6.1.4.1.232.6.2.6.7.1.5',
cpqHeFltTolFanSpeed => '1.3.6.1.4.1.232.6.2.6.7.1.6',
cpqHeFltTolFanRedundant => '1.3.6.1.4.1.232.6.2.6.7.1.7',
cpqHeFltTolFanRedundantPartner => '1.3.6.1.4.1.232.6.2.6.7.1.8',
cpqHeFltTolFanCondition => '1.3.6.1.4.1.232.6.2.6.7.1.9',
cpqHeFltTolFanHotPlug => '1.3.6.1.4.1.232.6.2.6.7.1.10',
cpqHeFltTolFanHwLocation => '1.3.6.1.4.1.232.6.2.6.7.1.11',
cpqHeFltTolFanCurrentSpeed => '1.3.6.1.4.1.232.6.2.6.7.1.12',
cpqHeFltTolFanLocaleValue => {
1 => "other",
2 => "unknown",
3 => "system",
4 => "systemBoard",
5 => "ioBoard",
6 => "cpu",
7 => "memory",
8 => "storage",
9 => "removableMedia",
10 => "powerSupply",
11 => "ambient",
12 => "chassis",
13 => "bridgeCard",
},
cpqHeFltTolFanPresentValue => {
1 => "other",
2 => "absent",
3 => "present",
},
cpqHeFltTolFanSpeedValue => {
1 => "other",
2 => "normal",
3 => "high",
},
cpqHeFltTolFanRedundantValue => {
1 => "other",
2 => "notRedundant",
3 => "redundant",
},
cpqHeFltTolFanTypeValue => {
1 => "other",
2 => "tachInput",
3 => "spinDetect",
},
cpqHeFltTolFanConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqHeFltTolFanHotPlugValue => {
1 => "other",
2 => "nonHotPluggable",
3 => "hotPluggable",
},
};
# INDEX { cpqHeFltTolFanChassis, cpqHeFltTolFanIndex }
foreach ($self->get_entries($oids, 'cpqHeFltTolFanEntry')) {
next if ! defined $_->{cpqHeFltTolFanIndex};
# z.b. USM65201WS hat nur solche fragmente. die werden erst gar nicht
# als fans akzeptiert. dafuer gibts dann die overall condition
# SNMPv2-SMI::enterprises.232.6.2.6.7.1.1.0.1 = INTEGER: 0
# SNMPv2-SMI::enterprises.232.6.2.6.7.1.1.0.2 = INTEGER: 0
$_->{cpqHeFltTolFanPctMax} = ($_->{cpqHeFltTolFanPresent} eq 'present') ?
50 : 0;
push(@{$self->{he_fans}},
HP::Proliant::Component::FanSubsystem::Fan->new(%{$_}));
}
}
sub unite {
my $self = shift;
my $tmpfans = {};
foreach (@{$self->{he_fans}}) {
$tmpfans->{$_->{cpqHeFltTolFanIndex}} = $_;
}
foreach (@{$self->{he_fans}}) {
if (exists $tmpfans->{$_->{cpqHeFltTolFanRedundantPartner}}) {
$_->{partner} = $tmpfans->{$_->{cpqHeFltTolFanRedundantPartner}};
} else {
$_->{partner} = undef;
}
}
@{$self->{fans}} = @{$self->{he_fans}};
}
sub overall_check {
my $self = shift;
my $result = 0;
if ($self->{sysstatus} && $self->{cpustatus}) {
if ($self->{sysstatus} eq 'degraded') {
$result = 1;
$self->add_message(WARNING,
sprintf 'system fan overall status is %s', $self->{sysstatus});
} elsif ($self->{sysstatus} eq 'failed') {
$result = 2;
$self->add_message(CRITICAL,
sprintf 'system fan overall status is %s', $self->{sysstatus});
}
if ($self->{cpustatus} eq 'degraded') {
$result = 1;
$self->add_message(WARNING,
sprintf 'cpu fan overall status is %s', $self->{cpustatus});
} elsif ($self->{cpustatus} eq 'failed') {
$result = 2;
$self->add_message(CRITICAL,
sprintf 'cpu fan overall status is %s', $self->{cpustatus});
}
$self->add_info(sprintf 'overall fan status: system=%s, cpu=%s',
$self->{sysstatus}, $self->{cpustatus});
} else {
$result = 0;
$self->add_info('this system seems to be water-cooled. no fans found');
}
return $result;
}
package HP::Proliant::Component::MemorySubsystem::CLI;
our @ISA = qw(HP::Proliant::Component::MemorySubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
dimms => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init(%params);
return $self;
}
sub init {
my $self = shift;
my %params = @_;
$self->{dimms} = [];
my %tmpdimm = (
runtime => $params{runtime},
);
my $inblock = 0;
foreach (grep(/^dimm/, split(/\n/, $self->{rawdata}))) {
s/^dimm\s*$//g;
if (/Cartridge #:\s+(\d+)/ || /Processor #:\s+(\d+)/) {
# neuerdings (g6) tauchen hier prozessor- statt cartridge-angaben auf
$tmpdimm{cartridge} = $1;
$tmpdimm{board} = $1;
$inblock = 1;
} elsif (/Module #:\s+(\d+)/) {
$tmpdimm{module} = $1;
} elsif (/Present:\s+(\w+)/) {
$tmpdimm{status} = lc $1 eq 'yes' ? 'present' :
lc $1 eq 'no' ? 'notPresent' : 'other';
} elsif (/Status:\s+(.+?)\s*$/) {
$tmpdimm{condition} = lc $1 =~ /degraded/ ? 'degraded' :
lc $1 eq 'ok' ? 'ok' : lc $1 =~ /n\/a/ ? 'n/a' : 'other';
} elsif (/Size:\s+(\d+)\s*(.+?)\s*$/) {
$tmpdimm{size} = $1 * (lc $2 eq 'mb' ? 1024*1024 :
lc $2 eq 'gb' ? 1024*1024*1024 : 1);
} elsif (/^\s*$/) {
if ($inblock) {
$inblock = 0;
push(@{$self->{dimms}},
HP::Proliant::Component::MemorySubsystem::Dimm->new(%tmpdimm));
%tmpdimm = (
runtime => $params{runtime},
);
}
}
}
if ($inblock) {
push(@{$self->{dimms}},
HP::Proliant::Component::MemorySubsystem::Dimm->new(%tmpdimm));
}
}
sub is_faulty {
my $self = shift;
return 0; # cli hat so einen globalen status nicht
}
package HP::Proliant::Component::MemorySubsystem::SNMP;
our @ISA = qw(HP::Proliant::Component::MemorySubsystem
HP::Proliant::Component::SNMP);
use strict;
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
dimms => [],
si_dimms => [],
he_dimms => [],
h2_dimms => [],
he_cartridges => [],
h2_cartridges => [],
si_overall_condition => undef,
he_overall_condition => undef,
h2_overall_condition => undef,
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->si_init();
$self->he_init();
$self->he_cartridge_init();
$self->h2_init();
#$self->h2_cartridge_init();
$self->condense();
return $self;
}
sub si_init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
my $oids = {
cpqSiMemModuleEntry => '1.3.6.1.4.1.232.2.2.4.5.1',
cpqSiMemBoardIndex => '1.3.6.1.4.1.232.2.2.4.5.1.1',
cpqSiMemModuleIndex => '1.3.6.1.4.1.232.2.2.4.5.1.2',
cpqSiMemModuleSize => '1.3.6.1.4.1.232.2.2.4.5.1.3',
cpqSiMemModuleType => '1.3.6.1.4.1.232.2.2.4.5.1.4',
cpqSiMemECCStatus => '1.3.6.1.4.1.232.2.2.4.5.1.11',
cpqSiMemModuleHwLocation => '1.3.6.1.4.1.232.2.2.4.5.1.12',
cpqSiMemModuleTypeValue => {
1 => 'other',
2 => 'board',
3 => 'cpqSingleWidthModule',
4 => 'cpqDoubleWidthModule',
5 => 'simm',
6 => 'pcmcia',
7 => 'compaq-specific',
8 => 'dimm',
9 => 'smallOutlineDimm',
10 => 'rimm',
11 => 'srimm',
},
cpqSiMemECCStatusValue => {
0 => "n/a",
1 => "other",
2 => "ok",
3 => "degraded",
4 => "degradedModuleIndexUnknown",
34 => 'n/a', # es ist zum kotzen...
104 => 'n/a',
},
};
# INDEX { cpqSiMemBoardIndex, cpqSiMemModuleIndex }
foreach ($self->get_entries($oids, 'cpqSiMemModuleEntry')) {
$_->{cartridge} = $_->{cpqSiMemBoardIndex};
$_->{module} = $_->{cpqSiMemModuleIndex};
next if (! defined $_->{cartridge} || ! defined $_->{module});
$_->{size} = $_->{cpqSiMemModuleSize};
$_->{type} = $_->{cpqSiMemModuleType};
$_->{condition} = $_->{cpqSiMemECCStatus};
$_->{status} = ($_->{cpqSiMemModuleSize} > 0) ? 'present' : 'notPresent';
push(@{$self->{si_dimms}},
HP::Proliant::Component::MemorySubsystem::Dimm->new(%{$_})
);
}
my $cpqSiMemECCCondition = '1.3.6.1.4.1.232.2.2.4.15.0';
my $cpqSiMemECCConditionValue = {
1 => 'other',
2 => 'ok',
3 => 'degraded',
};
$self->{si_overall_condition} = SNMP::Utils::get_object_value(
$self->{rawdata}, $cpqSiMemECCCondition,
$cpqSiMemECCConditionValue);
$self->trace(2, sprintf 'overall si condition is %s',
$self->{si_overall_condition} || 'undefined');
}
sub he_init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
my $oids = {
cpqHeResMemModuleEntry => '1.3.6.1.4.1.232.6.2.14.11.1',
cpqHeResMemBoardIndex => '1.3.6.1.4.1.232.6.2.14.11.1.1',
cpqHeResMemModuleIndex => '1.3.6.1.4.1.232.6.2.14.11.1.2',
cpqHeResMemModuleStatus => '1.3.6.1.4.1.232.6.2.14.11.1.4',
cpqHeResMemModuleCondition => '1.3.6.1.4.1.232.6.2.14.11.1.5',
cpqHeResMemModuleStatusValue => {
1 => "other", # unknown or could not be determined
2 => "notPresent", # not present or un-initialized
3 => "present", # present but not in use
4 => "good", # present and in use. ecc threshold not exceeded
5 => "add", # added but not yet in use
6 => "upgrade", # upgraded but not yet in use
7 => "missing", # expected but missing
8 => "doesNotMatch", # does not match the other modules in the bank
9 => "notSupported", # module not supported
10 => "badConfig", # violates add/upgrade configuration
11 => "degraded", # ecc exceeds threshold
},
# condition = status of the correctable memory errors
cpqHeResMemModuleConditionValue => {
0 => "n/a", # this appears only with buggy firmwares.
# (only 1 module shows up)
1 => "other",
2 => "ok",
3 => "degraded",
},
};
my $tablesize = SNMP::Utils::get_size($snmpwalk,
$oids->{cpqHeResMemModuleEntry});
# INDEX { cpqHeResMemBoardIndex, cpqHeResMemModuleIndex }
foreach ($self->get_entries($oids, 'cpqHeResMemModuleEntry')) {
$_->{cartridge} = $_->{cpqHeResMemBoardIndex};
$_->{module} = $_->{cpqHeResMemModuleIndex};
$_->{present} = $_->{cpqHeResMemModuleStatus};
$_->{status} = $_->{cpqHeResMemModuleStatus};
$_->{condition} = $_->{cpqHeResMemModuleCondition};
if ((! defined $_->{module}) && ($_->{cartridge} == 0)) {
$_->{module} = $_->{index2}; # auf dem systemboard verbaut
}
push(@{$self->{he_dimms}},
HP::Proliant::Component::MemorySubsystem::Dimm->new(%{$_})
) unless (! defined $_->{cartridge} || ! defined $_->{module} ||
$tablesize == 1);
}
my $cpqHeResilientMemCondition = '1.3.6.1.4.1.232.6.2.14.4.0';
my $cpqHeResilientMemConditionValue = {
1 => 'other',
2 => 'ok',
3 => 'degraded',
};
$self->{he_overall_condition} = SNMP::Utils::get_object_value(
$self->{rawdata}, $cpqHeResilientMemCondition,
$cpqHeResilientMemConditionValue);
$self->trace(2, sprintf 'overall he condition is %s',
$self->{hei_overall_condition} || 'undefined');
}
sub he_cartridge_init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
my $oids = {
cpqHeResMemBoardEntry => '1.3.6.1.4.1.232.6.2.14.10.1',
cpqHeResMemBoardSlotIndex => '1.3.6.1.4.1.232.6.2.14.10.1.1',
cpqHeResMemBoardOnlineStatus => '1.3.6.1.4.1.232.6.2.14.10.1.2',
cpqHeResMemBoardErrorStatus => '1.3.6.1.4.1.232.6.2.14.10.1.3',
cpqHeResMemBoardNumSockets => '1.3.6.1.4.1.232.6.2.14.10.1.5',
cpqHeResMemBoardOsMemSize => '1.3.6.1.4.1.232.6.2.14.10.1.6',
cpqHeResMemBoardTotalMemSize => '1.3.6.1.4.1.232.6.2.14.10.1.7',
cpqHeResMemBoardCondition => '1.3.6.1.4.1.232.6.2.14.10.1.8',
# onlinestatus
cpqHeResMemBoardOnlineStatusValue => {
0 => "n/a", # this appears only with buggy firmwares.
# (only 1 module shows up)
1 => "other",
2 => "present",
3 => "absent",
},
cpqHeResMemBoardErrorStatusValue => {
1 => "other", #
2 => "noError", #
3 => "dimmEccError", #
4 => "unlockError", #
5 => "configError", #
6 => "busError", #
7 => "powerError", #
},
# condition = status of the correctable memory errors
cpqHeResMemBoardConditionValue => {
0 => "n/a", # this appears only with buggy firmwares.
# (only 1 module shows up)
1 => "other",
2 => "ok",
3 => "degraded",
},
};
my $tablesize = SNMP::Utils::get_size($snmpwalk,
$oids->{cpqHeResMemBoardEntry});
# INDEX { cpqHeResMemBoardIndex, cpqHeResMemBoardIndex }
foreach ($self->get_entries($oids, 'cpqHeResMemBoardEntry')) {
push(@{$self->{he_cartridges}},
HP::Proliant::Component::MemorySubsystem::Cartridge->new(%{$_})
) unless (! defined $_->{cpqHeResMemBoardSlotIndex} || $tablesize == 1);
}
}
sub h2_init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
my $oids = {
cpqHeResMem2ModuleEntry => '1.3.6.1.4.1.232.6.2.14.13.1',
cpqHeResMem2BoardNum => '1.3.6.1.4.1.232.6.2.14.13.1.2',
cpqHeResMem2ModuleNum => '1.3.6.1.4.1.232.6.2.14.13.1.5',
cpqHeResMem2ModuleStatus => '1.3.6.1.4.1.232.6.2.14.13.1.19',
cpqHeResMem2ModuleCondition => '1.3.6.1.4.1.232.6.2.14.13.1.20',
cpqHeResMem2ModuleSize => '1.3.6.1.4.1.232.6.2.14.13.1.6',
cpqHeResMem2ModuleStatusValue => {
1 => "other", # unknown or could not be determined
2 => "notPresent", # not present or un-initialized
3 => "present", # present but not in use
4 => "good", # present and in use. ecc threshold not exceeded
5 => "add", # added but not yet in use
6 => "upgrade", # upgraded but not yet in use
7 => "missing", # expected but missing
8 => "doesNotMatch", # does not match the other modules in the bank
9 => "notSupported", # module not supported
10 => "badConfig", # violates add/upgrade configuration
11 => "degraded", # ecc exceeds threshold
},
# condition = status of the correctable memory errors
cpqHeResMem2ModuleConditionValue => {
0 => "n/a", # this appears only with buggy firmwares.
# (only 1 module shows up)
1 => "other",
2 => "ok",
3 => "degraded",
},
};
# INDEX { cpqHeResMem2ModuleNum }
my $lastboard = 0;
my $lastmodule = 0;
my $myboard= 0;
my $hpboard = 0;
foreach (sort { $a->{index1} <=> $b->{index1} }
$self->get_entries($oids, 'cpqHeResMem2ModuleEntry')) {
$hpboard = $_->{cpqHeResMem2BoardNum};
# dass hier faelschlicherweise 0 zurueckkommt, wundert mich schon
# gar nicht mehr
$_->{module} = $_->{cpqHeResMem2ModuleNum};
if ($_->{module} < $lastmodule) {
# sieht so aus, als haette man es mit einem neuen board zu tun
# da hp zu bloed ist, selber hochzuzaehlen, muss ich das tun
$myboard++;
}
$lastmodule = $_->{cpqHeResMem2ModuleNum};
$_->{cartridge} = ($myboard != $hpboard) ? $myboard : $hpboard;
$_->{present} = $_->{cpqHeResMem2ModuleStatus};
$_->{status} = $_->{cpqHeResMem2ModuleStatus};
$_->{condition} = $_->{cpqHeResMem2ModuleCondition};
$_->{size} = $_->{cpqHeResMem2ModuleSize};
push(@{$self->{h2_dimms}},
HP::Proliant::Component::MemorySubsystem::Dimm->new(%{$_})
) unless (! defined $_->{cpqHeResMem2BoardNum} ||
! defined $_->{cpqHeResMem2ModuleNum});
}
}
sub h2_cartridge_init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
my $oids = {
cpqHeResMem2BoardEntry => '1.3.6.1.4.1.232.6.2.14.12.1',
cpqHeResMem2BoardIndex => '1.3.6.1.4.1.232.6.2.14.12.1.1',
cpqHeResMem2BoardOnlineStatus => '1.3.6.1.4.1.232.6.2.14.12.1.5',
cpqHeResMem2BoardErrorStatus => '1.3.6.1.4.1.232.6.2.14.12.1.6',
cpqHeResMem2BoardNumSockets => '1.3.6.1.4.1.232.6.2.14.12.1.8',
cpqHeResMem2BoardOsMemSize => '1.3.6.1.4.1.232.6.2.14.12.1.9',
cpqHeResMem2BoardTotalMemSize => '1.3.6.1.4.1.232.6.2.14.12.1.10',
cpqHeResMem2BoardCondition => '1.3.6.1.4.1.232.6.2.14.12.1.11',
# onlinestatus
cpqHeResMem2BoardOnlineStatusValue => {
0 => "n/a", # this appears only with buggy firmwares.
# (only 1 module shows up)
1 => "other",
2 => "present",
3 => "absent",
},
cpqHeResMem2BoardErrorStatusValue => {
1 => "other", #
2 => "noError", #
3 => "dimmEccError", #
4 => "unlockError", #
5 => "configError", #
6 => "busError", #
7 => "powerError", #
},
# condition = status of the correctable memory errors
cpqHeResMem2BoardConditionValue => {
0 => "n/a", # this appears only with buggy firmwares.
# (only 1 module shows up)
1 => "other",
2 => "ok",
3 => "degraded",
},
};
my $tablesize = SNMP::Utils::get_size($snmpwalk,
$oids->{cpqHeResMemBoardEntry});
# INDEX { cpqHeResMem2BoardIndex, cpqHeResMem2BoardIndex }
foreach ($self->get_entries($oids, 'cpqHeResMem2BoardEntry')) {
push(@{$self->{h2_cartridges}},
HP::Proliant::Component::MemorySubsystem::Cartridge->new(%{$_})
) unless (! defined $_->{cpqHeRes2MemBoardIndex} || $tablesize == 1);
}
}
sub condense {
my $self = shift;
my $snmpwalk = $self->{rawdata};
# wenn saemtliche dimms n/a sind
# wenn ignore dimms: ignoring %d dimms with status 'n/a'
# wenn buggyfirmware: ignoring %d dimms with status 'n/a' because of buggy firmware
# if buggy firmware : condition n/a ist normal
# ignore-dimms :
# es gibt si_dimms und he_dimms
my $si_dimms = scalar(@{$self->{si_dimms}});
my $he_dimms = scalar(@{$self->{he_dimms}});
my $h2_dimms = scalar(@{$self->{h2_dimms}});
$self->trace(2, sprintf "SI: %02d HE: %02d H2: %02d",
$si_dimms, $he_dimms, $h2_dimms)
if ($self->{runtime}->{options}->{verbose} >= 2);
foreach ($self->get_si_boards()) {
printf "SI%02d-> ", $_ if ($self->{runtime}->{options}->{verbose} >= 2);
foreach ($self->get_si_modules($_)) {
printf "%02d ", $_ if ($self->{runtime}->{options}->{verbose} >= 2);
}
printf "\n" if ($self->{runtime}->{options}->{verbose} >= 2);
}
foreach ($self->get_he_boards()) {
printf "HE%02d-> ", $_ if ($self->{runtime}->{options}->{verbose} >= 2);
foreach ($self->get_he_modules($_)) {
printf "%02d ", $_ if ($self->{runtime}->{options}->{verbose} >= 2);
}
printf "\n" if ($self->{runtime}->{options}->{verbose} >= 2);
}
foreach ($self->get_h2_boards()) {
printf "H2%02d-> ", $_ if ($self->{runtime}->{options}->{verbose} >= 2);
foreach ($self->get_h2_modules($_)) {
printf "%02d ", $_ if ($self->{runtime}->{options}->{verbose} >= 2);
}
printf "\n" if ($self->{runtime}->{options}->{verbose} >= 2);
}
if (($h2_dimms == 0) && ($he_dimms == 0) && ($si_dimms > 0)) {
printf "TYP1 %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
@{$self->{dimms}} = $self->update_si_with_si();
} elsif (($h2_dimms == 0) && ($he_dimms > 0) && ($si_dimms > 0)) {
printf "TYP2 %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
@{$self->{dimms}} = $self->update_si_with_he();
} elsif (($h2_dimms == 0) && ($he_dimms > 0) && ($si_dimms == 0)) {
printf "TYP3 %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
@{$self->{dimms}} = $self->update_he_with_he();
} elsif (($h2_dimms > 0) && ($he_dimms == 0) && ($si_dimms == 0)) {
printf "TYP4 %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
@{$self->{dimms}} = $self->update_h2_with_h2();
} elsif (($h2_dimms > 0) && ($he_dimms > 0) && ($si_dimms == 0)) {
printf "TYP5 %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
@{$self->{dimms}} = $self->update_he_with_h2();
} elsif (($h2_dimms > 0) && ($he_dimms == 0) && ($si_dimms > 0)) {
printf "TYP6 %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
@{$self->{dimms}} = $self->update_si_with_h2();
} elsif (($h2_dimms > 0) && ($he_dimms > 0) && ($si_dimms > 0)) {
if ($h2_dimms > $si_dimms) {
printf "TYP7 %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
@{$self->{dimms}} = $self->update_he_with_h2();
} else {
printf "TYP8 %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
@{$self->{dimms}} = $self->update_si_with_he();
}
} else {
printf "TYPX %s\n", $self->{runtime}->{product}
if ($self->{runtime}->{options}->{verbose} >= 2);
}
my $all_dimms = scalar(@{$self->{dimms}});
$self->trace(2, sprintf "ALL: %02d", $all_dimms);
}
sub dump {
my $self = shift;
if ($self->{runtime}->{options}->{verbose} > 2) {
printf "[SI]\n";
foreach (@{$self->{si_dimms}}) {
$_->dump();
}
printf "[HE]\n";
foreach (@{$self->{he_dimms}}) {
$_->dump();
}
printf "[H2]\n";
foreach (@{$self->{h2_dimms}}) {
$_->dump();
}
}
$self->SUPER::dump();
}
sub update_si_with_si {
my $self = shift;
my $snmpwalk = $self->{rawdata};
my @dimms = ();
my $repaircondition = undef;
# wenn si keine statusinformationen liefert, dann besteht die chance
# dass ein undokumentiertes he-fragment vorliegt
# 1.3.6.1.4.1.232.6.2.14.11.1.1.0.<anzahl der dimms>
my $cpqHeResMemModuleEntry = "1.3.6.1.4.1.232.6.2.14.11.1";
if (SNMP::Utils::get_size($snmpwalk, $cpqHeResMemModuleEntry) == 1) {
$repaircondition = lc SNMP::Utils::get_object(
$snmpwalk, $cpqHeResMemModuleEntry.'.1.0.'.scalar(@{$self->{si_dimms}}));
# repaircondition 0 (ok) biegt alles wieder gerade
} else {
# anderer versuch
if ($self->{si_overall_condition} &&
$self->{si_overall_condition} eq 'ok') {
$repaircondition = 0;
}
}
foreach my $si_dimm (@{$self->{si_dimms}}) {
if (($si_dimm->{condition} eq 'n/a') ||
($si_dimm->{condition} eq 'other')) {
$si_dimm->{condition} = 'ok' if
(defined $repaircondition && $repaircondition == 0);
}
push(@dimms,
HP::Proliant::Component::MemorySubsystem::Dimm->new(
runtime => $si_dimm->{runtime},
cartridge => $si_dimm->{cartridge},
module => $si_dimm->{module},
size => $si_dimm->{size},
status => $si_dimm->{status},
condition => $si_dimm->{condition},
));
}
return @dimms;
}
sub update_si_with_he {
my $self = shift;
my @dimms = ();
my $first_si_cartridge = ($self->get_si_boards())[0];
my $first_he_cartridge = ($self->get_he_boards())[0];
my $offset = 0;
if (scalar(@{$self->{si_dimms}}) == scalar(@{$self->{he_dimms}})) {
# aufpassen! sowas kann vorkommen: si cartridge 0...6, he cartridge 1...7
if ($first_si_cartridge != $first_he_cartridge) {
# README case 5
$offset = $first_si_cartridge - $first_he_cartridge;
}
} elsif ((scalar(@{$self->{si_dimms}}) > 1) &&
(scalar(@{$self->{he_dimms}}) == 1)) {
# siehe update_si_with_si. he-fragment
$self->update_si_with_si();
return;
} else {
# z.b. 4 si notpresent, 4 si present, 4 he
}
foreach my $si_dimm (@{$self->{si_dimms}}) {
if (($si_dimm->{condition} eq 'n/a') ||
($si_dimm->{condition} eq 'other')) {
if (my $he_dimm = $self->get_he_module(
$si_dimm->{cartridge} - $offset, $si_dimm->{module})) {
# vielleicht hat he mehr ahnung
$si_dimm->{condition} = $he_dimm->{condition};
if (($si_dimm->{condition} eq 'n/a') ||
($si_dimm->{condition} eq 'other')) {
# wenns immer noch kein brauchbares ergebnis gibt....
if ($self->{he_overall_condition} &&
$self->{he_overall_condition} eq 'ok') {
# wird schon stimmen...
$si_dimm->{condition} = 'ok';
} else {
# ansonsten stellen wir uns dumm
$si_dimm->{status} = 'notPresent';
}
}
} else {
# in dem fall zeigt si unbestueckte cartridges an
}
}
push(@dimms,
HP::Proliant::Component::MemorySubsystem::Dimm->new(
runtime => $si_dimm->{runtime},
cartridge => $si_dimm->{cartridge},
module => $si_dimm->{module},
size => $si_dimm->{size},
status => $si_dimm->{status},
condition => $si_dimm->{condition},
));
}
return @dimms;
}
sub update_he_with_he {
my $self = shift;
my @dimms = ();
foreach my $he_dimm (@{$self->{he_dimms}}) {
push(@dimms,
HP::Proliant::Component::MemorySubsystem::Dimm->new(
runtime => $he_dimm->{runtime},
cartridge => $he_dimm->{cartridge},
module => $he_dimm->{module},
size => $he_dimm->{size},
status => $he_dimm->{status},
condition => $he_dimm->{condition},
));
}
return @dimms;
}
sub update_si_with_h2 {
my $self = shift;
my @dimms = ();
my $first_si_cartridge = ($self->get_si_boards())[0];
my $first_h2_cartridge = ($self->get_h2_boards())[0];
my $offset = 0;
if (scalar(@{$self->{si_dimms}}) == scalar(@{$self->{h2_dimms}})) {
# aufpassen! sowas kann vorkommen: si cartridge 0...6, he cartridge 1...7
if ($first_si_cartridge != $first_h2_cartridge) {
# README case 5
$offset = $first_si_cartridge - $first_h2_cartridge;
}
} else {
# z.b. 4 si notpresent, 4 si present, 4 he
}
foreach my $si_dimm (@{$self->{si_dimms}}) {
if (($si_dimm->{condition} eq 'n/a') ||
($si_dimm->{condition} eq 'other')) {
if (my $h2_dimm = $self->get_h2_module(
$si_dimm->{cartridge} - $offset, $si_dimm->{module})) {
# vielleicht hat h2 mehr ahnung
$si_dimm->{condition} = $h2_dimm->{condition};
if (1) {
# ist zwar da, aber irgendwie auskonfiguriert
$si_dimm->{status} = 'notPresent' if $h2_dimm->{status} eq 'other';
}
} else {
# in dem fall zeigt si unbestueckte cartridges an
}
}
push(@dimms,
HP::Proliant::Component::MemorySubsystem::Dimm->new(
runtime => $si_dimm->{runtime},
cartridge => $si_dimm->{cartridge},
module => $si_dimm->{module},
size => $si_dimm->{size},
status => $si_dimm->{status},
condition => $si_dimm->{condition},
));
}
return @dimms;
}
sub update_he_with_h2 {
my $self = shift;
my @dimms = ();
my $first_he_cartridge = ($self->get_he_boards())[0];
my $first_h2_cartridge = ($self->get_h2_boards())[0];
my $offset = 0;
# auch hier koennte sowas u.u.vorkommen: he cartridge 0..6, h2 cartridge 1..7
# ich habs zwar nie gesehen, aber wer weiss...
if ($first_h2_cartridge != $first_he_cartridge) {
$offset = $first_h2_cartridge - $first_he_cartridge;
}
foreach my $he_dimm (@{$self->{he_dimms}}) {
if (($he_dimm->{condition} eq 'n/a') ||
($he_dimm->{condition} eq 'other')) {
if (my $h2_dimm = $self->get_h2_module(
$he_dimm->{cartridge} + $offset, $he_dimm->{module})) {
# vielleicht hat h2 mehr ahnung
$he_dimm->{condition} = $h2_dimm->{condition};
if (1) {
# ist zwar da, aber irgendwie auskonfiguriert
$he_dimm->{status} = 'notPresent' if $h2_dimm->{status} eq 'other';
}
} else {
# in dem fall weiss he mehr als h2
}
}
if ($he_dimm->{size} == 0) {
if (my $h2_dimm = $self->get_h2_module(
$he_dimm->{cartridge} + $offset, $he_dimm->{module})) {
$he_dimm->{size} = $h2_dimm->{size};
# h2 beinhaltet eine size-oid
}
}
push(@dimms,
HP::Proliant::Component::MemorySubsystem::Dimm->new(
runtime => $he_dimm->{runtime},
cartridge => $he_dimm->{cartridge},
module => $he_dimm->{module},
size => $he_dimm->{size},
status => $he_dimm->{status},
condition => $he_dimm->{condition},
));
}
return @dimms;
}
sub update_h2_with_h2 {
my $self = shift;
my @dimms = ();
foreach my $h2_dimm (@{$self->{h2_dimms}}) {
push(@dimms,
HP::Proliant::Component::MemorySubsystem::Dimm->new(
runtime => $h2_dimm->{runtime},
cartridge => $h2_dimm->{cartridge},
module => $h2_dimm->{module},
size => $h2_dimm->{size},
status => $h2_dimm->{status},
condition => $h2_dimm->{condition},
));
}
return @dimms;
}
sub is_faulty {
my $self = shift;
if (scalar(@{$self->{si_dimms}}) > 0 &&
scalar(@{$self->{he_dimms}}) > 0) {
return $self->si_is_faulty() || $self->he_is_faulty();
} elsif (scalar(@{$self->{si_dimms}}) > 0 &&
scalar(@{$self->{he_dimms}}) == 0) {
return $self->si_is_faulty();
} elsif (scalar(@{$self->{si_dimms}}) == 0 &&
scalar(@{$self->{he_dimms}}) > 0) {
return $self->he_is_faulty();
} else {
return 0;
}
}
sub si_is_faulty {
my $self = shift;
return ! defined $self->{si_overall_condition} ? 0 :
$self->{si_overall_condition} eq 'degraded' ? 1 : 0;
}
sub si_is_ok {
my $self = shift;
return ! defined $self->{si_overall_condition} ? 1 :
$self->{si_overall_condition} eq 'ok' ? 1 : 0;
}
sub he_is_faulty {
my $self = shift;
return ! defined $self->{he_overall_condition} ? 0 :
$self->{he_overall_condition} eq 'degraded' ? 1 : 0;
}
sub he_is_ok {
my $self = shift;
return ! defined $self->{he_overall_condition} ? 1 :
$self->{he_overall_condition} eq 'ok' ? 1 : 0;
}
sub get_si_boards {
my $self = shift;
my %found = ();
foreach (@{$self->{si_dimms}}) {
$found{$_->{cartridge}} = 1;
}
return sort { $a <=> $b } keys %found;
}
sub get_si_modules {
my $self = shift;
my $board = shift;
my %found = ();
foreach (grep { $_->{cartridge} == $board } @{$self->{si_dimms}}) {
$found{$_->{module}} = 1;
}
return sort { $a <=> $b } keys %found;
}
sub get_he_boards {
my $self = shift;
my %found = ();
foreach (@{$self->{he_dimms}}) {
$found{$_->{cartridge}} = 1;
}
return sort { $a <=> $b } keys %found;
}
sub get_he_modules {
my $self = shift;
my $board = shift;
my %found = ();
foreach (grep { $_->{cartridge} == $board } @{$self->{he_dimms}}) {
$found{$_->{module}} = 1;
}
return sort { $a <=> $b } keys %found;
}
sub get_he_module {
my $self = shift;
my $board = shift;
my $module = shift;
my $found = (grep { $_->{cartridge} == $board && $_->{module} == $module }
@{$self->{he_dimms}})[0];
return $found;
}
sub get_h2_boards {
my $self = shift;
my %found = ();
#
foreach (@{$self->{h2_dimms}}) {
$found{$_->{cartridge}} = 1;
}
return sort { $a <=> $b } keys %found;
}
sub get_h2_modules {
my $self = shift;
my $board = shift;
my %found = ();
foreach (grep { $_->{cartridge} == $board } @{$self->{h2_dimms}}) {
$found{$_->{module}} = 1;
}
return sort { $a <=> $b } keys %found;
}
sub get_h2_module {
my $self = shift;
my $board = shift;
my $module = shift;
my $found = (grep { $_->{cartridge} == $board && $_->{module} == $module }
@{$self->{h2_dimms}})[0];
return $found;
}
package HP::Proliant::Component::MemorySubsystem;
our @ISA = qw(HP::Proliant::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
condition => $params{condition},
status => $params{status},
blacklisted => 0,
info => undef,
extendedinfo => undef,
dimms => [],
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
return HP::Proliant::Component::MemorySubsystem::SNMP->new(%params);
} elsif ($self->{method} eq 'cli') {
return HP::Proliant::Component::MemorySubsystem::CLI->new(%params);
} else {
die "unknown method";
}
}
sub check {
my $self = shift;
my $errorfound = 0;
$self->add_info('checking memory');
foreach (@{$self->{dimms}}) {
$_->check(); # info ausfuellen
}
if ((scalar(grep {
$_->is_present() &&
($_->{condition} ne 'n/a' && $_->{condition} ne 'other' )
} @{$self->{dimms}})) != 0) {
foreach (@{$self->{dimms}}) {
if (($_->is_present()) && ($_->{condition} ne 'ok')) {
$_->add_message(CRITICAL, $_->{info});
$errorfound++;
}
}
} else {
if ($self->{runtime}->{options}->{ignore_dimms}) {
$self->add_message(OK,
sprintf "ignoring %d dimms with status 'n/a' ",
scalar(grep { ($_->is_present()) } @{$self->{dimms}}));
} elsif ($self->{runtime}->{options}->{buggy_firmware}) {
$self->add_message(OK,
sprintf "ignoring %d dimms with status 'n/a' because of buggy firmware",
scalar(grep { ($_->is_present()) } @{$self->{dimms}}));
} else {
$self->add_message(WARNING,
sprintf "status of all %d dimms is n/a (please upgrade firmware)",
scalar(grep { $_->is_present() } @{$self->{dimms}}));
$errorfound++;
}
}
foreach (@{$self->{dimms}}) {
printf "%s\n", $_->{info} if $self->{runtime}->{options}->{verbose} >= 2;
}
if (! $errorfound && $self->is_faulty()) {
#if ($self->is_faulty()) {
$self->add_message(WARNING,
sprintf 'overall memory error found');
}
}
sub dump {
my $self = shift;
printf "i dump the memory\n";
foreach (@{$self->{dimms}}) {
$_->dump();
}
}
package HP::Proliant::Component::MemorySubsystem::Dimm;
our @ISA = qw(HP::Proliant::Component::MemorySubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cartridge => $params{cartridge},
module => $params{module},
size => $params{size} || 0,
status => $params{status},
condition => $params{condition},
type => $params{type},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->{name} = sprintf '%s:%s',
$self->{cartridge}, $self->{module};
$self->{location} = sprintf 'module %s @ cartridge %s',
$self->{module}, $self->{cartridge};
return $self;
}
sub check {
my $self = shift;
# check dient nur dazu, info und extended_info zu f<>llen
# die eigentliche bewertung findet eins h<>her statt
$self->blacklist('d', $self->{name});
if (($self->{status} eq 'present') || ($self->{status} eq 'good')) {
if ($self->{condition} eq 'other') {
$self->add_info(sprintf 'dimm %s (%s) is n/a',
$self->{name}, $self->{location});
} elsif ($self->{condition} ne 'ok') {
$self->add_info(
sprintf "dimm module %s (%s) needs attention (%s)",
$self->{name}, $self->{location}, $self->{condition});
} else {
$self->add_info(sprintf 'dimm module %s (%s) is %s',
$self->{name}, $self->{location}, $self->{condition});
}
} elsif ($self->{status} eq 'notPresent') {
$self->add_info(sprintf 'dimm module %s (%s) is not present',
$self->{name}, $self->{location});
} else {
$self->add_info(
sprintf "dimm module %s (%s) needs attention (%s)",
$self->{name}, $self->{location}, $self->{condition});
}
}
sub is_present {
my $self = shift;
my @signs_of_presence = (qw(present good add upgraded doesnotmatch
notsupported badconfig degraded));
return scalar(grep { $self->{status} eq $_ } @signs_of_presence);
}
sub dump {
my $self = shift;
#printf "[DIMM_%s_%s]\n", $self->{cartridge}, $self->{module};
#foreach (qw(cartridge module size status condition info)) {
# printf "%s: %s\n", $_, $self->{$_};
#}
#printf "status: %s\n", $self->{status} if exists $self->{status};
#printf "\n";
printf "car %02d mod %02d siz %.0f sta %-12s con %-10s typ %s\n",
$self->{cartridge}, $self->{module}, $self->{size},
$self->{status}, $self->{condition}, defined $self->{type} ? $self->{type} : "";
}
package HP::Proliant::Component::MemorySubsystem::Cartridge;
our @ISA = qw(HP::Proliant::Component::MemorySubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
cpqHeResMemBoardSlotIndex => $params{cpqHeResMemBoardSlotIndex},
cpqHeResMemBoardOnlineStatus => $params{cpqHeResMemBoardOnlineStatus},
cpqHeResMemBoardErrorStatus => $params{cpqHeResMemBoardErrorStatus},
cpqHeResMemBoardNumSockets => $params{cpqHeResMemBoardNumSockets},
cpqHeResMemBoardOsMemSize => $params{cpqHeResMemBoardOsMemSize},
cpqHeResMemBoardTotalMemSize => $params{cpqHeResMemBoardTotalMemSize},
cpqHeResMemBoardCondition => $params{cpqHeResMemBoardCondition},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
return $self;
}
sub dump {
my $self = shift;
#printf "[CARTRIDGE_%s_%s]\n", $self->{cpqHeResMemBoardSlotIndex};
#foreach (qw(cpqHeResMemBoardSlotIndex cpqHeResMemBoardOnlineStatus
# cpqHeResMemBoardErrorStatus cpqHeResMemBoardNumSockets
# cpqHeResMemBoardOsMemSize cpqHeResMemBoardTotalMemSize
# cpqHeResMemBoardCondition)) {
# printf "%s: %s\n", $_, $self->{$_};
#}
#printf "\n";
}
package HP::Proliant::Component::SNMP;
sub get_entries {
my $self = shift;
my $oids = shift;
my $entry = shift;
my $snmpwalk = $self->{rawdata};
my @params = ();
my @indices = SNMP::Utils::get_indices($snmpwalk, $oids->{$entry});
foreach (@indices) {
my @idx = @{$_};
my %params = (
runtime => $self->{runtime},
);
my $maxdimension = scalar(@idx) - 1;
foreach my $idxnr (1..scalar(@idx)) {
$params{'index'.$idxnr} = $_->[$idxnr - 1];
}
foreach my $oid (keys %{$oids}) {
next if $oid =~ /Entry$/;
next if $oid =~ /Value$/;
if (exists $oids->{$oid.'Value'}) {
$params{$oid} = SNMP::Utils::get_object_value(
$snmpwalk, $oids->{$oid}, $oids->{$oid.'Value'}, @idx);
if (! defined $params{$oid}) {
my $numerical_value = SNMP::Utils::get_object(
$snmpwalk, $oids->{$oid}, @idx);
if (! defined $numerical_value) {
# maschine liefert schrott
$params{$oid} = 'value_unknown';
} else {
$params{$oid} = 'value_'.SNMP::Utils::get_object(
$snmpwalk, $oids->{$oid}, @idx);
}
}
} else {
$params{$oid} = SNMP::Utils::get_object(
$snmpwalk, $oids->{$oid}, @idx);
}
}
push(@params, \%params);
}
return @params;
}
sub mib {
my $self = shift;
my $mib = shift;
my $condition = {
0 => 'other',
1 => 'ok',
2 => 'degraded',
3 => 'failed',
};
my $MibRevMajor = $mib.'.1.0';
my $MibRevMinor = $mib.'.2.0';
my $MibRevCondition = $mib.'.3.0';
return (
$self->SNMP::Utils::get_object($self->{rawdata},
$MibRevMajor),
$self->SNMP::Utils::get_object($self->{rawdata},
$MibRevMinor),
$self->SNMP::Utils::get_object_value($self->{rawdata},
$MibRevCondition, $condition));
};
package HP::Proliant::Component::DiskSubsystem::Da::CLI;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Da);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
my $hpacucli = $self->{rawdata};
my $slot = 0;
my $type = "unkn";
my @lines = ();
my $thistype = 0;
my $tmpcntl = {};
my $tmpaccel = {};
my $tmpld = {};
my $tmppd = {};
my $cntlindex = 0;
my $ldriveindex = 0;
my $pdriveindex = 0;
my $incontroller = 0;
foreach (split(/\n/, $hpacucli)) {
next unless /^status/;
next if /^status\s*$/;
s/^status\s*//;
if (/([\s\w]+) in Slot\s+(\d+)/) {
$incontroller = 1;
$slot = $2;
$cntlindex++;
$tmpcntl->{$slot}->{cpqDaCntlrIndex} = $cntlindex;
$tmpcntl->{$slot}->{cpqDaCntlrModel} = $1;
$tmpcntl->{$slot}->{cpqDaCntlrSlot} = $slot;
} elsif (/Controller Status: (\w+)/) {
$tmpcntl->{$slot}->{cpqDaCntlrBoardCondition} = lc $1;
$tmpcntl->{$slot}->{cpqDaCntlrCondition} = lc $1;
} elsif (/Cache Status: (\w+)/) {
$tmpaccel->{$slot}->{cpqDaAccelCntlrIndex} = $cntlindex;
$tmpaccel->{$slot}->{cpqDaAccelSlot} = $slot;
$tmpaccel->{$slot}->{cpqDaAccelCondition} = lc $1;
$tmpaccel->{$slot}->{cpqDaAccelStatus} = 'enabled';
} elsif (/Battery.* Status: (\w+)/) {
# sowas gibts auch Battery/Capacitor Status: OK
$tmpaccel->{$slot}->{cpqDaAccelBattery} = lc $1;
} elsif (/^\s*$/) {
}
}
$cntlindex = 0;
$ldriveindex = 0;
$pdriveindex = 0;
foreach (split(/\n/, $hpacucli)) {
next unless /^config/;
next if /^config\s*$/;
s/^config\s*//;
if (/([\s\w]+) in Slot\s+(\d+)/) {
$slot = $2;
$cntlindex++;
$pdriveindex = 1;
} elsif (/logicaldrive\s+(.+?)\s+\((.*)\)/) {
# logicaldrive 1 (683.5 GB, RAID 5, OK)
# logicaldrive 1 (683.5 GB, RAID 5, OK)
# logicaldrive 2 (442 MB, RAID 1+0, OK)
$ldriveindex = $1;
$tmpld->{$slot}->{$ldriveindex}->{cpqDaLogDrvCntlrIndex} = $cntlindex;
$tmpld->{$slot}->{$ldriveindex}->{cpqDaLogDrvIndex} = $ldriveindex;
($tmpld->{$slot}->{$ldriveindex}->{cpqDaLogDrvSize},
$tmpld->{$slot}->{$ldriveindex}->{cpqDaLogDrvFaultTol},
$tmpld->{$slot}->{$ldriveindex}->{cpqDaLogDrvCondition}) =
map { lc $_ } split(/,\s*/, $2);
$tmpld->{$slot}->{$ldriveindex}->{cpqDaLogDrvStatus} =
$tmpld->{$slot}->{$ldriveindex}->{cpqDaLogDrvCondition};
$tmpld->{$slot}->{$ldriveindex}->{cpqDaLogDrvPhyDrvIDs} = 'unknown';
} elsif (/physicaldrive\s+(.+?)\s+\((.*)\)/) {
# physicaldrive 2:0 (port 2:id 0 , Parallel SCSI, 36.4 GB, OK)
# physicaldrive 2I:1:6 (port 2I:box 1:bay 6, SAS, 146 GB, OK)
my $name = $1;
my($location, $type, $size, $status) = split(/,/, $2);
$status =~ s/^\s+//g;
$status =~ s/\s+$//g;
$status = lc $status;
my %location = ();
foreach (split(/:/, $location)) {
$location{$1} = $2 if /(\w+)\s+(\w+)/;
}
$location{box} ||= 0;
$location{id} ||= $pdriveindex;
$location{bay} ||= $location{id};
$tmppd->{$slot}->{$name}->{name} = lc $name;
$tmppd->{$slot}->{$name}->{cpqDaPhyDrvCntlrIndex} = $cntlindex;
$tmppd->{$slot}->{$name}->{cpqDaPhyDrvIndex} = $location{id};
$tmppd->{$slot}->{$name}->{cpqDaPhyDrvBay} = $location{bay};
$tmppd->{$slot}->{$name}->{cpqDaPhyDrvBusNumber} = $location{port};
$tmppd->{$slot}->{$name}->{cpqDaPhyDrvSize} = $size;
$tmppd->{$slot}->{$name}->{cpqDaPhyDrvStatus} = $status;
$tmppd->{$slot}->{$name}->{cpqDaPhyDrvCondition} = $status;
$tmppd->{$slot}->{$name}->{ldriveindex} = $ldriveindex || -1;
foreach (keys %{$tmppd->{$slot}->{$name}}) {
$tmppd->{$slot}->{$name}->{$_} =~ s/^\s+//g;
$tmppd->{$slot}->{$name}->{$_} =~ s/\s+$//g;
$tmppd->{$slot}->{$name}->{$_} = lc $tmppd->{$slot}->{$name}->{$_};
}
}
}
foreach my $slot (keys %{$tmpcntl}) {
if (exists $tmpcntl->{$slot}->{cpqDaCntlrModel} &&
! $self->identified($tmpcntl->{$slot}->{cpqDaCntlrModel})) {
delete $tmpcntl->{$slot};
delete $tmpaccel->{$slot};
delete $tmpld->{$slot};
delete $tmppd->{$slot};
}
}
#printf "%s\n", Data::Dumper::Dumper($tmpcntl);
#printf "%s\n", Data::Dumper::Dumper($tmpaccel);
#printf "%s\n", Data::Dumper::Dumper($tmpld);
#printf "%s\n", Data::Dumper::Dumper($tmppd);
foreach my $slot (sort {
$tmpcntl->{$a}->{cpqDaCntlrIndex} <=> $tmpcntl->{$b}->{cpqDaCntlrIndex}
}keys %{$tmpcntl}) {
$tmpcntl->{$slot}->{runtime} = $self->{runtime};
push(@{$self->{controllers}},
HP::Proliant::Component::DiskSubsystem::Da::Controller->new(
%{$tmpcntl->{$slot}}));
}
foreach my $slot (sort {
$tmpaccel->{$a}->{cpqDaAccelCntlrIndex} <=> $tmpaccel->{$b}->{cpqDaAccelCntlrIndex}
} keys %{$tmpaccel}) {
$tmpaccel->{$slot}->{runtime} = $self->{runtime};
push(@{$self->{accelerators}},
HP::Proliant::Component::DiskSubsystem::Da::Accelerator->new(
%{$tmpaccel->{$slot}}));
}
foreach my $slot (keys %{$tmpld}) {
foreach my $ldriveindex (keys %{$tmpld->{$slot}}) {
$tmpld->{$slot}->{$ldriveindex}->{runtime} = $self->{runtime};
push(@{$self->{logical_drives}},
HP::Proliant::Component::DiskSubsystem::Da::LogicalDrive->new(
%{$tmpld->{$slot}->{$ldriveindex}}));
}
foreach my $pdriveindex (sort {
(split ':', $a, 2)[0] cmp (split ':', $b, 2)[0] ||
(split ':', $a, 2)[1] cmp (split ':', $b, 2)[1] ||
(split ':', $a, 2)[2] <=> (split ':', $b, 2)[2]
} keys %{$tmppd->{$slot}}) {
$tmppd->{$slot}->{$pdriveindex}->{runtime} = $self->{runtime};
push(@{$self->{physical_drives}},
HP::Proliant::Component::DiskSubsystem::Da::PhysicalDrive->new(
%{$tmppd->{$slot}->{$pdriveindex}}));
}
}
}
sub identified {
my $self = shift;
my $info = shift;
return 1 if $info =~ /Parallel SCSI/;
return 1 if $info =~ /Smart Array/; # Trond: works fine on E200i, P400, E400
#return 1 if $info =~ /Smart Array (5|6)/;
#return 1 if $info =~ /Smart Array P400i/; # snmp sagt Da, trotz SAS in cli
#return 1 if $info =~ /Smart Array P410i/; # dto
return 0;
}
package HP::Proliant::Component::DiskSubsystem::Da::SNMP;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Da
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
# CPQIDA-MIB
my $oids = {
cpqDaCntlrEntry => "1.3.6.1.4.1.232.3.2.2.1.1",
cpqDaCntlrIndex => "1.3.6.1.4.1.232.3.2.2.1.1.1",
cpqDaCntlrModel => "1.3.6.1.4.1.232.3.2.2.1.1.2",
cpqDaCntlrSlot => "1.3.6.1.4.1.232.3.2.2.1.1.5",
cpqDaCntlrCondition => "1.3.6.1.4.1.232.3.2.2.1.1.6",
cpqDaCntlrBoardCondition => "1.3.6.1.4.1.232.3.2.2.1.1.12",
cpqDaCntlrModelValue => {
1 => 'other',
2 => 'ida',
3 => 'idaExpansion',
4 => 'ida-2',
5 => 'smart',
6 => 'smart-2e',
7 => 'smart-2p',
8 => 'smart-2sl',
9 => 'smart-3100es',
10 => 'smart-3200',
11 => 'smart-2dh',
12 => 'smart-221',
13 => 'sa-4250es',
14 => 'sa-4200',
15 => 'sa-integrated',
16 => 'sa-431',
17 => 'sa-5300',
18 => 'raidLc2',
19 => 'sa-5i',
20 => 'sa-532',
21 => 'sa-5312',
22 => 'sa-641',
23 => 'sa-642',
24 => 'sa-6400',
25 => 'sa-6400em',
26 => 'sa-6i',
},
cpqDaCntlrConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqDaCntlrBoardConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
};
# INDEX { cpqDaCntlrIndex }
foreach ($self->get_entries($oids, 'cpqDaCntlrEntry')) {
push(@{$self->{controllers}},
HP::Proliant::Component::DiskSubsystem::Da::Controller->new(%{$_}));
}
$oids = {
cpqDaAccelEntry => "1.3.6.1.4.1.232.3.2.2.2.1",
cpqDaAccelCntlrIndex => "1.3.6.1.4.1.232.3.2.2.2.1.1",
cpqDaAccelStatus => "1.3.6.1.4.1.232.3.2.2.2.1.2",
cpqDaAccelSlot => "1.3.6.1.4.1.232.3.2.2.2.1.5",
cpqDaAccelBattery => "1.3.6.1.4.1.232.3.2.2.2.1.6",
cpqDaAccelCondition => "1.3.6.1.4.1.232.3.2.2.2.1.9",
cpqDaAccelBatteryValue => {
1 => 'other',
2 => 'ok',
3 => 'recharging',
4 => 'failed',
5 => 'degraded',
6 => 'notPresent',
},
cpqDaAccelConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqDaAccelStatusValue => {
1 => "other",
2 => "invalid",
3 => "enabled",
4 => "tmpDisabled",
5 => "permDisabled",
}
};
# INDEX { cpqDaAccelCntlrIndex }
foreach ($self->get_entries($oids, 'cpqDaAccelEntry')) {
push(@{$self->{accelerators}},
HP::Proliant::Component::DiskSubsystem::Da::Accelerator->new(%{$_}));
}
$oids = {
cpqDaLogDrvEntry => "1.3.6.1.4.1.232.3.2.3.1.1",
cpqDaLogDrvCntlrIndex => "1.3.6.1.4.1.232.3.2.3.1.1.1",
cpqDaLogDrvIndex => "1.3.6.1.4.1.232.3.2.3.1.1.2",
cpqDaLogDrvFaultTol => "1.3.6.1.4.1.232.3.2.3.1.1.3",
cpqDaLogDrvStatus => "1.3.6.1.4.1.232.3.2.3.1.1.4",
cpqDaLogDrvSize => "1.3.6.1.4.1.232.3.2.3.1.1.9",
cpqDaLogDrvPhyDrvIDs => "1.3.6.1.4.1.232.3.2.3.1.1.10",
cpqDaLogDrvCondition => "1.3.6.1.4.1.232.3.2.3.1.1.11",
cpqDaLogDrvPercentRebuild => "1.3.6.1.4.1.232.3.2.3.1.1.12",
cpqDaLogDrvFaultTolValue => {
1 => "other",
2 => "none",
3 => "mirroring",
4 => "dataGuard",
5 => "distribDataGuard",
7 => "advancedDataGuard",
},
cpqDaLogDrvConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqDaLogDrvStatusValue => {
1 => "other",
2 => "ok",
3 => "failed",
4 => "unconfigured",
5 => "recovering",
6 => "readyForRebuild",
7 => "rebuilding",
8 => "wrongDrive",
9 => "badConnect",
10 => "overheating",
11 => "shutdown",
12 => "expanding",
13 => "notAvailable",
14 => "queuedForExpansion",
},
};
# INDEX { cpqDaLogDrvCntlrIndex, cpqDaLogDrvIndex }
foreach ($self->get_entries($oids, 'cpqDaLogDrvEntry')) {
$_->{cpqDaLogDrvPhyDrvIDs} ||= 'empty';
push(@{$self->{logical_drives}},
HP::Proliant::Component::DiskSubsystem::Da::LogicalDrive->new(%{$_}));
}
$oids = {
cpqDaPhyDrvEntry => "1.3.6.1.4.1.232.3.2.5.1.1",
cpqDaPhyDrvCntlrIndex => "1.3.6.1.4.1.232.3.2.5.1.1.1",
cpqDaPhyDrvIndex => "1.3.6.1.4.1.232.3.2.5.1.1.2",
cpqDaPhyDrvBay => "1.3.6.1.4.1.232.3.2.5.1.1.5",
cpqDaPhyDrvStatus => "1.3.6.1.4.1.232.3.2.5.1.1.6",
cpqDaPhyDrvSize => "1.3.6.1.4.1.232.3.2.5.1.1.9",
cpqDaPhyDrvCondition => "1.3.6.1.4.1.232.3.2.5.1.1.37",
cpqDaPhyDrvBusNumber => "1.3.6.1.4.1.232.3.2.5.1.1.50",
cpqDaPhyDrvConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqDaPhyDrvStatusValue => {
1 => "other",
2 => "ok",
3 => "failed",
4 => "predictiveFailure",
},
};
# INDEX { cpqDaPhyDrvCntlrIndex, cpqDaPhyDrvIndex }
foreach ($self->get_entries($oids, 'cpqDaPhyDrvEntry')) {
push(@{$self->{physical_drives}},
HP::Proliant::Component::DiskSubsystem::Da::PhysicalDrive->new(%{$_}));
}
}
package HP::Proliant::Component::DiskSubsystem::Da;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
condition => undef,
blacklisted => 0,
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Da::SNMP';
} else {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Da::CLI';
}
$self->init();
$self->assemble();
return $self;
}
sub check {
my $self = shift;
foreach (@{$self->{controllers}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{controllers}}) {
$_->dump();
}
}
package HP::Proliant::Component::DiskSubsystem::Da::Controller;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Da);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqDaCntlrIndex => $params{cpqDaCntlrIndex},
cpqDaCntlrSlot => $params{cpqDaCntlrSlot},
cpqDaCntlrModel => $params{cpqDaCntlrModel},
cpqDaCntlrCondition => $params{cpqDaCntlrCondition},
cpqDaCntlrBoardCondition => $params{cpqDaCntlrBoardCondition},
blacklisted => 0,
};
$self->{name} = $params{name} || $self->{cpqDaCntlrSlot};
$self->{controllerindex} = $self->{cpqDaCntlrIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
#$self->dumper($self);
$self->blacklist('daco', $self->{cpqDaCntlrIndex});
if ($self->{cpqDaCntlrCondition} eq 'other') {
if (scalar(@{$self->{physical_drives}})) {
$self->add_message(CRITICAL,
sprintf 'da controller %s in slot %s needs attention',
$self->{cpqDaCntlrIndex}, $self->{cpqDaCntlrSlot});
$self->add_info(sprintf 'da controller %s in slot %s needs attention',
$self->{cpqDaCntlrIndex}, $self->{cpqDaCntlrSlot});
} else {
$self->add_info(sprintf 'da controller %s in slot %s is ok and unused',
$self->{cpqDaCntlrIndex}, $self->{cpqDaCntlrSlot});
$self->{blacklisted} = 1;
}
} elsif ($self->{cpqDaCntlrCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'da controller %s in slot %s needs attention',
$self->{cpqDaCntlrIndex}, $self->{cpqDaCntlrSlot});
$self->add_info(sprintf 'da controller %s in slot %s needs attention',
$self->{cpqDaCntlrIndex}, $self->{cpqDaCntlrSlot});
} else {
$self->add_info(sprintf 'da controller %s in slot %s is ok',
$self->{cpqDaCntlrIndex}, $self->{cpqDaCntlrSlot});
}
foreach (@{$self->{accelerators}}) {
$_->check();
}
foreach (@{$self->{logical_drives}}) {
$_->check();
}
foreach (@{$self->{physical_drives}}) {
$_->check();
}
foreach (@{$self->{spare_drives}}) {
$_->check();
}
}
sub dump {
my $self = shift;
printf "[DA_CONTROLLER_%s]\n", $self->{name};
foreach (qw(cpqDaCntlrSlot cpqDaCntlrIndex cpqDaCntlrCondition
cpqDaCntlrModel)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
foreach (@{$self->{accelerators}}) {
$_->dump();
}
foreach (@{$self->{logical_drives}}) {
$_->dump();
}
foreach (@{$self->{physical_drives}}) {
$_->dump();
}
foreach (@{$self->{spare_drives}}) {
$_->dump();
}
}
package HP::Proliant::Component::DiskSubsystem::Da::Accelerator;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Da);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqDaAccelCntlrIndex => $params{cpqDaAccelCntlrIndex},
cpqDaAccelBattery => $params{cpqDaAccelBattery} || 'notPresent',
cpqDaAccelCondition => $params{cpqDaAccelCondition},
cpqDaAccelStatus => $params{cpqDaAccelStatus},
blacklisted => 0,
};
$self->{controllerindex} = $self->{cpqDaAccelCntlrIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('daac', $self->{cpqDaAccelCntlrIndex});
$self->add_info(sprintf 'controller accelerator is %s',
$self->{cpqDaAccelCondition});
if ($self->{cpqDaAccelStatus} ne "enabled") {
} elsif ($self->{cpqDaAccelCondition} ne "ok") {
$self->add_message(CRITICAL, "controller accelerator needs attention");
}
$self->blacklist('daacb', $self->{cpqDaAccelCntlrIndex});
$self->add_info(sprintf 'controller accelerator battery is %s',
$self->{cpqDaAccelBattery});
if ($self->{cpqDaAccelBattery} eq "notPresent") {
} elsif ($self->{cpqDaAccelBattery} eq "recharging") {
$self->add_message(WARNING, "controller accelerator battery recharging");
} elsif ($self->{cpqDaAccelBattery} ne "ok") {
# (other) failed degraded
$self->add_message(CRITICAL, "controller accelerator battery needs attention");
}
}
sub dump {
my $self = shift;
printf "[ACCELERATOR]\n";
foreach (qw(cpqDaAccelCntlrIndex cpqDaAccelBattery
cpqDaAccelStatus cpqDaAccelCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Da::LogicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Da);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqDaLogDrvIndex => $params{cpqDaLogDrvIndex},
cpqDaLogDrvCntlrIndex => $params{cpqDaLogDrvCntlrIndex},
cpqDaLogDrvSize => $params{cpqDaLogDrvSize},
cpqDaLogDrvFaultTol => $params{cpqDaLogDrvFaultTol},
cpqDaLogDrvPercentRebuild => $params{cpqDaLogDrvPercentRebuild},
cpqDaLogDrvStatus => $params{cpqDaLogDrvStatus},
cpqDaLogDrvCondition => $params{cpqDaLogDrvCondition},
cpqDaLogDrvPhyDrvIDs => $params{cpqDaLogDrvPhyDrvIDs},
blacklisted => 0,
};
bless $self, $class;
$self->{name} = $params{name} ||
$self->{cpqDaLogDrvCntlrIndex}.':'.$self->{cpqDaLogDrvIndex}; ##vorerst
$self->{controllerindex} = $self->{cpqDaLogDrvCntlrIndex};
if (! $self->{cpqDaLogDrvPercentRebuild} ||
$self->{cpqDaLogDrvPercentRebuild} == 4294967295) {
$self->{cpqDaLogDrvPercentRebuild} = 100;
}
return $self;
}
sub check {
my $self = shift;
$self->blacklist('dald', $self->{name});
$self->add_info(sprintf "logical drive %s is %s (%s)",
$self->{name}, $self->{cpqDaLogDrvStatus},
$self->{cpqDaLogDrvFaultTol});
if ($self->{cpqDaLogDrvCondition} ne "ok") {
if ($self->{cpqDaLogDrvStatus} =~
/rebuild|recovering|expanding|queued/) {
$self->add_message(WARNING,
sprintf "logical drive %s is %s",
$self->{name}, $self->{cpqDaLogDrvStatus});
} else {
$self->add_message(CRITICAL,
sprintf "logical drive %s is %s",
$self->{name}, $self->{cpqDaLogDrvStatus});
}
}
}
sub dump {
my $self = shift;
printf "[LOGICAL_DRIVE]\n";
foreach (qw(cpqDaLogDrvCntlrIndex cpqDaLogDrvIndex cpqDaLogDrvSize
cpqDaLogDrvFaultTol cpqDaLogDrvStatus cpqDaLogDrvCondition
cpqDaLogDrvPercentRebuild cpqDaLogDrvPhyDrvIDs)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Da::PhysicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Da);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
name => $params{name},
cpqDaPhyDrvCntlrIndex => $params{cpqDaPhyDrvCntlrIndex},
cpqDaPhyDrvIndex => $params{cpqDaPhyDrvIndex},
cpqDaPhyDrvBay => $params{cpqDaPhyDrvBay},
cpqDaPhyDrvBusNumber => $params{cpqDaPhyDrvBusNumber},
cpqDaPhyDrvSize => $params{cpqDaPhyDrvSize},
cpqDaPhyDrvStatus => $params{cpqDaPhyDrvStatus},
cpqDaPhyDrvCondition => $params{cpqDaPhyDrvCondition},
blacklisted => 0,
};
bless $self, $class;
$self->{name} = $params{name} ||
$self->{cpqDaPhyDrvCntlrIndex}.':'.$self->{cpqDaPhyDrvIndex}; ##vorerst
$self->{controllerindex} = $self->{cpqDaPhyDrvCntlrIndex};
return $self;
}
sub check {
my $self = shift;
$self->blacklist('dapd', $self->{name});
$self->add_info(
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqDaPhyDrvCondition});
if ($self->{cpqDaPhyDrvCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqDaPhyDrvCondition});
}
}
sub dump {
my $self = shift;
printf "[PHYSICAL_DRIVE]\n";
foreach (qw(cpqDaPhyDrvCntlrIndex cpqDaPhyDrvIndex cpqDaPhyDrvBay
cpqDaPhyDrvBusNumber cpqDaPhyDrvSize cpqDaPhyDrvStatus
cpqDaPhyDrvCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Da::SpareDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Da);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub dump {
my $self = shift;
printf "[LOGICAL_DRIVE]\n";
foreach (qw(cntrlcpqDaCntlrIndex cpqDaCntlrIndex size level status condition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Sas::CLI;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Sas);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
}
package HP::Proliant::Component::DiskSubsystem::Sas::SNMP;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Sas
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
# CPQSCSI-MIB
my $oids = {
cpqSasHbaEntry => "1.3.6.1.4.1.232.5.5.1.1.1",
cpqSasHbaIndex => "1.3.6.1.4.1.232.5.5.1.1.1.1",
cpqSasHbaLocation => "1.3.6.1.4.1.232.5.5.1.1.1.2",
cpqSasHbaSlot => "1.3.6.1.4.1.232.5.5.1.1.1.6",
cpqSasHbaStatus => "1.3.6.1.4.1.232.5.5.1.1.1.4",
cpqSasHbaStatusValue => {
1 => "other",
2 => "ok",
3 => "failed",
},
cpqSasHbaCondition => "1.3.6.1.4.1.232.5.5.1.1.1.5",
cpqSasHbaConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
};
# INDEX { cpqSasHbaIndex }
foreach ($self->get_entries($oids, 'cpqSasHbaEntry')) {
push(@{$self->{controllers}},
HP::Proliant::Component::DiskSubsystem::Sas::Controller->new(%{$_}));
}
$oids = {
cpqSasLogDrvEntry => "1.3.6.1.4.1.232.5.5.3.1.1",
cpqSasLogDrvHbaIndex => "1.3.6.1.4.1.232.5.5.3.1.1.1",
cpqSasLogDrvIndex => "1.3.6.1.4.1.232.5.5.3.1.1.2",
cpqSasLogDrvStatus => "1.3.6.1.4.1.232.5.5.3.1.1.4",
cpqSasLogDrvCondition => "1.3.6.1.4.1.232.5.5.3.1.1.5",
cpqSasLogDrvRebuildingPercent => "1.3.6.1.4.1.232.5.5.3.1.1.12",
cpqSasLogDrvRaidLevel => "1.3.6.1.4.1.232.5.5.3.1.1.3",
cpqSasLogDrvRaidLevelValue => {
1 => "other",
2 => "raid0",
3 => "raid1",
4 => "raid0plus1",
5 => "raid5",
6 => "raid15",
7 => "volume",
},
cpqSasLogDrvConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqSasLogDrvStatusValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "rebuilding",
5 => "failed",
6 => "offline",
}
};
# INDEX { cpqSasLogDrvCntlrIndex, cpqSasLogDrvIndex }
foreach ($self->get_entries($oids, 'cpqSasLogDrvEntry')) {
push(@{$self->{logical_drives}},
HP::Proliant::Component::DiskSubsystem::Sas::LogicalDrive->new(%{$_}));
}
$oids = {
cpqSasPhyDrvEntry => "1.3.6.1.4.1.232.5.5.2.1.1",
cpqSasPhyDrvHbaIndex => "1.3.6.1.4.1.232.5.5.2.1.1.1",
cpqSasPhyDrvIndex => "1.3.6.1.4.1.232.5.5.2.1.1.2",
cpqSasPhyDrvLocationString => "1.3.6.1.4.1.232.5.5.2.1.1.3",
cpqSasPhyDrvStatus => "1.3.6.1.4.1.232.5.5.2.1.1.5",
cpqSasPhyDrvSize => "1.3.6.1.4.1.232.5.5.2.1.1.8",
cpqSasPhyDrvCondition => "1.3.6.1.4.1.232.5.5.2.1.1.6",
cpqSasPhyDrvConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqSasPhyDrvStatusValue => {
1 => "other",
2 => "ok",
3 => "predictiveFailure",
4 => "offline",
5 => "failed",
6 => "missingWasOk",
7 => "missingWasPredictiveFailure",
8 => "missingWasOffline",
9 => "missingWasFailed",
},
};
# INDEX { cpqPhyLogDrvCntlrIndex, cpqSasPhyDrvIndex }
foreach ($self->get_entries($oids, 'cpqSasPhyDrvEntry')) {
push(@{$self->{physical_drives}},
HP::Proliant::Component::DiskSubsystem::Sas::PhysicalDrive->new(%{$_}));
}
}
package HP::Proliant::Component::DiskSubsystem::Sas;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
controllers => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
condition => undef,
blacklisted => 0,
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Sas::SNMP';
} else {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Sas::CLI';
}
$self->init();
$self->assemble();
return $self;
}
sub check {
my $self = shift;
foreach (@{$self->{controllers}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{controllers}}) {
$_->dump();
}
}
package HP::Proliant::Component::DiskSubsystem::Sas::Controller;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Sas);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqSasHbaIndex => $params{cpqSasHbaIndex},
cpqSasHbaLocation => $params{cpqSasHbaLocation},
cpqSasHbaSlot => $params{cpqSasHbaSlot},
cpqSasHbaStatus => $params{cpqSasHbaStatus},
cpqSasHbaCondition => $params{cpqSasHbaCondition},
blacklisted => 0,
};
$self->{name} = $params{name} || $self->{cpqSasHbaSlot};
$self->{controllerindex} = $self->{cpqSasHbaIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqSasHbaCondition} eq 'other') {
if (scalar(@{$self->{physical_drives}})) {
$self->add_message(CRITICAL,
sprintf 'sas controller in slot %s needs attention',
$self->{cpqSasHbaSlot});
$self->add_info(sprintf 'sas controller in slot %s needs attention',
$self->{cpqSasHbaSlot});
} else {
$self->add_info(sprintf 'sas controller in slot %s is ok and unused',
$self->{cpqSasHbaSlot});
$self->{blacklisted} = 1;
}
} elsif ($self->{cpqSasHbaCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'sas controller in slot %s needs attention',
$self->{cpqSasHbaSlot});
$self->add_info(sprintf 'sas controller in slot %s needs attention',
$self->{cpqSasHbaSlot});
} else {
$self->add_info(sprintf 'sas controller in slot %s is ok',
$self->{cpqSasHbaSlot});
}
foreach (@{$self->{logical_drives}}) {
$_->check();
}
foreach (@{$self->{physical_drives}}) {
$_->check();
}
foreach (@{$self->{spare_drives}}) {
$_->check();
}
}
sub dump {
my $self = shift;
printf "[SAS_HBA%s]\n", $self->{name};
foreach (qw(cpqSasHbaSlot cpqSasHbaIndex cpqSasHbaCondition
cpqSasHbaStatus cpqSasHbaLocation)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
foreach (@{$self->{logical_drives}}) {
$_->dump();
}
foreach (@{$self->{physical_drives}}) {
$_->dump();
}
foreach (@{$self->{spare_drives}}) {
$_->dump();
}
}
package HP::Proliant::Component::DiskSubsystem::Sas::LogicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Sas);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqSasLogDrvHbaIndex => $params{cpqSasLogDrvHbaIndex},
cpqSasLogDrvIndex => $params{cpqSasLogDrvIndex},
cpqSasLogDrvStatus => $params{cpqSasLogDrvStatus},
cpqSasLogDrvCondition => $params{cpqSasLogDrvCondition},
cpqSasLogDrvRebuildingPercent => $params{cpqSasLogDrvRebuildingPercent},
cpqSasLogDrvRaidLevel => $params{cpqSasLogDrvRaidLevel},
blacklisted => 0,
};
bless $self, $class;
$self->{name} = $params{name} ||
$self->{cpqSasLogDrvHbaIndex}.':'.$self->{cpqSasLogDrvIndex}; ####vorerst
$self->{controllerindex} = $self->{cpqSasLogDrvHbaIndex};
if (! $self->{cpqSasLogDrvRebuildingPercent} ||
$self->{cpqSasLogDrvRebuildingPercent} == 4294967295) {
$self->{cpqSasLogDrvRebuildingPercent} = 100;
}
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqSasLogDrvCondition} ne "ok") {
if ($self->{cpqSasLogDrvStatus} =~
/rebuild|recovering|expanding|queued/) {
$self->add_message(WARNING,
sprintf "logical drive %s is %s",
$self->{name}, $self->{cpqSasLogDrvStatus});
} else {
$self->add_message(CRITICAL,
sprintf "logical drive %s is %s",
$self->{name}, $self->{cpqSasLogDrvStatus});
}
}
$self->add_info(
sprintf "logical drive %s is %s (%s)", $self->{name},
$self->{cpqSasLogDrvStatus}, $self->{cpqSasLogDrvRaidLevel});
}
sub dump {
my $self = shift;
printf "[LOGICAL_DRIVE]\n";
foreach (qw(cpqSasLogDrvHbaIndex cpqSasLogDrvIndex cpqSasLogDrvRaidLevel
cpqSasLogDrvStatus cpqSasLogDrvCondition
cpqSasLogDrvRebuildingPercent)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Sas::PhysicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Sas);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqSasPhyDrvHbaIndex => $params{cpqSasPhyDrvHbaIndex},
cpqSasPhyDrvIndex => $params{cpqSasPhyDrvIndex},
cpqSasPhyDrvLocationString => $params{cpqSasPhyDrvLocationString},
cpqSasPhyDrvStatus => $params{cpqSasPhyDrvStatus},
cpqSasPhyDrvSize => $params{cpqSasPhyDrvSize},
cpqSasPhyDrvCondition => $params{cpqSasPhyDrvCondition},
blacklisted => 0,
};
$self->{name} = $params{name} ||
$self->{cpqSasPhyDrvHbaIndex}.':'.$self->{cpqSasPhyDrvIndex}; ####vorerst
$self->{controllerindex} = $self->{cpqSasPhyDrvHbaIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqSasPhyDrvCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqSasPhyDrvCondition});
}
$self->add_info(
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqSasPhyDrvCondition});
}
sub dump {
my $self = shift;
printf "[PHYSICAL_DRIVE]\n";
foreach (qw(cpqSasPhyDrvHbaIndex cpqSasPhyDrvIndex cpqSasPhyDrvLocationString
cpqSasPhyDrvSize cpqSasPhyDrvStatus cpqSasPhyDrvCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Sas::SpareDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Sas);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub dump {
my $self = shift;
printf "[SPARE_DRIVE]\n";
}
package HP::Proliant::Component::DiskSubsystem::Scsi::CLI;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Scsi);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
}
package HP::Proliant::Component::DiskSubsystem::Scsi::SNMP;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Scsi
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
# CPQSCSI-MIB
my $oids = {
cpqScsiCntlrEntry => '1.3.6.1.4.1.232.5.2.2.1.1',
cpqScsiCntlrIndex => '1.3.6.1.4.1.232.5.2.2.1.1.1',
cpqScsiCntlrBusIndex => '1.3.6.1.4.1.232.5.2.2.1.1.2',
cpqScsiCntlrSlot => '1.3.6.1.4.1.232.5.2.2.1.1.6',
cpqScsiCntlrStatus => '1.3.6.1.4.1.232.5.2.2.1.1.7',
cpqScsiCntlrCondition => '1.3.6.1.4.1.232.5.2.2.1.1.12',
cpqScsiCntlrHwLocation => '1.3.6.1.4.1.232.5.2.2.1.1.16',
cpqScsiCntlrStatusValue => {
1 => "other",
2 => "ok",
3 => "failed",
},
cpqScsiCntlrConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
}
};
# INDEX { cpqScsiCntlrIndex, cpqScsiCntlrBusIndex }
foreach ($self->get_entries($oids, 'cpqScsiCntlrEntry')) {
push(@{$self->{controllers}},
HP::Proliant::Component::DiskSubsystem::Scsi::Controller->new(%{$_}));
}
$oids = {
cpqScsiLogDrvEntry => '1.3.6.1.4.1.232.5.2.3.1.1',
cpqScsiLogDrvCntlrIndex => '1.3.6.1.4.1.232.5.2.3.1.1.1',
cpqScsiLogDrvBusIndex => '1.3.6.1.4.1.232.5.2.3.1.1.2',
cpqScsiLogDrvIndex => '1.3.6.1.4.1.232.5.2.3.1.1.3',
cpqScsiLogDrvFaultTol => '1.3.6.1.4.1.232.5.2.3.1.1.4',
cpqScsiLogDrvStatus => '1.3.6.1.4.1.232.5.2.3.1.1.5',
cpqScsiLogDrvSize => '1.3.6.1.4.1.232.5.2.3.1.1.6',
cpqScsiLogDrvPhyDrvIDs => '1.3.6.1.4.1.232.5.2.3.1.1.7',
cpqScsiLogDrvCondition => '1.3.6.1.4.1.232.5.2.3.1.1.8',
cpqScsiLogDrvStatusValue => {
1 => "other",
2 => "ok",
3 => "failed",
4 => "unconfigured",
5 => "recovering",
6 => "readyForRebuild",
7 => "rebuilding",
8 => "wrongDrive",
9 => "badConnect",
},
cpqScsiLogDrvConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqScsiLogDrvFaultTolValue => {
1 => "other",
2 => "none",
3 => "mirroring",
4 => "dataGuard",
5 => "distribDataGuard",
},
};
# INDEX { cpqScsiLogDrvCntlrIndex, cpqScsiLogDrvBusIndex, cpqScsiLogDrvIndex }
foreach ($self->get_entries($oids, 'cpqScsiLogDrvEntry')) {
push(@{$self->{logical_drives}},
HP::Proliant::Component::DiskSubsystem::Scsi::LogicalDrive->new(%{$_}));
}
$oids = {
cpqScsiPhyDrvEntry => '1.3.6.1.4.1.232.5.2.4.1.1',
cpqScsiPhyDrvCntlrIndex => '1.3.6.1.4.1.232.5.2.4.1.1.1',
cpqScsiPhyDrvBusIndex => '1.3.6.1.4.1.232.5.2.4.1.1.2',
cpqScsiPhyDrvIndex => '1.3.6.1.4.1.232.5.2.4.1.1.3',
cpqScsiPhyDrvStatus => '1.3.6.1.4.1.232.5.2.4.1.1.9',
cpqScsiPhyDrvSize => '1.3.6.1.4.1.232.5.2.4.1.1.7',
cpqScsiPhyDrvCondition => '1.3.6.1.4.1.232.5.2.4.1.1.26',
cpqScsiPhyDrvConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqScsiPhyDrvStatusValue => {
1 => "other",
2 => "ok",
3 => "failed",
4 => "notConfigured",
5 => "badCable",
6 => "missingWasOk",
7 => "missingWasFailed",
8 => "predictiveFailure",
9 => "missingWasPredictiveFailure",
10 => "offline",
11 => "missingWasOffline",
12 => "hardError",
},
};
# INDEX { cpqScsiPhyDrvCntlrIndex, cpqScsiPhyDrvBusIndex, cpqScsiPhyDrvIndex }
foreach ($self->get_entries($oids, 'cpqScsiPhyDrvEntry')) {
push(@{$self->{physical_drives}},
HP::Proliant::Component::DiskSubsystem::Scsi::PhysicalDrive->new(%{$_}));
}
}
package HP::Proliant::Component::DiskSubsystem::Scsi;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
controllers => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
condition => undef,
blacklisted => 0,
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Scsi::SNMP';
} else {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Scsi::CLI';
}
$self->init();
$self->assemble();
return $self;
}
sub check {
my $self = shift;
foreach (@{$self->{controllers}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{controllers}}) {
$_->dump();
}
}
package HP::Proliant::Component::DiskSubsystem::Scsi::Controller;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Scsi);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqScsiCntlrIndex => $params{cpqScsiCntlrIndex},
cpqScsiCntlrBusIndex => $params{cpqScsiCntlrBusIndex},
cpqScsiCntlrSlot => $params{cpqScsiCntlrSlot},
cpqScsiCntlrStatus => $params{cpqScsiCntlrStatus},
cpqScsiCntlrCondition => $params{cpqScsiCntlrCondition},
cpqScsiCntlrHwLocation => $params{cpqScsiCntlrHwLocation},
blacklisted => 0,
};
$self->{name} = $params{name} || $self->{cpqScsiCntlrIndex};
$self->{controllerindex} = $self->{cpqScsiCntlrIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqScsiCntlrCondition} eq 'other') {
if (scalar(@{$self->{physical_drives}})) {
$self->add_message(CRITICAL,
sprintf 'scsi controller in slot %s needs attention',
$self->{cpqScsiCntlrSlot});
$self->add_info(sprintf 'scsi controller in slot %s needs attention',
$self->{cpqScsiCntlrSlot});
} else {
$self->add_info(sprintf 'scsi controller in slot %s is ok and unused',
$self->{cpqScsiCntlrSlot});
$self->{blacklisted} = 1;
}
} elsif ($self->{cpqScsiCntlrCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'scsi controller in slot %s needs attention',
$self->{cpqScsiCntlrSlot});
$self->add_info(sprintf 'scsi controller in slot %s needs attention',
$self->{cpqScsiCntlrSlot});
} else {
$self->add_info(sprintf 'scsi controller in slot %s is ok',
$self->{cpqScsiCntlrSlot});
}
foreach (@{$self->{logical_drives}}) {
$_->check();
}
foreach (@{$self->{physical_drives}}) {
$_->check();
}
foreach (@{$self->{spare_drives}}) {
$_->check();
}
}
sub dump {
my $self = shift;
printf "[SCSI_CONTROLLER_%s]\n", $self->{name};
foreach (qw(cpqScsiCntlrIndex cpqScsiCntlrBusIndex cpqScsiCntlrSlot
cpqScsiCntlrStatus cpqScsiCntlrCondition cpqScsiCntlrHwLocation)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
foreach (@{$self->{logical_drives}}) {
$_->dump();
}
foreach (@{$self->{physical_drives}}) {
$_->dump();
}
foreach (@{$self->{spare_drives}}) {
$_->dump();
}
}
package HP::Proliant::Component::DiskSubsystem::Scsi::LogicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Scsi);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqScsiLogDrvCntlrIndex => $params{cpqScsiLogDrvCntlrIndex},
cpqScsiLogDrvBusIndex => $params{cpqScsiLogDrvBusIndex},
cpqScsiLogDrvIndex => $params{cpqScsiLogDrvIndex},
cpqScsiLogDrvFaultTol => $params{cpqScsiLogDrvFaultTol},
cpqScsiLogDrvStatus => $params{cpqScsiLogDrvStatus},
cpqScsiLogDrvSize => $params{cpqScsiLogDrvSize},
cpqScsiLogDrvPhyDrvIDs => $params{cpqScsiLogDrvPhyDrvIDs},
cpqScsiLogDrvCondition => $params{cpqScsiLogDrvCondition},
blacklisted => 0,
};
bless $self, $class;
$self->{name} = $params{name} ||
$self->{cpqScsiLogDrvCntlrIndex}.':'.
$self->{cpqScsiLogDrvBusIndex}.':'.
$self->{cpqScsiLogDrvIndex}; ####vorerst
$self->{controllerindex} = $self->{cpqScsiLogDrvCntlrIndex};
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqScsiLogDrvCondition} ne "ok") {
if ($self->{cpqScsiLogDrvStatus} =~
/rebuild|recovering/) {
$self->add_message(WARNING,
sprintf "logical drive %s is %s",
$self->{name}, $self->{cpqScsiLogDrvStatus});
} else {
$self->add_message(CRITICAL,
sprintf "logical drive %s is %s",
$self->{name}, $self->{cpqScsiLogDrvStatus});
}
}
$self->add_info(
sprintf "logical drive %s is %s", $self->{name},
$self->{cpqScsiLogDrvStatus});
}
sub dump {
my $self = shift;
printf "[LOGICAL_DRIVE]\n";
foreach (qw(cpqScsiLogDrvCntlrIndex cpqScsiLogDrvBusIndex cpqScsiLogDrvIndex
cpqScsiLogDrvFaultTol cpqScsiLogDrvStatus cpqScsiLogDrvSize
cpqScsiLogDrvPhyDrvIDs cpqScsiLogDrvCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Scsi::PhysicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Scsi);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqScsiPhyDrvCntlrIndex => $params{cpqScsiPhyDrvCntlrIndex},
cpqScsiPhyDrvBusIndex => $params{cpqScsiPhyDrvBusIndex},
cpqScsiPhyDrvIndex => $params{cpqScsiPhyDrvIndex},
cpqScsiPhyDrvStatus => $params{cpqScsiPhyDrvStatus},
cpqScsiPhyDrvSize => $params{cpqScsiPhyDrvSize},
cpqScsiPhyDrvCondition => $params{cpqScsiPhyDrvCondition},
blacklisted => 0,
};
$self->{name} = $params{name} ||
$self->{cpqScsiPhyDrvCntlrIndex}.':'.$self->{cpqScsiPhyDrvIndex};
$self->{controllerindex} = $self->{cpqScsiPhyDrvCntlrIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqScsiPhyDrvCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqScsiPhyDrvCondition});
}
$self->add_info(
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqScsiPhyDrvCondition});
}
sub dump {
my $self = shift;
printf "[PHYSICAL_DRIVE]\n";
foreach (qw(cpqScsiPhyDrvCntlrIndex cpqScsiPhyDrvBusIndex cpqScsiPhyDrvIndex
cpqScsiPhyDrvStatus cpqScsiPhyDrvSize cpqScsiPhyDrvCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Scsi::SpareDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Scsi);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub dump {
my $self = shift;
printf "[SPARE_DRIVE]\n";
}
package HP::Proliant::Component::DiskSubsystem::Ide::CLI;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Ide);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
}
package HP::Proliant::Component::DiskSubsystem::Ide::SNMP;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Ide
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
# CPQIDE-MIB
my $oids = {
cpqIdeControllerEntry => '1.3.6.1.4.1.232.14.2.3.1.1',
cpqIdeControllerIndex => '1.3.6.1.4.1.232.14.2.3.1.1.1',
cpqIdeControllerOverallCondition => '1.3.6.1.4.1.232.14.2.3.1.1.2',
cpqIdeControllerModel => '1.3.6.1.4.1.232.14.2.3.1.1.3',
cpqIdeControllerSlot => '1.3.6.1.4.1.232.14.2.3.1.1.5',
cpqIdeControllerOverallConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
};
# INDEX { cpqIdeControllerIndex }
foreach ($self->get_entries($oids, 'cpqIdeControllerEntry')) {
push(@{$self->{controllers}},
HP::Proliant::Component::DiskSubsystem::Ide::Controller->new(%{$_}));
}
$oids = {
cpqIdeLogicalDriveEntry => '1.3.6.1.4.1.232.14.2.6.1.1',
cpqIdeLogicalDriveControllerIndex => '1.3.6.1.4.1.232.14.2.6.1.1.1',
cpqIdeLogicalDriveIndex => '1.3.6.1.4.1.232.14.2.6.1.1.2',
cpqIdeLogicalDriveRaidLevel => '1.3.6.1.4.1.232.14.2.6.1.1.3',
cpqIdeLogicalDriveCapacity => '1.3.6.1.4.1.232.14.2.6.1.1.4',
cpqIdeLogicalDriveStatus => '1.3.6.1.4.1.232.14.2.6.1.1.5',
cpqIdeLogicalDriveCondition => '1.3.6.1.4.1.232.14.2.6.1.1.6',
cpqIdeLogicalDriveDiskIds => '1.3.6.1.4.1.232.14.2.6.1.1.7',
cpqIdeLogicalDriveSpareIds => '1.3.6.1.4.1.232.14.2.6.1.1.9',
cpqIdeLogicalDriveRebuildingDisk => '1.3.6.1.4.1.232.14.2.6.1.1.10',
cpqIdeLogicalDriveRaidLevelValue => {
1 => "other",
2 => "raid0",
3 => "raid1",
4 => "raid0plus1",
},
cpqIdeLogicalDriveStatusValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "rebuilding",
5 => "failed",
},
cpqIdeLogicalDriveConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
};
# INDEX { cpqIdeLogicalDriveControllerIndex, cpqIdeLogicalDriveIndex }
foreach ($self->get_entries($oids, 'cpqIdeLogicalDriveEntry')) {
push(@{$self->{logical_drives}},
HP::Proliant::Component::DiskSubsystem::Ide::LogicalDrive->new(%{$_}));
}
$oids = {
cpqIdeAtaDiskEntry => '1.3.6.1.4.1.232.14.2.4.1.1',
cpqIdeAtaDiskControllerIndex => '1.3.6.1.4.1.232.14.2.4.1.1.1',
cpqIdeAtaDiskIndex => '1.3.6.1.4.1.232.14.2.4.1.1.2',
cpqIdeAtaDiskModel => '1.3.6.1.4.1.232.14.2.4.1.1.3',
cpqIdeAtaDiskStatus => '1.3.6.1.4.1.232.14.2.4.1.1.6',
cpqIdeAtaDiskCondition => '1.3.6.1.4.1.232.14.2.4.1.1.7',
cpqIdeAtaDiskCapacity => '1.3.6.1.4.1.232.14.2.4.1.1.8',
cpqIdeAtaDiskLogicalDriveMember => '1.3.6.1.4.1.232.14.2.4.1.1.13',
cpqIdeAtaDiskIsSpare => '1.3.6.1.4.1.232.14.2.4.1.1.14',
cpqIdeAtaDiskStatusValue => {
1 => "other",
2 => "ok",
3 => "smartError",
4 => "failed",
},
cpqIdeAtaDiskConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
};
# INDEX { cpqIdeAtaDiskControllerIndex, cpqIdeAtaDiskIndex }
foreach ($self->get_entries($oids, 'cpqIdeAtaDiskEntry')) {
push(@{$self->{physical_drives}},
HP::Proliant::Component::DiskSubsystem::Ide::PhysicalDrive->new(%{$_}));
}
}
package HP::Proliant::Component::DiskSubsystem::Ide;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
controllers => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
condition => undef,
blacklisted => 0,
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Ide::SNMP';
} else {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Ide::CLI';
}
$self->init();
$self->assemble();
return $self;
}
sub check {
my $self = shift;
foreach (@{$self->{controllers}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{controllers}}) {
$_->dump();
}
}
package HP::Proliant::Component::DiskSubsystem::Ide::Controller;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Ide);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqIdeControllerIndex => $params{cpqIdeControllerIndex},
cpqIdeControllerOverallCondition => $params{cpqIdeControllerOverallCondition},
cpqIdeControllerModel => $params{cpqIdeControllerModel},
cpqIdeControllerSlot => $params{cpqIdeControllerSlot}, # -1 ist sysboard?
blacklisted => 0,
};
$self->{name} = $params{name} || $self->{cpqIdeControllerIndex};
$self->{controllerindex} = $self->{cpqIdeControllerIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqIdeControllerOverallCondition} eq 'other') {
if (scalar(@{$self->{physical_drives}})) {
$self->add_message(CRITICAL,
sprintf 'ide controller %s in slot %s needs attention',
$self->{cpqIdeControllerIndex}, $self->{cpqIdeControllerSlot});
$self->add_info(sprintf 'ide controller %s in slot %s needs attention',
$self->{cpqIdeControllerIndex}, $self->{cpqIdeControllerSlot});
} else {
$self->add_info(sprintf 'ide controller %s in slot %s is ok and unused',
$self->{cpqIdeControllerIndex}, $self->{cpqIdeControllerSlot});
$self->{blacklisted} = 1;
}
} elsif ($self->{cpqIdeControllerOverallCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'ide controller %s in slot %s needs attention',
$self->{cpqIdeControllerIndex}, $self->{cpqIdeControllerSlot});
$self->add_info(sprintf 'ide controller %s in slot %s needs attention',
$self->{cpqIdeControllerIndex}, $self->{cpqIdeControllerSlot});
} else {
$self->add_info(sprintf 'ide controller %s in slot %s is ok',
$self->{cpqIdeControllerIndex}, $self->{cpqIdeControllerSlot});
}
foreach (@{$self->{logical_drives}}) {
$_->check();
}
foreach (@{$self->{physical_drives}}) {
$_->check();
}
foreach (@{$self->{spare_drives}}) {
$_->check();
}
}
sub dump {
my $self = shift;
printf "[IDE_CONTROLLER_%s]\n", $self->{name};
foreach (qw(cpqIdeControllerIndex cpqIdeControllerSlot
cpqIdeControllerModel cpqIdeControllerOverallCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
foreach (@{$self->{logical_drives}}) {
$_->dump();
}
foreach (@{$self->{physical_drives}}) {
$_->dump();
}
foreach (@{$self->{spare_drives}}) {
$_->dump();
}
}
package HP::Proliant::Component::DiskSubsystem::Ide::LogicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Ide);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqIdeLogicalDriveControllerIndex => $params{cpqIdeLogicalDriveControllerIndex},
cpqIdeLogicalDriveIndex => $params{cpqIdeLogicalDriveIndex},
cpqIdeLogicalDriveRaidLevel => $params{cpqIdeLogicalDriveRaidLevel},
cpqIdeLogicalDriveCapacity => $params{cpqIdeLogicalDriveCapacity},
cpqIdeLogicalDriveStatus => $params{cpqIdeLogicalDriveStatus},
cpqIdeLogicalDriveCondition => $params{cpqIdeLogicalDriveCondition},
cpqIdeLogicalDriveDiskIds => $params{cpqIdeLogicalDriveDiskIds},
cpqIdeLogicalDriveSpareIds => $params{cpqIdeLogicalDriveSpareIds},
cpqIdeLogicalDriveRebuildingDisk => $params{cpqIdeLogicalDriveRebuildingDisk},
blacklisted => 0,
};
bless $self, $class;
$self->{name} = $params{name} ||
$self->{cpqIdeLogicalDriveControllerIndex}.':'.
$self->{cpqIdeLogicalDriveIndex};
$self->{controllerindex} = $self->{cpqIdeLogicalDriveControllerIndex};
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqIdeLogicalDriveCondition} ne "ok") {
if ($self->{cpqIdeLogicalDriveStatus} =~
/rebuild/) {
$self->add_message(WARNING,
sprintf "logical drive %s is %s",
$self->{name}, $self->{cpqIdeLogicalDriveStatus});
} else {
$self->add_message(CRITICAL,
sprintf "logical drive %s is %s",
$self->{name}, $self->{cpqIdeLogicalDriveStatus});
}
}
$self->add_info(
sprintf "logical drive %s is %s", $self->{name},
$self->{cpqIdeLogicalDriveStatus});
}
sub dump {
my $self = shift;
printf "[LOGICAL_DRIVE]\n";
foreach (qw(cpqIdeLogicalDriveControllerIndex cpqIdeLogicalDriveIndex
cpqIdeLogicalDriveRaidLevel cpqIdeLogicalDriveCapacity
cpqIdeLogicalDriveDiskIds cpqIdeLogicalDriveSpareIds
cpqIdeLogicalDriveRebuildingDisk cpqIdeLogicalDriveStatus
cpqIdeLogicalDriveCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Ide::PhysicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Ide);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqIdeAtaDiskControllerIndex => $params{cpqIdeAtaDiskControllerIndex},
cpqIdeAtaDiskIndex => $params{cpqIdeAtaDiskIndex},
cpqIdeAtaDiskModel => $params{cpqIdeAtaDiskModel},
cpqIdeAtaDiskStatus => $params{cpqIdeAtaDiskStatus},
cpqIdeAtaDiskCondition => $params{cpqIdeAtaDiskCondition},
cpqIdeAtaDiskCapacity => $params{cpqIdeAtaDiskCapacity},
cpqIdeAtaDiskLogicalDriveMember => $params{cpqIdeAtaDiskLogicalDriveMember},
cpqIdeAtaDiskIsSpare => $params{cpqIdeAtaDiskIsSpare},
blacklisted => 0,
};
$self->{name} = $params{name} ||
$self->{cpqIdeAtaDiskControllerIndex}.':'.
$self->{cpqIdeAtaDiskIndex}; ####vorerst
$self->{controllerindex} = $self->{cpqIdeAtaDiskControllerIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqIdeAtaDiskCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqIdeAtaDiskCondition});
}
$self->add_info(
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqIdeAtaDiskCondition});
}
sub dump {
my $self = shift;
printf "[PHYSICAL_DRIVE]\n";
foreach (qw(cpqIdeAtaDiskControllerIndex cpqIdeAtaDiskIndex
cpqIdeAtaDiskModel cpqIdeAtaDiskCapacity cpqIdeAtaDiskLogicalDriveMember
cpqIdeAtaDiskStatus cpqIdeAtaDiskCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Ide::SpareDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Ide);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub dump {
my $self = shift;
printf "[SPARE_DRIVE]\n";
}
package HP::Proliant::Component::DiskSubsystem::Fca::CLI;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
# .....
$self->{global_status} =
HP::Proliant::Component::DiskSubsystem::Fca::GlobalStatus->new(
runtime => $self->{runtime},
cpqFcaMibCondition => 'n/a',
);
}
package HP::Proliant::Component::DiskSubsystem::Fca::SNMP;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca
HP::Proliant::Component::SNMP);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
blacklisted => 0,
};
bless $self, $class;
return $self;
}
sub init {
my $self = shift;
my $snmpwalk = $self->{rawdata};
# CPQFCA-MIB
my $oids = {
cpqFcaHostCntlrEntry => '1.3.6.1.4.1.232.16.2.7.1.1',
cpqFcaHostCntlrIndex => '1.3.6.1.4.1.232.16.2.7.1.1.1',
cpqFcaHostCntlrSlot => '1.3.6.1.4.1.232.16.2.7.1.1.2',
cpqFcaHostCntlrModel => '1.3.6.1.4.1.232.16.2.7.1.1.3',
cpqFcaHostCntlrStatus => '1.3.6.1.4.1.232.16.2.7.1.1.4',
cpqFcaHostCntlrCondition => '1.3.6.1.4.1.232.16.2.7.1.1.5',
cpqFcaHostCntlrOverallCondition => '1.3.6.1.4.1.232.16.2.7.1.1.8',
cpqFcaHostCntlrModelValue => {
1 => "other",
2 => "fchc-p",
3 => "fchc-e",
4 => "fchc64",
5 => "sa-sam",
6 => "fca-2101",
7 => "sw64-33",
8 => "fca-221x",
9 => "dpfcmc",
},
cpqFcaHostCntlrStatusValue => {
1 => "other",
2 => "ok",
3 => "failed",
4 => "shutdown",
5 => "loopDegraded",
6 => "loopFailed",
},
cpqFcaHostCntlrConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
cpqFcaHostCntlrOverallConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
}, # cntrl + alle associated storage boxes
};
# INDEX { cpqFcaHostCntlrIndex }
foreach ($self->get_entries($oids, 'cpqFcaHostCntlrEntry')) {
push(@{$self->{host_controllers}},
HP::Proliant::Component::DiskSubsystem::Fca::HostController->new(%{$_}));
}
$oids = {
cpqFcaCntlrEntry => '1.3.6.1.4.1.232.16.2.2.1.1',
cpqFcaCntlrBoxIndex => '1.3.6.1.4.1.232.16.2.2.1.1.1',
cpqFcaCntlrBoxIoSlot => '1.3.6.1.4.1.232.16.2.2.1.1.2',
cpqFcaCntlrModel => '1.3.6.1.4.1.232.16.2.2.1.1.3',
cpqFcaCntlrStatus => '1.3.6.1.4.1.232.16.2.2.1.1.5',
cpqFcaCntlrCondition => '1.3.6.1.4.1.232.16.2.2.1.1.6',
cpqFcaCntlrModelValue => {
1 => "other",
2 => "fibreArray",
3 => "msa1000",
4 => "smartArrayClusterStorage",
5 => "hsg80",
6 => "hsv110",
7 => "msa500g2",
8 => "msa20",
},
cpqFcaCntlrStatusValue => {
1 => "other",
2 => "ok",
3 => "failed",
4 => "offline",
4 => "redundantPathOffline",
},
cpqFcaCntlrConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
};
# INDEX { cpqFcaCntlrBoxIndex, cpqFcaCntlrBoxIoSlot }
foreach ($self->get_entries($oids, 'cpqFcaCntlrEntry')) {
push(@{$self->{controllers}},
HP::Proliant::Component::DiskSubsystem::Fca::Controller->new(%{$_}));
}
$oids = {
cpqFcaAccelEntry => '1.3.6.1.4.1.232.16.2.2.2.1',
cpqFcaAccelBoxIndex => '1.3.6.1.4.1.232.16.2.2.2.1.1',
cpqFcaAccelBoxIoSlot => '1.3.6.1.4.1.232.16.2.2.2.1.2',
cpqFcaAccelStatus => '1.3.6.1.4.1.232.16.2.2.2.1.3',
cpqFcaAccelErrCode => '1.3.6.1.4.1.232.16.2.2.2.1.5',
cpqFcaAccelBatteryStatus => '1.3.6.1.4.1.232.16.2.2.2.1.6',
cpqFcaAccelCondition => '1.3.6.1.4.1.232.16.2.2.2.1.9',
cpqFcaAccelStatusValue => {
1 => "other",
2 => "invalid",
3 => "enabled",
4 => "tmpDisabled",
5 => "permDisabled",
},
cpqFcaAccelErrCodeValue => {
1 => 'other',
2 => 'invalid',
3 => 'badConfig',
4 => 'lowBattery',
5 => 'disableCmd',
6 => 'noResources',
7 => 'notConnected',
8 => 'badMirrorData',
9 => 'readErr',
10 => 'writeErr',
11 => 'configCmd',
12 => 'expandInProgress',
13 => 'snapshotInProgress',
14 => 'redundantLowBattery',
15 => 'redundantSizeMismatch',
16 => 'redundantCacheFailure',
17 => 'excessiveEccErrors',
19 => 'postEccErrors',
},
cpqFcaAccelBatteryStatusValue => {
1 => 'other',
2 => 'ok',
3 => 'recharging',
4 => 'failed',
5 => 'degraded',
6 => 'notPresent',
},
cpqFcaAccelConditionValue => {
1 => "other",
2 => "ok",
3 => "degraded",
4 => "failed",
},
};
# INDEX { cpqFcaAccelBoxIndex, cpqFcaAccelBoxIoSlot }
foreach ($self->get_entries($oids, 'cpqFcaAccelEntry')) {
push(@{$self->{accelerators}},
HP::Proliant::Component::DiskSubsystem::Fca::Accelerator->new(%{$_}));
}
$oids = {
cpqFcaLogDrvEntry => '1.3.6.1.4.1.232.16.2.3.1.1',
cpqFcaLogDrvBoxIndex => '1.3.6.1.4.1.232.16.2.3.1.1.1',
cpqFcaLogDrvIndex => '1.3.6.1.4.1.232.16.2.3.1.1.2',
cpqFcaLogDrvFaultTol => '1.3.6.1.4.1.232.16.2.3.1.1.3',
cpqFcaLogDrvStatus => '1.3.6.1.4.1.232.16.2.3.1.1.4',
cpqFcaLogDrvPercentRebuild => '1.3.6.1.4.1.232.16.2.3.1.1.6',
cpqFcaLogDrvSize => '1.3.6.1.4.1.232.16.2.3.1.1.9',
cpqFcaLogDrvPhyDrvIDs => '1.3.6.1.4.1.232.16.2.3.1.1.10',
cpqFcaLogDrvCondition => '1.3.6.1.4.1.232.16.2.3.1.1.11',
cpqFcaLogDrvFaultTolValue => {
1 => 'other',
2 => 'none',
3 => 'mirroring',
4 => 'dataGuard',
5 => 'distribDataGuard',
7 => 'advancedDataGuard',
},
cpqFcaLogDrvStatusValue => {
1 => 'other',
2 => 'ok',
3 => 'failed',
4 => 'unconfigured',
5 => 'recovering',
6 => 'readyForRebuild',
7 => 'rebuilding',
8 => 'wrongDrive',
9 => 'badConnect',
10 => 'overheating',
11 => 'shutdown',
12 => 'expanding',
13 => 'notAvailable',
14 => 'queuedForExpansion',
15 => 'hardError',
},
cpqFcaLogDrvConditionValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
},
};
# INDEX { cpqFcaLogDrvBoxIndex, cpqFcaLogDrvIndex }
foreach ($self->get_entries($oids, 'cpqFcaLogDrvEntry')) {
push(@{$self->{logical_drives}},
HP::Proliant::Component::DiskSubsystem::Fca::LogicalDrive->new(%{$_}));
}
$oids = {
cpqFcaPhyDrvEntry => '1.3.6.1.4.1.232.16.2.5.1.1',
cpqFcaPhyDrvBoxIndex => '1.3.6.1.4.1.232.16.2.5.1.1.1',
cpqFcaPhyDrvIndex => '1.3.6.1.4.1.232.16.2.5.1.1.2',
cpqFcaPhyDrvModel => '1.3.6.1.4.1.232.16.2.5.1.1.3',
cpqFcaPhyDrvBay => '1.3.6.1.4.1.232.16.2.5.1.1.5',
cpqFcaPhyDrvStatus => '1.3.6.1.4.1.232.16.2.5.1.1.6',
cpqFcaPhyDrvCondition => '1.3.6.1.4.1.232.16.2.5.1.1.31',
cpqFcaPhyDrvSize => '1.3.6.1.4.1.232.16.2.5.1.1.38',
cpqFcaPhyDrvBusNumber => '1.3.6.1.4.1.232.16.2.5.1.1.42',
cpqFcaPhyDrvStatusValue => {
1 => 'other',
2 => 'unconfigured',
3 => 'ok',
4 => 'threshExceeded',
5 => 'predictiveFailure',
6 => 'failed',
},
cpqFcaPhyDrvConditionValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
},
};
# INDEX { cpqFcaPhyDrvBoxIndex, cpqFcaPhyDrvIndex }
foreach ($self->get_entries($oids, 'cpqFcaPhyDrvEntry')) {
push(@{$self->{physical_drives}},
HP::Proliant::Component::DiskSubsystem::Fca::PhysicalDrive->new(%{$_}));
}
$oids = {
cpqFcaMibRevMajor => '1.3.6.1.4.1.232.16.1.1.0',
cpqFcaMibRevMinor => '1.3.6.1.4.1.232.16.1.2.0',
cpqFcaMibCondition => '1.3.6.1.4.1.232.16.1.3.0',
cpqFcaMibConditionValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
},
};
$self->{global_status} =
HP::Proliant::Component::DiskSubsystem::Fca::GlobalStatus->new(
runtime => $self->{runtime},
cpqFcaMibCondition =>
SNMP::Utils::get_object_value($snmpwalk,
$oids->{cpqFcaMibCondition}, $oids->{cpqFcaMibConditionValue})
);
}
package HP::Proliant::Component::DiskSubsystem::Fca;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
host_controllers => [],
controllers => [],
accelerators => [],
physical_drives => [],
logical_drives => [],
spare_drives => [],
global_status => undef,
blacklisted => 0,
};
bless $self, $class;
if ($self->{method} eq 'snmp') {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Fca::SNMP';
} else {
bless $self, 'HP::Proliant::Component::DiskSubsystem::Fca::CLI';
}
$self->init();
$self->assemble();
return $self;
}
sub assemble {
my $self = shift;
$self->trace(3, sprintf "%s controllers und platten zusammenf<6E>hren",
ref($self));
$self->trace(3, sprintf "has %d host controllers",
scalar(@{$self->{host_controllers}}));
$self->trace(3, sprintf "has %d controllers",
scalar(@{$self->{controllers}}));
$self->trace(3, sprintf "has %d physical_drives",
scalar(@{$self->{physical_drives}}));
$self->trace(3, sprintf "has %d logical_drives",
scalar(@{$self->{logical_drives}}));
$self->trace(3, sprintf "has %d spare_drives",
scalar(@{$self->{spare_drives}}));
}
sub check {
my $self = shift;
foreach (@{$self->{host_controllers}}) {
$_->check();
}
foreach (@{$self->{controllers}}) {
$_->check();
}
foreach (@{$self->{accelerators}}) {
$_->check();
}
foreach (@{$self->{logical_drives}}) {
$_->check();
}
foreach (@{$self->{physical_drives}}) {
$_->check();
}
# wozu eigentlich?
#if (! $self->has_controllers()) {
#$self->{global_status}->check();
#}
}
sub dump {
my $self = shift;
foreach (@{$self->{host_controllers}}) {
$_->dump();
}
foreach (@{$self->{controllers}}) {
$_->dump();
}
foreach (@{$self->{accelerators}}) {
$_->dump();
}
foreach (@{$self->{logical_drives}}) {
$_->dump();
}
foreach (@{$self->{physical_drives}}) {
$_->dump();
}
#$self->{global_status}->dump();
}
package HP::Proliant::Component::DiskSubsystem::Fca::GlobalStatus;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqFcaMibCondition => $params{cpqFcaMibCondition},
};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
if ($self->{cpqFcaMibCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'fcal overall condition is %s', $self->{cpqFcaMibCondition});
}
$self->{info} =
sprintf 'fcal overall condition is %s', $self->{cpqFcaMibCondition};
}
sub dump {
my $self = shift;
printf "[FCAL]\n";
foreach (qw(cpqFcaMibCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Fca::HostController;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqFcaHostCntlrIndex => $params{cpqFcaHostCntlrIndex},
cpqFcaHostCntlrSlot => $params{cpqFcaHostCntlrSlot},
cpqFcaHostCntlrModel => $params{cpqFcaHostCntlrModel},
cpqFcaHostCntlrStatus => $params{cpqFcaHostCntlrStatus},
cpqFcaHostCntlrCondition => $params{cpqFcaHostCntlrCondition},
cpqFcaHostCntlrOverallCondition => $params{cpqFcaHostCntlrOverallCondition},
blacklisted => 0,
};
$self->{name} = $params{name} || $self->{cpqFcaHostCntlrIndex};
$self->{controllerindex} = $self->{cpqFcaHostCntlrIndex};
$self->{ident} = sprintf '%s in slot %s',
$self->{cpqFcaHostCntlrIndex}, $self->{cpqFcaHostCntlrSlot};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
if ($self->is_blacklisted('fcahc',
$self->{cpqFcaHostCntlrSlot}.'-'.$self->{cpqFcaHostCntlrIndex})) {
$self->add_info(sprintf 'fcal host controller %s is %s (blacklisted)',
$self->{ident}, $self->{cpqFcaHostCntlrCondition});
} elsif ($self->{cpqFcaHostCntlrCondition} eq 'other') {
$self->add_message(CRITICAL,
sprintf 'fcal host controller %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaHostCntlrStatus});
$self->add_info(sprintf 'fcal host controller %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaHostCntlrStatus});
} elsif ($self->{cpqFcaHostCntlrCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'fcal host controller %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaHostCntlrStatus});
$self->add_info(sprintf 'fcal host controller %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaHostCntlrStatus});
} else {
$self->add_info(sprintf 'fcal host controller %s is ok',
$self->{ident});
}
if ($self->is_blacklisted('fcahc',
$self->{cpqFcaHostCntlrSlot}.'-'.$self->{cpqFcaHostCntlrIndex})) {
} elsif ($self->{cpqFcaHostCntlrOverallCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'fcal host controller %s reports problems (%s)',
$self->{ident}, $self->{cpqFcaHostCntlrStatus});
$self->add_info(sprintf 'fcal host controller %s reports problems (%s)',
$self->{ident}, $self->{cpqFcaHostCntlrStatus});
}
}
sub dump {
my $self = shift;
printf "[FCAL_HOST_CONTROLLER_%s]\n", $self->{name};
foreach (qw(cpqFcaHostCntlrIndex cpqFcaHostCntlrSlot
cpqFcaHostCntlrModel cpqFcaHostCntlrStatus cpqFcaHostCntlrCondition
cpqFcaHostCntlrOverallCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Fca::Controller;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqFcaCntlrBoxIndex => $params{cpqFcaCntlrBoxIndex},
cpqFcaCntlrBoxIoSlot => $params{cpqFcaCntlrBoxIoSlot},
cpqFcaCntlrModel => $params{cpqFcaCntlrModel},
cpqFcaCntlrStatus => $params{cpqFcaCntlrStatus},
cpqFcaCntlrCondition => $params{cpqFcaCntlrCondition},
blacklisted => 0,
};
$self->{name} = $params{name} ||
$self->{cpqFcaCntlrBoxIndex}.':'.$self->{cpqFcaCntlrBoxIoSlot};
$self->{controllerindex} = $self->{cpqFcaCntlrBoxIndex};
$self->{ident} = sprintf 'in box %s/slot %s',
$self->{cpqFcaCntlrBoxIndex}, $self->{cpqFcaCntlrBoxIoSlot};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('fcaco', $self->{name});
if ($self->{cpqFcaCntlrCondition} eq 'other') {
if (1) { # was ist mit phys. drives?
$self->add_message(CRITICAL,
sprintf 'fcal controller %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaCntlrStatus});
$self->add_info(sprintf 'fcal controller %s %s needs attention (%s)',
$self->{name}, $self->{ident}, $self->{cpqFcaCntlrStatus});
} else {
$self->add_info(sprintf 'fcal controller %s is ok and unused',
$self->{ident});
$self->{blacklisted} = 1;
}
} elsif ($self->{cpqFcaCntlrCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'fcal controller %s needs attention',
$self->{ident});
$self->add_info(sprintf 'fcal controller %s %s needs attention (%s)',
$self->{name}, $self->{ident}, $self->{cpqFcaCntlrCondition});
} else {
$self->add_info(sprintf 'fcal controller %s is ok',
$self->{ident});
}
}
sub dump {
my $self = shift;
printf "[FCAL_CONTROLLER_%s]\n", $self->{name};
foreach (qw(cpqFcaCntlrBoxIndex cpqFcaCntlrBoxIoSlot cpqFcaCntlrModel
cpqFcaCntlrStatus cpqFcaCntlrCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Fca::Accelerator;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqFcaAccelBoxIndex => $params{cpqFcaAccelBoxIndex},
cpqFcaAccelBoxIoSlot => $params{cpqFcaAccelBoxIoSlot},
cpqFcaAccelStatus => $params{cpqFcaAccelStatus},
cpqFcaAccelErrCode => $params{cpqFcaAccelErrCode},
cpqFcaAccelBatteryStatus => $params{cpqFcaAccelBatteryStatus},
cpqFcaAccelCondition => $params{cpqFcaAccelCondition},
blacklisted => 0,
};
$self->{name} = $params{name} ||
$self->{cpqFcaAccelBoxIndex}.':'.$self->{cpqFcaAccelBoxIoSlot};
$self->{controllerindex} = $self->{cpqFcaAccelBoxIndex};
$self->{ident} = sprintf 'in box %s/slot %s',
$self->{cpqFcaAccelBoxIndex}, $self->{cpqFcaAccelBoxIoSlot};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
# !!! cpqFcaAccelStatus
$self->blacklist('fcaac', $self->{name});
if ($self->{cpqFcaAccelStatus} eq 'invalid') {
$self->add_info(sprintf 'fcal accelerator %s is not installed',
$self->{ident});
} elsif ($self->{cpqFcaAccelStatus} eq 'tmpDisabled') {
$self->add_info(sprintf 'fcal accelerator %s is temp disabled',
$self->{ident});
} elsif ($self->{cpqFcaAccelCondition} eq 'other') {
$self->add_message(CRITICAL,
sprintf 'fcal accelerator %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaAccelErrCode});
$self->add_info(sprintf 'fcal accelerator %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaAccelErrCode});
} elsif ($self->{cpqFcaAccelCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf 'fcal accelerator %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaAccelErrCode});
$self->add_info(sprintf 'fcal accelerator %s needs attention (%s)',
$self->{ident}, $self->{cpqFcaAccelErrCode});
} else {
$self->add_info(sprintf 'fcal accelerator %s is ok',
$self->{ident});
}
}
sub dump {
my $self = shift;
printf "[FCAL_ACCELERATOR_%s]\n", $self->{name};
foreach (qw(cpqFcaAccelBoxIndex cpqFcaAccelBoxIoSlot cpqFcaAccelStatus
cpqFcaAccelErrCode cpqFcaAccelBatteryStatus cpqFcaAccelCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Fca::LogicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqFcaLogDrvBoxIndex => $params{cpqFcaLogDrvBoxIndex},
cpqFcaLogDrvIndex => $params{cpqFcaLogDrvIndex},
cpqFcaLogDrvFaultTol => $params{cpqFcaLogDrvFaultTol},
cpqFcaLogDrvStatus => $params{cpqFcaLogDrvStatus},
cpqFcaLogDrvPercentRebuild => $params{cpqFcaLogDrvPercentRebuild},
cpqFcaLogDrvSize => $params{cpqFcaLogDrvSize},
cpqFcaLogDrvPhyDrvIDs => $params{cpqFcaLogDrvPhyDrvIDs},
cpqFcaLogDrvCondition => $params{cpqFcaLogDrvCondition},
blacklisted => 0,
};
bless $self, $class;
$self->{name} = $params{name} ||
$self->{cpqFcaLogDrvBoxIndex}.':'.
$self->{cpqFcaLogDrvIndex};
$self->{controllerindex} = $self->{cpqFcaLogDrvBoxIndex};
return $self;
}
sub check {
my $self = shift;
$self->blacklist('fcald', $self->{name});
if ($self->{cpqFcaLogDrvCondition} ne "ok") {
if ($self->{cpqFcaLogDrvStatus} =~
/rebuild|recovering|expand/) {
$self->add_message(WARNING,
sprintf "logical drive %s is %s (%s)",
$self->{name}, $self->{cpqFcaLogDrvStatus},
$self->{cpqFcaLogDrvFaultTol});
} else {
$self->add_message(CRITICAL,
sprintf "logical drive %s is %s (%s)",
$self->{name}, $self->{cpqFcaLogDrvStatus},
$self->{cpqFcaLogDrvFaultTol});
}
}
$self->add_info(
sprintf "logical drive %s is %s (%s)", $self->{name},
$self->{cpqFcaLogDrvStatus}, $self->{cpqFcaLogDrvFaultTol});
}
sub dump {
my $self = shift;
printf "[LOGICAL_DRIVE]\n";
foreach (qw(cpqFcaLogDrvBoxIndex cpqFcaLogDrvIndex cpqFcaLogDrvFaultTol
cpqFcaLogDrvStatus cpqFcaLogDrvPercentRebuild cpqFcaLogDrvSize
cpqFcaLogDrvPhyDrvIDs cpqFcaLogDrvCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Fca::PhysicalDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
cpqFcaPhyDrvBoxIndex => $params{cpqFcaPhyDrvBoxIndex},
cpqFcaPhyDrvIndex => $params{cpqFcaPhyDrvIndex},
cpqFcaPhyDrvModel => $params{cpqFcaPhyDrvModel},
cpqFcaPhyDrvBay => $params{cpqFcaPhyDrvBay},
cpqFcaPhyDrvStatus => $params{cpqFcaPhyDrvStatus},
cpqFcaPhyDrvCondition => $params{cpqFcaPhyDrvCondition},
cpqFcaPhyDrvSize => $params{cpqFcaPhyDrvSize},
cpqFcaPhyDrvBusNumber => $params{cpqFcaPhyDrvBusNumber},
blacklisted => 0,
};
$self->{name} = $params{name} ||
$self->{cpqFcaPhyDrvBoxIndex}.':'.$self->{cpqFcaPhyDrvIndex}; ####vorerst
$self->{controllerindex} = $self->{cpqScsiPhyDrvCntlrIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('fcapd', $self->{name});
if ($self->{cpqFcaPhyDrvStatus} eq 'unconfigured') {
# not part of a logical drive
# condition will surely be other
} elsif ($self->{cpqFcaPhyDrvCondition} ne 'ok') {
$self->add_message(CRITICAL,
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqFcaPhyDrvStatus});
}
$self->add_info(
sprintf "physical drive %s is %s",
$self->{name}, $self->{cpqFcaPhyDrvStatus});
}
sub dump {
my $self = shift;
printf "[PHYSICAL_DRIVE]\n";
foreach (qw(cpqFcaPhyDrvBoxIndex cpqFcaPhyDrvIndex cpqFcaPhyDrvModel
cpqFcaPhyDrvBay cpqFcaPhyDrvStatus cpqFcaPhyDrvCondition
cpqFcaPhyDrvSize cpqFcaPhyDrvBusNumber)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::Proliant::Component::DiskSubsystem::Fca::SpareDrive;
our @ISA = qw(HP::Proliant::Component::DiskSubsystem::Fca);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub dump {
my $self = shift;
printf "[SPARE_DRIVE]\n";
}
package HP::Proliant::Component::DiskSubsystem;
our @ISA = qw(HP::Proliant::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
da_subsystem => undef,
sas_da_subsystem => undef,
ide_da_subsystem => undef,
fca_da_subsystem => undef,
scsi_da_subsystem => undef,
condition => $params{condition},
blacklisted => 0,
};
bless $self, $class;
$self->init();
return $self;
}
sub init {
my $self = shift;
$self->{da_subsystem} = HP::Proliant::Component::DiskSubsystem::Da->new(
runtime => $self->{runtime},
rawdata => $self->{rawdata},
method => $self->{method},
);
$self->{sas_subsystem} = HP::Proliant::Component::DiskSubsystem::Sas->new(
runtime => $self->{runtime},
rawdata => $self->{rawdata},
method => $self->{method},
);
$self->{scsi_subsystem} = HP::Proliant::Component::DiskSubsystem::Scsi->new(
runtime => $self->{runtime},
rawdata => $self->{rawdata},
method => $self->{method},
);
$self->{ide_subsystem} = HP::Proliant::Component::DiskSubsystem::Ide->new(
runtime => $self->{runtime},
rawdata => $self->{rawdata},
method => $self->{method},
);
$self->{fca_subsystem} = HP::Proliant::Component::DiskSubsystem::Fca->new(
runtime => $self->{runtime},
rawdata => $self->{rawdata},
method => $self->{method},
);
}
sub check {
my $self = shift;
$self->add_info('checking disk subsystem');
$self->{da_subsystem}->check();
$self->{sas_subsystem}->check();
$self->{scsi_subsystem}->check();
$self->{ide_subsystem}->check();
$self->{fca_subsystem}->check();
$self->disk_summary();
}
sub dump {
my $self = shift;
$self->{da_subsystem}->dump();
$self->{sas_subsystem}->dump();
$self->{scsi_subsystem}->dump();
$self->{ide_subsystem}->dump();
$self->{fca_subsystem}->dump();
}
sub disk_summary {
my $self = shift;
foreach my $subsys (qw(da sas scsi ide fca)) {
if (my $pd = $self->{$subsys.'_subsystem'}->has_physical_drives()) {
my $ld = $self->{$subsys.'_subsystem'}->has_logical_drives();
$self->add_summary(sprintf '%s: %d logical drives, %d physical drives',
$subsys, $ld, $pd);
}
}
}
sub assemble {
my $self = shift;
$self->trace(3, sprintf "%s controllers und platten zusammenf<6E>hren",
ref($self));
$self->trace(3, sprintf "has %d controllers",
scalar(@{$self->{controllers}}));
$self->trace(3, sprintf "has %d accelerators",
scalar(@{$self->{accelerators}})) if exists $self->{accelerators};
$self->trace(3, sprintf "has %d physical_drives",
scalar(@{$self->{physical_drives}}));
$self->trace(3, sprintf "has %d logical_drives",
scalar(@{$self->{logical_drives}}));
$self->trace(3, sprintf "has %d spare_drives",
scalar(@{$self->{spare_drives}}));
my $found = {
accelerators => {},
logical_drives => {},
physical_drives => {},
spare_drives => {},
};
# found->{komponente}->{controllerindex} ist ein array
# von teilen, die zu einem controller gehoeren
foreach my $item (qw(accelerators logical_drives physical_drives spare_drives)) {
foreach (@{$self->{$item}}) {
$found->{item}->{$_->{controllerindex}} = []
unless exists $found->{$item}->{$_->{controllerindex}};
push(@{$found->{$item}->{$_->{controllerindex}}}, $_);
}
}
foreach my $item (qw(accelerators logical_drives physical_drives spare_drives)) {
foreach (@{$self->{controllers}}) {
if (exists $found->{$item}->{$_->{controllerindex}}) {
$_->{$item} = $found->{$item}->{$_->{controllerindex}};
delete $found->{$item}->{$_->{controllerindex}};
} else {
$_->{$item} = []; # z.b. ein leerer controller: physical_drives = []
}
}
}
# was jetzt noch in $found uebrig ist, gehoert zu keinem controller
# d.h. komponenten mit ungueltigen cnrtlindex wurden gefunden
}
sub has_controllers {
my $self = shift;
return scalar(@{$self->{controllers}});
}
sub has_accelerators {
my $self = shift;
return exists $self->{accelerators} ? scalar(@{$self->{accelerators}}) : 0;
}
sub has_physical_drives {
my $self = shift;
return scalar(@{$self->{physical_drives}});
}
sub has_logical_drives {
my $self = shift;
return scalar(@{$self->{logical_drives}});
}
package HP::Proliant::Component;
our @ISA = qw(HP::Proliant);
package HP::Proliant;
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
use Data::Dumper;
our @ISA = qw(HP::Server);
sub init {
my $self = shift;
$self->{components} = {
powersupply_subsystem => undef,
fan_subsystem => undef,
temperature_subsystem => undef,
cpu_subsystem => undef,
memory_subsystem => undef,
disk_subsystem => undef,
};
$self->{serial} = 'unknown';
$self->{product} = 'unknown';
$self->{romversion} = 'unknown';
$self->collect();
if (! $self->{runtime}->{plugin}->check_messages() &&
! exists $self->{noinst_hint}) {
$self->set_serial();
$self->check_for_buggy_firmware();
$self->analyze_cpus();
$self->analyze_powersupplies();
$self->analyze_fan_subsystem();
$self->analyze_temperatures();
$self->analyze_memory_subsystem();
$self->analyze_disk_subsystem();
$self->auto_blacklist();
$self->check_cpus();
$self->check_powersupplies();
$self->check_fan_subsystem();
$self->check_temperatures();
$self->check_memory_subsystem();
$self->check_disk_subsystem();
}
}
sub identify {
my $self = shift;
return sprintf "System: '%s', S/N: '%s', ROM: '%s'",
$self->{product}, $self->{serial}, $self->{romversion};
}
sub check_for_buggy_firmware {
my $self = shift;
my @buggyfirmwares = (
"P24 12/11/2001",
"P24 11/15/2002",
"D13 06/03/2003",
"D13 09/15/2004",
"P20 12/17/2002"
);
$self->{runtime}->{options}->{buggy_firmware} =
grep /^$self->{romversion}/, @buggyfirmwares;
}
sub dump {
my $self = shift;
printf STDERR "serial %s\n", $self->{serial};
printf STDERR "product %s\n", $self->{product};
printf STDERR "romversion %s\n", $self->{romversion};
printf STDERR "%s\n", Data::Dumper::Dumper($self->{components});
}
sub analyze_powersupplies {
my $self = shift;
$self->{components}->{powersupply_subsystem} =
HP::Proliant::Component::PowersupplySubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_fan_subsystem {
my $self = shift;
$self->{components}->{fan_subsystem} =
HP::Proliant::Component::FanSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_temperatures {
my $self = shift;
$self->{components}->{temperature_subsystem} =
HP::Proliant::Component::TemperatureSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_cpus {
my $self = shift;
$self->{components}->{cpu_subsystem} =
HP::Proliant::Component::CpuSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_memory_subsystem {
my $self = shift;
$self->{components}->{memory_subsystem} =
HP::Proliant::Component::MemorySubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_disk_subsystem {
my $self = shift;
$self->{components}->{disk_subsystem} =
HP::Proliant::Component::DiskSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub check_cpus {
my $self = shift;
$self->{components}->{cpu_subsystem}->check();
$self->{components}->{cpu_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_powersupplies {
my $self = shift;
$self->{components}->{powersupply_subsystem}->check();
$self->{components}->{powersupply_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_fan_subsystem {
my $self = shift;
$self->{components}->{fan_subsystem}->check();
$self->{components}->{fan_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_temperatures {
my $self = shift;
$self->{components}->{temperature_subsystem}->check();
$self->{components}->{temperature_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_memory_subsystem {
my $self = shift;
$self->{components}->{memory_subsystem}->check();
$self->{components}->{memory_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_disk_subsystem {
my $self = shift;
$self->{components}->{disk_subsystem}->check();
$self->{components}->{disk_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
# zum anhaengen an die normale ausgabe... da: 2 logical drives, 5 physical...
$self->{runtime}->{plugin}->add_message(OK,
$self->{components}->{disk_subsystem}->{summary})
if $self->{components}->{disk_subsystem}->{summary};
}
sub auto_blacklist() {
my $self = shift;
if ($self->{product} =~ /380 g6/) {
# http://bizsupport1.austin.hp.com/bc/docs/support/SupportManual/c01723408/c01723408.pdf seite 19
if ($self->{components}->{cpu_subsystem}->num_cpus() == 1) {
$self->add_blacklist('ff/f:5,6');
}
} elsif ($self->{product} =~ /380 g6/) {
# http://bizsupport1.austin.hp.com/bc/docs/support/SupportManual/c01704762/c01704762.pdf Fan 2 is only required when processor 2 is installed in the server.
}
}
package HP::Proliant::CLI;
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
our @ISA = qw(HP::Proliant);
sub collect {
my $self = shift;
my $hpasmcli = undef;
if (($self->{runtime}->{plugin}->opts->hpasmcli) &&
(-f $self->{runtime}->{plugin}->opts->hpasmcli) &&
(! -x $self->{runtime}->{plugin}->opts->hpasmcli)) {
no strict 'refs';
open(BIRK, $self->{runtime}->{plugin}->opts->hpasmcli);
# all output in one file prefixed with server|powersupply|fans|temp|dimm
while(<BIRK>) {
chomp;
$self->{rawdata} .= $_."\n";
}
close BIRK;
# If you run this script and redirect it's output to a file
# you can use it for testing purposes with
# --hpasmcli <output>
# It must not be executable. (chmod 644)
my $diag = <<'EOEO';
hpasmcli=$(which hpasmcli)
hpacucli=$(which hpacucli)
for i in server powersupply fans temp dimm
do
$hpasmcli -s "show $i" | while read line
do
printf "%s %s\n" $i "$line"
done
done
if [ -x "$hpacucli" ]; then
for i in config status
do
$hpacucli ctrl all show $i | while read line
do
printf "%s %s\n" $i "$line"
done
done
fi
EOEO
} else {
#die "exec hpasmcli";
# alles einsammeln und in rawdata stecken
my $hpasmcli = undef;
$hpasmcli = $self->{runtime}->{plugin}->opts->hpasmcli ?
$self->{runtime}->{plugin}->opts->hpasmcli : '/sbin/hpasmcli';
# check if this exists at all
# descend the directory
if ($< != 0) {
$hpasmcli = "sudo ".$hpasmcli;
}
$self->trace(2, sprintf "calling %s\n", $hpasmcli);
$self->check_daemon();
if (! $self->{runtime}->{plugin}->check_messages()) {
$self->check_hpasm_client($hpasmcli);
if (! $self->{runtime}->{plugin}->check_messages()) {
foreach my $component (qw(server fans temp dimm powersupply)) {
if (open HPASMCLI, "$hpasmcli -s \"show $component\"|") {
my @output = <HPASMCLI>;
close HPASMCLI;
$self->{rawdata} .= join("\n", map {
$component.' '.$_;
} @output);
}
}
if ($self->{runtime}->{options}->{hpacucli}) {
#1 oder 0. pfad selber finden
my $hpacucli = undef;
if (-e '/usr/sbin/hpacucli') {
$hpacucli = '/usr/sbin/hpacucli';
} elsif (-e '/usr/local/sbin/hpacucli') {
$hpacucli = '/usr/local/sbin/hpacucli';
} else {
$hpacucli = $hpasmcli;
$hpacucli =~ s/^sudo\s*//;
$hpacucli =~ s/hpasmcli/hpacucli/;
$hpacucli = -e $hpacucli ? $hpacucli : undef;
}
if ($hpacucli) {
if ($< != 0) {
$hpacucli = "sudo ".$hpacucli;
}
$self->trace(2, sprintf "calling %s\n", $hpacucli);
$self->check_hpacu_client($hpacucli);
if (! $self->{runtime}->{plugin}->check_messages()) {
if (open HPACUCLI, "$hpacucli ctrl all show config 2>&1|") {
my @output = <HPACUCLI>;
close HPACUCLI;
$self->{rawdata} .= join("\n", map {
'config '.$_;
} @output);
}
if (open HPACUCLI, "$hpacucli ctrl all show status 2>&1|") {
my @output = <HPACUCLI>;
close HPACUCLI;
$self->{rawdata} .= join("\n", map {
'status '.$_;
} @output);
}
}
} else {
if ($self->{runtime}->{options}->{noinstlevel} eq 'ok') {
$self->add_message(OK,
'hpacucli is not installed. let\'s hope the best...');
} else {
$self->add_message(
uc $self->{runtime}->{options}->{noinstlevel},
'hpacucli is not installed.');
}
}
}
}
}
}
}
sub check_daemon {
my $self = shift;
my $multiproc_os_signatures_files = {
'/etc/SuSE-release' => 'VERSION\s*=\s*8',
'/etc/trustix-release' => '.*',
'/etc/redhat-release' => '.*Pensacola.*',
'/etc/debian_version' => '3\.1',
'/etc/issue' => '.*Kernel 2\.4\.9-vmnix2.*', # VMware ESX Server 2.5.4
};
if (open PS, "/bin/ps -e -ocmd|") {
my $numprocs = 0;
my $numcliprocs = 0;
my @procs = <PS>;
close PS;
$numprocs = grep /hpasm.*d$/, map { (split /\s+/, $_)[0] } @procs;
$numcliprocs = grep /hpasmcli/, grep !/check_hpasm/, @procs;
if (! $numprocs ) {
$self->add_message(CRITICAL, 'hpasmd needs to be restarted');
} elsif ($numprocs > 1) {
my $known = 0;
foreach my $osfile (keys %{$multiproc_os_signatures_files}) {
if (-f $osfile) {
open OSSIG, $osfile;
if (grep /$multiproc_os_signatures_files->{$osfile}/, <OSSIG>) {
$known = 1;
}
close OSSIG;
}
}
if (! $known) {
$self->add_message(UNKNOWN, 'multiple hpasmd procs');
}
}
if ($numcliprocs == 1) {
$self->add_message(UNKNOWN, 'another hpasmdcli is running');
} elsif ($numcliprocs > 1) {
$self->add_message(UNKNOWN, 'hanging hpasmdcli processes');
}
}
}
sub check_hpasm_client {
my $self = shift;
my $hpasmcli = shift;
if (open HPASMCLI, "$hpasmcli -s help 2>&1 |") {
my @output = <HPASMCLI>;
close HPASMCLI;
if (grep /Could not communicate with hpasmd/, @output) {
$self->add_message(CRITICAL, 'hpasmd needs to be restarted');
} elsif (grep /(asswor[dt]:)|(You must be root)/, @output) {
$self->add_message(UNKNOWN,
sprintf "insufficient rights to call %s", $hpasmcli);
} elsif (grep /must have a tty/, @output) {
$self->add_message(CRITICAL,
'sudo must be configured with requiretty=no (man sudo)');
} elsif (! grep /CLEAR/, @output) {
$self->add_message(UNKNOWN,
sprintf "insufficient rights to call %s", $hpasmcli);
}
} else {
$self->add_message(UNKNOWN,
sprintf "insufficient rights to call %s", $hpasmcli);
}
}
sub check_hpacu_client {
my $self = shift;
my $hpacucli = shift;
if (open HPACUCLI, "$hpacucli help 2>&1 |") {
my @output = <HPACUCLI>;
close HPACUCLI;
if (grep /Another instance of hpacucli is running/, @output) {
$self->add_message(UNKNOWN, 'another hpacucli is running');
} elsif (grep /You need to have administrator rights/, @output) {
$self->add_message(UNKNOWN,
sprintf "insufficient rights to call %s", $hpacucli);
} elsif (grep /(asswor[dt]:)|(You must be root)/, @output) {
$self->add_message(UNKNOWN,
sprintf "insufficient rights to call %s", $hpacucli);
} elsif (! grep /CLI Syntax/, @output) {
$self->add_message(UNKNOWN,
sprintf "insufficient rights to call %s", $hpacucli);
}
} else {
$self->add_message(UNKNOWN,
sprintf "insufficient rights to call %s", $hpacucli);
}
}
sub set_serial {
my $self = shift;
foreach (grep(/^server/, split(/\n/, $self->{rawdata}))) {
if (/System\s+:\s+(.*[^\s])/) {
$self->{product} = lc $1;
} elsif (/Serial No\.\s+:\s+(\w+)/) {
$self->{serial} = $1;
} elsif (/ROM version\s+:\s+(.*[^\s])/) {
$self->{romversion} = $1;
}
}
$self->{serial} = $self->{serial};
$self->{product} = lc $self->{product};
$self->{romversion} = $self->{romversion};
}
package HP::Proliant::SNMP;
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
our @ISA = qw(HP::Proliant);
sub collect {
my $self = shift;
if ($self->{runtime}->{plugin}->opts->snmpwalk) {
my $cpqSeMibCondition = '1.3.6.1.4.1.232.1.1.3.0'; # 2=ok
my $cpqHeMibCondition = '1.3.6.1.4.1.232.6.1.3.0'; # hat nicht jeder
if ($self->{productname} =~ /4LEE/) {
# rindsarsch!
$self->{rawdata}->{$cpqHeMibCondition} = 0;
}
if (! exists $self->{rawdata}->{$cpqHeMibCondition} &&
! exists $self->{rawdata}->{$cpqSeMibCondition}) { # vlt. geht doch was
$self->add_message(CRITICAL,
'snmpwalk returns no health data (cpqhlth-mib)');
}
} else {
my $net_snmp_version = Net::SNMP->VERSION(); # 5.002000 or 6.000000
#$params{'-translate'} = [
# -all => 0x0
#];
my ($session, $error) =
Net::SNMP->session(%{$self->{runtime}->{snmpparams}});
if (! defined $session) {
$self->{plugin}->add_message(CRITICAL, 'cannot create session object');
$self->trace(1, Data::Dumper::Dumper($self->{runtime}->{snmpparams}));
} else {
# revMajor is often used for discovery of hp devices
my $cpqHeMibRev = '1.3.6.1.4.1.232.6.1';
my $cpqHeMibRevMajor = '1.3.6.1.4.1.232.6.1.1.0';
my $cpqHeMibCondition = '1.3.6.1.4.1.232.6.1.3.0';
my $result = $session->get_request(
-varbindlist => [$cpqHeMibCondition]
);
if ($self->{productname} =~ /4LEE/) {
# rindsarsch!
$result->{$cpqHeMibCondition} = 0;
}
if (!defined($result) ||
$result->{$cpqHeMibCondition} eq 'noSuchInstance' ||
$result->{$cpqHeMibCondition} eq 'noSuchObject' ||
$result->{$cpqHeMibCondition} eq 'endOfMibView') {
$self->add_message(CRITICAL,
'snmpwalk returns no health data (cpqhlth-mib)');
$session->close;
} else {
# this is not reliable. many agents return 4=failed
#if ($result->{$cpqHeMibCondition} != 2) {
# $obstacle = "cmapeerstart";
#}
}
}
if (! $self->{runtime}->{plugin}->check_messages()) {
# snmp peer is alive
$self->trace(2, sprintf "Protocol is %s",
$self->{runtime}->{snmpparams}->{'-version'});
my $cpqStdEquipment = "1.3.6.1.4.1.232";
my $cpqSeProcessor = "1.3.6.1.4.1.232.1.2.2";
my $cpqSeRom = "1.3.6.1.4.1.232.1.2.6";
my $cpqHeComponent = "1.3.6.1.4.1.232.6.2";
my $cpqHePWSComponent = "1.3.6.1.4.1.232.6.2.9";
my $cpqHeThermal = "1.3.6.1.4.1.232.6.2.6";
#my $cpqHeFComponent = "1.3.6.1.4.1.232.6.2.6.7";
#my $cpqHeTComponent = "1.3.6.1.4.1.232.6.2.6.8";
my $cpqHeMComponent = "1.3.6.1.4.1.232.6.2.14";
my $cpqDaComponent = "1.3.6.1.4.1.232.3.2";
my $cpqSasComponent = "1.3.6.1.4.1.232.5";
my $cpqIdeComponent = "1.3.6.1.4.1.232.14";
my $cpqFcaComponent = "1.3.6.1.4.1.232.16.2";
my $cpqSiComponent = "1.3.6.1.4.1.232.2.2";
$session->translate;
my $response = {}; #break the walk up in smaller pieces
my $tic = time; my $tac = $tic;
my $response1 = $session->get_table(
-baseoid => $cpqSeProcessor);
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqSeProcessor (%d oids)",
$tac - $tic, scalar(keys %{$response1}));
# Walk for PowerSupply
$tic = time;
my $response2p = $session->get_table(
-maxrepetitions => 1,
-baseoid => $cpqHePWSComponent);
if (scalar (keys %{$response2p}) == 0) {
$self->trace(2, sprintf "maxrepetitions failed. fallback");
$response2p = $session->get_table(
-baseoid => $cpqHePWSComponent);
}
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqHePWSComponent (%d oids)",
$tac - $tic, scalar(keys %{$response2p}));
# Walk for Fans/Temp/Overall
$tic = time;
my $response2f = $session->get_table(
-maxrepetitions => 1,
-baseoid => $cpqHeThermal);
if (scalar (keys %{$response2f}) == 0) {
$self->trace(2, sprintf "maxrepetitions failed. fallback");
$response2f = $session->get_table(
-baseoid => $cpqHeThermal);
}
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqHeThermal (%d oids)",
$tac - $tic, scalar(keys %{$response2f}));
# # Walk for Fans
# $tic = time;
# my $response2f = $session->get_table(
# -maxrepetitions => 1,
# -baseoid => $cpqHeFComponent);
# if (scalar (keys %{$response2f}) == 0) {
# $self->trace(2, sprintf "maxrepetitions failed. fallback");
# $response2f = $session->get_table(
# -baseoid => $cpqHeFComponent);
# }
# $tac = time;
# $self->trace(2, sprintf "%03d seconds for walk cpqHeFComponent (%d oids)",
# $tac - $tic, scalar(keys %{$response2f}));
# # Walk for Temp
# $tic = time;
# my $response2t = $session->get_table(
# -maxrepetitions => 1,
# -baseoid => $cpqHeTComponent);
# if (scalar (keys %{$response2t}) == 0) {
# $self->trace(2, sprintf "maxrepetitions failed. fallback");
# $response2t = $session->get_table(
# -baseoid => $cpqHeTComponent);
# }
# $tac = time;
# $self->trace(2, sprintf "%03d seconds for walk cpqHeTComponent (%d oids)",
# $tac - $tic, scalar(keys %{$response2t}));
# Walk for Mem
$tic = time;
my $response2m = $session->get_table(
-maxrepetitions => 1,
-baseoid => $cpqHeMComponent);
if (scalar (keys %{$response2m}) == 0) {
$self->trace(2, sprintf "maxrepetitions failed. fallback");
$response2m = $session->get_table(
-baseoid => $cpqHeMComponent);
}
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqHeMComponent (%d oids)",
$tac - $tic, scalar(keys %{$response2m}));
#
$tic = time;
my $response3 = $session->get_table(
-baseoid => $cpqDaComponent);
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqDaComponent (%d oids)",
$tac - $tic, scalar(keys %{$response3}));
$tic = time;
my $response4 = $session->get_table(
-baseoid => $cpqSiComponent);
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqSiComponent (%d oids)",
$tac - $tic, scalar(keys %{$response4}));
$tic = time;
my $response5 = $session->get_table(
-baseoid => $cpqSeRom);
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqSeRom (%d oids)",
$tac - $tic, scalar(keys %{$response5}));
$tic = time;
my $response6 = $session->get_table(
-baseoid => $cpqSasComponent);
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqSasComponent (%d oids)",
$tac - $tic, scalar(keys %{$response6}));
$tic = time;
my $response7 = $session->get_table(
-baseoid => $cpqIdeComponent);
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqIdeComponent (%d oids)",
$tac - $tic, scalar(keys %{$response7}));
$tic = time;
my $response8 = $session->get_table(
-baseoid => $cpqFcaComponent);
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqFcaComponent (%d oids)",
$tac - $tic, scalar(keys %{$response8}));
$tic = time;
$session->close;
map { $response->{$_} = $response1->{$_} } keys %{$response1};
map { $response->{$_} = $response2p->{$_} } keys %{$response2p};
map { $response->{$_} = $response2f->{$_} } keys %{$response2f};
# map { $response->{$_} = $response2t->{$_} } keys %{$response2t};
map { $response->{$_} = $response2m->{$_} } keys %{$response2m};
map { $response->{$_} = $response3->{$_} } keys %{$response3};
map { $response->{$_} = $response4->{$_} } keys %{$response4};
map { $response->{$_} = $response5->{$_} } keys %{$response5};
map { $response->{$_} = $response6->{$_} } keys %{$response6};
map { $response->{$_} = $response7->{$_} } keys %{$response7};
map { $response->{$_} = $response8->{$_} } keys %{$response8};
map { $response->{$_} =~ s/^\s+//; $response->{$_} =~ s/\s+$//; }
keys %$response;
$self->{rawdata} = $response;
}
}
return $self->{runtime}->{plugin}->check_messages();
}
sub set_serial {
my $self = shift;
my $cpqSiSysSerialNum = "1.3.6.1.4.1.232.2.2.2.1.0";
my $cpqSiProductName = "1.3.6.1.4.1.232.2.2.4.2.0";
my $cpqSeSysRomVer = "1.3.6.1.4.1.232.1.2.6.1.0";
$self->{serial} =
SNMP::Utils::get_object($self->{rawdata}, $cpqSiSysSerialNum);
$self->{product} =
SNMP::Utils::get_object($self->{rawdata}, $cpqSiProductName);
$self->{romversion} =
SNMP::Utils::get_object($self->{rawdata}, $cpqSeSysRomVer);
if ($self->{romversion} && $self->{romversion} =~
#/(\d{2}\/\d{2}\/\d{4}).*?([ADP]{1}\d{2}).*/) {
/(\d{2}\/\d{2}\/\d{4}).*?Family.*?([A-Z]{1})(\d+).*/) {
$self->{romversion} = sprintf("%s%02d %s", $2, $3, $1);
} elsif ($self->{romversion} && $self->{romversion} =~
/([ADP]{1}\d{2})\-(\d{2}\/\d{2}\/\d{4})/) {
$self->{romversion} = sprintf("%s %s", $1, $2);
}
if (!$self->{serial} && $self->{romversion}) {
# this probably is a very, very old server.
$self->{serial} = "METHUSALEM";
$self->{runtime}->{scrapiron} = 1;
}
$self->{serial} = $self->{serial};
$self->{product} = lc $self->{product};
$self->{romversion} = $self->{romversion};
$self->{runtime}->{product} = $self->{product};
}
package HP::BladeSystem::Component::CommonEnclosureSubsystem;
our @ISA = qw(HP::BladeSystem::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
common_enclosures => [],
common_enclosure_temps => [],
common_enclosure_fan_subsys => undef,
common_enclosure_fuses => [],
common_enclosure_frus => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub init {
my $self = shift;
# jeweils ein block fuer
# enclosures, temps, fans, fuses
# loop ueber oids und entspr. new
my $oids = {
cpqRackCommonEnclosureEntry => '1.3.6.1.4.1.232.22.2.3.1.1.1',
cpqRackCommonEnclosureRack => '1.3.6.1.4.1.232.22.2.3.1.1.1.1',
cpqRackCommonEnclosureIndex => '1.3.6.1.4.1.232.22.2.3.1.1.1.2',
cpqRackCommonEnclosureModel => '1.3.6.1.4.1.232.22.2.3.1.1.1.3',
cpqRackCommonEnclosureSerialNum => '1.3.6.1.4.1.232.22.2.3.1.1.1.7',
cpqRackCommonEnclosureFWRev => '1.3.6.1.4.1.232.22.2.3.1.1.1.8',
cpqRackCommonEnclosureName => '1.3.6.1.4.1.232.22.2.3.1.1.1.9',
cpqRackCommonEnclosureCondition => '1.3.6.1.4.1.232.22.2.3.1.1.1.16',
cpqRackCommonEnclosureHasServerBlades => '1.3.6.1.4.1.232.22.2.3.1.1.1.17',
cpqRackCommonEnclosureHasPowerBlades => '1.3.6.1.4.1.232.22.2.3.1.1.1.18',
cpqRackCommonEnclosureHasNetConnectors => '1.3.6.1.4.1.232.22.2.3.1.1.1.19',
cpqRackCommonEnclosureHasTempSensors => '1.3.6.1.4.1.232.22.2.3.1.1.1.20',
cpqRackCommonEnclosureHasFans => '1.3.6.1.4.1.232.22.2.3.1.1.1.21',
cpqRackCommonEnclosureHasFuses => '1.3.6.1.4.1.232.22.2.3.1.1.1.22',
cpqRackCommonEnclosureConditionValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
},
cpqRackCommonEnclosureHasServerBladesValue => {
1 => 'false',
2 => 'true',
},
};
$oids->{cpqRackCommonEnclosureHasPowerBladesValue} =
$oids->{cpqRackCommonEnclosureHasServerBladesValue};
$oids->{cpqRackCommonEnclosureHasNetConnectorsValue} =
$oids->{cpqRackCommonEnclosureHasServerBladesValue};
$oids->{cpqRackCommonEnclosureHasTempSensorsValue} =
$oids->{cpqRackCommonEnclosureHasServerBladesValue};
$oids->{cpqRackCommonEnclosureHasFansValue} =
$oids->{cpqRackCommonEnclosureHasServerBladesValue};
$oids->{cpqRackCommonEnclosureHasServerBladesValue} =
$oids->{cpqRackCommonEnclosureHasServerBladesValue};
# INDEX { cpqRackCommonEnclosureRack cpqRackCommonEnclosureIndex }
foreach ($self->get_entries($oids, 'cpqRackCommonEnclosureEntry')) {
push(@{$self->{common_enclosures}},
HP::BladeSystem::Component::CommonEnclosureSubsystem::CommonEnclosure->new(%{$_}));
}
$self->{common_enclosure_fan_subsys} = HP::BladeSystem::Component::CommonEnclosureSubsystem::FanSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub check {
my $self = shift;
foreach (@{$self->{common_enclosures}}) {
$_->check();
}
$self->{common_enclosure_fan_subsys}->check();
}
sub dump {
my $self = shift;
foreach (@{$self->{common_enclosures}}) {
$_->dump();
}
$self->{common_enclosure_fan_subsys}->dump();
}
package HP::BladeSystem::Component::CommonEnclosureSubsystem::CommonEnclosure;
our @ISA = qw(HP::BladeSystem::Component::CommonEnclosureSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
cpqRackCommonEnclosureRack => $params{cpqRackCommonEnclosureRack},
cpqRackCommonEnclosureIndex => $params{cpqRackCommonEnclosureIndex},
cpqRackCommonEnclosureModel => $params{cpqRackCommonEnclosureModel},
cpqRackCommonEnclosureSerialNum => $params{cpqRackCommonEnclosureSerialNum},
cpqRackCommonEnclosureFWRev => $params{cpqRackCommonEnclosureFWRev},
cpqRackCommonEnclosureName => $params{cpqRackCommonEnclosureName},
cpqRackCommonEnclosureCondition => $params{cpqRackCommonEnclosureCondition},
cpqRackCommonEnclosureHasServerBlades => $params{cpqRackCommonEnclosureHasServerBlades},
cpqRackCommonEnclosureHasPowerBlades => $params{cpqRackCommonEnclosureHasPowerBlades},
cpqRackCommonEnclosureHasNetConnectors => $params{cpqRackCommonEnclosureHasNetConnectors},
cpqRackCommonEnclosureHasTempSensors => $params{cpqRackCommonEnclosureHasTempSensors},
cpqRackCommonEnclosureHasFans => $params{cpqRackCommonEnclosureHasFans},
cpqRackCommonEnclosureHasFuses => $params{cpqRackCommonEnclosureHasFuses},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
$self->{name} = $self->{cpqRackCommonEnclosureRack}.':'.$self->{cpqRackCommonEnclosureIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('ce', $self->{cpqRackCommonEnclosureName});
my $info = sprintf 'common enclosure %s condition is %s',
$self->{cpqRackCommonEnclosureName}, $self->{cpqRackCommonEnclosureCondition};
$self->add_info($info);
if ($self->{cpqRackCommonEnclosureCondition} eq 'failed') {
$self->add_message(CRITICAL, $info);
} elsif ($self->{cpqRackCommonEnclosureCondition} eq 'degraded') {
$self->add_message(WARNING, $info);
}
}
sub dump {
my $self = shift;
printf "[COMMON_ENCLOSURE_%s]\n", $self->{cpqRackCommonEnclosureName};
foreach (qw(cpqRackCommonEnclosureRack cpqRackCommonEnclosureIndex cpqRackCommonEnclosureModel
cpqRackCommonEnclosureSerialNum cpqRackCommonEnclosureFWRev cpqRackCommonEnclosureName
cpqRackCommonEnclosureCondition cpqRackCommonEnclosureHasServerBlades
cpqRackCommonEnclosureHasPowerBlades cpqRackCommonEnclosureHasNetConnectors
cpqRackCommonEnclosureHasTempSensors cpqRackCommonEnclosureHasFans cpqRackCommonEnclosureHasFuses)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::BladeSystem::Component::CommonEnclosureSubsystem::FanSubsystem;
our @ISA = qw(HP::BladeSystem::Component::CommonEnclosureSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
blacklisted => 0,
fans => [],
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub init {
my $self = shift;
my $oids = {
cpqRackCommonEnclosureFanEntry => '1.3.6.1.4.1.232.22.2.3.1.3.1',
cpqRackCommonEnclosureFanRack => '1.3.6.1.4.1.232.22.2.3.1.3.1.1',
cpqRackCommonEnclosureFanChassis => '1.3.6.1.4.1.232.22.2.3.1.3.1.2',
cpqRackCommonEnclosureFanIndex => '1.3.6.1.4.1.232.22.2.3.1.3.1.3',
cpqRackCommonEnclosureFanEnclosureName => '1.3.6.1.4.1.232.22.2.3.1.3.1.4',
cpqRackCommonEnclosureFanLocation => '1.3.6.1.4.1.232.22.2.3.1.3.1.5',
cpqRackCommonEnclosureFanPartNumber => '1.3.6.1.4.1.232.22.2.3.1.3.1.6',
cpqRackCommonEnclosureFanSparePartNumber => '1.3.6.1.4.1.232.22.2.3.1.3.1.7',
cpqRackCommonEnclosureFanPresent => '1.3.6.1.4.1.232.22.2.3.1.3.1.8',
cpqRackCommonEnclosureFanRedundant => '1.3.6.1.4.1.232.22.2.3.1.3.1.9',
cpqRackCommonEnclosureFanRedundantGroupId => '1.3.6.1.4.1.232.22.2.3.1.3.1.10',
cpqRackCommonEnclosureFanCondition => '1.3.6.1.4.1.232.22.2.3.1.3.1.11',
cpqRackCommonEnclosureFanEnclosureSerialNum => '1.3.6.1.4.1.232.22.2.3.1.3.1.12',
cpqRackCommonEnclosureFanPresentValue => {
1 => 'other',
2 => 'absent',
3 => 'present',
},
cpqRackCommonEnclosureFanRedundantValue => {
0 => 'other', # meiner phantasie entsprungen, da sich hp nicht aeussert
1 => 'other',
2 => 'notRedundant',
3 => 'redundant',
},
cpqRackCommonEnclosureFanConditionValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
}
};
# INDEX { cpqRackCommonEnclosureFanRack, cpqRackCommonEnclosureFanChassis, cpqRackCommonEnclosureFanIndex }
foreach ($self->get_entries($oids, 'cpqRackCommonEnclosureFanEntry')) {
push(@{$self->{fans}},
HP::BladeSystem::Component::CommonEnclosureSubsystem::FanSubsystem::Fan->new(%{$_}));
}
}
sub check {
my $self = shift;
foreach (@{$self->{fans}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{fans}}) {
$_->dump();
}
}
package HP::BladeSystem::Component::CommonEnclosureSubsystem::FanSubsystem::Fan;
our @ISA = qw(HP::BladeSystem::Component::CommonEnclosureSubsystem::FanSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},cklisted => 0,
#params
cpqRackCommonEnclosureFanEntry => $params{cpqRackCommonEnclosureFanEntry},
cpqRackCommonEnclosureFanRack => $params{cpqRackCommonEnclosureFanRack},
cpqRackCommonEnclosureFanChassis => $params{cpqRackCommonEnclosureFanChassis},
cpqRackCommonEnclosureFanIndex => $params{cpqRackCommonEnclosureFanIndex},
cpqRackCommonEnclosureFanEnclosureName => $params{cpqRackCommonEnclosureFanEnclosureName},
cpqRackCommonEnclosureFanLocation => $params{cpqRackCommonEnclosureFanLocation},
cpqRackCommonEnclosureFanPartNumber => $params{cpqRackCommonEnclosureFanPartNumber},
cpqRackCommonEnclosureFanSparePartNumber => $params{cpqRackCommonEnclosureFanSparePartNumber},
cpqRackCommonEnclosureFanPresent => $params{cpqRackCommonEnclosureFanPresent},
cpqRackCommonEnclosureFanRedundant => $params{cpqRackCommonEnclosureFanRedundant},
cpqRackCommonEnclosureFanRedundantGroupId => $params{cpqRackCommonEnclosureFanRedundantGroupId},
cpqRackCommonEnclosureFanCondition => $params{cpqRackCommonEnclosureFanCondition},
cpqRackCommonEnclosureFanEnclosureSerialNum => $params{cpqRackCommonEnclosureFanEnclosureSerialNum},
info => undef,
extendedinfo => undef,
};
$self->{name} = $self->{cpqRackCommonEnclosureFanRack}.':'.$self->{cpqRackCommonEnclosureFanChassis}.':'.$self->{cpqRackCommonEnclosureFanIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('f', $self->{name});
$self->add_info(sprintf 'fan %s is %s, location is %s, redundance is %s',
$self->{name}, $self->{cpqRackCommonEnclosureFanPresent},
$self->{cpqRackCommonEnclosureFanLocation},
$self->{cpqRackCommonEnclosureFanRedundant});
if ($self->{cpqRackCommonEnclosureFanCondition} eq 'degraded') {
$self->add_message(WARNING, 'fan %s is %s', $self->{name},
$self->{cpqRackCommonEnclosureFanCondition});
} elsif ($self->{cpqRackCommonEnclosureFanCondition} eq 'failed') {
$self->add_message(CRITICAL, 'fan %s is %s', $self->{name},
$self->{cpqRackCommonEnclosureFanCondition});
}
}
sub dump {
my $self = shift;
printf "[FAN_%s]\n", $self->{name};
foreach (qw(cpqRackCommonEnclosureFanRack cpqRackCommonEnclosureFanChassis
cpqRackCommonEnclosureFanIndex cpqRackCommonEnclosureFanEnclosureName
cpqRackCommonEnclosureFanLocation cpqRackCommonEnclosureFanPartNumber
cpqRackCommonEnclosureFanSparePartNumber cpqRackCommonEnclosureFanPresent
cpqRackCommonEnclosureFanRedundant cpqRackCommonEnclosureFanRedundantGroupId
cpqRackCommonEnclosureFanCondition cpqRackCommonEnclosureFanEnclosureSerialNum)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "info: %s\n", $self->{info};
printf "\n";
}
package HP::BladeSystem::Component::PowerEnclosureSubsystem;
our @ISA = qw(HP::BladeSystem::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
power_enclosures => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub init {
my $self = shift;
# cpqRackPowerEnclosureTable
my $oids = {
cpqRackPowerEnclosureEntry => '1.3.6.1.4.1.232.22.2.3.3.1.1',
cpqRackPowerEnclosureRack => '1.3.6.1.4.1.232.22.2.3.3.1.1.1',
cpqRackPowerEnclosureIndex => '1.3.6.1.4.1.232.22.2.3.3.1.1.2',
cpqRackPowerEnclosureName => '1.3.6.1.4.1.232.22.2.3.3.1.1.3',
cpqRackPowerEnclosureMgmgtBoardSerialNum => '1.3.6.1.4.1.232.22.2.3.3.1.1.4',
cpqRackPowerEnclosureRedundant => '1.3.6.1.4.1.232.22.2.3.3.1.1.5',
cpqRackPowerEnclosureLoadBalanced => '1.3.6.1.4.1.232.22.2.3.3.1.1.6',
cpqRackPowerEnclosureInputPwrType => '1.3.6.1.4.1.232.22.2.3.3.1.1.7',
cpqRackPowerEnclosurePwrFeedMax => '1.3.6.1.4.1.232.22.2.3.3.1.1.8',
cpqRackPowerEnclosureCondition => '1.3.6.1.4.1.232.22.2.3.3.1.1.9',
cpqRackPowerEnclosureRedundantValue => {
1 => 'other',
2 => 'notRedundant',
3 => 'redundant',
},
cpqRackPowerEnclosureLoadBalancedValue => {
0 => 'aechz',
1 => 'other',
2 => 'notLoadBalanced',
3 => 'loadBalanced',
},
cpqRackPowerEnclosureInputPwrTypeValue => {
1 => 'other',
2 => 'singlePhase',
3 => 'threePhase',
4 => 'directCurrent',
},
cpqRackPowerEnclosureConditionValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
},
};
# INDEX { cpqRackPowerEnclosureRack, cpqRackPowerEnclosureIndex }
# dreckada dreck, dreckada
foreach ($self->get_entries($oids, 'cpqRackPowerEnclosureEntry')) {
push(@{$self->{power_enclosures}},
HP::BladeSystem::Component::PowerEnclosureSubsystem::PowerEnclosure->new(%{$_}));
}
}
sub check {
my $self = shift;
foreach (@{$self->{power_enclosures}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{power_enclosures}}) {
$_->dump();
}
}
package HP::BladeSystem::Component::PowerEnclosureSubsystem::PowerEnclosure;
our @ISA = qw(HP::BladeSystem::Component::PowerEnclosureSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
cpqRackPowerEnclosureEntry => $params{cpqRackPowerEnclosureEntry},
cpqRackPowerEnclosureRack => $params{cpqRackPowerEnclosureRack},
cpqRackPowerEnclosureIndex => $params{cpqRackPowerEnclosureIndex},
cpqRackPowerEnclosureName => $params{cpqRackPowerEnclosureName},
cpqRackPowerEnclosureMgmgtBoardSerialNum => $params{cpqRackPowerEnclosureMgmgtBoardSerialNum},
cpqRackPowerEnclosureRedundant => $params{cpqRackPowerEnclosureRedundant},
cpqRackPowerEnclosureLoadBalanced => $params{cpqRackPowerEnclosureLoadBalanced},
cpqRackPowerEnclosureInputPwrType => $params{cpqRackPowerEnclosureInputPwrType},
cpqRackPowerEnclosurePwrFeedMax => $params{cpqRackPowerEnclosurePwrFeedMax},
cpqRackPowerEnclosureCondition => $params{cpqRackPowerEnclosureCondition},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub check {
my $self = shift;
$self->blacklist('pe', $self->{cpqRackPowerEnclosureName});
my $info = sprintf 'power enclosure %s condition is %s',
$self->{cpqRackPowerEnclosureName}, $self->{cpqRackPowerEnclosureCondition};
$self->add_info($info);
if ($self->{cpqRackPowerEnclosureCondition} eq 'degraded') {
$self->add_message(WARNING, $info);
}
}
sub dump {
my $self = shift;
printf "[POWER_ENCLOSURE_%s]\n", $self->{cpqRackPowerEnclosureName};
foreach (qw(cpqRackPowerEnclosureRack cpqRackPowerEnclosureIndex
cpqRackPowerEnclosureName cpqRackPowerEnclosureMgmgtBoardSerialNum
cpqRackPowerEnclosureRedundant cpqRackPowerEnclosureLoadBalanced
cpqRackPowerEnclosureInputPwrType cpqRackPowerEnclosurePwrFeedMax
cpqRackPowerEnclosureCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::BladeSystem::Component::PowerSupplySubsystem;
our @ISA = qw(HP::BladeSystem::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
power_supplies => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub init {
my $self = shift;
my $oids = {
cpqRackPowerSupplyEntry => '1.3.6.1.4.1.232.22.2.5.1.1.1',
cpqRackPowerSupplyRack => '1.3.6.1.4.1.232.22.2.5.1.1.1.1',
cpqRackPowerSupplyChassis => '1.3.6.1.4.1.232.22.2.5.1.1.1.2',
cpqRackPowerSupplyIndex => '1.3.6.1.4.1.232.22.2.5.1.1.1.3',
cpqRackPowerSupplyEnclosureName => '1.3.6.1.4.1.232.22.2.5.1.1.1.4',
cpqRackPowerSupplyMaxPwrOutput => '1.3.6.1.4.1.232.22.2.5.1.1.1.9',
cpqRackPowerSupplyCurPwrOutput => '1.3.6.1.4.1.232.22.2.5.1.1.1.10',
cpqRackPowerSupplyIntakeTemp => '1.3.6.1.4.1.232.22.2.5.1.1.1.12',
cpqRackPowerSupplyExhaustTemp => '1.3.6.1.4.1.232.22.2.5.1.1.1.13',
cpqRackPowerSupplyStatus => '1.3.6.1.4.1.232.22.2.5.1.1.1.14',
cpqRackPowerSupplySupplyInputLineStatus => '1.3.6.1.4.1.232.22.2.5.1.1.1.15',
cpqRackPowerSupplyPresent => '1.3.6.1.4.1.232.22.2.5.1.1.1.16',
cpqRackPowerSupplyCondition => '1.3.6.1.4.1.232.22.2.5.1.1.1.17',
cpqRackPowerSupplySupplyInputLineStatusValue => {
1 => 'noError',
2 => 'lineOverVoltage',
3 => 'lineUnderVoltage',
4 => 'lineHit',
5 => 'brownOut',
6 => 'linePowerLoss',
},
cpqRackPowerSupplyStatusValue => {
1 => 'noError',
2 => 'generalFailure',
3 => 'bistFailure',
4 => 'fanFailure',
5 => 'tempFailure',
6 => 'interlockOpen',
7 => 'epromFailed',
8 => 'vrefFailed',
9 => 'dacFailed',
10 => 'ramTestFailed',
11 => 'voltageChannelFailed',
12 => 'orringdiodeFailed',
13 => 'brownOut',
14 => 'giveupOnStartup',
15 => 'nvramInvalid',
16 => 'calibrationTableInvalid',
},
cpqRackPowerSupplyPresentValue => {
1 => 'other',
2 => 'absent',
3 => 'present',
},
cpqRackPowerSupplyConditionValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
},
};
# INDEX { cpqRackPowerSupplyRack, cpqRackPowerSupplyChassis, cpqRackPowerSupplyIndex }
# dreckada dreck, dreckada
foreach ($self->get_entries($oids, 'cpqRackPowerSupplyEntry')) {
push(@{$self->{power_supplies}},
HP::BladeSystem::Component::PowerSupplySubsystem::PowerSupply->new(%{$_}));
}
my $total_power_output = 0;
foreach my $powersupply (@{$self->{power_supplies}}) {
$total_power_output += $powersupply->{cpqRackPowerSupplyCurPwrOutput};
}
$self->{runtime}->{plugin}->add_perfdata(
label => 'total_power_output',
value => $total_power_output,
uom => 'Watts',
);
}
sub check {
my $self = shift;
foreach (@{$self->{power_supplies}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{power_supplies}}) {
$_->dump();
}
}
package HP::BladeSystem::Component::PowerSupplySubsystem::PowerSupply;
our @ISA = qw(HP::BladeSystem::Component::PowerSupplySubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
cpqRackPowerSupplyRack => $params{cpqRackPowerSupplyRack},
cpqRackPowerSupplyChassis => $params{cpqRackPowerSupplyChassis},
cpqRackPowerSupplyIndex => $params{cpqRackPowerSupplyIndex},
cpqRackPowerSupplyEnclosureName => $params{cpqRackPowerSupplyEnclosureName},
cpqRackPowerSupplyMaxPwrOutput => $params{cpqRackPowerSupplyMaxPwrOutput},
cpqRackPowerSupplyCurPwrOutput => $params{cpqRackPowerSupplyCurPwrOutput},
cpqRackPowerSupplyIntakeTemp => $params{cpqRackPowerSupplyIntakeTemp},
cpqRackPowerSupplyExhaustTemp => $params{cpqRackPowerSupplyExhaustTemp},
cpqRackPowerSupplyStatus => $params{cpqRackPowerSupplyStatus},
cpqRackPowerSupplySupplyInputLineStatus => $params{cpqRackPowerSupplySupplyInputLineStatus},
cpqRackPowerSupplyPresent => $params{cpqRackPowerSupplyPresent},
cpqRackPowerSupplyCondition => $params{cpqRackPowerSupplyCondition},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
$self->{name} = $params{cpqRackPowerSupplyRack}.':'.$params{cpqRackPowerSupplyChassis}.':'.$params{cpqRackPowerSupplyIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('ps', $self->{name});
my $info = sprintf 'power supply %s is %s, condition is %s',
$self->{name}, $self->{cpqRackPowerSupplyPresent},
$self->{cpqRackPowerSupplyCondition};
$self->add_info($info) if $self->{cpqRackPowerSupplyPresent} eq 'present' ||
$self->{runtime}->{options}->{verbose} >= 3;
if ($self->{cpqRackPowerSupplyPresent} eq 'present') {
$self->{runtime}->{plugin}->add_perfdata(
label => sprintf('power_supply_output_%s', $self->{name}),
value => $self->{cpqRackPowerSupplyCurPwrOutput},
uom => 'Watts',
);
if ($self->{cpqRackPowerSupplyCondition} eq 'degraded') {
$self->add_message(WARNING, $info);
$self->add_info(sprintf 'power supply %s status is %s, inp.line status is %s',
$self->{cpqRackPowerSupplyName}, $self->{cpqRackPowerSupplyStatus},
$self->{cpqRackPowerSupplySupplyInputLineStatus});
} elsif ($self->{cpqRackPowerSupplyCondition} eq 'failed') {
$self->add_message(CRITICAL, $info);
$self->add_info(sprintf 'power supply %s status is %s, inp.line status is %s',
$self->{cpqRackPowerSupplyName}, $self->{cpqRackPowerSupplyStatus},
$self->{cpqRackPowerSupplySupplyInputLineStatus});
}
}
}
sub dump {
my $self = shift;
printf "[POWER_SUPPLY%s]\n", $self->{name};
foreach (qw(cpqRackPowerSupplyRack cpqRackPowerSupplyChassis cpqRackPowerSupplyIndex cpqRackPowerSupplyEnclosureName cpqRackPowerSupplyMaxPwrOutput cpqRackPowerSupplyCurPwrOutput cpqRackPowerSupplyIntakeTemp cpqRackPowerSupplyExhaustTemp cpqRackPowerSupplyStatus cpqRackPowerSupplySupplyInputLineStatus cpqRackPowerSupplyPresent cpqRackPowerSupplyCondition)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::BladeSystem::Component::NetConnectorSubsystem;
our @ISA = qw(HP::BladeSystem::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
net_connectors => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub init {
my $self = shift;
my $oids = {
cpqRackNetConnectorEntry => '1.3.6.1.4.1.232.22.2.6.1.1.1',
cpqRackNetConnectorRack => '1.3.6.1.4.1.232.22.2.6.1.1.1.1',
cpqRackNetConnectorChassis => '1.3.6.1.4.1.232.22.2.6.1.1.1.2',
cpqRackNetConnectorIndex => '1.3.6.1.4.1.232.22.2.6.1.1.1.3',
cpqRackNetConnectorEnclosureName => '1.3.6.1.4.1.232.22.2.6.1.1.1.4',
cpqRackNetConnectorName => '1.3.6.1.4.1.232.22.2.6.1.1.1.5',
cpqRackNetConnectorModel => '1.3.6.1.4.1.232.22.2.6.1.1.1.6',
cpqRackNetConnectorSerialNum => '1.3.6.1.4.1.232.22.2.6.1.1.1.7',
cpqRackNetConnectorPartNumber => '1.3.6.1.4.1.232.22.2.6.1.1.1.8',
cpqRackNetConnectorSparePartNumber => '1.3.6.1.4.1.232.22.2.6.1.1.1.9',
cpqRackNetConnectorFWRev => '1.3.6.1.4.1.232.22.2.6.1.1.1.10',
cpqRackNetConnectorType => '1.3.6.1.4.1.232.22.2.6.1.1.1.11',
cpqRackNetConnectorLocation => '1.3.6.1.4.1.232.22.2.6.1.1.1.12',
cpqRackNetConnectorPresent => '1.3.6.1.4.1.232.22.2.6.1.1.1.13',
cpqRackNetConnectorHasFuses => '1.3.6.1.4.1.232.22.2.6.1.1.1.14',
cpqRackNetConnectorEnclosureSerialNum => '1.3.6.1.4.1.232.22.2.6.1.1.1.15',
cpqRackNetConnectorTypeValue => {
0 => 'other', # undefined
1 => 'other',
2 => 'active',
3 => 'passive',
},
cpqRackNetConnectorPresentValue => {
1 => 'other',
2 => 'absent',
3 => 'present',
},
cpqRackNetConnectorHasFusesValue => {
-1 => 'false', # wird geliefert, also vermute ich false
1 => 'false',
2 => 'true',
},
};
# INDEX { cpqRackNetConnectorRack, cpqRackNetConnectorChassis, cpqRackNetConnectorIndex }
# dreckada dreck, dreckada
foreach ($self->get_entries($oids, 'cpqRackNetConnectorEntry')) {
push(@{$self->{net_connectors}},
HP::BladeSystem::Component::NetConnectorSubsystem::NetConnector->new(%{$_}));
}
}
sub check {
my $self = shift;
foreach (@{$self->{net_connectors}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{net_connectors}}) {
$_->dump();
}
}
package HP::BladeSystem::Component::NetConnectorSubsystem::NetConnector;
our @ISA = qw(HP::BladeSystem::Component::NetConnectorSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
cpqRackNetConnectorRack => $params{cpqRackNetConnectorRack},
cpqRackNetConnectorChassis => $params{cpqRackNetConnectorChassis},
cpqRackNetConnectorIndex => $params{cpqRackNetConnectorIndex},
cpqRackNetConnectorEnclosureName => $params{cpqRackNetConnectorEnclosureName},
cpqRackNetConnectorName => $params{cpqRackNetConnectorName},
cpqRackNetConnectorModel => $params{cpqRackNetConnectorModel},
cpqRackNetConnectorSerialNum => $params{cpqRackNetConnectorSerialNum},
cpqRackNetConnectorPartNumber => $params{cpqRackNetConnectorPartNumber},
cpqRackNetConnectorSparePartNumber => $params{cpqRackNetConnectorSparePartNumber},
cpqRackNetConnectorFWRev => $params{cpqRackNetConnectorFWRev},
cpqRackNetConnectorType => $params{cpqRackNetConnectorType},
cpqRackNetConnectorLocation => $params{cpqRackNetConnectorLocation},
cpqRackNetConnectorPresent => $params{cpqRackNetConnectorPresent},
cpqRackNetConnectorHasFuses => $params{cpqRackNetConnectorHasFuses},
cpqRackNetConnectorEnclosureSerialNum => $params{cpqRackNetConnectorEnclosureSerialNum},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
$self->{name} = $params{cpqRackNetConnectorRack}.':'.$params{cpqRackNetConnectorChassis}.':'.$params{cpqRackNetConnectorIndex};
bless $self, $class;
return $self;
}
sub check {
my $self = shift;
$self->blacklist('nc', $self->{name});
my $info = sprintf 'net connector %s is %s, model is %s',
$self->{name}.($self->{cpqRackNetConnectorName} ? '('.$self->{cpqRackNetConnectorName}.')' : ''),
$self->{cpqRackNetConnectorPresent},
$self->{cpqRackNetConnectorModel};
$self->add_info($info) if $self->{cpqRackNetConnectorPresent} eq 'present' ||
$self->{runtime}->{options}->{verbose} >= 3;
# hat weder status noch condition
}
sub dump {
my $self = shift;
printf "[NET_CONNECTOR_%s]\n", $self->{cpqRackNetConnectorName};
foreach (qw(cpqRackNetConnectorRack cpqRackNetConnectorChassis cpqRackNetConnectorIndex cpqRackNetConnectorEnclosureName cpqRackNetConnectorName cpqRackNetConnectorModel cpqRackNetConnectorSerialNum cpqRackNetConnectorPartNumber cpqRackNetConnectorSparePartNumber cpqRackNetConnectorFWRev cpqRackNetConnectorType cpqRackNetConnectorLocation cpqRackNetConnectorPresent cpqRackNetConnectorHasFuses cpqRackNetConnectorEnclosureSerialNum)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::BladeSystem::Component::ServerBladeSubsystem;
our @ISA = qw(HP::BladeSystem::Component);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
server_blades => [],
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub init {
my $self = shift;
my $oids = {
cpqRackServerBladeEntry => '1.3.6.1.4.1.232.22.2.4.1.1.1',
cpqRackServerBladeRack => '1.3.6.1.4.1.232.22.2.4.1.1.1.1',
cpqRackServerBladeChassis => '1.3.6.1.4.1.232.22.2.4.1.1.1.2',
cpqRackServerBladeIndex => '1.3.6.1.4.1.232.22.2.4.1.1.1.3',
cpqRackServerBladeName => '1.3.6.1.4.1.232.22.2.4.1.1.1.4',
cpqRackServerBladeEnclosureName => '1.3.6.1.4.1.232.22.2.4.1.1.1.5',
cpqRackServerBladePartNumber => '1.3.6.1.4.1.232.22.2.4.1.1.1.6',
cpqRackServerBladeSparePartNumber => '1.3.6.1.4.1.232.22.2.4.1.1.1.7',
cpqRackServerBladePosition => '1.3.6.1.4.1.232.22.2.4.1.1.1.8',
cpqRackServerBladeHeight => '1.3.6.1.4.1.232.22.2.4.1.1.1.9',
cpqRackServerBladeWidth => '1.3.6.1.4.1.232.22.2.4.1.1.1.10',
cpqRackServerBladeDepth => '1.3.6.1.4.1.232.22.2.4.1.1.1.11',
cpqRackServerBladePresent => '1.3.6.1.4.1.232.22.2.4.1.1.1.12',
cpqRackServerBladeHasFuses => '1.3.6.1.4.1.232.22.2.4.1.1.1.13',
cpqRackServerBladeEnclosureSerialNum => '1.3.6.1.4.1.232.22.2.4.1.1.1.14',
cpqRackServerBladeSlotsUsed => '1.3.6.1.4.1.232.22.2.4.1.1.1.15',
cpqRackServerBladeStatus => '1.3.6.1.4.1.232.22.2.4.1.1.1.21',
cpqRackServerBladeDiagnosticString => '1.3.6.1.4.1.232.22.2.4.1.1.1.24',
cpqRackServerBladePowered => '1.3.6.1.4.1.232.22.2.4.1.1.1.25',
cpqRackServerBladePOSTStatus => '1.3.6.1.4.1.232.22.2.4.1.1.1.35',
cpqRackServerBladePresentValue => {
1 => 'other',
2 => 'absent',
3 => 'present',
},
cpqRackServerBladeStatusValue => {
1 => 'other',
2 => 'ok',
3 => 'degraded',
4 => 'failed',
},
cpqRackServerBladePoweredValue => {
0 => 'aechz',
1 => 'other',
2 => 'on',
3 => 'off',
4 => 'powerStagedOff',
5 => 'reboot',
},
cpqRackServerBladePOSTStatusValue => {
1 => 'other',
2 => 'started',
3 => 'completed',
4 => 'failed',
},
};
# INDEX { cpqRackServerBladeRack, cpqRackServerBladeChassis, cpqRackServerBladeIndex }
# dreckada dreck, dreckada
foreach ($self->get_entries($oids, 'cpqRackServerBladeEntry')) {
push(@{$self->{server_blades}},
HP::BladeSystem::Component::ServerBladeSubsystem::ServerBlade->new(%{$_}));
}
}
sub check {
my $self = shift;
foreach (@{$self->{server_blades}}) {
$_->check();
}
}
sub dump {
my $self = shift;
foreach (@{$self->{server_blades}}) {
$_->dump();
}
}
package HP::BladeSystem::Component::ServerBladeSubsystem::ServerBlade;
our @ISA = qw(HP::BladeSystem::Component::ServerBladeSubsystem);
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
rawdata => $params{rawdata},
method => $params{method},
cpqRackServerBladeRack => $params{cpqRackServerBladeRack},
cpqRackServerBladeChassis => $params{cpqRackServerBladeChassis},
cpqRackServerBladeIndex => $params{cpqRackServerBladeIndex},
cpqRackServerBladeName => $params{cpqRackServerBladeName},
cpqRackServerBladeEnclosureName => $params{cpqRackServerBladeEnclosureName},
cpqRackServerBladePartNumber => $params{cpqRackServerBladePartNumber},
cpqRackServerBladeSparePartNumber => $params{cpqRackServerBladeSparePartNumber},
cpqRackServerBladePosition => $params{cpqRackServerBladePosition},
cpqRackServerBladeHeight => $params{cpqRackServerBladeHeight},
cpqRackServerBladeWidth => $params{cpqRackServerBladeWidth},
cpqRackServerBladeDepth => $params{cpqRackServerBladeDepth},
cpqRackServerBladePresent => $params{cpqRackServerBladePresent},
cpqRackServerBladeHasFuses => $params{cpqRackServerBladeHasFuses},
cpqRackServerBladeEnclosureSerialNum => $params{cpqRackServerBladeEnclosureSerialNum},
cpqRackServerBladeSlotsUsed => $params{cpqRackServerBladeSlotsUsed},
cpqRackServerBladeStatus => $params{cpqRackServerBladeStatus},
cpqRackServerBladeDiagnosticString => $params{cpqRackServerBladeDiagnosticString} || '',
cpqRackServerBladePowered => $params{cpqRackServerBladePowered},
cpqRackServerBladePOSTStatus => $params{cpqRackServerBladePOSTStatus},
blacklisted => 0,
info => undef,
extendedinfo => undef,
};
bless $self, $class;
$self->init();
return $self;
}
sub check {
my $self = shift;
$self->blacklist('sb', $self->{cpqRackServerBladeName});
my $info = sprintf 'serverblade %s is %s; partnumber=%s; name=%s',
$self->{cpqRackServerBladeIndex}, $self->{cpqRackServerBladePresent},
$self->{cpqRackServerBladePartNumber}, $self->{cpqRackServerBladeName};
$self->add_info($info) if $self->{cpqRackServerBladePresent} eq 'present' ||
$self->{runtime}->{options}->{verbose} >= 3; # absent blades nur bei -vvv
if ($self->{cpqRackServerBladePowered} eq 'on') {
if ($self->{cpqRackServerBladeCondition} eq 'degraded') {
$self->add_message(WARNING, sprintf 'server blade %s diag is \'%s\', post status is %s',
$self->{cpqRackServerBladeName}, $self->{cpqRackServerBladeDiagnosticString},
$self->{cpqRackServerBladePOSTStatus});
} elsif ($self->{cpqRackServerBladeCondition} eq 'failed') {
$self->add_message(CRITICAL, sprintf 'server blade %s diag is \'%s\', post status is %s',
$self->{cpqRackServerBladeName}, $self->{cpqRackServerBladeDiagnosticString},
$self->{cpqRackServerBladePOSTStatus});
}
}
}
sub dump {
my $self = shift;
printf "[SERVER_BLADE_%s]\n", $self->{cpqRackServerBladeName};
foreach (qw(cpqRackServerBladeRack cpqRackServerBladeChassis cpqRackServerBladeIndex cpqRackServerBladeName cpqRackServerBladeEnclosureName cpqRackServerBladePartNumber cpqRackServerBladeSparePartNumber cpqRackServerBladePosition cpqRackServerBladeHeight cpqRackServerBladeWidth cpqRackServerBladeDepth cpqRackServerBladePresent cpqRackServerBladeHasFuses cpqRackServerBladeEnclosureSerialNum cpqRackServerBladeSlotsUsed cpqRackServerBladeStatus cpqRackServerBladeDiagnosticString cpqRackServerBladePowered cpqRackServerBladePOSTStatus)) {
printf "%s: %s\n", $_, $self->{$_};
}
printf "\n";
}
package HP::BladeSystem::Component;
use strict;
our @ISA = qw(HP::BladeSystem);
package HP::BladeSystem;
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
use Data::Dumper;
our @ISA = qw(HP::Server HP::Proliant::Component::SNMP);
sub init {
my $self = shift;
$self->{components} = {
common_enclosure_subsystem => undef,
power_enclosure_subsystem => undef,
power_supply_subsystem => undef,
net_connector_subsystem => undef,
server_blade_subsystem => undef,
};
$self->{serial} = 'unknown';
$self->{product} = 'unknown';
$self->{romversion} = 'unknown';
$self->trace(3, 'BladeSystem identified');
$self->collect();
if (! $self->{runtime}->{plugin}->check_messages()) {
$self->set_serial();
$self->analyze_common_enclosures();
$self->analyze_power_enclosures();
$self->analyze_power_supplies();
$self->analyze_net_connectors();
$self->analyze_server_blades();
$self->check_common_enclosures();
$self->check_power_enclosures();
$self->check_power_supplies();
$self->check_net_connectors();
$self->check_server_blades();
}
}
sub identify {
my $self = shift;
return sprintf "System: '%s', S/N: '%s'",
$self->{product}, $self->{serial};
}
sub dump {
my $self = shift;
printf STDERR "serial %s\n", $self->{serial};
printf STDERR "product %s\n", $self->{product};
printf STDERR "romversion %s\n", $self->{romversion};
printf STDERR "%s\n", Data::Dumper::Dumper($self->{enclosures});
}
sub analyze_common_enclosures {
my $self = shift;
$self->{components}->{common_enclosure_subsystem} =
HP::BladeSystem::Component::CommonEnclosureSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_power_enclosures {
my $self = shift;
$self->{components}->{power_enclosure_subsystem} =
HP::BladeSystem::Component::PowerEnclosureSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_power_supplies {
my $self = shift;
$self->{components}->{power_supply_subsystem} =
HP::BladeSystem::Component::PowerSupplySubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_net_connectors {
my $self = shift;
$self->{components}->{net_connector_subsystem} =
HP::BladeSystem::Component::NetConnectorSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_server_blades {
my $self = shift;
$self->{components}->{server_blade_subsystem} =
HP::BladeSystem::Component::ServerBladeSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub check_common_enclosures {
my $self = shift;
$self->{components}->{common_enclosure_subsystem}->check();
$self->{components}->{common_enclosure_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_power_enclosures {
my $self = shift;
$self->{components}->{power_enclosure_subsystem}->check();
$self->{components}->{power_enclosure_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_power_supplies {
my $self = shift;
$self->{components}->{power_supply_subsystem}->check();
$self->{components}->{power_supply_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_net_connectors {
my $self = shift;
$self->{components}->{net_connector_subsystem}->check();
$self->{components}->{net_connector_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_server_blades {
my $self = shift;
$self->{components}->{server_blade_subsystem}->check();
$self->{components}->{server_blade_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub collect {
my $self = shift;
if ($self->{runtime}->{plugin}->opts->snmpwalk) {
my $cpqRackMibCondition = '1.3.6.1.4.1.232.22.1.3.0';
$self->trace(3, 'getting cpqRackMibCondition');
if (! exists $self->{rawdata}->{$cpqRackMibCondition}) {
$self->add_message(CRITICAL,
'snmpwalk returns no health data (cpqrack-mib)');
}
} else {
my $net_snmp_version = Net::SNMP->VERSION(); # 5.002000 or 6.000000
#$params{'-translate'} = [
# -all => 0x0
#];
my ($session, $error) =
Net::SNMP->session(%{$self->{runtime}->{snmpparams}});
if (! defined $session) {
$self->{plugin}->add_message(CRITICAL, 'cannot create session object');
$self->trace(1, Data::Dumper::Dumper($self->{runtime}->{snmpparams}));
} else {
# revMajor is often used for discovery of hp devices
my $cpqSeMibRev = '1.3.6.1.4.1.232.22.1';
my $cpqSeMibRevMajor = '1.3.6.1.4.1.232.22.1.1.0';
my $cpqRackMibCondition = '1.3.6.1.4.1.232.22.1.3.0';
$self->trace(3, 'getting cpqRackMibCondition');
my $result = $session->get_request(
-varbindlist => [$cpqRackMibCondition]
);
if (!defined($result) ||
$result->{$cpqRackMibCondition} eq 'noSuchInstance' ||
$result->{$cpqRackMibCondition} eq 'noSuchObject' ||
$result->{$cpqRackMibCondition} eq 'endOfMibView') {
$self->add_message(CRITICAL,
'snmpwalk returns no health data (cpqrack-mib)');
$session->close;
} else {
$self->trace(3, 'getting cpqRackMibCondition done');
}
}
if (! $self->{runtime}->{plugin}->check_messages()) {
# snmp peer is alive
$self->trace(2, sprintf "Protocol is %s",
$self->{runtime}->{snmpparams}->{'-version'});
my $cpqSiComponent = "1.3.6.1.4.1.232.2.2";
my $cpqSiAsset = "1.3.6.1.4.1.232.2.2.2";
my $cpqRackInfo = "1.3.6.1.4.1.232.22";
$session->translate;
my $response = {}; #break the walk up in smaller pieces
my $tic = time; my $tac = $tic;
# Walk for Asset
$tic = time;
my $response0 = $session->get_table(
-maxrepetitions => 1,
-baseoid => $cpqSiComponent);
if (scalar (keys %{$response0}) == 0) {
$self->trace(2, sprintf "maxrepetitions failed. fallback");
$response0 = $session->get_table(
-baseoid => $cpqSiComponent);
}
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqSiComponent (%d oids)",
$tac - $tic, scalar(keys %{$response0}));
$tic = time;
my $response1 = $session->get_table(
-maxrepetitions => 1,
-baseoid => $cpqRackInfo);
if (scalar (keys %{$response1}) == 0) {
$self->trace(2, sprintf "maxrepetitions failed. fallback");
$response1 = $session->get_table(
-baseoid => $cpqRackInfo);
}
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqRackInfo (%d oids)",
$tac - $tic, scalar(keys %{$response1}));
$session->close;
map { $response->{$_} = $response0->{$_} } keys %{$response0};
map { $response->{$_} = $response1->{$_} } keys %{$response1};
map { $response->{$_} =~ s/^\s+//; $response->{$_} =~ s/\s+$//; }
keys %$response;
$self->{rawdata} = $response;
}
}
return $self->{runtime}->{plugin}->check_messages();
}
sub set_serial {
my $self = shift;
my $cpqSiSysSerialNum = "1.3.6.1.4.1.232.2.2.2.1.0";
my $cpqSiProductName = "1.3.6.1.4.1.232.2.2.4.2.0";
$self->{serial} =
SNMP::Utils::get_object($self->{rawdata}, $cpqSiSysSerialNum);
$self->{product} =
SNMP::Utils::get_object($self->{rawdata}, $cpqSiProductName);
$self->{serial} = $self->{serial};
$self->{product} = lc $self->{product};
$self->{romversion} = 'unknown';
#####################################################################
$self->{runtime}->{product} = $self->{product};
}
package HP::Storage;
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
use Data::Dumper;
our @ISA = qw(HP::Server);
sub init {
my $self = shift;
$self->{components} = {
powersupply_subsystem => undef,
fan_subsystem => undef,
temperature_subsystem => undef,
cpu_subsystem => undef,
memory_subsystem => undef,
disk_subsystem => undef,
};
$self->{serial} = 'unknown';
$self->{product} = 'unknown';
$self->{romversion} = 'unknown';
$self->collect();
if (! $self->{runtime}->{plugin}->check_messages()) {
$self->set_serial();
# $self->check_for_buggy_firmware();
# $self->analyze_cpus();
# $self->analyze_powersupplies();
# $self->analyze_fan_subsystem();
# $self->analyze_temperatures();
# $self->analyze_memory_subsystem();
$self->analyze_disk_subsystem();
# $self->check_cpus();
# $self->check_powersupplies();
# $self->check_fan_subsystem();
# $self->check_temperatures();
# $self->check_memory_subsystem();
$self->check_disk_subsystem();
}
}
sub identify {
my $self = shift;
return sprintf "System: '%s', S/N: '%s', ROM: '%s'",
$self->{product}, $self->{serial}, $self->{romversion};
}
sub check_for_buggy_firmware {
my $self = shift;
my @buggyfirmwares = (
"P24 12/11/2001",
"P24 11/15/2002",
"D13 06/03/2003",
"D13 09/15/2004",
"P20 12/17/2002"
);
$self->{runtime}->{options}->{buggy_firmware} =
grep /^$self->{romversion}/, @buggyfirmwares;
}
sub dump {
my $self = shift;
printf STDERR "serial %s\n", $self->{serial};
printf STDERR "product %s\n", $self->{product};
printf STDERR "romversion %s\n", $self->{romversion};
printf STDERR "%s\n", Data::Dumper::Dumper($self->{components});
}
sub analyze_powersupplies {
my $self = shift;
$self->{components}->{powersupply_subsystem} =
HP::Storage::Component::PowersupplySubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_fan_subsystem {
my $self = shift;
$self->{components}->{fan_subsystem} =
HP::Storage::Component::FanSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_temperatures {
my $self = shift;
$self->{components}->{temperature_subsystem} =
HP::Storage::Component::TemperatureSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_cpus {
my $self = shift;
$self->{components}->{cpu_subsystem} =
HP::Storage::Component::CpuSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_memory_subsystem {
my $self = shift;
$self->{components}->{memory_subsystem} =
HP::Storage::Component::MemorySubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub analyze_disk_subsystem {
my $self = shift;
$self->{components}->{disk_subsystem} =
HP::Proliant::Component::DiskSubsystem->new(
rawdata => $self->{rawdata},
method => $self->{method},
runtime => $self->{runtime},
);
}
sub check_cpus {
my $self = shift;
$self->{components}->{cpu_subsystem}->check();
$self->{components}->{cpu_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_powersupplies {
my $self = shift;
$self->{components}->{powersupply_subsystem}->check();
$self->{components}->{powersupply_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_fan_subsystem {
my $self = shift;
$self->{components}->{fan_subsystem}->check();
$self->{components}->{fan_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_temperatures {
my $self = shift;
$self->{components}->{temperature_subsystem}->check();
$self->{components}->{temperature_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_memory_subsystem {
my $self = shift;
$self->{components}->{memory_subsystem}->check();
$self->{components}->{memory_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 2;
}
sub check_disk_subsystem {
my $self = shift;
$self->{components}->{disk_subsystem}->check();
$self->{components}->{disk_subsystem}->dump()
if $self->{runtime}->{options}->{verbose} >= 1;
}
sub collect {
my $self = shift;
if ($self->{runtime}->{plugin}->opts->snmpwalk) {
my $cpqSeMibCondition = '1.3.6.1.4.1.232.6.1.3.0';
# rindsarsch!
$self->{rawdata}->{$cpqSeMibCondition} = 0;
if (! exists $self->{rawdata}->{$cpqSeMibCondition}) {
$self->add_message(CRITICAL,
'snmpwalk returns no health data (cpqhlth-mib)');
}
} else {
my $net_snmp_version = Net::SNMP->VERSION(); # 5.002000 or 6.000000
#$params{'-translate'} = [
# -all => 0x0
#];
my ($session, $error) =
Net::SNMP->session(%{$self->{runtime}->{snmpparams}});
if (! defined $session) {
$self->{plugin}->add_message(CRITICAL, 'cannot create session object');
$self->trace(1, Data::Dumper::Dumper($self->{runtime}->{snmpparams}));
} else {
# revMajor is often used for discovery of hp devices
my $cpqSeMibRev = '1.3.6.1.4.1.232.6.1';
my $cpqSeMibRevMajor = '1.3.6.1.4.1.232.6.1.1.0';
my $cpqSeMibCondition = '1.3.6.1.4.1.232.6.1.3.0';
my $result = $session->get_request(
-varbindlist => [$cpqSeMibCondition]
);
# rindsarsch!
$result->{$cpqSeMibCondition} = 0;
if (!defined($result) ||
$result->{$cpqSeMibCondition} eq 'noSuchInstance' ||
$result->{$cpqSeMibCondition} eq 'noSuchObject' ||
$result->{$cpqSeMibCondition} eq 'endOfMibView') {
$self->add_message(CRITICAL,
'snmpwalk returns no health data (cpqhlth-mib)');
$session->close;
} else {
# this is not reliable. many agents return 4=failed
#if ($result->{$cpqSeMibCondition} != 2) {
# $obstacle = "cmapeerstart";
#}
}
}
if (! $self->{runtime}->{plugin}->check_messages()) {
# snmp peer is alive
$self->trace(2, sprintf "Protocol is %s",
$self->{runtime}->{snmpparams}->{'-version'});
my $cpqSsSys = "1.3.6.1.4.1.232.8";
$session->translate;
my $response = {}; #break the walk up in smaller pieces
my $tic = time; my $tac = $tic;
my $response1 = $session->get_table(
-baseoid => $cpqSsSys);
$tac = time;
$self->trace(2, sprintf "%03d seconds for walk cpqSsSys (%d oids)",
$tac - $tic, scalar(keys %{$response1}));
$session->close;
map { $response->{$_} = $response1->{$_} } keys %{$response1};
map { $response->{$_} =~ s/^\s+//; $response->{$_} =~ s/\s+$//; }
keys %$response;
$self->{rawdata} = $response;
}
}
return $self->{runtime}->{plugin}->check_messages();
}
sub set_serial {
my $self = shift;
my $snmpwalk = $self->{rawdata};
my @serials = ();
my @models = ();
my @fws = ();
my $cpqSsBackplaneEntry = '1.3.6.1.4.1.232.8.2.2.6.1';
my $cpqSsBackplaneFWRev = '1.3.6.1.4.1.232.8.2.2.6.1.3';
my $cpqSsBackplaneModel = '1.3.6.1.4.1.232.8.2.2.6.1.9';
my $cpqSsBackplaneSerialNumber = '1.3.6.1.4.1.232.8.2.2.6.1.13';
# INDEX { cpqSsBackplaneChassisIndex, cpqSsBackplaneIndex }
my @indexes = SNMP::Utils::get_indices($snmpwalk,
$cpqSsBackplaneEntry);
foreach (@indexes) {
my($idx1, $idx2) = ($_->[0], $_->[1]);
my $fw = SNMP::Utils::get_object($snmpwalk,
$cpqSsBackplaneFWRev, $idx1, $idx2);
my $model = SNMP::Utils::get_object($snmpwalk,
$cpqSsBackplaneModel, $idx1, $idx2);
my $serial = SNMP::Utils::get_object($snmpwalk,
$cpqSsBackplaneSerialNumber, $idx1, $idx2);
push(@serials, $serial);
push(@models, $model);
push(@fws, $fw);
}
$self->{serial} = join('/', @serials);
$self->{product} = join('/', @models);
$self->{romversion} = join('/', @fws);
$self->{runtime}->{product} = $self->{product};
}
package HP::Server;
use strict;
use constant { OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 };
sub new {
my $class = shift;
my %params = @_;
my $self = {
runtime => $params{runtime},
productname => 'unknown',
};
bless $self, $class;
if (! ($self->{runtime}->{plugin}->opts->hostname ||
$self->{runtime}->{plugin}->opts->snmpwalk)) {
bless $self, 'HP::Proliant::CLI';
$self->{method} = 'cli';
} else {
$self->check_snmp_and_model();
if ($self->{runtime}->{options}->{servertype}) {
$self->{productname} = 'ProLiant' if
$self->{runtime}->{options}->{servertype} eq 'proliant';
$self->{productname} = 'BladeSystem' if
$self->{runtime}->{options}->{servertype} eq 'bladesystem';
$self->{productname} = 'Storage' if
$self->{runtime}->{options}->{servertype} eq 'storage';
}
if (! $self->{runtime}->{plugin}->check_messages()) {
if ($self->{productname} =~ /ProLiant/) {
bless $self, 'HP::Proliant::SNMP';
$self->trace(3, 'using HP::Proliant::SNMP');
} elsif ($self->{productname} =~ /OpenView .* appliance/) {
bless $self, 'HP::Proliant::SNMP';
$self->trace(3, 'using HP::Proliant::SNMP');
} elsif ($self->{productname} =~ /BladeSystem/) {
bless $self, 'HP::BladeSystem';
$self->trace(3, 'using HP::BladeSystem');
} elsif ($self->{productname} =~ /PROLIANT 4LEE/) {
bless $self, 'HP::Storage';
$self->trace(3, 'using HP::Storage');
} elsif ($self->{productname} =~ /Storage/) { # fake
bless $self, 'HP::Storage';
$self->trace(3, 'using HP::Storage');
} else {
$self->add_message(CRITICAL,
sprintf('unknown device%s', $self->{productname} eq 'unknown' ?
'' : '('.$self->{productname}.')'));
}
$self->{method} = 'snmp';
}
}
if ($self->{runtime}->{options}->{blacklist} &&
-f $self->{runtime}->{options}->{blacklist}) {
$self->{runtime}->{options}->{blacklist} = do {
local (@ARGV, $/) = $self->{runtime}->{options}->{blacklist}; <> };
}
return $self;
}
sub check_snmp_and_model {
# uptime pruefen
# dann whoami
my $self = shift;
if ($self->{runtime}->{plugin}->opts->snmpwalk) {
my $response = {};
if (! -f $self->{runtime}->{plugin}->opts->snmpwalk) {
$self->{runtime}->{plugin}->add_message(CRITICAL,
sprintf 'file %s not found',
$self->{runtime}->{plugin}->opts->snmpwalk);
} elsif (-x $self->{runtime}->{plugin}->opts->snmpwalk) {
my $cmd = sprintf "%s -On -v%s -c%s %s 1.3.6.1.4.1.232 2>&1",
$self->{runtime}->{plugin}->opts->snmpwalk,
$self->{runtime}->{plugin}->opts->protocol,
$self->{runtime}->{plugin}->opts->community,
$self->{runtime}->{plugin}->opts->hostname;
open(WALK, "$cmd |");
while (<WALK>) {
if (/^.*?\.(232\.[\d\.]+) = .*?: (\-*\d+)/) {
$response->{'1.3.6.1.4.1.'.$1} = $2;
} elsif (/^.*?\.(232\.[\d\.]+) = .*?: "(.*?)"/) {
$response->{'1.3.6.1.4.1.'.$1} = $2;
$response->{'1.3.6.1.4.1.'.$1} =~ s/\s+$//;
}
}
close WALK;
} else {
open(MESS, $self->{runtime}->{plugin}->opts->snmpwalk);
while(<MESS>) {
# SNMPv2-SMI::enterprises.232.6.2.6.7.1.3.1.4 = INTEGER: 6
if (/^.*?\.(232\.[\d\.]+) = .*?: (\-*\d+)/) {
$response->{'1.3.6.1.4.1.'.$1} = $2;
} elsif (/^.*?\.(232\.[\d\.]+) = .*?: "(.*?)"/) {
$response->{'1.3.6.1.4.1.'.$1} = $2;
$response->{'1.3.6.1.4.1.'.$1} =~ s/\s+$//;
} if (/^.*?\.(232\.[\d\.]+) = (\-*\d+)/) {
$response->{'1.3.6.1.4.1.'.$1} = $2;
} elsif (/^.*?\.(232\.[\d\.]+) = "(.*?)"/) {
$response->{'1.3.6.1.4.1.'.$1} = $2;
$response->{'1.3.6.1.4.1.'.$1} =~ s/\s+$//;
}
}
close MESS;
}
map { $response->{$_} =~ s/^\s+//; $response->{$_} =~ s/\s+$//; }
keys %$response;
$self->{rawdata} = $response;
$self->whoami();
} else {
if (eval "require Net::SNMP") {
my %params = ();
my $net_snmp_version = Net::SNMP->VERSION(); # 5.002000 or 6.000000
#$params{'-translate'} = [
# -all => 0x0
#];
$params{'-hostname'} = $self->{runtime}->{plugin}->opts->hostname;
$params{'-version'} = $self->{runtime}->{plugin}->opts->protocol;
if ($self->{runtime}->{plugin}->opts->port) {
$params{'-port'} = $self->{runtime}->{plugin}->opts->port;
}
if ($self->{runtime}->{plugin}->opts->protocol eq '3') {
$params{'-username'} = $self->{runtime}->{plugin}->opts->username;
if ($self->{runtime}->{plugin}->opts->authpassword) {
$params{'-authpassword'} = $self->{runtime}->{plugin}->opts->authpassword;
}
if ($self->{runtime}->{plugin}->opts->authprotocol) {
$params{'-authprotocol'} = $self->{runtime}->{plugin}->opts->authprotocol;
}
if ($self->{runtime}->{plugin}->opts->privpassword) {
$params{'-privpassword'} = $self->{runtime}->{plugin}->opts->privpassword;
}
if ($self->{runtime}->{plugin}->opts->privprotocol) {
$params{'-privprotocol'} = $self->{runtime}->{plugin}->opts->privprotocol;
}
} else {
$params{'-community'} = $self->{runtime}->{plugin}->opts->community;
}
$self->{runtime}->{snmpparams} = \%params;
my ($session, $error) = Net::SNMP->session(%params);
$self->{session} = $session;
if (! defined $session) {
$self->{plugin}->add_message(CRITICAL, 'cannot create session object');
$self->trace(1, Data::Dumper::Dumper(\%params));
} else {
my $sysUpTime = '1.3.6.1.2.1.1.3.0';
my $result = $session->get_request(
-varbindlist => [$sysUpTime]
);
if (!defined($result)) {
$self->add_message(CRITICAL,
'could not contact snmp agent');
$session->close;
} else {
$self->trace(3, 'snmp agent answered');
$self->whoami();
}
}
} else {
$self->add_message(CRITICAL,
'could not find Net::SNMP module');
}
}
}
sub whoami {
my $self = shift;
my $productname = undef;
if ($self->{runtime}->{plugin}->opts->snmpwalk) {
my $cpqSiProductName = '1.3.6.1.4.1.232.2.2.4.2.0';
my $cpqSsMibRevMajor = '1.3.6.1.4.1.232.8.1.1.0';
my $cpqSsBackplaneModel = '1.3.6.1.4.1.232.8.2.2.6.1.9'.'.1.1';
if ($productname = $self->{rawdata}->{$cpqSiProductName}) {
if (! $productname) {
$self->{productname} = 'ProLiant';
} else {
$self->{productname} = $self->{rawdata}->{$cpqSiProductName};
}
} elsif (exists $self->{rawdata}->{$cpqSsBackplaneModel}) {
$self->{productname} = $self->{rawdata}->{$cpqSsBackplaneModel};
} elsif (exists $self->{rawdata}->{$cpqSsMibRevMajor}) {
# at least there is a CPQSTSYS-MIB
$self->{productname} = 'Storage'
} else {
$self->add_message(CRITICAL,
'snmpwalk returns no product name (cpqsinfo-mib)');
}
} else {
my $cpqSiProductName = '1.3.6.1.4.1.232.2.2.4.2.0';
my $cpqSsMibRevMajor = '1.3.6.1.4.1.232.8.1.1.0';
my $cpqSsBackplaneModel = '1.3.6.1.4.1.232.8.2.2.6.1.9'.'.1.1';
my $dummy = '1.3.6.1.2.1.1.5.0';
if ($productname = $self->valid_response($cpqSiProductName)) {
if ($productname eq '') {
$self->{productname} = 'ProLiant';
} else {
$self->{productname} = $productname;
}
} elsif ($productname = $self->valid_response($cpqSsBackplaneModel)) {
$self->{productname} = $productname;
} elsif ($self->valid_response($cpqSsMibRevMajor)) {
# at least there is a CPQSTSYS-MIB
$self->{productname} = 'Storage'
} else {
$self->add_message(CRITICAL,
'snmpwalk returns no product name (cpqsinfo-mib)');
$self->{session}->close;
}
$self->trace(3, 'whoami: '.$self->{productname});
}
}
sub valid_response {
my $self = shift;
my $oid = shift;
my $result = $self->{session}->get_request(
-varbindlist => [$oid]
);
if (!defined($result) ||
! defined $result->{$oid} ||
$result->{$oid} eq 'noSuchInstance' ||
$result->{$oid} eq 'noSuchObject' ||
$result->{$oid} eq 'endOfMibView') {
return undef;
} else {
return $result->{$oid};
}
}
sub trace {
my $self = shift;
my $level = shift;
my $message = shift;
if ($self->{runtime}->{options}->{verbose} >= $level) {
printf "%s\n", $message;
}
}
sub blacklist {
my $self = shift;
my $type = shift;
my $name = shift;
$self->{blacklisted} = $self->is_blacklisted($type, $name);
}
sub add_blacklist {
my $self = shift;
my $list = shift;
$self->{runtime}->{options}->{blacklist} = join('/',
(split('/', $self->{runtime}->{options}->{blacklist}), $list));
}
sub is_blacklisted {
my $self = shift;
my $type = shift;
my $name = shift;
my $blacklisted = 0;
# $name =~ s/\:/-/g;
foreach my $bl_items (split(/\//, $self->{runtime}->{options}->{blacklist})) {
if ($bl_items =~ /^(\w+):([\:\d\-,]+)$/) {
my $bl_type = $1;
my $bl_names = $2;
foreach my $bl_name (split(/,/, $bl_names)) {
if ($bl_type eq $type && $bl_name eq $name) {
$blacklisted = 1;
}
}
} elsif ($bl_items =~ /^(\w+)$/) {
my $bl_type = $1;
if ($bl_type eq $type) {
$blacklisted = 1;
}
}
}
return $blacklisted;
}
sub add_message {
my $self = shift;
my $level = shift;
my $message = shift;
$self->{runtime}->{plugin}->add_message($level, $message)
unless $self->{blacklisted};
}
sub add_info {
my $self = shift;
my $info = shift;
$info = $self->{blacklisted} ? $info.' (blacklisted)' : $info;
$self->{info} = $info;
if (! exists $self->{runtime}->{plugin}->{info}) {
$self->{runtime}->{plugin}->{info} = [];
}
push(@{$self->{runtime}->{plugin}->{info}}, $info);
}
sub annotate_info {
my $self = shift;
my $annotation = shift;
my $lastinfo = pop(@{$self->{runtime}->{plugin}->{info}});
$lastinfo .= sprintf ' (%s)', $annotation;
push(@{$self->{runtime}->{plugin}->{info}}, $lastinfo);
}
sub add_extendedinfo {
my $self = shift;
my $info = shift;
$self->{extendedinfo} = $info;
return if ! $self->{runtime}->{options}->{extendedinfo};
if (! exists $self->{runtime}->{plugin}->{extendedinfo}) {
$self->{runtime}->{plugin}->{extendedinfo} = [];
}
push(@{$self->{runtime}->{plugin}->{extendedinfo}}, $info);
}
sub get_extendedinfo {
my $self = shift;
if (! exists $self->{runtime}->{plugin}->{extendedinfo}) {
$self->{runtime}->{plugin}->{extendedinfo} = [];
}
return join(' ', @{$self->{runtime}->{plugin}->{extendedinfo}});
}
sub add_summary {
my $self = shift;
my $summary = shift;
if (! exists $self->{runtime}->{plugin}->{summary}) {
$self->{runtime}->{plugin}->{summary} = [];
}
push(@{$self->{runtime}->{plugin}->{summary}}, $summary);
}
sub get_summary {
my $self = shift;
if (! exists $self->{runtime}->{plugin}->{summary}) {
$self->{runtime}->{plugin}->{summary} = [];
}
return join(', ', @{$self->{runtime}->{plugin}->{summary}});
}
sub dumper {
my $self = shift;
my $object = shift;
my $run = $object->{runtime};
delete $object->{runtime};
printf STDERR "%s\n", Data::Dumper::Dumper($object);
$object->{runtime} = $run;
}
package main;
#! /usr/bin/perl
use strict;
my $CELSIUS = 1;
my $PERFDATA = 1;
my $EXTENDEDINFO = 1;
my $HWINFO = 1;
my $HPACUCLI = 0;
my $NOINSTLEVEL = 'unknown';
use constant OK => 0;
use constant WARNING => 1;
use constant CRITICAL => 2;
use constant UNKNOWN => 3;
use constant DEPENDENT => 4;
my $plugin = Nagios::MiniPlugin->new(
shortname => '',
usage => 'Usage: %s [ -v|--verbose ] [ -t <timeout> ] '.
'--hostname <proliant> --community <snmp-community>'.
' ...]',
version => '4.1.2',
blurb => 'This plugin checks the hardware of hp/compaq proliant servers',
url => 'http://labs.consol.de/nagios/check_hpasm',
timeout => 60,
shortname => '',
);
$plugin->add_arg(
spec => 'blacklist|b=s',
help => '--blacklist
Blacklist some (missing/failed) components',
required => 0,
default => '',
);
$plugin->add_arg(
spec => 'ignore-dimms|i',
help => '--ignore-dimms
Ignore "N/A"-DIMM status on misc. servers (e.g. older DL320)',
required => 0,
);
$plugin->add_arg(
spec => 'ignore-fan-redundancy',
help => '--ignore-fan-redundancy
Ignore missing redundancy partners',
required => 0,
);
$plugin->add_arg(
spec => 'customthresholds|c=s',
help => '--customthresholds
Use custom thresholds for certain temperatures',
required => 0,
);
$plugin->add_arg(
spec => 'perfdata=s',
help => '--perfdata=[short]
Output performance data. If your performance data string becomes
too long and is truncated by Nagios, then you can use --perfdata=short
instead. This will output temperature tags without location information',
required => 0,
);
$plugin->add_arg(
spec => 'hostname|H=s',
help => '--hostname
Hostname or IP-address of the server (SNMP mode only)',
required => 0,
);
$plugin->add_arg(
spec => 'port=i',
help => '--port
The SNMP port to use (default: 161)',
required => 0,
default => 161,
);
$plugin->add_arg(
spec => 'protocol|P=s',
help => '--protocol
The SNMP protocol to use (default: 2c, other possibilities: 1,3)',
required => 0,
default => '2c',
);
$plugin->add_arg(
spec => 'community|C=s',
help => '--community
SNMP community of the server (SNMP v1/2 only)',
required => 0,
default => 'public',
);
$plugin->add_arg(
spec => 'username=s',
help => '--username
The securityName for the USM security model (SNMPv3 only)',
required => 0,
);
$plugin->add_arg(
spec => 'authpassword=s',
help => '--authpassword
The authentication password for SNMPv3',
required => 0,
);
$plugin->add_arg(
spec => 'authprotocol=s',
help => '--authprotocol
The authentication protocol for SNMPv3 (md5|sha)',
required => 0,
);
$plugin->add_arg(
spec => 'privpassword=s',
help => '--privpassword
The password for authPriv security level',
required => 0,
);
$plugin->add_arg(
spec => 'privprotocol=s',
help => '--privprotocol
The private protocol for SNMPv3 (des|aes|aes128|3des|3desde)',
required => 0,
);
$plugin->add_arg(
spec => 'snmpwalk=s',
help => '--snmpwalk
A file with the output of snmpwalk 1.3.6.1.4.1.232',
required => 0,
);
$plugin->add_arg(
spec => 'hpasmcli=s',
help => '--hpasmcli
A file with the output of hpasmcli',
required => 0,
);
$plugin->add_arg(
spec => 'servertype=s',
help => '--servertype
The type of the server: proliant (default) or bladecenter',
required => 0,
);
$plugin->getopts();
if (! $PERFDATA && $plugin->opts->get('perfdata')) {
$PERFDATA = 1;
}
if ($PERFDATA && $plugin->opts->get('perfdata') &&
($plugin->opts->get('perfdata') eq 'short')) {
$PERFDATA = 2;
}
$plugin->{messages}->{unknown} = []; # wg. add_message(UNKNOWN,...)
$plugin->{info} = []; # gefrickel
my $server = HP::Server->new( runtime => {
plugin => $plugin,
options => {
servertype => $plugin->opts->get('servertype'),
verbose => $plugin->opts->get('verbose'),
scrapiron => 0,
ignore_fan_redundancy => $plugin->opts->get('ignore-fan-redundancy'),
ignore_dimms => $plugin->opts->get('ignore-dimms'),
customthresholds => $plugin->opts->get('customthresholds'),
blacklist => $plugin->opts->get('blacklist'),
celsius => $CELSIUS,
perfdata => $PERFDATA,
extendedinfo => $EXTENDEDINFO,
hwinfo => $HWINFO,
hpacucli => $HPACUCLI,
noinstlevel => $NOINSTLEVEL,
},
},);
if (! $plugin->check_messages()) {
$server->init();
$plugin->add_message(OK, $server->identify()) if $HWINFO;
if (! $plugin->check_messages()) {
$plugin->add_message(OK, 'hardware working fine');
$plugin->add_message(OK, $server->get_summary())
if $server->get_summary();
$plugin->add_message(OK, $server->get_extendedinfo())
if $server->get_extendedinfo();
}
} else {
$plugin->add_message(CRITICAL, 'wrong device');
}
my ($code, $message) = $plugin->check_messages(join => ', ', join_all => ', ');
$message .= sprintf "\n%s\n", join("\n", @{$plugin->{info}})
if $plugin->opts->get('verbose') >= 1;
#printf "%s\n", Data::Dumper::Dumper($plugin->{info});
$plugin->nagios_exit($code, $message);