Tuto : Comment automatiser votre supervision Centreon avec Salt

This post is also available in: Anglais

A l’heure actuelle, les infrastructures IT sont de plus en plus complexes et dynamiques. Avec les infrastructures dans le Cloud et les applications basées sur les conteneurs, votre infrastructure change rapidement et doit être à jour dans votre système de supervision.

La meilleure façon d’être à jour est d’utiliser l’automatisation avec un outil de gestion de configuration (configuration management). Dans cet article, nous allons nous appuyer sur l’outil Salt.

Buts

Quand un salt-minion s’enregistre à un salt-master, le serveur avec le salt-minion sera automatiquement ajouté dans la configuration de Centreon avec les bons modèles d’hôtes. Ensuite la configuration du collecteur sera rechargée.

Voici l’architecture de la plateforme à superviser :

salt-article-schema

Pré-requis

Pour ce tutoriel, vous avez besoin de bonnes connaissances des modèles hôtes et des groupes hôtes dans Centreon Web.

Les logiciels requis :

  • SaltStack
  • Centreon Web => 2.8.x
  • python-sdk-centreonapi => 0.0.1

Préparez votre Centreon Web

Vous devez avoir configuré des modèles d’hôtes et des groupes d’hôtes.

Pour ce tutoriel, je vais utiliser les modèles d’hôtes et groupes d’hôtes suivants :

Modèles d’hôtes venant des Plugin Packs

  • Linux SNMP (operatingsystems-linux-snmp) : la base pour superviser un serveur Linux en utilisant SNMP
  • Apache Server (applications-webservers-apache-serverstatus) : superviser un serveur Apache
  • MySQL DB (applications-databases-mysql) : superviser un serveur MySQL

Groupes d’hôtes

  • linux-servers : Liste des serveurs linux
  • frontend : Liste des serveurs HTTP
  • backend : Liste des serveurs de base de données

Configuration du salt-master

Ajout des informations liées à Centreon Web dans la configuration de salt-master

Je suggère d’utiliser un fichier supplémentaire pour cette configuration comme /etc/salt/master.d/centreon.conf.

Les options de configuration :

Nom de la clé Description
url L’url pour accéder à Centreon Web.
username Un utilisateur qui peut utiliser les APIs REST.
password Le mot de passe de l’utilisateur.
poller Le collecteur où les nouveaux hôtes seront supervisés.
hosttemplates La liste des modèles d’hôtes pour les nouveaux hôtes. Cette liste pourra être complétée par la configuration du minion.
hostgroups La liste des groupes d’hôtes à attacher aux nouveaux hôtes. Cette liste pourra être complétée par la configuration du minion.

Exemple :


centreon:
  url: http://centreon.domain.tld/centreon
  username: username
  password: password
  poller: Central
  hosttemplates:
    - operatingsystems-linux-snmp
  hostgroups:
    - linux-servers

Ecrire le salt-runner

Le salt-runner sera exécuté sur le salt-master. Il appellera l’API REST de Centreon Web au moment de l’enregistrement d’un nouveau salt-minion. Ce script est écrit en Python. Vous pouvez aller voir la documentation salt pour plus d’informations.

J’utilise le chemin /srv/runners pour mes scripts de runner. Ce chemin est configuré dans le fichier /etc/salt/master, ajouté a la fin du fichier :


runner_dirs: ['/srv/runners']

Ensuite, je crée le fichier /srv/runners/centreon.py qui contient le code suivant :


# -*- coding: utf-8 -*-

from __future__ import absolute_import

import json
import logging
import salt.client

# Import from python-sdk-centreonapi
from centreonapi.webservice import Webservice
from centreonapi.webservice.configuration.host import Host
from centreonapi.webservice.configuration.poller import Poller

# Initialize the default logger to write in salt-master log file
logger = logging.getLogger(__name__)

