Datadope Discovery Parte 2 – Generación de soporte para un nuevo software

Datadope Discovery Parte 2 – Generación de soporte para un nuevo software

Datadope Discovery Parte 2 – Generación de soporte para un nuevo software

Tiempo de lectura: 5

Introducción

Como ya exploramos en la parte 1 del blog, la colección de Ansible de Datadope Discovery ofrece un conjunto de herramientas que facilitan la extracción de información de servidores. Ahora, vamos a aprovechar dichas herramientas para añadir soporte a una nueva tipología de software (en este caso, telegraf).

Análisis previo

Antes de elaborar las tareas que permitan extraer la información de interés, es importante hacer un análisis previo. Por ejemplo, podemos ver en la lista de software soportado que telegraf tiene un soporte básico. Esto nos permite saber si está instalado en la máquina, pero no nos da ninguna información adicional mediante la ejecución de tareas específicas.

También podemos analizar una instancia de telegraf que se encuentre en ejecución en una máquina para intentar obtener más información. Por ejemplo, ejecutando:

				
					ps aux | grep telegraf
				
			

Obtenemos:

				
					root     20827  0.9  1.9 1476720 75108 ?       Ssl  mar23 1071:48 /usr/bin/telegraf --config /etc/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d
				
			

Lo cual ya nos aporta cierta información relevante, como que telegraf proporciona su fichero de configuración con el parámetro –config o que, viendo el archivo de configuración ubicado en /etc/telegraf/telegraf.conf, la configuración de telegraf se encuentra en formato TOML.

Este análisis previo nos proporciona una lista de tareas que nos permitirá elaborar nuestra nueva extracción:

  • Ampliar la definición de telegraf para que ejecute nuestras tareas personalizadas.
  • Extraer el valor del parámetro –config si se encuentra en la cmdline del proceso detectado.
  • Almacenar la ruta del fichero de configuración.
  • Validar que se cuenta con acceso a dicho fichero.
  • Leer el fichero de configuración.
  • Almacenar el fichero de configuración.

Implementación

Ejecución de tareas personalizadas

Para ampliar la definición de telegraf, e incluir nuestras tareas personalizadas, es necesario actualizar la variable software_discovery__software_list sustituyendo la entrada de telegraf o reescribir la variable entera indicando únicamente la nueva entrada de telegraf, lo que más se adecue a nuestra situación. En nuestro caso, vamos a redefinir la entrada de telegraf dejándola exactamente igual a como viene originalmente, pero agregando una ruta al fichero donde vayamos a definir nuestras nuevas tareas personalizadas:

				
					- name: Telegraf
  cmd_regexp: '/usr/bin/telegraf'
  pkg_regexp: 'telegraf|iometrics-agent'
  process_type: parent
  return_children: false
  return_packages: true
  custom_tasks:
    - name: Include Telegraf specific plugins
      include_tasks:
        file: "/tmp/telegraf_tasks.yaml"

				
			

Extracción del parámetro –config

Realizar la extracción del parámetro –config requiere considerar varias posibilidades. Por un lado, el parámetro de configuración puede venir dado como –config o como -config-. Por otro lado, es importante considerar que el parámetro puede no estar definido y que la ejecución de la expresión regular podría ocasionar algún fallo.

La forma de realizar una implementación que cumpla con los requisitos anteriores es elaborar una tarea que tenga controlado el que pueda fallar y que intente extraer el parámetro de configuración y registrarlo, haciendo uso de un regex que soporte ambos parámetros de configuración.

Por otro lado, es importante considerar que el parámetro puede no estar definido y que la ejecución de la expresión regular podría ocasionar algún fallo.

Una posible mejora para el texto sería la siguiente implementación: ejecutar un regex que cumpla con las condiciones anteriores, acceder al primer grupo de extracción de regex y registrar el resultado en la variable _config_path de la instancia (__instance__._config_path) utilizando el módulo set_instance_fact, al mismo tiempo que se controlan los posibles errores que puedan surgir (por ejemplo, al acceder al grupo de un regex sin resultado) con el parámetro ignore_errors: yes de la tarea:

				
					- name: Get _config_path regex
  set_instance_fact:
    _config_path: "<< __instance__.process.cmdline | regex_search('-?-config ([\\S]+)', '\\1' ,ignorecase=True) | first  >>"
  ignore_errors: yes

				
			

NOTA

Es importante tener cuidado con incluir dobles escapados (\\) de cara al templating, pues puede inducir a cometer errores.

Almacenamiento del parámetro extraído

En caso de haber podido registrar la variable, es recomendable almacenarla en la clave file de la instancia. Se puede hacer fácilmente con la siguiente tarea, que se encargará además de separar el fichero de su directorio padre:

				
					- name: Save _config_path in files
  add_file_info:
    path: "<< __instance__._config_path | dirname >>"
    name: "<< __instance__._config_path | basename >>"
    type: 'config'
    subtype: 'config_file'
  when: __instance__._config_path is defined

				
			

NOTA

Hay que tener en cuenta que para usar las variables propias de Datadope Discovery, como __instance__, es necesario usar para el escapado del templating << y >>, en lugar de {{ y }}. En caso de querer usar directamente el templating de Ansible (al que delega el de Datadope Discovery), se puede utilizar directamente {{ y }} como se hace habitualmente.

Validación de permisos

El módulo stat nos permite verificar si tenemos acceso a un fichero simplemente ejecutando el módulo y registrando su resultado. Por ejemplo:

				
					- name: Check if _config_path is accessible
  stat:
    path: "<< __instance__._config_path >>"
  register: stat_result
  when: __instance__._config_path is defined

				
			

NOTA

Los resultados de parámetros register de las tareas no se almacenan como variables de la instancia, por lo que no es necesario eliminarlos cuando ya no sean necesarios.

Lectura de fichero de configuración

Una vez validado si tenemos acceso al fichero de configuración, podremos leer dicho fichero en caso de que el resultado haya sido positivo. Para realizar dicha lectura, podremos hacer uso del módulo read_remote_file:

				
					- name: Read config file
  read_remote_file:
    file_path: "<< __instance__._config_path >>"
  register: _config_file
  when:
    - stat_result is not failed
    - stat_result is not skipped

				
			

NOTA

Como la tarea anterior contaba con un when, es importante no solo validar si la tarea ha fallado, sino que también es necesario comprobar si la tarea ha sido omitida por no cumplirse el when, que provocaría un skipped: true.

Almacenamiento de fichero de configuración

Si la lectura del fichero de configuración no ha provocado ningún error, el resultado puede ser almacenado en la clave configuration de __instance__ haciendo uso del módulo set_instance_fact:

				
					- name: Set configuration
  set_instance_fact:
    configuration: "<< _config_file.content >>"
  when:
    - _config_file is not failed
    - _config_file is not skipped

				
			

NOTA

Al igual que en la anterior tarea, en esta también ha de tenerse en cuenta que _config_file puede ser o failed o skipped, en función de sí la tarea ha fallado o ha sido omitida a causa del when.

Extra: Limpieza de variables

Una vez que ya no vamos a hacer uso de variables temporales de la instancia, es recomendable eliminarlas para que dichas variables no sean incluidas en el resultado. En este caso, la única variable que habría que suprimir sería _config_path, tarea que podremos realizar usando el módulo del_instance_fact:

				
					- name: Remove temporary vars
  del_instance_fact:
    - _config_path

				
			

NOTA

Como ya hemos indicado anteriormente, los register no almacenan los resultados en la instancia, por lo que no es necesario eliminar dichos resultados manualmente.

Resultado

El resultado de implementar todos los puntos anteriores es un fichero de tareas personalizadas llamado telegraf_tasks.yaml como el siguiente:

				
					- name: Get _config_path regex
  set_instance_fact:
    _config_path: "<< __instance__.process.cmdline | regex_search('-?-config ([\\S]+)', '\\1' ,ignorecase=True) | first  >>"
  ignore_errors: yes

- name: Save _config_path in files
  add_file_info:
    path: "<< __instance__._config_path | dirname >>"
    name: "<< __instance__._config_path | basename >>"
    type: 'config'
    subtype: 'config_file'
  when: __instance__._config_path is defined

- name: Check if _config_path is accessible
  stat:
    path: "<< __instance__._config_path >>"
  register: stat_result
  when: __instance__._config_path is defined

- name: Read config file
  read_remote_file:
    file_path: "<< __instance__._config_path >>"
  register: _config_file
  when:
    - stat_result is not failed
    - stat_result is not skipped

- name: Set configuration
  set_instance_fact:
    configuration: "<< _config_file.content >>"
  when:
    - _config_file is not failed
    - _config_file is not skipped

- name: Remove temporary vars
  del_instance_fact:
    - _config_path

				
			

Se complementará con un playbook como el incluido a continuación, que incluye la reescritura de las definiciones de software y una referencia al fichero descrito anteriormente:

				
					---
- hosts: all
  name: Execute role software_discovery
  become: yes
  vars:
    software_discovery__software_list:
      - name: Telegraf
        cmd_regexp: '/usr/bin/telegraf'
        pkg_regexp: 'telegraf|iometrics-agent'
        process_type: parent
        return_children: false
        return_packages: true
        custom_tasks:
          - name: Include Telegraf specific plugins
            include_tasks:
              file: "/tmp/telegraf_tasks.yaml"
  roles:
    - role: datadope.discovery.software_discovery

				
			

Conclusión

En esta segunda parte del blog sobre Datadope Discovery hemos explicado, a modo de ejemplo, cómo usar alguna de las herramientas que ofrece la colección de Ansible de Datadope Discovery para extraer información de un software, en este caso Telegraf. El conjunto de herramientas que se ofrecen es muy amplio, pudiendo extraer casi cualquier información de un software que se esté ejecutando en una máquina.

Os animamos a que profundicéis en el uso de estas herramientas usando los recursos proporcionados y las uséis para extraer información de más tipos de software, además de todos los ya proporcionados directamente desde la collection. Y que podáis contribuir a la misma, de forma que, entre todos, podamos ir ampliando el catálogo de software que la collection es capaz de descubrir.

Recursos

Colección de Ansible Datadope Discovery:
https://github.com/datadope-io/ansible_collection_discovery

Documentación sobre la instalación de colecciones en ansible:
https://docs.ansible.com/ansible/latest/collections_guide/collections_installing.html

David Nieto Sanz
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