pnp4nagios/scripts/verify_pnp_config_v2.pl

1010 lines
29 KiB
Perl
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/perl
# Copyright (c) 2005-2011 PNP4Nagios Developer Team (http://www.pnp4nagios.org)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
use strict;
use warnings;
use Data::Dumper;
use Getopt::Long;
use File::Find;
use File::Glob;
use Term::ANSIColor;
my $version = 'pnp4nagios-head';
# process command line parameters
use vars qw ( $help $debug $mode $vInfo $PNPCfg $MainCfg $last_check $object);
my $start_options = $0 . " " . join(" ", @ARGV);
Getopt::Long::Configure('bundling');
GetOptions(
"h|help" => \$help,
"d|debug" => \$debug,
"m|mode=s" => \$mode,
"c|config=s" => \$MainCfg,
"p|pnpcfg=s" => \$PNPCfg,
"o|object=s" => \$object,
);
my @modes = ("bulk", "bulk+npcd", "sync", "npcdmod");
my @products = ("nagios", "icinga");
my @states = ("OK", "WARN", "CRIT", "UNKN", "INFO", "HINT", "DBG");
my @colors = ("bold green", "bold yellow", "bold red", "bold blue", "bold blue", "bold yellow", "black on_red");
my %process_perf_data_stats = ('hosts' => 0, 'services' => 0, 'noperf' => 0, 'noperf_but_enabled' => 0 , 0 => 0, 1 => 0);
my %stats = ( 0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 =>0 );
my %sizing = (
50 => 'sync',
200 => 'bulk',
5000 => 'bulk+npcd',
10000 => 'npcdmod',
);
if ( ! $MainCfg ){
usage();
usage_no_config();
exit;
}
if ( ! $mode ){
usage();
usage_no_mode();
exit;
}
if ( ! $PNPCfg ){
usage();
usage_no_pnpcfg();
exit;
}
if( ! in_array(\@modes, $mode)){
usage();
info("'$mode' is not a valid option",2);
info("Valid modes are [@modes]",2);
exit;
}
my %statistics = (
'OK' => 0,
'WARN' => 0,
'CRIT' => 0,
);
my %cfg = ();
my %commands = ();
my $uid = 0;
my $gid = 0;
my $process_perfdata_cfg = 0;
#
# Begin
#
info("========== Starting Environment Checks ============",4);
info("My version is: ".$version,4);
info("Start Options: ".$start_options, 4);
#
# Read Main config file
#
process_nagios_cfg();
#
# get the product name
#
my $product = get_product();
if( $product eq 0 ){
info("Can´t determine product while reading $MainCfg", 4);
info_and_exit("$MainCfg does not look like a valid config file", 2);
}else{
info("Running product is '$product'", 0);
}
#
# Read objects cache file to get more information
# Needs a running product
#
check_config_var('object_cache_file', 'exists', 'break');
if( -r $cfg{'object_cache_file'} ){
process_objects_file($cfg{'object_cache_file'});
}else{
info_and_exit($cfg{'object_cache_file'}. " is not readable", 2);
}
#
# Read resource.cfg
#
check_config_var('resource_file', 'exists', 'break');
if( -r $cfg{'resource_file'} ){
process_npcd_cfg($cfg{'resource_file'});
}else{
info_and_exit($cfg{'resource_file'}. " is not readable", 2);
}
#
# Read process_perfdata.cfg
#
if ( ! -d $PNPCfg ){
info_and_exit("Directory $PNPCfg does not exist",2);
}
if ( ! -d "$PNPCfg/check_commands" ){
info("Directory $PNPCfg/check_commands does not exist",2);
info_and_exit("$PNPCfg does not look like a PNP4Nagios config directory",2);
}
my $ppcfg = "$PNPCfg/process_perfdata.cfg";
process_perfdata_cfg($ppcfg);
#
# Read etc/pnp_release file if exists
#
if( -r "$PNPCfg/pnp4nagios_release" ){
process_pnp4nagios_release("$PNPCfg/pnp4nagios_release");
info("Found PNP4Nagios version ".get_config_var('PKG_VERSION'), 0);
info("./configure Options ".get_config_var('CONFIGURE_ARGS'), 0) if get_config_var('CONFIGURE_ARGS');
}else{
info("No pnp4nagios_release file found. This might be an older version of PNP4Nagios", 0);
}
#
# Start Main config checks
#
if(config_var_exists($product.'_user') ){
my $user = get_config_var($product.'_user');
$uid = getpwnam($user);
info( "Effective User is '$user'", 0);
if($uid){
info("User $user exists with ID '$uid'", 0 );
}else{
info_and_exit("User $user does not exist", 2 );
}
}else{
info_and_exit("Option '".$product."_user' not found in $MainCfg", 2);
}
if(config_var_exists($product.'_group') ){
my $group = get_config_var($product.'_group');
$gid = getgrnam($group);
info( "Effective group is '$group'", 0);
if($gid){
info("Group $group exists with ID '$gid'", 0 );
}else{
info_and_exit("Group $group does not exist", 2 );
}
}else{
info_and_exit("Option '".$product."_group' not found in $MainCfg", 2);
}
#
# Start sync config checks
#
if($mode eq "sync"){
info("========== Checking Sync Mode Config ============",4);
compare_config_var('process_performance_data', '1');
compare_config_var('enable_environment_macros', '1');
check_config_var('service_perfdata_command', 'exists');
check_config_var('host_perfdata_command', 'exists');;
last_info("Needed config options are missing.",5,$last_check);
# Options not allowed in sync mode
check_config_var('service_perfdata_file', 'notexists');
check_config_var('service_perfdata_file_template', 'notexists');
check_config_var('service_perfdata_file_mode', 'notexists');
check_config_var('service_perfdata_file_processing_interval', 'notexists');
check_config_var('service_perfdata_file_processing_command', 'notexists',);
check_config_var('host_perfdata_file', 'notexists');
check_config_var('host_perfdata_file_template', 'notexists');
check_config_var('host_perfdata_file_mode', 'notexists');
check_config_var('host_perfdata_file_processing_interval', 'notexists');
check_config_var('host_perfdata_file_processing_command', 'notexists');
check_config_var('broker_module', 'notexists');
last_info("Config options are not allowed in sync mode. http://docs.pnp4nagios.org",5,$last_check);
info(ucfirst($product)." config looks good so far",4);
info("========== Checking config values ============",4);
my $command_line;
$command_line = check_command_definition('service_perfdata_command');
check_process_perfdata_pl($command_line);
$command_line = check_command_definition('host_perfdata_command');
check_process_perfdata_pl($command_line);
}
if($mode eq "bulk"){
info("========== Checking Bulk Mode Config ============",4);
compare_config_var('process_performance_data', '1');
check_config_var('service_perfdata_file', 'exists');
check_config_var('service_perfdata_file_template', 'exists');
check_perfdata_file_template(get_config_var('service_perfdata_file_template'));
check_config_var('service_perfdata_file_mode', 'exists');
check_config_var('service_perfdata_file_processing_interval', 'exists');
check_config_var('service_perfdata_file_processing_command', 'exists');
check_config_var('host_perfdata_file', 'exists');
check_config_var('host_perfdata_file_template', 'exists');
check_perfdata_file_template(get_config_var('host_perfdata_file_template'));
check_config_var('host_perfdata_file_mode', 'exists');
check_config_var('host_perfdata_file_processing_interval', 'exists');
check_config_var('host_perfdata_file_processing_command', 'exists');
last_info("Needed config options are missing.",5,$last_check);
# Options not allowed in bulk mode
check_config_var('service_perfdata_command', 'notexists');
check_config_var('host_perfdata_command', 'notexists');
check_config_var('broker_module', 'notexists');
last_info("Config options are not allowed in bulk mode",5,$last_check);
info(ucfirst($product)." config looks good so far",4);
info("========== Checking config values ============",4);
my $command_line;
$command_line = check_command_definition('service_perfdata_file_processing_command');
check_process_perfdata_pl($command_line);
$command_line = check_command_definition('host_perfdata_file_processing_command');
check_process_perfdata_pl($command_line);
}
if($mode eq "bulk+npcd"){
info("========== Checking Bulk Mode + NPCD Config ============",4);
compare_config_var('process_performance_data', '1');
check_config_var('service_perfdata_file', 'exists');
check_config_var('service_perfdata_file_template', 'exists');
check_perfdata_file_template(get_config_var('service_perfdata_file_template'));
check_config_var('service_perfdata_file_mode', 'exists');
check_config_var('service_perfdata_file_processing_interval', 'exists');
check_config_var('service_perfdata_file_processing_command', 'exists');
check_config_var('host_perfdata_file', 'exists');
check_config_var('host_perfdata_file_template', 'exists');
check_perfdata_file_template(get_config_var('host_perfdata_file_template'));
check_config_var('host_perfdata_file_mode', 'exists');
check_config_var('host_perfdata_file_processing_interval', 'exists');
check_config_var('host_perfdata_file_processing_command', 'exists');
last_info("Needed config options are missing. http://docs.pnp4nagios.org",5,$last_check);
# Options not allowed in bulk mode
check_config_var('service_perfdata_command', 'notexists');
check_config_var('host_perfdata_command', 'notexists');
check_config_var('broker_module', 'notexists');
last_info("Config options are not allowed in bulk mode with npcd",5,$last_check);
info(ucfirst($product)." config looks good so far",4);
info("========== Checking config values ============",4);
my $command_line;
my $npcd_cfg = check_proc_npcd(get_config_var($product.'_user'));
if( -r $npcd_cfg){
info("$npcd_cfg is used by npcd and readable",0);
}else{
info_and_exit("$npcd_cfg is not readable",0);
}
# read npcd.cfg into %cfg
process_npcd_cfg($npcd_cfg);
check_config_var('perfdata_spool_dir', 'exists');
count_spool_files(get_config_var('perfdata_spool_dir'));
$command_line = check_command_definition('service_perfdata_file_processing_command');
$command_line = check_command_definition('host_perfdata_file_processing_command');
check_process_perfdata_pl($cfg{'perfdata_file_run_cmd'});
}
if($mode eq "npcdmod"){
my $val;
info("========== Checking npcdmod Mode Config ============",4);
compare_config_var('process_performance_data', '1');
last_info ("Needed config options are missing. http://docs.pnp4nagios.org",5,$last_check);
# Options not allowed in sync mode
check_config_var('service_perfdata_file', 'notexists');
check_config_var('service_perfdata_file_template', 'notexists');
check_config_var('service_perfdata_file_mode', 'notexists');
check_config_var('service_perfdata_file_processing_interval', 'notexists');
check_config_var('service_perfdata_file_processing_command', 'notexists');
check_config_var('host_perfdata_file', 'notexists');
check_config_var('host_perfdata_file_template', 'notexists');
check_config_var('host_perfdata_file_mode', 'notexists');
check_config_var('host_perfdata_file_processing_interval', 'notexists');
check_config_var('host_perfdata_file_processing_command', 'notexists');
last_info("Config options are not allowed in bulk mode with npcd",5,$last_check);
# event_broker_option must have enabled bits 2 and 3 (0b01100)
check_config_var ('event_broker_options', 'exists');
$val = get_config_var('event_broker_options') & 0x0c;
if($val == 12){
info("event_broker_option bits 2 and 3 enabled ($val)",0);
}else{
info_and_exit("event_broker_option bits 2 and/or 3 not enabled",2);
}
check_config_var('broker_module', 'exists', 'break');
$val = get_config_var('broker_module');
# extract npcd.cfg patch from broker_module definition
my $npcdmod_npcd_cfg;
$val =~ /npcdmod\.o\s+config_file=(.*)$/;
if($1){
$npcdmod_npcd_cfg=$1;
info("npcdmod.o config file is $npcdmod_npcd_cfg",0);
if( -r $npcdmod_npcd_cfg){
info("$npcdmod_npcd_cfg used by npcdmod.o is readable",0);
}else{
info_and_exit("$npcdmod_npcd_cfg used by npcdmod.o is not readable",2);
}
}else{
info("broker_module definition looks suspect '$val'",2);
info_and_exit("Can´t extract path to npcd.cfg from your broker_module definition",2);
}
# extract npcd.cfg path from process list
my $npcd_cfg = check_proc_npcd(get_config_var($product.'_user'));
if( -r $npcd_cfg){
info("$npcd_cfg is used by npcd and readable",0);
}
if($npcd_cfg eq $npcdmod_npcd_cfg){
info("npcd and npcdmod.o are using the same config file ($npcd_cfg)",0);
}else{
info_and_exit("npcd and npcdmod.o are not using the same config file($npcd_cfg<=>$npcdmod_npcd_cfg)",2);
}
# read npcd.cfg into %cfg
process_npcd_cfg($npcd_cfg);
check_config_var('perfdata_spool_dir', 'exists');
count_spool_files(get_config_var('perfdata_spool_dir'));
info(ucfirst($product)." config looks good so far",4);
info("========== Checking config values ============",4);
# read npcd.cfg into %cfg
process_npcd_cfg($npcd_cfg);
check_process_perfdata_pl($cfg{'perfdata_file_run_cmd'});
}
info("========== Starting global checks ============",4);
check_config_var('status_file', 'exists', 'break');
process_status_file();
info("==== Starting rrdtool checks ====",4);
check_rrdtool();
info("==== Starting directory checks ====",4);
check_config_var('RRDPATH', 'exists', 'break');
check_perfdata_dir(get_config_var('RRDPATH'));
if($process_perf_data_stats{1} == 0){
info("'process_perf_data 1' is not set for any of your hosts/services",2);
}
if($process_perf_data_stats{'noperf'} > 0){
info($process_perf_data_stats{'noperf'}." hosts/services are not providing performance data",1);
}
if($process_perf_data_stats{'noperf_but_enabled'} > 0){
info("'process_perf_data 1' is set for ".$process_perf_data_stats{'noperf_but_enabled'}." hosts/services which are not providing performance data!",1);
}
if($process_perf_data_stats{0} > 0){
info("'process_perf_data 0' is set for ".$process_perf_data_stats{0}." of your hosts/services",1);
}
if($process_perf_data_stats{1} > 0){
info("'process_perf_data 1' is set for ".$process_perf_data_stats{1}." of your hosts/services",0);
}
if ( get_config_var('LOG_LEVEL') gt 0 ){
info("Logging is enabled in process_perfdata.cfg. This will reduce the overall performance of PNP4Nagios",1)
}
info("==== System sizing ====",4);
print_sizing();
info("==== Check statistics ====",4);
print_stats();
exit;
#
# Helper Functions
#
sub config_var_exists {
my $key = shift;
if(exists $cfg{$key}){
return 1;
}else{
return 0;
}
}
sub get_config_var {
my $key = shift;
if(exists $cfg{$key}){
return $cfg{$key};
}else{
return undef;
}
}
sub count_spool_files {
my $spool_dir = shift;
my @all_files = glob "$spool_dir/*";
if($#all_files >= 10){
info("$#all_files files found in $spool_dir",2);
info("Something went wrong here!",5);
}elsif($#all_files >= 3){
info("$#all_files files found in $spool_dir",1);
info("Something went wrong here!",5);
}else{
info("$#all_files files found in $spool_dir",0);
}
}
sub check_command_definition {
my $option = shift;
warn $option;
my $key = get_config_var($option);
my $val = $commands{$key};
if(exists $commands{$key}){
info("Command $key is defined",0);
info("'$val'",0);
}else{
info_and_exit("Command $key is not defined",2);
}
if($mode eq "sync"){
if ( $option eq "host_perfdata_command"){
if( $val =~ m/process_perfdata.pl\s+-d\s+HOSTPERFDATA/ ){
info ( "Command looks good",0 );
}else{
info_and_exit ( "Command looks suspect ($val)",2 );
}
}else{
if( $val =~ m/process_perfdata.pl$/ or $val =~ m/process_perfdata.pl\s+-d\s+SERVICEPERFDATA/ ){
info ( "Command looks good",0 );
}else{
info_and_exit ( "Command looks suspect ($val)",2 );
}
}
}
if($mode eq "bulk"){
if( $val =~ m/process_perfdata.pl\s+--bulk=/){
info ( "Command looks good",0 );
}else{
info_and_exit ( "Command looks suspect ($val)",2 );
}
}
if($mode eq "bulk+npcd"){
my $dump_file = get_config_var( $option =~m/(.*)_processing_command/ );
my $perfdata_spool_dir = get_config_var( 'perfdata_spool_dir');
#print "$dump_file\n";
my $regex = qr/\/bin\/mv\s+$dump_file\s+$perfdata_spool_dir/;
if( $val =~ m/$regex/){
info ( "Command looks good",0 );
}else{
info ( "Regex = $regex", 4 );
info_and_exit ( "Command looks suspect ($val)",2 );
}
}
return $commands{$key};
}
#
# Max three parameters
#
sub check_config_var {
my $key = shift;
my $check = shift;
my $break = shift||0;
my $var = get_config_var($key);
if($check eq "exists"){
if(defined($var)){
info("$key is defined",0);
info("$key=$var",0);
#$last_check = 0;
}else{
info("$key is not defined",2);
$last_check++;
exit if $break;
}
}
if($check eq "notexists"){
if( ! defined($var)){
#info("$key is not defined",0);
#$last_check = 0;
}else{
info("$key is defined ($key=$var)",2);
info("$key is not allowed in mode '$mode'",2);
$last_check++;
exit if $break;
}
}
}
sub compare_config_var {
my $key = shift;
my $compare = shift;
my $break = shift||0;
my $var = get_config_var($key);
if( $var =~ /$compare/){
info("$key is $var compared with '/$compare/'",0);
}else{
info("$key is $var compared with '/$compare/'",2);
exit if $break;
}
}
sub check_perfdata_file_template {
$_ = shift;
if ( not $_ ){
return;
}
if( /^DATATYPE::(HOST|SERVICE)PERFDATA/ ){
info("PERFDATA template looks good",0);
}else{
info("PERFDATA template looks suspect",2);
}
}
sub info {
my $string = shift;
my $state = shift||0;
my $break = shift||0;
$stats{$state}++;
return if $state == 6 and not defined $debug;
$statistics{$states[$state]}++;
print color $colors[$state];
printf("[%-4s]", $states[$state]);
print color 'reset';
printf(" %s\n", $string);
}
sub last_info {
my $string = shift;
my $state = shift;
my $break = shift||0;
return if $break == 0;
info("$string ($break)", $state);
exit if $break > 0;
}
sub info_and_exit {
my $string = shift;
my $state = shift;
info($string, $state);
exit $state;
}
sub print_stats {
my $state = 0;
$state = 1 if $stats{1} > 0;
$state = 2 if $stats{2} > 0;
info(sprintf("Warning: %d, Critical: %d",$stats{1}, $stats{2}),$state);
info("Checks finished...", $state);
}
sub print_sizing {
my $object_count = ($process_perf_data_stats{'hosts'} + $process_perf_data_stats{'services'});
my $graph_count = ($process_perf_data_stats{'hosts'} + $process_perf_data_stats{'services'});
info("$object_count hosts/service objects defined",0);
foreach my $limit ( sort {$a <=> $b} keys %sizing){
if($graph_count >= $limit and $sizing{$limit} eq $mode){
info("Use at least mode '".get_mode_by_size($graph_count)."' to reduce I/O",5);
last;
}
}
}
sub get_mode_by_size {
my $graph_count = shift;
foreach my $limit ( sort {$a <=> $b} keys %sizing){
return $sizing{$limit} if $limit >= $graph_count;
}
return 'gearman';
}
sub check_rrdtool {
check_config_var('RRDTOOL', 'exists', 'break');
my $rrdtool = get_config_var('RRDTOOL');
if ( -x $rrdtool ){
info("$rrdtool is executable",0);
}else{
info_and_exit("$rrdtool is not executable",2);
}
my @version = `$rrdtool`;
chomp $version[0];
info($version[0],0);
check_config_var('USE_RRDs', 'exists', 'break');
if(get_config_var('USE_RRDs')){
unless ( eval "use RRDs;1" ) {
info("Perl RRDs modules are not loadable",1);
}else{
info("Perl RRDs modules are loadable",0);
}
}else{
unless ( eval "use RRDs;1" ) {
info("Perl RRDs modules are neither loadable nor enabled (USE_RRDs = 0)",1);
}else{
info("RRDs modules are loadable but not enabled (USE_RRDs = 0)",1);
}
}
}
sub check_proc_npcd {
my $user = shift;
my $out = `ps -u $user -o cmd | grep /npcd | grep -v grep`;
my $rc = $?;
chomp $out;
info("Check process: 'ps -u $user -o cmd | grep /npcd | grep -v grep'", 6);
info("Result: $out", 6);
info("Returncode: $rc", 6);
#extract npcd.cfg
$out =~ /-f\s?(\S+)/;
my $npcd_cfg = $1;
if($rc == 0){
info("npcd daemon is running",0);
}else{
info("npcd daemon is not running",2);
info_and_exit("A running npcd daemon is needed to process data.",4);
}
return $npcd_cfg;
}
# process nagios.cfg
sub process_nagios_cfg {
info ("Reading $MainCfg", 4);
open (NFILE, "$MainCfg") || info_and_exit("Failed to open '$MainCfg'. $! ", 2);
while (<NFILE>) {
process_main_cfg_line();
}
close (NFILE);
}
# process process_perfdata.cfg
sub process_perfdata_cfg {
my $cfg_file = shift;
if ( -r $cfg_file ){
if ( process_cfg($cfg_file) ){
$process_perfdata_cfg = 1;
}else{
$process_perfdata_cfg = 0;
}
}elsif(-e "$PNPCfg/process_perfdata.cfg-sample"){
info ("$cfg_file does not exist.",1);
info ("We will try to parse defaults from process_perfdata.pl later on", 1);
info ("process_perfdata.cfg-sample exists in $PNPCfg", 5);
info ("It is recommended to rename process_perfdata.cfg-sample to process_perfdata.cfg", 5);
$process_perfdata_cfg = 0; # we have to parse process_perfdata.pl to get defaults
}else{
info ("$cfg_file does not exist.",1);
info ("We will try to parse defaults from process_perfdata.pl later on", 1);
info ("It is recommended to place $cfg_file in $PNPCfg", 5);
info ("A sample file is installed by 'make install-config'", 5);
$process_perfdata_cfg = 0; # we have to parse process_perfdata.pl to get defaults
}
}
sub process_pnp4nagios_release {
my $cfg_file = shift;
if ( -r $cfg_file ){
process_cfg($cfg_file);
}
}
sub process_cfg {
my $cfg_file = shift;
if ( -r $cfg_file ){
info ("Reading $cfg_file", 4);
open (NFILE, "$cfg_file") || info_and_exit("Failed to open '$cfg_file'. $! ", 2);
while (<NFILE>) {
process_main_cfg_line();
}
close (NFILE);
return 1;
}
return 0;
}
# process npcd.cfg
sub process_npcd_cfg {
my $cfg_file = shift;
if ( -r $cfg_file ){
info ("Reading $cfg_file", 4);
}else{
info ("$cfg_file does not exist", 4);
info ("this file is needed to get more information about your system", 5);
info_and_exit("no further processing possible",2);
}
open (NFILE, "$cfg_file") || info_and_exit("Failed to open '$cfg_file'. $! ", 2);
while (<NFILE>) {
process_main_cfg_line();
}
close (NFILE);
}
# process main config line
sub process_main_cfg_line {
chomp;
return if (/^$/);
return if (/^#/);
s/#.*//;
s/\s*$//;
if (my ($par, $val) = /([^=]+)\s?=\s?(.*)/){
$par = trim($par);
$val = trim($val);;
if ( (defined($par) && $par eq "") ) {
info ("oddLine -> $_" ,4);
return;;
}
# skip broker_module lines.
return if (($par eq "broker_module") and ($val !~ /npcdmod.o/));
info("'$par' -> '$val'",6);
$cfg{"$par"} = $val;
}
}
sub trim {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
# read object_file
sub process_objects_file {
my ($file) = @_;
my $cmd = "";
my $line = "";
info ("Reading $file", 4);
open (CFILE, "$file") || info_and_exit("Failed to open '$file'. $! ", 2);
while (<CFILE>) {
s/#.*//;
next if (/^$/);
chomp;
if (/command_name/) {
($cmd) = /command_name\s*(.*)/;
next;
}
next unless ( /command_line/);
($line) = /command_line\s*(.*)/ ;
$commands{"$cmd"} = "$line";
next unless (/process_perfdata.pl/);
my @cmd = split (/\s+/,$line);
}
close (CFILE);
}
sub process_status_file {
my ($file) = get_config_var('status_file');
my $line = "";
my $perfdata_found = 0;
my ($host_query,$service_query) = split(/;/,$object) if ($object);
$host_query = "" unless (defined $host_query);
$service_query = "" unless (defined $service_query);
info("host_query = $host_query",4);
info("service_query = $service_query",4);
my $hst = "";
my $srv = "";
my $perf = "";
my $ppd = "";
info ("Reading $file", 4);
open (CFILE, "$file") || info_and_exit("Failed to open '$file'. $! ", 2);
while (<CFILE>) {
s/#.*//;
next if (/^$/);
chomp;
if(/\shost_name=(.+)/){
$hst = $1;
$srv = "";
}
if(/\sservice_description=(.+)/){
$srv = $1;
}
if(/\sperformance_data=$/){
$process_perf_data_stats{'noperf'}++;
$perfdata_found = 0;
$perf = " $hst/$srv: [empty perf data]";
}
if(/\sperformance_data=(.+)$/){
$perfdata_found = 1;
$perf = " $hst/$srv: [$1]";
}
# count process_perf_data definitions
if (/process_performance_data=(\d)$/){
$ppd=$1;
$process_perf_data_stats{$1}++ ;
if ( $perfdata_found == 0 && $1 == 1){
$process_perf_data_stats{'noperf_but_enabled'}++;
}
if ($host_query ne '') {
$perf = "" if ($hst !~ /$host_query/i);
if ($service_query ne '') {
$perf = "" if ($srv !~ /$service_query/i);
}else{
$perf = '';
}
}else{
$perf='';
}
if ($perf ne ""){
info ("$perf, ppd=$ppd", 4);
}
}
if(/^hoststatus /){
$process_perf_data_stats{'hosts'}++;
}
if(/^servicestatus /){
$process_perf_data_stats{'services'}++;
}
}
close (CFILE);
}
sub check_process_perfdata_pl {
my $command_line = shift;
my $path = '';
if( $command_line =~ /\s?([^\s]*)\/process_perfdata.pl\s?/ ){
$path = $1;
if ($path =~ /(\$USER\d+\$)/) {
if (exists $cfg{"$1"}) {
my $val = $cfg{"$1"};
$path =~ s/\$USER\d+\$/$val/;
}
}
if( -x "$path/process_perfdata.pl" ){
info("Script $path/process_perfdata.pl is executable",0);
}else{
info_and_exit("Script $path/process_perfdata.pl is not executable",2);
}
process_pp_pl ("$path/process_perfdata.pl") if $process_perfdata_cfg == 0;
}else{
info_and_exit("Can´t find path to process_perfdata.pl",2);
}
}
sub check_perfdata_spool_dir {
my $dir = shift;
if( -d $dir ){
info("Spool directory '$dir' exists",0);
}else{
info_and_exit("Spool directory $dir does not exist",2);
}
my @files = <$dir/*>;
my $count = @files;
if($count > 1){
info("$count files in $dir", 1);
}else{
info("$dir is empty", 0);
}
}
#
sub check_perfdata_dir {
my $dir = shift;
if( -d $dir ){
info("Perfdata directory '$dir' exists",0);
find(\&check_perm, "$dir");
}else{
info_and_exit("Perfdata directory $dir does not exist",2);
}
}
sub check_perm {
-d ;
my $f = "$File::Find::name";
return unless (($f =~ /\/$/) or ($f =~ /rrd$|xml$/));
check_usrgrp ($f);
}
sub check_usrgrp {
my $file = shift;
my $break = shift || 0;
if ($uid) {
my $fuid = (stat("$file"))[4];
my $fname = getpwuid($fuid);
info ("$file: owner is $fname", 2, $break) if ($fuid != $uid);
}
if ($gid) {
my $fgid = (stat("$file"))[5];
my $fgroup = getgrgid($fgid);
info ("$file: group is $fgroup", 2, $break) if ($fgid != $gid);
}
}
# read config inside process_perfdata.pl
sub process_pp_pl {
my $cfg_file = shift;
my $loop = 0;
info ("Reading $cfg_file", 4);
open (NFILE, "$cfg_file") || info_and_exit("Failed to open '$cfg_file'. $! ", 2);
while (<NFILE>) {
chomp;
last if (/^\s*\);/);
s/#.*//;
s/\s*$//;
s/^\s+//;
next if (/^$/);
#$loop++ if (/%conf/);
#next unless ($loop);
my ($par, $val) = /([^\s]+)\s+=>\s+([^\s]+)/; # shortest string
next unless ((defined $par) and (defined $val));
$val =~ s/['",]//g;
$cfg{"$par"} = $val;
}
close (NFILE);
}
sub get_product {
for my $product (@products){
my $string = $product . "_user";
if ( exists $cfg{$string} ){
return $product;
}
}
return 0;
}
sub in_array{
my ($arr,$search_for) = @_;
my %items = map {$_ => 1} @$arr;
return (exists($items{$search_for}))?1:0;
}
sub usage{
print <<EOF;
verify_pnp_config -m|--mode=[sync|bulk|bulk+npcd|npcdmod]
-c|--config=[location of nagios.cfg]
-p|--pnpcfg=[path to PNP config dir]
-o|--object="[host][;service]" (optional)
This script will check certain settings/entries of your PNP environ-
ment to assist you in finding problems when you are using PNP.
It may be used prior and during operation of PNP.
Output starts with a letter with the following meaning:
[INFO] informational message about settings, ...
[OK ] ok message, will not affect the operation of PNP
[WARN] warning message, might effect the operation of PNP
[CRIT] error message: PNP will not work without resolving the problem(s)
[HINT] hint: it might be worth reading the appropriate documentation
[DBG ] debugging message, hopefully showing the source of your problem
EOF
}
sub usage_no_config{
info("-c | --config option not given",2);
info_and_exit("please specify the path to your nagios or icinga.cfg",2);
}
sub usage_no_pnpcfg{
info("-p | --pnpcfg option not given",2);
info_and_exit("please specify the path to your PNP config dir",2);
}
sub usage_no_mode{
info("-m | --mode option not given",2);
info_and_exit("Valid options are [@modes]",2);
}