#!/usr/bin/perl -w use lib "/usr/lib/vmware-vcli/apps/"; use VMware::VIRuntime; use AppUtil::HostUtil; my $debug = 1; my $NSCA_HOST="127.0.0.1"; my $NSCA_SEND="/usr/sbin/send_nsca"; my $NSCA_CONF="/etc/nagios/send_nsca.cfg"; sub print_service_status($$$$) { my ($id,$service,$status,$info) = @_; my %statuses = ("OK" => 0, "WARNING" => 1, "CRITICAL" => 2, "UNKNOWN" =>3, "PENDING" => 4 ); $status="UNKNOWN" unless defined($statuses{$status}); print "$id\t$service\t$statuses{$status}\tVIMA:$info\n" if ($debug); open NSCA, "|$NSCA_SEND -H $NSCA_HOST -c $NSCA_CONF > /dev/null" || die; print NSCA "$id\t$service\t$statuses{$status}\tVIMA:$info\n"; close NSCA; } sub print_host_status($$$) { my ($id,$status,$info) = @_; my %statuses = ("OK" => 0, "WARNING" => 1, "CRITICAL" => 2, "UNKNOWN" =>3, "PENDING" => 4 ); print "id=$id\n"; print "status=$status\n"; print "info=$info\n"; $status="UNKNOWN" unless defined($statuses{$status}); print "$id\t$statuses{$status}\tVIMA:$info\n" if ($debug); open NSCA, "|$NSCA_SEND -H $NSCA_HOST -c $NSCA_CONF" || die; print NSCA "$id\t$statuses{$status}\tVIMA:$info\n"; close NSCA; } sub vm_check_dc { my ($dcfilter) = Opts::get_option('dcfilter'); my $dc_views; if ($dcfilter eq '--auto--') { $dc_views = Vim::find_entity_views(view_type => 'Datacenter'); }else { $dc_views = Vim::find_entity_views(view_type => 'Datacenter', filter => {'name' => qr/^$dcfilter/i }); } return if !defined(@$dc_views); foreach $dc_view (@$dc_views) { # Check host overall status (green,yellow, red) my $dc_name = $dc_view->name; my $dc_moref = Vim::find_entity_view(view_type=>'Datacenter', filter=>{'name' => qr/$dc_name/ }); vm_check_host($dc_moref); } } sub vm_check_host { my ($datacenter) = @_; my %statuses = ("green" => "OK", "yellow" => "WARNING", "red" => "CRITICAL"); my $retval = undef; my ($dcname) = Opts::get_option('dcname'); $dcname = 'vmdc-'.lc($datacenter->name) if ($dcname eq '--auto--'); my $host_views = Vim::find_entity_views(begin_entity=>$datacenter, view_type => 'HostSystem'); if (defined(@$host_views)) { foreach $host_view (@$host_views) { # Check host overall status (green,yellow, red) my $host_overall_status = $host_view->overallStatus->val; my $host_nagios_status; if (defined($statuses{$host_overall_status})) { $host_nagios_status = $statuses{$host_overall_status}; } else { $host_nagios_status = 'UNKNOWN'; } print_service_status($dcname,"HOST ". $host_view->name,$host_nagios_status, "overall status=" . $host_overall_status); my $autoStartMgr = Vim::get_view(mo_ref => $host_view->configManager->autoStartManager); my $powerInfo = $autoStartMgr->config->powerInfo; if ($powerInfo) { my $vmPrev = ""; foreach(sort {$b->startOrder cmp $a->startOrder} @$powerInfo) { my $vmProp = Vim::get_view(mo_ref => $_->key, properties=>['name']); my $vmName = $vmProp->{'name'}; if ($_->startAction eq 'PowerOn') { if ($vmOrder) { $vmOrder .= ",".$vmName; } else { $vmOrder = $vmProp->{'name'}; } # print_service_status($dcname, "STARTAFTER ".$vmName, 0, $vmPrev); $vmPrev = $vmName unless($vmOrder eq '-1'); }else { $vmPrev = ""; # print_service_status($dcname, "STARTAFTER ".$vmName, 0, $vmPrev); } } } } } my $vm_views; $vm_views = Vim::find_entity_views(begin_entity=>$datacenter, view_type => 'VirtualMachine', filter=>{'config.template'=>qr/false/i}); if (defined(@$vm_views)) { foreach my $vm (@$vm_views) { my $vm_overall_status = $vm->overallStatus->val; my $vm_nagios_status; my $vm_state = $vm->runtime->powerState->val; my $service = lc($vm->name); my $mor_host = $vm->runtime->host; my $vm_host = Vim::get_view(mo_ref => $mor_host)->name; $service =~s/ /_/g; if (defined($statuses{$vm_overall_status})) { $vm_nagios_status = $statuses{$vm_overall_status}; } else { $vm_nagios_status = 'UNKNOWN'; } if ($vm_state =~ /poweredOff/) { $vm_nagios_status = 'WARNING'; } print_service_status($dcname,"VM $service",$vm_nagios_status, "host=$vm_host,state=$vm_state,status=" . $vm_overall_status); } } $vm_views = Vim::find_entity_views(begin_entity=>$datacenter, view_type => 'VirtualMachine', filter=>{'config.template'=>qr/true/i}); if (defined(@$vm_views)) { foreach my $vm (@$vm_views) { my $vm_overall_status = $vm->overallStatus->val; my $vm_nagios_status; my $vm_state = $vm->runtime->powerState->val; my $service = lc($vm->name); my $mor_host = $vm->runtime->host; my $vm_host = Vim::get_view(mo_ref => $mor_host)->name; $service =~s/ /_/g; if (defined($statuses{$vm_overall_status})) { $vm_nagios_status = $statuses{$vm_overall_status}; } else { $vm_nagios_status = 'UNKNOWN'; } print_service_status($dcname,"TMPLT $service",$vm_nagios_status, "host=$vm_host,state=$vm_state,status=" . $vm_overall_status); } } } my %opts = ( dcname => { type => "=s", help => "Override datacenter name", required => 0, default => '--auto--', variable => 'VI_DCNAME', }, dcfilter => { type => "=s", help => "Check this datacenter", required => 0, default => '--auto--', variable => 'VI_DCFILTER', }, nscahost => { type => "=s", help => "IP address or host name of Nagios server", required => 0, default => "127.0.0.1", variable => 'VI_NSCAHOST', }, nscasend => { type => "=s", help => "Full path to send_nsca binary", required => 0, default => "/usr/sbin/send_nsca", variable => 'VI_NSCASEND', }, nscaconf => { type => "=s", help => "Full path to send_nsca configuration file", required => 0, default => "/etc/nagios/send_nsca.cfg", variable => 'VI_NSCACONF' }, ); Opts::add_options(%opts); Opts::parse(); Opts::validate(); $NSCA_HOST = Opts::get_option('nscahost'); $NSCA_SEND = Opts::get_option('nscasend'); $NSCA_CONF = Opts::get_option('nscaconf'); eval{ $retval = Util::connect(); }; if ($@) { print_host_status($datacenter,"CRITICAL", "Unable to connect to vCenter: $@"); exit(1); }elsif (!defined($retval)) { print_host_status($datacenter,"CRITICAL", "Unable to connect to vCenter: unknown error"); exit(1); } eval { vm_check_dc(); }; Util::disconnect();