Checkmk
to checkmk.com
Important

This is a machine translation based on the English version of the article. It might or might not have already been subject to text preparation. If you find errors, please file a GitHub issue that states the paragraph that has to be improved.

1. Introducción

Los complementos de comprobación que funcionan con SNMP se desarrollan de forma similar a sus homólogos basados en agentes. La diferencia radica tanto en el proceso de detección de servicios como en la propia comprobación. Con los complementos de comprobación basados en agentes, el complemento del agente se utiliza para determinar qué datos se envían al sitio de Checkmk, y a menudo el prefiltrado (pero no la evaluación) ya tiene lugar en el host. En cambio, con SNMP debes especificar exactamente qué campos de datos necesitas y solicitarlos explícitamente. Con SNMP, estas áreas (ramas de un árbol) o campos de datos individuales (hojas) se identifican mediante OID (identificadores de objeto).

En teoría, sería posible una transferencia completa de todos los datos (utilizando el llamado «SNMP walk»), sin embargo, incluso con dispositivos rápidos esto lleva varios minutos, y con conmutadores complejos puede llevar más de una hora. Por lo tanto, esto ya supone un problema durante el descubrimiento y aún más durante la propia comprobación. En este sentido, Checkmk adopta un enfoque más específico. No obstante, los «SNMP walks» están disponibles en Checkmk para depurar comprobaciones existentes y desarrollar tus propias comprobaciones.

Si aún no tienes experiencia con SNMP, te recomendamos que leas el artículo sobre Monitorización vía SNMP.

1.1. ¿Qué funciona de forma diferente en SNMP?

En comparación con un complemento de comprobación para el agente de Checkmk, hay algunas características especiales que debes tener en cuenta con SNMP. Con un complemento de comprobación para SNMP, el descubrimiento de servicios se divide en dos fases.

En primer lugar, se utiliza la función de detección SNMP para detectar el dispositivo. Esto sirve para determinar si el complemento de comprobación es de interés para el dispositivo en cuestión y se lleva a cabo para cada dispositivo que se supervisa a través de SNMP. Para ello, se recuperan algunos OID —individuales, sin un recorrido SNMP—. El más importante de ellos es el OID de información sobre el dispositivo (sysDescr, OID: 1.3.6.1.2.1.1.1.0). Bajo este OID, cada dispositivo SNMP proporciona una descripción de sí mismo, por ejemplo, Flintstones, Inc. Fred Router rev23.

En el segundo paso, se recuperan los datos de monitorización necesarios para cada uno de estos candidatos mediante recorridos SNMP. A continuación, estos se resumen en una tabla y se proporcionan a la función de detección del complemento de comprobación en el argumento «section», que luego determina los elementos que se van a monitorizar. A continuación, se genera un servicio para cada uno de estos elementos.

Durante la comprobación ya se sabe si el complemento debe ejecutarse para el dispositivo, por lo que no es necesaria una nueva detección SNMP. Los datos de monitorización actuales necesarios para el complemento se recuperan aquí mediante recorridos SNMP.

Entonces, ¿qué tienes que hacer de forma diferente con un complemento de comprobación para SNMP en comparación con uno basado en agente?

  1. No necesitas un complemento de agente.

  2. Tú defines los OID necesarios para la detección SNMP y los textos que deben contener.

  3. Tú decides qué ramas y hojas del árbol SNMP hay que recuperar para la monitorización.

1.2. ¡No le tengas miedo a las MIB!

En esta breve introducción nos gustaría hablar de los famosos MIB de SNMP, sobre los que existen muchos prejuicios. La buena noticia: ¡Checkmk no necesita MIB! Sin embargo, pueden ser una ayuda importante a la hora de desarrollar un plugin de comprobación o solucionar problemas en plugins de comprobación existentes.

¿Qué son las MIB? MIB significa literalmente «Base de Información de Gestión», lo que contiene poco más información que la propia abreviatura. Básicamente, una MIB es un archivo de texto legible para humanos que describe las ramas y hojas de un árbol de datos SNMP.

