# -*- perl -*-
# vim: syntax=perl

# $Id: statuscheck.plm,v 1.6 2005/10/17 20:01:54 thomas Exp $

# Generate a description file from an existing system

# $Log: statuscheck.plm,v $
# Revision 1.6  2005/10/17 20:01:54  thomas
# Report prime user
#
# Revision 1.5  2005/09/14 20:05:21  thomas
# Host attribute audit checks added
#
# Revision 1.4  2005/09/01 20:29:13  thomas
# Tweak missing config part
#
# Revision 1.3  2005/08/31 20:47:40  thomas
# Add check for hosts without host attributes
#
# Revision 1.2  2005/07/11 19:26:33  thomas
# misc mods
#
# Revision 1.1  2005/04/28 14:30:13  thomas
# Report hosts with certain statuses
#

=head1 NAME

What::Command::statuscheck - Report all hosts with certain statuses

=head1 SYNOPSIS

what statuscheck [I<status> ...]

=head1 DESCRIPTION

Read the cached data for all hosts known to what, and report any hosts
that have the requested status(es).

=head1 OPTIONS

=over 4

=item (-s|--status) I<status[,...]>

Report on the listed statuses, instead of the default I<Repair and
Setup>I.  Specify this option for each status you want reported.

=back

=head1 SEE ALSO

What::Data

=cut

package What::Command::statuscheck;

use strict;
use Getopt::Long;
use Pod::Usage;
use Data::Dumper;

use base qw(What::Command);
use What::Csdb;
use What::HostAttributes;
use What::MachineStatus;
use What::OsMap;

our $helpmsg = 'Report hosts with certain status';

###############################################################################

sub main {
  my $self = shift;
  my $what = shift;
  local (@ARGV) = @_;

  my ($res, $help, $all, $hosts) = (0, 0, 0, {});
  my ($Csdb, $host, $href, $status, %status, $map);

  # Get the default set of statuses from MachineStatus
  my $Stat = new What::MachineStatus;
  my $stat = $Stat->find;
  foreach $status (keys %$stat) {
    $status{$status} = 1 if $stat->{$status}->{StatusReport};
  }

  Getopt::Long::Configure ("bundling");
  $res = GetOptions (
		     'help|h'     => \$help,
		     'all|a'      => \$all,
		    );

  $res or return $what->err ("Bad option passed to allhosts command!\n");

  $help and return $self->help();

  (%status = map { $_ => 1 } @ARGV) if @ARGV;

  # Read all host csdb, and put it into appropriate status groups
  return 0 unless defined ($Csdb = new What::Csdb);

  my ($Attrs, $attrtext, $attrs, $attrhosts, $os, $prime_user, $Map);
  return 0 unless defined ($Attrs = new What::HostAttributes);

  return 0 unless defined ($Map = new What::OsMap);

  $Csdb->start_hostlist;
  while (defined ($href = $Csdb->next_host)) {
    next unless defined ($href->{status});
    $os = $href->{os} || 'unknown';
    $prime_user = $href->{prime_user} || 'undef';
    if ($all || defined $status{$href->{status}}) {
      $hosts->{$href->{status}}->{$href->{cpuname}} = "$os -- $prime_user";
    }


    # Also check for the existence of host attributes for the host
    $map = $Map->get_attrs (csdb=>$href->{os});
    next unless defined ($map)
      && defined ($map->{HostAttrType})
	&& $map->{HostAttrType} eq 'Required';

    # OK.  The OS requires attributes.  Are they there?
    if (!defined ($attrtext = $Attrs->find ($href->{cpuname}))) {
      $attrhosts->{$os}->{$href->{cpuname}}
	= "No Host Attribute text found ($href->{status})";
      next;
    }
    $attrs = $Attrs->parse_attrs ($attrtext);
    if (!defined ($attrs) || !@$attrs) {
      $attrhosts->{$os}->{$href->{cpuname}}
	= "No Host Attributes found ($href->{status})";
      next;
    }
  }

  # Print Setup/Repair hosts
  foreach $status (sort keys %$hosts) {
    print "Status $status:\n";
    foreach $host (sort keys %{$hosts->{$status}}) {
      print "  $host ($hosts->{$status}->{$host})\n";
    }
    print "\n";
  }

  # Print missing attribute data
  foreach $os (sort keys %$attrhosts) {
    print "Hosts needing attributes for $os:\n";
    foreach $host (sort keys %{$attrhosts->{$os}}) {
      print "  $host: $attrhosts->{$os}->{$host}\n";
    }
    print "\n";
  }

  return 0;
}


###############################################################################

1;

