Florent Peterschmitt

Check Delivery - SMTP, IMAP, IRC, FTP…

Initialement, je voulais vérifier que je ne m’étais pas gouré dans la configuration de mon serveur mail, et automatiser la vérification de l’envoi/réception interne/externe.

Ça existe déjà, ça s’appelle check_mail_delivery et ça propose sans doute plus de fonctionnalités que ce que j’ai à proposer. Et pour certains mordus de Perl, c’est écrit en Perl ;-)

Néanmoins, comme je suis pas fan de Perl, ni de ce programme, j’en suis venu à coder un petit chéri, en Python 3, sous license MIT : Check Delivery

Check Delivery

Le mail c’est une chose, mais je me suis dit que ça serait sympa de proposer d’autres choses. Au final, le but du jeu, c’est de s’assurer qu’une chaîne délivrant, peu importe le moyen, des messages, fonctionne : FTP, IRC, des fichiers…

Pour fonctionner, on lui précise un sender et un receiver, sous forme d’une URL (voir exemples), ou bien un fichier de conf.

Selon comme le sender et receiver est codé, le receiver sera connecté (ou disponible) avant que le sender ne commence à bosser, ce qui dans le cas de SMTP/IMAP est inutile, mais dans le cas d’IRC, est obligatoire.

Si à l’avenir on prenait XMPP par exemple, il faudrait avoir les deux modes : livraison du message après connexion de l’utilisateur, et livraison en direct.

Le format de sortie est configurable et on peut coder son propre format.

Fonctionnalités

Pour l’instant, voici ce qui est disponible :

  • smtp, smtps, smtp + starttls, en envoi uniquement
  • imap, imaps, imap + starttls, en réception uniquement
  • irc, irc + tls, deux modes
  • ftp, ftps, deux modes
  • file (en local), deux modes
  • sorties Nagios et JSON
  • fichier de configuration

Exemple

[creds]
user = user%40peterschmitt.fr:password

[senders]
smtp = smtpstarttls://${creds:user}@peterschmitt.fr:587

[receivers]
imap = imapstarttls://${creds:user}@peterschmitt.fr:143

[scenarios]
smtp.to.imap.send = ${senders:smtp}
smtp.to.imap.recv = ${receivers:imap}
$ check_delivery --conf config.ini --play smtp.to.imap --wait 3
$ OK - Token found in message b'1'
$ echo $?
0

Le sender nommé arbitrairement smtp va envoyer un token, une somme SHA512, et si tout se passe bien, on devrait récupérer ce message via notre serveur IMAP, configuré dans le receiver arbitrairement nommé imap.

L’option --wait fait attendre la vérification trois secondes après que le sender ai terminé son travail.

Le nom des sections est au choix, sauf scenarios, de même que le nom des clefs, on fait sa vie comme on veut.

Installation

Pas encore d’enregistrement sur pypi, donc on passera par une installation par le dépôts GitHub.

# From local clone
pip install -e .
pip install -e .[irc] # with IRC delivery

# Or from GitHub
pip install -e "git+https://github.com/Leryan/check_delivery.git#egg=check_delivery"
pip install -e "git+https://github.com/Leryan/check_delivery.git#egg=check_delivery[irc]"

Il vous faudra Python 3.2 minimum.

Sécurité

Pour les modes avec chiffrement, on pourra utiliser, dans l’URL, le paramètre ssl_verify.

Par défaut, un certificat reconnu est demandé.

Évolutivité

En prenant exemple sur le file delivery, combiné avec le point d’entrée du programme de référence check_delivery, on peut obtenir assez facilement ce qu’on souhaite.

Il suffira de passer un dictionnaire classmap à cette fonction, l’exécuter et retourner le code de retour en sortie de script, et c’est fini.

#!/usr/bin/env python

import sys

import check_delivery

from check_delivery import Method

class MMBase(Method):

    def connect(self):
        ...

class MMSend(MMBase):

    def send(self, message):
        ...

class MMRecv(MMBase):

    def recv(self, message):
        ...

def mycd():
    classmap = {
        "__methods": {
            "mamethode": {
                "send": MMSend,
                "recv": MMRecv
            }
        }
    }

    return check_delivery.check_delivery(custom_classmap=classmap)

if __name__ == '__main__':
    sys.exit(mycd())

À noter que l’utilisation de deux classes distinctes pour l’envoi et la réception n’est pas nécessaire, il suffira d’implémenter send() et recv(), qui recevront en paramètre le token à envoyer / recevoir.

Évolutions

  • Pouvoir configurer des retry, configurables bien entendu.

  • Si possible coder une gestion évènementielle de la réception du token, ce qui permettrait de demander un timeout sur la réception du token, mais également de fournir une information de performance.

  • Dans le cas où l’évènementiel n’est pas possible, une configuration de l’interval entre deux essais, et un nombre d’essais maximum.

  • Pouvoir lancer le test sur plusieurs receivers. Dans le cas du mail ça serait IMAP et POP3 par exemple.

  • Proposer un mode évènementiel pour ce qui peut l’être, comme ZeroMQ par exemple.

  • Paramétrer la connexion des receivers : avant ou après le sender ?

Comments