#!/usr/bin/perl
#
# Generate list of nodes to load from /etc/munin/munin.conf to check
# all the machines reporting to sitesummary.

use strict;
use warnings;

use SiteSummary;
use Getopt::Std;

sub usage {
    print <<EOF;
Usage: $0 [-hmnw]

 -h  Show usage information
 -m  Generate munin configuration for all munin clients
 -n  Generate nagios configuration for all nagios clients
 -w  List all client DNS/IP-addresses and MAC addresses
EOF
}

my %opts;
getopts("hmnw", \%opts) || (usage(), exit(1));

my %hostnames;

for_all_hosts(\&handle_host);

if ($opts{'h'}) {
    usage();
    exit 0;
} elsif ($opts{'m'}) {
    print_munin_list();
} elsif ($opts{'w'}) {
    print_ip_hw_list();
} elsif ($opts{'n'}) { # XXX Nagios config generation do not work yet
    generate_nagios_config();
} else {
    print_list();
}
exit 0;

sub handle_host {
    my $hostid = shift;
    my $address = get_dns_address($hostid);
    $hostnames{$address} = $hostid;
}

sub print_list {
    for my $hostname (sort keys %hostnames) {
        print "$hostname\n";
    }
}

sub is_pkg_installed {
    my ($hostid, $pkgname) = @_;
    # Check debian/dpkg-l for 'ii *pkgname '
    my $path = get_filepath_current($hostid, "/debian/dpkg-l");
    if (open (my $fh, $path)) {
        while(<$fh>) {
            if (m/^ii *$pkgname /) {
                close($fh);
                return 1
            }
        }
        close($fh);
    }
    return undef;
}

sub is_munin_client {
    my $hostid = shift;
    return is_pkg_installed($hostid, "munin-node");
}

sub is_nagios_client {
    my $hostid = shift;
    return is_pkg_installed($hostid, "nagios-nrpe-server") ||
        is_pkg_installed($hostid, "nagios-text") ||
        is_pkg_installed($hostid, "nagios2") ||
        is_pkg_installed($hostid, "nagios3");
}

sub print_munin_list {
    for my $hostname (sort keys %hostnames) {
        next unless (is_munin_client($hostnames{$hostname}));

    # Using hostname as address, to avoid hardcoding IP addresses in
    # the file.  Might be an idea to fetch the IP address from
    # system/ifconfig-a
        print <<EOF;
[$hostname]
    address $hostname
    use_node_name yes

EOF
    }
}

sub print_ip_hw_list {
    for my $hostname (sort keys %hostnames) {
        my $macaddress = get_primary_macaddress($hostnames{$hostname});
        print "$hostname $macaddress\n";
    }
}

sub generate_nagios_config {
    for my $hostname (sort keys %hostnames) {
        my $hostid = $hostnames{$hostname};
        next unless (is_nagios_client($hostid));

        my $address = get_dns_address($hostid);

        # first, check ping to see if the other checks should be performed
        print <<EOF;
##################### $hostname #######################
define host {
        host_name           $hostname
        address             $address
}
define service {
        use                 server-service
        host_name           $hostname
        service_description PING
        check_command       check_ping!100.0,20%!500.0,60%
}
EOF

        # check disk free space
        my $path = get_filepath_current($hostid, "/system/procmounts");
        if ( -e $path ) {
            open (F, "<", $path) || die "unable to read from $path";
            my %checked;
            while (<F>) {
                chomp;
                my ($dev, $partition, $fs, $opts) = split;
                next if (exists $checked{$partition});
                next if ($fs eq "devpts" ||
                         $fs eq "autofs" ||
                         $fs eq "binfmt_misc" ||
                         $fs eq "iso9660" ||
                         $fs eq "nfs" ||
                         $fs eq "nfsd" ||
                         $fs eq "proc" ||
                         $fs eq "rootfs" ||
                         $fs eq "rpc_pipefs" ||
                         $fs eq "sysfs" ||
                         $fs eq "tmpfs" ||
                         $fs eq "usbfs");

                $checked{$partition} = 1;
                my $warn = 10;
                my $crit = 5;
                print <<EOF;
define service {
        use                 server-service
        host_name           $hostname
        service_description Disk $partition
        check_command       check_disk!$warn%!$crit%!$partition
}
EOF
            }
        }

        my %tcpservices =
        (
         139  => { name => 'samba',   package => 'samba' },
         631  => { name => 'CUPS',    package => 'cupsys' },
         636  => { name => 'ldaps',   package => 'slapd' },
         3128 => { name => 'squid',   package => 'squid' },
#       10000 => { name => 'webmin',  package => 'webmin' },
         );

        for my $port (sort { $a <=> $b } keys %tcpservices) {
            next if (exists $tcpservices{$port}->{package} && !
                     is_pkg_installed($hostid,
                                      $tcpservices{$port}->{package}));
            my $servicename = $tcpservices{$port}->{name};
            print <<EOF;
define service {
        use                 server-service
        host_name           $hostname
        service_description $servicename
        check_command       check_tcp!$port
}
EOF
        }
        # check munin if munin-node is installed
        # check hw and sw raid status
        # check hardware status
        # check free swap
        # check X font server
        # check LDAP
        # check DNS
        # Check SSH server
        print <<EOF if is_pkg_installed($hostid, "openssh-server");
define service {
        use                 server-service
        host_name           $hostname
        service_description SSH
        check_command       check_ssh
}
EOF
        print <<EOF if (is_pkg_installed($hostid, "apache") || is_pkg_installed($hostid, "apache2"));
define service {
        use                 server-service
        host_name           $hostname
        service_description HTTP
        check_command       check_http
        }
EOF

        print <<EOF if (is_pkg_installed($hostid, "ntp") || is_pkg_installed($hostid, "ntp-server"));
define service {
        use                 server-service
        host_name           $hostname
        service_description Time server NTP
        check_command       check_ntp!-H!localhost
}
EOF
        # Check unix load
        print <<EOF;
define service {
        use                 server-service
        host_name           $hostname
        service_description Load as in top
        check_command       check_load!75,75,75!90,90,90
}
EOF
    }
}