Los OID pueden identificar ramas u hojas. La descripción de la rama contiene información sobre el sistema y el subsistema que proporciona dicha rama. Si un OID hace referencia a una hoja, la información del MIB incluye datos sobre el tipo de datos (cadena de caracteres, número de punto fijo, cadena hexadecimal, …​), el rango de valores y la representación. Por ejemplo, las temperaturas se pueden almacenar como un número de punto fijo con signo en la escala Celsius con una resolución de 0,1 °C o sin signo en pasos de 1,0 °C en la escala Kelvin.

Checkmk proporciona una serie de archivos MIB de libre acceso. Estos describen campos muy generales del árbol global de OID, pero no contienen ningún campo específico del fabricante. Por lo tanto, no son de gran ayuda para los complementos de comprobación desarrollados por ti mismo.

Así que intenta encontrar los archivos MIB relevantes para tu dispositivo específico en algún lugar de la página web del fabricante o incluso en la interfaz de gestión del dispositivo. Instala estos archivos en el sitio de Checkmk, en el directorio ~/local/share/snmp/mibs/. A continuación, puedes traducir los números OID a nombres utilizando recorridos SNMP y, de este modo, encontrar más rápidamente los datos de interés para la monitorización. Como ya se ha mencionado, los MIB bien mantenidos también contienen información interesante en sus comentarios. Puedes ver fácilmente un archivo MIB con un editor de texto o con el visor less.

2. Encontrar los OID correctos

El requisito previo fundamental para desarrollar un complemento de comprobación basado en SNMP es saber qué OID contienen la información relevante. Para el escenario de ejemplo presentado, hemos supuesto que acabas de poner en marcha un lote de routers del tipo Flintstones, Inc. Fred Router rev23. A menudo te encontrarás con este dispositivo ficticio en la documentación del fabricante y en los comentarios de la MIB. Sin embargo, te has olvidado de introducir la información de contacto y ubicación de algunos dispositivos. Un complemento de comprobación escrito por ti mismo para Checkmk debería ayudarte ahora a identificar estos dispositivos.

Tip

El complemento de ejemplo que hemos preparado está escrito de tal manera que puedes ejecutarlo con casi cualquier dispositivo compatible con SNMP. Solo tienes que adaptar la cadena de caracteres que se va a comparar. Si no tienes un dispositivo a mano, encontrarás varias opciones de simulación en el capítulo sobre resolución de problemas.

El primer paso es realizar un recorrido SNMP completo. Esto implica recuperar todos los datos disponibles a través de SNMP. Con Checkmk, esto se puede hacer muy fácilmente. Primero, incluye en la monitorización el dispositivo para el que quieres desarrollar un plugin de comprobación. Asegúrate de que se pueda monitorizar en las funciones básicas. Como mínimo, deben encontrarse los servicios SNMP Info y Uptime, y probablemente también al menos un Interface. Esto garantizará que el acceso SNMP funcione correctamente.

A continuación, pasa a la línea de comandos del sitio de Checkmk. Aquí puedes ejecutar un recorrido completo con el siguiente comando — en el siguiente ejemplo para el dispositivo con el nombre de host mydevice01. Te recomendamos que utilices también la opción -v (para obtener información detallada):

OMD[mysite]:~$ cmk -v --snmpwalk mydevice01
mydevice01:
Walk on ".1.3.6.1.2.1"...3898 variables.
Walk on ".1.3.6.1.4.1"...6025 variables.
Wrote fetched data to /omd/sites/mysite/var/check_mk/snmpwalks/mydevice01.
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Como ya se ha mencionado, un recorrido SNMP completo puede tardar minutos o incluso horas (aunque esto último es poco habitual), así que no te preocupes si tarda un rato en completarse. Los resultados del recorrido se guardan en el archivo ~/var/check_mk/snmpwalks/mydevice01. Se trata de un archivo de texto fácil de leer que comienza así:

~/var/check_mk/snmpwalks/mydevice01
.1.3.6.1.2.1.1.1.0 Flintstones, Inc. Fred Router rev23
.1.3.6.1.2.1.1.2.0 .1.3.6.1.4.1.424242.2.3
.1.3.6.1.2.1.1.3.0 546522419
.1.3.6.1.2.1.1.4.0 barney@example.com
.1.3.6.1.2.1.1.5.0 big-router-01
.1.3.6.1.2.1.1.6.0 Server room 23, Stonestreet 52, Munich
.1.3.6.1.2.1.1.7.0 72
.1.3.6.1.2.1.1.8.0 0

