manager.pm
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:36k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. package NetSNMP::manager;
  2. use strict ();
  3. use Apache::Constants qw(:common);
  4. use CGI qw(:standard delete_all);
  5. use SNMP ();
  6. use DBI ();
  7. use NetSNMP::manager::displaytable qw(displaytable displaygraph);
  8. # globals
  9. $NetSNMP::manager::hostname = 'localhost';          # Host that serves the mSQL Database
  10. $NetSNMP::manager::dbname = 'snmp';                 # mySQL Database name
  11. $NetSNMP::manager::user = 'root';
  12. # $NetSNMP::manager::pass = "password";
  13. $NetSNMP::manager::imagebase = "/home/hardaker/src/snmp/manager"; # <=== CHANGE ME ====
  14. $NetSNMP::manager::redimage = "/graphics/red.gif";
  15. $NetSNMP::manager::greenimage = "/graphics/green.gif";
  16. #$NetSNMP::manager::verbose = 1;
  17. $NetSNMP::manager::tableparms  = "border=1 bgcolor="#c0c0e0"";
  18. $NetSNMP::manager::headerparms = "border=1 bgcolor="#b0e0b0"";
  19. # init the snmp library
  20. $SNMP::save_descriptions=1;
  21. #SNMP::init_mib();
  22. %NetSNMP::manager::myorder = qw(id 0 oidindex 1 host 2 updated 3);
  23. sub handler {
  24.     my $r = shift;
  25.     Apache->request($r);
  26.     # get info from handler
  27.     my $hostname = $r->dir_config('hostname') || $NetSNMP::manager::hostname;
  28.     my $dbname = $r->dir_config('dbname') || $NetSNMP::manager::dbname;
  29.     my $sqluser = $r->dir_config('user') || $NetSNMP::manager::user;
  30.     my $pass = $r->dir_config('pass') || $NetSNMP::manager::pass;
  31.     my $verbose = $r->dir_config('verbose') || $NetSNMP::manager::verbose;
  32. #===========================================================================
  33. #  Global defines
  34. #===========================================================================
  35. my ($dbh, $query, $remuser);
  36. $remuser = $ENV{'REMOTE_USER'};
  37. $remuser = "guest" if (!defined($remuser) || $remuser eq "");
  38. #===========================================================================
  39. # Connect to the mSQL database with the appropriate driver
  40. #===========================================================================
  41. ($dbh = DBI->connect("DBI:mysql:database=$dbname;host=$hostname", $sqluser, $pass))
  42.     or die "tConnect not ok: $DBI::errstrn";
  43. #===========================================================================
  44. # stats Images, for inclusion on another page. (ie, slashdot user box)
  45. #===========================================================================
  46. if (my $group = param('groupstat')) {
  47.     $r->content_type("image/gif");
  48.     $r->send_http_header();
  49.     my $cur = getcursor($dbh, "select host from usergroups as ug, hostgroups as hg where ug.groupname = '$group' and hg.groupname = '$group' and user = '$remuser'");
  50.     while (my $row = $cur->fetchrow_hashref ) {
  51. if (checkhost($dbh, $group, $row->{'host'})) {
  52.     open(I, "$NetSNMP::manager::imagebase$NetSNMP::manager::redimage");
  53.     while(read(I, $_, 4096)) { print; }
  54.     close(I);
  55. }
  56.     }
  57.     open(I, "$NetSNMP::manager::imagebase$NetSNMP::manager::greenimage");
  58.     while(read(I, $_, 4096)) { print; }
  59.     close(I);
  60.     return OK();
  61. }
  62. sub date_format {
  63.     my $time = shift;
  64.     my @out = localtime($time);
  65.     my $ret = $out[4] . "-" . $out[3] . "-" . $out[5] . " " . $out[2] . " " . $out[1];
  66. #    print STDERR "$time: $retn";
  67.     return $ret;
  68. }
  69. #
  70. # Graphing of historical data
  71. #
  72. if ((param('displaygraph') || param('dograph')) && param('table')) {
  73.     my $host = param('host');
  74.     my $group = param('group');
  75.     if (!isuser($dbh, $remuser, $group)) {
  76. $r->content_type("image/png");
  77. $r->send_http_header();
  78. print "Unauthorized access to that group ($group)n";
  79. return Exit($dbh, $group);
  80.     }    
  81.     my $table = param('table');
  82.     my @columns;
  83.     if (!param('dograph')) {
  84. $r->content_type("text/html");
  85. $r->send_http_header();
  86. print "<body bgcolor="#ffffff">n";
  87. print "<form>n";
  88. print "<table border=1><tr><td>n";
  89. print "<table>n";
  90. print "<tr align=top><th></th><th>Select indexes<br>to graph</th></tr>n";
  91. my $handle = getcursor($dbh, "SELECT sql_small_result distinct(oidindex) FROM $table where host = '$host'");
  92. my @cols;
  93. while (  $row = $handle->fetchrow_hashref ) {
  94.     print "<tr><td>$row->{oidindex}</td><td><input type=checkbox value=1 name=" . 'graph_' . displaytable::to_unique_key($row->{'oidindex'}) . "></td></tr>n";
  95. }
  96. print "</table>n";
  97. print "</td><td>n";
  98. print "<table>n";
  99. print "<tr align=top><th></th><th>Select Columns<br>to graph</th></tr>n";
  100. my $handle = getcursor($dbh, "SELECT * FROM $table limit 1");
  101. my $row = $handle->fetchrow_hashref;
  102. map { print "<tr><td>$_</td><td><input type=checkbox value=1 name=column_" . displaytable::to_unique_key($_) . "></td></tr>n"; } keys(%$row);
  103. print "</table>n";
  104. print "</td></tr></table>n";
  105. print "<br>Graph as a Rate: <input type=checkbox value=1 name=graph_as_rate><br>n";
  106. print "<br>Maximum Y Value: <input type=text value=inf name=max_y><br>n";
  107. print "<br>Minimum Y Value: <input type=text value=-inf name=min_y><br>n";
  108. print "<input type=hidden name=table value="$table">n";
  109. print "<input type=hidden name=host value="$host">n";
  110. print "<input type=hidden name=dograph value=1>n";
  111. print "<input type=hidden name=group value="$group">n";
  112. print "<input type=submit name="Make Graph">n";
  113. print "</form>n";
  114. my $handle = getcursor($dbh, "SELECT distinct(oidindex) FROM $table where host = '$host' order by oidindex");
  115. return Exit($dbh, $group);
  116.     }
  117.     if (param('graph_all_data')) {
  118. $clause = "host = '$host'";
  119.     } else {
  120. my $handle = getcursor($dbh, "SELECT distinct(oidindex) FROM $table where host = '$host'");
  121. $clause = "where (";
  122. while (  $row = $handle->fetchrow_hashref ) {
  123. #     print STDERR "graph test: " . $row->{'oidindex'} . "=" . "graph_" . displaytable::to_unique_key($row->{'oidindex'}) . "=" . param("graph_" . displaytable::to_unique_key($row->{'oidindex'})) . "n";
  124.     if (param("graph_" . displaytable::to_unique_key($row->{'oidindex'}))) {
  125. $clause .= " or oidindex = " . $row->{'oidindex'} . "";
  126.     }
  127. }
  128. my $handle = getcursor($dbh, "SELECT * FROM $table limit 1");
  129. my $row = $handle->fetchrow_hashref;
  130. map { push @columns, $_ if (param('column_' . displaytable::to_unique_key($_))) } keys(%$row);
  131. $clause .= ")";
  132. $clause =~ s/( or /(/;
  133. if ($clause =~ /()/ || $#columns == -1) {
  134.     $r->content_type("text/html");
  135.     $r->send_http_header();
  136.     print "<body bgcolor="#ffffff">n";
  137.     print "<h1>No Data to Graph</h1>n";
  138.     print STDERR "No data to graph: $clause, $#columnsn";
  139.     return Exit($dbh, "$group");
  140. }
  141. $clause .= " and host = '$host'";
  142.     }
  143. #    print STDERR "graphing clause: $clausen";
  144.     # all is ok, display the graph
  145.     $r->content_type("image/png");
  146.     $r->send_http_header();
  147.     print STDERR "graphing clause: $clause, columns: ", join(", ",@columns), "n";
  148.     my @args;
  149.     push (@args, '-rate', '60') if (param('graph_as_rate'));
  150.     push (@args, '-max', param('max_y')) if (param('max_y') && param('max_y') =~ /^[-.d]+$/);
  151.     push (@args, '-min', param('min_y')) if (param('min_y') && param('min_y') =~ /^[-.d]+$/);
  152.     my $ret = 
  153.     displaygraph($dbh, $table,
  154. #  '-xcol', "date_format(updated,'%m-%d-%y %h:%i')",
  155.  '-xcol', "unix_timestamp(updated)",
  156.  '-pngparms', [
  157.      'x_labels_vertical', '1',
  158.      'x_tick_number', 6,
  159.      'x_number_format', &date_format,
  160.      'y_label', 'Count/Min',
  161.      'title', $table,
  162. #      'y_min_value', 0,
  163.  ],
  164.  '-clauses', "$clause order by updated",
  165.  @args,
  166.  '-columns', @columns,
  167.  '-indexes', ['oidindex']);
  168.     print STDERR "$ret rows graphedn";
  169.     return OK();
  170. }
  171. #===========================================================================
  172. # Start HTML.
  173. #===========================================================================
  174. $r->content_type("text/html");
  175. $r->send_http_header();
  176. print "<body bgcolor="#ffffff">n";
  177. print "<h1>UCD-SNMP Management Console</h1>n";
  178. print "<hr>n";
  179. #===========================================================================
  180. # Display mib related data information
  181. #===========================================================================
  182. if (param('displayinfo')) {
  183.     makemibtable(param('displayinfo'));
  184.     return Exit($dbh, "");
  185. }
  186. #===========================================================================
  187. # Display a generic sql table of any kind (debugging).
  188. #===========================================================================
  189. # if (my $disptable = param('displaytable')) {
  190. #     if (param('editable') == 1) {
  191. #  print "<form submit=dont>n";
  192. #  displaytable($disptable, -editable, 1);
  193. #  print "</form>n";
  194. #     } else {
  195. #  displaytable($disptable);
  196. #     }
  197. #     return Exit($dbh,  "");
  198. # }
  199. #===========================================================================
  200. # Get host and group from CGI query.
  201. #===========================================================================
  202. my $host = param('host');
  203. my $group = param('group');
  204. #===========================================================================
  205. # Editable user information
  206. #===========================================================================
  207. if (param('setuponcall')) {
  208.     print "<title>oncall schedule for user: $remuser</title>n";
  209.     print "<h2>oncall schedule for user: $remuser</h2>n";
  210.     print "<p>Please select your oncall schedule and mailing addresses for your groups below:";
  211.     if (!isexpert($remuser)) {
  212. print "<ul>n";
  213.         print "<li>Values for the days/hours fields can be comma seperated lists of hours/days/ranges.  EG: hours: 7-18,0-4.n";
  214. print "</ul>n";
  215.     }
  216.     print "<form method=post><input type=hidden name=setuponcall value=1>n";
  217.     displaytable($dbh, 'oncall',
  218.     '-clauses',"where user = '$remuser' order by groupname",
  219.     '-select','id, user, groupname, email, pager, days, hours',
  220.     '-selectorder', 1,
  221.     '-notitle', 1,
  222.     '-editable', 1,
  223.     '-indexes', ['id','user','groupname'],
  224.     '-CGI', $CGI::Q
  225.     );
  226.     print "<input type=submit value="submit changes">n";
  227.     print "</form>n";
  228.     return Exit($dbh, $group);
  229. }
  230. #===========================================================================
  231. # show the list of groups a user belongs to.
  232. #===========================================================================
  233. if (!defined($group)) {
  234.     my @groups = getgroupsforuser($dbh, $remuser);
  235.     print "<title>Net-SNMP Group List</title>n";
  236.     print "<h2>Host groupings you may access:</h2>n";
  237.     if (!isexpert($remuser)) {
  238. print "<ul>n";
  239. print "<li>Click on a group to operate or view the hosts in that group.n";
  240. print "<li>Click on a red status light below to list the problems found.n";
  241. print "</ul>n";
  242.     }
  243.     if ($#groups > 0) {
  244. displaytable($dbh, 'usergroups', 
  245.      '-clauses', "where (user = '$remuser')",
  246.      '-select', 'distinct groupname',
  247.      '-notitle', 1,
  248.      '-printonly', ['groupname'],
  249.      '-datalink', sub { my $q = self_url();
  250. my $key = shift;
  251. my $h = shift;
  252. return if ($key ne "groupname");
  253. return addtoken($q,"group=$h");
  254.     },
  255.      '-beginhook', 
  256.      sub { 
  257.  my $q = self_url();
  258.  my($dbh, $junk, $data) = @_;
  259.  if (!defined($data)) {
  260.      print "<th>Status</th>";
  261.      return;
  262.  }
  263.  my ($cur, $row);
  264.  $cur = getcursor($dbh, "select host from hostgroups where groupname = '$data->{groupname}'");
  265.  while (  $row = $cur->fetchrow_hashref ) {
  266.      if (checkhost($dbh, $data->{'groupname'}, 
  267.    $row->{'host'})) {
  268.  print "<td><a href="" . addtoken($q,"group=$data->{groupname}&summarizegroup=1") . ""><img border=0 src=$NetSNMP::manager::redimage></a></td>n";
  269.  return;
  270.      }
  271.  }
  272.  print "<td><img src=$NetSNMP::manager::greenimage></td>n";
  273.      }
  274.      );
  275. $dbh->disconnect();
  276. return Exit($dbh,  $group);
  277.     } else {
  278. if ($#groups == -1) {
  279.     print "You are not configured to use the Net-SNMP-manager, please contact your system administrator.";
  280.     return Exit($dbh,  $group);
  281. }
  282. $group = $groups[0];
  283.     }
  284. }
  285. #===========================================================================
  286. # reject un-authorized people accessing a certain group
  287. #===========================================================================
  288. if (!isuser($dbh, $remuser, $group)) {
  289.     print "Unauthorized access to that group ($group)n";
  290.     return Exit($dbh, $group);
  291. }    
  292. #===========================================================================
  293. # add a new host to a group
  294. #===========================================================================
  295. if (defined(my $newhost = param('newhost'))) {
  296.     if (isadmin($dbh, $remuser, $group)) {
  297. if ($dbh->do("select * from hostgroups where host = '$newhost' and groupname = '$group'") eq "0E0") {
  298.     $dbh->do("insert into hostgroups(host,groupname) values('$newhost','$group')") ;
  299. } else {
  300.     print "<b>ERROR: host $newhost already in $group</b>n";
  301. }
  302. CGI::delete('newhost');
  303.     }
  304. }
  305. #===========================================================================
  306. # display setup configuration for a group
  307. #===========================================================================
  308. if (defined(param('setupgroup'))) {
  309.     if (isadmin($dbh, $remuser, $group)) {
  310. setupgroup($dbh, $group);
  311.     } else {
  312. print "<h2>You're not able to perform setup operations for group $groupn";
  313.     }
  314.     return Exit($dbh, $group);
  315. }
  316. #===========================================================================
  317. # save configuration information submitted about a group
  318. #===========================================================================
  319. if (defined(param('setupgroupsubmit')) && 
  320.     isadmin($dbh, $remuser, $group)) {
  321.     setupgroupsubmit($dbh, $group);
  322.     delete_all();
  323.     param(-name => 'group', -value => $group);
  324.     print "<a href="" . self_url() . "">Entries submitted</a>";
  325.     return Exit($dbh, $group);
  326. }
  327. #===========================================================================
  328. # user preferences
  329. #===========================================================================
  330. if (defined(param('userprefs'))) {
  331.     setupuserpreferences($dbh, $remuser, $group);
  332.     return Exit($dbh, $group);
  333. }
  334. #===========================================================================
  335. # save submitted user preferences
  336. #===========================================================================
  337. if (defined(param('setupuserprefssubmit')) && 
  338.     isadmin($dbh, $remuser, $group)) {
  339.     setupusersubmit($dbh, $remuser, $group);
  340.     delete_all();
  341.     param(-name => 'group', -value => $group);
  342.     print "<a href="" . self_url() . "">Entries submitted</a>";
  343.     return Exit($dbh, $group);
  344. }
  345. #===========================================================================
  346. # summarize problems in a group
  347. #===========================================================================
  348. if (defined(param('summarizegroup'))) {
  349.     print "<title>group problem summary: $group</title>n";
  350.     print "<h2>The following is a list of problems in the group "$group":</h2>n";
  351.     summarizeerrors($dbh, "where groupname = '$group'");
  352.     return Exit($dbh, $group);
  353. }
  354. #===========================================================================
  355. # summarize problems on a host
  356. #===========================================================================
  357. if (defined($host) && defined(param('summarizehost'))) {
  358.     print "<title>host summary: $host</title>n";
  359.     print "<h2>The following is a list of problems for the host "$host":</h2>n";
  360.     summarizeerrors($dbh, "where groupname = '$group' and host = '$host'");
  361.     return Exit($dbh, $group);
  362. }
  363. #===========================================================================
  364. # display a list of hosts in a group
  365. #===========================================================================
  366. if (!defined($host)) {
  367.     print "<title>Net-SNMP Host $host</title>n";
  368.     print "<h2>Hosts in the group "$group":</h2>n";
  369.     if (!isexpert($remuser)) {
  370. print "<ul>n";
  371. if (isadmin($dbh, $remuser, $group)) {
  372.     my $q = self_url();
  373.     $q =~ s/?.*//;
  374.             print "<li>Make sure you <a href="" . addtoken($q,"group=$group&setupgroup=1") . "">set up the host</a> for the SNMP tables you want to monitor.n";
  375.         }
  376. print "<li>Click on a hostname to operate on or view the information tables associated with that group.n";
  377. print "<li>Click on a red status light below to list the problems found in with a particular host.n";
  378. print "</ul>n";
  379.     }
  380.     displaytable($dbh, 'hostgroups', 
  381.  '-notitle',0,
  382.  '-clauses', "where (groupname = '$group')",
  383.  '-select', 'distinct host, sysObjectId, sysDescr, sysUpTime, versionTag',
  384.  '-datalink', sub { my $q = self_url();
  385.     my $key = shift;
  386.     my $h = shift;
  387.     return if ($key ne "host");
  388.     return addtoken($q,"host=$h");
  389. },
  390.  '-beginhook', 
  391.  sub { 
  392.      my $q = self_url();
  393.      my($dbh, $junk, $data) = @_;
  394.      if (!defined($data)) {
  395.  print "<th>Status</th>";
  396.  return;
  397.      }
  398.      if (checkhost($dbh, $group, $data->{'host'})) {
  399.  print "<td><a href="" . addtoken($q,"group=$group&summarizehost=1&host=$data->{host}") . ""><img border=0 src=$NetSNMP::manager::redimage></a></td>n";
  400.      } else {
  401.  print "<td><img src=$NetSNMP::manager::greenimage></td>n";
  402.      }
  403.  }
  404.  );
  405.     if (isadmin($dbh, $remuser, $group)) {
  406. addhostentryform($group);
  407. my $q = self_url();
  408. $q =~ s/?.*//;
  409. print "<a href="" . addtoken($q,"group=$group&setupgroup=1") . "">setup group $group</a>n";
  410.     }
  411.     return Exit($dbh, $group);
  412. }
  413. #===========================================================================
  414. # setup the host's history records
  415. #===========================================================================
  416. if (param('setuphost')) {
  417.     print "<title>Net-SNMP history setup for host: $host</title>n";
  418.     print "<h2>Net-SNMP history setup for the host: "$host"</h2>n";
  419.     print "<p>Enter the number of days to keep the data for a given table for the host "$host":n";
  420.     if (!isexpert($remuser)) {
  421. print "<ul>n";
  422.         print "<li>Numbers must be greater than or equal to 1 to enable history logging.n";
  423. print "</ul>n";
  424.     }
  425.     print "<form method=post><input type=hidden name=setuphost value=1><input type=hidden name=host value="$host"><input type=hidden name=group value="$group">n";
  426.     displaytable($dbh, 'hosttables',
  427.     '-clauses',"where host = '$host' and groupname = '$group'",
  428.     '-select','groupname, host, tablename, keephistory',
  429.     '-selectorder', 1,
  430.     '-notitle', 1,
  431.     '-editable', 1,
  432.     '-indexes', ['groupname','host','tablename'],
  433.     '-CGI', $CGI::Q
  434.     );
  435.     print "<input type=submit value="submit changes">n";
  436.     print "</form>n";
  437.     return Exit($dbh, $group);
  438. }
  439. #===========================================================================
  440. # display a huge table of history about something
  441. #===========================================================================
  442. if (param('displayhistory')) {
  443.     if (!isuser($dbh, $remuser, $group)) {
  444.         print "Unauthorized access to that group ($group)n";
  445.         return Exit($dbh, $group);
  446.     }
  447.     displaytable($dbh, param('table'), 
  448.     '-clauses', "where (host = '$host')",
  449.     '-dolink', &linktodisplayinfo,
  450.     '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'"
  451.     );
  452.     return Exit($dbh, $group);
  453. }
  454. #===========================================================================
  455. # display inforamation about a host
  456. #  optionally add new collection tables
  457. #===========================================================================
  458. showhost($dbh, $host, $group, $remuser);
  459. if (isadmin($dbh, $remuser, $group)) {
  460.     if (param('newtables')) {
  461.      my $x = param('newtables');
  462.      $x =~ s/,/ /g;
  463.      if (/[^ws]/) {
  464.          print "<br>Illegal table names in addition list: $x<br>n" 
  465.      } else {
  466.     my @x = split(/s+/,$x);
  467.     foreach my $i (@x) {
  468. $dbh->do("insert into hosttables(host, groupname, tablename, keephistory) values('$host','$group','$i','0')");
  469.     }
  470.          print "<br>adding: ",join(", ",@x),"<br>n";
  471.      }
  472.     } else {
  473.         print "<br>Add new MIB Tables or Groups that you want to collect for this host: <form><input type=hidden name=host value="$host"><input type=hidden name=group value="$group"><input name="newtables" type=text><br><input type=submit value="add tables"></form>n";
  474.     }
  475.     my $q = self_url();
  476.     $q =~ s/?.*//;
  477.     print "<a href="" . addtoken($q, "setuphost=1&host=$host&group=$group") . "">setup host $host</a>n";
  478. }
  479. return Exit($dbh, $group);
  480. #===========================================================================
  481. # END of handler
  482. #===========================================================================
  483. }
  484. # add a token to a url string.  Use either a ? or an & depending on
  485. # existence of ?.
  486. sub addtoken {
  487.     my $url = shift;
  488.     my $token = shift;
  489.     return "$url&$token" if ($url =~ /?/);
  490.     return "$url?$token";
  491. }
  492. #
  493. # summarizeerrors(DB-HANDLE, CLAUSE):
  494. #   summarize the list of errors in a given CLAUSE
  495. #
  496. sub summarizeerrors {
  497.     my $dbh = shift;
  498.     my $clause = shift;
  499.     $clause = "where" if ($clause eq "");
  500.     my $clause2 = $clause;
  501.     $clause2 =~ s/ host / hosterrors.host /;
  502.     # Major errors
  503.     displaytable($dbh, 'hosterrors, hostgroups',  # , hostgroups
  504.  '-select', "hosterrors.host as host, errormsg",
  505.  '-notitle', 1,
  506.  '-title', "Fatal Errors",
  507.  '-clauses', "$clause2 and hosterrors.host = hostgroups.host",
  508.  '-beginhook', sub {
  509.      if ($#_ < 2) {
  510.  #doing header;
  511.  print "<td></td>";
  512.      } else {
  513.  print "<td><img src="$NetSNMP::manager::redimage"></td>n";
  514.      }});
  515.     my $tabletop = "<br><table $NetSNMP::manager::tableparms><tr $NetSNMP::manager::headerparms><th><b>Host</b></th><th><b>Table</b></th><th><b>Description</b></th></tr>n";
  516.     my $donetop = 0;
  517.     my $cursor = 
  518. getcursor($dbh, "SELECT * FROM hosttables $clause");
  519.     while (my $row = $cursor->fetchrow_hashref ) {
  520. my $exprs = getcursor($dbh, "SELECT * FROM errorexpressions where (tablename = '$row->{tablename}')");
  521. while (my  $expr = $exprs->fetchrow_hashref ) {
  522.     my $errors = getcursor($dbh, "select * from $row->{tablename} where $expr->{expression} and host = '$row->{host}'");
  523.     while (my  $error = $errors->fetchrow_hashref ) {
  524. print $tabletop if ($donetop++ == 0);
  525. print "<tr><td>$row->{host}</td><td>$row->{tablename}</td><td>$expr->{returnfield}: $error->{$expr->{returnfield}}</td></tr>";
  526.     }
  527. }
  528.     }
  529.     print "</table>";
  530. }
  531. #
  532. # getcursor(CMD):
  533. #    genericlly get a cursor for a given sql command, displaying and
  534. #    printing errors where necessary.
  535. #
  536. sub getcursor {
  537.     my $dbh = shift;
  538.     my $cmd = shift;
  539.     my $cursor;
  540.     ( $cursor = $dbh->prepare( $cmd ))
  541. or print "nnot ok: $DBI::errstrn";
  542.     ( $cursor->execute )
  543. or print( "tnot ok: $DBI::errstrn" );
  544.     return $cursor;
  545. }
  546. #
  547. # mykeysort($a, $b)
  548. #    sorts $a and $b against the order in the mib or against the hard
  549. #    coded special list.
  550. #
  551. sub mykeysort {
  552.     my $a = $displaytable::a;
  553.     my $b = $displaytable::b;
  554.     my $mb = $SNMP::MIB{SNMP::translateObj($b)};
  555.     my $ma = $SNMP::MIB{SNMP::translateObj($a)};
  556.     return $NetSNMP::manager::myorder{$a} <=> $NetSNMP::manager::myorder{$b} if ((defined($NetSNMP::manager::myorder{$a}) || !defined($ma->{'subID'})) && (defined($NetSNMP::manager::myorder{$b}) || !defined($mb->{'subID'})));
  557.     return 1 if (defined($NetSNMP::manager::myorder{$b}) || !defined($mb->{'subID'}));
  558.     return -1 if (defined($NetSNMP::manager::myorder{$a}) || !defined($ma->{'subID'}));
  559.     $ma->{'subID'} <=> $mb->{'subID'};
  560. }
  561. #
  562. # checkhost(GROUP, HOST):
  563. #    if anything in a host is an error, as defined by the
  564. #    errorexpressions table, return 1, else 0
  565. #
  566. sub checkhost {
  567.     my $dbh = shift;
  568.     my $group = shift;
  569.     my $host = shift;
  570.     my ($tblh);
  571.     return 2 if ($dbh->do("select * from hosterrors where host = '$host'") ne "0E0");
  572.     # get a list of tables we want to display
  573.     $tblh = getcursor($dbh, "SELECT * FROM hosttables where (host = '$host' and groupname = '$group')");
  574.     # table data
  575.     my($exprs, $tablelist);
  576.     while ( $tablelist = $tblh->fetchrow_hashref ) {
  577. $exprs = getcursor($dbh, "SELECT * FROM errorexpressions where (tablename = '$tablelist->{tablename}')");
  578. while(my $expr = $exprs->fetchrow_hashref) {
  579.     if ($dbh->do("select * from $tablelist->{tablename} where $expr->{expression} and host = '$host'") ne "0E0") {
  580. return 1;
  581.     }
  582. }
  583.     }
  584.     return 0;
  585. }
  586. #
  587. #  showhost(HOST):
  588. #
  589. #    display all the tables monitored for a given host (in a group).
  590. #
  591. sub showhost {
  592.     my $dbh = shift;
  593.     my $host = shift;
  594.     my $group = shift;
  595.     my $remuser = shift;
  596.     my $q = self_url();
  597.     $q =~ s/?.*//;
  598.     # host header
  599.     print "<title>Net-SNMP manager report for host: $host</title>n";
  600.     print "<h2>Monitored information for the host $host</h2>n";
  601.     if (!isexpert($remuser)) {
  602. print "<ul>n";
  603. print "<li>Click on a column name for information about the data in that column.n";
  604. print "<li>Click on a column name or table name for information about the data in the table.n";
  605. print "<li>If you are <a href="" . addtoken($q, "setuphost=1&host=$host&group=$group") . "">collecting past history</a> for a data set, links will appear below the table that allow you to view and/or graph the historic data.n";
  606. print "</ul>n";
  607.     }
  608.     # does the host have a serious error?
  609.     my $errlist = getcursor($dbh, "SELECT * FROM hosterrors where (host = '$host')");
  610.     if ( $dbh->do("SELECT * FROM hosterrors where (host = '$host')") ne "0E0") {
  611. displaytable($dbh, 'hosterrors', 
  612.      '-clauses', "where (host = '$host')",
  613.      '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'",
  614.      '-beginhook', sub {
  615.  if ($#_ < 2) {
  616.      #doing header;
  617.      print "<td></td>";
  618.  } else {
  619.      print "<td><img src="$NetSNMP::manager::redimage"></td>n";
  620.  }});
  621.     }
  622.     # get a list of tables we want to display
  623.     my $tblh = getcursor($dbh, "SELECT * FROM hosttables where (host = '$host' and groupname = '$group')");
  624.     # table data
  625.     my($tablelist);
  626.     while (  $tablelist = $tblh->fetchrow_hashref ) {
  627. displaytable($dbh, $tablelist->{'tablename'},
  628.      '-clauses', "where (host = '$host') order by oidindex",
  629.      '-dontdisplaycol', "select * from userprefs where user = '$remuser' and groupname = '$group' and tablename = ? and columnname = ? and displayit = 'N'",
  630.      '-sort', &mykeysort,
  631.      '-dolink', &linktodisplayinfo,
  632.      '-beginhook', &printredgreen);
  633. if ($tablelist->{'keephistory'}) {
  634.     my $q = self_url();
  635.     $q =~ s/?.*//;
  636.     print "history: ";
  637.     print "<a href="" . addtoken($q, "displayhistory=1&host=$host&group=$group&table=$tablelist->{'tablename'}hist") . "">[table]</a>n";
  638.     print "<a href="" . addtoken($q, "displaygraph=1&host=$host&group=$group&table=$tablelist->{'tablename'}hist") . "">[graph]</a>n";
  639.     print "<br>n";
  640. }
  641.     }
  642. }
  643. #
  644. #  linktodisplayinfo(STRING):
  645. #
  646. #    returns a url to the appropriate displayinfo link if STRING is a
  647. #    mib node.
  648. #
  649. sub linktodisplayinfo {
  650.     return if (exists($NetSNMP::manager::myorder{shift}));
  651.     return self_url() . "&displayinfo=" . shift;
  652. }
  653. # printredgreen(TABLENAME, DATA):
  654. #
  655. #   display a red or a green dot in a table dependent on the table's
  656. #   values and associated expression
  657. #
  658. #   DATA is NULL when in a header row (displaying header names).
  659. #
  660. sub printredgreen {
  661.     my $dbh = shift;
  662.     my $tablename = shift;
  663.     my $data = shift;
  664.     my ($exprs, $expr, $img);
  665.     if (!defined($data)) {
  666. #doing header;
  667. print "<td></td>";
  668. return;
  669.     }
  670.     my $cmd = "SELECT * FROM errorexpressions where (tablename = '$tablename')";
  671.     print " $cmdn" if ($NetSNMP::manager::verbose);
  672.     ( $exprs = $dbh->prepare( $cmd ) )
  673. or die "nnot ok: $DBI::errstrn";
  674.     ( $exprs->execute )
  675. or print( "tnot ok: $DBI::errstrn" );
  676.     $img = $NetSNMP::manager::greenimage;
  677.     while($expr = $exprs->fetchrow_hashref) {
  678. if ($dbh->do("select oidindex from $tablename where host = '$data->{host}' and oidindex = '$data->{oidindex}' and $expr->{expression}") ne "0E0") {
  679.     $img = $NetSNMP::manager::redimage;
  680. }
  681.     }
  682.     print "<td><img src=$img></td>";
  683. }
  684. #
  685. # display information about a given mib node as a table.
  686. #
  687. sub makemibtable {
  688.     my $dispinfo = shift;
  689.     # display information about a data type in a table
  690.     my $mib = $SNMP::MIB{SNMP::translateObj($dispinfo)};
  691.     print "<table $NetSNMP::manager::tableparms><tr><td>n";
  692.     foreach my $i (qw(label type access status units hint moduleID description enums)) {
  693. #    foreach my $i (keys(%$mib)) {
  694. next if (!defined($$mib{$i}) || $$mib{$i} eq "");
  695. next if (ref($$mib{$i}) eq "HASH" && $#{keys(%{$$mib{$i}})} == -1);
  696. print "<tr><td>$i</td><td>";
  697. if (ref($$mib{$i}) eq "HASH") {
  698.     print "<table $NetSNMP::manager::tableparms><tr><td>n";
  699.     foreach my $j (sort { $$mib{$i}{$a} <=> $$mib{$i}{$b} } keys(%{$$mib{$i}})) {
  700.   print "<tr><td>$$mib{$i}{$j}</td><td>$j</td></tr>";
  701.     }
  702.     print "</table>n";
  703. } else {
  704.     print "$$mib{$i}";
  705. }
  706. print "</td></tr>n";
  707.     }
  708.     print "</table>n";
  709. }
  710. # given a user, get all the groups he belongs to.
  711. sub getgroupsforuser {
  712.     my (@ret, $cursor, $row);
  713.     my ($dbh, $remuser) = @_;
  714.     ( $cursor = $dbh->prepare( "SELECT * FROM usergroups where (user = '$remuser')"))
  715. or die "nnot ok: $DBI::errstrn";
  716.     ( $cursor->execute )
  717. or print( "tnot ok: $DBI::errstrn" );
  718.     while (  $row = $cursor->fetchrow_hashref ) {
  719. push(@ret, $row->{'groupname'});
  720.     }
  721.     @ret;
  722. }
  723. # given a host, get all the groups it belongs to.
  724. sub gethostsforgroup {
  725.     my (@ret, $cursor, $row);
  726.     my ($dbh, $group) = @_;
  727.     ( $cursor = $dbh->prepare( "SELECT * FROM hostgroups where (groupname = '$group')"))
  728. or die "nnot ok: $DBI::errstrn";
  729.     ( $cursor->execute )
  730. or print( "tnot ok: $DBI::errstrn" );
  731.     while (  $row = $cursor->fetchrow_hashref ) {
  732. push(@ret, $row->{'host'});
  733.     }
  734.     @ret;
  735. }
  736. # display the host add entry box
  737. sub addhostentryform {
  738.     my $group = shift;
  739.     print "<form method="get" action="" . self_url() . "">n";
  740.     print "Add a new host to the group "$group": <input type="text" name="newhost"><br>";
  741.     print "<input type="hidden" name="group" value="$group">";
  742.     print "<input type=submit value="Add Hosts">n";
  743.     print "</form>";
  744. }
  745. #is an expert user?
  746. sub isexpert {
  747.     return 0;
  748. }
  749. #is remuser a admin?
  750. sub isadmin {
  751.     my ($dbh, $remuser, $group) = @_;
  752.     return 0 if (!defined($remuser) || !defined($group));
  753.     return 1 if ($dbh->do("select * from usergroups where user = '$remuser' and groupname = '$group' and isadmin = 'Y'") ne "0E0");
  754.     return 0;
  755. }
  756. #is user a member of this group?
  757. sub isuser {
  758.     my ($dbh, $remuser, $group) = @_;
  759.     return 0 if (!defined($remuser) || !defined($group));
  760.     return 1 if ($dbh->do("select * from usergroups where user = '$remuser' and groupname = '$group'") ne "0E0");
  761.     return 0;
  762. }
  763. # displayconfigarray(HOSTS, NAMES, CONFIG):
  764. #
  765. #   displays an array of generic check buttons to turn on/off certain
  766. #   variables.
  767. sub displayconfigarray {
  768.     my $dbh = shift;
  769.     my $hosts = shift;
  770.     my $names = shift;
  771.     my %config = @_;
  772.     my $cmd;
  773.     if ($config{'-check'}) {
  774. ( $cmd = $dbh->prepare( $config{'-check'} ) )
  775.     or die "nnot ok: $DBI::errstrn";
  776.     }
  777.     print "<table $NetSNMP::manager::tableparms>n";
  778.     print "<tr><td></td>";
  779.     my ($i, $j);
  780.     foreach $j (@$names) {
  781. my $nj = $j;
  782. $nj = $j->[0] if ($config{'-arrayrefs'} || $config{'-arrayref2'});
  783. print "<td>$nj</td>";
  784.     }
  785.     foreach my $i (@$hosts) {
  786. my $ni = $i;
  787. $ni = $i->[0] if ($config{'-arrayrefs'} || $config{'-arrayref1'});
  788. print "<tr><td>$ni</td>";
  789. foreach $j (@$names) {
  790.     my $nj = $j;
  791.     $nj = $j->[0] if ($config{'-arrayrefs'} || $config{'-arrayref2'});
  792.     my $checked = "checked" if (defined($cmd) && $cmd->execute($ni,$nj) ne "0E0");
  793.     print "<td><input type=checkbox $checked value=y name=" . $config{prefix} . $ni . $nj . "></td>n";
  794. }
  795. print "</tr>n";
  796.     }
  797.     print "</tr>";
  798.     print "</table>";
  799. }
  800. sub adddefaulttables {
  801.     my ($dbh, $names) = @_;
  802.     my $row;
  803.     # add in known expression tables.
  804.     my $handle = getcursor($dbh, "SELECT * FROM errorexpressions");
  805.     expr: 
  806.     while($row = $handle->fetchrow_hashref) {
  807. foreach $i (@$names) {
  808.     if ($i->[0] eq $row->{tablename}) {
  809. next expr;
  810.     }
  811. }
  812. push @$names, [$row->{tablename}];
  813.     }
  814. }
  815. #
  816. # display the setup information page for a given group.
  817. #
  818. sub setupgroup {
  819.     my $dbh = shift;
  820.     my $group = shift;
  821.     
  822.     my ($hosts, $names) = gethostandgroups($dbh, $group);
  823.     adddefaulttables($dbh, $names);
  824.     print "<form method="post" action="" . self_url() . "">n";
  825.     print "<input type=hidden text="setupgroupsubmit" value="y">";
  826.     displayconfigarray($dbh, $hosts, $names, 
  827.        -arrayrefs, 1,
  828.        -check, "select * from hosttables where (host = ? and tablename = ? and groupname = '$group')");
  829.     print "<input type=hidden name=group value="$group">n";
  830.     print "<input type=submit value=submit name="setupgroupsubmit">n";
  831.     print "</form>";
  832. }
  833. # a wrapper around fetching arrays of everything in a table.
  834. sub getarrays {
  835.     my $dbh = shift;
  836.     my $table = shift;
  837.     my %config = @_;
  838.     my $selectwhat = $config{'-select'} || "*";
  839.     my $handle;
  840.     
  841.     $handle = getcursor($dbh, "SELECT $selectwhat FROM $table $config{-clauses}");
  842.     return $handle->fetchall_arrayref;
  843. }
  844. #
  845. # get a list of all tablenames and hostnames for a given group.
  846. #
  847. sub gethostandgroups {
  848.     my $dbh = shift;
  849.     my $group = shift;
  850.     my ($tbnms);
  851.     my $names = getarrays($dbh, 'hosttables', 
  852.   "-select", 'distinct tablename',
  853.   "-clauses", "where groupname = '$group'");
  854.     my $hosts = getarrays($dbh, 'hostgroups', 
  855.   "-select", 'distinct host',
  856.   "-clauses", "where groupname = '$group'");
  857.     
  858.     return ($hosts, $names);
  859. }
  860. sub setupgroupsubmit {
  861.     my $dbh = shift;
  862.     my $group = shift;
  863.     
  864.     my ($hosts, $names) = gethostandgroups($dbh, $group);
  865.     adddefaulttables($dbh, $names);
  866.     foreach my $i (@$hosts) {
  867. $dbh->do("delete from hosttables where host = '${$i}[0]' and groupname = '$group'");
  868.     }
  869.     my $rep = $dbh->prepare("insert into hosttables(host,tablename,groupname) values(?,?,'$group')");
  870.     foreach my $i (@$hosts) {
  871. foreach my $j (@$names) {
  872.     if (param("${$i}[0]" . "${$j}[0]")) {
  873. print "test: ","${$i}[0] : ${$j}[0]<br>n";
  874. $rep->execute("${$i}[0]", "${$j}[0]") || print "$! $DBI::errstr<br>n";
  875.             }
  876. }
  877.     }
  878.     
  879. }
  880. #
  881. # save user pref data submitted by the user
  882. #
  883. sub setupusersubmit {
  884.     my ($dbh, $remuser, $group) = @_;
  885.     my $tables = getarrays($dbh, 'hosttables', 
  886.    "-select", 'distinct tablename',
  887.    "-clauses", "where groupname = '$group'");
  888.     
  889.     $dbh->do("delete from userprefs where user = '$remuser' and groupname = '$group'");
  890.     my $rep = $dbh->prepare("insert into userprefs(user, groupname, tablename, columnname, displayit) values('$remuser', '$group', ?, ?, 'N')");
  891.     my ($i, $j);
  892.     foreach my $i (@$tables) {
  893. my $sth = $dbh->prepare("select * from ${$i}[0] where 1 = 0");
  894. $sth->execute();
  895. foreach $j (@{$sth->{NAME}}) {
  896.     if (param("${$i}[0]" . "$j")) {
  897. $rep->execute("${$i}[0]", "$j");
  898.     }
  899. }
  900.     }
  901. }
  902. sub Exit {
  903.     my ($dbh, $group) = @_;
  904.     my $tq = self_url();
  905.     $tq =~ s/?.*//;
  906.     print "<hr>n";
  907.     print "<a href="$tq">[TOP]</a>n";
  908.     print "<a href="$tq?userprefs=1&group=$group">[display options]</a>n";
  909.     print "<a href="$tq?setuponcall=1">[setup oncall schedule]</a>n";
  910.     if (defined($group)) {
  911. print "<a href="$tq?group=$group">[group: $group]</a>n";
  912. print "<a href="$tq?group=$group&summarizegroup=1">[summarize errors]</a>n";
  913.     }
  914.     $dbh->disconnect() if (defined($dbh));
  915.     return OK();
  916. #    exit shift;
  917. }
  918. #
  919. # setup user preferences by displaying a configuration array of
  920. # checkbuttons for each table.
  921. #
  922. sub setupuserpreferences {
  923.     my ($dbh, $remuser, $group) = @_;
  924.     my $tables = getarrays($dbh, 'hosttables', 
  925.    "-select", 'distinct tablename',
  926.    "-clauses", "where groupname = '$group'");
  927.     print "<h3>Select the columns from the tables that you want to <b>hide</b> below and click on submit:</h3>n";
  928.     print "<form method="post" action="" . self_url() . "">n";
  929.     my ($i, $j);
  930.     foreach my $i (@$tables) {
  931. my $sth = $dbh->prepare("select * from ${$i}[0] where 1 = 0");
  932. $sth->execute();
  933. displayconfigarray($dbh, [${$i}[0]], $sth->{NAME},
  934.    -check, "select * from userprefs where (tablename = ? and columnname = ? and user = '$remuser' and groupname = '$group' and displayit = 'N')");
  935.     print "<br>n";
  936.     }
  937.     print "<input type=hidden name=group value="$group">n";
  938.     print "<input type=submit value=submit name="setupuserprefssubmit">n";
  939.     print "</form>";
  940. }