initial version of check_hpasm script
[mirror/dsa-nagios.git] / dsa-nagios-checks / checks / dsa-check-hpasm
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 # check status of various hardware devices (fans, temp, dimms, powersupply)
7 # requires hpasmcli
8
9 # Copyright (c) 2009 Stephen Gran <steve@lobefin.net>
10 #
11 # Permission is hereby granted, free of charge, to any person obtaining
12 # a copy of this software and associated documentation files (the
13 # "Software"), to deal in the Software without restriction, including
14 # without limitation the rights to use, copy, modify, merge, publish,
15 # distribute, sublicense, and/or sell copies of the Software, and to
16 # permit persons to whom the Software is furnished to do so, subject to
17 # the following conditions:
18 #
19 # The above copyright notice and this permission notice shall be
20 # included in all copies or substantial portions of the Software.
21 #
22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 my $command = <<EOF;
31 SHOW DIMM
32 SHOW FANS
33 SHOW POWERSUPPLY
34 SHOW TEMP
35 QUIT
36 EOF
37
38 $ENV{'LD_LIBRARY_PATH'} = '/home/sgran/lib';
39
40 my %callbacks = (
41   'SHOW DIMM'        => \&do_dimm,
42   'SHOW FANS'        => \&do_fans,
43   'SHOW POWERSUPPLY' => \&do_powersupply,
44   'SHOW TEMP'        => \&do_temp,
45 );
46
47 my $prompt = "hpasmcli>";
48 my $exit_status = 0;
49 my $ret = '';
50
51 sub do_dimm {
52   my @output = @_;
53   my $dimm_num = my $status = my $return = my $message = '';
54   my $in_block = my $header_seen = my $num_dimms = 0;
55
56   for my $line (@output) {
57     chomp $line;
58     unless ($header_seen) {
59       next until ($line eq "$prompt SHOW DIMM");
60       $header_seen++;
61       next;
62     }
63
64     if ($line =~ /(^\s*$|-----)/) {
65       if ($in_block) {
66         if ($status ne 'Ok') {
67           $message = sprintf("DIMM%d: %s ", $dimm_num, $status);
68           $exit_status |= 2;
69         }
70         $return .= $message if ($message);
71         $message = $status = '';
72       } else {
73         $in_block++;
74       }
75     }
76
77     if ($line =~ /^Module #:\s+(\d)/) {
78       $dimm_num = $1;
79       $num_dimms++;
80     } elsif ($line =~ /Status:\s+(\S+(\s*(.*)?))/) {
81       $status = $1;
82     } elsif ($line =~ /$prompt/) {
83       last;
84     }
85   }
86
87   if ($return eq '') {
88     return "All DIMMS OK ($num_dimms)";
89   } else {
90     return $return;
91   }
92 }
93
94 sub do_fans {
95   my @output = @_;
96   my $fan_num = my $status = my $present = my $return = my $message = '';
97   my $header_seen = my $num_fans = 0;
98
99   for my $line (@output) {
100     chomp $line;
101     unless ($header_seen) {
102       next until ($line eq "$prompt SHOW FANS");
103       $header_seen++;
104       next;
105     }
106
107     if ($line =~ /^#(\d+)/) {
108       if ($num_fans) {
109         $return .= $message if ($message);
110         $message = '';
111       }
112
113       $fan_num = $1;
114       $num_fans++;
115       my @line = split /\s+/, $line;
116
117       if ($line[2] ne 'Yes') {
118         $message = sprintf("FAN%d: status=%s ", $fan_num, $line[2]);
119         $exit_status |= 2;
120       } elsif ($line[3] ne 'NORMAL') {
121         $message = sprintf("FAN%d: speed=%s ", $fan_num, $line[3]);
122         $exit_status |= 1;
123       } elsif ($line[5] ne 'Yes') {
124         $message = sprintf("FAN%d: redundant=%s ",$fan_num, $line[5]);
125         $exit_status |= 1;
126       }
127     } elsif ($line =~ /($prompt|^\s*$)/) {
128       last;
129     }
130   }
131   $return .= $message if ($message);
132
133   if ($return eq '') {
134     return "FANS OK ($num_fans) ";
135   } else {
136     return $return;
137   }
138 }
139
140 sub do_powersupply {
141   my @output = @_;
142   my $ps_num = my $return = my $message = '';
143   my $header_seen = my $num_ps = 0;
144
145   for my $line (@output) {
146     chomp $line;
147     unless ($header_seen) {
148       next until ($line eq "$prompt SHOW POWERSUPPLY");
149       $header_seen++;
150       next;
151     }
152
153     if ($line =~ /^Power supply #(\d+)/) {
154       if ($num_ps) {
155         $return .= $message if ($message);
156         $message = '';
157       }
158       $ps_num = $1;
159       $num_ps++;
160     } elsif ($line =~ /\s+Present\s*:\s+(.*)/) {
161       my $present = $1;
162       if ($present ne 'Yes') {
163         $message = sprintf("PS%d missing ", $ps_num);
164         $exit_status |= 1;
165       }
166     } elsif ($line =~ /\s+Condition\s*:\s+(.*)/) {
167       my $status = $1;
168       if ($status ne 'Ok') {
169         $message = sprintf("PS%d: %s  ", $ps_num, $status);
170         $exit_status |= 2;
171       }
172     } elsif ($line =~ /\s+Redundant\s*:\s+(.*)/) {
173       my $redundant = $1;
174       if ($redundant ne 'Yes') {
175         $message = sprintf("PS%d not redundant ", $ps_num);
176         $exit_status |= 1;
177       }
178     } elsif ($line =~ /($prompt|^\s*$)/) {
179       last;
180     }
181   }
182   $return .= $message if ($message);
183
184   if ($return eq '') {
185     return "POWER OK ($num_ps) ";
186   } else {
187     return $return;
188   }
189 }
190
191 sub do_temp {
192   my @output = @_;
193   my $temp_num = my $return = my $message = '';
194   my $header_seen = my $num_temp = 0;
195
196   for my $line (@output) {
197     chomp $line;
198     unless ($header_seen) {
199       next until ($line eq "$prompt SHOW TEMP");
200       $header_seen++;
201       next;
202     }
203
204     if ($line =~ /^#(\d+)/) {
205       if ($num_temp) {
206         $return .= $message if ($message);
207         $message = '';
208       }
209
210       $temp_num = $1;
211       $num_temp++;
212       my @line = split /\s+/, $line;
213
214       my $zone = $line[1];
215       my $current_temp = $line[2];
216       my $threshold = $line[3];
217
218       $current_temp =~ s/(.*)C.*/$1/;
219       $threshold =~ s/(.*)C.*/$1/;
220
221       my $off = $threshold - $current_temp;
222       if ($off <= 0) {
223         $message = sprintf("TEMP zone=%s %sC/%sC ", $zone, $current_temp, $threshold);
224         $exit_status |= 2;
225       } elsif ($off < ($threshold/10)) {
226         $message = sprintf("TEMP zone=%s %sC/%sC ", $zone, $current_temp, $threshold);
227         $exit_status |= 1;
228       }
229     } elsif ($line =~ /($prompt|^\s*$)/) {
230       last;
231     }
232   }
233   $return .= $message if ($message);
234   if ($return eq '') {
235     return "TEMP OK ($num_temp) ";
236   } else {
237     return $return;
238   }
239 }
240
241 my @output = `echo "$command"|hpasmcli 2>&1`;
242 if (($? >> 8) != 0) {
243   print "UNKNOWN: Can't exec hpasmcli: @output\n";
244   exit 3;
245 }
246
247 for my $line (@output) {
248   chomp $line;
249   for my $check (sort keys %callbacks) {
250     if ($line eq "$prompt $check") {
251       $ret .= &{$callbacks{$check}}(@output);
252     }
253   }
254 }
255
256 if ($exit_status & 2) {
257   print "CRTICAL: $ret\n";
258   exit 2;
259 } elsif ($exit_status & 1) {
260   print "WARNING: $ret\n";
261   exit 1;
262 } else {
263   print "OK: $ret\n";
264   exit 0;
265 }