[scripts] Going to utf-8
This commit is contained in:
parent
c4a19a88ed
commit
a1bf0a4547
54 changed files with 676 additions and 573 deletions
|
@ -1,21 +1,21 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) Stéphane Glondu, Alexandre Bos, Michel Blockelet
|
||||
# Copyright (C) Stéphane Glondu, Alexandre Bos, Michel Blockelet
|
||||
# Licence : GPLv2
|
||||
|
||||
u"""Ce script permet au secrétaire de repérer plus facilement les membres
|
||||
actifs qui n'ont pas signé la charte du même nom.
|
||||
u"""Ce script permet au secrétaire de repérer plus facilement les membres
|
||||
actifs qui n'ont pas signé la charte du même nom.
|
||||
|
||||
Utilisation :
|
||||
%(prog)s {liste|modif|spam} [--debug <adresse>]
|
||||
|
||||
L'unique option est :
|
||||
--debug <adresse> envoyer tous les mails à l'<adresse> indiquée, plutôt
|
||||
--debug <adresse> envoyer tous les mails à l'<adresse> indiquée, plutôt
|
||||
qu'aux vrais destinataires
|
||||
Les commandes sont :
|
||||
* liste énumérer les membres n'ayant pas signé la charte
|
||||
* modif modifier les membres actifs n'ayant pas signé la charte
|
||||
* liste énumérer les membres n'ayant pas signé la charte
|
||||
* modif modifier les membres actifs n'ayant pas signé la charte
|
||||
* spam envoie des mails de rappel pour les chartes
|
||||
"""
|
||||
|
||||
|
@ -29,7 +29,7 @@ from email_tools import send_email, parse_mail_template
|
|||
# Fonctions d'affichage
|
||||
from affich_tools import coul, tableau, prompt, cprint
|
||||
|
||||
# Importation de la base de données
|
||||
# Importation de la base de données
|
||||
from ldap_crans import crans_ldap, ann_scol
|
||||
db = crans_ldap()
|
||||
|
||||
|
@ -44,12 +44,12 @@ if __name__ == '__main__':
|
|||
sys.argv.pop()
|
||||
|
||||
if debug:
|
||||
cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug)
|
||||
cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug)
|
||||
|
||||
|
||||
def _controle_interactif_adherents(liste):
|
||||
"""
|
||||
Contrôle interactif des adhérents de la liste.
|
||||
Contrôle interactif des adhérents de la liste.
|
||||
Retourne (nb_OK, nb_pas_OK).
|
||||
"""
|
||||
|
||||
|
@ -57,10 +57,10 @@ def _controle_interactif_adherents(liste):
|
|||
if restant == 0:
|
||||
return 0, 0
|
||||
|
||||
cprint(u'\nContrôle des membre actifs' , 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom, Prénom (aid).")
|
||||
cprint(u'\nContrôle des membre actifs' , 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom, Prénom (aid).")
|
||||
cprint(u"")
|
||||
|
||||
nb = 0
|
||||
|
@ -81,7 +81,7 @@ def _controle_interactif_adherents(liste):
|
|||
modifiable.charteMA(True)
|
||||
cprint(modifiable.save())
|
||||
else:
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
elif ok == 'n':
|
||||
if a.charteMA() == True:
|
||||
modifiable = db.search('aid=%s' % a.id(), 'w')['adherent'][0]
|
||||
|
@ -89,16 +89,16 @@ def _controle_interactif_adherents(liste):
|
|||
modifiable.charteMA(False)
|
||||
cprint(modifiable.save())
|
||||
else:
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
else:
|
||||
cprint(u'Arrêt du contrôle %s des membres actifs' % explicite, 'rouge')
|
||||
cprint(u'Arrêt du contrôle %s des membres actifs' % explicite, 'rouge')
|
||||
break
|
||||
|
||||
return nb, len(liste)-nb
|
||||
|
||||
|
||||
def liste_charte_nok():
|
||||
"""Retourne la liste des membres actifs qui n'ont pas signé la charte."""
|
||||
"""Retourne la liste des membres actifs qui n'ont pas signé la charte."""
|
||||
liste_actifs = db.search('droits=*')['adherent']
|
||||
liste_nok = []
|
||||
for adh in liste_actifs:
|
||||
|
@ -110,25 +110,25 @@ def liste_charte_nok():
|
|||
|
||||
def controle_interactif():
|
||||
"""
|
||||
Procédure interactive de contrôle des chartes de membres actifs.
|
||||
Procédure interactive de contrôle des chartes de membres actifs.
|
||||
"""
|
||||
todo_list = liste_charte_nok()
|
||||
|
||||
# Tri de la liste des adhérents selon nom, prénom
|
||||
# Ça peut se faire plus facilement en Python 2.4 avec l'argument key
|
||||
# Tri de la liste des adhérents selon nom, prénom
|
||||
# Ça peut se faire plus facilement en Python 2.4 avec l'argument key
|
||||
todo_list.sort(lambda x, y: cmp((x.nom(), x.prenom()), (y.nom(), y.prenom())))
|
||||
|
||||
# Zou !
|
||||
ok, nok = _controle_interactif_adherents(todo_list)
|
||||
|
||||
cprint(u'\nRécapitulatif des nouveaux contrôles :', 'violet')
|
||||
cprint(u'\nRécapitulatif des nouveaux contrôles :', 'violet')
|
||||
liste = [[u'membres actifs', str(ok), str(nok)]]
|
||||
cprint(tableau(liste,
|
||||
titre = [u'Catégorie', u'OK', u'pas OK'],
|
||||
titre = [u'Catégorie', u'OK', u'pas OK'],
|
||||
largeur = [15, 10, 10]))
|
||||
|
||||
def spammer():
|
||||
# On envoie un mail à chacun des membres actifs qui n'ont pas donné le papier
|
||||
# On envoie un mail à chacun des membres actifs qui n'ont pas donné le papier
|
||||
todo_list = liste_charte_nok()
|
||||
|
||||
if todo_list:
|
||||
|
@ -144,10 +144,10 @@ def spammer():
|
|||
print to
|
||||
if not debug:
|
||||
data = config.mails.txt_charte_MA % {'From' : u"ca@crans.org", 'To' : to}
|
||||
connexion.sendmail("ca@crans.org",to,data.encode('iso-8859-15'))
|
||||
connexion.sendmail("ca@crans.org",to,data.encode('utf-8'))
|
||||
|
||||
def __usage(message=None):
|
||||
""" Comment ça marche ? """
|
||||
""" Comment ça marche ? """
|
||||
cprint(__doc__ % { 'prog': sys.argv[0] })
|
||||
if message:
|
||||
cprint(message)
|
||||
|
@ -161,7 +161,7 @@ if __name__ == '__main__' :
|
|||
elif sys.argv[1] == 'liste':
|
||||
if len(sys.argv) != 2:
|
||||
__usage(u'Mauvaise utilisation de liste')
|
||||
print "Liste des membres actifs n'ayant pas signé la charte :"
|
||||
print "Liste des membres actifs n'ayant pas signé la charte :"
|
||||
for adh in liste_charte_nok():
|
||||
print adh.Nom()
|
||||
elif sys.argv[1] == 'modif':
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) Stéphane Glondu
|
||||
# Copyright (C) Stéphane Glondu
|
||||
# Licence : GPLv2
|
||||
|
||||
u"""Ce script permet au trésorier de repérer plus facilement les papiers que
|
||||
les câbleurs n'ont pas encore rendus.
|
||||
u"""Ce script permet au trésorier de repérer plus facilement les papiers que
|
||||
les câbleurs n'ont pas encore rendus.
|
||||
|
||||
Utilisations possibles :
|
||||
* %(prog)s OPTIONS {paiement|carte|list}
|
||||
* %(prog)s OPTIONS mail <liste>
|
||||
|
||||
Les options sont:
|
||||
-d, --debug <adresse> envoyer tous les mails à l'<adresse> indiquée, plutôt
|
||||
-d, --debug <adresse> envoyer tous les mails à l'<adresse> indiquée, plutôt
|
||||
qu'aux vrais destinataires
|
||||
-h, --help affiche ce message
|
||||
-t, --tri <champ> trier suivant ce champ. Les champs possibles sont:
|
||||
id, nom, cableur ou date. Le défaut est ``nom''
|
||||
id, nom, cableur ou date. Le défaut est ``nom''
|
||||
-i, --inverse trier par ordre inverse
|
||||
|
||||
Les commandes sont :
|
||||
* paiement contrôle interactif des nouvelles (ré-)adhésions
|
||||
* carte contrôle interactif des nouvelles cartes d'étudiant
|
||||
* list affiche le récapitulatif des papiers manquants
|
||||
* mail <liste> envoyer les mails de rappel aux câbleurs dont le
|
||||
login est dans la <liste>, 'bureau' désignant le mail
|
||||
récapitulatif envoyé à bureau ; si la liste est vide
|
||||
tous les mails nécessaires seront envoyés
|
||||
* paiement contrôle interactif des nouvelles (ré-)adhésions
|
||||
* carte contrôle interactif des nouvelles cartes d'étudiant
|
||||
* list affiche le récapitulatif des papiers manquants
|
||||
* mail <liste> envoyer les mails de rappel aux câbleurs dont le
|
||||
login est dans la <liste>, 'bureau' désignant le mail
|
||||
récapitulatif envoyé à bureau ; si la liste est vide
|
||||
tous les mails nécessaires seront envoyés
|
||||
* help affiche ce message
|
||||
|
||||
Le modèle du mail envoyé aux câbleurs est lu sur l'entrée standard (typiquement
|
||||
via une redirection). Les trois premières lignes doivent être :
|
||||
Le modèle du mail envoyé aux câbleurs est lu sur l'entrée standard (typiquement
|
||||
via une redirection). Les trois premières lignes doivent être :
|
||||
Encoding: <encodage du fichier>
|
||||
Subject: <sujet du mail>
|
||||
<ligne vide>
|
||||
Le reste est le corps du message. Il doit contenir une occurrence de '%%s' qui
|
||||
sera remplacée par la liste des papiers manquants.
|
||||
sera remplacée par la liste des papiers manquants.
|
||||
|
||||
Le mail récapitulatif envoyé à bureau est immuable."""
|
||||
Le mail récapitulatif envoyé à bureau est immuable."""
|
||||
|
||||
|
||||
import sys, os, re, getopt
|
||||
|
@ -46,21 +46,21 @@ sys.path.append('/usr/scripts/gestion')
|
|||
# Fonctions d'affichage
|
||||
from affich_tools import coul, tableau, prompt, cprint
|
||||
|
||||
# Importation de la base de données
|
||||
# Importation de la base de données
|
||||
from ldap_crans import crans_ldap, ann_scol
|
||||
db = crans_ldap()
|
||||
|
||||
# Détermination de l'uid du câbleur
|
||||
# Détermination de l'uid du câbleur
|
||||
from user_tests import getuser
|
||||
uid = getuser()
|
||||
if not uid :
|
||||
cprint(u"Impossible de déterminer l'utilisateur !")
|
||||
cprint(u"Impossible de déterminer l'utilisateur !")
|
||||
sys.exit(1)
|
||||
cableur = db.search('uid=%s' % uid)['adherent'][0]
|
||||
|
||||
# Vérification des droits
|
||||
# Vérification des droits
|
||||
if u'Tresorier' not in cableur.droits():
|
||||
cprint(u"Il faut etre tresorier pour exécuter ce script !")
|
||||
cprint(u"Il faut etre tresorier pour exécuter ce script !")
|
||||
sys.exit(1)
|
||||
|
||||
# Lors des tests, on m'envoie tous les mails !
|
||||
|
@ -77,19 +77,19 @@ if gethostname().split(".")[0] == 'egon':
|
|||
|
||||
def _controle_interactif_adherents(liste, quoi):
|
||||
"""
|
||||
Contrôle interactif des adhérents de la liste (quoi = p ou c).
|
||||
Contrôle interactif des adhérents de la liste (quoi = p ou c).
|
||||
Retourne (nb_OK, nb_pas_OK).
|
||||
"""
|
||||
if quoi not in 'pc': raise ValueError
|
||||
explicite = {'p': u'du paiement', 'c': u"de la carte d'étudiant"}[quoi]
|
||||
explicite = {'p': u'du paiement', 'c': u"de la carte d'étudiant"}[quoi]
|
||||
restant = len(liste)
|
||||
if restant == 0:
|
||||
return 0, 0
|
||||
|
||||
cprint(u'\nContrôle %s des adhérents' % explicite, 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom, Prénom (aid).")
|
||||
cprint(u'\nContrôle %s des adhérents' % explicite, 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom, Prénom (aid).")
|
||||
cprint(u"")
|
||||
|
||||
nb = 0
|
||||
|
@ -104,9 +104,9 @@ def _controle_interactif_adherents(liste, quoi):
|
|||
cprint(modifiable.save())
|
||||
nb += 1
|
||||
else:
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
elif ok != 'n':
|
||||
cprint(u'Arrêt du contrôle %s des adhérents' % explicite, 'rouge')
|
||||
cprint(u'Arrêt du contrôle %s des adhérents' % explicite, 'rouge')
|
||||
break
|
||||
|
||||
return nb, len(liste)-nb
|
||||
|
@ -114,16 +114,16 @@ def _controle_interactif_adherents(liste, quoi):
|
|||
|
||||
def _controle_interactif_clubs(liste):
|
||||
"""
|
||||
Contrôle interactif des clubs de la liste (uniquement la charte).
|
||||
Contrôle interactif des clubs de la liste (uniquement la charte).
|
||||
Retourne (nb_OK, nb_pas_OK).
|
||||
"""
|
||||
restant = len(liste)
|
||||
if restant == 0:
|
||||
return 0, 0
|
||||
|
||||
cprint(u'\nContrôle de la charte des clubs', 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n'.")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u'\nContrôle de la charte des clubs', 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n'.")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom (cid).")
|
||||
cprint(u"")
|
||||
|
||||
|
@ -139,17 +139,17 @@ def _controle_interactif_clubs(liste):
|
|||
cprint(modifiable.save())
|
||||
nb += 1
|
||||
else:
|
||||
cprint(u'Club %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
cprint(u'Club %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
elif ok != 'n':
|
||||
cprint(u'Arrêt du contrôle de la charte des clubs', 'rouge')
|
||||
cprint(u'Arrêt du contrôle de la charte des clubs', 'rouge')
|
||||
break
|
||||
|
||||
return nb, len(liste)-nb
|
||||
|
||||
def qui(historique, quoi):
|
||||
"""
|
||||
Recherche le câbleur qui a effectué la dernière modification quoi
|
||||
dans l'historique, ou qui a inscrit l'adhérent.
|
||||
Recherche le câbleur qui a effectué la dernière modification quoi
|
||||
dans l'historique, ou qui a inscrit l'adhérent.
|
||||
Retourne le couple (date, cableur) ou ('_inconnu_', '_inconnu_').
|
||||
"""
|
||||
regexp = re.compile(r'^([^,]*), ([^ :]*)')
|
||||
|
@ -166,13 +166,13 @@ def qui(historique, quoi):
|
|||
|
||||
def controle_interactif(quoi):
|
||||
"""
|
||||
Procédure interactive de contrôle des paiements/chartes (quoi=p) et cartes (quoi=c).
|
||||
Procédure interactive de contrôle des paiements/chartes (quoi=p) et cartes (quoi=c).
|
||||
"""
|
||||
if quoi not in 'pc': raise ValueError
|
||||
todo_list = db.search('%s=%d&controle!=*%s*'
|
||||
% ({'p': 'paiement', 'c': 'carteEtudiant'}[quoi], ann_scol, quoi))
|
||||
|
||||
# Tri de la liste des adhérents selon nom, prénom
|
||||
# Tri de la liste des adhérents selon nom, prénom
|
||||
todo_list['adherent'].sort(key = lambda x: (x.nom(), x.prenom()))
|
||||
|
||||
if trier_par == 'id':
|
||||
|
@ -183,7 +183,7 @@ def controle_interactif(quoi):
|
|||
champ = { 'date': 0, 'cableur': 1 }[trier_par]
|
||||
todo_list['adherent'].sort(key = lambda x: qui(x.historique(), r'paiement')[champ])
|
||||
|
||||
# Traitement des adhérents
|
||||
# Traitement des adhérents
|
||||
oka, noka = _controle_interactif_adherents(todo_list['adherent'], quoi)
|
||||
|
||||
if quoi == 'p':
|
||||
|
@ -193,18 +193,18 @@ def controle_interactif(quoi):
|
|||
# Traitement des clubs (uniquement la charte)
|
||||
okc, nokc =_controle_interactif_clubs(todo_list['club'])
|
||||
|
||||
cprint(u'\nRécapitulatif des nouveaux contrôles +%s :' % quoi, 'violet')
|
||||
liste = [[u'adhérents', str(oka), str(noka)]]
|
||||
cprint(u'\nRécapitulatif des nouveaux contrôles +%s :' % quoi, 'violet')
|
||||
liste = [[u'adhérents', str(oka), str(noka)]]
|
||||
if quoi == 'p':
|
||||
liste.append([u'clubs', str(okc), str(nokc)])
|
||||
cprint(tableau(liste,
|
||||
titre = [u'Catégorie', u'OK', u'pas OK'],
|
||||
titre = [u'Catégorie', u'OK', u'pas OK'],
|
||||
largeur = [15, 10, 10]))
|
||||
|
||||
|
||||
def formater_pour_cableur(liste):
|
||||
"""
|
||||
Formate la liste d'adhérents ou de clubs avec les dates correspondantes.
|
||||
Formate la liste d'adhérents ou de clubs avec les dates correspondantes.
|
||||
liste est une liste de couples (date, objet).
|
||||
"""
|
||||
lignes = []
|
||||
|
@ -231,8 +231,8 @@ def formater_pour_cableur(liste):
|
|||
|
||||
def formater_pour_bureau(dico):
|
||||
"""
|
||||
Formate la liste d'adhérents ou de clubs avec les câbleurs correspondantes
|
||||
pour le mail récapitulatif envoyé à bureau.
|
||||
Formate la liste d'adhérents ou de clubs avec les câbleurs correspondantes
|
||||
pour le mail récapitulatif envoyé à bureau.
|
||||
"""
|
||||
lignes = []
|
||||
total = 0
|
||||
|
@ -253,15 +253,15 @@ def formater_pour_bureau(dico):
|
|||
if tri_inverse: lignes.reverse()
|
||||
|
||||
return tableau(lignes,
|
||||
titre = [u'id', u'Nom', u'Câbleur', u'Date'],
|
||||
titre = [u'id', u'Nom', u'Câbleur', u'Date'],
|
||||
largeur = [6, 40, 18, 18],
|
||||
alignement = ['d', 'c', 'c', 'c']) + u'\nTotal : %d' % total
|
||||
|
||||
|
||||
def chercher_cableurs(liste, quoi):
|
||||
"""
|
||||
Renvoie un dictionnaire cableur->adherents à partir de liste, quoi
|
||||
désigne le champ qui sera recherché dans l'historique.
|
||||
Renvoie un dictionnaire cableur->adherents à partir de liste, quoi
|
||||
désigne le champ qui sera recherché dans l'historique.
|
||||
"""
|
||||
resultat = {}
|
||||
|
||||
|
@ -275,21 +275,21 @@ def chercher_cableurs(liste, quoi):
|
|||
|
||||
from email_tools import send_email, parse_mail_template
|
||||
|
||||
# Mise en application du mémorable cours de Fred sur les objets :-)
|
||||
# Mise en application du mémorable cours de Fred sur les objets :-)
|
||||
|
||||
class ControleMailer:
|
||||
|
||||
def __init__(self):
|
||||
# Recherche des câbleurs possédant des cotisations/chartes
|
||||
# Recherche des câbleurs possédant des cotisations/chartes
|
||||
todo_list = db.search('paiement=%d&controle!=*p*' % ann_scol)
|
||||
self._paiements = chercher_cableurs(todo_list['adherent'], r'(paiement|controle.*\+k)')
|
||||
self._chartes = chercher_cableurs(todo_list['club'], 'paiement')
|
||||
|
||||
# Recherche des câbleurs possédant des cartes d'étudiant
|
||||
# Recherche des câbleurs possédant des cartes d'étudiant
|
||||
todo_list = db.search('carteEtudiant=%d&controle!=*c*' % ann_scol)
|
||||
self._cartes = chercher_cableurs(todo_list['adherent'], 'carteEtudiant')
|
||||
|
||||
# Récupère tous les câbleurs qui doivent quelque chose
|
||||
# Récupère tous les câbleurs qui doivent quelque chose
|
||||
cableurs = {}
|
||||
for a in self._paiements.keys():
|
||||
if a != '_inconnu_': cableurs[a] = None
|
||||
|
@ -299,14 +299,14 @@ class ControleMailer:
|
|||
if a != '_inconnu_': cableurs[a] = None
|
||||
self._cableurs = cableurs.keys()
|
||||
|
||||
# Vérification de l'alias pour l'expéditeur
|
||||
# Vérification de l'alias pour l'expéditeur
|
||||
if u'tresorier' in cableur.alias():
|
||||
self._sender = u'%s <tresorier@crans.org>' % cableur.Nom()
|
||||
else:
|
||||
self._sender = u'%s <%s@crans.org>' % (cableur.Nom(),
|
||||
cableur.canonical_alias() or cableur.mail())
|
||||
|
||||
# Se connecte au serveur SMTP par défaut
|
||||
# Se connecte au serveur SMTP par défaut
|
||||
from smtplib import SMTP
|
||||
self._server = SMTP()
|
||||
self._server.connect()
|
||||
|
@ -317,47 +317,47 @@ class ControleMailer:
|
|||
|
||||
def recapitulatif(self):
|
||||
"""
|
||||
Renvoie le récapitulatif pour le bureau.
|
||||
Renvoie le récapitulatif pour le bureau.
|
||||
"""
|
||||
msg = u''
|
||||
|
||||
if self._paiements:
|
||||
msg += u"Fiches d'adhésion et cotisations et/ou caution des adhérents :\n"
|
||||
msg += u"Fiches d'adhésion et cotisations et/ou caution des adhérents :\n"
|
||||
msg += formater_pour_bureau(self._paiements) + '\n\n'
|
||||
|
||||
if self._chartes:
|
||||
msg += u"Chartes signées des clubs :\n"
|
||||
msg += u"Chartes signées des clubs :\n"
|
||||
msg += formater_pour_bureau(self._chartes) + '\n\n'
|
||||
|
||||
if self._cartes:
|
||||
msg += u"Carte d'étudiant des adhérents :\n"
|
||||
msg += u"Carte d'étudiant des adhérents :\n"
|
||||
msg += formater_pour_bureau(self._cartes) + '\n\n'
|
||||
|
||||
return msg.strip()
|
||||
|
||||
def mail_bureau(self):
|
||||
"""
|
||||
Envoie le mail récapitulatif à bureau (s'il y a qqch à envoyer).
|
||||
Envoie le mail récapitulatif à bureau (s'il y a qqch à envoyer).
|
||||
"""
|
||||
msg = self.recapitulatif()
|
||||
if msg:
|
||||
msg += u"\n\n-- \nScript exécuté par %s\n" % cableur.Nom()
|
||||
msg += u"\n\n-- \nScript exécuté par %s\n" % cableur.Nom()
|
||||
send_email(self._sender,
|
||||
u"Bureau <bureau@crans.org>",
|
||||
u"Récapitulatif des papiers manquants",
|
||||
u"Récapitulatif des papiers manquants",
|
||||
msg,
|
||||
server = self._server,
|
||||
debug = debug)
|
||||
return coul(u'Mail envoyé à bureau avec succès !', 'vert')
|
||||
return coul(u'Mail envoyé à bureau avec succès !', 'vert')
|
||||
else:
|
||||
return coul(u'Tout est à jour, aucun mail envoyé.', 'vert')
|
||||
return coul(u'Tout est à jour, aucun mail envoyé.', 'vert')
|
||||
|
||||
def mail_cableurs(self, subject, body, liste=None):
|
||||
"""
|
||||
Envoie un mail aux câbleurs concernés qui figurent dans la liste.
|
||||
Si liste vaut None, envoie un mail à tous les câbleurs concernés.
|
||||
Envoie un mail aux câbleurs concernés qui figurent dans la liste.
|
||||
Si liste vaut None, envoie un mail à tous les câbleurs concernés.
|
||||
Les arguments subject, body permettent de personnaliser (un peu)
|
||||
le mail qui sera envoyé.
|
||||
le mail qui sera envoyé.
|
||||
"""
|
||||
nb = 0
|
||||
if liste == None:
|
||||
|
@ -367,15 +367,15 @@ class ControleMailer:
|
|||
msg = u''
|
||||
|
||||
if self._paiements.has_key(c):
|
||||
msg += u"Fiches d'adhésion, cotisations et/ou caution des adhérents :\n"
|
||||
msg += u"Fiches d'adhésion, cotisations et/ou caution des adhérents :\n"
|
||||
msg += formater_pour_cableur(self._paiements[c]) + '\n\n'
|
||||
|
||||
if self._chartes.has_key(c):
|
||||
msg += u"Chartes signées des clubs :\n"
|
||||
msg += u"Chartes signées des clubs :\n"
|
||||
msg += formater_pour_cableur(self._chartes[c]) + '\n\n'
|
||||
|
||||
if self._cartes.has_key(c):
|
||||
msg += u"Carte d'étudiant des adhérents :\n"
|
||||
msg += u"Carte d'étudiant des adhérents :\n"
|
||||
msg += formater_pour_cableur(self._cartes[c]) + '\n\n'
|
||||
|
||||
if msg:
|
||||
|
@ -388,11 +388,11 @@ class ControleMailer:
|
|||
debug = debug)
|
||||
nb += 1
|
||||
|
||||
return coul(u'%d mail(s) envoyé(s) aux câbleurs avec succès !' % nb, 'vert')
|
||||
return coul(u'%d mail(s) envoyé(s) aux câbleurs avec succès !' % nb, 'vert')
|
||||
|
||||
|
||||
def __usage(message=None):
|
||||
""" Comment ça marche ? """
|
||||
""" Comment ça marche ? """
|
||||
cprint(__doc__ % { 'prog': sys.argv[0] })
|
||||
if message:
|
||||
cprint(message)
|
||||
|
@ -412,7 +412,7 @@ if __name__ == '__main__' :
|
|||
|
||||
elif opt in [ '-d', '--debug' ]:
|
||||
debug = val
|
||||
cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug)
|
||||
cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug)
|
||||
|
||||
elif opt in [ '-t', '--tri' ]:
|
||||
if val in [ 'id', 'nom', 'cableur', 'date' ]:
|
||||
|
@ -424,7 +424,7 @@ if __name__ == '__main__' :
|
|||
tri_inverse = True
|
||||
|
||||
else:
|
||||
__usage("option inconnue « %s »'" % opt)
|
||||
__usage("option inconnue « %s »'" % opt)
|
||||
|
||||
if len(arg) == 0 or arg[0] == 'help':
|
||||
__usage()
|
||||
|
@ -456,14 +456,14 @@ if __name__ == '__main__' :
|
|||
bureau = True
|
||||
cableurs = mailer._cableurs
|
||||
if cableurs:
|
||||
cprint(u'Des mails vont être envoyés aux câbleurs, lecture du modèle...')
|
||||
cprint(u'Des mails vont être envoyés aux câbleurs, lecture du modèle...')
|
||||
subject, body = parse_mail_template(sys.stdin)
|
||||
try:
|
||||
body % u''
|
||||
except TypeError:
|
||||
cprint(u"Le format du modèle n'est pas correct, arrêt.")
|
||||
cprint(u"Le format du modèle n'est pas correct, arrêt.")
|
||||
sys.exit(1)
|
||||
cprint(u'Modèle OK, on envoie les mails...')
|
||||
cprint(u'Modèle OK, on envoie les mails...')
|
||||
cprint(mailer.mail_cableurs(subject, body, cableurs))
|
||||
if bureau:
|
||||
cprint(mailer.mail_bureau())
|
||||
|
|
|
@ -47,7 +47,7 @@ if u'Tresorier' not in cableur.droits():
|
|||
|
||||
dlg = dialog.Dialog()
|
||||
dlg.setBackgroundTitle('Tresorerie')
|
||||
encoding = sys.stdin.encoding or 'ISO-8859-15'
|
||||
encoding = sys.stdin.encoding or 'UTF-8'
|
||||
|
||||
########################################################################
|
||||
# Retrait des accents
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
|
||||
# Copyright (C) Stéphane Glondu, Alexandre Bos
|
||||
# Copyright (C) Stéphane Glondu, Alexandre Bos
|
||||
# Licence : GPLv2
|
||||
|
||||
__doc__ = u"""Ce script permet de faire le menages parmis les câbleurs qui ne
|
||||
sont plus sur le campus, ie ceux qui ne sont plus à jour de cotisation.
|
||||
__doc__ = u"""Ce script permet de faire le menages parmis les câbleurs qui ne
|
||||
sont plus sur le campus, ie ceux qui ne sont plus à jour de cotisation.
|
||||
|
||||
Utilisation :
|
||||
%(prog)s {lister|radier} [--debug <adresse>]
|
||||
|
||||
Les commandes sont :
|
||||
* lister afficher la liste des câbleurs succeptibles d'être
|
||||
radiés
|
||||
* lister afficher la liste des câbleurs succeptibles d'être
|
||||
radiés
|
||||
* radier selectionner, parmis eux, les cableurs que l'on
|
||||
souhaite radier
|
||||
"""
|
||||
|
@ -28,23 +28,23 @@ from email_tools import send_email, parse_mail_template
|
|||
# Fonctions d'affichage
|
||||
from affich_tools import coul, tableau, prompt, cprint
|
||||
|
||||
# Importation de la base de données
|
||||
# Importation de la base de données
|
||||
from ldap_crans import crans_ldap, ann_scol
|
||||
db = crans_ldap()
|
||||
|
||||
def _controle_interactif_adherents(liste):
|
||||
"""
|
||||
Demande ce qu'il faut faire à chaque fois
|
||||
Demande ce qu'il faut faire à chaque fois
|
||||
"""
|
||||
|
||||
restant = len(liste)
|
||||
if restant == 0:
|
||||
return 0, 0
|
||||
|
||||
cprint(u'\nRadiation des câbleurs fantômes' , 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom, Prénom (aid).")
|
||||
cprint(u'\nRadiation des câbleurs fantômes' , 'cyan')
|
||||
cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).")
|
||||
cprint(u"Une autre réponse entraîne l'interruption du processus.")
|
||||
cprint(u"Le format est [nb_restant] Nom, Prénom (aid).")
|
||||
cprint(u"")
|
||||
|
||||
nb = 0
|
||||
|
@ -58,9 +58,9 @@ def _controle_interactif_adherents(liste):
|
|||
modifiable.droits([])
|
||||
cprint(modifiable.save())
|
||||
else:
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
|
||||
elif ok != 'n':
|
||||
cprint(u'Arrêt du contrôle %s des membres actifs' % explicite, 'rouge')
|
||||
cprint(u'Arrêt du contrôle %s des membres actifs' % explicite, 'rouge')
|
||||
break
|
||||
|
||||
def candidats():
|
||||
|
@ -74,10 +74,10 @@ def candidats():
|
|||
|
||||
def lister():
|
||||
"""
|
||||
Afficher les câbleurs fantômes potentiels.
|
||||
Afficher les câbleurs fantômes potentiels.
|
||||
"""
|
||||
todo_list = candidats()
|
||||
print "Liste des câbleur dont la cotisation n'est pas à jour."
|
||||
print "Liste des câbleur dont la cotisation n'est pas à jour."
|
||||
print
|
||||
for adh in todo_list:
|
||||
print adh.prenom() + " " + adh.nom()
|
||||
|
@ -86,7 +86,7 @@ def lister():
|
|||
|
||||
def controle_interactif():
|
||||
"""
|
||||
Procédure interactive de radiations des câbleurs fantômes.
|
||||
Procédure interactive de radiations des câbleurs fantômes.
|
||||
"""
|
||||
todo_list = candidats()
|
||||
|
||||
|
@ -94,7 +94,7 @@ def controle_interactif():
|
|||
_controle_interactif_adherents(todo_list)
|
||||
|
||||
def __usage(message=None):
|
||||
""" Comment ça marche ? """
|
||||
""" Comment ça marche ? """
|
||||
|
||||
cprint(__doc__ % { 'prog': sys.argv[0] })
|
||||
if message:
|
||||
|
|
|
@ -18,11 +18,11 @@ except:
|
|||
pass
|
||||
|
||||
if not encoding:
|
||||
encoding = sys.stdin.encoding or "ISO-8859-15"
|
||||
encoding = sys.stdin.encoding or 'UTF-8'
|
||||
|
||||
# Si aucune locale n'est définie, on se met en ISO-8859-15
|
||||
# Si aucune locale n'est définie, on se met en...
|
||||
if encoding == "ANSI_X3.4-1968":
|
||||
encoding = "ISO-8859-15"
|
||||
encoding = 'UTF-8'
|
||||
|
||||
if 'TERM' in os.environ and os.environ['TERM'] != 'unknown':
|
||||
el = subprocess.Popen('tput cr ; tput el', shell=True, stdout=subprocess.PIPE).stdout.read()
|
||||
|
@ -115,7 +115,7 @@ def to_unicode(txt, enc=encoding):
|
|||
return txt.decode("UTF-8")
|
||||
except:
|
||||
# Sinon c'est surement de l'iso
|
||||
return txt.decode("ISO8859-15")
|
||||
return txt.decode("UTF-8")
|
||||
|
||||
def to_encoding(txt, enc=encoding):
|
||||
return to_unicode(txt).encode(enc, 'ignore')
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#: Envoyé à la ML disconnect@ en cas de déconnexion pour p2p
|
||||
avertissement = u"""From: %(From)s
|
||||
To: %(To)s
|
||||
Subject: =?iso-8859-1?Q?D=E9tection?= de p2p sur la machine %(hostname)s
|
||||
Subject: =?utf-8?q?D=C3=A9tection?= de p2p sur la machine %(hostname)s
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
La machine %(hostname)s a été déconnectée pendant 24h pour
|
||||
|
@ -20,7 +20,7 @@ Message créé par deconnexion.py"""
|
|||
#: Envoyé à l'adhérent en cas de déconnexion pour p2p
|
||||
deconnexion = u"""From: %(From)s
|
||||
To: %(To)s
|
||||
Subject: Avis de =?iso-8859-15?Q?D=E9connexion?=
|
||||
Subject: Avis de =?utf-8?q?D=C3=A9connexion?=
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
Bonjour,
|
||||
|
@ -81,7 +81,7 @@ Disconnect Team"""
|
|||
#: Envoyé à la ML disconnect@ en cas de déconnexion pour p2p plusieurs fois
|
||||
message_disconnect_multi = u"""From: %(from)s
|
||||
To: %(to)s
|
||||
Subject: %(proprio)s a =?iso-8859-15?Q?=E9t=E9=20d=E9connect=E9?= %(nbdeco)d fois pour p2p en un an !
|
||||
Subject: %(proprio)s a =?utf-8?q?=C3=A9t=C3=A9_d=C3=A9connect=C3=A9?= %(nbdeco)d fois pour p2p en un an !
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
L'adhérent %(proprio)s a été déconnecté %(nbdeco)d fois pour p2p en un an !
|
||||
|
@ -90,4 +90,4 @@ Le PS a été généré et se trouve sur zamok :
|
|||
%(ps)s
|
||||
|
||||
--\u0020
|
||||
Message créé par deconnexion.py"""
|
||||
Message créé par deconnexion.py"""
|
||||
|
|
|
@ -124,7 +124,7 @@ Message créé par deconnexion.py"""
|
|||
#: Envoyé à la ML disconnect@ en cas de dépassement de la limite hard
|
||||
message_disconnect_hard = u"""From: %(from)s
|
||||
To: %(to)s
|
||||
Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20brid=E9?=
|
||||
Subject: %(proprio)s a =?utf-8?q?=C3=A9t=C3=A9_brid=C3=A9?=
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
%(proprio)s (%(id)s) a été limité en débit montant du fait d'un
|
||||
|
@ -141,7 +141,7 @@ Message créé par deconnexion.py"""
|
|||
#: Envoyé à la ML disconnect@ en cas de dépassement de la limite hard plusieurs fois
|
||||
message_disconnect_multi = u"""From: %(from)s
|
||||
To: %(to)s
|
||||
Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20brid=E9?=
|
||||
Subject: %(proprio)s a =?utf-8?q?=C3=A9t=C3=A9_brid=C3=A9?=
|
||||
%(nbdeco)d fois pour upload en un mois !
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ format_sender et send_email adaptés depuis /usr/scripts/impression/crans_backen
|
|||
import re
|
||||
|
||||
|
||||
def format_sender(sender, header_charset='ISO-8859-15'):
|
||||
def format_sender(sender, header_charset='utf-8'):
|
||||
"""
|
||||
Check and format sender for header.
|
||||
"""
|
||||
|
@ -42,8 +42,8 @@ def send_email(sender, recipient, subject, body, server='localhost', cc=None, de
|
|||
Only the real name part of sender and recipient addresses may contain
|
||||
non-ASCII characters. The email will be properly MIME encoded.
|
||||
|
||||
The charset of the email will be the first one out of US-ASCII, ISO-8859-15
|
||||
and UTF-8 that can represent all the characters occurring in the email.
|
||||
The charset of the email will be the first one out of US-ASCII or UTF-8
|
||||
that can represent all the characters occurring in the email.
|
||||
|
||||
Argument server maybe a string, indicating the name of the SMTP server, or
|
||||
directly an instance of smtplib.SMTP.
|
||||
|
@ -57,10 +57,10 @@ def send_email(sender, recipient, subject, body, server='localhost', cc=None, de
|
|||
|
||||
# Header class is smart enough to try US-ASCII, then the charset we
|
||||
# provide, then fall back to UTF-8.
|
||||
header_charset = 'ISO-8859-15'
|
||||
header_charset = 'UTF-8'
|
||||
|
||||
# We must choose the body charset manually
|
||||
for body_charset in 'US-ASCII', 'ISO-8859-15', 'UTF-8':
|
||||
for body_charset in 'US-ASCII', 'UTF-8':
|
||||
try:
|
||||
body.encode(body_charset)
|
||||
except UnicodeError:
|
||||
|
|
30
gestion/gen_confs/__init__.py
Executable file → Normal file
30
gestion/gen_confs/__init__.py
Executable file → Normal file
|
@ -1,9 +1,9 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Package pour la génération des fichiers de conf
|
||||
""" Package pour la génération des fichiers de conf
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
|
@ -18,11 +18,11 @@ import config
|
|||
from tempfile import NamedTemporaryFile
|
||||
|
||||
class gen_config :
|
||||
""" Base pour toutes les classes de génération de fichiers de conf """
|
||||
""" Base pour toutes les classes de génération de fichiers de conf """
|
||||
base = None
|
||||
debug = 0
|
||||
_locked = 0
|
||||
__restore={} # pour restorer la config d'origine en cas d'erreur de génération
|
||||
__restore={} # pour restorer la config d'origine en cas d'erreur de génération
|
||||
|
||||
def lockname(self):
|
||||
"""Nom du lock"""
|
||||
|
@ -39,7 +39,7 @@ class gen_config :
|
|||
if self._locked : remove_lock(self.lockname())
|
||||
|
||||
def __del__(self) :
|
||||
# Au cas où...
|
||||
# Au cas où...
|
||||
self.unlock()
|
||||
|
||||
def _restore(self) :
|
||||
|
@ -54,12 +54,12 @@ class gen_config :
|
|||
os.system('cp -f %s %s' % ( f.name, nom ) )
|
||||
|
||||
def _open_conf(self,nom,comment=None) :
|
||||
""" Créé un fichier
|
||||
si comment est fourni, insère une entète qui utilisera le caractère
|
||||
""" Créé un fichier
|
||||
si comment est fourni, insère une entète qui utilisera le caractère
|
||||
de commentaire fourni
|
||||
|
||||
copie l'ancien fichier dans un fichier temporaire pour permettre
|
||||
la restauration en cas d'échec de la configuration
|
||||
la restauration en cas d'échec de la configuration
|
||||
|
||||
Retourne le descripteur du fichier """
|
||||
|
||||
|
@ -89,15 +89,15 @@ class gen_config :
|
|||
return fd
|
||||
|
||||
def gen_conf(self) :
|
||||
""" Génération des fichiers de conf, retourne False si erreur """
|
||||
""" Génération des fichiers de conf, retourne False si erreur """
|
||||
self.lock()
|
||||
self.anim = anim('\tgénération fichiers')
|
||||
self.anim = anim('\tgénération fichiers')
|
||||
try :
|
||||
warn = self._gen()
|
||||
if warn :
|
||||
self.anim.reinit()
|
||||
print WARNING
|
||||
if self.debug : sys.stderr.write(warn.encode("ISO-8859-15"))
|
||||
if self.debug : sys.stderr.write(warn.encode("UTF-8"))
|
||||
else :
|
||||
self.anim.reinit()
|
||||
print OK
|
||||
|
@ -110,7 +110,7 @@ class gen_config :
|
|||
return False
|
||||
|
||||
def restart(self) :
|
||||
""" Redémarrage du service concerné """
|
||||
""" Redémarrage du service concerné """
|
||||
if not self.restart_cmd : return
|
||||
self.lock()
|
||||
self.anim = anim('\trestart')
|
||||
|
@ -127,8 +127,8 @@ class gen_config :
|
|||
self.unlock()
|
||||
|
||||
def reconfigure(self) :
|
||||
""" Génère les fichiers puis redémarre le service
|
||||
si la génération c'est bien passée """
|
||||
""" Génère les fichiers puis redémarre le service
|
||||
si la génération c'est bien passée """
|
||||
cprint(u'Reconfiguration %s :' % self.__str__(), 'gras')
|
||||
if self.gen_conf() :
|
||||
return self.restart()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) Frédéric Pauget
|
||||
# Copyright (C) Frédéric Pauget
|
||||
# Licence : GPLv2
|
||||
|
||||
import smtplib, sys, commands, shutil, os, traceback
|
||||
|
@ -18,7 +18,7 @@ try:
|
|||
from Mailman.UserDesc import UserDesc
|
||||
from Mailman.Errors import MMAlreadyAMember
|
||||
except:
|
||||
# Machine sans mailman, les ML ne seront pas reconfigurées
|
||||
# Machine sans mailman, les ML ne seront pas reconfigurées
|
||||
pass
|
||||
|
||||
|
||||
|
@ -101,7 +101,7 @@ class home:
|
|||
self.args = args
|
||||
|
||||
def reconfigure(self):
|
||||
cprint(u'Création home', 'gras')
|
||||
cprint(u'Création home', 'gras')
|
||||
for args in self.args:
|
||||
anim('\t' + args)
|
||||
try:
|
||||
|
@ -116,11 +116,11 @@ class home:
|
|||
os.mkdir(home, 0755)
|
||||
os.chown(home, int(uid), config.gid)
|
||||
elif os.path.isdir(home):
|
||||
# Il y un répertoire existant
|
||||
# Il y un répertoire existant
|
||||
# Bon UID ?
|
||||
stat = os.stat(home)
|
||||
if stat[4] != int(uid) or stat[5] != config.gid:
|
||||
# Le home n'est pas pas à la bonne personne
|
||||
# Le home n'est pas pas à la bonne personne
|
||||
raise OSError('home existant')
|
||||
|
||||
### Quota
|
||||
|
@ -226,7 +226,7 @@ class ML_ens:
|
|||
try:
|
||||
mlist.ApprovedAddMember(UserDesc(mail))
|
||||
except MMAlreadyAMember:
|
||||
cprint(u"DÉJÀ INSCRIT", "jaune")
|
||||
cprint(u"DÉJÀ INSCRIT", "jaune")
|
||||
except:
|
||||
print ERREUR
|
||||
if self.debug:
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Génération de la configuration pour bind9
|
||||
""" Génération de la configuration pour bind9
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
import time, sys, re, hashlib, base64, os
|
||||
|
@ -56,36 +56,36 @@ def netv6_to_arpa(net):
|
|||
|
||||
class dns(gen_config) :
|
||||
"""
|
||||
Génération des fichiers de configuration de bind9 :
|
||||
* fichier DNS_CONF qui contient les définitions de zone conformément
|
||||
à zone_template. Ce fichier doit être inclus à partir de la config statique
|
||||
Génération des fichiers de configuration de bind9 :
|
||||
* fichier DNS_CONF qui contient les définitions de zone conformément
|
||||
à zone_template. Ce fichier doit être inclus à partir de la config statique
|
||||
de bind
|
||||
* les fichiers de zones, ce sont eux qui contiennent les données du
|
||||
dns, ils ont appellés par le fichier DNS_CONF et sont générés dans DNS_DIR
|
||||
Leur entète est générée à partir de zone_entete.
|
||||
* les fichiers de zones, ce sont eux qui contiennent les données du
|
||||
dns, ils ont appellés par le fichier DNS_CONF et sont générés dans DNS_DIR
|
||||
Leur entète est générée à partir de zone_entete.
|
||||
|
||||
Les fichiers générés placent bind comme autoritaire sur les noms de
|
||||
zones_direct et les adresses de zones_reverse. Les données proviennent de
|
||||
Les fichiers générés placent bind comme autoritaire sur les noms de
|
||||
zones_direct et les adresses de zones_reverse. Les données proviennent de
|
||||
la base LDAP
|
||||
"""
|
||||
######################################PARTIE DE CONFIGURATION
|
||||
|
||||
### Fichiers à écrire
|
||||
# Répertoire d'écriture des fichiers de zone
|
||||
DNS_DIR = '/etc/bind/generated/' # Avec un / à la fin
|
||||
DNSSEC_DIR = '/etc/bind/signed/' # Avec un / à la fin
|
||||
# Fichier de définition des zones pour le maître
|
||||
### Fichiers à écrire
|
||||
# Répertoire d'écriture des fichiers de zone
|
||||
DNS_DIR = '/etc/bind/generated/' # Avec un / à la fin
|
||||
DNSSEC_DIR = '/etc/bind/signed/' # Avec un / à la fin
|
||||
# Fichier de définition des zones pour le maître
|
||||
DNS_CONF = DNS_DIR + 'zones_crans'
|
||||
|
||||
# Fichier de définition des zones pour les esclaves géré par BCfg2
|
||||
# Fichier de définition des zones pour les esclaves géré par BCfg2
|
||||
DNS_CONF_BCFG2 = "/var/lib/bcfg2/Cfg/etc/bind/generated/zones_crans/zones_crans"
|
||||
|
||||
### Sur quelles zones on a autorité ?
|
||||
## En cas de modification de ces zones penser à regéner le fichier de
|
||||
### Sur quelles zones on a autorité ?
|
||||
## En cas de modification de ces zones penser à regéner le fichier de
|
||||
## zone des esclaves (sur le serveur principal de bcfg2 : python /usr/scripts/gestion/gen_confs/bind.py puis lancer bcfg2 sur les miroirs)
|
||||
# Résolution directe
|
||||
# Résolution directe
|
||||
zones_direct = config.dns.zones_direct
|
||||
# Zones signée par opendnssec sur le serveur maitre
|
||||
# Zones signée par opendnssec sur le serveur maitre
|
||||
zones_dnssec = config.dns.zones_dnssec
|
||||
# Zones alias pour les enregistrement A AAAA CNAME TXT et SSHFP
|
||||
zone_alias = config.dns.zone_alias
|
||||
|
@ -97,7 +97,7 @@ la base LDAP
|
|||
'adm.crans.org': 'adm.v6.crans.org',
|
||||
'ferme.crans.org': 'ferme.v6.crans.org',
|
||||
}
|
||||
# Résolution inverse
|
||||
# Résolution inverse
|
||||
zones_reverse = config.dns.zones_reverse
|
||||
zones_v6_to_net = {
|
||||
'crans.eu': config.prefix["fil"][0],
|
||||
|
@ -105,26 +105,26 @@ la base LDAP
|
|||
'wifi.crans.org': config.prefix["wifi"][0],
|
||||
'adm.crans.org': config.prefix["adm"][0],
|
||||
'ferme.crans.org': config.prefix["fil"][0],
|
||||
# Hack pour générer un fichier de zone vide
|
||||
# Hack pour générer un fichier de zone vide
|
||||
'##HACK##': config.prefix["subnet"][0],
|
||||
}
|
||||
### Liste DNS
|
||||
# Le premier doit être le maitre
|
||||
# Le premier doit être le maitre
|
||||
DNSs = ['sable.crans.org', 'freebox.crans.org', 'ovh.crans.org']
|
||||
DNSs_private = []
|
||||
ip_master_DNS = config.dns.master
|
||||
|
||||
zone_multicast = 'tv.crans.org'
|
||||
|
||||
### Liste des délégations de zone
|
||||
# Pour les demandes de ces zones, le DNS dira d'aller voir les serveurs listés ici
|
||||
### Liste des délégations de zone
|
||||
# Pour les demandes de ces zones, le DNS dira d'aller voir les serveurs listés ici
|
||||
# Pour les noms des serveurs on met l'IP sans point ou le nom avec un point
|
||||
DELEG = {
|
||||
zone_multicast : [ 'sable.crans.org.' , 'mdr.crans.org.', 'freebox.crans.org.', 'ovh.crans.org.'] ,
|
||||
}
|
||||
|
||||
### Serveurs de mail
|
||||
# format : [ priorité serveur , .... ]
|
||||
# format : [ priorité serveur , .... ]
|
||||
MXs = ['10 redisdead.crans.org', '20 ovh.crans.org', '20 freebox.crans.org']
|
||||
SRVs = [
|
||||
'_jabber._tcp.crans.org. 86400 IN SRV 5 0 5269 xmpp.crans.org.',
|
||||
|
@ -135,7 +135,7 @@ la base LDAP
|
|||
'_sips._tcp.crans.org. 86400 IN SRV 5 0 5061 asterisk.crans.org.',
|
||||
]
|
||||
|
||||
# DS à publier dans zone parentes : { parent : [ zone. TTL IN DS key_id algo_id 1 hash ] }
|
||||
# DS à publier dans zone parentes : { parent : [ zone. TTL IN DS key_id algo_id 1 hash ] }
|
||||
# ex : { 'crans.eu' : ['wifi.crans.eu. 86400 IN DS 33131 8 1 3B573B0E2712D8A8B1B0C3'] }
|
||||
# /!\ Il faut faire attention au rollback des keys, il faudrait faire quelque chose d'automatique avec opendnssec
|
||||
DS = {
|
||||
|
@ -161,7 +161,7 @@ la base LDAP
|
|||
}
|
||||
|
||||
|
||||
### Entète des fichiers de zone
|
||||
### Entète des fichiers de zone
|
||||
zone_entete="""
|
||||
$ORIGIN %(zone)s.
|
||||
$TTL 3600
|
||||
|
@ -174,14 +174,14 @@ $TTL 3600
|
|||
)
|
||||
"""
|
||||
|
||||
# Syntaxe utilisée dans le fichier DNS_CONF pour définir une zone sur le maître
|
||||
# Syntaxe utilisée dans le fichier DNS_CONF pour définir une zone sur le maître
|
||||
zone_template="""
|
||||
zone "%(NOM_zone)s" {
|
||||
type master;
|
||||
file "%(FICHIER_zone)s";
|
||||
};
|
||||
"""
|
||||
# Syntaxe utilisée dans le fichier DNS_CONF_BCFG2 pour définir une zone sur un esclave
|
||||
# Syntaxe utilisée dans le fichier DNS_CONF_BCFG2 pour définir une zone sur un esclave
|
||||
zone_template_slave="""
|
||||
zone "%(NOM_zone)s" {
|
||||
type slave;
|
||||
|
@ -190,10 +190,10 @@ zone "%(NOM_zone)s" {
|
|||
};
|
||||
"""
|
||||
|
||||
### Verbosité
|
||||
# Si =2, ralera (chaine warnings) si machines hors zone trouvée
|
||||
### Verbosité
|
||||
# Si =2, ralera (chaine warnings) si machines hors zone trouvée
|
||||
# Si =1, comme ci-dessus, mais ne ralera pas pour freebox
|
||||
# Si =0, ralera seulement contre les machines ne pouvant être classées
|
||||
# Si =0, ralera seulement contre les machines ne pouvant être classées
|
||||
verbose = 1
|
||||
|
||||
hostname = short_name(gethostname())
|
||||
|
@ -208,8 +208,8 @@ zone "%(NOM_zone)s" {
|
|||
return "DNS"
|
||||
|
||||
def reverse(self, net, ip):
|
||||
"""Renvoie la zone DNS inverse correspondant au réseau et à
|
||||
l'adresse donnés, ainsi que le nombre d'éléments de l'ip a
|
||||
"""Renvoie la zone DNS inverse correspondant au réseau et à
|
||||
l'adresse donnés, ainsi que le nombre d'éléments de l'ip a
|
||||
mettre dans le fichier de zone."""
|
||||
n = netaddr.IPNetwork(net)
|
||||
a = netaddr.IPAddress(ip)
|
||||
|
@ -228,7 +228,7 @@ zone "%(NOM_zone)s" {
|
|||
zone_reverse=netv4_to_arpa(config.NETs['multicast'][0])[0]
|
||||
sap=open('/tmp/chaines_recup_sap.txt').readlines()
|
||||
|
||||
DNS='; DNS de la zone par ordre de priorité\n'
|
||||
DNS='; DNS de la zone par ordre de priorité\n'
|
||||
for d in self.DELEG[self.zone_multicast] :
|
||||
DNS += '@\tIN\tNS %s\n' % d
|
||||
DNS += '\n'
|
||||
|
@ -238,9 +238,9 @@ zone "%(NOM_zone)s" {
|
|||
lignes_d +='@\tIN\tA\t%s\n' % '138.231.136.243'
|
||||
for line in sap:
|
||||
[nom,ip]=line.split(':')
|
||||
nom=re.sub('TNT([0-9]*) ','',nom) # on enlève les TNT## des noms
|
||||
nom=re.sub(' +([^ ])','-\g<1>',nom) # on remplaces les espaces intérieur par un tiret
|
||||
nom=re.sub('[ .():,"\'+<>]','',nom) # on enlève tous les caractères illégaux
|
||||
nom=re.sub('TNT([0-9]*) ','',nom) # on enlève les TNT## des noms
|
||||
nom=re.sub(' +([^ ])','-\g<1>',nom) # on remplaces les espaces intérieur par un tiret
|
||||
nom=re.sub('[ .():,"\'+<>]','',nom) # on enlève tous les caractères illégaux
|
||||
nom=nom.lower()
|
||||
try:
|
||||
[ip1,ip2,ip3,ip4]=ip.strip().split('.')
|
||||
|
@ -248,7 +248,7 @@ zone "%(NOM_zone)s" {
|
|||
lignes_d +='%s\tIN\tA\t%s' % (nom,ip)
|
||||
except:
|
||||
pass
|
||||
# Écriture de la zone directe
|
||||
# Écriture de la zone directe
|
||||
file = self.DNS_DIR + 'db.' + self.zone_multicast
|
||||
fd = self._open_conf(file,';')
|
||||
fd.write(self.zone_entete % \
|
||||
|
@ -258,7 +258,7 @@ zone "%(NOM_zone)s" {
|
|||
fd.write(lignes_d)
|
||||
fd.close()
|
||||
|
||||
# Écriture du reverse
|
||||
# Écriture du reverse
|
||||
file = self.DNS_DIR + 'db.' + zone_reverse
|
||||
fd = self._open_conf(file,';')
|
||||
fd.write(self.zone_entete % \
|
||||
|
@ -270,7 +270,7 @@ zone "%(NOM_zone)s" {
|
|||
|
||||
|
||||
def gen_slave(self) :
|
||||
""" Génération du fichier de config de zone pour les esclaves """
|
||||
""" Génération du fichier de config de zone pour les esclaves """
|
||||
zones = self.zones_direct
|
||||
zones.extend(self.zones_v4_to_v6.values())
|
||||
|
||||
|
@ -297,13 +297,13 @@ zone "%(NOM_zone)s" {
|
|||
fd.close()
|
||||
|
||||
def _gen(self) :
|
||||
### Génération du numéro de série
|
||||
# Le + 1000.... s'explique pas l'idée précédente et peu pratique d'avoir
|
||||
# le numéro de série du type AAAAMMJJNN (année, mois, jour, incrément par jour)
|
||||
### Génération du numéro de série
|
||||
# Le + 1000.... s'explique pas l'idée précédente et peu pratique d'avoir
|
||||
# le numéro de série du type AAAAMMJJNN (année, mois, jour, incrément par jour)
|
||||
serial = time.time() + 1000000000
|
||||
|
||||
### DNS
|
||||
DNS='; DNS de la zone par ordre de priorité\n'
|
||||
DNS='; DNS de la zone par ordre de priorité\n'
|
||||
for d in self.DNSs :
|
||||
DNS += '@\tIN\tNS %s.\n' % d
|
||||
DNS += '\n'
|
||||
|
@ -311,7 +311,7 @@ zone "%(NOM_zone)s" {
|
|||
### Serveurs de mail
|
||||
MX='; Serveurs de mails\n'
|
||||
for m in self.MXs :
|
||||
MX += '%(zone)s.\t' # Sera remplacé par le nom de zone plus tard
|
||||
MX += '%(zone)s.\t' # Sera remplacé par le nom de zone plus tard
|
||||
MX += 'IN\tMX\t%s.\n' % m
|
||||
MX += '\n'
|
||||
|
||||
|
@ -345,12 +345,12 @@ zone "%(NOM_zone)s" {
|
|||
self.anim.iter=len(self.machines)
|
||||
for machine in self.machines :
|
||||
self.anim.cycle()
|
||||
# Calculs préliminaires
|
||||
# Calculs préliminaires
|
||||
try :
|
||||
nom , zone = machine.nom().split('.',1)
|
||||
zone = zone.encode('iso-8859-1')
|
||||
zone = zone.encode('utf-8')
|
||||
except :
|
||||
warnings += u'Machine ignorée (mid=%s) : format nom incorrect (%s)\n' % ( machine.id().encode('iso-8859-1'), machine.nom().encode('iso-8859-1') )
|
||||
warnings += u'Machine ignorée (mid=%s) : format nom incorrect (%s)\n' % ( machine.id().encode('utf-8'), machine.nom().encode('utf-8') )
|
||||
continue
|
||||
|
||||
# Le direct
|
||||
|
@ -359,7 +359,7 @@ zone "%(NOM_zone)s" {
|
|||
# Si la machine est une borne wifi, on ajoute la position
|
||||
if isinstance(machine,ldap_crans.BorneWifi) and machine.position():
|
||||
ligne +="%s\tIN\tTXT\t\"LOC %s,%s \"\n" % (nom,machine.position()[0],machine.position()[1])
|
||||
# Si la machine à des clefs ssh, on ajoute les champs SSFP correspondant
|
||||
# Si la machine à des clefs ssh, on ajoute les champs SSFP correspondant
|
||||
for sshkey in machine.sshFingerprint():
|
||||
try:
|
||||
[algo_txt,key]=sshkey.split()[:2]
|
||||
|
@ -378,7 +378,7 @@ zone "%(NOM_zone)s" {
|
|||
for alias in self.zone_alias[zone]:
|
||||
direct[alias] = direct.get(alias, "") + ligne
|
||||
elif self.verbose and machine.nom() != "ftp.federez.net":
|
||||
warnings += u'Résolution directe ignorée (mid=%s) : zone non autoritaire (%s)\n' % ( machine.id().encode('iso-8859-1'), zone.encode('iso-8859-1') )
|
||||
warnings += u'Résolution directe ignorée (mid=%s) : zone non autoritaire (%s)\n' % ( machine.id().encode('utf-8'), zone.encode('utf-8') )
|
||||
|
||||
# IPv6
|
||||
if zone in self.zones_v4_to_v6:
|
||||
|
@ -406,23 +406,23 @@ zone "%(NOM_zone)s" {
|
|||
|
||||
# Le direct avec alias
|
||||
for alias in machine.alias() :
|
||||
alias = alias.encode('iso-8859-1')
|
||||
alias = alias.encode('utf-8')
|
||||
# Cas particulier : nom de l'alias = nom de la zone
|
||||
if alias in self.zones_direct :
|
||||
ligne = "@\tIN\tA\t%s\n" % machine.ip()
|
||||
ligne = ligne.encode('iso-8859-1')
|
||||
ligne = ligne.encode('utf-8')
|
||||
direct[alias] = direct.get(alias, "") + ligne
|
||||
if alias in self.zone_alias:
|
||||
for alias2 in self.zone_alias[alias]: direct[alias2] = direct.get(alias2, "") + ligne
|
||||
if machine.dnsIpv6():
|
||||
ligne = "@\tIN\tAAAA\t%s\n" % machine.ipv6()
|
||||
ligne = ligne.encode('iso-8859-1')
|
||||
ligne = ligne.encode('utf-8')
|
||||
direct[alias]= direct.get(alias, "") + ligne
|
||||
if alias in self.zone_alias:
|
||||
for alias2 in self.zone_alias[alias]: direct[alias2] = direct.get(alias2, "") + ligne
|
||||
if alias in self.zones_v4_to_v6:
|
||||
ligne = "@\tIN\tAAAA\t%s\n" % machine.ipv6()
|
||||
ligne = ligne.encode('iso-8859-1')
|
||||
ligne = ligne.encode('utf-8')
|
||||
zone6 = self.zones_v4_to_v6[alias]
|
||||
direct[zone6] = direct.get(zone6, '') + ligne
|
||||
if alias in self.zone_alias:
|
||||
|
@ -445,9 +445,9 @@ zone "%(NOM_zone)s" {
|
|||
ok = 1
|
||||
break
|
||||
if not ok:
|
||||
warnings += u'Alias ignoré (mid=%s) : %s\n' % ( machine.id().encode('iso-8859-1'), alias.encode('iso-8859-1') )
|
||||
warnings += u'Alias ignoré (mid=%s) : %s\n' % ( machine.id().encode('utf-8'), alias.encode('utf-8') )
|
||||
continue
|
||||
zone = zone.encode('iso-8859-1')
|
||||
zone = zone.encode('utf-8')
|
||||
ligne = "%s\tIN\tCNAME\t%s.\n" % ( nom, machine.nom() )
|
||||
direct[zone] = direct.get(zone, '') + ligne
|
||||
if zone in self.zones_v4_to_v6:
|
||||
|
@ -468,40 +468,40 @@ zone "%(NOM_zone)s" {
|
|||
base_ip = ip.split('.')
|
||||
base_ip.reverse()
|
||||
zone, length = self.reverse(net, ip)
|
||||
zone = zone.encode('iso-8859-1')
|
||||
zone = zone.encode('utf-8')
|
||||
ligne = '%s\tIN\tPTR\t%s.\n' % ('.'.join(base_ip[:length]), machine.nom())
|
||||
try : reverse[zone] += ligne
|
||||
except : reverse[zone] = ligne
|
||||
elif self.verbose >= 2 or machine.nom() not in ('freebox.crans.org', 'ovh.crans.org', 'kokarde.crans.org'):
|
||||
warnings += u'Résolution inverse ignorée (mid=%s) : ip sur zone non autoritaire (%s)\n' % ( machine.id().encode('iso-8859-1'), machine.ip().encode('iso-8859-1') )
|
||||
warnings += u'Résolution inverse ignorée (mid=%s) : ip sur zone non autoritaire (%s)\n' % ( machine.id().encode('utf-8'), machine.ip().encode('utf-8') )
|
||||
|
||||
### Ajouts pour les fichiers de résolution directs
|
||||
### Ajouts pour les fichiers de résolution directs
|
||||
for zone in direct.keys() :
|
||||
# MXs
|
||||
direct[zone] = MX % { 'zone' : zone } + direct[zone]
|
||||
|
||||
### XXX: création de la zone inverse pour le /48 IPv6 complet du Cr@ns
|
||||
### XXX: création de la zone inverse pour le /48 IPv6 complet du Cr@ns
|
||||
full_net_v6 = self.zones_v6_to_net["##HACK##"]
|
||||
zone_rev, length = self.reverse(full_net_v6, netaddr.IPNetwork(full_net_v6).first)
|
||||
reverse[zone_rev] = reverse.get(zone_rev, "")
|
||||
|
||||
### Ajout des délégations de zones
|
||||
### Ajout des délégations de zones
|
||||
for deleg in self.DELEG.keys():
|
||||
nom, zone = deleg.split('.',1)
|
||||
if not zone in direct.keys():
|
||||
warnings += u'Délégation ignorée %s : on ne génère pas la zone parent\n' % deleg
|
||||
warnings += u'Délégation ignorée %s : on ne génère pas la zone parent\n' % deleg
|
||||
continue
|
||||
for serv in self.DELEG[deleg]:
|
||||
direct[zone] = direct[zone] + "%s\tIN\tNS\t%s\n" % ( nom, serv )
|
||||
|
||||
|
||||
### Ajout d'eventuel champs DS pour les délégation dnssec
|
||||
### Ajout d'eventuel champs DS pour les délégation dnssec
|
||||
for zone,ds in self.DS.items():
|
||||
for s in ds:
|
||||
direct[zone] += s + '\n'
|
||||
direct[zone] += '\n'
|
||||
|
||||
### Ecriture des fichiers de zone et préparation du fichier de définition
|
||||
### Ecriture des fichiers de zone et préparation du fichier de définition
|
||||
f = ''
|
||||
for zone, lignes in direct.items() + reverse.items() :
|
||||
if zone in self.zones_dnssec:
|
||||
|
@ -523,7 +523,7 @@ zone "%(NOM_zone)s" {
|
|||
else:
|
||||
f += self.zone_template % { 'NOM_zone' : zone, 'FICHIER_zone' : path }
|
||||
|
||||
### Ecriture fichier de définition
|
||||
### Ecriture fichier de définition
|
||||
fd = self._open_conf(self.DNS_CONF,'//')
|
||||
fd.write(f)
|
||||
fd.close()
|
||||
|
@ -535,13 +535,13 @@ if __name__ == '__main__' :
|
|||
from config import bcfg2_main
|
||||
hostname = short_name(gethostname())
|
||||
if hostname == short_name(bcfg2_main):
|
||||
print "Reconfiguration du fichier de BCfg2 pour configurer le bind d'un serveur en esclave (pensez à lancer bcfg2 sur les esclaves)."
|
||||
print "Reconfiguration du fichier de BCfg2 pour configurer le bind d'un serveur en esclave (pensez à lancer bcfg2 sur les esclaves)."
|
||||
c = dns()
|
||||
c.gen_slave()
|
||||
if hostname == short_name(dns.DNSs[0]):
|
||||
print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate."
|
||||
print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate."
|
||||
elif hostname == short_name(dns.DELEG['tv.crans.org'][0][0:-1]):
|
||||
print "Serveur ma�tre pour tv.crans.org, génération de la zone"
|
||||
print "Serveur maᅵtre pour tv.crans.org, génération de la zone"
|
||||
c = dns()
|
||||
c.gen_tv()
|
||||
import subprocess
|
||||
|
@ -551,10 +551,10 @@ if __name__ == '__main__' :
|
|||
print ret[0].strip()
|
||||
print ret[1].strip()
|
||||
if hostname == short_name(dns.DNSs[0]):
|
||||
print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate."
|
||||
print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate."
|
||||
elif hostname == short_name(dns.DNSs[0]):
|
||||
print "Ce serveur est maître ! Utilisez generate."
|
||||
print "Ce serveur est maître ! Utilisez generate."
|
||||
elif hostname in map(lambda fullhostname : short_name(fullhostname),dns.DNSs[1:]+dns.DNSs_private):
|
||||
print "Ce serveur est esclave! Lancez ce script sur %s, puis lancez bcfg2 ici" % bcfg2_main
|
||||
else:
|
||||
print "Ce serveur ne correspond à rien pour la configuration DNS."
|
||||
print "Ce serveur ne correspond à rien pour la configuration DNS."
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Génération de la configuration pour le dhcp
|
||||
""" Génération de la configuration pour le dhcp
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
|
@ -12,22 +12,22 @@ from gen_confs import gen_config
|
|||
from ldap_crans import hostname
|
||||
|
||||
class dhcp(gen_config) :
|
||||
""" Génération du fichier de configuration pour dhcpd (DHCPD_CONF)
|
||||
Le fichier comporte une partie par réseau servi, chaque réseau
|
||||
servi doit être une clef du dictionnaire reseaux, la valeur correspondante
|
||||
est une chaine décrivant les options spécifiques à ce réseau.
|
||||
""" Génération du fichier de configuration pour dhcpd (DHCPD_CONF)
|
||||
Le fichier comporte une partie par réseau servi, chaque réseau
|
||||
servi doit être une clef du dictionnaire reseaux, la valeur correspondante
|
||||
est une chaine décrivant les options spécifiques à ce réseau.
|
||||
Les options communes sont celles de base_dhcp.
|
||||
|
||||
Chaque machines possède ensuite une entrée de la forme de host_template
|
||||
Chaque machines possède ensuite une entrée de la forme de host_template
|
||||
"""
|
||||
######################################PARTIE DE CONFIGURATION
|
||||
# Fichier à écire
|
||||
# Fichier à écire
|
||||
if hostname == 'ragnarok' :
|
||||
DHCPD_CONF='/etc/dhcpd.conf'
|
||||
else :
|
||||
DHCPD_CONF = '/etc/dhcp3/dhcpd.conf'
|
||||
|
||||
# Hotspot ENS plus utilisé...
|
||||
# Hotspot ENS plus utilisé...
|
||||
# elif hostname == 'ragnarok' :
|
||||
# On rajoute les IP dynamiques
|
||||
# base_conf = """
|
||||
|
@ -47,7 +47,7 @@ class dhcp(gen_config) :
|
|||
#"""
|
||||
|
||||
elif hostname == 'sable':
|
||||
# Options communes à toutes les réseaux servis
|
||||
# Options communes à toutes les réseaux servis
|
||||
base_conf="""
|
||||
# VLan accueil
|
||||
subnet 10.51.0.0 netmask 255.255.0.0 {
|
||||
|
@ -68,7 +68,7 @@ subnet 10.52.0.0 netmask 255.255.0.0 {
|
|||
else :
|
||||
base_conf = ''
|
||||
|
||||
# Réseaux servis avec leurs options spécifiques
|
||||
# Réseaux servis avec leurs options spécifiques
|
||||
# if hostname == 'zamok':
|
||||
# reseaux = { '138.231.136.0/21' :
|
||||
#"""option routers 138.231.136.4;
|
||||
|
@ -110,7 +110,7 @@ subnet 10.52.0.0 netmask 255.255.0.0 {
|
|||
option routers 10.42.0.1;
|
||||
option domain-name-servers 10.42.0.1;""" }
|
||||
|
||||
# Options communes à toutes les réseaux servis
|
||||
# Options communes à toutes les réseaux servis
|
||||
base_dhcp="""
|
||||
subnet %(network)s netmask %(netmask)s {
|
||||
default-lease-time 86400;
|
||||
|
@ -153,9 +153,9 @@ subnet %(network)s netmask %(netmask)s {
|
|||
}
|
||||
"""
|
||||
|
||||
### Verbosité
|
||||
# Si =1 ralera (chaine warnings) si machines hors zone trouvée
|
||||
# Si =0 ralera seulement si réseau vide
|
||||
### Verbosité
|
||||
# Si =1 ralera (chaine warnings) si machines hors zone trouvée
|
||||
# Si =0 ralera seulement si réseau vide
|
||||
verbose = 1
|
||||
|
||||
# if hostname == 'zamok':
|
||||
|
@ -195,7 +195,7 @@ subnet %(network)s netmask %(netmask)s {
|
|||
fd.write(self.base_conf)
|
||||
for net, options in self.reseaux.items() :
|
||||
if not hosts.has_key(net) :
|
||||
warnings += u'Réseau %s ignoré : aucune machine à servir\n' % net
|
||||
warnings += u'Réseau %s ignoré : aucune machine à servir\n' % net
|
||||
continue
|
||||
d = param(net)
|
||||
d['OPTIONS_RESEAU'] = options
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Génération de la configuration pour le dhcp
|
||||
""" Génération de la configuration pour le dhcp
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
import os
|
||||
|
@ -63,15 +63,15 @@ class dydhcp:
|
|||
conn.close()
|
||||
|
||||
class dhcp(gen_config) :
|
||||
""" Génération du fichier de déclaration des hosts.
|
||||
Chaque réseau servi doit être une clef du dictionnaire reseaux,
|
||||
""" Génération du fichier de déclaration des hosts.
|
||||
Chaque réseau servi doit être une clef du dictionnaire reseaux,
|
||||
la valeur correspondante est une chaine contenant le nom du fichier
|
||||
associé à ce réseau.
|
||||
associé à ce réseau.
|
||||
|
||||
Chaque machine possède ensuite une entrée de la forme de host_template.
|
||||
Chaque machine possède ensuite une entrée de la forme de host_template.
|
||||
"""
|
||||
######################################PARTIE DE CONFIGURATION
|
||||
# Fichier à écire
|
||||
# Fichier à écire
|
||||
if hostname == 'sable':
|
||||
restart_cmd = '/etc/init.d/isc-dhcp-server restart'
|
||||
reseaux = { '138.231.136.0/21' : '/etc/dhcp3/generated/adherents.liste',
|
||||
|
@ -114,9 +114,9 @@ class dhcp(gen_config) :
|
|||
}
|
||||
"""
|
||||
|
||||
### Verbosité
|
||||
# Si =1 ralera (chaine warnings) si machines hors zone trouvée
|
||||
# Si =0 ralera seulement si réseau vide
|
||||
### Verbosité
|
||||
# Si =1 ralera (chaine warnings) si machines hors zone trouvée
|
||||
# Si =0 ralera seulement si réseau vide
|
||||
verbose = 1
|
||||
|
||||
######################################FIN PARTIE DE CONFIGURATION
|
||||
|
@ -145,7 +145,7 @@ class dhcp(gen_config) :
|
|||
|
||||
|
||||
def _gen(self) :
|
||||
"""Construction de la liste des machines appartenant à un réseau
|
||||
"""Construction de la liste des machines appartenant à un réseau
|
||||
"""
|
||||
|
||||
warnings = ''
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) Frédéric Pauget
|
||||
# Copyright (C) Frédéric Pauget
|
||||
# Licence : GPLv2
|
||||
|
||||
#"""Ce script permet de lancer la reconfiguration des divers services
|
||||
|
@ -9,8 +9,8 @@
|
|||
#Usage: %(prog)s options
|
||||
#Les options possibles sont :
|
||||
#\t%(options)s
|
||||
#Les options avec = doivent être suivies d'un argument. Plusieurs
|
||||
#arguments peuvent être founis pour une même option, les séparer par &
|
||||
#Les options avec = doivent être suivies d'un argument. Plusieurs
|
||||
#arguments peuvent être founis pour une même option, les séparer par &
|
||||
#"""
|
||||
|
||||
import sys, signal, os, getopt
|
||||
|
@ -68,19 +68,19 @@ class base_reconfigure:
|
|||
|
||||
def __init__(self, to_do=None):
|
||||
|
||||
# On vérifie que l'on est root
|
||||
# On vérifie que l'on est root
|
||||
if os.getuid() != 0:
|
||||
sys.stderr.write("Il faut être root\n")
|
||||
sys.stderr.write("Il faut être root\n")
|
||||
sys.exit(1)
|
||||
|
||||
if not to_do:
|
||||
if debug:
|
||||
print 'Lecture des services à redémarrer dans la base LDAP...'
|
||||
print 'Lecture des services à redémarrer dans la base LDAP...'
|
||||
auto = True
|
||||
to_do = {}
|
||||
# Création de la liste de ce qu'il y a à faire
|
||||
# Création de la liste de ce qu'il y a à faire
|
||||
for serv in db.services_to_restart():
|
||||
# Services spéciaux portant sur plusieurs machines
|
||||
# Services spéciaux portant sur plusieurs machines
|
||||
to_add = self.__service_develop.get(serv.nom, [])
|
||||
if to_add:
|
||||
for nom in to_add:
|
||||
|
@ -97,13 +97,13 @@ class base_reconfigure:
|
|||
else:
|
||||
auto = False
|
||||
if debug:
|
||||
print 'Services à redémarrer imposés (non lecture de la base LDAP)'
|
||||
print 'Services à redémarrer imposés (non lecture de la base LDAP)'
|
||||
|
||||
for serv, args in to_do.items():
|
||||
# Au cas où le service porte sur plusieurs machines
|
||||
# Au cas où le service porte sur plusieurs machines
|
||||
service = serv.replace('%s-' % hostname, '')
|
||||
if hasattr(self, service):
|
||||
# Le service est à reconfigurer sur cette machine
|
||||
# Le service est à reconfigurer sur cette machine
|
||||
db.services_to_restart('-%s' % serv)
|
||||
try:
|
||||
m = getattr(self, service)
|
||||
|
@ -125,17 +125,17 @@ class base_reconfigure:
|
|||
if debug:
|
||||
reste = db.services_to_restart()
|
||||
if reste:
|
||||
print "Reste à faire :"
|
||||
print "Reste à faire :"
|
||||
for s in reste:
|
||||
try:
|
||||
print '\t%s' % s
|
||||
except UnicodeDecodeError:
|
||||
print '\t%s: non imprimable' % s.nom
|
||||
else:
|
||||
print "Plus rien à faire"
|
||||
print "Plus rien à faire"
|
||||
|
||||
def _machines(self):
|
||||
""" Retourne les machines de la base étant 'à jour' """
|
||||
""" Retourne les machines de la base étant 'à jour' """
|
||||
return db.all_machines(graphic=True)
|
||||
|
||||
def _do(self, service, machines=None):
|
||||
|
@ -180,8 +180,8 @@ class redisdead(base_reconfigure):
|
|||
|
||||
def mail_modif(self, trucs):
|
||||
"""
|
||||
trucs est une liste de recherches à effectuer dans la base
|
||||
l'affichage des résultats formera le corps du mail
|
||||
trucs est une liste de recherches à effectuer dans la base
|
||||
l'affichage des résultats formera le corps du mail
|
||||
"""
|
||||
from supervison import mail
|
||||
self._do(mail(trucs))
|
||||
|
@ -238,7 +238,7 @@ class zbee(base_reconfigure):
|
|||
|
||||
class komaz(base_reconfigure):
|
||||
|
||||
# Mimétisme de ma part -- xhub
|
||||
# Mimétisme de ma part -- xhub
|
||||
def __fw6(self):
|
||||
if not hasattr(self, '__real_fw6'):
|
||||
from firewall6 import Update
|
||||
|
@ -312,7 +312,7 @@ if __name__ == '__main__':
|
|||
classe = eval(hostname)
|
||||
|
||||
args_autorises = ['quiet', 'remove=', 'add=', 'list', 'help', 'reconnect']
|
||||
# Ajout aussi des arguments spécifiques à la machine
|
||||
# Ajout aussi des arguments spécifiques à la machine
|
||||
for nom in dir(classe):
|
||||
if nom[0] != '_':
|
||||
if len(getargspec(getattr(classe, nom))[0]) > 1:
|
||||
|
@ -330,7 +330,7 @@ if __name__ == '__main__':
|
|||
sys.stderr.write('%s\n' % msg)
|
||||
sys.exit(255)
|
||||
|
||||
debug = 1 # défaut
|
||||
debug = 1 # défaut
|
||||
to_do = {}
|
||||
|
||||
for opt, val in options:
|
||||
|
@ -344,7 +344,7 @@ if __name__ == '__main__':
|
|||
sys.exit(0)
|
||||
|
||||
elif opt == '--list':
|
||||
print 'Services à redémarrer :'
|
||||
print 'Services à redémarrer :'
|
||||
for s in db.services_to_restart():
|
||||
try:
|
||||
print '\t%s' % s
|
||||
|
@ -353,7 +353,7 @@ if __name__ == '__main__':
|
|||
sys.exit(0)
|
||||
|
||||
elif opt == '--reconnect':
|
||||
# Personnes à reconnecter
|
||||
# Personnes à reconnecter
|
||||
print 'Recherche des personnes en fin de sanction...'
|
||||
c = db.search('blacklist=*')
|
||||
services = []
|
||||
|
@ -369,7 +369,7 @@ if __name__ == '__main__':
|
|||
sys.exit(0)
|
||||
|
||||
elif opt == '--add':
|
||||
# Ajout d'un item dans les services à redémarrer
|
||||
# Ajout d'un item dans les services à redémarrer
|
||||
for serv in val.split('&'):
|
||||
if serv.find(',') != -1:
|
||||
serv, arg = serv.split(',', 1)
|
||||
|
@ -390,5 +390,5 @@ if __name__ == '__main__':
|
|||
to_do[opt[2:]] = val.split('&')
|
||||
|
||||
|
||||
# On fait ce qu'il y a à faire
|
||||
# On fait ce qu'il y a à faire
|
||||
classe(to_do)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Licence : GPLv2
|
||||
|
||||
|
@ -13,8 +13,8 @@ from email.mime.text import MIMEText
|
|||
|
||||
class mail:
|
||||
"""
|
||||
Envoie un mail à toutes les personnes de la liste 'To', avec les
|
||||
informations détaillées des objets contenus dans 'objets'
|
||||
Envoie un mail à toutes les personnes de la liste 'To', avec les
|
||||
informations détaillées des objets contenus dans 'objets'
|
||||
(instances des classes Adherent, Machine ou Club) """
|
||||
|
||||
From = 'roots@crans.org'
|
||||
|
@ -25,14 +25,14 @@ class mail:
|
|||
To: %(To)s
|
||||
Subject: %(Subject)s
|
||||
Mime-Version: 1.0
|
||||
Content-Type: text/plain; charset="iso-8859-1"
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Disposition: inline
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
|
||||
%(Text)s"""
|
||||
|
||||
# Avec les caractères d'échappement qui vont bien pour la couleur ?
|
||||
# Avec les caractères d'échappement qui vont bien pour la couleur ?
|
||||
couleur = False
|
||||
|
||||
def __init__(self,recherches) :
|
||||
|
@ -96,7 +96,7 @@ Subject: %(Subject)s
|
|||
|
||||
%(Text)s"""
|
||||
|
||||
# Avec les caractères d'échappement qui vont bien pour la couleur ?
|
||||
# Avec les caractères d'échappement qui vont bien pour la couleur ?
|
||||
couleur = False
|
||||
|
||||
def __init__(self,modifs) :
|
||||
|
|
12
gestion/gen_confs/surveillance.py
Normal file → Executable file
12
gestion/gen_confs/surveillance.py
Normal file → Executable file
|
@ -1,11 +1,11 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Classe de synchronisation entre la base ldap et
|
||||
la base postgresql pour la liste des exemptions
|
||||
et la liste des machines.
|
||||
Utilisé par generate.py
|
||||
Utilisé par generate.py
|
||||
"""
|
||||
|
||||
# importation des fonctions et classes
|
||||
|
@ -18,7 +18,7 @@ import psycopg2
|
|||
|
||||
db = crans_ldap()
|
||||
|
||||
# Génération des la tables d'exemptions
|
||||
# Génération des la tables d'exemptions
|
||||
#######################################
|
||||
|
||||
class exemptions(gen_config) :
|
||||
|
@ -49,7 +49,7 @@ class exemptions(gen_config) :
|
|||
|
||||
pgsql.commit()
|
||||
|
||||
# Génération des la liste des machines
|
||||
# Génération des la liste des machines
|
||||
######################################
|
||||
|
||||
class machines(gen_config) :
|
||||
|
@ -70,7 +70,7 @@ class machines(gen_config) :
|
|||
# machines = self.machines
|
||||
# machines = db.search('ip=*')['machine']
|
||||
|
||||
# connexion à la base postgresql
|
||||
# connexion à la base postgresql
|
||||
import psycopg2
|
||||
pgsql = psycopg2.connect(database='filtrage', user='crans')
|
||||
curseur = pgsql.cursor()
|
||||
|
@ -82,7 +82,7 @@ class machines(gen_config) :
|
|||
ipv6_vu[ipv6] = True
|
||||
return ret
|
||||
|
||||
# ajout des entrée
|
||||
# ajout des entrée
|
||||
for m in machines:
|
||||
if m.proprietaire().__class__ == Club:
|
||||
curseur.execute("INSERT INTO machines (ip, type, id) VALUES (inet'%s','club',%s);"%(m.ip(),m.proprietaire().id()))
|
||||
|
|
|
@ -500,7 +500,7 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
return ','.join(result)
|
||||
|
||||
# Saut de ligne parasite
|
||||
params['INTERFACES_CONF'] = params['INTERFACES_CONF'][:-1].encode('iso-8859-15')
|
||||
params['INTERFACES_CONF'] = params['INTERFACES_CONF'][:-1].encode('utf-8')
|
||||
|
||||
# Conversion des listes
|
||||
for key in [ 'uplinks', 'non_uplinks' ] :
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import time, commands
|
||||
from gen_confs import gen_config, ERREUR, OK, anim
|
||||
|
@ -9,11 +9,11 @@ sys.path.append('/usr/scripts/gestion')
|
|||
from ldap_crans import crans_ldap, BorneWifi
|
||||
|
||||
class conf_wifi_ng(gen_config) :
|
||||
""" Génération de la configuration de isakmpd dans ISAKMPD_CONF
|
||||
Le fichier est constitué en 5 parties :
|
||||
1) Configuration générale insérée telle quelle
|
||||
""" Génération de la configuration de isakmpd dans ISAKMPD_CONF
|
||||
Le fichier est constitué en 5 parties :
|
||||
1) Configuration générale insérée telle quelle
|
||||
2) Phase 1 : une ligne par host suivant template
|
||||
3) Phase 2 : une entrée par machine
|
||||
3) Phase 2 : une entrée par machine
|
||||
4) Bloc par machine suivant template
|
||||
5) Ajout de net_crans
|
||||
|
||||
|
@ -21,8 +21,8 @@ class conf_wifi_ng(gen_config) :
|
|||
"""
|
||||
######################################PARTIE DE CONFIGURATION
|
||||
|
||||
# Fichiers à écrire
|
||||
# Répertoire d'écriture des fichiers de zone
|
||||
# Fichiers à écrire
|
||||
# Répertoire d'écriture des fichiers de zone
|
||||
ISAKMPD_CONF='/etc/isakmpd/isakmpd.conf'
|
||||
# Correspondance MAC/IP
|
||||
MACIP='/etc/wifi/wifi-update-ng/common/etc/macip'
|
||||
|
@ -57,7 +57,7 @@ class conf_wifi_ng(gen_config) :
|
|||
self.anim=anim('\tfin reconfigurations')
|
||||
|
||||
def gen_bornes(self, bornes):
|
||||
"""Génération de la configuration des bornes"""
|
||||
"""Génération de la configuration des bornes"""
|
||||
|
||||
TARGET = "/var/www/wifi-update"
|
||||
WORK = "%s/work" % TARGET
|
||||
|
@ -68,20 +68,20 @@ class conf_wifi_ng(gen_config) :
|
|||
if self._bornes and borne.nom().split(".")[0] not in self._bornes:
|
||||
continue
|
||||
self.anim=anim('\treconfiguration de %s' % borne.nom())
|
||||
# Il s'agit de faire l'union du répertoire common et du
|
||||
# répertoire propre (s'il existe) ou alors du répertoire default
|
||||
# On supprime le répertoire de travail
|
||||
# Il s'agit de faire l'union du répertoire common et du
|
||||
# répertoire propre (s'il existe) ou alors du répertoire default
|
||||
# On supprime le répertoire de travail
|
||||
if os.path.isdir(WORK):
|
||||
shutil.rmtree(WORK)
|
||||
# On copie COMMON
|
||||
shutil.copytree(COMMON, WORK)
|
||||
# Est-ce qu'un répertoire spécifique existe ?
|
||||
# Est-ce qu'un répertoire spécifique existe ?
|
||||
top = os.path.join(ROOT, borne.nom())
|
||||
if not os.path.isdir(top):
|
||||
top = DEFAULT
|
||||
# On en copie aussi le contenu
|
||||
for root, dirs, files in os.walk(top, topdown=True):
|
||||
# On créé les répertoires
|
||||
# On créé les répertoires
|
||||
for name in dirs:
|
||||
try:
|
||||
os.mkdir(os.path.join("%s%s" % (WORK, root[len(top):]),
|
||||
|
@ -93,7 +93,7 @@ class conf_wifi_ng(gen_config) :
|
|||
shutil.copy(os.path.join(root, name),
|
||||
os.path.join("%s%s" % (WORK, root[len(top):]),
|
||||
name))
|
||||
# On créé/complète le fichier /etc/nvram.updates
|
||||
# On créé/complète le fichier /etc/nvram.updates
|
||||
if isinstance(borne, BorneWifi) and borne.nom() != "non-configure.wifi.crans.org":
|
||||
fd = file(os.path.join(WORK, "etc", "nvram.updates"), "a")
|
||||
data = { 'HOST': borne.nom().split('.')[0],
|
||||
|
@ -113,7 +113,7 @@ NVRAM_wl0_radio=%(ON)d
|
|||
NVRAM_crans_hotspot=%(HOTSPOT)d
|
||||
|
||||
""" % data)
|
||||
# On complète par les variables de la NVRAM
|
||||
# On complète par les variables de la NVRAM
|
||||
for info in borne.nvram():
|
||||
fd.write('variables="${variables} %s"\n' % info.split("=")[0])
|
||||
fd.write("NVRAM_%s\n" % info)
|
||||
|
@ -122,15 +122,15 @@ NVRAM_crans_hotspot=%(HOTSPOT)d
|
|||
# On fait du menage
|
||||
os.system("find %s -name CVS -type d -exec rm -rf {} \\; 2> /dev/null" % WORK)
|
||||
os.system("find %s -name '*~' -type f -exec rm -f {} \\;" % WORK)
|
||||
# Ensuite, on créé le tar
|
||||
# Ensuite, on créé le tar
|
||||
os.system("tar zcf %s/%s.tmp.tar.gz -C %s ." % (TARGET, borne.nom(), WORK))
|
||||
# Et on le renomme (on espère que c'est atomique)
|
||||
# Et on le renomme (on espère que c'est atomique)
|
||||
os.rename("%s/%s.tmp.tar.gz" % (TARGET, borne.nom()),
|
||||
"%s/%s.tar.gz" % (TARGET, borne.nom()))
|
||||
print OK
|
||||
|
||||
def gen_macip(self, clients, bornes):
|
||||
"""Génération de la correspondance MAC/IP"""
|
||||
"""Génération de la correspondance MAC/IP"""
|
||||
self.anim=anim('\r\tFichier MAC/IP',len(clients + bornes))
|
||||
fd = file(self.MACIP, "w")
|
||||
for machine in clients + bornes:
|
||||
|
@ -141,9 +141,9 @@ NVRAM_crans_hotspot=%(HOTSPOT)d
|
|||
print OK
|
||||
|
||||
def gen_isakmpd(self, clients):
|
||||
"""Génération du fichier pour isakmpd"""
|
||||
"""Génération du fichier pour isakmpd"""
|
||||
|
||||
# Config générale de ISAKMPd
|
||||
# Config générale de ISAKMPd
|
||||
general="""
|
||||
[General]
|
||||
Listen-on= 138.231.148.1
|
||||
|
@ -202,7 +202,7 @@ Remote-ID= Net-%(HOST)s
|
|||
ID-type= IPV4_ADDR
|
||||
Address= %(IP)s
|
||||
"""
|
||||
# Dernière partie du fichier
|
||||
# Dernière partie du fichier
|
||||
net_crans="""
|
||||
[Net-crans]
|
||||
ID-type= IPV4_ADDR_SUBNET
|
||||
|
@ -226,7 +226,7 @@ Netmask= 0.0.0.0
|
|||
|
||||
# Phase 2
|
||||
if blocs != '' :
|
||||
# Ce n'est pas la première machine, il faut insérer un séparateur
|
||||
# Ce n'est pas la première machine, il faut insérer un séparateur
|
||||
phase2 += phase2_sep
|
||||
phase2 += phase2_template % data
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ droits = db.search("uid=%s" % script_utilisateur)['adherent'][0].droits()
|
|||
isimprimeur = u"Imprimeur" in droits
|
||||
iscontroleur = u'Tresorier' in droits
|
||||
isbureau = u'Bureau' in droits
|
||||
encoding = sys.stdin.encoding or 'ISO-8859-15'
|
||||
encoding = sys.stdin.encoding or 'UTF-8'
|
||||
|
||||
if u'Nounou' in droits:
|
||||
if os.path.exists(os.path.expanduser('~/.dialogrc')):
|
||||
|
@ -1892,7 +1892,7 @@ def select(clas, quoi, mde=''):
|
|||
s= ['', '', '', '', '', '', '', '', '', '']
|
||||
def f(a):
|
||||
try:
|
||||
return unicode(a, 'iso-8859-15')
|
||||
return unicode(a, 'utf-8')
|
||||
except:
|
||||
return a
|
||||
while 1:
|
||||
|
|
|
@ -182,7 +182,7 @@ def preattr(val):
|
|||
val = str(val).strip()
|
||||
# On passe tout en utf-8 pour ne pas avoir de problèmes
|
||||
# d'accents dans la base
|
||||
return [len(val), unicode(val, 'iso-8859-1').encode('utf-8')]
|
||||
return [len(val), val]
|
||||
elif isinstance(val, unicode):
|
||||
val = val.strip()
|
||||
return [len(val), val.encode('utf-8')]
|
||||
|
@ -690,8 +690,7 @@ class CransLdap:
|
|||
closelog()
|
||||
|
||||
if type(expression) == str:
|
||||
# Transformation de l'expression en utf-8
|
||||
expression = unicode(expression, 'iso-8859-15').encode('utf-8')
|
||||
pass
|
||||
elif type(expression) == unicode:
|
||||
expression = expression.encode('utf-8')
|
||||
else:
|
||||
|
@ -1889,7 +1888,7 @@ class BaseProprietaire(BaseClasseCrans):
|
|||
|
||||
if self.idn !='cid':
|
||||
# Mail de bienvenue
|
||||
self.services_to_restart('mail_bienvenue', [self.mail().encode('iso-8859-15')], start = time.time() + 660)
|
||||
self.services_to_restart('mail_bienvenue', [self.mail().encode('utf-8')], start = time.time() + 660)
|
||||
|
||||
else:
|
||||
ret += coul(u"Modification %s effectuée avec succès." % self.Nom(), 'vert')
|
||||
|
@ -2178,7 +2177,7 @@ class Adherent(BaseProprietaire):
|
|||
self.mail_invalide(False)
|
||||
|
||||
# on renvoie le mail de bienvenue
|
||||
self.services_to_restart('mail_bienvenue', [new.encode('iso-8859-15')])
|
||||
self.services_to_restart('mail_bienvenue', [new.encode('utf-8')])
|
||||
|
||||
return new
|
||||
|
||||
|
@ -2876,7 +2875,7 @@ Contactez nounou si la MAC est bien celle d'une carte.""", 3)
|
|||
def __host_alias(self, champ, new):
|
||||
""" Vérification de la validité d'un nom de machine """
|
||||
# Supression des accents
|
||||
new = strip_accents(unicode(new, 'iso-8859-15'))
|
||||
new = strip_accents(unicode(new, 'utf-8'))
|
||||
|
||||
l, new = preattr(new)
|
||||
new = new.lower()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import sys
|
||||
|
|
|
@ -72,7 +72,7 @@ par le script.
|
|||
s = smtplib.SMTP()
|
||||
s.connect('smtp.crans.org')
|
||||
for adherent in adherents:
|
||||
mail = adherent.mail().encode("iso-8859-15", "ignore")
|
||||
mail = adherent.mail().encode("utf-8", "ignore")
|
||||
if "@" not in mail:
|
||||
mail = mail + "@crans.org"
|
||||
cprint(u"Envoi du mail à %s <%s>..." % (adherent.Nom(), mail))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
@ -15,7 +15,7 @@ for m in machines :
|
|||
|
||||
# texte pour la machine
|
||||
txt = u''
|
||||
txt += u'Propriétaire : %s\n' % m.proprietaire().Nom()
|
||||
txt += u'Propriétaire : %s\n' % m.proprietaire().Nom()
|
||||
txt += u'Machine : %s\n' % m.nom()
|
||||
txt += u'destination : %s\n' % ', '.join(m.exempt())
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
@ -13,7 +13,7 @@ done = []
|
|||
txts = []
|
||||
|
||||
for m in machines :
|
||||
# on vérifie qu'on l'a pas encore traité
|
||||
# on vérifie qu'on l'a pas encore traité
|
||||
if m.ip() in done :
|
||||
continue
|
||||
if m.proprietaire().__class__ == AssociationCrans :
|
||||
|
@ -22,7 +22,7 @@ for m in machines :
|
|||
|
||||
# texte pour la machine
|
||||
txt = u''
|
||||
txt += u'Propriétaire : %s\n' % m.proprietaire().Nom()
|
||||
txt += u'Propriétaire : %s\n' % m.proprietaire().Nom()
|
||||
txt += u'Machine : %s\n' % m.nom()
|
||||
if m.portTCPin() :
|
||||
txt += u'ports TCP in : %s\n' % ' '.join(m.portTCPin())
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
from commands import getoutput
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
@ -15,7 +15,7 @@ for a in adherents :
|
|||
if a.solde() == 0 :
|
||||
continue
|
||||
|
||||
# texte pour l'adhérent
|
||||
# texte pour l'adhérent
|
||||
txt = u''
|
||||
txt += u'Nom : %s\n' % a.Nom()
|
||||
txt += u'Solde : %s\n' % a.solde()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
@ -12,11 +12,11 @@ def titre (bat) :
|
|||
if bat == 'P' :
|
||||
return 'Pavillon des jardins'
|
||||
elif bat == '?' :
|
||||
return 'Autres (extérieurs et chambres invalides)'
|
||||
return 'Autres (extérieurs et chambres invalides)'
|
||||
else :
|
||||
return 'Bâtiment %s' % bat
|
||||
return 'Bâtiment %s' % bat
|
||||
|
||||
# création de la liste vide
|
||||
# création de la liste vide
|
||||
###########################
|
||||
|
||||
liste = {}
|
||||
|
@ -26,7 +26,7 @@ for bat in bats + '?' :
|
|||
# remplissage de la liste
|
||||
#########################
|
||||
|
||||
# les extérieurs
|
||||
# les extérieurs
|
||||
adhs = db.search( 'paiement=ok&etudes!=Pers' )['adherent']
|
||||
for adh in adhs :
|
||||
bat = adh.chbre()[0]
|
||||
|
@ -34,7 +34,7 @@ for adh in adhs :
|
|||
bat = '?'
|
||||
liste[bat].append( u'%s %s' % ( adh.nom(), adh.prenom() ) )
|
||||
|
||||
# création du fichier tex
|
||||
# création du fichier tex
|
||||
#########################
|
||||
|
||||
print """\\documentclass[a4paper,11pt]{article}
|
||||
|
@ -61,7 +61,7 @@ for bat in bats + '?' :
|
|||
\\hline
|
||||
\\endhead""" % {'bat' : titre(bat) }
|
||||
|
||||
# ajout des adhérents
|
||||
# ajout des adhérents
|
||||
liste[bat].sort()
|
||||
for adh in liste[bat] :
|
||||
print (u'%s& \\\\\n\\hline' % adh).encode('iso 8859-15')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
@ -10,21 +10,21 @@ from affich_tools import coul
|
|||
import threading
|
||||
from os import getuid
|
||||
|
||||
# il faut être root
|
||||
# il faut être root
|
||||
if getuid() :
|
||||
print 'Il faut être root !'
|
||||
print 'Il faut être root !'
|
||||
sys.exit(1)
|
||||
|
||||
# connexion à la base de données
|
||||
# connexion à la base de données
|
||||
db = crans_ldap()
|
||||
|
||||
# décompostion des arguments
|
||||
# décompostion des arguments
|
||||
try :
|
||||
mac = ":".join([i.zfill(2) for i in sys.argv[1].split(":")]).upper()
|
||||
except :
|
||||
mac = None
|
||||
|
||||
# dit si une mac a déja été traitée
|
||||
# dit si une mac a déja été traitée
|
||||
mac_done=[]
|
||||
def done (mac) :
|
||||
global mac_done
|
||||
|
@ -34,7 +34,7 @@ def done (mac) :
|
|||
mac_done.append(mac)
|
||||
return False
|
||||
|
||||
# liste des résultats
|
||||
# liste des résultats
|
||||
results = []
|
||||
|
||||
# classe d'interrogation des bornes
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys, re
|
||||
from time import sleep
|
||||
|
@ -37,11 +37,11 @@ class interroge_switch (threading.Thread) :
|
|||
if (prise != None):
|
||||
nom=sw.nom(None,prise)
|
||||
if self.affiche_uplinks or "uplink" not in nom:
|
||||
self.reponse = ("%-10s => prise %-2s : %s" % (self.switch.encode('iso-8859-15').replace('.adm.crans.org',''), str(prise), nom))
|
||||
self.reponse = ("%-10s => prise %-2s : %s" % (self.switch.encode('utf-8').replace('.adm.crans.org',''), str(prise), nom))
|
||||
|
||||
|
||||
# Retourne les infos sur la machine (l'équivalent d'un whos, mais renvoie la
|
||||
# chaîne de caractères)
|
||||
# Retourne les infos sur la machine (l'équivalent d'un whos, mais renvoie la
|
||||
# chaîne de caractères)
|
||||
def info_machine(mac):
|
||||
s = []
|
||||
db = crans_ldap()
|
||||
|
@ -52,7 +52,7 @@ def info_machine(mac):
|
|||
r = re.sub('\x1b\[1;([0-9]|[0-9][0-9])m', '', r)
|
||||
s.append(r)
|
||||
if len(machines) == 0:
|
||||
s.append(u"Recherche LDAP de la MAC %s : aucune machine trouvée\n" % mac)
|
||||
s.append(u"Recherche LDAP de la MAC %s : aucune machine trouvée\n" % mac)
|
||||
return u"\n".join(s)
|
||||
|
||||
|
||||
|
@ -66,7 +66,7 @@ def trace_machine(mac, affiche_uplinks=False):
|
|||
for t in tableau:
|
||||
t.join()
|
||||
|
||||
resultat = u'Traçage de %s...\n' % mac
|
||||
resultat = u'Traçage de %s...\n' % mac
|
||||
|
||||
tracage = u''
|
||||
for t in tableau:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- encoding: iso-8859-15 -*-
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Stats sur les historiques
|
||||
|
||||
|
@ -13,22 +13,22 @@ import re
|
|||
from time import mktime, strptime
|
||||
|
||||
def plat(chose):
|
||||
"""Applatit une liste de liste. Hautement récursif."""
|
||||
"""Applatit une liste de liste. Hautement récursif."""
|
||||
if type(chose) != ListType:
|
||||
return [chose]
|
||||
return sum(map(lambda x: plat(x), chose), [])
|
||||
|
||||
|
||||
def hist():
|
||||
"""Récupère l'historique dans une base SQLite dont la connexion est returnée."""
|
||||
# On récupèr les adhérents
|
||||
"""Récupère l'historique dans une base SQLite dont la connexion est returnée."""
|
||||
# On récupèr les adhérents
|
||||
adherents = crans_ldap().search("nom=*")['adherent']
|
||||
# Et les historiques rattachés à eux et à leurs machines
|
||||
# Et les historiques rattachés à eux et à leurs machines
|
||||
historiques = map(lambda x: [x.historique(), map(lambda y: y.historique(), x.machines())],
|
||||
adherents)
|
||||
historiques = plat(historiques)
|
||||
# On va maintenant coller les historiques dans une structure plus
|
||||
# sympa, style une base SQL que l'on garde en mémoire
|
||||
# sympa, style une base SQL que l'on garde en mémoire
|
||||
con = sqlite.connect("historiques")
|
||||
cur = con.cursor()
|
||||
cur.execute("CREATE TABLE historique (date INTEGER, nom TEXT, action TEXT)")
|
||||
|
|
5
gestion/virtualisation/manage.py
Normal file
5
gestion/virtualisation/manage.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
#
|
||||
# High level interface between XEN
|
||||
# and XEN user
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
# #############################################################
|
||||
# ..
|
||||
# .... ............ ........
|
||||
|
@ -28,7 +28,7 @@
|
|||
Copyright (c) 2006 by www.crans.org
|
||||
"""
|
||||
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
import time
|
||||
# Fin
|
||||
import sys, tempfile, os, commands, shutil, syslog, stat
|
||||
|
@ -48,7 +48,7 @@ COUT_UNITE_NOIRE = config.impression.c_noir
|
|||
COUT_PASSAGE_TAMBOUR_NOIR = config.impression.c_tambour_noir
|
||||
COUT_PASSAGE_TAMBOUR_COULEUR = config.impression.c_tambour_coul
|
||||
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
FICHIER_LOG="/var/log/log_couts/estimations"
|
||||
# Fin
|
||||
|
||||
|
@ -88,10 +88,10 @@ def try_command(cmd, tmp_rep, error_msg):
|
|||
def base_prix(path_pdf_file, color=False):
|
||||
u""" Calcul le prix d'une impression couleur ou noir et blanc sur papier A4 """
|
||||
|
||||
# nom_rep seras le dossier dans tmp ou tous les fichier créé par
|
||||
# convert seront entreposé
|
||||
# nom_rep seras le dossier dans tmp ou tous les fichier créé par
|
||||
# convert seront entreposé
|
||||
nom_rep = tempfile.mkdtemp(prefix='tmpimpr')
|
||||
nom_png = "%s/convert.png" % nom_rep # Nom prefixe et chemin des png créé par convert
|
||||
nom_png = "%s/convert.png" % nom_rep # Nom prefixe et chemin des png créé par convert
|
||||
escaped_path_pdf_file = escapeForShell(path_pdf_file)
|
||||
escaped_path_ps_file = escapeForShell(path_pdf_file + ".ps")
|
||||
error_msg = "ERREUR %%d : Fichier invalide. Aucun %s cree."
|
||||
|
@ -113,14 +113,14 @@ def base_prix(path_pdf_file, color=False):
|
|||
nom_rep,
|
||||
error_msg % "ps")
|
||||
|
||||
# Convertit les ps en png (il est néscessaire de passer par un ps
|
||||
# Convertit les ps en png (il est néscessaire de passer par un ps
|
||||
# car ghostscript refuse certain pdf)
|
||||
try_command("nice -n 5 gs -sDEVICE=%s -r30 -dBATCH -dNOPAUSE -dSAFER -dPARANOIDSAFER -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dMaxBitmap=50000000 -sOutputFile=%s%%d -q %s" %
|
||||
(gs_device, nom_png, escaped_path_ps_file),
|
||||
nom_rep,
|
||||
error_msg % "png")
|
||||
|
||||
# Récupère la liste des fichiers
|
||||
# Récupère la liste des fichiers
|
||||
list_filepng=os.listdir(nom_rep)
|
||||
# Calcule le nombre de pixel
|
||||
remplissage = [0] * (nb_composante + 1) # couleurs (N ou CMJN), nombre de pages
|
||||
|
@ -146,7 +146,7 @@ def base_prix(path_pdf_file, color=False):
|
|||
c_total = (COUT_PASSAGE_TAMBOUR_NOIR * faces # passage dans les toners
|
||||
+ COUT_UNITE_NOIRE * total_noir) # cout encre noire
|
||||
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
fichier_log_est=open(FICHIER_LOG,"a")
|
||||
fichier_log_est.write("%d %d %3d %10.3f %10.3f %s\n" % (time.time(), color, faces, total_noir, total_couleur, path_pdf_file) )
|
||||
fichier_log_est.close()
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
etat_imprimante.py
|
||||
|
||||
Récupère, filtre et formate l'état actuel de l'imprimante
|
||||
Récupère, filtre et formate l'état actuel de l'imprimante
|
||||
|
||||
Copyright (c) 2006, 2007, 2008, 2009 by Cr@ns (http://www.crans.org)
|
||||
|
||||
|
@ -28,7 +28,7 @@ def etat_canon():
|
|||
'printing(4)\nrunning(2)' : u'Impression en cours',
|
||||
'other(1)\ndown(5)' : u"Imprimante hors-service",
|
||||
'other(1)\nrunning(2)' : u'Imprimante en veille',
|
||||
'warmup(5)\nrunning(2)' : u'Préchauffage',
|
||||
'warmup(5)\nrunning(2)' : u'Préchauffage',
|
||||
'idle(3)\nwarning(3)' : u'Imprimante fonctionnelle',
|
||||
'printing(4)\nwarning(3)' : u'Impression en cours'
|
||||
}
|
||||
|
@ -53,15 +53,15 @@ def etat_canon():
|
|||
def etat_laserjet():
|
||||
""" Renvoie une liste des differents ecrans actuels du display de l'imprimante """
|
||||
_dico = {
|
||||
u"READY": u"Prête",
|
||||
u"PrÁt": u"Prêt",
|
||||
u"READY": u"Prête",
|
||||
u"PrÁt": u"Prêt",
|
||||
u"Pr menus, appuy \x1e": u"",
|
||||
u"Powersave activÅ": u"En veille",
|
||||
u"Verification": u"Vérification imprimante",
|
||||
u"Powersave activÅ": u"En veille",
|
||||
u"Verification": u"Vérification imprimante",
|
||||
u"imprimante": u"",
|
||||
u"PrÅchauffage": u"Préchauffage",
|
||||
u"PrÅchauffage": u"Préchauffage",
|
||||
u"Traitement de la": u"Impression en cours",
|
||||
u"tÀche du bac 4": u"",
|
||||
u"tÀche du bac 4": u"",
|
||||
u"COMMANDER CARTOUCHE": u"",
|
||||
u"COMMANDER KIT NETTOY": u"",
|
||||
u"COMMANDER FOURNIT.": u"",
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#! /bin/sh
|
||||
|
||||
LANG=fr_FR@euro sudo -u respbats /usr/scripts/gestion/gest_crans.py $*
|
||||
LANG=fr_FR.UTF-8 sudo -u respbats /usr/scripts/gestion/gest_crans.py $*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
#execution avec des droits suffisants
|
||||
LANG=fr_FR@euro sudo -u '#120' /usr/scripts/gestion/tools/locate_mac.py $*
|
||||
LANG=fr_FR.UTF-8 sudo -u '#120' /usr/scripts/gestion/tools/locate_mac.py $*
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#! /bin/sh
|
||||
|
||||
#LANG=fr_FR@euro
|
||||
sudo -u respbats /usr/scripts/gestion/logreader/rsyslog_reader.py $*
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#! /bin/sh
|
||||
|
||||
LANG=fr_FR@euro sudo -u respbats /usr/scripts/gestion/ressuscite.py $*
|
||||
LANG=fr_FR.UTF-8 sudo -u respbats /usr/scripts/gestion/ressuscite.py $*
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
LANG=fr_FR@euro sudo -u respbats /usr/scripts/gestion/whos.py $*
|
||||
LANG=fr_FR.UTF-8 sudo -u respbats /usr/scripts/gestion/whos.py $*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
#execution avec des droits suffisants
|
||||
LANG=fr_FR@euro sudo -u 'arpwatch' /usr/scripts/surveillance/arpwatch_sendmail.py $*
|
||||
LANG=fr_FR.UTF-8 sudo -u 'arpwatch' /usr/scripts/surveillance/arpwatch_sendmail.py $*
|
||||
|
|
|
@ -1,49 +1,149 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
# Ajout d'un whos et d'un tracage aux mails d'arpwatch
|
||||
# Auteurs : Stéphane Glondu, Cyril Cohen
|
||||
# Licence : GPLv2
|
||||
|
||||
import sys, os, re, smtplib
|
||||
from commands import getstatusoutput
|
||||
|
||||
sys.path.append('/usr/scripts/gestion/tools')
|
||||
from locate_mac import trace_machine, format_mac, info_machine
|
||||
|
||||
find_mac = re.compile(r'[0-9A-Fa-f]{1,2}(?::[0-9A-Fa-f]{1,2}){5}')
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
|
||||
def get_machine(unformated_mac):
|
||||
mac = format_mac(unformated_mac)
|
||||
return u"\n" + info_machine(mac) + u"\n" + trace_machine(mac)
|
||||
###########################
|
||||
# Import des commmandes : #
|
||||
###########################
|
||||
|
||||
import commands
|
||||
import os
|
||||
# import pg # Import des commandes de postgres
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
import iptools
|
||||
import psycopg2
|
||||
import re
|
||||
sys.path.append('/usr/script/surveillance')
|
||||
import strptime
|
||||
|
||||
# Définition de constantes :
|
||||
############################
|
||||
reseau = ["138.231.136.0/21", "138.231.148.0/22"]
|
||||
|
||||
# Ouverture de la base de données :
|
||||
###################################
|
||||
pgsql = psycopg2.connect(host='pgsql.adm.crans.org', database='filtrage', user='crans')
|
||||
# Ancienne méthode pour faire de l'autocommit.
|
||||
# Sous wheezy, il faudra remplacer par pgsql.set_session(autocommit=True) !!!
|
||||
pgsql.set_isolation_level(0)
|
||||
curseur = pgsql.cursor()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
texte = sys.stdin.read() #.decode('ISO-8859-15')
|
||||
textes = texte.splitlines(True)
|
||||
i = textes.index(u'\n')
|
||||
textes[i-1:i-1] = [
|
||||
u'MIME-Version: 1.0\n',
|
||||
u'Content-Type: text/plain; charset=UTF-8\n',
|
||||
u'Content-Transfer-Encoding: 8bit\n',
|
||||
]
|
||||
###########################################
|
||||
# Récupération des tables de protocoles : #
|
||||
###########################################
|
||||
|
||||
# On récupère les destinataires dans les arguments (très ad hoc)
|
||||
recipients = sys.argv[2].split(',')
|
||||
# On complète le message
|
||||
try:
|
||||
macs = find_mac.findall(texte)
|
||||
for mac in macs:
|
||||
textes.append(get_machine(mac))
|
||||
except:
|
||||
# En cas d'exception, on envoie le traceback
|
||||
import traceback
|
||||
textes.append(u'\n')
|
||||
textes.append(u''.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)))
|
||||
textes.append('\n-- \narpwatch_sendmail.py\n')
|
||||
requete = "SELECT nom,id_p2p from protocole_p2p"
|
||||
curseur.execute(requete)
|
||||
curseur.fetchall
|
||||
tableau = curseur.fetchall()
|
||||
protocole_p2p = {}
|
||||
for cellule in tableau:
|
||||
protocole_p2p[cellule[0]]=cellule[1]
|
||||
|
||||
smtp = smtplib.SMTP()
|
||||
smtp.connect()
|
||||
smtp.sendmail("arpwatch@crans.org", recipients, u''.join(textes).encode('UTF-8'))
|
||||
smtp.quit()
|
||||
requete = "SELECT nom,id from protocole"
|
||||
curseur.execute(requete)
|
||||
curseur.fetchall
|
||||
tableau = curseur.fetchall()
|
||||
protocole = {}
|
||||
for cellule in tableau:
|
||||
protocole[cellule[0]]=cellule[1]
|
||||
|
||||
|
||||
|
||||
##############################################################
|
||||
# Parser ler log du firewall: /var/log/firewall/filtre.log : #
|
||||
##############################################################
|
||||
|
||||
# Définition des motifs des comparaisons :
|
||||
##########################################
|
||||
motif_p2p = re.compile("^(.*) komaz .* IPP2P=([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*")
|
||||
|
||||
motif_virus = re.compile("^(.*) komaz .* Virus:([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*")
|
||||
|
||||
motif_flood = re.compile("^(.*) komaz .* Flood:([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*")
|
||||
|
||||
|
||||
# On récupère en continu les log du firewall:
|
||||
#############################################
|
||||
filtre = os.popen("tail -F /var/log/firewall/filtre.log 2> /dev/null")
|
||||
|
||||
|
||||
# On matche les log du firewall avec les motifs :
|
||||
#################################################
|
||||
for log in filtre:
|
||||
resultat_p2p = motif_p2p.match(log)
|
||||
resultat_virus = motif_virus.match(log)
|
||||
resultat_flood = motif_flood.match(log)
|
||||
|
||||
if resultat_p2p :
|
||||
try:
|
||||
ip_src = resultat_p2p.group(3)
|
||||
verif = iptools.AddrInNets (ip_src,reseau)
|
||||
except ValueError:
|
||||
continue #IP malformee
|
||||
if verif :
|
||||
try:
|
||||
date = resultat_p2p.group(1)
|
||||
id_p2p = int(protocole_p2p[resultat_p2p.group(2)])
|
||||
ip_src = resultat_p2p.group(3)
|
||||
ip_dest = resultat_p2p.group(4)
|
||||
proto = int(protocole[resultat_p2p.group(5)]) #C'est à dire id pour la base
|
||||
port_src = int(resultat_p2p.group(6))
|
||||
port_dest = int(resultat_p2p.group(7))
|
||||
date=strptime.syslog2pgsql(date)
|
||||
except ValueError, KeyError:
|
||||
continue #mal parse
|
||||
|
||||
# On remplit la base :
|
||||
######################
|
||||
requete = "INSERT INTO p2p (date,ip_src,ip_dest,id_p2p,id,port_src,port_dest) VALUES ('%s','%s','%s',%d,%d,%d,%d)" % (date,ip_src,ip_dest,id_p2p,proto,port_src,port_dest)
|
||||
curseur.execute(requete)
|
||||
|
||||
# On teste si le log contient des virus
|
||||
########################################
|
||||
elif resultat_virus :
|
||||
try:
|
||||
ip_src = resultat_virus.group(3)
|
||||
verif = iptools.AddrInNets (ip_src,reseau)
|
||||
except ValueError:
|
||||
continue
|
||||
if verif :
|
||||
try:
|
||||
date = resultat_virus.group(1)
|
||||
ip_src = resultat_virus.group(3)
|
||||
ip_dest = resultat_virus.group(4)
|
||||
proto = int(protocole[resultat_virus.group(5)]) #C'est à dire id pour la base
|
||||
port_src = int(resultat_virus.group(6))
|
||||
port_dest = int(resultat_virus.group(7))
|
||||
# On remplit la base :
|
||||
######################
|
||||
date=strptime.syslog2pgsql(date)
|
||||
except ValueError, KeyError:
|
||||
continue
|
||||
requete = "INSERT INTO virus (date,ip_src,ip_dest,id,port_src,port_dest) VALUES ('%s','%s','%s',%d,%d,%d)" % (date,ip_src,ip_dest,proto,port_src,port_dest)
|
||||
curseur.execute(requete)
|
||||
|
||||
elif resultat_flood :
|
||||
try:
|
||||
ip_src = resultat_flood.group(3)
|
||||
verif = iptools.AddrInNets (ip_src,reseau)
|
||||
except ValueError:
|
||||
continue
|
||||
if verif :
|
||||
try:
|
||||
date = resultat_flood.group(1)
|
||||
ip_src = resultat_flood.group(3)
|
||||
ip_dest = resultat_flood.group(4)
|
||||
proto = int(protocole[resultat_flood.group(5)]) #C'est à dire id pour la base
|
||||
port_src = int(resultat_flood.group(6))
|
||||
port_dest = int(resultat_flood.group(7))
|
||||
|
||||
# On remplit la base :
|
||||
######################
|
||||
date=strptime.syslog2pgsql(date)
|
||||
except ValueError, KeyError:
|
||||
continue
|
||||
requete = "INSERT INTO flood (date,ip_src,ip_dest,id,port_src,port_dest) VALUES ('%s','%s','%s',%d,%d,%d)" % (date,ip_src,ip_dest,proto,port_src,port_dest)
|
||||
curseur.execute(requete)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""DESCRIPTION
|
||||
Ce script repère les comptes inactifs en parsant les logs de dernière
|
||||
connexion de sshd et dovecot, et en lisant et mettant à jour les champs
|
||||
Ce script repère les comptes inactifs en parsant les logs de dernière
|
||||
connexion de sshd et dovecot, et en lisant et mettant à jour les champs
|
||||
derniereConnexion dans la base LDAP.
|
||||
|
||||
UTILISATION
|
||||
|
@ -12,7 +12,7 @@ UTILISATION
|
|||
ACTIONS POSSIBLES
|
||||
%(acts)s"""
|
||||
|
||||
# Copyright (C) 2006 Stéphane Glondu
|
||||
# Copyright (C) 2006 Stéphane Glondu
|
||||
# Licence : GPLv2
|
||||
|
||||
|
||||
|
@ -41,8 +41,8 @@ openlog('comptes_inactifs')
|
|||
|
||||
def nb_mails_non_lus(login):
|
||||
"""
|
||||
Renvoie le nombre de mails non lus de login, ou None si impossible à
|
||||
déterminer.
|
||||
Renvoie le nombre de mails non lus de login, ou None si impossible à
|
||||
déterminer.
|
||||
"""
|
||||
try:
|
||||
maildir = '/var/mail/%s/new' % login
|
||||
|
@ -56,8 +56,8 @@ def nb_mails_non_lus(login):
|
|||
|
||||
|
||||
class ComptesInactifs(object):
|
||||
# liste d'expressions régulières qui seront testées sur les lignes de log
|
||||
# le premier groupe doit correspondre à la date, le second au login
|
||||
# liste d'expressions régulières qui seront testées sur les lignes de log
|
||||
# le premier groupe doit correspondre à la date, le second au login
|
||||
re = [re.compile(r'^(\w+\s+\d+\s+\d+:\d+:\d+).*(?:'
|
||||
r'dovecot.*Login: user=<|'
|
||||
r'sshd.*Accepted.*for '
|
||||
|
@ -70,7 +70,7 @@ class ComptesInactifs(object):
|
|||
self.dic = {}
|
||||
|
||||
def search(self, query, mode=''):
|
||||
""" CransLdap.search allégé """
|
||||
""" CransLdap.search allégé """
|
||||
query = '(&(objectClass=cransAccount)(objectClass=adherent)(%s))' % query
|
||||
result = db.conn.search_s(db.base_dn, db.scope['adherent'], query)
|
||||
result = [db.make(x, mode) for x in result]
|
||||
|
@ -79,13 +79,13 @@ class ComptesInactifs(object):
|
|||
def commit_to_ldap(self):
|
||||
"""
|
||||
Sauvegarde du dico dans la base LDAP.
|
||||
Renvoie le nombre d'entrées mises à jour.
|
||||
Renvoie le nombre d'entrées mises à jour.
|
||||
"""
|
||||
total = 0
|
||||
for (login, timestamp) in self.dic.items():
|
||||
a = self.search('uid=%s' % login, 'w')
|
||||
if not a:
|
||||
# Probablement un adhérent récemment parti
|
||||
# Probablement un adhérent récemment parti
|
||||
continue
|
||||
a = a[0]
|
||||
if a._modifiable == 'w':
|
||||
|
@ -93,7 +93,7 @@ class ComptesInactifs(object):
|
|||
if a.modifs: total += 1
|
||||
a.save()
|
||||
else:
|
||||
# on loggue on espérant que les logs seront réinjectés
|
||||
# on loggue on espérant que les logs seront réinjectés
|
||||
# plus tard
|
||||
syslog("LDAP(lock): derniereConnexion=<%s>, login=<%s>" %
|
||||
(strftime("%b %d %H:%M:%S", localtime(timestamp)), login))
|
||||
|
@ -101,7 +101,7 @@ class ComptesInactifs(object):
|
|||
|
||||
def update(self, login, timestamp):
|
||||
"""
|
||||
Met à jour l'entrée correspondant au login donné.
|
||||
Met à jour l'entrée correspondant au login donné.
|
||||
"""
|
||||
dic = self.dic
|
||||
timestamp = int(timestamp)
|
||||
|
@ -110,8 +110,8 @@ class ComptesInactifs(object):
|
|||
|
||||
def update_from_syslog(self, loglines):
|
||||
"""
|
||||
Met à jour le dico avec les lignes de syslog données.
|
||||
Renvoie le nombre de lignes traitées.
|
||||
Met à jour le dico avec les lignes de syslog données.
|
||||
Renvoie le nombre de lignes traitées.
|
||||
"""
|
||||
annee = localtime(time())[0]
|
||||
now = time() + 600
|
||||
|
@ -124,8 +124,8 @@ class ComptesInactifs(object):
|
|||
date = list(strptime(m.group(1), "%b %d %H:%M:%S"))
|
||||
date[0] = annee
|
||||
t = mktime(date)
|
||||
# les lignes de syslog n'indiquent pas l'année
|
||||
# on suppose qu'une date dans le futur est en fait l'année dernière
|
||||
# les lignes de syslog n'indiquent pas l'année
|
||||
# on suppose qu'une date dans le futur est en fait l'année dernière
|
||||
if t > now:
|
||||
date[0] = annee - 1
|
||||
t = mktime(date)
|
||||
|
@ -135,21 +135,21 @@ class ComptesInactifs(object):
|
|||
|
||||
def do_log(self):
|
||||
"""
|
||||
Lit des lignes de log sur l'entrée std et met à jour la base LDAP.
|
||||
Lit des lignes de log sur l'entrée std et met à jour la base LDAP.
|
||||
"""
|
||||
parsed_lines = self.update_from_syslog(sys.stdin)
|
||||
updated_entries = self.commit_to_ldap()
|
||||
syslog("%(parsed_lines)s ligne(s) traitée(s)" % locals())
|
||||
syslog("%(updated_entries)s entrée(s) mise(s) à jour dans la base LDAP" % locals())
|
||||
syslog("%(parsed_lines)s ligne(s) traitée(s)" % locals())
|
||||
syslog("%(updated_entries)s entrée(s) mise(s) à jour dans la base LDAP" % locals())
|
||||
if parsed_lines == 0 or updated_entries == 0:
|
||||
sys.stderr.write("""Erreur lors de la mise à jour de la base LDAP :
|
||||
%(parsed_lines)s ligne(s) traitée(s)
|
||||
%(updated_entries)s entrée(s) mise(s) à jour dans la base LDAP
|
||||
sys.stderr.write("""Erreur lors de la mise à jour de la base LDAP :
|
||||
%(parsed_lines)s ligne(s) traitée(s)
|
||||
%(updated_entries)s entrée(s) mise(s) à jour dans la base LDAP
|
||||
""" % locals())
|
||||
|
||||
def do_dump(self):
|
||||
"""
|
||||
Affiche la liste des dernières connexions, triées par date.
|
||||
Affiche la liste des dernières connexions, triées par date.
|
||||
"""
|
||||
liste = self.search('derniereConnexion=*')
|
||||
liste = [(x.derniereConnexion(), x.compte()) for x in liste]
|
||||
|
@ -157,15 +157,15 @@ class ComptesInactifs(object):
|
|||
liste = [(x[1], strftime('%d/%m/%Y %H:%M', localtime(x[0])))
|
||||
for x in liste]
|
||||
cprint(tableau(liste,
|
||||
titre = (u'Login', u'Dernière connexion'),
|
||||
titre = (u'Login', u'Dernière connexion'),
|
||||
largeur = (20, 20)))
|
||||
cprint(u"Total : %d" % len(liste))
|
||||
|
||||
def get_idle_accounts(self, since=32*24*3600):
|
||||
"""
|
||||
Renvoie la liste des objets Adherent de ceux qui ne se sont pas
|
||||
connectés depuis since secondes, par défaut un mois (32 jours,
|
||||
pour être sûr).
|
||||
connectés depuis since secondes, par défaut un mois (32 jours,
|
||||
pour être sûr).
|
||||
"""
|
||||
limit = int(time()) - since
|
||||
liste = self.search("derniereConnexion<=%d" % limit)
|
||||
|
@ -176,20 +176,20 @@ class ComptesInactifs(object):
|
|||
|
||||
def do_summary(self):
|
||||
"""
|
||||
Envoie à disconnect un résume des comptes inactifs depuis plus d'un
|
||||
Envoie à disconnect un résume des comptes inactifs depuis plus d'un
|
||||
mois.
|
||||
"""
|
||||
modele = u"""*Membres inscrits ne s'étant pas connectés depuis plus d'un mois*
|
||||
modele = u"""*Membres inscrits ne s'étant pas connectés depuis plus d'un mois*
|
||||
|
||||
%(inscrits)s
|
||||
Total : %(inscrits_total)d
|
||||
|
||||
*Anciens membres ne s'étant pas connectés depuis plus d'un mois*
|
||||
*Anciens membres ne s'étant pas connectés depuis plus d'un mois*
|
||||
|
||||
%(anciens)s
|
||||
Total : %(anciens_total)d
|
||||
|
||||
Légende :
|
||||
Légende :
|
||||
- F : existence d'un .forward
|
||||
- M : existence de mails non lus
|
||||
|
||||
|
@ -219,7 +219,7 @@ comptes_inactifs.py
|
|||
else:
|
||||
anciens.append(ligne)
|
||||
|
||||
titres = (u'aid', u'Login', u'Nom', u'Dernière connexion', u'F', u'M')
|
||||
titres = (u'aid', u'Login', u'Nom', u'Dernière connexion', u'F', u'M')
|
||||
largeurs = (6, 15, 20, 20, 1, 1)
|
||||
alignements = ('d', 'g', 'c', 'c', 'c', 'c')
|
||||
|
||||
|
@ -237,9 +237,9 @@ comptes_inactifs.py
|
|||
def do_spam(self):
|
||||
"""
|
||||
Envoie un mail explicatif aux possesseurs de compte inactif
|
||||
(doit être exécuté en tant que root).
|
||||
(doit être exécuté en tant que root).
|
||||
"""
|
||||
# Nombre de personnes concernées, en expansant de droite à gauche :
|
||||
# Nombre de personnes concernées, en expansant de droite à gauche :
|
||||
# inscrit/ancien, avec/sans procmail, avec/sans mail non lu
|
||||
# Voir aussi template_path
|
||||
stats = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
@ -262,7 +262,7 @@ comptes_inactifs.py
|
|||
if not os.path.isfile('/home/%s/.forward' % login): i += 2
|
||||
# a-il-des mails non lus ?
|
||||
if not mail: i += 1
|
||||
# on incrémente
|
||||
# on incrémente
|
||||
stats[i] += 1
|
||||
if i == 1:
|
||||
# on laisse tranquilles les membres inscrits sans mails non
|
||||
|
@ -303,7 +303,7 @@ comptes_inactifs.py
|
|||
""" % total
|
||||
send_email(mail_sender,
|
||||
mail_report,
|
||||
u"Récapitulatif des comptes inactifs",
|
||||
u"Récapitulatif des comptes inactifs",
|
||||
recapitulatif,
|
||||
server = smtp,
|
||||
debug = debug)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Encoding: iso-8859-15
|
||||
Encoding: utf-8
|
||||
Subject: [CRANS] Compte inactif depuis plus d'un mois
|
||||
|
||||
Bonjour %(nom)s,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Encoding: iso-8859-15
|
||||
Encoding: utf-8
|
||||
Subject: [CRANS] Compte inactif depuis plus d'un mois
|
||||
|
||||
Bonjour %(nom)s,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Encoding: iso-8859-15
|
||||
Encoding: utf-8
|
||||
Subject: [CRANS] Compte inactif depuis plus d'un mois
|
||||
|
||||
Bonjour %(nom)s,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Encoding: iso-8859-15
|
||||
Encoding: utf-8
|
||||
Subject: [CRANS] Compte inactif depuis plus d'un mois
|
||||
|
||||
Bonjour %(nom)s,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Encoding: iso-8859-15
|
||||
Encoding: utf-8
|
||||
Subject: [CRANS] Compte inactif depuis plus d'un mois
|
||||
|
||||
Bonjour %(nom)s,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Script de déconnection automatique des machines du crans pour les raisons :
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- encoding: iso-8859-15 -*-
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Utilisation de scappy pour détecter un DHCP pirate.
|
||||
# Utilisation de scappy pour détecter un DHCP pirate.
|
||||
# $Id: dhcp-detect.py,v 1.3 2006/12/11 23:31:39 glondu Exp $
|
||||
|
||||
import sys, os
|
||||
|
@ -25,23 +25,23 @@ PIDFILE = "/var/run/dhcp-detect.pid"
|
|||
# dhcp-server attendu
|
||||
DHCPSERVER = '138.231.136.9'
|
||||
|
||||
# Interface à surveiller
|
||||
# Interface à surveiller
|
||||
INTERFACE = "crans"
|
||||
|
||||
# Adresse MAC
|
||||
mac = os.popen(r"ifconfig | grep '^%s' | awk '{print $(NF)}'" % INTERFACE).readline().strip()
|
||||
|
||||
# Paquet à envoyer pour détecter un DHCP (il a été capturé pour avoir la bonne tête)
|
||||
# Paquet à envoyer pour détecter un DHCP (il a été capturé pour avoir la bonne tête)
|
||||
tosend = Ether("\xff\xff\xff\xff\xff\xff\x00\x80\xc8\xc9\xab\x01\x08\x00E\x10\x01H\x00\x00\x00\x00@\x11y\x96\x00\x00\x00\x00\xff\xff\xff\xff\x00D\x00C\x014\x9aA\x01\x01\x06\x00\xb2\x87\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xc8\xc9\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x012\x04R\xe1'67\x07\x01\x1c\x02\x03\x0f\x06\x0c\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
|
||||
|
||||
# On met à jour ce paquet
|
||||
# On met à jour ce paquet
|
||||
tosend.getlayer(Ether).src = mac
|
||||
tosend.getlayer(IP).chksum = None
|
||||
tosend.getlayer(UDP).chksum = None
|
||||
tosend.getlayer(BOOTP).chaddr = ''.join(map(lambda x: chr(int(x,16)),mac.split(":")+['0']*10))
|
||||
tosend = Ether(tosend.build())
|
||||
|
||||
# Tableau associatif "mac" - "mailé pour la dernière fois"
|
||||
# Tableau associatif "mac" - "mailé pour la dernière fois"
|
||||
dejavu = {}
|
||||
|
||||
|
||||
|
@ -88,7 +88,7 @@ def mail(paquet):
|
|||
print "Envoi d'un mail...",
|
||||
msg = u"""Boujour,
|
||||
|
||||
Un DHCP pirate a été découvert sur le réseau. Voici quelques renseignements mineurs à son sujet :
|
||||
Un DHCP pirate a été découvert sur le réseau. Voici quelques renseignements mineurs à son sujet :
|
||||
|
||||
Son adresse Ethernet : %s
|
||||
Son adresse IP : %s
|
||||
|
@ -99,7 +99,7 @@ Un DHCP pirate a
|
|||
msg += u"\n"
|
||||
msg += info_machine(mac_pirate)
|
||||
msg += u"""
|
||||
Merci de votre attention et à bientôt.
|
||||
Merci de votre attention et à bientôt.
|
||||
|
||||
--
|
||||
dhcp-detect.py
|
||||
|
@ -111,10 +111,10 @@ dhcp-detect.py
|
|||
print "ok"
|
||||
|
||||
|
||||
# Réception d'une réponse
|
||||
# Réception d'une réponse
|
||||
def recoit(paquet):
|
||||
# On affiche
|
||||
print "Réception de : ", paquet.summary()
|
||||
print "Réception de : ", paquet.summary()
|
||||
# On verifie que c'est bien ce qu'on attend
|
||||
if paquet.getlayer(Ether).dst.upper() == globals()['mac'] and paquet.haslayer(BOOTP) and paquet.getlayer(BOOTP).op == 2 and paquet.getlayer(IP).src != DHCPSERVER:
|
||||
# DHCP pirate ?
|
||||
|
@ -140,7 +140,7 @@ def get():
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# On quitte les éventuelles instances démonisées en cours
|
||||
# On quitte les éventuelles instances démonisées en cours
|
||||
try:
|
||||
pid = int(file(PIDFILE).read().strip())
|
||||
os.kill(pid, 15)
|
||||
|
@ -150,12 +150,12 @@ if __name__ == "__main__":
|
|||
createDaemon()
|
||||
file(PIDFILE, "w").write("%d\n" % os.getpid())
|
||||
else:
|
||||
print "Le paquet suivant va être envoyé à intervalles réguliers pour tester la présence de DHCP pirates :"
|
||||
print "Le paquet suivant va être envoyé à intervalles réguliers pour tester la présence de DHCP pirates :"
|
||||
print tosend.summary()
|
||||
|
||||
openlog("dhcp-detect", LOG_PID)
|
||||
syslog("Démarrage de dhcp-detect")
|
||||
# On démarre le thread qui envoie régulièrement le paquet...
|
||||
syslog("Démarrage de dhcp-detect")
|
||||
# On démarre le thread qui envoie régulièrement le paquet...
|
||||
Thread(target=send, name="send").start()
|
||||
# ...et celui qui sniffe régulièrement la réponse
|
||||
# ...et celui qui sniffe régulièrement la réponse
|
||||
Thread(target=get, name="get").start()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- encoding: iso-8859-15 -*-
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
|
||||
###########################
|
||||
|
@ -17,21 +17,21 @@ import re
|
|||
sys.path.append('/usr/script/surveillance')
|
||||
import strptime
|
||||
|
||||
# Définition de constantes :
|
||||
# Définition de constantes :
|
||||
############################
|
||||
reseau = ["138.231.136.0/21", "138.231.148.0/22"]
|
||||
|
||||
# Ouverture de la base de données :
|
||||
# Ouverture de la base de données :
|
||||
###################################
|
||||
pgsql = psycopg2.connect(host='pgsql.adm.crans.org', database='filtrage', user='crans')
|
||||
# Ancienne méthode pour faire de l'autocommit.
|
||||
# Ancienne méthode pour faire de l'autocommit.
|
||||
# Sous wheezy, il faudra remplacer par pgsql.set_session(autocommit=True) !!!
|
||||
pgsql.set_isolation_level(0)
|
||||
curseur = pgsql.cursor()
|
||||
|
||||
|
||||
###########################################
|
||||
# Récupération des tables de protocoles : #
|
||||
# Récupération des tables de protocoles : #
|
||||
###########################################
|
||||
|
||||
requete = "SELECT nom,id_p2p from protocole_p2p"
|
||||
|
@ -56,7 +56,7 @@ for cellule in tableau:
|
|||
# Parser ler log du firewall: /var/log/firewall/filtre.log : #
|
||||
##############################################################
|
||||
|
||||
# Définition des motifs des comparaisons :
|
||||
# Définition des motifs des comparaisons :
|
||||
##########################################
|
||||
motif_p2p = re.compile("^(.*) komaz .* IPP2P=([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*")
|
||||
|
||||
|
@ -65,7 +65,7 @@ motif_virus = re.compile("^(.*) komaz .* Virus:([^ ]*).* SRC=([^ ]*).* DST=([^ ]
|
|||
motif_flood = re.compile("^(.*) komaz .* Flood:([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*")
|
||||
|
||||
|
||||
# On récupère en continu les log du firewall:
|
||||
# On récupère en continu les log du firewall:
|
||||
#############################################
|
||||
filtre = os.popen("tail -F /var/log/firewall/filtre.log 2> /dev/null")
|
||||
|
||||
|
@ -89,7 +89,7 @@ for log in filtre:
|
|||
id_p2p = int(protocole_p2p[resultat_p2p.group(2)])
|
||||
ip_src = resultat_p2p.group(3)
|
||||
ip_dest = resultat_p2p.group(4)
|
||||
proto = int(protocole[resultat_p2p.group(5)]) #C'est à dire id pour la base
|
||||
proto = int(protocole[resultat_p2p.group(5)]) #C'est à dire id pour la base
|
||||
port_src = int(resultat_p2p.group(6))
|
||||
port_dest = int(resultat_p2p.group(7))
|
||||
date=strptime.syslog2pgsql(date)
|
||||
|
@ -114,7 +114,7 @@ for log in filtre:
|
|||
date = resultat_virus.group(1)
|
||||
ip_src = resultat_virus.group(3)
|
||||
ip_dest = resultat_virus.group(4)
|
||||
proto = int(protocole[resultat_virus.group(5)]) #C'est à dire id pour la base
|
||||
proto = int(protocole[resultat_virus.group(5)]) #C'est à dire id pour la base
|
||||
port_src = int(resultat_virus.group(6))
|
||||
port_dest = int(resultat_virus.group(7))
|
||||
# On remplit la base :
|
||||
|
@ -136,7 +136,7 @@ for log in filtre:
|
|||
date = resultat_flood.group(1)
|
||||
ip_src = resultat_flood.group(3)
|
||||
ip_dest = resultat_flood.group(4)
|
||||
proto = int(protocole[resultat_flood.group(5)]) #C'est à dire id pour la base
|
||||
proto = int(protocole[resultat_flood.group(5)]) #C'est à dire id pour la base
|
||||
port_src = int(resultat_flood.group(6))
|
||||
port_dest = int(resultat_flood.group(7))
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
###########################
|
||||
# Import des commmandes : #
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
###############################################################################
|
||||
# parse_auth_log.py : Détecte les problèmes d'authentifications
|
||||
# parse_auth_log.py : Détecte les problèmes d'authentifications
|
||||
###############################################################################
|
||||
# The authors of this code are
|
||||
# Jérémie Dimino <dimino@crans.org>
|
||||
# Jérémie Dimino <dimino@crans.org>
|
||||
#
|
||||
# Copyright (C) 2006 Jérémie Dimino
|
||||
# Copyright (C) 2006 Jérémie Dimino
|
||||
# All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
@ -40,7 +40,7 @@ prise_chbre = {}
|
|||
aujourdhui = datetime.date.today()
|
||||
|
||||
def trouve_chambre(bat, prise):
|
||||
""" Trouve la chambre associée à une prise """
|
||||
""" Trouve la chambre associée à une prise """
|
||||
|
||||
if prise in ('????', 'EXT', 'CRA'):
|
||||
return prise
|
||||
|
@ -59,7 +59,7 @@ def trouve_chambre(bat, prise):
|
|||
|
||||
|
||||
def trouve_prise(chbre):
|
||||
""" Trouve la prise associée à une chambre """
|
||||
""" Trouve la prise associée à une chambre """
|
||||
|
||||
if chbre in ('EXT', '????', 'CRA'):
|
||||
return chbre
|
||||
|
@ -72,7 +72,7 @@ def trouve_prise(chbre):
|
|||
|
||||
|
||||
def __calcul_max(table):
|
||||
""" Calcule les différents maxima (voir parse_auth_log pour plus de détails) """
|
||||
""" Calcule les différents maxima (voir parse_auth_log pour plus de détails) """
|
||||
|
||||
nb_m = 0
|
||||
nb_p = 0
|
||||
|
@ -93,7 +93,7 @@ def __calcul_max(table):
|
|||
|
||||
|
||||
def __ajoute_ligne(errs, ligne, prise, mac, info=None):
|
||||
""" Ajoute une ligne dans le dico pour la prise et la mac donnée """
|
||||
""" Ajoute une ligne dans le dico pour la prise et la mac donnée """
|
||||
|
||||
erreur_prise = errs.get(prise)
|
||||
if not erreur_prise:
|
||||
|
@ -108,29 +108,29 @@ def __ajoute_ligne(errs, ligne, prise, mac, info=None):
|
|||
erreur_mac['lignes'].append(ligne)
|
||||
|
||||
|
||||
# Correspondance 'noms de mois' -> n°
|
||||
# Correspondance 'noms de mois' -> n°
|
||||
__mois_num = { 'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
|
||||
'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12 }
|
||||
|
||||
def parse_auth_log(fichier_log='/var/log/freeradius/radius_auth.log', jour=None):
|
||||
""" Retourne la liste des problèmes de connexions: retourne deux dicos, la première étant pour les macs qui n'ont pas été trouvées dans la base et la seconde pour les connexions qui ont eu lieu à partir d'une mauvaise prise
|
||||
""" Retourne la liste des problèmes de connexions: retourne deux dicos, la première étant pour les macs qui n'ont pas été trouvées dans la base et la seconde pour les connexions qui ont eu lieu à partir d'une mauvaise prise
|
||||
|
||||
les deux dictionnaires ont la structure suivante:
|
||||
- nombre_mac_max: nombre maximal d'erreurs trouvées pour une mac
|
||||
- nombre_prise_max: nombre maximal d'erreurs trouvées pour une prise
|
||||
- prises: dico associant à une prise la listes des erreurs à partir de cette prise:
|
||||
- nombre_mac_max: nombre maximal d'erreurs trouvées pour une mac
|
||||
- nombre_prise_max: nombre maximal d'erreurs trouvées pour une prise
|
||||
- prises: dico associant à une prise la listes des erreurs à partir de cette prise:
|
||||
- nombre: nombre total d'erreurs survenues sur la prise
|
||||
- nombre_max: nombre maximal d'erreurs trouvéss pour une mac
|
||||
- macs: dico associant à une mac la liste des erreurs à partir de cette mac
|
||||
- nombre_max: nombre maximal d'erreurs trouvéss pour une mac
|
||||
- macs: dico associant à une mac la liste des erreurs à partir de cette mac
|
||||
- nombre: le nombre d'erreurs survenues pour cette mac sur cette prise
|
||||
- lignes: la liste des lignes du fichier de logs où la mac apparaît sur cette prise
|
||||
- info: informations sur le propriétaire (vaut None pour la première table)
|
||||
- lignes: la liste des lignes du fichier de logs où la mac apparaît sur cette prise
|
||||
- info: informations sur le propriétaire (vaut None pour la première table)
|
||||
- machine: la machine en question
|
||||
- prise: la prise de sa chambre
|
||||
- chambre: sa chambre
|
||||
- prop: le propriétaire
|
||||
- prop: le propriétaire
|
||||
|
||||
Si jour est spécifié (de type datetime.date), toutes les connexions avant cette dates seront ignorées.
|
||||
Si jour est spécifié (de type datetime.date), toutes les connexions avant cette dates seront ignorées.
|
||||
"""
|
||||
|
||||
try:
|
||||
|
@ -139,13 +139,13 @@ Si jour est sp
|
|||
cprint(u"Impossible d'ouvrir le fichier %s" % fichier_log, 'rouge')
|
||||
sys.exit(1)
|
||||
|
||||
# Les macs non trouvées
|
||||
# Les macs non trouvées
|
||||
errs_inconnue = {}
|
||||
|
||||
# Les pc connectés sur la mauvaise prise
|
||||
# Les pc connectés sur la mauvaise prise
|
||||
errs_prise = {}
|
||||
|
||||
# Les recherches déjà effectuées sur les macs
|
||||
# Les recherches déjà effectuées sur les macs
|
||||
mac_machine = {}
|
||||
|
||||
annee = None
|
||||
|
@ -161,12 +161,12 @@ Si jour est sp
|
|||
|
||||
if annee == None:
|
||||
if nouveau_mois > aujourdhui.month:
|
||||
# Là on suppose qu'il s'agit de l'année dernière
|
||||
# Là on suppose qu'il s'agit de l'année dernière
|
||||
annee = aujourdhui.year - 1
|
||||
else:
|
||||
annee = aujourdhui.year
|
||||
elif mois > nouveau_mois:
|
||||
# Là on suppose qu'on est passé à l'année suivante
|
||||
# Là on suppose qu'on est passé à l'année suivante
|
||||
annee += 1
|
||||
|
||||
mois = nouveau_mois
|
||||
|
@ -213,7 +213,7 @@ Si jour est sp
|
|||
|
||||
|
||||
def affiche_erreurs(errs, message, min_mac=1, min_prise=1):
|
||||
""" Affiche les infos contenues dans un dico renvoyé par parse_auth_log """
|
||||
""" Affiche les infos contenues dans un dico renvoyé par parse_auth_log """
|
||||
|
||||
if errs['nombre_mac_max'] >= min_mac and errs['nombre_prise_max'] >= min_prise:
|
||||
|
||||
|
@ -248,35 +248,35 @@ def __usage(err=''):
|
|||
|
||||
|
||||
def __param_entier(opt, val):
|
||||
""" Récupère un entier passé en ligne de commande """
|
||||
""" Récupère un entier passé en ligne de commande """
|
||||
|
||||
try:
|
||||
return int(val)
|
||||
except:
|
||||
__usage(u'La valeur du paramètre %s est incorecte (doit être un entier positif)' % opt)
|
||||
__usage(u'La valeur du paramètre %s est incorecte (doit être un entier positif)' % opt)
|
||||
|
||||
|
||||
def __aide():
|
||||
""" Aide """
|
||||
|
||||
cprint(u"""Usage: %s [OPTIONS]
|
||||
Parse les logs d'authentifications et affiche les erreurs trouvées (macs inconnues ou connexion d'une machine sur une prise autre que celle du propriétaire).
|
||||
Parse les logs d'authentifications et affiche les erreurs trouvées (macs inconnues ou connexion d'une machine sur une prise autre que celle du propriétaire).
|
||||
|
||||
Options:
|
||||
-h, --help affiche cette aide
|
||||
-l, --log <fichier> fichier de log à parser (par défaut: /var/log/freeradius/radius_auth.log)
|
||||
-m, --min-mac <nombre> nombre minimal d'occurrences d'une mac sur une prise pour qu'elle soit reportée
|
||||
-n, --min-prise <nombre> nombre minimal d'erreurs sur une prise pour qu'elle soit reportée
|
||||
-l, --log <fichier> fichier de log à parser (par défaut: /var/log/freeradius/radius_auth.log)
|
||||
-m, --min-mac <nombre> nombre minimal d'occurrences d'une mac sur une prise pour qu'elle soit reportée
|
||||
-n, --min-prise <nombre> nombre minimal d'erreurs sur une prise pour qu'elle soit reportée
|
||||
-i, --inconnue n'affiche que les erreurs de mac inconnues
|
||||
-p, --prise n'affiche que les connexions sur une prise autre que celle du propriétaire
|
||||
-p, --prise n'affiche que les connexions sur une prise autre que celle du propriétaire
|
||||
-d, --date <date> ignorer totalement les lignes avant cette date
|
||||
|
||||
<date> peut être:
|
||||
<date> peut être:
|
||||
- une date absolue sous la forme AAAAMMJJ
|
||||
- une date relative à aujourd'hui sous la forme +<nombre de jour>
|
||||
Par exemple pour ne considérer que les deux dernier jours: +2
|
||||
- une date relative à aujourd'hui sous la forme +<nombre de jour>
|
||||
Par exemple pour ne considérer que les deux dernier jours: +2
|
||||
|
||||
Rapporter toutes anomalies à <dimino@crans.org>.""" % sys.argv[0].split('/')[-1].split('.')[0])
|
||||
Rapporter toutes anomalies à <dimino@crans.org>.""" % sys.argv[0].split('/')[-1].split('.')[0])
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
|
@ -288,7 +288,7 @@ if __name__ == '__main__':
|
|||
# Info que l'on veut afficher
|
||||
aff_inconnue = True
|
||||
aff_prise = True
|
||||
# Date de départ
|
||||
# Date de départ
|
||||
jour = None
|
||||
|
||||
import getopt, time
|
||||
|
@ -318,7 +318,7 @@ if __name__ == '__main__':
|
|||
try:
|
||||
jour = datetime.date(*(time.strptime(val, "%Y%m%d")[0:3]))
|
||||
except:
|
||||
__usage(u'La valeur du paramètre %s est incorecte (doit être de la forme AAAAMMJJ)' % opt)
|
||||
__usage(u'La valeur du paramètre %s est incorecte (doit être de la forme AAAAMMJJ)' % opt)
|
||||
else:
|
||||
cprint(u'Option inconnue: %s' % opt, 'rouge')
|
||||
__usage()
|
||||
|
@ -328,7 +328,7 @@ if __name__ == '__main__':
|
|||
errs_inconnue, errs_prise = parse_auth_log(fichier_log, jour)
|
||||
|
||||
if aff_inconnue:
|
||||
affiche_erreurs(errs_inconnue, u"Pour les connexions suivantes la mac n'a pas été trouvée dans la base:", min_mac, min_prise)
|
||||
affiche_erreurs(errs_inconnue, u"Pour les connexions suivantes la mac n'a pas été trouvée dans la base:", min_mac, min_prise)
|
||||
|
||||
if aff_prise:
|
||||
affiche_erreurs(errs_prise, u"Les connexions suivantes ont eu lieu sur une prise autre que celle du proriétaire:", min_mac, min_prise)
|
||||
affiche_erreurs(errs_prise, u"Les connexions suivantes ont eu lieu sur une prise autre que celle du proriétaire:", min_mac, min_prise)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- encoding: iso-8859-15 -*-
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Script d'envoi des statistiques des déconnections
|
||||
et du trafic de la journée à disconnect@
|
||||
Script d'envoi des statistiques des déconnections
|
||||
et du trafic de la journée à disconnect@
|
||||
|
||||
Copyright (C) Xavier Pessoles - Étienne Chové - Michel Blockelet
|
||||
Copyright (C) Xavier Pessoles - Étienne Chové - Michel Blockelet
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
|
@ -111,9 +111,9 @@ liste_upload = tableau(data = [ (l[1], l[2], ipv4or6(str(l[0])), socket.getfqdn(
|
|||
titre = ['upload', 'download', 'proto', 'machine'],
|
||||
largeur = [10, 10, 10, 40],
|
||||
format = ['o', 'o', 's', 's'],
|
||||
alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15')
|
||||
alignement = ['d', 'd', 'c', 'c']).encode('utf-8')
|
||||
|
||||
# Trafic exempté :
|
||||
# Trafic exempté :
|
||||
##################
|
||||
requete = """(SELECT ip_crans, sum(upload) AS somme, sum(download)
|
||||
FROM upload
|
||||
|
@ -149,7 +149,7 @@ liste_exemptes = tableau(data = [[l[1], l[2], ipv4or6(str(l[0])), socket.getfqdn
|
|||
titre = ['upload', 'download', 'proto', 'machine'],
|
||||
largeur = [10, 10, 10, 30],
|
||||
format = ['o', 'o', 's', 's'],
|
||||
alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15')
|
||||
alignement = ['d', 'd', 'c', 'c']).encode('utf-8')
|
||||
|
||||
# Upload des serveurs :
|
||||
#######################
|
||||
|
@ -170,7 +170,7 @@ liste_serveurs = tableau(data = liste_serveurs,
|
|||
titre = ['upload', 'download', 'proto', 'serveur'],
|
||||
largeur = [10, 10, 10, 30],
|
||||
format = ['o', 'o', 's', 's'],
|
||||
alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15')
|
||||
alignement = ['d', 'd', 'c', 'c']).encode('utf-8')
|
||||
|
||||
|
||||
# statistiques des gros uploads depuis les serveurs
|
||||
|
@ -178,7 +178,7 @@ liste_serveurs = tableau(data = liste_serveurs,
|
|||
# Liste des IP des serveurs
|
||||
gros_uploads_des_serveurs = stats(ip_crans=ips_serveurs,
|
||||
show=['ip_crans', 'ip_ext'], upload_mini=50,
|
||||
show_limit=100).encode('iso-8859-15')
|
||||
show_limit=100).encode('utf-8')
|
||||
|
||||
############################
|
||||
# Statistiques virus/p2p : #
|
||||
|
@ -206,10 +206,10 @@ liste_etherunk = tableau(data = [[l[0], socket.getfqdn(str(l[1]))]
|
|||
for l in curseur.fetchall()],
|
||||
titre = ['nombre','ip'],
|
||||
largeur = [10, 30],
|
||||
alignement = ['d','c']).encode('iso-8859-15')
|
||||
alignement = ['d','c']).encode('utf-8')
|
||||
|
||||
|
||||
# Machines actuellement déconnectées :
|
||||
# Machines actuellement déconnectées :
|
||||
######################################
|
||||
requete = "SELECT DISTINCT ip_crans FROM avertis_virus"
|
||||
curseur.execute(requete)
|
||||
|
@ -220,9 +220,9 @@ for IP in infections:
|
|||
liste_virus.append(["%s" % (str(hostname))])
|
||||
|
||||
liste_virus = tableau(liste_virus,
|
||||
titre=['machine'], largeur=[30]).encode('iso-8859-15')
|
||||
titre=['machine'], largeur=[30]).encode('utf-8')
|
||||
|
||||
# Machines ayant fait des attaques virus dans la journée :
|
||||
# Machines ayant fait des attaques virus dans la journée :
|
||||
##########################################################
|
||||
requete = """SELECT * FROM (SELECT ip_src,count(ip_src) as compteur FROM virus
|
||||
WHERE date > timestamp 'now' - interval '1 day'
|
||||
|
@ -237,10 +237,10 @@ for IP, compteur in curseur.fetchall():
|
|||
liste_virus2 = tableau(data = liste_virus2,
|
||||
titre = ['machine', 'nombre'],
|
||||
largeur = [30, 12],
|
||||
alignement = ['c', 'd']).encode('iso-8859-15')
|
||||
alignement = ['c', 'd']).encode('utf-8')
|
||||
|
||||
|
||||
# Machines ayant fait de attaques flood dans la journée :
|
||||
# Machines ayant fait de attaques flood dans la journée :
|
||||
#########################################################
|
||||
requete = """SELECT * FROM (SELECT ip_src,count(ip_src) as compteur FROM flood
|
||||
WHERE date > timestamp 'now' - interval '1 day'
|
||||
|
@ -255,7 +255,7 @@ for IP, compteur in curseur.fetchall():
|
|||
liste_virus3 = tableau(data = liste_virus3,
|
||||
titre = ['machine', 'nombre'],
|
||||
largeur = [30, 12],
|
||||
alignement = ['c', 'd']).encode('iso-8859-15')
|
||||
alignement = ['c', 'd']).encode('utf-8')
|
||||
|
||||
|
||||
#############
|
||||
|
@ -266,11 +266,11 @@ expediteur = "disconnect@crans.org"
|
|||
destinataire = "disconnect@crans.org"
|
||||
message = """From: %(From)s
|
||||
To: %(To)s
|
||||
Subject: Statistiques des =?iso-8859-1?Q?derni=E8res?= 24h
|
||||
Subject: Statistiques des =?utf-8?q?derni=C3=A8res?= 24h
|
||||
Message-Id: <%(uuid)s1@crans.org>
|
||||
Content-Type: text/plain; charset="iso-8859-15"
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
*Gros uploads des serveurs* (charybde et sable sont exemptés totalement)
|
||||
*Gros uploads des serveurs* (charybde et sable sont exemptés totalement)
|
||||
|
||||
%(gros_uploads_des_serveurs)s
|
||||
|
||||
|
@ -282,23 +282,23 @@ Content-Type: text/plain; charset="iso-8859-15"
|
|||
|
||||
%(liste_etherunk)s
|
||||
|
||||
*Machines actuellement déconnectées pour virus*
|
||||
*Machines actuellement déconnectées pour virus*
|
||||
|
||||
%(liste_virus)s
|
||||
|
||||
*Machines ayant commis des attaques virales dans la journée*
|
||||
*Machines ayant commis des attaques virales dans la journée*
|
||||
|
||||
%(liste_virus2)s
|
||||
|
||||
*Machines ayant commis des attaques virales de type flood dans la journée*
|
||||
*Machines ayant commis des attaques virales de type flood dans la journée*
|
||||
|
||||
%(liste_virus3)s
|
||||
|
||||
*Statistiques de trafic des adhérents* (tout le trafic)
|
||||
*Statistiques de trafic des adhérents* (tout le trafic)
|
||||
|
||||
%(liste_upload)s
|
||||
|
||||
*Statistiques de trafic des adhérents exemptés* (juste le trafic exempté)
|
||||
*Statistiques de trafic des adhérents exemptés* (juste le trafic exempté)
|
||||
|
||||
%(liste_exemptes)s
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
"""chambre_on_off.py: Affiche le statut, active ou désactive une prise
|
||||
# -*- coding: utf-8 -*-
|
||||
"""chambre_on_off.py: Affiche le statut, active ou désactive une prise
|
||||
|
||||
syntaxe : chambre-on-off.py chbre <cmd>
|
||||
chbre de la forme A101d
|
||||
<cmd> peut être :
|
||||
<cmd> peut être :
|
||||
- on : activer la prise
|
||||
- off : désactiver la prise
|
||||
- off : désactiver la prise
|
||||
- absent : affiche le statut de la prise
|
||||
|
||||
"""
|
||||
|
@ -17,10 +17,10 @@ sys.path.append("/usr/scripts/gestion/")
|
|||
import hptools
|
||||
|
||||
def chambre_on_off(chambre, cmd = None):
|
||||
"""Active ou désactive une prise
|
||||
"""Active ou désactive une prise
|
||||
|
||||
chambre: numéro de chambre
|
||||
cmd: si fourni, "on" ou "off" pour activer ou désactiver la prise
|
||||
chambre: numéro de chambre
|
||||
cmd: si fourni, "on" ou "off" pour activer ou désactiver la prise
|
||||
si cmd n'est pas fourni, ne fait qu'afficher le statut de la prise
|
||||
"""
|
||||
# connexion au switch
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue