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

El inventario de HW/SW te ayuda a llevar un control del hardware existente y a mantener el control sobre el software instalado en todo momento. Checkmk ofrece Plugins ya preparados para muchos escenarios de uso básicos. Sin embargo, en muchos casos querrás obtener información más detallada sobre hardware y software específicos. Aquí es donde entran en juego los Plugins personalizados de inventario de HW/SW.

Para este artículo, daremos por hecho que ya tienes conocimientos básicos sobre la programación de check plugins basados en agentes. Por lo tanto, en los aspectos en los que el uso de la API de inventario no difiere significativamente del uso de la API de comprobación, las explicaciones de este artículo serán algo escuetas. No obstante, cuando sea necesario, señalaremos cualquier diferencia significativa con mayor claridad.

Tip

Ten en cuenta la diferencia entre los check plugins y los complementos de inventario. Los check plugins son adecuados principalmente para datos que cambian rápidamente, mientras que los complementos de inventario son adecuados para datos que rara vez cambian. En este artículo, utilizaremos un ejemplo sencillo con dispositivos USB para ilustrar este punto. Por ejemplo, si quieres asegurarte de que nadie realice una conexión con dispositivos USB que no estén en una lista blanca a ningún ordenador del sistema de monitorización, un check plugin será más adecuado.

1.1. La documentación de la API de check

La API de inventario forma parte de la API de comprobación. Para acceder a la documentación, sigue los mismos pasos que para los check plugins basados en agentes.

Puedes acceder a la documentación que se incluye con tu site de Checkmk. Para ello, ve a Help > Developer resources > Plug-in API references en la GUI de Checkmk. En la nueva ventana del navegador, selecciona «Agent based ("Check API") > Version 2» en la barra de navegación de la izquierda. Incluso si no tienes un site de Checkmk en funcionamiento, puedes ver una copia de la documentación de la API de Plugins en docs.checkmk.com/plugin-api.

2. Preparación

La configuración predeterminada de Checkmk es actualizar los datos de inventario solo una vez al día. Esto, por supuesto, entra en conflicto con la necesidad de que los resultados sean visibles rápidamente cuando pruebas tu propia programación. Por lo tanto, recomendamos dos medidas preparatorias para aumentar la velocidad sin incrementar significativamente la carga del sistema:

  1. No utilices el Plugin «mk_inventory», ya que genera una carga elevada en el host que proporciona los datos para el nuevo Plugin que se va a crear.

  2. Establece el intervalo de ejecución de la check activa para este host en uno o unos pocos minutos.

3. El plugin de agente

Si quieres añadir funcionalidad de inventario a un check plugin basado en agente, es posible que puedas usar una sección de agente escrita para tu check plugin. Para nuestro ejemplo, crea la tuya propia. La base para esto es el comando `lsusb`. Cuando se ejecuta sin parámetros, muestra una lista de todos los dispositivos USB conectados. Podría tener este aspecto:

OMD[mysite]:~$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 002: ID 0bda:0409 Realtek Semiconductor Corp. USB3.2 Hub
Bus 002 Device 003: ID 0bda:0409 Realtek Semiconductor Corp. USB3.2 Hub
Bus 002 Device 004: ID 0bda:8153 Realtek Semiconductor Corp. RTL8153 Gigabit Ethernet Adapter
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 002: ID 0c45:6a09 Microdia Integrated_Webcam_HD
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

La versión corta que se usa aquí en sus primeros campos muestra a qué bus y puerto está conectado un dispositivo. A esto le sigue —separado por dos puntos— primero el ID del fabricante y luego el ID del dispositivo. El resto de la línea contiene texto descriptivo.

3.1. El script resultante

Dado que Checkmk maneja bien la salida línea por línea, tres líneas son suficientes para el check plugin necesario:

/usr/lib/check_mk_agent/plugins/lsusb
#!/bin/bash
echo '<<<lsusb_demo>>>'
lsusb
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

No te olvides de hacer que el Plugin sea ejecutable:

root@linux# chmod 0755 /usr/lib/check_mk_agent/plugins/lsusb
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Si el host en el que estás probando el plugin de agente es una máquina virtual, o si no quieres estar quitando y haciendo conexiones continuamente, simplemente guarda el siguiente ejemplo en un archivo en el directorio spool. Los archivos spool se incluyen en la salida del agente y se transfieren con ella, así que asegúrate de que el archivo termine con un salto de línea.

