Projet

Général

Profil

migration_scribe_26.py

ma version scribe - équipe eole Academie d'Orléans-Tours, 24/01/2019 12:04

Télécharger (20,3 ko)

 
1
#!/usr/bin/env python
2
# -*- coding: UTF-8 -*-
3

    
4
import sys
5
if '/usr/share/eole/orl' not in sys.path:
6
        sys.path.append('/usr/share/eole/orl')
7
if '/usr/share/eole/orl/scripts' not in sys.path:
8
        sys.path.append('/usr/share/eole/orl/scripts')
9
###########################################################################
10
# Eole - 2014
11
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
12
# Licence CeCill  cf /root/LicenceEole.txt
13
# eole@ac-dijon.fr
14
#
15
# migration_2.4.py
16
#
17
# squelette de script permettant de générer des configurations de migration
18
# en mode batch (via l'API XMLRPC de Zéphir)
19
#
20
# Ce script génère une configuration de la même façon qu'en utilisant
21
# le bouton "générer un configuration de migration' de l'application web.
22
#
23
# Il est possible de personnaliser la fonction update_conf pour gérer
24
# des variables supplémentaires non gérées par la fonction d'origine.
25
# (variables déclarées au niveau des variantes / serveurs).
26
#
27
###########################################################################
28

    
29
import csv,getpass,os
30
import base64,xmlrpclib
31
from zephir.utils.creolewrap import ZephirDict
32
import sys
33
reload(sys)
34
import string
35
# force l'encodage par défaut à utf-8 pour les chaînes unicode
36
sys.setdefaultencoding('utf-8')
37

    
38
# à redéfinir si utilisé à distance
39
adresse_zephir='localhost'
40

    
41
# délimiteur de champ pour le fichier CSV décrivant les serveurs à traiter
42
delimiter = ';'
43
# contenu des champs du fichier csv:
44
# id_serveur;id_variante_destination
45

    
46
# !!  mettre à True pour vérifier les valeurs lors de tests (la configuration ne sera pas sauvegardée) !!
47
debug = True
48

    
49
#######################################################
50
## FONCTIONS UTILITAIRES POUR LE TRAITEMENT DES VALEURS
51

    
52
def is_empty(value):
53
    # renvoie True si value est 'vide' :
54
    # liste vide / chaine vide / liste de chaines vides
55
    return len(u"".join(value)) == 0
56

    
57
def is_equal(dico, nom_var, test):
58
    """renvoie True si la valeur de la variable nom_var est équivalente à test
59
    gère le cas des chaines unicode ou non et des listes 'vides'
60
    """
61
    if nom_var in dico.liste_vars:
62
        if test in ([], [''], [u'']):
63
            if dico.get_value(nom_var) in ([], [''], [u'']):
64
                return True
65
        if dico.get_value(nom_var) == test or \
66
           dico.get_value(nom_var) == [test] or \
67
           dico.get_value(nom_var) == [unicode(test)]:
68
            return True
69
        return False
70
    else:
71
        print u"Appel de is_equal sur une variable inconnue : {0}".format(nom_var)
72

    
73
def copy_val(dico, nom_var, value):
74
    """ définit une valeur sur une variable en transformant
75
    les chaînes non unicode en unicode dico est une configuration 2.4
76
    """
77
    if nom_var in dico.liste_vars:
78
        if value == "[u'']" or  value == "['']":
79
            value = []
80
        if value != '[]' and type(value) != list:
81
            if value.startswith(u"["):
82
                value = eval(value)
83
        # si le dictionnaire de destination est de type 'creole3' (eole 2.4),
84
        # on transforme les type 'str' en 'unicode'
85
        if dico.version == 'creole3':
86
            if type(value) == list:
87
                for  index ,val in enumerate(value):
88
                    if type(val) == str:
89
                        value[index] = unicode(val, 'utf-8')
90
            elif type(value) == str:
91
                value = unicode(value, 'utf-8')
92
        dico.get_var(nom_var)
93
        dico.set_value(value)
94
    else:
95
        print u"Appel de copy_val sur une variable inconnue : {0}".format(nom_var)
96

    
97
def read_val(dico, nom_var):
98
    if nom_var in dico.liste_vars:
99
        value = dico.get_value(nom_var)
100
        if value == "[u'']" or  value == "['']" or value == ['']:
101
            value = []
102
        if value != '[]' and type(value) != list:
103
            if value.startswith(u"["):
