# -*- coding: utf-8 -*- """ Classe de génération du fichier de l'autostatus Utilisé par generate.py """ # importation des fonctions et classes import sys, os, commands sys.path.append('/usr/scripts/gestion') from ldap_crans import AssociationCrans, BorneWifi from gen_confs import gen_config # définition de la classe def inform(string): pass # print string class autostatus(gen_config) : # CONFIGURATION # ################# # fichier de l'autostatus CONFFILE = '/usr/scripts/var/autostatus/hosts' # machines crans à ne pas mettre dans l'autostatus pasimportant = [ # Serveurs de tests "test.adm.crans.org", "bcfg2tmp0.adm.crans.org", "bcfg2tmp0.crans.org", "bcfg2tmp1.adm.crans.org", "bcfg2tmp1.crans.org", "diskless.crans.org", "notyetbroken.crans.org", "notyetbroken.adm.crans.org", "willbreaksoon.crans.org", "willbreaksoon.adm.crans.org", "obm.crans.org", "obm.adm.crans.org", "batv-3.adm.crans.org", "batv-1.adm.crans.org", # Config par défaut "non-configure.wifi.crans.org", "kiss.crans.org", "freebox.crans.org", "ssh2.crans.org", "reboot-p1.crans.org", "reboot-p2.crans.org", "reboot-default.crans.org", "minigiga.adm.crans.org", "ytrap-llatsni.crans.org", "pegase.adm.crans.org", # Pas ou plus en production "malloc.crans.org", # serveur inutilisé "morgan.crans.org", "venus.crans.org", # ancienne cableuse "cableuse.crans.org", "dyson-g.crans.org", # dyson n'est plus routeur du G "ftp.federez.net", # épave du 4J (?) "sila.crans.org", # mort, cf charybde "cerbere.crans.org", # ne sert pas pour le moment "rouge.crans.org", # RIP --> domU redisdead "slon.adm.crans.org", # --> cf nols "ragnarok.crans.org", # RIP contrôleur disque... "zamok.crans.org", # c'est en fait fx "bati-2.adm.crans.org", # N'est plus en place "batv-1.crans.org", # Bornes wifi de test "bullet5.wifi.crans.org", "toto.wifi.crans.org", "toto2.wifi.crans.org", # Modules de surveillance des locaux "vigile--1i.adm.crans.org", "vigile-0a.adm.crans.org", "vigile-0b.adm.crans.org", "vigile-0c.adm.crans.org", "vigile-0g.adm.crans.org", "vigile-0h.adm.crans.org", "vigile-0j.adm.crans.org", "vigile-0m.adm.crans.org", "vigile-2b.adm.crans.org", "vigile-2g.adm.crans.org", "vigile-4g.adm.crans.org", "vigile-4j.adm.crans.org", ] # matrice du fichier d'autostatus matrice = u"""# Format : name address depend,list contact description # routeurs vers l'extérieur # ############################# %%HTML: Routeurs, dans l'ordre où ils sont entre le crans et l'extérieur : %(route)s # serveurs du crans # ##################### %%HTML:

Serveurs : %(serveurs)s # ferme # ######### %%HTML:

La ferme, diffusion de la télé : %(ferme)s # switchs # ########### %%HTML:

Switchs : %(switchs)s # bornes wifi # ############### %%HTML:

Bornes wifi : %(bornes)s # Sites web et Services # ######################### %%HTML:

Sites web et Services HORS de l'ENS: (21:FTP ; 80:HTTP) %(exterieur)s """ # quelque descriptions de routeurs triés par IP (pour la route vers l'extérieur) infos_routeurs = {} infos_routeurs [ '138.231.136.4' ] = ['Odlyd', u'Routeur principal du CRANS'] infos_routeurs [ '138.231.136.3' ] = ['Komaz', u'Routeur secondaire du CRANS'] infos_routeurs [ '138.231.132.1' ] = ['Pioneer.zrt', u'Routeur principal de l\'ENS (interne)'] infos_routeurs [ '138.231.132.101' ] = ['Pioneer1.zrt.ens-cachan', u'Routeur principal de l\'ENS (interne)'] infos_routeurs [ '138.231.132.102' ] = ['Pioneer2.zrt.ens-cachan', u'Routeur principal de l\'ENS (interne)'] infos_routeurs [ '138.231.176.1' ] = ['Pioneer', u'Routeur principal de l\'ENS'] infos_routeurs [ '193.49.65.1' ] = ['RenaterCachan1' , u'Routeur Renater' ] infos_routeurs [ '193.51.181.186' ] = ['RenaterCachan2', u'Routeur Renater'] infos_routeurs [ '193.51.189.237' ] = ['RenaterJussieu1', u'Routeur Renater'] # services extérieurs (triés par clé de dictionnaire) # format [ nom, ip, port(0=ping), description ] services_exterieurs = {} services_exterieurs ['Videolan'] = [ 'Videolan', '88.191.250.2', 21, 'Le serveur FTP de Videolan. (Chatenay-Malabry, France)', 'nobody'] services_exterieurs ['Free'] = [ 'Free', '212.27.60.27', 21, 'Le serveur FTP de free. (France)', 'nobody' ] services_exterieurs ['Monde'] = [ 'Monde', '195.154.120.129', 80, 'Est-ce que LeMonde.fr fonctionne ? (France)', 'nobody' ] services_exterieurs ['Yahoo!'] = [ 'Yahoo!', '206.190.36.45', 80, 'Est-ce que Yahoo! fonctionne ? (USA)', 'nobody' ] services_exterieurs ['Google'] = [ 'Google', '74.125.71.138', 80, 'Est-ce que Google fonctionne ? (USA)', 'nobody' ] # personnes à informer pour l'indiponibilité de certains serveurs contact = {} # service à redémarer restart_cmd = "" # FIN DE LA CONFIGURATION def __str__ (self) : return "autostatus" def make_config (self, dico ) : """ Transforme le dico en suite lignes de configuration """ liste = dico.keys() liste.sort() append = "" for i in liste : append = append + " ".join( dico[i] ) + "\n" return append.encode('utf-8') def mail_contact (self, nom) : # retourne le mail à qui envoyer les avis pour un serveur if nom in self.contact.keys() : return self.contact[nom] else : return 'nobody' def _gen (self) : # machines crans ################ inform(u"Récupération des machines du Cr@ns") machines = AssociationCrans().machines() # Quand un serveur est à la fois dans adm et dans autre chose, # on garde que le autre chose machines2 = machines for m in machines: if not m.nom().endswith(".adm.crans.org"): for n in machines: nom_adm = u"%s.adm.crans.org" % m.nom().split(".")[0] if n.nom() == nom_adm: machines2 = filter(lambda x: x.nom() != nom_adm, machines2) machines = machines2 # tri des machines par type bornes = {} switchs = {} serveurs = {} ferme = {} # tri des machines inform(u"tri des machines") for m in machines : # machine exclue if m.nom() in self.pasimportant : continue info = m.info() if any(i.startswith('<') for i in info): continue info = filter(lambda i: not i.startswith(';'), info) + [''] # les bornes if isinstance(m, BorneWifi): # C'est une borne if info: # on regarde si c'est une borne de batiment if ( info[0][0:3] == "Au " ) and ( len(info[0]) == 5 ) : bornes[ "1-" + info[0][4]+info[0][3] + "-" + m.nom() ] = [ m.nom().split(".")[0] , m.nom() , 'none' , self.mail_contact(m.nom()) , info[0] ] else : bornes[ "2-" + info[0] + m.nom() ] = [ m.nom().split(".")[0] , m.nom() , 'none' , self.mail_contact(m.nom()) , info[0] ] else : # on met les bornes non définies à la fin (ordre alphabétique) # On ne les met pas, ça pollue l'autostatus # bornes[ "3-" + m.nom() ] = [ m.nom().split(".")[0] , m.nom() , 'none' , self.mail_contact(m.nom()) , 'Inutilise' ] pass # les switchs elif any('switch' in i.lower() for i in info): # est ce que c'est un batiment if 'bat' == m.nom()[0:3] : index = '1-' + m.nom().split(".")[0] else : index = '0-' + m.nom().split(".")[0] # on ajoute au dictionnaire switchs[ index ] = [ m.nom().split(".")[0] , m.nom() , 'none' , self.mail_contact(m.nom()) , info[0] ] # la ferme elif '.ferme.crans.org' in m.nom() : nom = ".".join(m.nom().split(".")[0:2]) if m.info() : ferme[ nom ] = [ nom , m.nom() , 'none' , self.mail_contact(m.nom()) , m.info()[0] ] else : ferme[ nom ] = [ nom , m.nom() , 'none' , self.mail_contact(m.nom()) , 'Infos non disponibles' ] # les serveurs else : if ".wifi.crans.org" in m.nom(): nom = m.nom().split(".")[0] + ".wifi" else : nom = m.nom().split(".")[0] serveurs[ nom ] = [ nom , m.nom() , 'none' , self.mail_contact(m.nom()) , info[0] ] # route vers l'extérieur ######################## inform(u"Récupération de la route vers l'extérieur") # on récupère la route vers l'extérieur traceroute = commands.getoutput("/usr/bin/traceroute -I www.free.fr 2> /dev/null | sed 's/\*//g' | sed 's/ */ /g' | sed 's/^ //g' | sed 's/[(,)]//g' | cut -d ' ' -f 2,3").split("\n") inform(u"Analyse de la route") # initialisation des variables in_renater = 0 route_to_ext = '' depends_to_ext = '' for routeur in traceroute : # on commence à rentrer dans la chaine des routeurs renater if 'renater.fr' in routeur : in_renater = 1 # on est plus dans les routeurs renater donc on arrête if in_renater and not 'renater.fr' in routeur : continue # ajout du routeur # ip try: tmp_ip = routeur.split(' ')[1] except IndexError: print "Skipping %r" % routeur continue # nom & desciption if tmp_ip in self.infos_routeurs.keys() : tmp_name = self.infos_routeurs[tmp_ip][0] tmp_desc = self.infos_routeurs[tmp_ip][1] else : tmp_name = routeur.split(' ')[0].split('.')[0] tmp_desc = 'Pas de description' # dépendances if not depends_to_ext : tmp_depends = 'none' depends_to_ext = tmp_name else : tmp_depends = depends_to_ext depends_to_ext += ',' + tmp_name # on l'ajoute à la route if route_to_ext : route_to_ext += '\n' route_to_ext += '%s %s %s %s %s' % (tmp_name, tmp_ip, tmp_depends,self.mail_contact(tmp_name),tmp_desc) # services extérieurs ##################### inform(u"Services extérieurs") services_exterieurs = {} for key in self.services_exterieurs.keys() : s = self.services_exterieurs[key] if s[2] : services_exterieurs[ key ] = [ s[0] + ':' + str(s[2]), s[1] , depends_to_ext, s[4] , s[3] ] else : services_exterieurs[ key ] = [ s[0] , s[1] , depends_to_ext, s[4] , s[3] ] # génération du fichier ####################### file = self._open_conf(self.CONFFILE, "#") # génère le dictionnaire pour les modifications dico = {} dico['switchs'] = self.make_config(switchs) dico['bornes'] = self.make_config(bornes) dico['serveurs'] = self.make_config(serveurs) dico['ferme'] = self.make_config(ferme) dico['route'] = route_to_ext dico['exterieur'] = self.make_config(services_exterieurs) for item in dico: dico[item] = dico[item].decode('utf-8') # on écrit dans le fichier de configuration file.write( (self.matrice % dico).encode('utf-8') ) # on ferme le fichier file.close()