# Create a class to interact with object
class Centreon(object):
    def __init__(self):
        # Get configuration
        self.config = Centreon.getConfig()
        # Initialize the webservice connector
        Webservice.getInstance(
            self.config['url'],
            self.config['username'],
            self.config['password']
        )
        # Initialize Centreon objects
        self.host = Host()
        self.poller = Poller()
        # Initialize local salt client
        self.salt_client = salt.client.LocalClient()
        # Cache for salt grains
        self.grans_cache = None

    # Get the configuration from salt-master configuration file
    @staticmethod
    def getConfig():
        centreon_config = __opts__['centreon'] if 'centreon' in __opts__ else None

        if centreon_config is None:
            raise KeyError('Not configuration found')

        # Test required configuration parameters
        url = centreon_config.get('url', None)
        username = centreon_config.get('username', None)
        password = centreon_config.get('password', None)
        poller = centreon_config.get('poller', None)

        if url is None or username is None or password is None or poller is None:
            KeyError('Missing parameters')

        hosttemplates = centreon_config.get('hosttemplates', [])
        hostgroups = centreon_config.get('hostgroups', [])

        if len(hostgroups) == 0 or len(hosttemplates) == 0:
            KeyError('Missing parameters')

        return {
            'url': url,
            'username': username,
            'password': password,
            'poller': poller,
            'hosttemplates': hosttemplates,
            'hostgroups': hostgroups
        }

    # Test if the host exists in Centreon Web configuration
    def exists(self, minion_name):
        try:
            hosts = self.host.list()
        except Exception as exc:
            logger.error(exc)
            raise exc
        for info in hosts['result']:
            if info['name'] == minion_name:
                return True
        return False

    # Get the host ip address (use the first time when the host have multiple ip address)
    def get_minion_ip(self, minion_name):
        ip = self.salt_client.cmd(minion_name, 'network.ip_addrs')
        if minion_name not in ip or len(ip[minion_name]) == 0:
            raise KeyError('The minion has not ip !!! ...')
        return ip[minion_name][0]

    # Cache the grains centreon of the host to add
    def get_grains_centreon(self, minion_name):
        grains = self.salt_client.cmd(minion_name, 'grains.item', ['centreon'])
        if minion_name not in grains:
            self.grains_cache = {}
        self.grains_cache = grains[minion_name]['centreon']
        logger.error(json.dumps(self.grains_cache))

    # Generate the list of hostgroups for the host to add
    def get_hostgroups(self, minion_name):
        if self.grains_cache is None:
            self.get_grains_centreon(minion_name)
        if 'hostgroups' in self.grains_cache:
            hostgroups = list(set(self.config['hostgroups'] + self.grains_cache['hostgroups']))
        else:
            hostgroups = self.config['hostgroups']
        return '|'.join(hostgroups)

    # Generate the list of hosttemplates for the host to add
    def get_hosttemplates(self, minion_name):
        if self.grains_cache is None:
            self.get_grains_centreon(minion_name)
        if 'hosttemplates' in self.grains_cache:
            hosttemplates = list(set(self.config['hosttemplates'] + self.grains_cache['hosttemplates']))
        else:
            hosttemplates = self.config['hosttemplates']
        return '|'.join(hosttemplates)

# Function to register the runner on salt-master : test if salt-master configuration is valid
def __virtual__():
    try:
        Centreon.getConfig()
    except Exception as exc:
        logger.error(exc)
        return False
    return True

# The runner action to add host to Centreon Web
def register_instance(minion_name):
    try:
        # Create the Centreon object
        centreon = Centreon()
    except Exception as exc:
        logger.error(exc)
        raise exc
    # Test if the host exists in Centreon Web and add it if does not exist
    if not centreon.exists(minion_name):
        logger.info("Add host %s" % (minion_name))
        # Add the host
        host.add(
            minion_name,
            minion_name,
            centreon.get_minion_ip(minion_name),
            centreon.get_hosttemplates(minion_name),
            centreon.config['poller'],
            centreon.get_hostgroups(minion_name)
        )
        # Apply the host templates for create associate services
        host.applytpl(minion_name)
        # Apply Centreon configuration and reload the engine
        poller.applycfg(config['poller'])

Configuration du salt-reactor

Le salt-reactor est le mécanisme qui exécute une action quand l’événement est lancé par Salt. Vous pouvez aller voir la documentation salt pour plus d’informations.

Je configure l’action d’ajout d’un hôte quand le salt-master reçoit l’événement qu’un salt-minion est démarré.

Dans le fichier /etc/salt/master, j’ajoute à la fin la configuration pour l’événement.


reactor:
  - 'salt/minion/*/start':
    - /etc/salt/master.d/reactor_monitoring.sls

salt/minion/*/start est l’événement qu’un salt-minion démarre et envoie les informations de démarrage au salt-master.

Le fichier /etc/salt/master.d/reactor_monitoring.sls contient la configuration pour appeler le runner.


minion_to_monitoring:
  runner.centreon.register_instance:
    - minion_name: {{ data['id'] }}

runner.centreon.register_instance définit le runner pour Centreon et exécute l’action register_instance.

data[‘id’] est le nom du minion.

Après la configuration du salt-master, je redémarre le service salt-master.


service salt-master restart

Configuration du salt-minion

Cette configuration doit être faite avant le démarrage du salt-minion, sinon l’hôte sera ajouté sans les informations supplémentaires.

J’ajoute quelques configurations pour Centreon avec les grains pour avoir une meilleure configuration de mon hôte. Je sauvegarde ces informations dans le fichier /etc/salt/minion.d/grains.conf.

La liste des informations de configuration :

Nom de la clé Description
hosttemplates Les modèles d’hôtes supplémentaires pour le nouvel hôte.
hostgroups Les groupes d’hôtes supplémentaires pour le nouvel hôte.

Exemple pour un hôte de type serveur web :


grains:
  centreon:
    hostgroups:
      - frontend
    hosttemplates:
      - applications-webservers-apache-serverstatus

Exemple pour un hôte de type serveur de base de données MySQL :


grains:
  centreon:
    hostgroups:
      - backend
    hosttemplates:
      - applications-databases-mysql

Après cette configuration, je démarre le service du minion.


service salt-minion start

Et c’est tout.

N’hésitez pas à commenter et ajouter vos améliorations.

Incoming search terms:

  • centreon pre requis
  • equipe it centreon

Leave a Reply