domingo, 17 de mayo de 2020

Instalacion Prometheus y Grafana en Raspberry

No tenia pensado escribir este blog pero despues de instalar Grafana tuve problemas para visualizar la pagina de login de grafana. Así que aprovecho para hacer un breve proceso guiado de la instalación.

Raspberry: v2
SO: Linux Raspberrypi 4.19.97
Kernel: Raspbian GNU/Linux 10
Imagen: 2020-02-13-raspbian-buster-lite.img
Prometheus: 2.7.1+ds
Grafana:


PROMETHEUS

Primeramente la instalación de prometheus, si no hacemos ningún cambio en la configuración, despues de correr el siguiente comando el servicio quedara disponible en el siguiente URL http://192.168.0.13:9090, se tomara la IP que tenga el Raspberry, el portal no solicitara ningún usuario ni contraseña.

sudo apt-get install prometheus

Las configuraciones se realizaran en el archivo de configuracion /etc/prometheus/prometheus.yml, cada cambio podemos verificar que nuestra configuración sea correcta antes de hacer el reinicio de prometheus con el comando:

sudo promtool check config prometheus.yml


GRAFANA

Para la instalación de grafana, también con el comando apt-get, el servicio deberá quedara disponible en la URL http://192.168.0.13:3000/login, sin embargo, es en este paso donde únicamente se visualizaba una pantalla blanca dentro de los navegadores desde donde trataba de ingresar.