Cada línea contiene un OID y, a continuación, su valor. Encontrarás el más importante en la primera línea, concretamente sysDescr. Este debería ser un identificador único para un modelo de hardware.

La segunda línea también es interesante: Debajo de 1.3.6.1.4.1 hay ramas que los fabricantes de hardware pueden asignarse ellos mismos; aquí, Flintstones, Inc. tiene el ID de fabricante ficticio 424242. Debajo de esto, la empresa ha asignado 2 para routers y 3 para el mismo modelo. A continuación, encontrarás OID específicos del dispositivo dentro de esta rama.

Sin embargo, estos OID no son muy significativos. Si tienes instaladas las MIB correctas, puedes traducirlos a nombres en un segundo paso. Lo mejor es redirigir la salida del siguiente comando, que de otro modo se mostraría en el terminal, a un archivo:

OMD[mysite]:~$ cmk --snmptranslate mydevice01 > /tmp/translated
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Una vez que este archivo se ha etranslatedado, se lee como el recorrido original, pero además muestra el nombre del OID en cada línea después del «-->»:

/tmp/translated
.1.3.6.1.2.1.1.1.0 Flintstones, Inc. Fred Router rev23 --> SNMPv2-MIB::sysDescr.0
.1.3.6.1.2.1.1.2.0 .1.3.6.1.4.1.424242.2.3 --> SNMPv2-MIB::sysObjectID.0
.1.3.6.1.2.1.1.3.0 546522419 --> DISMAN-EVENT-MIB::sysUpTimeInstance
.1.3.6.1.2.1.1.4.0 barney@example.com --> SNMPv2-MIB::sysContact.0
.1.3.6.1.2.1.1.5.0 big-router-01 --> SNMPv2-MIB::sysName.0
.1.3.6.1.2.1.1.6.0 Server room 23, Stonestreet 52, Munich --> SNMPv2-MIB::sysLocation.0
.1.3.6.1.2.1.1.7.0 42 --> SNMPv2-MIB::sysServices.0
.1.3.6.1.2.1.1.8.0 27 --> SNMPv2-MIB::sysORLastChange.0

En la salida anterior, por ejemplo, el OID 1.3.6.1.2.1.1.4.0 tiene el valor barney@example.com y el nombre SNMPv2-MIB::sysContact.0. La información adicional que muestra los nombres de los OID proporciona datos importantes para identificar los OID de interés. Para el ejemplo presentado, los OID 1.3.6.1.2.1.1.4.0 a 1.3.6.1.2.1.1.6.0 son suficientes.

3. Crear un complemento de comprobación sencillo

Ya has completado el trabajo preparatorio: Ahora tienes una lista de los OID que quieres leer y evaluar. La tarea ahora es usar estas notas para enseñarle a Checkmk qué servicios se generan y cuándo deben ir a WARN o CRIT. La programación de un complemento de comprobación en Python que se usa para esto tiene muchos paralelismos con un complemento de comprobación basado en agentes. Como hay algunas sutilezas que hay que tener en cuenta, te mostraremos la estructura completa con todas las funciones que se utilizan.

3.1. Preparación del archivo

Para tus propios complementos de comprobación, encontrarás el directorio base ya preparado en la jerarquía local del directorio del sitio. Se trata de ~/local/lib/python3/cmk_addons/plugins/. El directorio pertenece al usuario del sitio y, por lo tanto, puedes escribir en él.

En este directorio, los complementos se organizan en familias de complementos, cuyos nombres de directorio se pueden elegir libremente. Por ejemplo, todos los complementos relacionados con dispositivos Cisco se almacenan en la carpeta cisco, o todos los complementos relacionados con routers del fabricante Flintstones, Inc. se almacenan en la carpeta flintstone.

En este subdirectorio <plug-in_family>, se crean a continuación otros subdirectorios con nombres predefinidos según sea necesario para las distintas API, p. ej., agent_based para la API Check de los complementos basados en agentes, incluidos los complementos de comprobación basados en SNMP.

Crea los dos subdirectorios para el nuevo complemento de comprobación y luego cambia a ellos para trabajar:

