63505f393885f2fb651749ab7da2884d11f82c0b
[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 my %callbacks = (
39   'SHOW DIMM'        => \&do_dimm,
40   'SHOW FANS'        => \&do_fans,
41   'SHOW POWERSUPPLY' => \&do_powersupply,
42   'SHOW TEMP'        => \&do_temp,
43 );
44
45 my $prompt = "hpasmcli>";
46 my $exit_status = 0;
47 my $ret = '';
48
49 sub do_dimm {
50   my @output = @_;
51   my $dimm_num = my $status = my $return = my $message = '';
52   my $in_block = my $header_seen = my $num_dimms = 0;
53
54   for my $line (@output) {
55     chomp $line;
56     unless ($header_seen) {
57       next until ($line eq "$prompt SHOW DIMM");
58       $header_seen++;
59       next;
60     }
61
62     if ($line =~ /(^\s*$|-----)/) {
63       if ($in_block) {
64         if ($status ne 'Ok') {
65           $message = sprintf("DIMM%d: %s ", $dimm_num, $status);
66           $exit_status |= 2;
67         }
68         $return .= $message if ($message);
69         $message = $status = '';
70       } else {
71         $in_block++;
72       }
73     }
74
75     if ($line =~ /^Module #:\s+(\d)/) {
76       $dimm_num = $1;
77       $num_dimms++;
78     } elsif ($line =~ /Status:\s+(\S+(\s*(.*)?))/) {
79       $status = $1;
80     } elsif ($line =~ /$prompt/) {
81       last;
82     }
83   }
84
85   if ($return eq '') {
86     return "DIMMS OK ($num_dimms) ";
87   } else {
88     return $return;
89   }
90 }
91
92 sub do_fans {
93   my @output = @_;
94   my $fan_num = my $status = my $present = my $return = my $message = '';
95   my $header_seen = my $num_fans = 0;
96
97   for my $line (@output) {
98     chomp $line;
99     unless ($header_seen) {
100       next until ($line eq "$prompt SHOW FANS");
101       $header_seen++;
102       next;
103     }
104
105     if ($line =~ /^#(\d+)/) {
106       if ($num_fans) {
107         $return .= $message if ($message);
108         $message = '';
109       }
110
111       $fan_num = $1;
112       $num_fans++;
113       my @line = split /\s+/, $line;
114
115       if ($line[2] ne 'Yes') {
116         $message = sprintf("FAN%d: status=%s ", $fan_num, $line[2]);
117         $exit_status |= 2;
118       } elsif ($line[3] ne 'NORMAL') {
119         $message = sprintf("FAN%d: speed=%s ", $fan_num, $line[3]);
120         $exit_status |= 1;
121       } elsif ($line[5] ne 'Yes') {
122         $message = sprintf("FAN%d: redundant=%s ",$fan_num, $line[5]);
123         $exit_status |= 1;
124       }
125     } elsif ($line =~ /($prompt|^\s*$)/) {
126       last;
127     }
128   }
129   $return .= $message if ($message);
130
131   if ($return eq '') {
132     return "FANS OK ($num_fans) ";
133   } else {
134     return $return;
135   }
136 }
137
138 sub do_powersupply {
139   my @output = @_;
140   my $ps_num = my $return = my $message = '';
141   my $header_seen = my $num_ps = 0;
142
143   for my $line (@output) {
144     chomp $line;
145     unless ($header_seen) {
146       next until ($line eq "$prompt SHOW POWERSUPPLY");
147       $header_seen++;
148       next;
149     }
150
151     if ($line =~ /^Power supply #(\d+)/) {
152       if ($num_ps) {
153         $return .= $message if ($message);
154         $message = '';
155       }
156       $ps_num = $1;
157       $num_ps++;
158     } elsif ($line =~ /\s+Present\s*:\s+(.*)/) {
159       my $present = $1;
160       if ($present ne 'Yes') {
161         $message = sprintf("PS%d missing ", $ps_num);
162         $exit_status |= 1;
163       }
164     } elsif ($line =~ /\s+Condition\s*:\s+(.*)/) {
165       my $status = $1;
166       if ($status ne 'Ok') {
167         $message = sprintf("PS%d: %s  ", $ps_num, $status);
168         $exit_status |= 2;
169       }
170     } elsif ($line =~ /\s+Redundant\s*:\s+(.*)/) {
171       my $redundant = $1;
172       if ($redundant ne 'Yes') {
173         $message = sprintf("PS%d not redundant ", $ps_num);
174         $exit_status |= 1;
175       }
176     } elsif ($line =~ /($prompt|^\s*$)/) {
177       last;
178     }
179   }
180   $return .= $message if ($message);
181
182   if ($return eq '') {
183     return "POWER OK ($num_ps) ";
184   } else {
185     return $return;
186   }
187 }
188
189 sub do_temp {
190   my @output = @_;
191   my $temp_num = my $return = my $message = '';
192   my $header_seen = my $num_temp = 0;
193
194   for my $line (@output) {
195     chomp $line;
196     unless ($header_seen) {
197       next until ($line eq "$prompt SHOW TEMP");
198       $header_seen++;
199       next;
200     }
201
202     if ($line =~ /^#(\d+)/) {
203       if ($num_temp) {
204         $return .= $message if ($message);
205         $message = '';
206       }
207
208       $temp_num = $1;
209       my @line = split /\s+/, $line;
210
211       my $zone = $line[1];
212       my $current_temp = $line[2];
213       my $threshold = $line[3];
214
215       $current_temp =~ s/(.*)C.*/$1/;
216       $threshold =~ s/(.*)C.*/$1/;
217       next if ($threshold eq '-');
218       $num_temp++;
219
220       my $off = $threshold - $current_temp;
221       if ($off <= 0) {
222         $message = sprintf("TEMP zone=%s %sC/%sC ", $zone, $current_temp, $threshold);
223         $exit_status |= 2;
224       } elsif ($off < ($threshold/10)) {
225         $message = sprintf("TEMP zone=%s %sC/%sC ", $zone, $current_temp, $threshold);
226         $exit_status |= 1;
227       }
228     } elsif ($line =~ /($prompt|^\s*$)/) {
229       last;
230     }
231   }
232   $return .= $message if ($message);
233   if ($return eq '') {
234     return "TEMP OK ($num_temp) ";
235   } else {
236     return $return;
237   }
238 }
239
240 my @output = `echo "$command"|sudo hpasmcli 2>&1`;
241 if (($? >> 8) != 0) {
242   print "UNKNOWN: Can't exec hpasmcli: @output\n";
243   exit 3;
244 }
245
246 for my $line (@output) {
247   chomp $line;
248   for my $check (sort keys %callbacks) {
249     if ($line eq "$prompt $check") {
250       $ret .= &{$callbacks{$check}}(@output);
251     }
252   }
253 }
254
255 if ($exit_status & 2) {
256   print "CRTICAL: $ret\n";
257   exit 2;
258 } elsif ($exit_status & 1) {
259   print "WARNING: $ret\n";
260   exit 1;
261 } else {
262   print "OK: $ret\n";
263   exit 0;
264 }