]>
Commit | Line | Data |
---|---|---|
b702b2ea | 1 | #!/usr/bin/perl |
2 | ||
3 | # ---------------------------------------------------------------------- | |
4 | # Web interface for Mon. | |
5 | # Arthur K. Chan <artchan@althem.com> | |
6 | # Based on the Mon program by Jim Trocki <trockij@transmeta.com>. | |
7 | # http://www.kernel.org/software/mon/ | |
8 | # ---------------------------------------------------------------------- | |
9 | # $Id$ | |
10 | # ---------------------------------------------------------------------- | |
11 | ||
12 | # Instructions --------------------------------------------------------- | |
13 | # | |
14 | # Install this cgi script to whereever your cgi-bin directory sits | |
15 | # on your mon server. If you don't have a web server installed, try | |
16 | # http://www.apache.org. | |
17 | # | |
18 | # Modify the "Configurable Parameters" section below to customize it | |
19 | # to your site's settings. Send comment about this web interface to | |
20 | # Art Chan at the address above. | |
21 | # | |
22 | # This script will require the CGI perl module. Available at any | |
23 | # perl CPAN site. See http://www.perl.org for details. | |
24 | ||
25 | ||
26 | # Configurable Parameters ---------------------------------------------- | |
27 | ||
28 | $organization = ""; # Organization name. | |
29 | $monadmin = ""; # Your e-mail address. | |
30 | $logo = ""; # Company or mon logo. | |
31 | $reload="180"; # Seconds for page reload. | |
32 | $monhost="monhost"; # Mon server hostname. | |
33 | $BGCOLOR = "white"; # Background color | |
34 | $BUTTONCOLOR = "tan"; # Button bar color | |
35 | ||
36 | # You shouldn't need to change these. | |
37 | $url = $ENV{SCRIPT_NAME}; # URL of this script. | |
38 | ||
39 | # General Declarations ------------------------------------------------- | |
40 | ||
41 | use CGI; # Use the cgi module. | |
42 | use Mon::Client; # mon client interface | |
43 | ||
44 | %OPSTAT = %Mon::Client::OPSTAT; | |
45 | ||
46 | $webpage = new CGI; # Declare instance of mod. | |
47 | ||
48 | $time = time; # This will be used for | |
49 | $localtime = localtime(time); # the time on the page. | |
50 | ||
51 | ||
52 | # Reverse sort --------------------------------------------------------- | |
53 | sub backwards { | |
54 | $b cmp $a; | |
55 | } | |
56 | ||
57 | # Return untainted host or group name if safe, undef otherwise --------- | |
58 | sub validate_name { | |
59 | return $_[0] =~ /^([\w.\-_]+)$/ ? $1 : undef; | |
60 | } | |
61 | ||
62 | ||
63 | # Setup the html doc headers and such ---------------------------------- | |
64 | sub setup_page { | |
65 | my ($title) = @_; | |
66 | print $webpage->header; | |
67 | print $webpage->start_html(-title=>"MON - $title", | |
68 | -BGCOLOR=>$BGCOLOR); | |
69 | print $webpage->h1("MON $title"); | |
70 | if ($logo){ | |
71 | $webpage->print("\n<img src=\"$logo\"><br><br>\n"); | |
72 | } | |
73 | if ($organization){ | |
74 | print $webpage->h3("$organization"); | |
75 | } | |
76 | &print_bar; | |
77 | ||
78 | $qtime = time; | |
79 | @time = localtime($qtime); | |
80 | my $ttime = sprintf ("%.2d:%.2d:%.2d", $time[2],$time[1],$time[0]); | |
81 | print $webpage->center | |
82 | ("\nThis information was presented at: $ttime. "); | |
83 | } | |
84 | ||
85 | ||
86 | # Print the button bar ------------------------------------------------- | |
87 | sub print_bar { | |
88 | $button = "INPUT TYPE=\"submit\" NAME=\"command\""; | |
89 | $webpage->print("\n\n<FORM METHOD=\"GET\">\n"); | |
90 | $webpage->print("<table bgcolor=$BUTTONCOLOR width=75% border=1 align=center>\n"); | |
91 | $webpage->print("<tr>\n"); | |
92 | $webpage->print("\t<td width=3 align=center>Show Operation Status</td>\n"); | |
93 | $webpage->print("\t<td width=3 align=center>Show Alert History</td>\n"); | |
94 | $webpage->print("\t<td width=3 align=center>Disable/Enable monitoring.</td>\n"); | |
95 | $webpage->print("\t<td width=3 align=center>List Disabled Hosts</td>\n"); | |
96 | $webpage->print("\t<td width=3 align=center>List PIDs for mon processes.</td>\n"); | |
97 | $webpage->print("\t<td width=3 align=center>Restart Mon</td>\n"); | |
98 | $webpage->print("</tr>\n"); | |
99 | $webpage->print("\t<tr><td width=3 align=center><$button VALUE=\"opstatus\"></td>\n"); | |
100 | $webpage->print("\t<td width=3 align=center><$button VALUE=\"alerthist\"></td>\n"); | |
101 | $webpage->print("\t<td width=3 align=center><$button VALUE=\"disable\"></td>\n"); | |
102 | $webpage->print("\t<td width=3 align=center><$button VALUE=\"disabled\"></td>\n"); | |
103 | $webpage->print("\t<td width=3 align=center><$button VALUE=\"pids\"></td>\n"); | |
104 | $webpage->print("\t<td width=3 align=center><$button VALUE=\"reset\"></td>\n"); | |
105 | $webpage->print("</tr></table>"); | |
106 | ||
107 | $webpage->print("</form>\n"); | |
108 | } | |
109 | ||
110 | ||
111 | # query the server operational status ---------------------------------- | |
112 | sub query_opstatus { | |
113 | ||
114 | print $webpage->center | |
115 | ("This page will reload every $reload seconds.<br><br>\n"); | |
116 | $webpage->print("\n<META HTTP-EQUIV=\"Refresh\""); | |
117 | $webpage->print("CONTENT=\"$reload\", URL=\"$url\">\n"); | |
118 | ||
119 | my $c = new Mon::Client ( | |
120 | host => $monhost, | |
121 | ); | |
122 | ||
123 | $c->connect(); | |
124 | ||
125 | if ($c->error ne "") { | |
126 | # ignore the error for now :( | |
127 | } | |
128 | ||
129 | my %op = $c->list_opstatus(); | |
130 | ||
131 | if ($c->error ne "") { | |
132 | # ignore the error for now :( | |
133 | } | |
134 | ||
135 | $c->disconnect(); | |
136 | ||
137 | $webpage->print("<table align=center border=1 width=35%>"); | |
138 | $webpage->print | |
139 | ("<tr><td><font color=black>Service color legend:</font></td>\n"); | |
140 | $webpage->print("<td><font color=black>Unchecked</font></td>\n"); | |
141 | $webpage->print("<td><font color=green>Good</font></td>\n "); | |
142 | $webpage->print("<td><font color=red>Error</font></td></tr>\n"); | |
143 | $webpage->print("</table>"); | |
144 | ||
145 | $webpage->print | |
146 | ("<table align=center width=80% border=1>\n"); | |
147 | $webpage->print | |
148 | ("<tr><th>Host Group</th><th>Service</th>\n"); | |
149 | $webpage->print | |
150 | ("<th>Last Checked</th><th>Est. Next Check</th></tr>\n"); | |
151 | ||
152 | foreach my $group (sort keys %op) { | |
153 | foreach my $service (sort keys %{$op{$group}}) { | |
154 | ||
155 | my $s = \%{$op{$group}->{$service}}; | |
156 | ||
157 | $webpage->print("<tr><td>\n"); | |
158 | $webpage->print | |
159 | ("<a href=\"$url?command=group&args=$group\">"); | |
160 | $webpage->print("$group</a></td>\n"); | |
161 | ||
162 | if ($s->{"opstatus"} == $OPSTAT{"untested"}) { | |
163 | $webpage->print("<td><font color=black>\n"); | |
164 | $webpage->print("$service</font></td>"); | |
165 | ||
166 | } elsif ($s->{"opstatus"} == $OPSTAT{"fail"}) { | |
167 | $webpage->print("<td><blink>"); | |
168 | $webpage->print | |
169 | ("<a href=\"$url?command=alert&args=$group,$service\">"); | |
170 | $webpage->print | |
171 | ("<font color=red>$service</font></a></blink></td>\n"); | |
172 | ||
173 | } elsif ($s->{"opstatus"} == $OPSTAT{"ok"}) { | |
174 | $webpage->print("<td><font color=green>"); | |
175 | $webpage->print("$service</font></td>\n"); | |
176 | ||
177 | } else { | |
178 | my $txt = ""; | |
179 | for (keys %OPSTAT) { | |
180 | $txt = $_ if ($s->{"opstatus"} == $OPSTAT{$_}); | |
181 | } | |
182 | $webpage->print("<td><font color=purple>"); | |
183 | $webpage->print("$service ($txt)</font></td>\n"); | |
184 | } | |
185 | ||
186 | if ($s->{"opstatus"} == $OPSTAT{"untested"}) { | |
187 | $webpage->print("<td>-</td>"); | |
188 | ||
189 | } else { | |
190 | my @time = localtime ($s->{"last_check"}); | |
191 | $webpage->print( | |
192 | sprintf ("<td>%.2d:%.2d:%.2d</td>\n", @time[2, 1, 0]) | |
193 | ); | |
194 | } | |
195 | ||
196 | my @time = localtime ($qtime+$s->{"next"}); | |
197 | $webpage->print( | |
198 | sprintf ("<td>%.2d:%.2d:%.2d</td>\n", @time[2, 1, 0]) | |
199 | ); | |
200 | $webpage->print("</tr>"); | |
201 | } | |
202 | } | |
203 | $webpage->print("</table>\n"); | |
204 | } | |
205 | ||
206 | ||
207 | # Extract the list of hosts associated with the group --------------- | |
208 | sub query_group { | |
209 | ||
210 | my $group = &validate_name ($args); | |
211 | ||
212 | if (!defined $group) { | |
213 | $webpage->print("Invalid host group\n"); | |
214 | ||
215 | } else { | |
216 | my $c = new Mon::Client ( | |
217 | host => $monhost, | |
218 | ); | |
219 | ||
220 | $c->connect(); | |
221 | ||
222 | if ($c->error ne "") { | |
223 | # ignore error for now | |
224 | } | |
225 | ||
226 | @hosts = $c->list_group ($group); | |
227 | ||
228 | if ($c->error ne "") { | |
229 | my $e = $c->error; | |
230 | $webpage->print (<<"EOF" | |
231 | <pre> | |
232 | Could not list groups: $e | |
233 | </pre> | |
234 | EOF | |
235 | ); | |
236 | return undef; | |
237 | } | |
238 | ||
239 | $c->disconnect(); | |
240 | ||
241 | $webpage->print("<table align=center width=50% border=1>"); | |
242 | $webpage->print("<th>Members of group \"<em>$group</em>\".</th>") ; | |
243 | ||
244 | foreach my $host (sort @hosts) { | |
245 | $webpage->print("<tr><td>$host</td></tr>") ; | |
246 | } | |
247 | $webpage->print("</table>"); | |
248 | } | |
249 | } | |
250 | ||
251 | ||
252 | # End the document ----------------------------------------------------- | |
253 | sub end_page { | |
254 | &print_bar; | |
255 | if ($monadmin) { | |
256 | print $webpage->center("For questions about this server. Contact:"); | |
257 | print $webpage->center | |
258 | ("<a href=\"mailto:$monadmin\">$monadmin</a><br>"); | |
259 | } | |
260 | print $webpage->end_html; | |
261 | } | |
262 | ||
263 | ||
264 | # Get the params from the form ----------------------------------------- | |
265 | sub get_params { | |
266 | $command = $webpage->param('command'); | |
267 | $args = $webpage->param('args'); | |
268 | $enable_host = $webpage->param('enablehost'); | |
269 | $enable_group = $webpage->param('enablegroup'); | |
270 | $enable_service = $webpage->param('enableservice'); | |
271 | $enable_watch = $webpage->param('enablewatch'); | |
272 | ||
273 | $disable_host = $webpage->param('disablehost'); | |
274 | $disable_group = $webpage->param('disablegroup'); | |
275 | $disable_service = $webpage->param('disableservice'); | |
276 | $disable_watch = $webpage->param('disablewatch'); | |
277 | } | |
278 | ||
279 | ||
280 | # What to do if the view alert details is depressed -------------------- | |
281 | sub alert { | |
282 | local ($arg) = @_; | |
283 | ||
284 | my ($group, $service) = split (/\,/, $arg); | |
285 | ||
286 | print $webpage->hr; | |
287 | $webpage->print | |
288 | ("<h2>Failure detail for group <font color=red>$group</font> "); | |
289 | $webpage->print | |
290 | ("and service <i>$service</i> test:</h2>"); | |
291 | ||
292 | my $c = new Mon::Client ( | |
293 | host => $monhost, | |
294 | ); | |
295 | ||
296 | $c->connect(); | |
297 | ||
298 | if ($c->error ne "") { | |
299 | # ignore errors for now | |
300 | } | |
301 | ||
302 | my %op = $c->list_opstatus(); | |
303 | ||
304 | if ($c->error ne "") { | |
305 | # ignore errors for now | |
306 | } | |
307 | ||
308 | $c->disconnect(); | |
309 | ||
310 | foreach my $g (keys %op) { | |
311 | next if ($g ne $group); | |
312 | foreach my $s (keys %{$op{$g}}) { | |
313 | next if ($s ne $service); | |
314 | $webpage->print("$op{$g}->{$s}->{last_summary}\n"); | |
315 | } | |
316 | } | |
317 | ||
318 | print $webpage->hr; | |
319 | } | |
320 | ||
321 | ||
322 | # List alert history -------------------------------------------------- | |
323 | sub alerthist { | |
324 | print $webpage->hr; | |
325 | print $webpage->h2("Alert History:"); | |
326 | ||
327 | my $c = new Mon::Client ( | |
328 | host => $monhost, | |
329 | ); | |
330 | ||
331 | $c->connect(); | |
332 | ||
333 | if ($c->error ne "") { | |
334 | # ignore error | |
335 | } | |
336 | ||
337 | my @l = $c->list_alerthist(); | |
338 | ||
339 | $c->disconnect(); | |
340 | ||
341 | $webpage->print("<table border=1 width=80% align=center>\n"); | |
342 | ||
343 | $webpage->print("<tr><th>Group</th><th>Service</th>\n"); | |
344 | $webpage->print("<th>Type</th><th>Time</th><th>Alert</th>\n"); | |
345 | $webpage->print("<th>Args</th><th>Summary</th>\n"); | |
346 | $webpage->print("</tr>\n"); | |
347 | ||
348 | foreach my $line (reverse sort {$a->{"time"} <=> $b->{"time"}} (@l)) { | |
349 | my $localtime = localtime ($line->{"time"}); | |
350 | ||
351 | $webpage->print("<tr><td><a href=\"$url?command=group&"); | |
352 | $webpage->print("args=$line->{group}\">$line->{group}</a></td>"); | |
353 | ||
354 | $webpage->print("<td>$line->{service}</td>\n"); | |
355 | $webpage->print("<td>$line->{type}</td>\n"); | |
356 | $webpage->print("<td>$localtime</td>\n"); | |
357 | ||
358 | $line->{"alert"} =~ s{^.*\/([^/]*)$}{$1}; | |
359 | ||
360 | $webpage->print("<td>$line->{alert}</td>\n"); | |
361 | ||
362 | my $args = "-"; | |
363 | if ($line->{"args"} !~ /^\s*$/) { | |
364 | $args = $line->{"args"}; | |
365 | } | |
366 | ||
367 | $webpage->print("<td>$args</td>\n"); | |
368 | $webpage->print("<td>$line->{summary}</td>"); | |
369 | ||
370 | $webpage->print("</tr>\n"); | |
371 | } | |
372 | ||
373 | $webpage->print("</table>\n"); | |
374 | print $webpage->hr; | |
375 | } | |
376 | ||
377 | ||
378 | # Generic button function --------------------------------------------- | |
379 | sub button { | |
380 | local ($title, $command) = @_; | |
381 | ||
382 | print $webpage->hr; | |
383 | print $webpage->h2("$title"); | |
384 | print "(command not implemented in this client)\n"; | |
385 | print $webpage->hr; | |
386 | } | |
387 | ||
388 | ||
389 | # Form to get item to disable ------------------------------------------- | |
390 | sub disable { | |
391 | print $webpage->hr; | |
392 | print $webpage->h2("$title"); | |
393 | ||
394 | $webpage->print ("(command not implemented in this client)\n"); | |
395 | ||
396 | print $webpage->hr; | |
397 | ||
398 | return; | |
399 | ||
400 | my ($desc, $cmd, @arg); | |
401 | if ($disable_host) { | |
402 | $desc = "Attempting to disable a host"; | |
403 | $cmd = "disable host"; | |
404 | push @arg, $disable_host; | |
405 | } elsif (($disable_group) && ($disable_service)) { | |
406 | $desc = "Attempting to disable a service"; | |
407 | $cmd = "disable service"; | |
408 | push @arg, $disable_group, $disable_service; | |
409 | } elsif ($disable_watch) { | |
410 | $desc = "Disable a watch"; | |
411 | $cmd = "disable watch"; | |
412 | push @arg, $disable_watch; | |
413 | } elsif ($enable_host) { | |
414 | $desc = "Attempting to enable a host"; | |
415 | $cmd = "enable host"; | |
416 | push @arg, $enable_host; | |
417 | } elsif (($enable_group) && ($enable_service)) { | |
418 | $desc = "Attempting to enable a service"; | |
419 | $cmd = "enable service"; | |
420 | push @arg, $enable_group, $enable_service; | |
421 | } elsif ($enable_watch) { | |
422 | $desc = "Enable a watch"; | |
423 | $cmd = "enable watch"; | |
424 | push @arg, $enable_watch; | |
425 | } | |
426 | if ($desc) { | |
427 | my $bad = 0; | |
428 | for (@arg) { | |
429 | $_ = &validate_name($_); | |
430 | $bad = 1 if !defined $_; | |
431 | } | |
432 | if ($bad) { | |
433 | # Don't try to print out the invalid arg, it wouldn't be | |
434 | # safe. | |
435 | print "Invalid argument for $cmd.\n"; | |
436 | } | |
437 | else { | |
438 | print "$desc: @arg<br>\n"; | |
439 | for (@arg) { | |
440 | $cmd .= " \Q$_"; | |
441 | } | |
442 | open (MON, "$moncmd -s $monhost $cmd|"); | |
443 | while (<MON>) { | |
444 | print "$_<BR>\n"; | |
445 | } | |
446 | close MON; | |
447 | } | |
448 | print $webpage->hr; | |
449 | } | |
450 | ||
451 | print "<table width=100%>"; | |
452 | print "<tr><td>"; | |
453 | print $webpage->startform(GET); | |
454 | print "Disable a host.<br>\n"; | |
455 | print $webpage->textfield('disablehost'); | |
456 | print " Hostname<br>"; | |
457 | print $webpage->submit(-name=>'command',-value=>'disable'); | |
458 | print $webpage->endform; | |
459 | print "</td><td>"; | |
460 | print $webpage->startform(GET); | |
461 | print "Enable a host.<br>\n"; | |
462 | print $webpage->textfield('enablehost'); | |
463 | print " Hostname<br>"; | |
464 | print $webpage->submit(-name=>'command',-value=>'enable'); | |
465 | print $webpage->endform; | |
466 | print "</td></table>"; | |
467 | print $webpage->hr; | |
468 | ||
469 | print "<table width=100%>"; | |
470 | print "<tr><td>"; | |
471 | print $webpage->startform(GET); | |
472 | print "Disable a service for a group.<br>\n"; | |
473 | print $webpage->textfield('disablegroup'); | |
474 | print " Group<br>"; | |
475 | print $webpage->textfield('disableservice'); | |
476 | print " Service<br>"; | |
477 | print $webpage->submit(-name=>'command',-value=>'disable'); | |
478 | print $webpage->endform; | |
479 | print "</td><td>"; | |
480 | print $webpage->startform(GET); | |
481 | print "Enable a service for a group.<br>\n"; | |
482 | print $webpage->textfield('enablegroup'); | |
483 | print " Group<br>"; | |
484 | print $webpage->textfield('enableservice'); | |
485 | print " Service<br>"; | |
486 | print $webpage->submit(-name=>'command',-value=>'enable'); | |
487 | print $webpage->endform; | |
488 | print "</td></table>"; | |
489 | print $webpage->hr; | |
490 | ||
491 | print "<table width=100%>"; | |
492 | print "<tr><td>"; | |
493 | print $webpage->startform(GET); | |
494 | print "Disable a watch.<br>\n"; | |
495 | print $webpage->textfield('disablewatch'); | |
496 | print " Watch<br>"; | |
497 | print $webpage->submit(-name=>'command',-value=>'disable'); | |
498 | print $webpage->endform; | |
499 | print "</td><td>"; | |
500 | print $webpage->startform(GET); | |
501 | print "Enable a watch.<br>\n"; | |
502 | print $webpage->textfield('enablewatch'); | |
503 | print " Watch<br>"; | |
504 | print $webpage->submit(-name=>'command',-value=>'enable'); | |
505 | print $webpage->endform; | |
506 | print "</td></table>"; | |
507 | print $webpage->hr; | |
508 | } | |
509 | ||
510 | ||
511 | ||
512 | # Main program --------------------------------------------------------- | |
513 | ||
514 | &get_params; # Read the args. | |
515 | ||
516 | if ($command =~ "group" ){ # Expand hostgroup. | |
517 | &setup_page("Group Expansion"); | |
518 | &query_group; | |
519 | } | |
520 | elsif ($command =~ "alerthist"){ # Alert history button. | |
521 | &setup_page("List the alert history"); | |
522 | &alerthist; | |
523 | } | |
524 | elsif ($command =~ "alert"){ # View alert details. | |
525 | &setup_page("Alert Details"); | |
526 | &alert($args); | |
527 | } | |
528 | elsif ($command =~ "disabled"){ # Disabled hosts button. | |
529 | &setup_page("List disabled hosts"); | |
530 | &button("Disabled hosts:","list disabled"); | |
531 | } | |
532 | elsif ($command =~ "disable"){ # Disabled | |
533 | &setup_page("Disable/Enable alert for host, group. or service"); | |
534 | &disable; | |
535 | } | |
536 | elsif ($command =~ "enable"){ # Disabled | |
537 | &setup_page("Disable/Enable alert for host, group. or service"); | |
538 | &disable; | |
539 | } | |
540 | elsif ($command =~ "pids"){ # View pid button. | |
541 | &setup_page("List pids of server, alerts and monitors."); | |
542 | &button("List pids for all mon processes:", "list pids"); | |
543 | } | |
544 | elsif ($command =~ "reset"){ # Reset mon button. | |
545 | &setup_page("Restart Mon."); | |
546 | &button("Attempting to reset mon...","reset"); | |
547 | } | |
548 | # Button "opstatus" will fall through to else. | |
549 | else { # All else. | |
550 | &setup_page("Operation Status"); | |
551 | &query_opstatus; | |
552 | } | |
553 | ||
554 | &end_page; | |
555 | ||
556 | ||
557 | # That's it! ---------------------------------------------------- |