104
                value = eval(value)
105
        if type(value) == list:
106
            for index,v in enumerate(value):
107
                if type(v) == str:
108
                        value[index] = unicode(v, 'utf-8')
109
            return value
110
        else:
111
            return unicode(dico.get_value(nom_var), 'utf-8')
112
    else:
113
        print u"Appel de read_val sur une variable inconnue : {0}".format(nom_var)
114

    
115
###AJOUT ORLEANS
116
nat_agr={"18":"20",
117
        "28":"21",
118
        "36":"22",
119
        "37":"23",
120
        "41":"24",
121
        "45":"25",
122
        "99":"25"
123
        }
124

    
125
def sub_octet_4(ip, octet4):
126
    octets=ip.split(".")
127
    octets.__delitem__(3)
128
    octets.append(str(octet4))
129
    return ".".join(octets)
130

    
131
def sub_octet_1D(ip):
132
    octets=ip.split(".")
133
    octets[1]="1"+octets[1]
134
    return ".".join(octets)
135

    
136
def concat_list(liste1, liste2):
137
    new_liste=[]
138
    for i in liste1:
139
        new_liste.append(i)
140
    for j in liste2:
141
        new_liste.append(j)
142
    return new_liste
143

    
144
######################################
145
## FONCTION PERSONNALISEE DE MIGRATION
146

    
147
def update_conf(d_eole1, d_eole2, variante, domaine, ip_amon, smtp, type_etab, statut, vm, sid, version):
148
    """
149
        traitement automatique des variables
150

151
    met à jour la configuration de migration en fonction de la configuration actuelle
152

153
    d_eole1 : dictionnaire avec la configuration d'origine du serveur
154
    d_eole2 : dictionnaire qui sera sauvegardé sur Zéphir comme 'migration.eol'
155
              (configuration à appliquer sur le serveur migré)
156
    variante: identifiant de la variante du serveur après migration
157
    proxy: proxy XMLRPC utilisable pour faire des appels à l'API Zéphir
158

159
    lire la valeur d'une variable (dico 1 ou 2):
160

161
          d_eoleX.get_value('nom_var')
162
          !ATTENTION! : get_value renvoie toujours une liste de valeur.
163
          En cas de test sur une valeur, récupérer la valeur voulue
164
          ex: if read_val(d_eole1,'activer_squid_auth')[0] == 'pedago':
165

166
    copier la valeur d'une variable de dico1 vers une variabel de dico2:
167
          copy_val(d_eole2,'nom_variable2.4',d_eole1.get_value('nom_variable2.2'))
168

169
    modifier la valeur d'une variable du dictionnaire eole 2:
170

171
          copy_val(d_eole2,'nom_var',u'valeur')
172

173
    pour une variable multiple :  copy_val(d_eole2,'nom_var',[u'valeur1',u'valeur2', ...])
174

175
    vérifier si une variable est présente dans un dictionnaire:
176

177
          if 'nom_variable' in d_eoleX.liste_vars:
178
              .....
179

180
    une bonne pratique peut être de créer des sous fonctions spécifiques à chaque variante
181

182
    Pour plus d'informations sur l'utilisation de l'API de Zéphir:
183
    https://<adresse_ip_zephir>:8070/aide/devel
184
    https://<adresse_ip_zephir>:8070/aide/api
185
    """
186

    
187
    # ----- inclure les traitements des variables ici
188
    # --- !! pour éviter des problèmes d'indentation, configurez l'éditeur pour remplacer
189
    # --- les tabulations par 4 espaces (ou éditez le fichier avec vi sur un module eole)
190
    #
191
    # --- Dans la mesure du possible, utilisez de préférence la modification des valeurs par défaut
192
    # --- des modules/variantes eole NG dans l'application web si les valeurs à renseigner sont les mêmes
193
    # --- pour tous les serveurs d'un(e) variante/module.
194

    
195

    
196
    ### Attention, pour la migration vers EOLE 2.4 :
197
    #
198
    # pour set_value sur d_eole2, il faut utiliser des chaînes unicode pour les chaînes de caractères :
199
    # par exemple:
200
    # - d_eole2.get_var('passerelle_smtp') : sélectionne la variable
201
    # - d_eole2.set_value(u'smtp.in.ac-dijon.fr') : applique la valeur (unicode)
202
    #
203
    # utiliser de préférence les fonction copy_val et read_val, qui convertissent les chaînes si besoin :