OMD[mysite]:~$ mkdir -p ~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based
OMD[mysite]:~$ cd ~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Crea aquí el archivo «flintstone_setup_check.py» para el complemento de comprobación. La convención es que el nombre del archivo refleje el nombre del complemento de comprobación tal y como se define cuando se crea el complemento de comprobación como una instancia de la clase «CheckPlugin». Es obligatorio que el archivo termine en «.py», ya que a partir de la versión 2.0.0 de Checkmk los complementos de comprobación son siempre módulos Python reales.

Un marco básico ejecutable (descargable en GitHub), que irás ampliando paso a paso a continuación, tiene este aspecto:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
#!/usr/bin/env python3

from cmk.agent_based.v2 import (
    CheckPlugin,
    CheckResult,
    startswith,
    DiscoveryResult,
    Result,
    Service,
    SimpleSNMPSection,
    SNMPTree,
    State,
    StringTable,
)

def parse_flintstone(string_table):
    return {}

def discover_flintstone(section):
    yield Service()

def check_flintstone(section):
    yield Result(state=State.OK, summary="Everything is fine")

snmp_section_flintstone_setup = SimpleSNMPSection(
    name = "flintstone_base_config",
    parse_function = parse_flintstone,
    detect = startswith(".1.3.6.1.2.1.1.1.0", "Flintstone"),
    fetch = SNMPTree(base='.1.3.6.1.2.1.1', oids=['4.0']),
)

