scripts/munin/scripts/link_plugins.py
Daniel STAN 4a225f1375 munin: s/dyson/munin-server/ (spec par bcfg2)
On s'autorise à lister les plugins à activer sur la base des groupes bcfg2
d'un serveur, au lieu de spécifier en dur le nom du serveur.
2014-03-18 18:49:29 +01:00

247 lines
7.5 KiB
Python
Executable file

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
#
# Liste les liens à créer pour les plugins munin.
#
# Utilise la liste de plugins classiques renvoyée par
# munin-node-configure, filtrée, et les plugins customisés Cr@ns
# configurés dans hosts_plugins.py
#
# Copyright © 2009 Nicolas Dandrimont <Nicolas.Dandrimont@crans.org>
#
# Licence: MIT
#
import optparse
import os
import shutil
import socket
import subprocess
import sys
import tempfile
from hosts_plugins import hosts_plugins, general_plugins
from gestion.config.services import services
# Plugins munin classiques à ignorer
IGNORE_PLUGINS = (
'apt_all',
'if_',
'if_err_',
'multips',
'nfs4_client',
'nfsd',
'nfsd4',
'exim_mailstats',
'port_',
'sensors_',
'squid_icp',
'tomcat_',
'vlan_',
)
if socket.gethostname() in services.get('iscsi', []):
IGNORE_PLUGINS += (
'diskstat',
'diskstats',
'diskstat_',
)
# Chemin d'accès aux plugins munin
MUNIN_PATH = "/usr/share/munin/plugins"
# Hacks crades
QUIRKS = []
if sys.version_info < (2, 5):
def any(genexpr):
"""Retourne True si quelque chose est vrai dans genexpr"""
for truc in genexpr:
if truc:
return True
return False
def register_quirk(f):
QUIRKS.append(f)
def get_munin_plugins():
"""Liste les plugins munin créés par le système
Retourne un dictionnaire dont la clé est le lien dans
/etc/munin/plugins, et la valeur le fichier à lier.
"""
# Dictionnaire de sortie
output = {}
# Crée un répertoire vide pour faire croire à Munin qu'on veut
# créer tous les liens...
tempdir = tempfile.mkdtemp()
# Demande à Munin quels plugins il lui semble bon nous faire
# utiliser. --families=auto,manual permet de récupérer plus de
# plugins (qu'il faut ensuite filtrer)
munin = subprocess.Popen(["/usr/sbin/munin-node-configure",
"--families=manual",
"--families=auto",
"--servicedir", tempdir,
"--shell"],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
munin_stdout, munin_stderr = munin.communicate()
# if munin.returncode != 0:
# raise RuntimeError, "munin-node-configure... Stderr:\n%s" % munin_stderr
munin_output_lines = munin_stdout.splitlines()
for line in munin_output_lines:
if line.startswith("ln -s"):
dst, src = line.split()[-2:]
if dst[0] == "'":
dst = dst[1:-1]
src = src[1:-1]
src = os.path.basename(src)
# filtrage
if not os.path.basename(dst) in IGNORE_PLUGINS:
output[src] = dst
os.rmdir(tempdir)
# Exécute les hacks sales sur la sortie
for quirk in QUIRKS:
quirk(output)
return output
def get_all_plugins():
"""Liste les liens de plugins munin à créer
Retourne un dictionnaire dont la clé est le lien dans
/etc/munin/plugins, et la valeur le fichier à lier.
"""
hostname = socket.gethostname()
result = get_munin_plugins()
custom_plugins = hosts_plugins.get(hostname, {})
for (group, hosts) in services.iteritems():
if hostname in hosts:
custom_plugins.update(hosts_plugins.get(group, {}))
custom_plugins.update(general_plugins)
for plugin, dest_file in custom_plugins.iteritems():
if dest_file.startswith('/'):
result[plugin] = dest_file
else:
result[plugin] = os.path.join('/usr/scripts/munin', dest_file)
return result
def list_plugins(plugins, directory):
"""Liste les plugins comme s'ils allaient être liés dans
directory"""
for name, path in sorted(plugins.items()):
print os.path.join(directory, name), '->', path
def link_plugins(plugins, directory):
"""Lie les plugins dans le répertoire directory"""
for name, path in plugins.iteritems():
try:
os.symlink(path, os.path.join(directory, name))
if options.verbose:
print "%s installé avec succès!" % name
except OSError:
print "Echec à l'installation de %s (déjà installé?)" % name
# Hack propre
def add_plugin(plugin):
"""Crée une fonction qui ajoute le plugin à la liste"""
# Les clôtures en Python, ça fait rêver...
def f(plugins, plugin=plugin):
plugins[plugin] = os.path.join(MUNIN_PATH, plugin)
return f
register_quirk(add_plugin("uptime")) # Coucou MoSaN
register_quirk(add_plugin("netstat"))
register_quirk(add_plugin("nfs_client"))
# Hacks sales
@register_quirk
def add_ifaces(plugins):
"""Ajoute les interfaces à la liste des plugins si munin n'a pas
trouvé d'interface (ou si elles ont été filtrées)"""
if not any(plugin.startswith('if_') for plugin in plugins):
# Liste les interfaces configurées sur le système
interfaces_file = None
interfaces = []
try:
interfaces_file = file('/etc/network/interfaces', 'r')
for line in interfaces_file:
line = line.split()
# Recherche d'une ligne type "iface eth0 inet static"
if line and line[0] == 'iface' and line[-1] == 'static':
interface_name = line[1]
# on dégage les interfaces sur vlan spéciaux et
# aliasées (leur nom contient ':' ou '.')
if not set('.:') & set(interface_name):
interfaces.append(interface_name)
finally:
if interfaces_file is not None:
interfaces_file.close()
for interface in interfaces:
plugins['if_%s' % interface] = os.path.join(MUNIN_PATH,'if_')
plugins['if_err_%s' % interface] = os.path.join(MUNIN_PATH, 'if_err_')
@register_quirk
def use_correct_postfix_mailstats(plugins):
"""Utilise un postfix_mailstats non buggué sur etch"""
if "postfix_mailstats" in plugins:
try:
debver_file = open('/etc/debian_version')
except IOError:
return
else:
debver = debver_file.read()
debver_file.close()
if debver.startswith('4'):
plugins["postfix_mailstats"] = "/usr/scripts/munin/postfix_mailstats"
if __name__ == "__main__":
parser = optparse.OptionParser()
parser.add_option('-d', '--directory',
help = 'Write plugin symlinks to DIR',
metavar = 'DIR',
default = '/etc/munin/plugins'
)
parser.add_option('-f', '--force',
action = 'store_true',
help = 'Remove destination directory'
)
parser.add_option('-p', '--pretend',
action = 'store_true',
help = 'Do not actually make links'
)
parser.add_option('-v', '--verbose',
action = 'store_true',
help = 'Increase verbosity'
)
(options, args) = parser.parse_args()
plugins = get_all_plugins()
if options.pretend:
list_plugins(plugins, options.directory)
else:
if options.force:
shutil.rmtree(options.directory)
os.mkdir(options.directory)
link_plugins(plugins, options.directory)