204
    # copy_val(d_eole2, 'passerelle_smtp', u'smtp.in.ac-dijon.fr') : ici, u est optionnel
205
    ###
206

    
207
    # exemple1 : mettre le nombre de cartes à 3 si le modèle de pare-feu dans la configuration amon-1.5
208
    # contient la chaine '3zones'
209
    #
210
    #if 'type_amon' in d_eole1.liste_vars:
211
    #    if '3zones' in d_eole1.get_value('type_amon'):
212
    #        d_eole2.dico.set_value('nombre_interfaces','3')
213

    
214
    # exemple2 : pour la variante 8, activer le serveur sso si le frontend ead-web est activé
215
    #
216
    #if variante == 8:
217
    #    if isequal(d_eole2, 'ead_web', 'oui'):
218
    #        copy_val(d_eole2,'adresse_ip_sso', read_val(d_eole1,'adresse_ip_eth0'))
219

    
220
    # exemple 3:
221
    #
222
    # passage à oui de 'activer_ajout_hosts' si des noms supplémentaires ont été ajoutés par la variante 2.4
223
    # (forcé à non au moment de l'upgrade si la configuration d_eole1 ne contient pas de noms supplémentaire)
224
    #
225
    #if len(d_eole2.get_value('adresse_ip_hosts')) != 0:
226
    #    copy_val(d_eole2, 'activer_ajout_hosts', u'oui')
227
        ###
228
    # Migration vers 2.4.2 => dictionnaire inchangé
229
        # Calul du département
230
    #
231
    #Cas particulier de l'upgrade 2.4.2 vers 2.5.2 => recopier le dico à l'identique
232
    #if version=="2.4.2":
233
    #    return d_eole2
234
    #
235
    rne=read_val(d_eole1,'numero_etab')[0]
236
    dept=rne[1:3]
237
    # Mise à jour des variables
238
    copy_val(d_eole2,'nom_domaine_local',domaine+".lan")
239
    copy_val(d_eole2,'web_url', read_val(d_eole1,'adresse_ip_eth0')[0])
240
    copy_val(d_eole2,'web_redirection','/roundcube')
241
    copy_val(d_eole2,'activer_exim_relay_smtp','oui')
242
    copy_val(d_eole2,'exim_relay_smtp', string.lower(smtp))
243
    copy_val(d_eole2,'system_mail_from','noreply-'+rne+'@ac-orleans-tours.fr')
244
    copy_val(d_eole2,'exim_address_rewrite','oui')
245
    copy_val(d_eole2,'exim_address_rewrite_pattern','bacula@*')
246
    copy_val(d_eole2,'exim_address_rewrite_replacement','noreply-'+rne+'@ac-orleans-tours.fr')
247
    copy_val(d_eole2,'system_mail_from_for_headers','oui') # new
248
    #copy_val(d_eole2,'exim_address_rewrite_flags','Ffrs') obsolète
249
    copy_val(d_eole2,'serveur_maj','eole.ac-dijon.fr')
250
    copy_val(d_eole2,'synchro_aaf_sendmail','oui') # new
251
    copy_val(d_eole2,'interface_gw','eth0') # forcer eth0
252
    copy_val(d_eole2,'nom_carte_eth0','eth0') # forcer eth0
253
    copy_val(d_eole2,'nom_zone_eth0','eth0') # forcer eth0
254
    copy_val(d_eole2,'synchro_aaf_mail','eole-exploitation@ac-orleans-tours.fr') # new
255
    if dept=="37" and type_etab=="clg" and statut=="PU":
256
        copy_val(d_eole2,'orl_bcdi','oui')
257
    copy_val(d_eole2,'orl_active_infoquota',read_val(d_eole1,'orl_active_infoquota')[0])
258
    copy_val(d_eole2,'ip_ssh_eth0','0.0.0.0')
259
    copy_val(d_eole2,'netmask_ssh_eth0','0.0.0.0')
260
    copy_val(d_eole2,'ip_admin_eth0','0.0.0.0')
261
    copy_val(d_eole2,'netmask_admin_eth0','0.0.0.0')
262
    copy_val(d_eole2,'esu_proxy','oui')
263
    copy_val(d_eole2,'esu_proxy_server',ip_amon)
264
    copy_val(d_eole2,'activer_snmpd','oui')
265
    copy_val(d_eole2,'snmp_allow_ip',['195.83.89.139','127.0.0.1'])