/var/lib/check_mk_agent/spool/lsusb.txt
<<<lsusb_demo>>>
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 002: ID 0bda:0409 Realtek Semiconductor Corp. USB3.2 Hub
Bus 002 Device 003: ID 0bda:0409 Realtek Semiconductor Corp. USB3.2 Hub
Bus 002 Device 004: ID 0bda:8153 Realtek Semiconductor Corp. RTL8153 Gigabit Ethernet Adapter
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 002: ID 0c45:6a09 Microdia Integrated_Webcam_HD
Bus 003 Device 004: ID 8087:0032 Intel Corp. AX210 Bluetooth
Bus 003 Device 005: ID 0bda:5409 Realtek Semiconductor Corp. USB2.1 Hub
Bus 003 Device 006: ID 0bda:5409 Realtek Semiconductor Corp. USB2.1 Hub
Bus 003 Device 007: ID 0bda:1100 Realtek Semiconductor Corp. HID Device
Bus 003 Device 071: ID 046d:c093 Logitech, Inc. M500s Optical Mouse
Bus 003 Device 096: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 003 Device 108: ID 6964:0075 MT ID75 Rev
Bus 003 Device 109: ID 0c45:636b Microdia USB 2.0 Camera
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

A continuación, puedes simular la conexión y desconexión de dispositivos USB añadiendo o eliminando líneas del archivo de texto.

3.2. Probar el agente

Prueba la salida del agente localmente con el siguiente comando:

root@linux# cmk-agent-ctl dump | grep -A25 '^<<<lsusb'
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Dependiendo del número de dispositivos USB conectados (o del número de líneas del archivo spool), ahora deberías ver la salida de lsusb y unas cuantas líneas de la siguiente sección del agente. Asegúrate de que el salto de línea al final de la sección del agente sea correcto.

4. El plugin de inventario

Los plugins de inventario se encuentran en la estructura de directorios habitual, junto a los check plugins normales. Puedes guardar los plugins de inventario como archivos independientes; en ese caso, te recomendamos usar el prefijo inventory_. También puedes integrar los plugins de inventario en los mismos archivos que los check plugins; en ese caso, debes omitir el prefijo por completo. El método que elijas dependerá de la claridad y de la necesidad de compartir funciones.

Para crear un Plugin de inventario puro, debes crear un directorio adecuado:

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

4.1. Un Plugin básico

Ahora puedes crear un Plugin de inventario básico, que puedes editar con cualquier editor de texto:

~/local/lib/python3/cmk_addons/plugins/lsusb_demo/agent_based/inventory_lsusb_demo.py
#!/usr/bin/env python3

from cmk.agent_based.v2 import InventoryPlugin, Attributes

def inventory_lsusb_demo(section):
    yield Attributes(
        path = [ "hardware", "usb", "general" ],
        inventory_attributes = { "Max standard": "3.2" },
    )