check_plugin_flintstone_setup = CheckPlugin(
    name = "flintstone_setup_check",
    sections = [ "flintstone_base_config" ],
    service_name = "Flintstone setup check",
    discovery_function = discover_flintstone,
    check_function = check_flintstone,
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Primero tendrás que importar las funciones y clases necesarias para los complementos de comprobación desde los módulos de Python. No recomendamos usar `import *`, que se utiliza ocasionalmente, ya que consume memoria innecesariamente y dificulta saber qué espacios de nombres están realmente disponibles. Para nuestro ejemplo, solo importaremos lo que sea necesario o pueda resultar útil en el resto de este artículo:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
from cmk.agent_based.v2 import (
    CheckPlugin,
    CheckResult,
    startswith,
    DiscoveryResult,
    Result,
    Service,
    SimpleSNMPSection,
    SNMPTree,
    State,
    StringTable,
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

En comparación con el complemento de comprobación basado en agentes, destacan las nuevas funciones y clases específicas de SNMP: SNMPTree, SimpleSNMPSection y startswith. SNMPTree se explica por sí misma: es una clase para mostrar árboles SNMP. La clase SimpleSNMPSection se utiliza para crear una sección SNMP. La función startswith() compara el contenido de una hoja SNMP con una cadena de caracteres. Más adelante hablaremos de esto.

3.2. Creación de la sección SNMP

Una vez que hayas identificado los OID correctos, es el momento de desarrollar el complemento de comprobación. Al crear la sección SNMP, debes especificar dos cosas:

  1. Identificas los dispositivos en los que se ejecutará el complemento de comprobación.
    En el siguiente ejemplo, esto se hace con la función `startswith()`, que compara una cadena de caracteres con el inicio del contenido de una hoja OID. A continuación se muestran más opciones de asignación.

  2. Declaras qué ramas u hojas de OID se deben recuperar para la supervisión.
    Esto se hace con el constructor de la clase `SNMPTree`.

Amplía el archivo de ejemplo preparado para que el complemento solo se ejecute en un pequeño número de dispositivos, en este caso los modelos Flintstones, Inc. Fred Router. A continuación, se recuperan los OID de contacto, nombre del dispositivo y ubicación para estos dispositivos. Cada dispositivo proporciona estos tres OID. Si quieres probar el ejemplo con dispositivos reales compatibles con SNMP, basta con personalizar el nombre del modelo para que sea reconocido.

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
snmp_section_flintstone_setup_check = SimpleSNMPSection(
    name = "flintstone_base_config",
    parse_function = parse_flintstone,
    detect = startswith(
        ".1.3.6.1.2.1.1.1.0",
        "Flintstones, Inc. Fred Router",
    ),
    fetch = SNMPTree(
        base = '.1.3.6.1.2.1.1',
        oids = ['4.0', '5.0', '6.0'],
    ),
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

El ejemplo también contiene el parámetro «name», con el que se identifica la sección SNMP generada, y una función de análisis, de la que hablaremos más adelante.

La detección SNMP

Usa el parámetro `detect` para especificar las condiciones bajo las cuales debe ejecutarse la función de detección. En nuestro ejemplo, esto ocurre si el valor del OID `1.3.6.1.2.1.1.1.0` (es decir, el `sysDescr`) comienza con el texto `Flintstones, Inc. Fred Router` (sin distinción entre mayúsculas y minúsculas). Además de `startswith`, hay toda una gama de otras funciones posibles para la identificación. También hay una forma negada de cada una, que comienza con `not_`. Ten en cuenta que cada función debe especificarse por separado en la instrucción `import`.

Atributo Función Negación

equals(oid, "needle")

El valor del OID coincide con el texto «needle».

not_equals(oid, "needle")

contains(oid, "needle")

El valor del OID contiene el texto «needle» en algún punto.

not_contains(oid, "needle")

startswith(oid, "needle")

El valor del OID empieza por el texto «needle».

not_startswith(oid, "needle")

endswith(oid, "needle")

El valor del OID termina con el texto needle.

not_endswith(oid, "needle")

matches(oid, regex)

El valor del OID se corresponde con la expresión regular «regex», anclada antes y después, es decir, con una coincidencia exacta. Si solo necesitas una subcadena, simplemente añade «.*» al principio o al final.

not_matches(oid, regex).

exists(oid)

El OID está disponible en el dispositivo. Su valor puede estar vacío.

not_exists(oid)

También existe la opción de vincular varios atributos con all_of o any_of.

all_of Requiere varias comprobaciones correctas para un reconocimiento positivo. El siguiente ejemplo asigna tu complemento de comprobación a un dispositivo si el texto de sysDescr comienza por foo (o FOO o Foo) y el OID 1.3.6.1.2.1.1.2.0 contiene el texto .4.1.11863.:

detect = all_of(
    startswith(".1.3.6.1.2.1.1.1.0", "foo"),
    contains(".1.3.6.1.2.1.1.2.0", ".4.1.11863.")
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Por el contrario, any_of se cumple si solo se ha cumplido uno de los criterios. Aquí tienes un ejemplo en el que se permiten diferentes valores para el sysDescr:

detect = any_of(
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 3 system"),
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 4 system"),
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 4.1 system"),
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Por cierto: ¿estás familiarizado con las expresiones regulares? Si es así, probablemente podrías simplificar este ejemplo y arreglártelas con una sola línea:

detect = matches(".1.3.6.1.2.1.1.1.0", "FOO Version (3|4|4.1) .*")
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Y otra nota importante: Los OID que pasas a la detección SNMP para un plugin de comprobación se recuperan de todos los dispositivos que se supervisan a través de SNMP. Esta es la única forma en que Checkmk puede determinar a qué dispositivos se debe aplicar el plugin de comprobación.

Por lo tanto, debes tener mucho cuidado al utilizar OID específicos de cada fabricante. Intenta diseñar tu detección SNMP para dar prioridad a que se comprueben primero el sysDescr (1.3.6.1.2.1.1.1.0) y el sysObjectID (1.3.6.1.2.1.1.2.0).

Si aún necesitas un OID diferente para una identificación exacta, utiliza all_of() y procede de la siguiente manera:

  1. Comprueba primero si hay un sysDescr o un sysObjectID.

  2. En los argumentos adicionales, puedes restringir aún más el grupo de dispositivos para los que se ejecutará tu complemento.

detect = all_of(
    startswith(".1.3.6.1.2.1.1.1.0", "Flintstone"),   # first check sysDescr
    contains(".1.3.6.1.4.1.424242.2.3.37.0", "foo"),  # fetch vendor specific OID
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Esto funciona gracias al principio de evaluación perezosa: En cuanto falla una de las comprobaciones anteriores, no se realizan más comprobaciones. En el ejemplo anterior, el OID 1.3.6.1.4.1.424242.2.3.37.0 solo se recupera de los dispositivos que también tienen Flintstone en su sysDescr.

3.3. Escribir la función de análisis

Al igual que con los complementos basados en agentes, la función de análisis del complemento de comprobación basado en SNMP también tiene la tarea de convertir los datos del agente recibidos a un formato que se pueda procesar fácilmente y, sobre todo, con un alto rendimiento.

Aquí también recibes los datos como una lista. Sin embargo, hay algunas sutilezas que debes tener en cuenta, ya que hay diferencias entre consultar hojas o ramas. Como recordatorio: en nuestro ejemplo anterior, se solicitan hojas:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
    fetch = SNMPTree(
        base = '.1.3.6.1.2.1.1',
        oids = ['4.0', '5.0', '6.0'],
    )
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Si amplías temporalmente la función parse con la función print(), puedes mostrar los datos que Checkmk proporciona a partir de esta consulta al probar el complemento de comprobación:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def parse_flintstone(string_table):
    print(string_table)
    return {}
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Recibirás una lista anidada que contiene solo un elemento en su primer nivel, es decir, una lista de los valores recuperados:

[
    ['barney@example.com', 'big-router-01', 'Server room 23, Stonestreet 52, Munich']
]
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

El resultado es un poco diferente si recuperas ramas que contienen varias hojas. Supongamos que el router puede equiparse con un número variable de tarjetas de red cuyo nombre, estado de conexión y velocidad se pueden leer en 1.3.6.1.4.1.424242.2.3.23

    fetch = SNMPTree(
        base = '.1.3.6.1.4.1.424242.2.3.23',
        oids = [
            '6', # all names
            '7', # all states
            '8', # all speeds
        ],
    )
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

… entonces la lista bidimensional podría tener este aspecto:

[
    # Name, State, Speed
    ['net0', '1', '1000'],
    ['net1', '0', '100'],
    ['net2', '1', '10000'],
    ['net3', '1', '1000'],
]
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Todas las hojas disponibles bajo un OID se escriben en una columna de la tabla. Por lo tanto, debería quedar claro que, a efectos de mostrar los datos, solo se pueden consultar los OID coincidentes.

Tip

El último ejemplo mostrado para recuperar ramas de OID también forma parte de nuestro recorrido SNMP disponible en GitHub, que puedes usar para simulaciones.

Pero volvamos al ejemplo en el que se consultan las hojas OID de contacto, nombre del dispositivo y ubicación: La siguiente función de análisis simplemente copia cada elemento de la lista interna en un par clave-valor en el diccionario devuelto:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def parse_flintstone(string_table):
    # print(string_table)
    result = {}
    result["contact"] = string_table[0][0]
    result["name"] = string_table[0][1]
    result["location"] = string_table[0][2]
    # print(result)
    return result
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

El resultado de la función de análisis tendrá entonces este aspecto:

{
    'contact': 'barney@example.com',
    'name': 'big-router-01',
    'location': 'Server room 23, Stonestreet 52, Munich'
}
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

3.4. Creación del complemento de comprobación

Un complemento de comprobación se crea exactamente como se describe en los complementos de comprobación basados en agentes.

Dado que en la mayoría de los casos consultarás varias ramas SNMP y esto dará lugar a varias secciones SNMP, normalmente se requiere el parámetro `sections` con la lista de secciones que se van a evaluar:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
check_plugin_flintstone_setup = CheckPlugin(
    name = "flintstone_setup_check",
    sections = [ "flintstone_base_config" ],
    service_name = "Flintstone setup check",
    discovery_function = discover_flintstone,
    check_function = check_flintstone,
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

3.5. Escribir la función de descubrimiento

La función de detección también se corresponde con el ejemplo de los complementos de comprobación basados en agentes. Para los complementos de comprobación que solo generan un servicio por host, basta con un único `yield()`:

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def discover_flintstone(section):
    yield Service()
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

3.6. Escribir la función de comprobación

En el ejemplo, queremos comprobar si la información de contacto, el nombre del dispositivo y la ubicación están disponibles. Por lo tanto, basta con comprobar qué campos están vacíos en la función de comprobación y, en consecuencia, establecer el estado en «CRIT» (si falta algo) o en «OK» (si todo está disponible):

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def check_flintstone(section):
    missing = 0
    for e in ["contact", "name", "location"]:
        if section[e] == "":
            missing += 1
            yield Result(state=State.CRIT, summary=f"Missing information: {e}!")
    if missing > 0:
        yield Result(state=State.CRIT, summary=f"Missing fields: {missing}!")
    else:
        yield Result(state=State.OK, summary="All required information is available.")
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Una vez creada la función de comprobación, el complemento de comprobación estará listo para usar.

Hemos publicado este complemento de comprobación completo en GitHub.

3.7. Prueba y activación del complemento de comprobación

Las pruebas y la activación se realizan de la misma manera que para un complemento de comprobación basado en agente. Primero, asegúrate de que tu complemento sea sintácticamente correcto:

OMD[mysite]:~$ cmk-validate-plugins
Agent based plugins loading succeeded, Active checks loading succeeded, Special agents
loading succeeded, Rule specs loading succeeded, Rule specs forms creation succeeded,
Referenced rule specs validation succeeded, Loaded rule specs usage succeeded
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Lo siguiente es la detección de servicios del complemento:

OMD[mysite]:~$ cmk -vI --detect-plugins=flintstone_setup_check mydevice01
Discovering services and host labels on: mydevice01
mydevice01:
+ FETCHING DATA
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
Get piggybacked data
+ ANALYSE DISCOVERED HOST LABELS
SUCCESS - Found no new host labels
+ ANALYSE DISCOVERED SERVICES
+ EXECUTING DISCOVERY PLUGINS (1)
  1 flintstone_setup_check
SUCCESS - Found 1 services
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Como era de esperar, la detección del servicio se ha realizado correctamente. Ahora puedes probar la comprobación incluida en el complemento de comprobación:

OMD[mysite]:~$ cmk -v --detect-plugins=flintstone_setup_check mydevice01
+ FETCHING DATA
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
Get piggybacked data
Flintstone setup check All required information is available.
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
[snmp] Success, [piggyback] Success ...
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Después de reiniciar el núcleo de monitorización…

OMD[mysite]:~$ cmk -R
Generating configuration for core (type nagios)...
Precompiling host checks...OK
Validating Nagios configuration...OK
Restarting monitoring core...OK
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

… el nuevo servicio aparecerá entonces en la supervisión:

The new service created by the check plug-in in the monitoring.
Dado que todos los campos de las tres hojas SNMP están rellenados, el servicio esOK

4. Solución de problemas

Dado que la resolución de problemas en los complementos de comprobación basados en agentes se aplica básicamente también a los complementos de comprobación basados en SNMP, aquí solo trataremos los aspectos específicos de SNMP.

4.1. Opciones de simulación

Uso de recorridos SNMP guardados en Checkmk

En el artículo sobre la monitorización vía SNMP te mostramos en detalle cómo puedes crear recorridos SNMP desde la interfaz gráfica de usuario y cómo puedes utilizarlos para la simulación. Esto también permite desarrollar complementos de comprobación en sistemas de prueba que no pueden acceder a los hosts SNMP para los que estás desarrollando un complemento. En nuestro repositorio de GitHub encontrarás un ejemplo de un recorrido SNMP, que utilizamos en este artículo y que puedes usar para desarrollar y probar el complemento de comprobación.

El demonio SNMP ficticio

Si quieres asegurarte de que determinados OID cambien en función unos de otros, puede ser útil programar un demonio SNMP ficticio que proporcione datos consistentes. El módulo Python snmp-agent puede ser de ayuda a la hora de programar dicho demonio ficticio.

4.2. Hardware no cooperativo

Antes de que un dispositivo pueda supervisarse con un nuevo complemento de comprobación basado en SNMP, primero debe poder supervisarse a través de SNMP. Por lo tanto, puedes encontrar un resumen de los problemas conocidos con soluciones sugeridas en el artículo sobre Supervisión a través de SNMP.

5. Archivos y directorios

Ruta del archivo Descripción

~/local/lib/python3/cmk_addons/plugins/

Directorio base para guardar los archivos de los complementos.

~/local/lib/python3/cmk_addons/plugins/<plug-in_family>/agent_based/

Ubicación de almacenamiento para los complementos de comprobación escritos según la API de comprobación V2.

~/local/share/snmp/mibs/

Guarda aquí los archivos MIB de SNMP que se van a cargar automáticamente.


Last modified: Wed, 01 Apr 2026 14:25:53 GMT via commit 0903c1786
En esta página