zephir_gen_csv.py
1 |
#!/usr/bin/env python
|
---|---|
2 |
# -*- coding: UTF-8 -*-
|
3 |
###########################################################################
|
4 |
# Eole NG - 2016
|
5 |
# Copyright Pole de Competence Eole (Ministere Education - Academie Dijon)
|
6 |
# Licence CeCill cf /root/LicenceEole.txt
|
7 |
# eole@ac-dijon.fr
|
8 |
###########################################################################
|
9 |
import getpass, sys, codecs, time |
10 |
try:
|
11 |
# si disponible, on utilise la librairie modifiée du client Zéphir
|
12 |
# (n'affiche pas les mots de passe dans l'url en cas de traceback)
|
13 |
from zephir.eolerpclib import xmlrpclib |
14 |
except:
|
15 |
import xmlrpclib |
16 |
|
17 |
HELP = """
|
18 |
|
19 |
usage: zephir_gen_csv.py
|
20 |
|
21 |
Ce script permet de récupérer des informations sur les serveurs
|
22 |
|
23 |
Le résultat est stocké dans un fichier de type CSV nommé
|
24 |
zephir_infos.csv contenant les informations suivantes:
|
25 |
|
26 |
id_serveur|libelle_module|libellé_serveur|rne|perte_contact|liste agents en erreur
|
27 |
|
28 |
"""
|
29 |
##################################
|
30 |
# délimiteur pour le fichier 'CSV'
|
31 |
##################################
|
32 |
delimiter = u";"
|
33 |
|
34 |
def selection_serveurs(zephir_proxy): |
35 |
|
36 |
# exemple : utiliser un groupe existant
|
37 |
rc, liste_groupes = zephir_proxy.serveurs.get_groups() |
38 |
print "* groupes disponibles *" |
39 |
# affichage id et libelle des groupes
|
40 |
groupes = {} |
41 |
for groupe in liste_groupes: |
42 |
print groupe[0], " - ", groupe[1] |
43 |
# dictionnaire id_groupe -> libelle, liste des serveurs
|
44 |
groupes[groupe[0]] = (groupe[1], groupe[2]) |
45 |
print "" |
46 |
id_groupe = raw_input('choix du groupe (rien pour choisir un module) : ') |
47 |
if id_groupe != '': |
48 |
try:
|
49 |
id_groupe = int(id_groupe)
|
50 |
assert id_groupe in groupes.keys() |
51 |
except:
|
52 |
sys.exit('Erreur, groupe inconnu')
|
53 |
# récupération des serveurs de ce groupe
|
54 |
rc, groupe_serv = zephir_proxy.serveurs.groupe_reload(groupes[id_groupe][1])
|
55 |
print "\nServeurs du groupe %s : " % groupes[id_groupe][0] |
56 |
return groupe_serv
|
57 |
# récupération par type de module si pas de groupe demandé
|
58 |
# si besoin, on peut récupérer la liste des variantes avec zephir_proxy.modules.get_variantes()
|
59 |
rc, liste_modules = zephir_proxy.modules.get_module() |
60 |
print "* modules disponibles *" |
61 |
# affichage id et libelle des groupes
|
62 |
modules = {} |
63 |
for module in liste_modules: |
64 |
print module['id'], " - ", module['libelle'] |
65 |
# dictionnaire id_module -> libelle
|
66 |
modules[module['id']] = module['libelle'] |
67 |
print "" |
68 |
id_module = raw_input('choix du module : ') |
69 |
try:
|
70 |
id_module = int(id_module)
|
71 |
assert id_module in modules.keys() |
72 |
except:
|
73 |
sys.exit('Erreur, module invalide')
|
74 |
# critères de séléction des serveurs (d'autres critères sont possibles : rne, variante, libelle ...)
|
75 |
criteres_selection = {'module_actuel':id_module}
|
76 |
# récupération du groupe de serveurs correspondants
|
77 |
rc, groupe_serv = zephir_proxy.serveurs.groupe_serveur(criteres_selection) |
78 |
print "\nServeurs de type %s : " % modules[id_module] |
79 |
return groupe_serv
|
80 |
|
81 |
def get_infos(zephir_proxy, groupe_serv, alert_only=False): |
82 |
"""récupère les informations pour les serveurs demandés.
|
83 |
"""
|
84 |
if alert_only:
|
85 |
# si alert_only == True: on ne liste que les serveurs considérés en alerte
|
86 |
print "\nRécupération des serveurs en alerte ..." |
87 |
ret_code, serveurs_alerte = zephir_proxy.serveurs.get_alertes() |
88 |
# constitution d'une liste d'identifiant des serveurs en alerte. l'id est dans l'avant dernier champ
|
89 |
serveurs_alerte = [serv[-2] for serv in serveurs_alerte] |
90 |
else:
|
91 |
serveurs_alerte = [] |
92 |
|
93 |
# Récupération des informations sur les modules
|
94 |
module_infos = {} |
95 |
ret_code, modules = zephir_proxy.modules.get_module() |
96 |
for mod in modules: |
97 |
module_infos[mod['id']] = mod['libelle'] |
98 |
|
99 |
# création d'un dictionnaire {id_serveur:infos_serveur}
|
100 |
csv_data = [] |
101 |
infos_serveur = {} |
102 |
for serv in groupe_serv: |
103 |
if alert_only == False or serv['id'] in serveurs_alerte: |
104 |
# informations de base des serveurs (rne, module, libelle, ...)
|
105 |
# {'etat': -1, 'remarques': '', 'md5s': -1, 'tel': '', 'timeout': 0, 'module_initial': 69, 'materiel': '', 'variante': 69, 'installateur': '', 'module_actuel': 69, 'rne': '0000000A', 'date_install': '2016-02-13', 'no_alert': 0, 'params': "{'cle_ok': 0, 'maj_ok': [-2, ''], 'perso_ok': [-2, ''], 'config_ok': 1, 'new_key': (0, ''), 'dictpaqs_ok': [-2, ''], 'service_restart_ok': [-2, ''], 'dico_ok': 0, 'configure_ok': [-2, ''], 'reconfigure_ok': [-2, ''], 'uucp_cmd': 0, 'upgrade_ok': [-2, ''], 'migration_ok': -1, 'uucp_transfert': 0, 'lock_ok': [1, ''], 'md5s': [-1, ''], 'sauvegarde_ok': [-2, ''], 'query_maj': [-2, ''], 'reboot_ok': [-2, ''], 'timeout': [1, ''], 'agents': 1, 'last_log': 'journal vide'}", 'disque_dur': '', 'libelle': 'aca.eolebase-basique-2.4.2', 'timestamp': 1455632654.43577, 'ip_publique': '', 'maj': -1, 'id': 24, 'processeur': ''}
|
106 |
infos_serveur[serv['id']] = serv
|
107 |
|
108 |
####################################################################################################
|
109 |
# récupération des informations d'état (état des actions zéphir, données des agents de surveillance)
|
110 |
#
|
111 |
# Si ces appels surchargent Zéphir, utiliser une boucle sur la liste des identifiants et
|
112 |
# faire l'appel à get_status/agents_status pour chaque serveur. Il est possible de temporiser
|
113 |
# les appels en ajoutant un délai à chaque itération (time.sleep(2) pour 2 secondes d'attente)
|
114 |
#
|
115 |
# commenter les appels non utiles
|
116 |
# (dans la version fournie, agents_status et measure_infos en sont pas utilisés)
|
117 |
####################################################################################################
|
118 |
serv_ids = infos_serveur.keys() |
119 |
print "Récupération des informations d'état (actions, perte de contact, etc.) ..." |
120 |
ret_code, status_infos = zephir_proxy.serveurs.get_status(serv_ids) |
121 |
# >>> zephir_proxy.serveurs.get_status(24)
|
122 |
# [1, {'cle_ok': 1, 'maj_ok': [1, '2016-02-09 16:43:48', u'Mise \xe0 jour OK'], 'agents': 1, 'config_ok': 0, 'new_key': [0, ''], 'dictpaqs_ok': [1, ''], 'service_restart_ok': [-2, ''], 'dico_ok': 0, 'reboot_ok': [-2, ''], 'reconfigure_ok': [-2, ''], 'uucp_cmd': 0, 'upgrade_ok': [-2, ''], 'migration_ok': -1, 'uucp_transfert': 0, 'lock_ok': [1, ''], 'md5s': [0, u'contenu modifi\xe9 : zephir.eol'], 'sauvegarde_ok': [-2, ''], 'query_maj': [0, 'Tue Feb 9 18:03:21 2016'], 'configure_ok': [1, 'Tue Feb 9 17:03:21 2016', 'Configuration OK'], 'timeout': [1, ''], 'perso_ok': [-2, ''], 'last_log': 'Tue Feb 9 17:03:22 2016'}]
|
123 |
print "Récupération de l'état des agents de surveillance ..." |
124 |
ret_code, agents_infos = zephir_proxy.serveurs.agents_status(serv_ids) |
125 |
# >>> zephir_proxy.serveurs.agents_status(24)
|
126 |
# [1, {'web': ['Services distants', 1, '2016-02-09 16:58:13'], 'network': [u'Etat des interfaces r\xe9seau', 1, '2016-02-09 16:59:13'], 'ead_server': ['Etat du service EAD (Serveur)', 1, '2016-02-09 16:58:33'], 'diag': ['Diagnostic', 1, '2016-02-09 16:43:13'], 'diskspace': ['Occupation des disques', 1, '2016-02-09 16:58:13'], 'bilan': [u'Resum\xe9 mensuel', 1, '2016-02-09 16:59:13'], 'tcpservices': ['Etat des services', 1, '2016-02-09 16:59:13'], 'ead_web': ['Etat du service EAD Web', 1, '2016-02-09 16:58:33'], 'debsums': [u'\xc9tat des sommes MD5 de paquets', 1, '2016-02-09 16:58:13'], 'sentinelle': [u'Donn\xe9es suppl\xe9mentaires pour Sentinelle', 1, '2016-02-09 16:58:13'], 'sysinfo': [u'Informations syst\xe8me', 1, '2016-02-09 16:59:13'], 'netstats': [u'Statistiques r\xe9seau', 1, '2016-02-09 16:59:13'], 'RootDebsums': [u'\xc9tat des sommes MD5 de paquets pour root', 1, '2016-02-09 16:43:13'], 'ssh': ['Etat du service SSH', 1, '2016-02-09 16:58:33']}]
|
127 |
print "Récupération des données de surveillance ..." |
128 |
ret_code, str_agents_measures = zephir_proxy.serveurs.get_measure(serv_ids) |
129 |
# Mesures remontées par les agents. Seuls certains agents implémentent cette fonction (fonction développée pour Sentinelle)
|
130 |
# dictionnaire préfixé par identifiant de serveur et 'sérialisé' sous forme d'une chaîne
|
131 |
agents_measures = eval(str_agents_measures)
|
132 |
# exemple sur 2 serveurs :
|
133 |
# eval(zephir_proxy.serveurs.get_measure([770,379])[1])
|
134 |
# { 770: {'web': {'R\xc3\xa9solution': 'On', 'Proxy (admin.ldij-carnot.loc)': 'On', 'Acc\xc3\xa8s Distant': 'On', 'DNS distant : 10.21.10.1': 'On'}, 'netbios': {'status': 'On'}, 'http': {'status': 'On'}, 'ead_server': {'status': 'On'}, 'diskspace': {'/dev': (1, 491, 0, 491, 'devtmpfs'), '/boot': (6, 703, 36, 631, 'ext4'), '/var': (100, 930172, 882923, 0, 'ext4'), '/tmp': (2, 1876, 35, 1745, 'ext4'), '/': (26, 3284, 786, 2331, 'ext4')}, 'diag': {}, 'bilan': {}, 'tcpservices': {'http': ['On', 'Serveur web'], 'ead_server': ['On', 'EAD 2 (Serveur)'], 'ead_web': ['On', 'EAD 2 (Web)'], 'ssh': ['On', 'shell s\xc3\xa9curis\xc3\xa9 (SSH)'], 'smb': ['On', 'Serveur de fichiers (SMB)'], 'netbios': ['On', 'Service netbios']}, 'netstats': {'out_lo': 2683668, 'out_eth0': 2390386, 'iner_eth0': 0, 'iner_lo': 0, 'in_eth0': 59481, 'outer_eth0': 0, 'in_lo': 2683668, 'outer_lo': 0}, 'ead_web': {'status': 'On'}, 'RootDebsums': {}, 'debsums': {}, 'sentinelle': {'maj_auto': ''}, 'sysinfo': {'kernel': '2.6.32-73-eole', 'swap_used': '12 Mo', 'load15': '0.00', 'swap_free': '2893 Mo', 'uptime': 14894426, 'swap_total': '2905 Mo', 'physique_used': '859 Mo', 'physique': '86 %', 'physique_total': '992 Mo', 'physique_free': '133 Mo', 'swap': '0', 'load1': '0.00', 'load5': '0.00'}, 'smb': {'status': 'On'}, 'ssh': {'status': 'On'}, 'network': {'eth0': 'On'}},
|
135 |
# 379: {'bacula-fd': {}, 'diskspace': {'/mnt/sauvegardes': (45, 924314, 394200, 483161, 'cifs'), '/tmp': (2, 1874, 35, 1743, 'ext4'), '/var': (16, 8445, 1271, 6744, 'ext4'), '/home': (67, 185297, 117581, 58303, 'ext4'), '/dev': (1, 1504, 0, 1504, 'devtmpfs'), '/boot': (6, 703, 34, 633, 'ext4'), '/': (36, 3283, 1092, 2023, 'ext4')}, 'mysql': {'status': 'On'}, 'sauvegarde': {}, 'RootDebsums': {}, 'ftp': {'status': 'On'}, 'bacula-sd': {}, 'ead_server': {'status': 'On'}, 'baculaservices': {'bacula-fd': ['On', 'bacula-fd'], 'bacula-dir': ['On', 'bacula-dir'], 'bacula-sd': ['On', 'bacula-sd']}, 'diag': {}, 'frontend_horus': {}, 'tcpservices': {'ftp': ['On', 'Transfert de fichiers (FTP)'], 'ead_web': ['Off', 'EAD 2 (Web)'], 'http': ['On', 'Serveur Web (HTTP)'], 'ssh': ['On', 'shell s\xc3\xa9curis\xc3\xa9 (SSH)'], 'ead_server': ['On', 'EAD 2 (Serveur)'], 'mysql': ['On', 'Bases de donn\xc3\xa9es (MySQL)'], 'ldap': ['On', "Annuaire d'authentification (LDAP)"], 'smb': ['On', 'Serveur de fichiers (SMB)']}, 'annuaire': {}, 'conn': {'connected': 0}, 'ldap': {'status': 'On'}, 'smb': {'status': 'On'}, 'http': {'status': 'On'}, 'web': {'DNS distant : 10.121.16.5': 'On', 'R\xc3\xa9solution': 'On', 'Acc\xc3\xa8s Distant': 'On'}, 'bilan': {}, 'bacula-dir': {}, 'ssh': {'status': 'On'}, 'netstats': {'out_lo': 305828178, 'out_eth0': 1302616276, 'iner_eth0': 0, 'iner_lo': 0, 'in_eth0': 40663804, 'outer_eth0': 0, 'in_lo': 305828178, 'outer_lo': 0}, 'sysinfo': {'kernel': '2.6.32-73-eole', 'swap_used': '3 Mo', 'load15': '0.00', 'swap_free': '1948 Mo', 'uptime': 4921380, 'swap_total': '1951 Mo', 'physique_used': '2955 Mo', 'physique': '97 %', 'physique_total': '3019 Mo', 'physique_free': '64 Mo', 'swap': '0', 'load1': '0.01', 'load5': '0.00'}, 'patches': {'/usr/share/eole/creole//patch/variante/sudoers.patch': {'/var/lib/creole/sudoers': []}, '/usr/share/eole/creole//patch/variante/vimrc.patch': {'/var/lib/creole/vimrc': []}}, 'sso': {'Application web EoleSSO': 'On'}, 'network': {'eth0': 'On'}, 'ead_web': {'status': 'Off'}, 'debsums': {}, 'sentinelle': {'maj_auto': ''}}}
|
136 |
|
137 |
|
138 |
###################################################################################
|
139 |
# mise en forme des données pour chaque serveur, à personnaliser selon les besoins
|
140 |
###################################################################################
|
141 |
|
142 |
for index, id_serveur in enumerate(serv_ids): |
143 |
# index permet de récupérer la bonne entrée dans les données récupérées ci dessus
|
144 |
rne = infos_serveur[id_serveur]['rne']
|
145 |
libelle_serveur = infos_serveur[id_serveur]['libelle']
|
146 |
module = module_infos[infos_serveur[id_serveur]['module_actuel']]
|
147 |
# vérification des pertes de contact
|
148 |
global_status = infos_serveur[id_serveur]['etat']
|
149 |
if global_status == 2: |
150 |
perte_contact = 1
|
151 |
else:
|
152 |
perte_contact = 0
|
153 |
# liste des agents en erreur
|
154 |
ag_errors = [] |
155 |
for nom_agent, agent_data in agents_infos[index].items(): |
156 |
descr, etat, date_measure = agent_data |
157 |
if etat == 0: |
158 |
ag_errors.append("%s (%s)" % (nom_agent, descr))
|
159 |
# ajout des données de ce serveur
|
160 |
csv_data.append(delimiter.join([str(id_serveur), module, libelle_serveur, rne, str(perte_contact), ", ".join(ag_errors)])) |
161 |
try:
|
162 |
# écriture du fichier résultat
|
163 |
csv_name = 'zephir_infos.csv'
|
164 |
f = codecs.open(csv_name, 'w', encoding='utf-8') |
165 |
f.write(u"\n".join(csv_data))
|
166 |
f.close() |
167 |
print "Fichier sauvegardé (%s)\n" % csv_name |
168 |
except:
|
169 |
import traceback |
170 |
traceback.print_exc() |
171 |
print "! Erreur à l'écriture du fichier %s !\n" % csv_name |
172 |
|
173 |
|
174 |
if __name__ == '__main__': |
175 |
|
176 |
# affichage aide
|
177 |
if '-h' in sys.argv or '--help' in sys.argv: |
178 |
print HELP
|
179 |
sys.exit(0)
|
180 |
|
181 |
zephir_infos = {} |
182 |
# informations sur le serveur à contacter et le compte à utiliser pour la lecture
|
183 |
# ex : zephir_infos = {'adresse_zephir':'localhost','user':'admin_zephir', 'pwd':'xxx'}
|
184 |
if zephir_infos == {}:
|
185 |
# saisie manuelle des infos zéphir/utilisateur pour débug du script
|
186 |
zephir_infos['adresse_zephir'] = raw_input("Entrez l'adresse du serveur Zéphir :") |
187 |
# proxy xmlrpc
|
188 |
zephir_infos['user'] = raw_input("nom de l'utilisateur zephir :") |
189 |
zephir_infos['pwd'] = getpass.getpass("mot de passe :") |
190 |
|
191 |
# définition du proxy XMLRPC ver le serveur Zéphir
|
192 |
if zephir_infos['adresse_zephir'] in ('localhost', '127.0.0.1'): |
193 |
zephir_proxy = xmlrpclib.ServerProxy('http://%(user)s:%(pwd)s@localhost:7081' % zephir_infos)
|
194 |
else:
|
195 |
zephir_proxy = xmlrpclib.ServerProxy('https://%(user)s:%(pwd)s@%(adresse_zephir)s:7080' % zephir_infos)
|
196 |
|
197 |
try:
|
198 |
####################################################################################
|
199 |
# pour récupérer l'ensemble des serveurs, remplacer l'appel à selection_serveur par:
|
200 |
# rc, serveurs = zephir_proxy.serveurs.get_serveur()
|
201 |
####################################################################################
|
202 |
groupe_serv = selection_serveurs(zephir_proxy) |
203 |
####################################################################
|
204 |
# alert_only : traiter uniquement les serveurs de la page d'alertes
|
205 |
####################################################################
|
206 |
get_infos(zephir_proxy, groupe_serv, alert_only = True)
|
207 |
except xmlrpclib.ProtocolError:
|
208 |
print "Erreur, autorisations insuffisantes" |
209 |
sys.exit(1)
|