package NagiosGrapher; use strict; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION $xmlhash); use Data::Dumper; use XML::Simple; use File::Copy; use Exporter; $VERSION = 1.2; # Or higher @ISA = qw(Exporter); my @configuration=(); my $nagiosversion=1; # Using NAGIOS Auth modell (Reads from CGI.cfg) my $use_auth=0; # NGRAPH CFG are loaded my $loaded_cfg=0; # Graph definitions are loaded my $loaded_graph=0; # XML Statements are loaded my $loaded_xml=0; # Nagios CFG are loaded my $nagios_loaded_cfg=0; # NAGIOS CGI CFG are loaded my $nagios_loaded_cgi=0; # NGRAPH Configuration my %ngraphcfg; # NGRAPH Grapher Definitions my @ngraphdef; my $ngraphcfg = "/etc/nagios/ngraph.cfg"; my $configfile=NagiosGrapher::get_ngraphercfg_value('nagios_config'); my $cgifile=NagiosGrapher::get_ngraphercfg_value('cgi_config'); my $xmlfile='index.xml'; my $rrdpath=NagiosGrapher::get_ngraphercfg_value('rrdpath'); sub read_cgi_cfg { if (open(CGI, "<".$cgifile)) { while() { if (m/^\s*use_authentication=([0-9])/) { $use_auth = $1; last; } } close (CFG); $nagios_loaded_cgi=1; } } sub get_use_auth { read_cgi_cfg() if (!$nagios_loaded_cgi); return ($use_auth); } sub read_nagios_cfg { my @cfgfiles; my ($cfg) = @_; @configuration=(); if(open(CFG,"<".$cfg)) { while() { if(m/^cfg_file/) { # Nagios V.1.X my ($dummy,$cfgfile)=split(/=/); push(@cfgfiles,$cfgfile); } elsif (m/^object_cache_file/) { # Nagios V.2.X and higher my ($dummy,$cfgfile)=split(/=/); @cfgfiles=(); push(@cfgfiles,$cfgfile); $nagiosversion=2; last; } } close(CFG); } # read configurations foreach(@cfgfiles) { if(open(CFG,"<".$_)) { while() { push(@configuration,$_); } close(CFG); } } $nagios_loaded_cfg=1; return; } sub parse_nagios_cfg { my $rw=""; my $act_item=""; my ($type,$item,$line)=@_; return "" if($item eq ""); my @items = split(/,/,$item); # parse all items foreach $item (@items) { $rw.="," if($rw ne ""); foreach(@configuration) { # item defined? if(/define $type {/../\t}/) { my $search=$type."_name"; # is this the item we are looking for? if(m/$search\s*(.*)/) { $act_item=$1; # return the line we want } elsif($act_item eq $item and m/\s*$line\s*(.*)/) { $rw.=$1; last; } } } } return $rw; } sub AuthCheckType { my ($users); my $rw=0; my ($user,$type) = @_; if (get_use_auth eq "1") { $users = get_ngraphercfg_value($type); if (defined($users) && length($users) > 0 && $users =~ m/$user/i) { $rw=1; } } else { $rw=1; } return ($rw); } sub AuthCheck { my $rw=0; my ($cfg,$host,$user)=@_; read_nagios_cfg($cfg) if(!$nagios_loaded_cfg); if($nagiosversion==2) { # Nagios Version 2.? Perform test $rw=1 if(parse_nagios_cfg('contactgroup',parse_nagios_cfg('host',$host,'contact_groups'),'members' ) =~ m/$user(,|$)/); } else { # Nagios Version 1.X isn't supported yet so everything is allowd $rw=1; } return $rw; } sub read_ngrapher_cfg { if(open(CFG,"<".$ngraphcfg)) { while() { if(m/\s*define\s+config\s*{/../\s*}/) { s/^\s*//; chomp(); if(m/(\w*[_]*\w*)\s+(.*)$/) { my $key=$1; my $value=$2; $value.="/" if($key =~ m/path$/ && $value !~ m/\/$/); $ngraphcfg{$key}=$value; } } } $loaded_cfg=1; close(CFG); } return; } sub get_ngraphercfg_value { read_ngrapher_cfg() if(!$loaded_cfg); my ($key)=@_; my $rw=$ngraphcfg{$key}; $rw=$ngraphcfg if($key eq "ngraphcfg"); return $rw; } sub read_ngrapher_def { my (%tmp); if(open(CFG,"<".$ngraphcfg)) { while() { # Remove comments s/#.*?$//; if (m/\s*define\s+ngraph\s*{/../\s*}/) { s/^\s*//; chomp(); # \w*[_]*\w* if(m/([a-z_]+)\s+(.*)$/i) { my $key=$1; my $value=$2; if ($key =~ /service_name/i && $value =~ m/\$/) { $value =~ s/\$.*?$//; } else { chomp($value); } $tmp{$key}=$value; } } elsif ((keys(%tmp)) > 0) { push @ngraphdef, {%tmp}; %tmp = (); } } $loaded_graph=1; close(CFG); } return; } sub get_ngrapherdef { my @out=(); read_ngrapher_def() if (!$loaded_graph); my ($service,$type) = @_; @out = @ngraphdef; # warn $service; @out = grep $service =~ m/$_->{service_name}/i, @out if (defined($service)); # warn Dumper (\@out); if (defined($type) && $type =~ m/graph/i) { @out = grep !exists $_->{type}, @out; } elsif (defined($type)) { @out = grep $_->{type} eq $type, @out; } return (@out); } sub read_ngrapher_xml { my $file = $rrdpath.$xmlfile; my $xs = new XML::Simple(XMLDecl => 1, RootName => 'main', KeyAttr => 'name', ForceArray => 1); if (-e $file) { $xmlhash = $xs->XMLin($file); $loaded_xml = 1; } return; } sub get_ngrapherxml { read_ngrapher_xml() unless ($loaded_xml); return ($xmlhash); } sub write_ngrapherxml { my ($filename, $filename2, $hash) = @_; unlink ($filename) if (-e $filename); my $xs = new XML::Simple(XMLDecl => 1, RootName => 'main', KeyAttr => 'name', ForceArray => 1); open (XF, ">$filename"); print XF $xs->XMLout($hash); close (XF); unlink ($filename2) if (-e $filename2); move ( $filename, $filename2 ); return; } 1;