266
    copy_val(d_eole2,'snmp_allow_mask',['255.255.255.255','255.255.255.255'])
267
    copy_val(d_eole2,'snmp_community',['public','public'])
268
    copy_val(d_eole2,'orl_nagios','oui')
269
    copy_val(d_eole2,'ssh_allow_groups','nagios')
270
    if dept=="37" and type_etab=="clg" and statut=="PU":
271
        copy_val(d_eole2,'esu_proxy_bypass',['172.19.*','172.20.*','172.21.*','172.22.*','172.23.*','localhost','127.0.0.1','192.168.227.125','10.137.*'])
272
    else:
273
        copy_val(d_eole2,'esu_proxy_bypass',['172.19.*','172.20.*','172.21.*','172.22.*','172.23.*','localhost','127.0.0.1'])
274
    copy_val(d_eole2,'activer_bareos_dir','oui')
275
    copy_val(d_eole2,'activer_bareos_sd','oui')
276
    copy_val(d_eole2,'bareos_db_type','mysql')
277
    copy_val(d_eole2,'bareos_full_retention','40')
278
    copy_val(d_eole2,'bareos_full_retention_unit','days')
279
    copy_val(d_eole2,'bareos_diff_retention','40')
280
    copy_val(d_eole2,'bareos_diff_retention_unit','days')
281
    copy_val(d_eole2,'bareos_inc_retention','8')
282
    copy_val(d_eole2,'bareos_inc_retention_unit','days')
283
    if (version=="2.2" and read_val(d_eole1,'dhcp')[0]=='oui') or (version=="2.3" and read_val(d_eole1,'activer_dhcp')[0]=='oui'):
284
        copy_val(d_eole2,'activer_dhcp','oui')
285
        if read_val(d_eole1,'orl_multi_vlan_dhcp')[0] == 'oui' and read_val(d_eole1,'adresse_network_dhcp') != ['']:
286
            copy_val(d_eole2,'adresse_network_dhcp',concat_list(read_val(d_eole1,'adresse_network_dhcp'),read_val(d_eole1,'orl_adresse_network_dhcp')))
287
            copy_val(d_eole2,'adresse_netmask_dhcp',concat_list(read_val(d_eole1,'adresse_netmask_dhcp'),read_val(d_eole1,'orl_adresse_netmask_dhcp')))
288
            copy_val(d_eole2,'ip_basse_dhcp',concat_list(read_val(d_eole1,'ip_basse_dhcp'),read_val(d_eole1,'orl_ip_basse_dhcp')))
289
            copy_val(d_eole2,'ip_haute_dhcp',concat_list(read_val(d_eole1,'ip_haute_dhcp'),read_val(d_eole1,'orl_ip_haute_dhcp')))
290
            copy_val(d_eole2,'adresse_ip_gw_dhcp',concat_list(read_val(d_eole1,'adresse_ip_gw_dhcp'),read_val(d_eole1,'orl_adresse_ip_gw_dhcp')))
291
            copy_val(d_eole2,'adresse_ip_dns_dhcp',concat_list(read_val(d_eole1,'adresse_ip_dns_dhcp'),read_val(d_eole1,'orl_adresse_ip_dns_dhcp')))
292
            copy_val(d_eole2,'nom_domaine_dhcp',(domaine+".lan"+(','+domaine+".lan")*(len(read_val(d_eole1,'adresse_network_dhcp')) - 1)).split(","))
293
            copy_val(d_eole2,'orl_multi_vlan_dhcp','non')
294
        elif read_val(d_eole1,'orl_multi_vlan_dhcp')[0] == 'oui' and read_val(d_eole1,'adresse_network_dhcp') == ['']:
295
            copy_val(d_eole2,'adresse_network_dhcp',read_val(d_eole1,'orl_adresse_network_dhcp'))
296
            copy_val(d_eole2,'adresse_netmask_dhcp',read_val(d_eole1,'orl_adresse_netmask_dhcp'))
297
            copy_val(d_eole2,'ip_basse_dhcp',read_val(d_eole1,'orl_ip_basse_dhcp'))
298
            copy_val(d_eole2,'ip_haute_dhcp',read_val(d_eole1,'orl_ip_haute_dhcp'))
299
            copy_val(d_eole2,'adresse_ip_gw_dhcp',read_val(d_eole1,'orl_adresse_ip_gw_dhcp'))
