=head1 NAME

B<check_insight> - spong-network module to check Compaq Insight Management
software

=head1 DESCRIPTION

This is a plugin module for the Spong L<spong-network> program.  The
B<check_insight> module checks the status of the Compaq Insight Management
software
on a host by polling via it SNMP. It reports the status of the various
components of the Insight software.

=cut

# Register the routine with the plugin registry
$PLUGINS{'insight'} = \&check_insight;

use Net::SNMP;

sub check_insight {
  my ($host) = @_;
  my ($color, $summary, $message ) = ( "green", "", "" );
  my ($community) = $HOSTS{$host}->{'snmp_community'} || 'public';

  # We use some look up tables for checking some config options.
  my (@State) = ("Not Available", "Other", "OK", "Degraded", "Failed");

  my (@MIBName) = ("", "Std", "Unknown", "Array",
                   "Netware", "SCSI", "Health","Unknown", 
                   "Store", "SM2", "Thresh", "OS", "UPS", 
                   "Unknown", "IDE", "Clusters", "Fibre", 
                   "MIB", "NIC");

  # These are the positions within the table to actually look at.
  my (@MIBs) = (1, 2, 3, 5, 6, 10, 11, 14, 18);

  my ($oid) = "1.3.6.1.4.1.232.11.2.10.1.0";	# SysArray

  # Open the connection.
  my ($session, $error) = Net::SNMP->session(Hostname  => $host,
                                             Community => $community);

  # If we can't open a connection, just return red straight away.
  if (! defined $session) {
    $color = "red";
    $summary = "Can't open connection.";
    $message = $summary;

    return ($color, $summary, $message);
  }


  $session->translate;
  my ($response) = $session->get_request($oid);

  if (!defined $response) {
    # If there's no response, something screwy is going on, give up.
    $color = 'red';
    $summary = $session->error;
    $message = $summary;
    $session->close;
  } else {
    $session->close;

    # I'm not convinced that this is the easiest way to go about this, this is
    # from some code which I've inherited and I've modified for use in here.
    # Hi George!
    %h = %$response;
    my ($d) = $h{$oid};

    my (@list) = ();
	
    # Gobble the first two char's.
    $d = substr $d,2;

    while (length($d) > 0) {
      my ($v) = substr($d,0,2);
      $v = hex($v);
      $d = substr $d,2;
      push @list, $v;
    }

    # Value in $MIBs[1] is the overall status of the machine...
    my ($cond) = $MIBs[1];
    $message .= "Status: $State[$cond]\n";

    foreach my $v (@MIBs) {
      $cond = $list[($v*4)+1];  # A little bit of magic.

      # We only bother printing the status out if it's actually available,
      # as if it's N/A or Unknown then it's probably because the machine
      # isn't available.
      $message .= "$MIBName[$v]: $State[$cond]\n" if $cond > 1;
      next if $cond < 2;

      # What follows is some trickery to try and not to override a previous
      # message at the same or lower color.
      if ($cond == 4) {
        if ($color ne 'red') {
          $color = 'red';
          $summary = "$MIBName[$v] is failed";
        }
      } elsif ($cond == 3) {
        if ($color ne 'red') {
          $color = 'yellow';
          $summary = "$MIBName[$v] is degraded" if $summary eq "";
        }
      } elsif ($cond < 2) {
        if ($color eq 'green') {
          $color = 'yellow';
          $summary = "$MIBName[$v] is unknown ($cond)" if $summary eq "";
        }
      }
    }
  }
  
  $summary = "Ok" if $summary eq "";

  return ($color, $summary, $message);
}

1;

__END__

=head2 Output Returned

=over 4

=item Status

If there is nothing degraded or failed on the machine then 'green' status
is returned.  Otherwise, 'yellow' is returned for degraded, 'red' for failed.

=item Summary Field

If there are no problems, 'Ok' is returned. Otherwise the summary field
will have a short description of what the problem or anamoly is.

=item Detail Message Field

If the machine is contactable, then the detail message will have the status
of each item which is available on that machine.  Possible values are 'Ok',
'Degraded' and 'Failed'.

=back

=head2 Configuration

=over 4

The default SNMP Community name is I<public>. To override the default name
specify a C<snmp_community> attribute in a host's entry in the I<%HOSTS)
variable in the L<spong.conf> configuration file. See the L<Examples|"EXAMPLES">
section for a detailed example.

=back

=head1 EXAMPLES

 %HOSTS = ( 'hostname.my-inc.com' => { 'services'  => 'insight',
                                       'ip_addr'  => ['192.168.13.123'],
                                       'snmp_community' => 'local-read',
          );

=head1 SEE ALSO

L<spong-network>, L<check_insight>,
L<spong-network Modules Template|spong-network-mod-template>,
L<Spong Developer's Guide|developer-guide>

=head1 NOTES

This module is based upon some internal software at Chelmer Ltd written by
George Sadlier <georges@actrix.gen.nz>.  This version is being released under
the GPL, if you find it useful, then excellant!

=head1 RESTRICTIONS

B<check_insight> uses the C<Net::SNMP> module, this must be installed for
this module to be useful.

=head1 AUTHOR

The author is Andrew Ruthven <puck@chelmer.co.nz> (or <andrew@etc.gen.nz>).
Based on code by George Sadlier <george@actrix.gen.nz>.