Incorporar CGI propio a la interfaz web de Nagios

Tal como prometí en un post anterior voy a explicar cómo incluí un CGI Perl a la web de administración de Nagios que permite buscar y/o mostrar información almacenada en un fichero.

En ese post habíamos visto cómo, usando el VI Perl Toolkit de VMware, obtener un listado de las máquinas virtuales que tenemos en todos los servidores ESXi de la organización así como si estas máquinas están encendidas o apagadas.

El resultado era algo como esto:

server01.miorganizacion.es,Windows_7_home_x86,poweredOff
server01.miorganizacion.es,BT4-R1,poweredOff
server01.miorganizacion.es,Ubuntu 10.10,poweredOn
server01.miorganizacion.es,XP Act 2010,poweredOff
server02.miorganizacion.es,7 ultimate,poweredOff
server02.miorganizacion.es,CentOS 5.5,poweredOn
server02.miorganizacion.es,Debian 6,poweredOn
server02.miorganizacion.es,Win 2003,poweredOn

Cuando el número de VMs empieza a ser elevado resulta útil tener esta información fácilmente accesible por ejemplo desde la web de administración de Nagios:

CGI listvm en la interfaz web de Nagios

CGI listvm en la interfaz web de Nagios

Como se ve en la imagen, se ha añadido a la columna de la izquierda la opción «VM Search» que tiene un formulario para buscar por el nombre de la máquina virtual o un botón para mostrar todas las máquinas:

Mostrar todas la maquinas virtuales

Mostrar todas la maquinas virtuales

Yo uso un «theme» de Nagios que se llama Nuvola Style que da a Nagios una apariencia que me gusta mucho más que la de la instalación por defecto.

Este tema incluye, además de estilos e iconos, un javascript que carga los menus de la parte izquierda y que tendremos que modificar para añadir la opción de «VM Search».

El fichero a editar es:

/usr/share/nagios3/htdocs/side/dtree_data.js

Buscaremos la línea correspondiente a la opción del menú «Event Log» y debajo añadiremos:

reporting.add(13,0,'VM Search',cgipath + 'listvms.cgi','','','side/icons/notes.gif');

El enlace al CGI, vemos que se construye con el «cgipath» que en la configuración de Nagios (en Debian) está definido como:

/usr/lib/cgi-bin/nagios3/

Por tanto, dejamos en este directorio el fichero listvms.cgi cuyo código es:

#!/usr/bin/perl -w

# Pintamos la primera parte de la pagina html
&start_html;

if($ENV{'CONTENT_LENGTH'} == 0)
{
        #No se ha enviado nada por POST, luego cargamos el formulario
        &print_form;
}
else
{
        #Se ha enviado algo por POST
        my $cadena = capture_data();
        my @results = search_infile($cadena);
        if ($#results >= 0)
        {
                print_results(\@results);
        }
}

&end_html;

sub start_html {
print "Content-type: text/html\n\n";
print "<html><head>";
print "<title>VM Search</title>";
print "<LINK REL='stylesheet' TYPE='text/css' HREF='/nagios3/stylesheets/common.css'>";
print "<LINK REL='stylesheet' TYPE='text/css' HREF='/nagios3/stylesheets/avail.css'>";
print "<LINK REL='stylesheet' TYPE='text/css' HREF='/nagios3/stylesheets/status.css'>";
print "</head>";
print "<BODY CLASS='avail'>";
print "<table border=0 width=100% cellspacing=0 cellpadding=0>";
print "<tr>";
print "<td align=left valign=top width=33%>";
print "                 <TABLE CLASS='infoBox' BORDER=1 CELLSPACING=0 CELLPADDING=0>";
print "                 <TR></TR>";
print "                 </TABLE>";
print "         </td>";
print "         <td align=center valign=top width=33%>";
print "         </td>";
print "         <td align=right valign=bottom width=33%>";
print "                 <table border=0 CLASS='optBox'>";
print "                         <tr></tr>";
print "                 </table>";
print "         </td>";
print " </tr>";
print "</table>";
}

sub print_form {
print '<p></p><div align="center" class="reportSelectTitle">Introduce el término a buscar...</div><p></p>';
print '<p></p><div align="center">';
print "<p>";
print "</p>";
print '<form action="listvms.cgi" method=post>';
print "<input type=text name=virtualmachine size=20><p>";
print '<input type=submit value="Enviar">';
print "</form>";
print '<p></p><div align="center" class="reportSelectTitle">...o puedes mostrar todo:</div><p></p>';
print '<p></p><div align="center">';
print "<p>";
print "</p>";
print '<form action="listvms.cgi" method=post>';
print '<input type="hidden" name="todo" value="si">';
print '<input type=submit value="Mostrar todo">';
print "</form>";
}

sub capture_data {

# Obtiene la entrada
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

# Divide las variables entre nombre y valor.
@pairs = split(/&/, $buffer);

# Optiene todas las variables y sus valores (aunque solo hemos pasado uno)
foreach $pair (@pairs)
        {
                ($name, $value) = split(/=/, $pair);

                $value =~ tr/+/ /;
                $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

                $FORM{$name} = $value;
        }
return ($FORM{'virtualmachine'});

}

sub search_infile {

        my $chain2search = shift(@_);
        my $server;
        my $vmachine;
        my $status;
        my $contador=0;
        my @matched;
        local $linea;
        my $data_file="/etc/nagios3/vm_inventory.txt";
        open(VMS, $data_file) || die("Could not open file!");
        my @raw_data=<VMS>;
        foreach $linea (@raw_data)
        {
                chomp($linea);
                ($server,$vmachine,$status)=split(/\,/,$linea);
                if ( $vmachine =~ /($chain2search)/i )
                {
                        $matched[$contador] = $linea;
                        $contador++;
                }
        }
        close(VMS);
        return(@matched);
}

sub print_results {
        #Cogemos los par#metros
    my ($uno)=@_;

    #desreferenciamos
    my @matriz=@$uno;
        # Definimos variables necesarias
        local $counter = 0;
        local $style;
        local $linea;

        # Pintamos la primera la cabecera de la tabla
        print '<table border="1" class="status">';
        print "<tbody>";
        print "         <tr>";
        print '                         <th class="status">Servidor</th><th class="status">Virtual Machine</th><th class="status">Status</th>';
        print "         </tr>";

        foreach $linea (@matriz)
        {
                chomp($linea);
                ($server,$vmachine,$status)=split(/\,/,$linea);
                if ($counter == 0) {
                        $style = "statusEven";
                        $counter = 1;
                } else {
                        $style = "statusOdd";
                        $counter = 0;
                }
                 # Ahora que ya tenemos el estilo, pintamos la linea
                print "<tr class=$style>";
                print "         <td class=$style>$server</td>";
                print "         <td class=$style>$vmachine</td>";
                print "         <td class=$style>$status</td>";
                print "</tr>";
        }

        # Cerramos la tabla
        print "</tbody></table>";
}

sub end_html {
print "</pre></body></html>";
}

En la función search_infile se especifica el fichero fuente de los datos (en este caso /etc/nagios3/vm_inventory.txt).

tags: , , ,
Escrito en Monitorización por Ignacio Vazquez

Follow comments via the RSS Feed | Deja un comentario | Trackback URL

Leave Your Comment

 
desdelaconsola.es