300
            copy_val(d_eole2,'adresse_ip_dns_dhcp',read_val(d_eole1,'orl_adresse_ip_dns_dhcp'))
301
            if len(read_val(d_eole1,'adresse_network_dhcp')) == 1:
302
                copy_val(d_eole2,'nom_domaine_dhcp',domaine+".lan")
303
            elif len(read_val(d_eole1,'adresse_network_dhcp')) > 1:
304
                copy_val(d_eole2,'nom_domaine_dhcp',(domaine+".lan"+(','+domaine+".lan")*(len(read_val(d_eole1,'adresse_network_dhcp')) - 1)).split(","))
305
            copy_val(d_eole2,'orl_multi_vlan_dhcp','non')
306
        elif len(read_val(d_eole1,'adresse_network_dhcp')) == 1:
307
            copy_val(d_eole2,'nom_domaine_dhcp',domaine+".lan")
308
        elif len(read_val(d_eole1,'adresse_network_dhcp')) > 1:
309
            copy_val(d_eole2,'nom_domaine_dhcp',(domaine+".lan"+(','+domaine+".lan")*(len(read_val(d_eole1,'adresse_network_dhcp')) - 1)).split(","))
310
    if vm=="1":
311
        copy_val(d_eole2,'orl_vmware_tools','oui')
312
    #réplication
313
    copy_val(d_eole2,'ldap_replication','oui')
314
    copy_val(d_eole2,'serverID',sid)
315
    #paratage scan du cd45
316
    if dept=="45" and type_etab=="clg" and statut=="PU":
317
            copy_val(d_eole2,'orl_scantofolder_cd45','oui')
318
    if version=="2.3":
319
        if dept=="41" and type_etab=="clg" and statut=="PU":
320
        #wpkg
321
        #le 41 n'en veut plus
322
            copy_val(d_eole2,'activer_wpkg','non')
323
        elif version=="2.2":
324
            copy_val(d_eole2,'activer_wpkg','non')
325
        else:
326
            copy_val(d_eole2,'activer_wpkg',read_val(d_eole1,'orl_active_wpkg')[0])
327
    #ocs
328
    copy_val(d_eole2,'ocsinventory_agent','oui')
329
    copy_val(d_eole2,'ocs_agent_server_port','80')
330
    copy_val(d_eole2,'ocs_agent_server','http://ocs-eple.adr.ac-orleans-tours.fr')
331
    if vm=="1":
332
        copy_val(d_eole2,'ocs_agent_use_rne_as_tag','oui')
333
    #clamav samba - on le desactive car pose des soucis au niveau de W10
334
    copy_val(d_eole2,'activer_clam','non')
335
    #Désactivation antivirus temps réel à cause du problème  https://dev-eole.ac-dijon.fr/issues/12454
336
    #copy_val(d_eole2,'smb_vscan','non')
337
    #logs samba
338
    copy_val(d_eole2,'smb_log_level','1')
339
    #limite ibdata mysql
340
    copy_val(d_eole2,'orl_limit_size_mysql','oui')
341
    #sinon les acces ead bug
342
    copy_val(d_eole2,'eolesso_adresse', read_val(d_eole1,'adresse_ip_eth0')[0])
343
    #GLPI #0121882
344
    copy_val(d_eole2,'smb_socket_options', 'TCP_NODELAY')
345

    
346

    
347
    # ---- fin des traitements
348

    
349
    return d_eole2
350

    
351
###AJOUT ORLEANS
352
def get_pass():
353
    fic=open("/root/pwd", "r")
354
    pwd=fic.readline().strip()
355
    fic.close()
356
    os.system("rm -f /root/pwd")
357
    login=pwd.split(";")[0]
358
    passwd=pwd.split(";")[1]
359
    return [login, passwd]
360

    
361
######################
362
## FONCTION PRINCIPALE
363

    
364
def migrate_serveurs(fic_csv_name="", main_loop=False):
365
    """
366
    boucle principal de parcours des serveurs
367
    """
368
    login, passwd = get_pass()
369
    # lecture du fichier csv
370
    if fic_csv_name == "":
371
        fic_csv_name = "/root/scribe.csv"
372
    else:
373
        fic_csv_name = "/root/"+fic_csv_name
374
    fic_csv = open(fic_csv_name)
375
    parser = csv.reader(fic_csv,delimiter=delimiter)
376
    proxy = xmlrpclib.ServerProxy('http://%s:%s@%s:7081' % (login,passwd,adresse_zephir))