Para dar solución, seguí la recomendación encontrada en [ https://community.grafana.com ] donde @bortzmeyer recomienda comentar una linea del archivo /usr/share/grafana/public/app/app.js, en la linea 54 se comenta ang-drag-drop como se muestra en la imagen.


Despues del cambio sera necesario reiniciar el servicio de grafana y listo, ya podemos visualizar la pantalla de login.


La clave por default es admin:admin, si por alguna razón llegamos a perderla la podríamos recuperar reasignándola con el comando:

grafana-cli --homepath /usr/share/grafana  admin reset-admin-password admin


Finalmente sera necesario conectar al datasource, para nuestro caso usaremos prometheus.




domingo, 21 de julio de 2019

Arrancando www.visitamorelia.com



Hace unos días me di tiempo para pensar sobre las cosas que me gustan, y debido a la añoranza que tengo sobre mi ciudad natal, Morelia, quise hacer una pagina turística sobre Morelia y de esta manera aun estando lejos de allá podría mantenerme conectado de alguna manera sobre lo que ocurre allá y al mismo tiempo hacerme el espacio para tener fotos. 

En www.visitamorelia.com quiero compartir para el visitante lugares culturales, lugares públicos, actividades que hacer para los vacacionistas o personas que quieran visitar la ciudad, lugares gastronómicos, restaurantes y lugares para comer, hoteles.

Para el contenido del día a día también hemos creado el espacio para un blog y colocar actividades relevantes del día a día que ocurren en la ciudad.

Definitivamente mi objetivo es convertir este sitio en una referencia de visitantes, viajeros y mochileros que gustan por viajar y conocer diferentes lugares, los que visitan Morelia pueden encontrar en la ciudad un lugar con mucha historia sobre México, arquitectura colonial, cuna de artesanías y el sentido tradicional del país.

Aunque el sitio aun está actualizándose cada semana, ya puedo invitarlos a visitarnos en www.visitamorelia.com y sobre todo en la ciudad de Morelia.


Catedral de Morelia | visitamorelia.com
Catedral de Morelia | visitamorelia.com

sábado, 20 de julio de 2019

50 años de la supuesta llegada a la Luna

20 de Julio de 1969 el hombre aluniza por primera vez, Neil Armstrong se convierte en el primer hombre en pisar la Luna... o al menos eso es lo que nos han contado.







A 50 años de distancia la pregunta sigue en el aire ¿Pudieron llegar los norteamericanos a la Luna? 

En un contexto de la carrera espacial donde Rusos y Norteamericanos compiten para conquistar el espacio y en la siguiente tabla se muestra la ventaja de que tenían los rusos sobre su competidor:
  • 1957: Sputnik, primer satelite artificial en el espacio (Rusia).
  • 1957: Perrita Laika, primer ser vivo en el espacio 😞 (Rusia).
  • 1958: Explorer 1, primer satelite norteamericano. 
  • 1959: E-1 (Luna 2), primer modulo en llegar a la luna y estrellandose en su superficie (Rusia).
  • 1960: Perritas Belka y Strelka, primeros seres vivos en ir a espacio y regresaron con vida (Rusia)
  • 1961: Yuri Gagarin, primer cosmonauta en el espacio y en orbita terrestre (Rusia).
  • 1961: Alan Shepard, primer norteamericano en hacer un viaje sub-orbital durante 15 minutos a una altura de 186km.
  • 1962, John Glenn, primer astronauta estadounidense en órbita terrestre.
  • 1963: Valentina Tereshkova, Primer Mujer en el espacio (Rusia).
  • 1965: Alexei Leonov, primer cosmonauta en hacer una caminata espacial (Rusia).
A pensar de las ventajas de los Rusos, fueron los Norteamericanos quienes llegaron por primera vez a la Luna, en donde no fallo no un cable, ni un tornillo, ni un circuito eléctrico, no fallo la comunicación, no fallo el lanzamiento, no fallaron los acoplamientos, no fallo la nave que protejio a los cosmonautas de la radiación espacial, no fallo el alunizaje, no fallo el despegue lunar ni los nuevos acoplamientos ni el regreso a casa, se atravesaron los anillos de Van Allen.

Además de eso, existen muchos dudas sobre las evidencias del viaje que se ha presentado al publico: fotos y videos. 

  • Luz y sombras: en varias fotos se detectan multiples sombras para los objetos. En nuestra experiencia en la tierra, se presentan multiples sombras cuando existen multiples objetos de luz.
  • Movimiento de la bandera: Con carencia de aire la bandera no tendria por que moverse.
  • Descenso de Armstrong del modulo: ¿Quien video grabo el descenso de Armstrong?
  • Huella formada: Una huella deberia formarse en presencia de agua.
  • Carencia de estrellas en las fotografias
  • Carencia de crater en el lugar donde alunizo el modulo.
  • Carencia de polvo en los pies del modulo. 
Previo al viaje se tuvieron problemas con las misiones Gemini y Apolo, además con el gasto publico invertido en la carrera espacial y algunos muertes, existía gran presión social en algunos sectores para ya no invertir en eso, con este antecedente ¿Podria la Nasa simplemente decir que no lograron llegar a la Luna despues de todo el gasto y todo el gasto de esfuerzo?


Uno de lo últimos cuestionamientos que se hacen es por que despues del programa Apollo, el hombre ya no volvió a la Luna.



viernes, 15 de junio de 2018

Flisol 2018 en Linux Cabal

El pasado 28 de Abril del 2018 se celebro en America Latina el Flisol, Festival de Instalación de Software Libre el evento donde simultaneamente se realizan instalaciones de Software Libre en diversas ciudades de America.

Las sedes del 2018 las podemos ver en [ Sedes Flisol en México ]
 
En la ciudad de Morelia se realizo en la UNAM Campus Morelia, me habría gustado acompañarlos pero no me fue posible, sin embargo, tuve oportunidad de asistir a la sede de Guadalajara organizada por Linux Cabal. Debo mencionar que en el 2016 también asistí a esta misma sede comparado con la de hace dos años me pareció que bajo la asistencia y la participación social pero eso no fue factor para afectar al evento.

Presencie dos muy buenas platicas, la primera de como usar Vim por Octavio Alvarez de Grupo de Usuarios Linux Tijuana donde observamos muchos secretos de este poderoso procesador de textos.

La segunda platica fue de Empresa Libre, un sistema de facturación electrónica basado en web para PyMEs desarrollado por Mauricio Baeza.




Nos vemos el proximo año en Flisol 2019.

jueves, 19 de abril de 2018

Balanceando con Citrix Netscaler

En este articulo mostrare como hacer una implementación rápida de un servicio TCP balanceado con Citrix Netscaler. Suponiendo que tenemos dos servidores con un servicio de Apache Tomcat cada uno y que ambos escuchan en el puerto 8080, requerimos lo siguiente:

  • 1 IP como IP virtual para publicar el servicio balanceado.
  • 2 IPs de los servidores a balancear.
  • puertos TCP a balancear.


El equipo utilizado en esta practica es
  • NS10.1: Build 120.13.nc
  • Citrix Netscaler MPX-8200

En la sección de "Load Balancing" tenemos la parametrizacion básica en los sub-menu de Servers, Services y Virtual Server. En el sub-menu de servers vamos a definir cada uno de los servidores que deseamos balancear es ahi donde vamos a capturar el hostname o alias, IP y algún comentario así como se muestra en la siguiente imagen. Para nuestra arquitectura básica propuesta es aquí donde definimos al host1 y host2 con sus respectivas IPs.


 En el sub-menu Services podemos definir el cada servicio que asociaremos a un servidor. Debemos ya tener documentado o planeado la siguiente informacion:
  • El nombre del servicio.
  • El protocolo a usar: TCP, UDP, DNS, HTTP, SSL, MSSQL, MYSQL, RDP, etc.
  • El puerto a usar.
  • El servidor al que asociaremos este servicio y que debimos definir en previamente.
  • Monitor, el cual es el mecanimos por el que verificaremos la salud del servicio.




Como complemento al servicio debemos asociar un monitor, el cual revisara la salud del servicio, existen monitores como validación por icmp, validación por conexión tcp, encabezados de http, encabezados por tcp, etc. Existe un listado ya definido y nosotros podemos definir nuevos monitores.

Finalmente en el sub-menu Virtual Servers, fijaremos una IP virtual para atender al servicio balanceado. Como en el caso de los servicios la información que debemos asignar es:

  • Nombre del servidor virtual.
  • Protocolo
  • El protocolo a usar: TCP, UDP, DNS, HTTP, SSL, MSSQL, MYSQL, RDP, etc.
  • El puerto a usar.
  • Debemos seleccionar los servicios que asignaremos a este Virtual Server.
  • Metodo de balanceo: Least Connection, Least Request, Least Response Time, Round Robin, etc.

De esta manera la consulta del servicio se realiza unicamente hacia la IP virtual.




viernes, 16 de marzo de 2018

Widgets en Centreon


En estos momentos me encuentro implementando una version estable de Centreon 2.7.13 por lo que la finalidad de este post es únicamente presentar la funcionalidad widgets en centreon.

Nos van a servir para mostrar rápidamente el monitoreo de recursos que puedan ser mas críticos y de rápido acceso, los elementos a colocar en el widget son parametrizables, muchas veces con patrones de búsqueda, ordenamientos, clasificados por hostgroup, etc. Entre los widgets que se pueden agregar están los siguientes:

  • Graph Monitoring: Mostrara las gráficas de algún recurso, nos da opción de parametrizar la frecuencia de actualización.
  • Host Monitoring: Muestra el monitorio de un host o conjunto de hosts dentro del widget
  • Hostgroup Monitoring: Muestra el monitoreo de un hostgroup definido previamente.
  • Service Monitoring: Muestra el monitoreo de un grupo de servicios.


Por definición un widget debe incrustarse en una vista, podemos tener varias vistas (o tabs)  en cada una de estas vistas colocar uno o mas widgets. En la siguientes dos imágenes podemos ver dos vistas: "Servicios en linea" y "Servicios para atención".

En la primera vista de servicios para atención hemos colocado dos widgets, el primero del tipo Service Monitoring donde vemos los servicios con status de Critical y Warning únicamente. El segundo widget podemos ver uno del tipo Host Monitoring.



En la segunda vista de servicios en linea hemos colocado un par de widgets del tipo Graph Monitoring donde mostramos el monitoreo del web request de un servidor supuestamente critico.



¿Cómo agregamos un nuevo widget?

En el Menu "Home" -> "Custom View" podemos ver la barra de control para la manipulacion de widgets, la barra es muy intitiva y hemos leido desde el principio seguro tendremos muy buena idea de lo como hacer estas definiciones.



Lo primero es definir un la vista, en nuestro caso definiremos una vista llamada "Vista test", durante este proceso de definición podemos iniciarla con 1, 2 y 3 columnas para colocar widgets y darle orden a nuestros elementos. Ya una vez definida la vista nos colocamos sobre ella y ahora si, agregamos el widget.






Para incrustar un nuevo widget primero debemos indicar de que tipo sera, con las imágenes mostradas anteriormente podemos darnos una idea de los resultados que podemos tener. Una vez agregado el componente podemos parametrizarlo con la barra superior derecha del widget, la llave mecánica indica modificar.






Una observación importante es que estos widgets no vienen activos inicialmente por lo que hay que cargarlos al centreon en el menu "Administration" -> "Extensions" -> "Widgets". Los circulos rojos indican que el widget esta activo mientras que el engrane indica que no esta activo y si lo necesitamos debemos activarlo dandole clic.



jueves, 16 de marzo de 2017

Comandos de Supervivencia en Windows Server

Debido a mi actual trabajo, en los últimos años he tenido mas acercamiento a Windows Server y definitivamente no fue tan fácil ya que te acostumbras a tus herramientas GNU que cuando te lo cambian es como volver a empezar casi desde cero.

Dicho lo anterior, les traigo el siguiente listado de comandos de supervivencia básica que he documentado en los últimos años para Windows Server 2003, 2018 y 2012 (No powershell).

Problemas con Remote Desktop

Cuando he tenido problemas para ingresar por remote desktop, algunas veces reiniciando el servicio de Remote Desktop o terminal services logramos volver a ingresar al servidor. A continuación muestro como el proceso su no se presenta ningún problema.

sc \\IP_ADDRS STOP TERMSERVICE
sc \\
IP_ADDRS START TERMSERVICE 

Si por alguna razón el servicio se queda en status de "STOPPING" al momento de detener el servicio aun podemos matar el proceso usando fuerza bruta, primero debemos conseguir el identificar del proceso, luego matar el proceso y despues iniciar el servicio.

sc \\
IP_ADDRS queryex termservice
taskkill /s
IP_ADDRS /u Administrator /PID
sc \\
IP_ADDRS START TERMSERVICE



Ahora supongamos que tenemos un servidor en otra ciudad a 300km de distancia y no podemos ingresar al sistema operativo por remote desktop, el servidor no tiene configurada o simplemente no tiene una interface de  administración como la iLO o el IMM y tampoco contamos con un ingeniero en sitio. Despues de agotar varias opciones solo queda intentar el reinicio remoto y espera que levanta bien todo el sistema operativo y escritorio remoto. Con el siguiente comando se nos muestra un cuadro de dialogo para reiniciar uno o varios servidores.


shutdown /i




Sesiones de usuarios y terminal services.
Por default windows server acepta dos usuarios simultáneos por remote desktop, si alguien quiere mas usuarios simultáneos debe comprar licenciamiento. En windows server 2003 muchas veces llegamos a tener problemas para ingresar ya que una sesion iniciada y no cerrada impide que alguien mas ingrese. La manera de ver que usuarios no cerraron bien su sesion y cerrarles la misma es con los comandos qwinsta y rwinsta.

qwinsta /server:IP_ADDRS

La tercer columna nos muestra el identificador de sesion, con este identificador podemos finalizar una sesion.

rwinsta /server:
IP_ADDRS 3




Puertos de red abiertos

En todo momento resulta útil conocer que puertos están abiertos en el sistema, pero resulta mas útil conocer que procesos abrieron cada puerto.

#Conexiones establecidas y el PID que lo atiende
netstat -oan

#Puertos abiertos en modo LISTENING
netstat -an | find /i "listening"


Depuración de espacio en disco

Aunque siempre es posible depurar usando herramientas como ccleaner y remover aplicaciones que ya no usamos, existen unos directorios asociados las actualizaciones y services packs del sistema operativo. Estos deben ejecutarse como administrador.

#Archivos viejos de Service pack anteriores ya no usados
Dism /online /cleanup-image /spsuperseded
#Archivos viejos de actualizaciones ya no usados.
Dism /online /Cleanup-Image /StartComponentCleanup       

Para el caso de que tengamos archivos muy viejos que ya no se usan podemos borrarlos, colocandonos en el directorio donde se encuentran todos esos archivos, ejecutamos el siguiente comando donde borrariamos todos los archivos con antigüedad mayor a 45 días. Esto resulta ideal para una aplicación que escribe logs diariamente.

forfiles /m *.* /d -45 /c "cmd /c del @file"


Windows Update, reinicio no programado

Si por alguna razón se nos quedaron los windows update encendidos configurados para actualizarse de manera automática, muy probablemente nos reiniciara el servidor sin darnos cuenta hasta afectar alguna plataforma de la empresa. La recomendación es controlar estas actualizaciones, permitiendo que se descarguen o no pero lo mas importante es que seamos nosotros quienes definamos el momento en que estas se realizan. Una manera de evitarlo, es decir, cancelar el reinicio automatico de windows server podemos dar de baja el servicio como se indica:

sc stop wuauserv


Información rapida de usuarios en dominio

Si queremos conseguir informacion mas rapida de un usuario de dominio sin ingresar al domain controller o sin tener instalado la aplicacion de Active Directory, podemos consultar de la siguiente manena

net user /DOMAIN USERNAME


Ligas simbólicas
Confieso que esto me sorprendió mucho, nunca pensé que en Windows se podría crear ligas simbólicas dentro de la misma unidad de disco o incluso hacia otro volumen. Esto puede resultar útil cuando el volumen no viene de una SAN y no se puede crecer. Una solución puede ser agregar mas disco local y con una liga simbólica escribir en el nuevo disco local añadido. Con el parametro /D definimos la liga simbólica y usamos rutas absolutas para el origen como el destino.


mklink /D c:\dell\logs e:\dell\logs


Uptime

Si queremos saber desde cuando esta corriendo un windows server podemos ejecutar el comando siguiente y ver la parte de "Statistics Since".

net stats server

jueves, 23 de febrero de 2017

Nuevo proyecto - Anuncios en Mexico - www.anunciosenmexico.com.mx

Hace unos días acabo de iniciar un nuevo proyecto, el cual consiste en un sitio de anuncios gratuitos. Dada la situación económica de México en los últimos años creo que un gran volumen de la población tiene necesidad de vender y buscar productos con precios atractivos.

Queda a su disposición el sitio:
www.anunciosenmexico.com.mx

martes, 9 de agosto de 2016

Primer prototipo LoadBalancer con IPtables

El siguiente script en bash es el primer prototipo de LoadBalancer para un servicio TCP en dos o mas servidores simultaneamente utilizando iptables.
#!/bin/bash
local_ip="10.10.50.81"

ip1="10.10.96.50"
ip2="10.10.50.106"
tcp_port="80"


#Se valida que los servicios esten disponibles
nmap $ip1 -p $tcp_port | grep -i open >> /dev/null
service1=$?
nmap $ip2 -p $tcp_port | grep -i open >> /dev/null
service2=$?
let status=$service1+$service2
echo "Valor: $status"
let remakerules=10

while [ 0 -eq 0 ]; do

        if [ "$remakerules" != "$status" ]; then
                # You need these system settings.
                echo 1 > /proc/sys/net/ipv4/ip_forward
                for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 1 > $f ; done

                # Clear iptables/netfilter settings.
                iptables -F
                iptables -X
                iptables -t nat -F
                iptables -t nat -X
                iptables -t filter -F
                iptables -t filter -X
                iptables -t mangle -F
                iptables -t mangle -X


                iptables -P INPUT ACCEPT
                iptables -P OUTPUT ACCEPT
                iptables -P FORWARD ACCEPT
                iptables -t nat -P PREROUTING ACCEPT
                iptables -t nat -P POSTROUTING ACCEPT

                if [ "$service1" == "0" -a "$service2" == "0" ]; then
                        #Los dos servicios estan disponibles
                        iptables -t nat -A PREROUTING -p tcp -d $local_ip --dport $tcp_port -m state --state NEW -m statistic --mode random --probability .5 -j DNAT --to $ip1:$tcp_port
                        iptables -t nat -A PREROUTING -p tcp -d $local_ip --dport $tcp_port -m state --state NEW -m statistic --mode random --probability .5 -j DNAT --to $ip2:$tcp_port
                else
                        if [ "$service2" == "0" ]; then
                                #Unicamente el servicio2 esta arriba
                                iptables -t nat -A PREROUTING -p tcp -d $local_ip --dport $tcp_port -m state --state NEW -m statistic --mode nth --every 1 --packet 0 -j DNAT --to $ip2:$tcp_port
                        else
                                if [ "$service1" == "0" ]; then
                                        #Unicamente el servicio1 esta arriba
                                        iptables -t nat -A PREROUTING -p tcp -d $local_ip --dport $tcp_port -m state --state NEW -m statistic --mode nth --every 1 --packet 0 -j DNAT --to $ip1:$tcp_port
                                else
                                        echo "CRITICAL: Los dos Servicios estan abajo"
                                fi
                        fi
                fi


                iptables -A INPUT -j ACCEPT
                iptables -A OUTPUT -j ACCEPT
                iptables -A FORWARD -j ACCEPT
                iptables -A INPUT -j LOG --log-prefix "iptables: " --log-level 4
                iptables -A OUTPUT -j LOG --log-prefix "iptables: " --log-level 4
                iptables -A FORWARD -j LOG --log-prefix "iptables: " --log-level 4

                iptables -t nat -A POSTROUTING  -j MASQUERADE
                echo "Cambio de reglas..."
        fi

        #sleep 1200
        sleep 1

        #Se valida que los servicios esten disponibles
        nmap $ip1 -p $tcp_port | grep -i open >> /dev/null
        service1=$?
        nmap $ip2 -p $tcp_port | grep -i open >> /dev/null
        service2=$?
        let remakerules=$status
        let status=$service1+$service2
        echo "Valor: $status"

done

domingo, 29 de mayo de 2016

Certificados SSL para Web Server

La instalación de certificados sobre un web server es muy sencilla. En este post vamos a mostrar como instalar un certificado en Apache Web Server.

En sintesis primeramente debemos escoger un proveedor de certificados digitales para hacer el proceso de compra con el, este proveedor requiere que le enviemos una solicitud conocido como archivo CSR, es muy importante generar este archivo CSR en el servidor donde vamos a instanciar el web server y que al mismo tiempo debe ser el mismo donde se colocara el certificado. Despues de que enviemos el CSR el proveedor nos enviara un archivo CRT, con este archivo podremos configurar el certificado.




Realizáremos paso a paso el proceso en el interprete de comandos de GNU/Linux, como buena practica recomiendo llamar al archivo igual que el FQDN a certificar, para nuestro caso vamos a suponer que nuestro objetivo es certificar a www.midominio.com.

Creamos una llave de seguridad de 2048 bits, se nos pedirá que ingresemos el passphrase. Desde luego es muy importante guardar el passphrase.
openssl genrsa -des3 -out www.midominio.com.key 2048

Creamos el archivo csr a partir de la llave que creamos anteriormente y con una vigencia de 365 dias. Se nos pedirá información del FQDN a certificar y datos de ubicación de la empresa que solicita el certificado.
openssl req -days 365 -new -key www.midominio.com.key -out www.midominio.com.csr

Ahora ya podemos enviarle el csr al proveedor para que el nos regrese el CRT, este crt debe incluir el certificado para el webserver y un certificado de autoridad (CA). Ya que tenemos todo, podemos configurar los certificados en la secciones de host virtuales en el FQDN que estamos configurando, se modificaran los siguientes parametros:
SSLCertificateFile: Archivo CRT con el certificado para el web server.
SSLCertificateKeyFile: Archivo llave
SSLCACertificateFile: Archivo CRT con el CA.

Despues de hacer estos cambios se reiniciara el web server y por cuestiones de seguridad, cada reinicio o inicialización del servicio pedirá la clave, por un lado es bueno que solo las personas autorizadas puedan reiniciar el servicio web, pero que pasa si el servidor completo se reinicia... el web server no arrancara por que se quedara esperando el passphrase. Existe una manera de evitar esto y es reemplazar la llave por otra que no requiera passphrase, eso se puede reaizar con el siguiente comando:

openssl genrsa -out www.midominio.com.key.nopass 2048

Finalmente solo reemplazamos en el parametro del Apache "SSLCertificateKeyFile" con valor www.midominio.com.key por www.midominio.com.key.nopass

viernes, 5 de febrero de 2016

Recuperando password de Administrator de iLO4 en servidor HP

Despues de algunos meses o incluso años, esto pensando en retomar el blog con nuevos proyectos y problemas del día a día.

Hace unos días me tope con la necesidad de actualizar el driver de la interface de red de un servidor HP que esta en otra ciudad diferente a la ciudad donde vivo. Dada esta necesidad había una situación que no me dejaba tranquilo ya que el servidor esta en otra ciudad ¿que pasa si no queda funcionando la interface de red? ¿Voy a tener que ir físicamente a actualizarlo?. La única opción para hacer esto es a traves de la Consola Remota de la iLO, pero tampoco tenia la clave y había que conseguirla de algún modo sin tener que viajar solo a eso.

La información del equipo es:
SO: Debian GNU/Linux 7.1
Kernel: 3.2.0-4-686-pae
Hp Server: ProLiant DL360p Gen8 (i
LO 4)

Paso 1. Agregar los repositorios de HPe a Debian para instalar HP Advanced Server Recovery Daemon, el cual nos permitira el acceso a la HP iLO.

sudo echo "deb http://downloads.linux.hpe.com/downloads/ManagementComponentPack/ubuntu precise current/non-free" >> /etc/apt/sources.list
sudo apt-get update
sudo apt-get install hponcfg
sudo apt-get install ams
sudo apt-get install hp-healt
Paso 2. Descargar "HP Lights-Out XML PERL Scripting Sample for Linux" al dia de hoy el archivo es linux-LOsamplescripts4.00.0.tgz, este archivo esta disponible en la URL http://h20564.www2.hpe.com/hpsc/swd/public/detail?swItemId=MTX_2e178c5435a742d5bbb60a3b0c

Ya en la linea de comandos con el archivo en el home, ejecutamos lo siguiente
mkdir linux-LOsamplescripts
mv linux-LOsamplescripts4.00.0.tgz linux-LOsamplescripts
cd linux-LOsamplescripts
tar -xvzf linux-LOsamplescripts4.00.0.tgz

Se modificara el archivo Administrator_reset_pw.xml, como se muestra a continuación:

   
      
         
            
         
      
   



En la etiqueta "PASSWORD" a su parametro value se le asigna la nueva contraseña para la iLO. y se ejecuta el siguiente comando

sudo hponcfg -f Administrator_reset_pw.xml -l log.txt > output.txt
Para el ejemplo, una vez realizado esto ya podemos ingresar a la iLO del servidor. Con las credenciales:
User: Administrator
Passwd: newpasswd


miércoles, 29 de agosto de 2012

Mi primer certificación LPIC

Hace unos días, la llegada de un paquete a mi casa me puso en gran medida emocionado, no me había buscado el espacio para compartirlo con el mundo, sin embargo, ahora les comento que me llego la certificación LPIC-1.

Después de aprobar los exámenes 101 y 102, espere un poco mas de seis semanas para recibir mi documento. Ustedes pueden leer mis comentarios preliminares para el proceso que seguí [ aquí ]. Los exámenes no son para nada fáciles, hay que estudiar mucho, son precisos (parámetros exactos, rutas absolutas, archivos de configuración, comandos, etc). Pero..., ¿Que fue lo que me llego?:


  • Certificación.
  • Tarjeta de Certificación (algo así como una cédula profesional en México).
  • Una revista Linux Magazine.
  • Certificacion adicional: Novell Certified Linux Administrator, la cual requiere un registro y esperar un tiempo adicional.

jueves, 19 de julio de 2012

Otrs stat from last week, last month, last everyday


Hace unos días había tenido la necesidad de automatizar el envió de reportes en OTRS (3.1.2), lo que buscábamos era enviar el reporte de las actividades realizadas en los últimos N días, por ejemplo enviar automáticamente cada domingo por la noche un reporte semanal de los tickets creados en la semana actual.

El problema: Las estadísticas con objetos dinámicos no permiten especificar un parámetro como "LastWeek", solo permite dos opciones
  • Definir un rango de fechas estéticamente.
  • Dejar a elección del usuario escoger la fecha en la interface web.

¿Que pasa con el script de generación de estadísticas?
El script otrs.GenerateStats.pl recibe algunos parámetros como el ID de la estadística, el directorio destino donde colocara el archivo, el formato en que entregara la estadística (csv, pdf). Incluso una opción "-p" que recibe valores para Format, GraphSize, StatID  y ExchangeAxis. Debo mencionar que esta parte tiene una documentación muy pobre.

Como la idea es automatizar el proceso, tenemos que pensar en cron job, pero cron implica otrs.GenerateStats.pl, y este ultimo no tiene el soporte que ocupamos, esperando que esta descripción sea clara ¿quien podrá ayudarnos?

La solución:  Construcción de un script traductor.

En la base de datos de OTRS, las estadísticas se almacenan en "xml_storage", cada generación de estadísticas consultara las fechas primeramente en un cache y luego en la tabla

select * from xml_storage where xml_key=29



xml_typexml_keyxml_content_keyxml_content_value
Stats29[0]{'otrs_stats'}[1]{'UseAsRestriction'}[1]{'TimeStop'} 2012-07-18 23:59:59
Stats29[0]{'otrs_stats'}[1]{'UseAsRestriction'}[1]{'TimeStart'} 2012-07-11 00:00:00


Es recomendable crear un usuario en mysql con acceso de select/update a nuestra tabla y nada mas, este para ser usado en nuestro script. Con esta información preliminar les presento el script resultante:
#!/bin/bash

################################################
# Martin Edmundo, [ Julio 2012 ]
# @martinedmundo
# www.elrincondemartin.org
# Funcion: Script de generacion de estadisticas
#          basado en los ultimos dias.
# Release: OTRS 3.1.2
################################################

#Definicion de variables usadas
OTRS_DIR=/opt/otrs
OTRS_BIN=$OTRS_DIR/bin
BODYMAIL=/usr/local/sbin/bodymail.txt

DBUSER='otrsstat'
DBPASSWD='xxxxxx'
DBNAME='otrs'
DBTABLE='xml_storage'

STATNUM='';
TARGETDIR=$HOME;
DAYSNUM='7';
FILENAME='';

FILENAMESTAT='';
PREFIXFILENAMESTAT='Estad';
datestart=''
datestop=''

function phelp {
        echo -e "Usage: $0 -n  -o  -d  | -h"
        echo -e "  -n Numero de estadistica."
        echo -e "  -o Directorio destino de la estadistica. [ Predeterminado: $HOME ]"
        echo -e "  -d Rango de fechas de los utimos dias hasta hoy. [ Predeterminado: 7 ]"
        echo -e "  -h Ayuda, este mensaje.\n"
}

function chdb {
        #Se define el rango de fechas para los ultimos DAYSNUM dias
        datestart=`date --date="-$DAYSNUM day" +"%F "`00:00:00;
        datestop=`date +"%F %H:%M:%S"`;

        #Limpiamos cache de estadisticas
        rm $OTRS_DIR/var/tmp/CacheFileStorable/XML/* 2> /dev/null

        #Actualizamos fechas de estadisticas
        mysql -u $DBUSER -p$DBPASSWD --database=$DBNAME --execute="UPDATE $DBTABLE SET xml_content_value='$datestart' WHERE xml_key=$STATNUM and xml_content_key LIKE '%TimeStart%'"
        mysql -u $DBUSER -p$DBPASSWD --database=$DBNAME --execute="UPDATE $DBTABLE SET xml_content_value='$datestop' WHERE xml_key=$STATNUM and xml_content_key LIKE '%TimeStop%'"
}

function sendmail_ {
        #Nos vamos al diretorio de los reportes
        cd $TARGETDIR

        #Se revisa los destinatarios de correo
        for mail in `cat $FILENAME`; do
                isComment=`echo "$mail" | cut -d "#" -f1`

                #Si no es un comentario, analizamos
                if [ -n "$isComment" ]; then
                        #Se requiere mejorar la expresion regular para correo
                        isMail=`echo "$mail" | grep ".*@.*"`

                        #Enviamos correo electronico
                        if [ "$?" = "0" ]; then
                                ( echo -e "Reporte de actividades correspondientes al siguiente periodo: \n
[ $datestart a $datestop ]"; uuencode $FILENAMESTAT Reporte_$STATNUM.pdf  ) | mail -s "Servicios update" $mail
                        else
                                echo "Formato de correo desconocido: $mail"
                        fi
                fi
        done
}

while getopts n:o:d:f:h OPT
do
        case $OPT in
                n) STATNUM="$OPTARG" ;;
                o) TARGETDIR="$OPTARG" ;;
                d) DAYSNUM="$OPTARG" ;;
                f) FILENAME="$OPTARG" ;;
                h)
                        phelp
                        exit 0
                ;;
                ?)
                        phelp
                        exit 1
                ;;
                esac
done

if [ -z "$STATNUM" ]; then
        echo "*** Ocurrio un error o hace falta el parametro -n"
        phelp
        exit 1;
fi

#Se actualiza la base de datos
chdb

#Se genera el reporte
rm $TARGETDIR/*.pdf 2> /dev/null
FILENAMESTAT=`$OTRS_BIN/otrs.GenerateStats.pl -n $STATNUM -o $TARGETDIR -f Print 2> /dev/null | grep -o "$PREFIXFILENAMESTAT.*pdf"`

#¿Quiere que se envie por correo?
if [ -n "$FILENAME" ]; then
        if [ -f $FILENAME ]; then
                sendmail_
        else
                echo "No existe el archivo $FILENAME"
                exit 1;
        fi
fi

exit 0;

Como lo usamos:
martinbarriga@monitoreo:/usr/local/sbin$ ./otrs.GenerateStats.sh -h
Usage: ./otrs.GenerateStats.sh -n  -o  -d  | -h
 -n Numero de estadística.
 -o Directorio destino de la estadistica. [ Predeterminado: /home/user ]
 -d Rango de fechas de los utimos dias hasta hoy. [ Predeterminado: 7 ]
 -h Ayuda, este mensaje.

lunes, 2 de julio de 2012

Resultados Elecciones 2012

Como parte de mi compromiso social con mi patria el pasado 1 de Julio fui a votar y el día 2 de Julio a verificar los resultados con los registrados por el PREP. Esto ultimo por que encontré algunas imágenes compartidas en las redes sociales donde se pone en evidencias supuestas anomalías en el proceso de contabilización.

Basado en esta información me decidí a tomar una muy pequeña muestra de mis distritos vecinos para validar la veracidad de los números mostrados en el PREP. No encontré ningún error, en mi pequeña muestra, les paso las imágenes para que uds. mismos las verifiquen en [ aqui ] y corresponden al estado de Michoacan:

Sección: 1148, Casilla contigua


Sección: 1150, Casilla básica



Sección: 1151, Casilla básica y contigua



Sección: 1152, Casilla básica y contigua



Sección: 1153, Casilla básica y contigua



Sección: 1154, Casilla básica


También revise la sección 1149 pero ya se habían robado los resultados, incluso de la 1148 tampoco estaba los resultados de la casilla básica, mi revisión la realice en la mañana.  Debo agregar que me interese por hacer esta tarea debido a las fotos que circulan en las redes sociales y las cuales no coinciden con los datos del PREP donde en el mejor de los casos se trata de errores de captura (para no pensar que existe malas intenciones en afectar un resultado en favor de algún candidato):

DISTRITO FEDERAL
Distrito 25 - IZTAPALAPA
Sección 2937


DISTRITO FEDERAL
Distrito 04 - IZTAPALAPA
Sección 2641
Nota: compartida por @joseluigarcia


NUEVO LEÓN
Distrito 07 - MONTERREY
Sección 1076


OAXACA
Distrito 11 - SANTIAGO PINOTEPA NACIONAL
Sección 2062
NOTA: Esta ya se ha corregido en PREP.


SAN LUIS POTOSÍ
Distrito 02 - SOLEDAD DE GRACIANO SANCHEZ
Sección 1257

TABASCO
Distrito 06 - CENTRO
Sección 0389
Nota: Se corrige el valor anterior de 11, pero ahora actualizan con 112

Si alguien tiene información de errores en la captura del PREP, por favor compartan.



sábado, 30 de junio de 2012

RRDTool Primeros pasos - Parte 1


Este sera la primera de dos entradas en mi blog donde hablare un poco RRDtool, una herramienta que apenas estoy conociendo, pero que me resulta mucho muy divertida. Hoy en día varios proyectos de software lo usan como centreon, mrtg, ipcop, cacti, etc.

En lo poco que he explorado a RRDtool puedo comentarles que me ha ayudado a graficar valores en 2D sobre una linea de tiempo, haciendo uso de archivos con una estructura muy parecida a una base de datos donde almacena muchos parámetros y valores.

Graficando.

Nuestro objetivo en esta entrada va a ser graficar los tiempos de respuesta ICMP hacia un servidor en Internet. Para comenzar a graficar se requiere el conjunto de RRDtool, esto lo hacemos en Debian instalando el siguiente paquete:
sudo apt-get install rrdtool

La información de las graficas se almacenan en archivos con el postfijo "rrd", el primer paso es definir y crear estos archivos. Lo que hace divertido graficar es que nuestras graficas únicamente estan limitadas por nuestra imaginación y dominio de gnu shell. Vamos entonces a definir nuestro archivo rrd para la latencia hacia un servidor de google:
user@localhost:~/rrd$ rrdtool create latency.rrd --step 60 DS:latency:GAUGE:300:0:100000000 RRA:AVERAGE:0.5:1:259200 RRA:AVERAGE:0.5:12:100946

El parámetro step, nos indica que tendremos representaciones lineales individuales cada 60 segundos, el DS:latency indica que nuestro DasaSource se llama "latency", el GAUGE indica que usaremos este Datasource para medir los valores que le pasaremos en el futuro. Después de esta definición, se crea el archivo "latency.rrd" y podemos ver la información de sus parámetros con:
user@localhost:~/rrd$ rrdtool info latency.rrd
filename = "latency.rrd"
rrd_version = "0003"
step = 60
last_update = 1341035342
header_size = 740
ds[latency].index = 0
ds[latency].type = "GAUGE"
ds[latency].minimal_heartbeat = 300
ds[latency].min = 0.0000000000e+00
ds[latency].max = 1.0000000000e+08
ds[latency].last_ds = "143"
ds[latency].value = 2.9254425200e+02
ds[latency].unknown_sec = 0
rra[0].cf = "AVERAGE"
rra[0].rows = 259200
rra[0].cur_row = 103763
rra[0].pdp_per_row = 1
rra[0].xff = 5.0000000000e-01
rra[0].cdp_prep[0].value = NaN
rra[0].cdp_prep[0].unknown_datapoints = 0
rra[1].cf = "AVERAGE"
rra[1].rows = 100946
rra[1].cur_row = 74902
rra[1].pdp_per_row = 12
rra[1].xff = 5.0000000000e-01
rra[1].cdp_prep[0].value = 1.4305392777e+02
rra[1].cdp_prep[0].unknown_datapoints = 0

Una vez que tenemos nuestra base de datos RRD, nos queda estar actualizandolo para estar alimentandolo de información. En la secuencia siguiente primeramente vemos como conseguir el tiempo de respuesta usando la salida del comando ping, después indicamos como se alimenta el archivo con un valor contante y finalmente indicamos como lo actualizamos con el tiempo de respuesta, el cual tiene que estar cambiando en canda instante del tiempo.
user@localhost:~/rrd$ ping -c 1 8.8.8.8 | grep -o time=[0-9]* | cut -d "=" -f2
145
user@localhost:~/rrd$ rrdtool update ~/rrd/latency.rrd N:100
user@localhost:~/rrd$ rrdtool update ~/rrd/latency.rrd N:`ping -c 1 8.8.8.8 | grep -o time=[0-9]* | cut -d "=" -f2`

Siendo mas prácticos podemos colocar esta ultima linea en nuestro cron par que se actualice cada minuto.
*/1 * * * * /usr/bin/rrdtool update ~/rrd/latency.rrd N:`ping -c 1 8.8.8.8 | egrep -o time=[0-9]* | cut -d "=" -f2`

Hasta aquí vamos a estar actualizando el archivo cada minuto. Lo ultimo que nos queda es conseguir graficas de estos datos que estamos pasando. Las graficas las podemos hacer basandonos en un periodo de tiempo, por ejemplo si quisieramos las ultimas 3 horas y colocarlo en el archivo latency.png:
user@localhost:~/rrd$ rrdtool graph latency.png --title="Latencia" --vertical-label "Time (ms)" --end now --start end-10800s DEF:time=latency.rrd:latency:AVERAGE  LINE1:time#ff0000:Tiempo
497x173
user@localhost:~/rrd$



Puede ser que solo queremos ver la ultima hora, podemos graficarlo así:
user@localhost:~/rrd$ rrdtool graph latency.png --title="Latencia" --vertical-label "Time (ms)" --end now --start end-3600s DEF:time=latency.rrd:latency:AVERAGE  LINE1:time#ff0000:Tiempo
497x173
user@localhost:~/rrd$



Finalmente podemos ver que es posible graficar muchas cosas con la ayuda de varios comandos. En la próxima entrada les mostrare como estoy graficando algunos de los recursos de mi notebook y graficas con un poco de mejor diseño.

miércoles, 30 de mayo de 2012

Enviar y recibir correo desde nuestro GNU Shell con fetchmail y ssmtp

En este ultimo par de días, me ha tocado realizar algunas pruebas de correo electrónico, por lo que creo que tengo un poco de información agrupada aquí que les puede servir para manejar básicamente un correo electrónico desde nuestro shell (en mi caso mis pruebas son con bash).

Para enviar correo electrónico usamos el protocolo smtp, por lo tanto requerimos un servidor que ofrezca este servicio. Por otro lado, en cuanto a la recepción de correo nos apoyamos de los servidores pop. Conocer un poco mas de estos detalles es importante a la hora de comenzar nuestro trabajo de configurar un cliente de correo cualquiera que este sea. En nuestra practica vamos a configurar una cuenta de Gmal. A continuación les dejo un muy breve listado con algunos servidores.


Propietario Servidor Protocolo Cifrado Puerto
Gmail imap.googlemail.com imap ssl 993
Gmail pop.googlemail.com pop3 ssl 995
Gmail smtp.googlemail.com smtp ssl 465
Yahoo imap.mail.yahoo.com imap ssl 993
Yahoo pop.mail.yahoo.com pop3 ssl 995
Yahoo smtp.mail.yahoo.com smtp ssl 465
Hotmail pop3.live.com pop3 ssl/tls 995
Hotmail smtp.live.com smtp starttls 587


1. Enviar correo
En el envió de correo vamos ocupar instalar un agente de envió: ssmtp. Es un paquete muy básico y simple: ssmtp. Primero hacemos la instalación y luego modificamos su archivo de configuración.

user@localhost:~$ sudo apt-get install ssmtp
user@localhost:~$ sudo vim /etc/ssmtp/ssmtp.conf


En la configuración tenemos que especificar correo electrónico, contraseña para identificarnos, servidor smtp, tipo de cifrado, etc. A continuación les muestro parcialmente mi archivo ssmtp.conf.

root=martingmail@gmail.com
mailhub=smtp.gmail.com:587
AuthUser=martingmail
AuthPass=xxxxxxxxxx
UseSTARTTLS=YES
FromLineOverride=YES
rewriteDomain=
hostname=martingmail@gmail.com


Una vez configurado los datos de la cuenta, asociamos el correo con una cuenta local de nuestro sistema en el archivo /etc/ssmtp/revaliases, eso lo hacemos colocando la siguiente linea "martin:martingmail@gmail.com:smtp.gmail.com:587".

Si nuestra configuracion y atutentificacion es correcta ya podemos enviar correos con mail command.

#Envio de correo, con redaccion interactiva
mail -s "Mi primer correo" miamigo@sudominio.org
#Envio de correo con redaccion desde el mismo shell
echo "Hola" | mail -s "Mi primer correo" miamigo@sudominio.org
cat miarchivo.txt | mail -s "Mi primer correo" miamigo@sudominio.org
#Enviar correo con archivo adjunto
uuencode ~/mifoto.png mifoto.png | mail -s "Mi foto" milindaamiga@sudominio.org
#Enviar correo con archivo adjunto y texto
( cat declaraciondeamor.txt ; uuencode ~/mifoto.png mifoto.png ) | mail -s "Mi foto" milindaamiga@sudominio.org


Para el caso donde adjuntamos archivos el comando uuencode lo encontramos en el paquete sharutils, por lo que tendríamos que instalarlo también.

2. Recibir correo
Fetchmail es un programa que nos ayuda a traer los nuestros correos de un mail server remoto, por lo tanto es el que no va a traer los correos de nuestro buzón gmail. El siguiente paso es instalar fechtmail y configurar su archivo:

user@localhost:~$ sudo apt-get install fetchmail
user@localhost:~$ sudo vim ~/fetchmailrc


El siguiente es mi archivo de configuración parcial (¿Por que parciales?, por que no puedo mostrar mis datos personales)

#Cada 600 segundos actualizar
set daemon 600
set logfile fetchmail.log
poll pop.googlemail.com proto POP3
user "martingmail@gmail.com" pass "xxxxxxxxx" is "martin"
ssl
mda "/usr/bin/procmail -f %F -d %T"


Ya configurado esto, podemos leer los correos con el mail command, y hacer las operaciones básicas que este nos ofrece, principalmente la redacción y respuesta de correos. El uso de comandos internos del mail command, no lo voy a tratar aquí ya que es un tema muy extenso y no lo domino ampliamente, por lo que en ese aspecto les tocara investigar.

viernes, 11 de mayo de 2012

OTRS y Nagios/Centreon

Como les había comentado antes, había estado trabajando un poco en OTRS para el control de servicios dentro de una unidad organizacional. Por simple curiosidad se me ocurrió agregar dos características al monitoreo para que se generen gráficas estadistas del los servicios que se realizan.

¿Por que construir un propio plugin y no usar los mecanismos que otrs nos ofrece para integrarse con Nagios? Primeramente por cuestiones de facilidad de implementación, la documentación de estos mecanismos no son muy claros (al menos para mi), sobre todo por que otrs ha cambiado entre versiones. La otra razón es por que los mecanismos de otrs tienen la limitante de trabajar únicamente en un entorno donde conviven en un mismo servidor Otrs/Nagios.

El script es muy básico, para este post, soporta  únicamente el monitoreo de tickets abiertos y tickets creados por día:

#!/bin/bash

dbHostname="127.0.0.1"
dbUser="otrsguest"
dbPasswd="qwerty"
dbName="otrs"
dbWhere=""

WARNING=10
CRITICAL=15
TYPE=""

# Plugin return codes
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

function report {
        val=`mysql -h $dbHostname -u $dbUser -p$dbPasswd --database=$dbName --execute="select count(*) as open from ticket $dbWhere" | awk 'BEGIN{FS="\n"; RS="\n\n";}{print $2}'`
        if [ "$val" -le "$WARNING"  ]; then
                echo "Tickets $TYPE: $val [ OK ] | value=$val"
                exit $STATE_OK
        else
                if [ "$val" -le "$CRITICAL" ]; then
                        echo "Tickets $TYPE: $val [ WARNING ] | value=$val"
                        exit $STATE_WARNING
                else
                        echo "Tickets $TYPE: $val [ CRITICAL ] | value=$val"
                        exit $STATE_CRITICAL
                fi
        fi
}

function phelp {
        echo -e "Usage: $0 -t  -w  -c  | -h"
        echo -e "  -t Tipo de tickets a consultar"
        echo -e "  -c Valor critico"
        echo -e "  -w Valor warning"
        echo -e "  -h Help, this message.\n"
}

while getopts t:w:c:h OPT
do
        case $OPT in
                t) TYPE="$OPTARG" ;;
                w) WARNING="$OPTARG" ;;
                c) CRITICAL="$OPTARG" ;;
                h)
                        phelp
                        exit $STATE_UNKNOWN
                ;;
        esac
