Discovery SNMP

Discovery SNMP

Discovery SNMP

Tiempo de lectura: 6
SNMP (Simple Network Management Protocol) fué introducido en 1988 como un protocolo que permite monitorizar y también administrar equipos de red. Después de varias revisiones y versiones en las que se han introducido mejoras y modificaciones sigue siendo uno de los protocolos más usados. Si tenemos en cuenta que es un protocolo extendido entre la mayoría de fabricantes y dispositivos que expone información de estado y que puede ser consultada en cualquier momento, hace que SNMP sea en sí el sistema de facto de observabilidad de cualquier dispositivo hardware y  por lo tanto podremos consultar y almacenar (para posteriormente poder tratar) toda la información de ese dispositivo.

Desde DataDope utilizamos este protocolo para realizar discoveries sobre dispositivos de red y sus interfaces para poblar CMDB y que no se pueden descubrir por otros protocolos. Periódicamente se lanzan escaneos de red sobre las redes configuradas en CMDB, con todo ello somos capaces de descubrir aquellas IPs con el puerto UDP y cuyo servicio SNMP está activado y así poder realizar una ejecución sobre los dispositivos de manera más óptima. Una vez hemos realizado el discovery sobre los dispositivos, los datos serán enviados a CMDB Bridge, este componente se encarga de estructurar los datos obtenidos y generar las distintas relaciones para posteriormente ser enviados a CMDB API Gateway que será el componente encargado de almacenar los datos de manera correcta en la CMDB.

A lo largo del documento vamos a puntualizar en qué consiste el desarrollo realizado en el módulo de Ansible para SNMP, configuración y flujo de ejecución junto con ejemplos gráficos de los mismos.

Módulo de Ansible para SNMP

Se ha desarrollado un módulo específico para SNMP incluido en Ansible Collection de Datadope y que está publicado para la comunidad junto al trabajo realizado de OS Facts por los compañeros.

El módulo está compuesto por un “module” que ejecuta en cliente el agente SNMP atacando a las OIDs previamente templatizadas y un “action” que se ejecuta en servidor (local, no remoto) y realiza toda la parte del pre-procesado y post-procesado de los datos obtenidos a través de SNMP. Se aporta un “role” que gestiona los ficheros necesarios para la ejecución del módulo. Los ficheros son plantillas customizables para consultar las distintas OIDs de un dispositivo y ficheros a modo de “databases” que nos ayudan a categorizar y nutrir de información los dispositivos descubiertos.

SysObjectID

El proveedor asigna un OID identificativo único para un tipo de dispositivo gestionado por SNMP y que nos permite identificar el tipo, la marca y el modelo. Se ha generado un fichero YAML que nos permite categorizar los dispositivos por plantillas y nutrir su información a través de varias fuentes de datos que recopilan información sobre sysObjectId y que complementamos a medida que vamos descubriendo nuevos dispositivos desconocidos.

A primer nivel identificamos el tipo de plantilla que vamos a utilizar (de la que hablaremos más adelante, por debajo de cada plantilla tenemos un listado de las distintas marcas de dispositivos disponibles, por cada marca a su vez tenemos el listado de los tipos de dispositivos (Networking, Printer, Storage, etc.) para finalmente agrupar los distintos SysObjectIDs disponibles mediante un diccionario cuyo valor es el modelo del dispositivo asignado a su identificativo.

El módulo en su primera iteración recoge información del SysObjectID y la SysDescription, por defecto utiliza una plantilla genérica para obtener datos de sus interfaces, pero a partir de las dos OIDs mencionadas podemos categorizar los dispositivos en nuestro fichero “sysobject_ids.yaml” dentro del role de snmp_discovery y generar una plantilla especifica si fuera necesario.

Templates

Se ha diseñado un sistema de plantillas en formato YAML que nos permite consultar las distintas OIDs de una manera sencilla y aplicar post-procesados sobre los valores obtenidos. Soportamos consultas a objetos escalares (el resultado de la consulta solo puede ser uno) y consultas a objetos tabulares (define varias instancias de objetos relacionados que se agrupan en tablas MIB). Los objetos tabulares o tablas pueden estar relacionadas entre sí, esta relación generalmente se suele hacer a través del índice que nos permite agrupar los valores dentro de una misma tabla, este índice puede coincidir entre varias tablas o que el valor de una tabla sea el índice para relacionar con otra tabla. Esto nos permite agrupar valores para generar una salida customizada.

Los objetos escalares se definen por una key cuyo diccionario será su OID a consultar y un post-procesado si fuera necesario (no obligatorio). El nombre que definamos a la key, será el valor de la key en la salida.

*Definición en plantilla

*Salida Ansible Facts

Los objetos tabulares o tablas se definen por una key con un diccionario de claves: valor. En primer lugar especificamos que es de tipo lista (type: list), dependencias si es que son requeridas, omisión de información (omit: true) si es que esa tabla es dependiente de otra para nutrir su información y queremos omitir su salida, su OID (base) de la tabla a consultar y por último las “entries”.

Las entries (listado) pertenecen a cada campo que vamos a consultar dentro de la tabla a modo de columna en SQL, estas entradas se definen igual que los objetos escalares, pero podemos omitir su salida si el valor es referencial como un índice y solamente es necesario para generar dependencias. Como OID dentro de una entry definimos la terminación de su OID base de la tabla, aunque podemos definirla completa y se omitirá la OID base al generar la consulta (solamente para esa entrada). Como resultado obtenemos una key con un listado de diccionarios con los valores obtenidos.

*Definición en plantilla

*Salida Ansible Facts

Actualmente soportamos dos tipos de dependencias (dependencies) que son agrupaciones de datos en un mismo diccionario ya que hay una relación entre tablas a través de índices.

Dependencia de tipo “index”: Internamente las agrupaciones de valores dentro de una misma tabla está asociada a un índice en común, si definimos una tabla con dependencia a una anterior (previamente consultada) y cuyas agrupaciones de diccionarios tienen el mismo índice, haremos un merge de valores entre las dos tablas para aquella tabla que definimos la dependencia.

*Definición en plantilla

*Estructura interna separada en tablas

*Estructura interna merge en tabla_2

Dependencia de tipo “value”: Este tipo de dependencia se genera para aquellas tablas que internamente tienen un identificador distinto pero que dentro de cada elemento de la tabla podemos consultar un campo cuyo valor es el indice de la tabla anterior y que nos permite generar la dependencia (merge de tablas).

*Definición en plantilla

*Estructura interna separada en tablas

*Estructura interna merge en tabla_2

Por último, con todo lo detallado anteriormente y utilizando la plantilla de ejemplo, definidos objetos escalares y tabulares con distintas dependencias, obtenemos la siguiente salida de un dispositivo de red con sus IPs (ipAddrEntry) y nutrida con los datos de las tablas ifMIB e interfaces.

Carlos Marín
Ana Ramírez

Ana Ramírez

¿Te ha resultado interesante?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

SÍGUENOS

CATEGORÍAS

ÚLTIMAS ENTRADAS