377
    # informations sur les module et variantes
378

    
379
    # parsing des données
380
    erreurs = []
381
    while True:
382
        try:
383
            # lecture d'une ligne du fichier csv
384
            data_serveur = parser.next()
385
        except StopIteration:
386
            # fin du fichier
387
            fic_csv.close()
388
            break
389
        # chaque ligne indique un numéro de serveur et le n° de la variante à utiliser après migration
390
        id_serveur, variante, domaine, ip_amon, smtp, type_etab, statut, vm, sid, version = data_serveur
391
        id_serveur = int(id_serveur)
392
        variante = int(variante)
393
        # migration du serveur (équivalent de 'générer la 'générer les données de migration' dans  l'appli web)
394
        try:
395
            # récupération du dictionnaire creole du serveur dans sa version actuelle
396
            code, data_ori = proxy.serveurs.get_dico(id_serveur,'modif_config',True)
397
            if version in ("2.2","2.3"): # passage 2.2 ou 2.3 à 2.6.2
398
                d_eole1 = ZephirDict(mode='')
399
            elif version in ("2.5.2"): # passage 2.5.2 à 2.6.2
400
                d_eole1 = ZephirDict(mode='', version='creole3')
401
            d_eole1.init_from_zephir(data_ori)
402
            # initialisation du dictionnaire creole2
403
            code, data_migration = proxy.serveurs.migrate_conf(int(id_serveur), 'migration', int(variante))
404
            if code == 0:
405
                raise Exception, data_migration
406
            ##  IMPORTANT, pour la migration vers eole 2.4, bien spécifier version='creole3'
407
            d_eole2 = ZephirDict(mode='', version='creole3')
408
            # initialisation du dictionnaire depuis les valeurs renvoyées par Zéphir
409
            d_eole2.init_from_zephir(data_migration)
410
            # déblocage temporaire des variables cachées et vérouillées ?
411
            #settings = d_eole2.dico.cfgimpl_get_settings()
412
            #settings.remove('disabled')
413
            #settings.remove('frozen')
414
            # mise à jour du dictionnaire de migration
415
            # APPEL DE LA FONCTION DE MIGRATION PERSONNALISEE
416
            d_eole2 = update_conf(d_eole1, d_eole2, int(variante), domaine, ip_amon, smtp, type_etab, statut, vm, sid, version)
417
            if debug:
418
                print "\n--- configuration du serveur %s\n" % id_serveur
419
                for var in d_eole2.liste_vars:
420
                    print var, '-->', d_eole2.get_value(var)
421
                if not main_loop:
422
                    # mod debug et appel depuis shell python: on retourne
423
                    # les 2 dictionnaires pour le premier serveur du fichier CSV
424
                    # pour faciliter les diagnostics
425
                    fic_csv.close()
426
                    return d_eole1, d_eole2
427
            else:
428
                save_data = d_eole2.save(force=False) #,eol_file='/tmp/test.txt')
429
                # sauvegarde de la conf sur zephir (migration.eol)
430
                code, detail = proxy.serveurs.save_conf(id_serveur, save_data, 'migration')
431
                print "serveur modifié : %s" % id_serveur
432
        except Exception, e:
433
            if debug:
434
                # trace complète en mode debug
435
                import traceback
436
                traceback.print_exc()
437
            print "erreur de modification du serveur %s : %s" % (id_serveur, str(e))
438
            erreurs.append(delimiter.join(data_serveur))
439

    
440
    # on stocke dans un fichier csv les serveurs non ajoutés
441
    if len(erreurs) > 0:
442
        f=open("error.csv","w")
443
        f.write('\n'.join(erreurs))
444
        f.close()
445
        print "\nDes erreurs ont été rencontrées :\n"
446
        print "- Vous pouvez consulter les logs du service zephir pour plus d'informations:\n"
447
        print "     /var/log/rsyslog/local/zephir_backend/zephir_backend.info.log\n"
448
        print "- un fichier error.csv a été généré pour relancer ce script sur les serveurs en erreur\n"
449

    
450
if __name__ == '__main__':
451
    try:
452
        # on regarde si un fichier csv est passé en argument
453
        assert os.path.isfile(sys.argv[1])
454
        fic_csv = sys.argv[1]
455
    except:
456
        fic_csv = ""
457
    migrate_serveurs(fic_csv, main_loop=True)