
J'ai retiré (ou remis) le mode executable suivant si le ficher python possède une section if __name__ == '__main__', ou pas.
334 lines
11 KiB
Python
334 lines
11 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import psycopg2
|
|
from functools import wraps
|
|
import time
|
|
|
|
conn = None
|
|
def _need_conn(f):
|
|
"""Décorateur à appliquer aux fonctions nécessitant une connexion pgsql"""
|
|
retries = 1
|
|
delay = 5
|
|
@wraps(f)
|
|
def first_connect(*args, **kwargs):
|
|
global conn
|
|
attempts = 0
|
|
while not conn or not attempts:
|
|
if __name__.endswith('annuaires_pg_test'):
|
|
host='localhost'
|
|
else:
|
|
host='pgsql.v4.adm.crans.org'
|
|
# "connecting …"
|
|
try:
|
|
if not conn:
|
|
conn = psycopg2.connect(user='crans', database='switchs',
|
|
host=host)
|
|
return f(*args, **kwargs)
|
|
except psycopg2.OperationalError:
|
|
attempts += 1
|
|
conn = None
|
|
time.sleep(delay)
|
|
if attempts >= retries:
|
|
raise NameError
|
|
# Les scripts appelant annuaires_pg n'ont pas à connaître le
|
|
# backend pgsql. On utilise donc une exception plus standard
|
|
return first_connect
|
|
|
|
bat_switchs = ["a", "b", "c", "g", "h", "i", "j", "m", "o", "p"]
|
|
|
|
@_need_conn
|
|
def chbre_prises(batiment, chambre = None):
|
|
"""Correspondance chambre -> prise"""
|
|
batiment = batiment.lower()
|
|
if chambre:
|
|
chambre = chambre.lower()
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT prise_crans FROM prises WHERE (batiment, chambre) = (%s, %s)", (batiment, chambre))
|
|
try:
|
|
return "%03d" % cur.fetchone()[0]
|
|
except TypeError:
|
|
raise ValueError("Chambre inexistante bat %r, chbre %r" % (batiment, chambre))
|
|
else:
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT chambre, prise_crans FROM prises WHERE batiment = %s", batiment)
|
|
ret = {}
|
|
for chambre, prise_crans in cur.fetchall():
|
|
ret[chambre] = "%03d" % prise_crans
|
|
if not ret:
|
|
raise ValueError("Batiment %s inexistant" % batiment)
|
|
return ret
|
|
|
|
@_need_conn
|
|
def chbre_commentaire(batiment, chambre):
|
|
""" Renvoie le commentaire associé à la chambre """
|
|
global conn
|
|
batiment = batiment.lower()
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT commentaire FROM prises WHERE (batiment, chambre) = (%s,%s)", (batiment, chambre))
|
|
try:
|
|
return cur.fetchone()[0]
|
|
except TypeError:
|
|
raise ValueError("Chambre inexistante bat %r, chbre %r" % (batiment, chambre))
|
|
|
|
@_need_conn
|
|
def reverse(batiment, prise = None):
|
|
"""Correspondance prise -> chambre"""
|
|
batiment = batiment.lower()
|
|
if prise:
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT chambre FROM prises WHERE (batiment, prise_crans) = (%s, %s)", (batiment, int(prise)))
|
|
try:
|
|
return [chbre for (chbre,) in cur.fetchall()]
|
|
except TypeError:
|
|
raise ValueError("Prise %s inexistante" % prise)
|
|
else:
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT chambre, prise_crans FROM prises WHERE batiment = %s", batiment)
|
|
ret = {}
|
|
for chambre, prise_crans in cur.fetchall():
|
|
try:
|
|
ret["%03d" % prise_crans].append(chambre)
|
|
except KeyError:
|
|
ret["%03d" % prise_crans] = [chambre]
|
|
|
|
if not ret:
|
|
raise ValueError("Batiment %s inexistant" % batiment)
|
|
return ret
|
|
|
|
@_need_conn
|
|
def is_crans(batiment, chambre):
|
|
"""Chambre cablee au Cr@ns ?"""
|
|
batiment = batiment.lower()
|
|
chambre = chambre.lower()
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT crans FROM prises WHERE (batiment, chambre) = (%s, %s)", (batiment, chambre))
|
|
return cur.fetchone()[0]
|
|
|
|
@_need_conn
|
|
def is_connected(batiment, chambre):
|
|
"""Cablage physique effectue ?"""
|
|
batiment = batiment.lower()
|
|
chambre = chambre.lower()
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT cablage_effectue FROM prises WHERE (batiment, chambre) = (%s, %s)", (batiment, chambre))
|
|
return cur.fetchone()[0]
|
|
|
|
@_need_conn
|
|
def crous_to_crans(batiment, chambre):
|
|
"""Passage d'une chambre de CROUS a Cr@ns"""
|
|
batiment = batiment.lower()
|
|
chambre = chambre.lower()
|
|
if is_crans(batiment, chambre):
|
|
return
|
|
cur = conn.cursor()
|
|
cur.execute("UPDATE prises SET (crans, crous, cablage_effectue) = (TRUE, FALSE, not cablage_effectue) WHERE (batiment, chambre) = (%s, %s)", (batiment, chambre))
|
|
conn.commit()
|
|
cur.close()
|
|
|
|
# Prises d'uplink, de machines du crans / Prises d'utilité CRANS
|
|
uplink_prises={ 'a' :
|
|
{ 49 : 'uplink->bata-4', 50 : 'libre-service',
|
|
149 : 'uplink->bata-4', 150 : 'libre-service',
|
|
225 : 'uplink->bata-4', 226 : 'libre-service',
|
|
325 : 'uplink->bata-4', 326 : 'libre-service',
|
|
401 : 'uplink->bata-0', 402 : 'uplink->bata-1',
|
|
403 : 'uplink->bata-2', 404 : 'uplink->bata-3',
|
|
424 : 'uplink->backbone' },
|
|
'b' :
|
|
{ 49 : 'uplink->batb-4', 50 : 'libre-service',
|
|
149 : 'uplink->batb-4', 150 : 'libre-service',
|
|
249 : 'uplink->batb-4', 250 : 'libre-service', # 249 morte ?! (olasd 21/01/2010)
|
|
349 : 'uplink->batb-4', 350 : 'libre-service',
|
|
401 : 'uplink->batb-0', 402 : 'uplink->batb-1',
|
|
403 : 'uplink->batb-2', 404 : 'uplink->batb-3',
|
|
405 : 'uplink->backbone' },
|
|
'c' :
|
|
{ 49 : 'uplink->batc-3', 50 : 'libre-service',
|
|
149 : 'uplink->batc-3', 150 : 'libre-service',
|
|
225 : 'uplink->batc-3', 226 : 'libre-service',
|
|
301 : 'uplink->batc-0', 302 : 'uplink->batc-1',
|
|
304 : 'uplink->batc-4',
|
|
303 : 'uplink->batc-2', 324 : 'uplink->backbone',
|
|
426 : 'uplink->batc-3',
|
|
},
|
|
'g' :
|
|
{
|
|
22 : 'uplink->backbone',
|
|
23 : 'libre-service', 24 : 'uplink->batg-8',
|
|
|
|
149 : 'uplink->batg-8', 150 : 'libre-service',
|
|
|
|
249 : 'uplink->batg-8', 250 : 'uplink->batg-3',
|
|
|
|
325 : 'uplink->batg-8', 326 : 'libre-service',
|
|
|
|
449 : 'uplink->batg-9', 450 : 'uplink->batg-5',
|
|
|
|
549 : 'uplink->batg-9', 550 : 'uplink->batg-6',
|
|
|
|
649 : 'uplink->batg-9', 650 : 'uplink->batg-5',
|
|
|
|
725 : 'uplink->batg-9', 726 : 'libre-service',
|
|
|
|
801 : 'uplink->batg-1', 802 : 'uplink->batg-2',
|
|
|
|
803 : 'uplink->batg-3', 821 : 'uplink->batg-0',
|
|
823 : 'uplink->batg-9',
|
|
|
|
901 : 'uplink->batg-4', 902 : 'uplink->batg-5',
|
|
903 : 'uplink->batg-6', 904 : 'uplink->batg-7',
|
|
921 : 'uplink->batg-8',
|
|
},
|
|
'h' :
|
|
{ 49 : 'uplink->bath-3', 50 : 'libre-service',
|
|
149 : 'uplink->bath-3', 150 : 'libre-service',
|
|
225 : 'uplink->bath-3', 226 : 'libre-service',
|
|
301 : 'uplink->bath-0', 302 : 'uplink->bath-1',
|
|
303 : 'uplink->bath-2', 324 : 'uplink->backbone' },
|
|
'i' :
|
|
{ 49 : 'uplink->bati-3', 50 : 'libre-service',
|
|
149 : 'uplink->bati-3', 150 : 'libre-service',
|
|
301 : 'uplink->bati-0', 302 : 'uplink->bati-1',
|
|
324 : 'uplink->backbone' },
|
|
'j' :
|
|
{ 49 : 'uplink->batj-3', 50 : 'libre-service',
|
|
149 : 'uplink->batj-3', 150 : 'libre-service', # XXX: 150 semble morte
|
|
225 : 'uplink->batj-3', 226 : 'libre-service',
|
|
321 : 'uplink->backbone',
|
|
301 : 'uplink->batj-0', 303 : 'uplink->batj-1',
|
|
305 : 'uplink->batj-2', 307 : 'uplink->multiprise',
|
|
},
|
|
'k' : {
|
|
25 : 'uplink->backbone',
|
|
},
|
|
'm' :
|
|
{
|
|
49 : 'libre-service', 50 : 'uplink->batm-7',
|
|
149 : 'libre-service', 150 : 'uplink->batm-7',
|
|
249 : 'libre-service', 250 : 'uplink->batm-7',
|
|
349 : 'libre-service', 350 : 'uplink->batm-7',
|
|
449 : 'libre-service', 450 : 'uplink->batm-7',
|
|
549 : 'libre-service', 550 : 'uplink->batm-7',
|
|
649 : 'libre-service', 650 : 'uplink->batm-7',
|
|
|
|
724 : 'libre-service', 723 : 'libre-service',
|
|
722 : 'libre-service',
|
|
|
|
721 : 'uplink->backbone', 720 : 'uplink->batm-0',
|
|
719 : 'uplink->batm-1', 718 : 'uplink->batm-2',
|
|
717 : 'uplink->batm-3', 716 : 'uplink->batm-4',
|
|
715 : 'uplink->batm-5', 714 : 'uplink->batm-6',
|
|
},
|
|
'p' :
|
|
{
|
|
49 : 'uplink->batp-4 (R4.1)',
|
|
149: 'uplink->batp-4 (R3.1)',
|
|
249: 'uplink->batp-4 (R2.1)',
|
|
350: 'uplink->batp-4 (R1.2)',
|
|
# On ne génère pas la conf de batp-4 automatiquement, mais ses uplinks
|
|
# peuvent être utiles à connaître
|
|
401: 'uplink->batp0', 402: 'uplink->batp-1',
|
|
403: 'uplink->batp2', 403: 'uplink->batp-3',
|
|
405: 'libre-service', 406: 'uplink->bato-1',
|
|
},
|
|
'o' :
|
|
{
|
|
25 : 'uplink->bato-1', 26 : 'libre-service',
|
|
101 : 'uplink->bato-0', 121: 'uplink->NRD',
|
|
122: 'uplink->backbone', 123: 'uplink->backbone (unused)',
|
|
124: 'uplink->batp-0'
|
|
} ,
|
|
'v' :
|
|
{
|
|
49: 'uplink', 50 : 'uplink',
|
|
} ,
|
|
'backbone' : #For your consideration
|
|
{
|
|
#A: 12eth+12fibre, B: 24 eth
|
|
'A1': 'odlyd', 'B1': 'bata',
|
|
'A2': 'komaz-ens', 'B2': 'multiprise-wifi',
|
|
'A3': 'sable', 'B3': 'dyson',
|
|
'A4': 'komaz', 'B4': 'fy',
|
|
'A5': 'zbee' , 'B5': 'switch-ilo',
|
|
'B6': 'vigile 0B',
|
|
'B7': 'kdell',
|
|
'B8': 'batb',
|
|
'B9': '2b',
|
|
'B10': 'fz',
|
|
'B11': 'ft',
|
|
'B12': 'nols2',
|
|
'A13': 'batm',
|
|
'A14': 'batp', 'B14': 'zamok',
|
|
'A15': 'batc', 'B15': 'charybde',
|
|
'A16': 'bato',
|
|
'A17': 'bath',
|
|
'A18': 'bati', 'B18': 'nols',
|
|
'A19': 'batj',
|
|
'A20': 'batg',
|
|
'A21': 'batk',
|
|
'B21': 'osm1',
|
|
'B22': 'osm1-ilo',
|
|
'B23': 'osm2',
|
|
'B24': 'osm2-ilo',
|
|
},
|
|
}
|
|
|
|
_SPECIAL_SWITCHES=['backbone.adm.crans.org',
|
|
'multiprise-v6.adm.crans.org',
|
|
'batk-0.crans.org',
|
|
'batp-4.adm.crans.org',
|
|
'minigiga.adm.crans.org',
|
|
]
|
|
|
|
def all_switchs(bat=None, hide=_SPECIAL_SWITCHES):
|
|
"""Retourne la liste des switchs pour un batiment.
|
|
|
|
Si bat est donné, seulement pour le bâtiment demandé, sinon pour
|
|
tous les bâtiments. bat peut être une liste aussi. Le backbone n'est
|
|
pas pris en compte. La convention est batx-y sauf si y=0 et on a donc
|
|
simplement batx"""
|
|
|
|
if bat == None:
|
|
bat = bat_switchs
|
|
if type(bat) not in [ tuple, list ] :
|
|
bat = [bat]
|
|
switchs = []
|
|
for b in bat:
|
|
indexes = set(n/100 for n in uplink_prises[b])
|
|
for i in indexes:
|
|
hostname = "bat%s-%s.adm.crans.org" % (b, i)
|
|
if hostname not in hide:
|
|
switchs.append(hostname)
|
|
# on ajoute quand-même le backbone et/ou multiprise-v6 si demandé
|
|
switchs += set(_SPECIAL_SWITCHES).difference(hide)
|
|
|
|
switchs.sort()
|
|
return switchs
|
|
|
|
# Locaux clubs : lecture dans chbre_prises et ajout des locaux dans les bats non
|
|
# manageables
|
|
def locaux_clubs() :
|
|
""" Retourne le dictionaire des locaux club : {bat: [locaux]} """
|
|
# Corespondance chbre -> nom du local club
|
|
locaux_clubs = { 'Kcl0' : 'Kfet' ,
|
|
'Bcl1' : 'Med',
|
|
'Pcl0' : 'Bds' ,
|
|
'Mcl0' : 'Shape',
|
|
'Mcl1' : 'Krobot',
|
|
'EXT' : 'EXT' }
|
|
# Ajout des locaux d'étage A, B et C
|
|
for b in 'ABC' :
|
|
for i in range(2,7) :
|
|
locaux_clubs['%scl%i' % ( b, i)] = '%i@%s' % (i, b)
|
|
# Ajout de ceux des H, I et J
|
|
for b in 'HIJ' :
|
|
for i in range(1,5) :
|
|
locaux_clubs['%scl%i' % ( b, i)] = '%i@%s' % (i, b)
|
|
# Dédoubleur pour le 3H (digicode)
|
|
locaux_clubs['Hcl3b'] = "3@Hbis"
|
|
# Supression du 2@B et 4@J
|
|
locaux_clubs.pop('Bcl2')
|
|
locaux_clubs.pop('Jcl4')
|
|
|
|
return locaux_clubs
|