inventory_plugin_lsusb_demo = InventoryPlugin(
    name = "lsusb_demo",
    inventory_function = inventory_lsusb_demo,
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

La estructura es similar a la de los check plugins. El complemento de inventario también importa desde el namespace cmk.agent_based.v2. Un objeto CheckPlugin instanciado se vincula a una función de comprobación específica que devuelve uno o más objetos Result a través de yield. Del mismo modo, un objeto InventoryPlugin instanciado se vincula a una función de inventario específica que devuelve un objeto Attributes a través de yield.

El Attributes devuelto por yield implementa la hoja mínima significativa de un árbol de inventario:

  • El path describe el nodo relevante en la jerarquía del árbol, en este caso Hardware > Usb > General.

  • Los pares clave-valor del objeto `inventory_attributes` se representan como una tabla clave-valor.

Primero, comprueba que el Plugin sea sintácticamente correcto y que se pueda iniciar durante el inventario:

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
OMD[mysite]:~$ cmk -vv --inventory myhost | grep lsusb_demo
<<<lsusb_demo>>> / Transition HostSectionParser -> HostSectionParser
  HostKey(hostname='myhost', source_type=<SourceType.HOST: 1>)  -> Add sections: ['check_mk', 'local', 'lsusb_demo', ...]
 lsusb_demo: ok
 lsusb_demo: skipped (no data)
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Si es así, actualiza la configuración del core de monitorización y, a continuación, reinicia tu site:

OMD[mysite]:~$ cmk -U
Generating configuration for core (type cmc)...
Starting full compilation for all hosts
 Creating global helper config...OK
 Creating cmc protobuf configuration...OK
OMD[mysite]:~$ omd restart
Stopping crontab...OK
Stopping dcd...killing 153645....OK
Stopping apache...killing 153387.................OK
Stopping cmc...killing 153300.....OK
Stopping ui-job-scheduler...killing 153285...OK
...
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Al consultar el inventario del host de prueba, ahora se ve —tan pronto como se haya realizado la siguiente check periódica— una nueva hoja en el árbol de inventario.

4.2. Escribir la función de análisis

Las secciones del agente que no tienen un separador especificado se convierten en una lista bidimensional de tokens utilizando el separador predeterminado (espacio) antes de pasarse a la función de inventario: Se crea una lista de tokens para cada línea. Cada una de estas listas es, a su vez, un elemento de una lista de líneas. Si se especifica un separador, este define el límite entre tokens. Esto facilita el procesamiento de datos en formato CSV, por ejemplo.

Una función de análisis como la de los check plugins basados en agentes no es absolutamente necesaria. Sin embargo, usar una función de análisis independiente puede tener algunas ventajas. Por ejemplo, aumenta la claridad y la extensibilidad. Y si se va a reutilizar un check plugin ya existente, ni siquiera hace falta plantearse la cuestión: Simplemente sigue usando la función de análisis existente.

En nuestro ejemplo, no importa dónde se realice la conexión de un dispositivo USB. Para el Plugin, hay que determinar los ID del fabricante y del dispositivo (sexto item de la lista) y la descripción (desde el séptimo item hasta el final de la lista).

Aunque en el sencillo ejemplo anterior la versión máxima de USB admitida simplemente se codificó de forma fija, te animamos a que pienses en cómo puedes determinar esto a medio plazo utilizando expresiones regulares a partir de la descripción. Para ello, se necesita la descripción completa, es decir, todo desde la séptima hasta la última palabra de la lista:

~/local/lib/python3/cmk_addons/plugins/lsusb_demo/agent_based/inventory_lsusb_demo.py
def parse_lsusb_demo(string_table):
    parsed = { "devices": [] }
    for line in string_table:
        vendor = line[5].split(":")[0]
        device = line[5].split(":")[1]
        description = ""
        for i in range(6, len(line)):
            description = description + " " + line[i]
        parsed["devices"].append({ "vendor": vendor, "device": device, "description": description })
    return parsed
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

4.3. Escribir la función de inventario

Aquí puedes tomarte un atajo: a diferencia de los check plugins basados en agente, la función de análisis no se integra creando un objeto `AgentSection`, sino que debe llamarse desde la propia función de inventario. Ya conoces el principio de «yield» para la transferencia continua de elementos desde los check plugins basados en agente:

~/local/lib/python3/cmk_addons/plugins/lsusb_demo/agent_based/inventory_lsusb_demo.py
def inventory_lsusb_demo(section):
    section = parse_lsusb_demo(section)
    yield Attributes(
        path = [ "hardware", "usb", "general" ],
        # FIXME: dynamically calculate from agent section
        inventory_attributes = { "Max standard": "3.2" },
    )
    for d in section["devices"]:
        yield TableRow(
            path = [ "hardware", "usb", "devices" ],
            key_columns = {
                "vendor": d["vendor"],
                "device": d["device"]
            },
            inventory_columns = {
                "description": d["description"]
            }
        )
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Aquí se devuelve un objeto de tipo TableRow por cada línea de la salida de lsusb. Este contiene tres columnas: el proveedor y el ID del dispositivo sirven juntos como claves. La tercera columna, que es puramente informativa, contiene la descripción.

Las columnas clave tienen la particularidad de que se utilizan para detectar cambios, lo que a su vez puede provocar un cambio de estado del servicio HW/SW Inventory en la monitorización. Además, las claves deben ser únicas. Por lo tanto, se ignoran las líneas adicionales con la misma combinación de ID de proveedor y de dispositivo.

Además de las columnas clave y de inventario, también puedes describir las entradas de la tabla con status_columns y análogos status_attributes, que representan el estado de un objeto. Los tipos de datos simples (int, float, str, bool o None) están disponibles para el valor del estado. Por ejemplo, si quieres crear una tabla que enumere qué conexión (Bus/Device) está ocupada, puedes usar key_columns (Bus y Device) y status_columns (aquí: bool).

4.4. El Plugin terminado

El Plugin terminado lo reúne todo. La clase TableRow también se importa aquí:

~/local/lib/python3/cmk_addons/plugins/lsusb_demo/agent_based/inventory_lsusb_demo.py
#!/usr/bin/env python3

from cmk.agent_based.v2 import InventoryPlugin, Attributes, TableRow

def parse_lsusb_demo(string_table):
    parsed = { "devices": [] }
    for line in string_table:
        vendor = line[5].split(":")[0]
        device = line[5].split(":")[1]
        description = ""
        for i in range(6, len(line)):
            description = description + " " + line[i]
        parsed["devices"].append({ "vendor": vendor, "device": device, "description": description })
    return parsed

def inventory_lsusb_demo(section):
    section = parse_lsusb_demo(section)
    yield Attributes(
        path = [ "hardware", "usb", "general" ],
        inventory_attributes = { "Plugin version": "0.1.0" },
    )
    for d in section["devices"]:
        yield TableRow(
            path = [ "hardware", "usb", "devices" ],
            key_columns = {
                "vendor": d["vendor"],
                "device": d["device"],
            },
            inventory_columns = {
                "description": d["description"],
            }
        )

inventory_plugin_lsusb_demo = InventoryPlugin(
    name = "lsusb_demo",
    inventory_function = inventory_lsusb_demo,
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

5. Conjuntos de reglas para el inventario

Dado que la API de inventario forma parte de la API de comprobación, la creación y aplicación de conjuntos de reglas es exactamente igual que en el desarrollo de check plugins normales. Por eso, aquí solo te mostraremos un ejemplo sencillo.

5.1. Definición de un conjunto de reglas

El resultado de lsusb incluye varias líneas para los hubs (hubs externos y raíz). Estos dispositivos, que no tienen funcionalidad propia, dificultan mantener una vista general.

Por lo tanto, los usuarios deberían poder decidir por sí mismos si se incluyen o no los concentradores. Deberían poder configurar este ajuste mediante una checkbox en una regla.

Para ello, crea la carpeta «rulesets» para la familia de Plugins:

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

Ahora crea el conjunto de reglas en esta carpeta:

~/local/lib/python3/cmk_addons/plugins/lsusb_demo/rulesets/ruleset_lsusb_demo_inventory.py
#!/usr/bin/env python3

from cmk.rulesets.v1 import Label, Title, Help
from cmk.rulesets.v1.form_specs import (
    BooleanChoice,
    DefaultValue,
    DictElement,
    Dictionary,
)
from cmk.rulesets.v1.rule_specs import (
    InventoryParameters,
    Topic
)
from cmk.rulesets.v1 import Label

def _parameter_form():
    return Dictionary(
        elements = {
            "hubs": DictElement(
                parameter_form = BooleanChoice(
                    title = Title("USB hubs"),
                    label = Label("Consider USB hubs in the inventory table"),
                    prefill = DefaultValue(True),
                ),
                required = True,
            ),
        }
    )

rule_spec_lsusb_demo_inventory = InventoryParameters(
    name = "lsusb_demo",
    title = Title("Lsusb inventory demo"),
    topic = Topic.GENERAL,
    parameter_form = _parameter_form,
)
Copiar el contenido del archivo al portapapeles
¡Se ha copiado correctamente el contenido del archivo al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Una vez que hayas guardado el script del conjunto de reglas, valídalo con cmk-validate-plugins y, a continuación, reinicia el site con omd restart. En este momento, puedes ignorar cualquier aviso de cmk-validate-plugins sobre conjuntos de reglas existentes pero sin vincular. La vinculación se realiza en la siguiente sección.

Ahora puedes ver y personalizar la regla en la GUI en Setup > Hosts > HW/SW inventory rules. Si conoces el nombre de una regla (aquí: Lsusb inventory demo), puedes escribirlo directamente en el campo de búsqueda. Con Add rule, puedes crear la regla que acabas de preparar y aplicarla como de costumbre a carpetas u hosts con las propiedades que hayas seleccionado.

5.2. Aplicar el conjunto de reglas

El conjunto de reglas aún no se ha vinculado. Para aplicarlo, añade dos named arguments más al crear la clase InventoryPlugin.

~/local/lib/python3/cmk_addons/plugins/lsusb_demo/agent_based/inventory_lsusb_demo.py
# ...

inventory_plugin_lsusb_demo = InventoryPlugin(
    name = "lsusb_demo",
    inventory_function = inventory_lsusb_demo,
    inventory_default_parameters = { "hubs": True },
    inventory_ruleset_name = "lsusb_demo",
)
Copiar el contenido del archivo al portapapeles
¡Se ha copiado correctamente el contenido del archivo al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Además, el diccionario de parámetros debe pasarse a la función de inventario como primer argumento. Aquí también añades una expresión regular para identificar qué descripciones de dispositivos terminan en «hub». Ten en cuenta que debes añadir otra línea import al principio del script para esto:

~/local/lib/python3/cmk_addons/plugins/lsusb_demo/agent_based/inventory_lsusb_demo.py
# ...

import re

# ...

def inventory_lsusb_demo(params, section):
    section = parse_lsusb_demo(section)
    yield Attributes(
        path = [ "hardware", "usb", "general" ],
        inventory_attributes = { "Plugin version": "0.1.0" },
    )
    h = re.compile('.*?hub$', re.IGNORECASE)
    for d in section["devices"]:
        if params['hubs'] or not h.match(d["description"]):
            yield TableRow(
                path = [ "hardware", "usb", "devices" ],
                key_columns = {
                    "vendor": d["vendor"],
                    "device": d["device"],
                },
                inventory_columns = {
                    "description": d["description"],
                }
            )
# ...
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

6. Opciones de ampliación

6.1. Suscribirse a varias secciones

En el ejemplo, hasta ahora has seguido el procedimiento estándar: Un complemento de inventario se suscribe a una sección de agente que tiene el mismo nombre que el complemento de inventario. Pero, ¿qué pasa si quieres usar secciones de agente existentes que ya están siendo evaluadas por un complemento de inventario existente? En este caso, hay una alta probabilidad de que ya exista un complemento de inventario que use el mismo nombre que la sección de agente. La siguiente salida ofrece una vista general de las secciones existentes:

OMD[mysite]:~$ cmk -vv --inventory myhost
Doing HW/SW Inventory on: myhost
myhost:
+ INVENTORIZING
+ FETCHING DATA
  Source: SourceInfo(hostname='myhost', ipaddress='127.0.0.1', ident='agent' ...)
...
+ EXECUTING INVENTORY PLUGINS
 mssql_instance: skipped (no data)
 mssql_instance: skipped (no data)
 azure_app_gateway: skipped (no data)
 azure_app_gateway: skipped (no data)
 redfish_firmware: skipped (no data)
 redfish_firmware: skipped (no data)
 redfish_firmware_hpe_ilo4: skipped (no data)
 redfish_firmware_hpe_ilo4: skipped (no data)
 robotmk: skipped (no data)
 robotmk: skipped (no data)
Copiar comando(s) al portapapeles
¡Comandos copiados correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

En este caso, y en los casos en los que un complemento de inventario deba evaluar varias secciones de agente, puedes especificar las secciones suscritas como una lista. Por ejemplo, supongamos que quieres evaluar dos secciones de agente que hacen referencia a items ficticios:

/var/lib/check_mk_agent/spool/fictional.txt
<<<zorg>>>
ZF1 23.0
<<<yoyodyne>>>
Gnomovision 42.1
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

En este caso, las secciones de agente suscritas deben especificarse explícitamente. El nombre del plugin de agente ya no tiene que coincidir con las secciones de agente:

~/local/lib/python3/cmk_addons/plugins/fictional/agent_based/fictional.py
inventory_plugin_lsusb_demo = InventoryPlugin(
    name = "fictional",
    sections = [ "yoyodyne", "zorg" ],
    inventory_function = inventory_fictional,
)
Copiar el contenido del archivo al portapapeles
¡Se ha copiado correctamente el contenido del archivo al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

La función de inventario recibe entonces las tablas de cadenas como variables basadas en el patrón section_sectionname:

~/local/lib/python3/cmk_addons/plugins/fictional/agent_based/fictional.py
def inventory_fictional(section_yoyodyne, section_zorg):
    # Do something with the two two-dimensional arrays...
Copiar el contenido del archivo al portapapeles
¡Se ha copiado correctamente el contenido del archivo al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

El Plugin completo, que incluye las versiones de Yoyodyne Gnomovision y Zorg ZF1 en el árbol de inventario, puede tener este aspecto:

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

from cmk.agent_based.v2 import InventoryPlugin, Attributes

def inventory_fictional(section_yoyodyne, section_zorg):
    yoyo = section_yoyodyne
    zorg = section_zorg
    yield Attributes(
        path = [ "software", "fictional", "example" ],
        inventory_attributes = { "Yoyodyne " + yoyo[0][0]: yoyo[0][1] },
    )
    yield Attributes(
        path = [ "hardware", "fictional", "example" ],
        inventory_attributes = { "Zorg " + zorg[0][0]: zorg[0][1] },
    )

inventory_plugin_lsusb_demo = InventoryPlugin(
    name = "fictional",
    sections = [ "yoyodyne", "zorg" ],
    inventory_function = inventory_fictional,
)
Copiar el contenido del archivo al portapapeles
¡Contenido del archivo copiado correctamente al portapapeles!
¡Se ha denegado el acceso de escritura al portapapeles!

Last modified: Thu, 05 Mar 2026 09:26:19 GMT via commit cb50dcaeb
En esta página