mirror of
https://github.com/opinkerfi/nagios-plugins.git
synced 2024-12-27 11:33:57 +01:00
8391 lines
262 KiB
Perl
Executable File
8391 lines
262 KiB
Perl
Executable File
#! /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);
|
||
|