Projet

Général

Profil

zephir_gen_csv.py

Bruno Boiget, 16/02/2016 18:16

Télécharger (14,9 ko)

 
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)