done


if [ "$TYPE" = "abiertos" ]; then
        dbWhere="where ticket_state_id='4'"
        report
else
        if [ "$TYPE" = "creados" ]; then
                date=`date +"%Y-%m-%d"`
                dbWhere="where create_time like '$date%'"
                report
        else
                echo "Carecteristica a monitorear desconocida. Conocidas: abiertos, creados"
                exit $STATE_UNKNOWN
        fi
fi


La siguiente gráfica nos representa la actividad de tickets abiertos para los últimos dos días.
 La siguiente gráfica nos representa la actividad de tickets creados por día, en los últimos tres días.

lunes, 7 de mayo de 2012

Construcción de Plugin Nagios/Centreon para HP Printer

Hace unas horas termine un script en bash para monitorear los consumibles de unas impresoras HP, la idea de agregarlas a centreon es para darnos conocer en buen momento cuando uno de los consumibles se están por terminar así como un histórico (usando las graficas) de cuanto se esta consumiendo. A posteriori, este script se tendría que poder usar en cualquier impresora HP con SNMP activado, los modelos de impresoras que tenemos son las siguientes:
  • HP LaserJet 4700 Color
  • HP LaserJet 4600 Color
  • HP LaserJet 4250
Requerimientos del script:
  • awk
  • snmpwalk
  • A nivel de red, acceso al segmento de las impresoras.
  • bash
  • etc.
