jueves, 25 de enero de 2018

BASH - Función para revisar listado de IP con ping

Hace tiempo me tocaba administrar multiples servers RedHat5 en producción, los suficientes para exigir un delay minimo en un full deployment de clases, instrucciones o actualizaciones a las aplicaciones que alojaban.

Para realizarlo, se hacia mediante un Script en BASH que estaba centralizado en un backend que todos podian ver, y con el que se logueaban por llave públicas (Autenticacion SSH por llave publica RSA) .

Los siguientes problemas se generaban:
- Algunos servidores estaban fuera de linea o no estaban accesibles.
- No habia log o notificacion de los fallidos.
- Se perdía la posibilidad de hacer un redeploy o rollback en caso de error.

Se resuelven estos puntos, creando una función para verificación de conexión.
*Nota: Esto solo aplica para el caso de conectividad, actividades propias del deploy deben tener su propio fail-safe.

Con que vamos a trabajar:

  • Manipulación de STDOUT ( Pipes )
  • BASH ( Arreglos, Ciclos)
  • gAWK (Substring, FNR, var, print )  

La función trabajará con un arreglo que ya contiene las direcciones IP, pero por motivos de practica, vamos a llenarlo con un archivo de texto

Desarrollo de funciónes:
Esta función se puede colocar en cualquier parte del script que se necesite.
Se irá comentando el código ( # ) para que pueda hacerse un copiar y pegar.

[usermacizo@centos ~]# vim tuscript.sh
  ó
[usermacizo@centos ~]# nano tuscript.sh

#-- Inicio del codigo

#!/bin/bash
## Este es un carrier que porta mis saltos de linea cuando no puedo poner un \n normal, por ejemplo se ve en los read -p .

cr=$(echo $'\n.')
cr=${cr%.}

## Se inicializa cuentaIP que será la variable que se usará para guardar el conteo de las IP que se van a evaluar, ya sea que vengan de un archivo de texto, que sean ingresadas manualmente, o de un rango especifico (en este caso solo usaremos archivo de texto)

cuentaIP=0

##### Se carga el arreglo con direcciones IP desde archivo de texto #####

archivo="/home/usermacizo/listado_ip.txt"

 while read -r linea || [[ -n "$linea" ]]; 
      do
       cuentaIP=$(( $cuentaIP + 1 ))
       direcciones[cuentaIP]=$linea  
      done < "$archivo"

# -r evita que secuencias de escape se interpreten (\ contrapleca)
# || [[ -n $linea ]]  evita que la última línea se ignore ya que esta es un EOF y no termina con \n.


##### Función para revisar IP que están en línea #####

revisarOnline()
{

# estas son las vars que llevaran el conteo de los servidores en linea y offline.  
 CuentaOn=0
 CuentaOff=0

 echo "*** Verificando de Conexion de ***"

#Se empieza en 1 y no en cero por cuestiones de estetica al momento de enumerar el resultado, igualmente cuando se cargan las IP al arreglo se comienza desde 1.

for (( cC=1;cC<=$cuentaIP;cC++))
do
 if [ "${direcciones[cC]}" != "" ]
 then


#El truco para determinar si está en línea o no, se encuentra en la siguiente línea, que evaluará todos las direcciones IP en el arreglo, a continuación lo explico a detalle:
##  se le hace un ping a la IP actual del arreglo con los argumentos -c 1 (contar una sola vez) y -w 2 (esperar solo 2segs hasta timeout)
## enviamos por un pipe lo que estos nos arroja al gAWK ,  donde seleccionamos la segunda linea de las lineas con el FNR==2 (number of record) y le ordenamos que imprima el substring del primer caracter, de la columna 6 
# Hecho todo esto, si hay un Ping nos va a responder, algo así:
#         PING 192.168.7.1 (192.168.7.1) 56(84) bytes of data.
#        64 bytes from 192.168.7.1: icmp_seq=1 ttl=64 time=2.08 ms
# Por eso es que con el gAWK, extraemos de la segunda línea, y le columna #6 el valor, que sería "ttl", pero usado el substring, nos daría unicamente "t"

    esTTL=$(ping ${direcciones[cC]} -c 1 -w 2 | gawk '(FNR==2) {print substr($6,1,1)}')

    if [[ $esTTL == "t" ]]
    then
# se incrementa el contador online, y se mete al arreglo la direccion. 
     cuentaOn=$(( $cuentaOn + 1 ))
     servidoresOn[cuentaOn]=${direcciones[cC]}
    else
# se incrementa el contador offline, y se mete al arreglo la direccion.
     cuentaOff=$(( $cuentaOff + 1 ))
     servidoresOff[cuentaOff]=${direcciones[cC]}
    fi

  fi
done

# Impresión de los resultados en pantalla

echo "---------------------------"
echo "Cantidad Online: $cuentaOn "
echo "------ Listado -------"
printf '%s\n' "${servidoresOn[@]}"

echo "---------------------------"
echo "Cantidad Offline: $cuentaOff "
echo "------ Listado -------"
printf '%s\n' "${servidoresOff[@]}"

# Notar que para el listado de IP no se uso echo, sinto el printf, con un caracter de escape \n para cada nuevo elemento, esto para que no aparezca en una sola linea horizontal.

}

revisarOnline

#-- Final del codigo

No hay comentarios:

Publicar un comentario