scripts/gestion/gen_confs/autostatus.py
2015-11-29 03:26:20 +01:00

357 lines
13 KiB
Python

# -*- 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: <TR><td colspan=3 class="table"><font size="+1"><B>Routeurs, dans l'ordre où ils sont entre le crans et l'extérieur :</font></b></TR>
%(route)s
# serveurs du crans #
#####################
%%HTML: <TR> <TD class=table colSpan=3><p></TD></TR> <TR><td colspan=3 class="table"><font size="+1"><B>Serveurs :</font></b></TR>
%(serveurs)s
# ferme #
#########
%%HTML: <TR> <TD class=table colSpan=3><p></TD></TR> <TR><td colspan=3 class="table"><font size="+1"><B>La ferme, diffusion de la télé :</font></b></TR>
%(ferme)s
# switchs #
###########
%%HTML: <TR> <TD class=table colSpan=3><p></TD></TR> <TR><td colspan=3 class="table"><font size="+1"><B>Switchs :</font></b></TR>
%(switchs)s
# bornes wifi #
###############
%%HTML: <TR> <TD class=table colSpan=3><p></TD></TR> <TR><td colspan=3 class="table"><font size="+1"><B>Bornes wifi :</font></b></TR>
%(bornes)s
# Sites web et Services #
#########################
%%HTML: <TR> <TD class=table colSpan=3><p></TD></TR> <TR><td colspan=3 class="table"><font size="+1"><B>Sites web et Services HORS de l'ENS:</font></b></TR> <TR><td colspan=3 class="table"><font size="2">(21:FTP ; 80:HTTP)</TR>
%(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()