#!/bin/bash
# Martin Barriga 2012

# Default options
COMMUNITY="public"
HOSTNAME="127.0.0.1"
CONSUMMABLE="black"
WARNING=20
CRITICAL=10
SNMPVERSION=2c
SHEETCOUNT="0"
sheetcount=""

#used MIBs
MAINMIB="mib-2.43.11.1.1.6.1"
SHEETMIB="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1"

# Plugin return codes
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

# Option processing
function phelp {
  echo -e "Usage: $0 -H  -C  -v  -o  -w  -c   [ -l | -s ] | -h "
  echo -e "  -H IP Addres HP Printer"
  echo -e "  -C SNMP Community. Default 'public'"
  echo -e "  -v SNMP Version. Default '2c'"
  echo -e "  -o Color Tonner: black, cyan, magenta, yellow, transfer, fuser. Default 'black'"
  echo -e "  -w Warning Value. Default '80'"
  echo -e "  -c Critical Value. Default '90'"
  echo -e "  -l List consumible support."
  echo -e "  -s Print with sheet count available."
  echo -e "  -h Help, this message.\n"
}

function list {
        allinfo=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $MAINMIB`;
        echo "$allinfo" | ( while read line; do
                echo $line | cut -d "\"" -f2;
        done )
}

function withsheetcount {
        index=`echo "$1" | cut -d "." -f8`;
        count=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $SHEETMIB.$index | cut -d " " -f4`;
        sheetcount=", Sheet Available: $count";
}

while getopts H:C:v:o:w:c:slh OPT
do
  case $OPT in
    H) HOSTNAME="$OPTARG" ;;
    C) COMMUNITY="$OPTARG" ;;
    v) SNMPVERSION="$OPTARG" ;;
    o) CONSUMMABLE="$OPTARG" ;;
    w) WARNING=$OPTARG ;;
    c) CRITICAL=$OPTARG ;;
    s) SHEETCOUNT="1" ;;
    l)
       list
       exit $STATE_UNKNOWN
    ;;
    h)
       phelp
       exit $STATE_UNKNOWN
    ;;
    #V)
    #  print_version
    #  exit $STATE_UNKNOWN
    #  ;;
   esac
done

info=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $MAINMIB | grep -i $CONSUMMABLE`
if [ "$info" != "" ]; then
        name=`echo "$info" | cut -d "\"" -f 2`;
        mib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3`;
        newmib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3 | awk -F. -v OFS=. '{$6=8}1'`;
        size=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $newmib | cut -d " " -f4`;
        newmib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3 | awk -F. -v OFS=. '{$6=9}1'`;
        value=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $newmib | cut -d " " -f4`;
        let porcent=($value*100)/$size;

        #If sheet count is required
        if [ "$SHEETCOUNT" = "1" ]; then
                withsheetcount $mib
        fi

        if [ "$porcent" -le "$CRITICAL" ]; then
                echo "$name: Status: $value/$size $porcent% available [ CRITICAL ] | size=$size used=$value";
                exit $STATE_CRITICAL;
        else
                if [ "$porcent" -le "$WARNING" ]; then
                        echo "$name: Status: $value/$size $porcent% available [ WARNING ] | size=$size used=$value";
                        exit $STATE_WARNING;
                else
                        echo "$name: Status: $value/$size $porcent% available [ OK ] | size=$size used=$value";
                        exit $STATE_OK;
                fi
        fi
else
        echo "No se encuentra consumible $CONSUMMABLE en $HOSTNAME [ UNKNOW ]"
        exit $STATE_UNKNOWN
fi