[OBM] : dev cookbook

Pascal salaun pascal.salaun at mclabosse.fr
Sun Oct 18 16:23:26 CEST 2009


Bonjour tout le monde,

après quelques jours de fainéantise (je voulais par taper sur mon 
clavier) :-)

voici la dernière mouture du fichier de stats pour obm (cf pj), enfin d'un

Les modifs apportées sont :

- on oublie la connexion au SGBD (=> plus besoin de savoir si c'est du 
My. ou du Posgres.) pour une connexion vers Cyrus (à moins qu'un admin  
Sécu ait décidé de bloquer la connexion imap entre Postfix et Cyrus).
- le wildcard fait maintenant référence au domaine et à son alias s'il 
existe. On aura ainsi des scripts intitulé, par exemple, 
obm-ms_nb_from_toto.com:toto.bzh
- possibilité de choisir entre le nom du domaine (par defaut) ou de 
l'alias à afficher dans le graphe,


Ainsi, pour une automatisation des scripts,on aurait par exemple quelque 
chose du style :

# cp obm-ms_nb_from_ obm-ms_nb_from_toto.com:toto.bzh   
# sed -i  's/_imap_srv_/127\.0\.0\.1/' obm-ms_nb_from_toto.com:toto.bzh
# sed -i  's/_imap_adm_/cyrus/' obm-ms_nb_from_toto.com:toto.bzh
# sed -i  's/_imap_adm_pwd_/cyrus/' obm-ms_nb_from_toto.com:toto.bzh
etc ...

Il reste :
- le cas des machines maitres:esclaves  où une copie du nouveau script 
doit être déposée.
- comment on active les stats (dès la création du domaine, à la demande...)

Enfin, encore du boulot en perspective.


Pascal

Pierre Baudracco a écrit :
>
>
>> Pour le point 2, avant de se connecter à la BD il faut savoir ce que 
>> l'on a besion. D'après ce que j'ai pu voir on a besion de connaitre 
>> les domaines existant pour pouvoir stater by domaine. Une piste qui 
>> est interressante serait d'utiliser obm-locator ou obm-satellite (ces 
>> services sont disponible en 2.3 seulement)
>> Je propose donc deux architecture qui vont fonctionner différement:
>>  * obm-locator:
>> obm-locator est un nouveau service pour obm 2.3 qui permet de 
>> localiser un service enregistre dans OBM. Il est automatiquement 
>> déployé ou se trouve la BD. c'est un web-service qui sera toujours 
>> installé en https (l'admin-sys sera déja plus content).
>> Actuellement il permet seulement de savoir quel est le serveur 
>> obm-sync associé a un utilisateur, on lui donne un login, il renvoi 
>> une ip.
>> Il pourrait être enrichi afin de pouvoir retourner la liste des 
>> domaines
>
> obm-locator ne me semble pas trop adapte pour sortir la liste des 
> domaines
>
>
>> *obm-satellite:
>> obm-satellite a été complètemen,t réécrit en 2.3, c'est 
>> mainteant lui aussi un web service qui peut-être étendu facilement. 
>> Là on ne fonctionne plus de la même façon qu'avec le locator. Avec 
>> obm-satellite, on l'install là ou en a besoin. Il est extensible via 
>> module. Le but serait donc de configurer les script munin via 
>> obm-satellite sur odre de l'interface OBM. Ainsi on a l'avantage de 
>> ne pas requeter sur un serveur distant a chaque appel des scripts 
>> munin. Lors de l'ajout d'un host smtp dans l'interface web, celle-ci 
>> fait une requete sur le web service obm-satellite en lui envoyant les 
>> informations necessaire pour se configurer, de son coter 
>> obm-satellite via son module 'muni-postfix' s'occupe de générer la 
>> con des scripts munin.
>>
>> PS: c'est quoi une version MIOCT ??
>
> MIOCT = ministere de l'interieur
>
>
>

-------------- next part --------------
#!/usr/bin/perl
=head1 DATE
Version 0.1   : 2009/08/24 21:55
Version 0.1.1 : 2009/08/25 09:45
Version 0.1.2 : 2009/08/29 09:45
Version 0.1.3 : 2009/10/18 15:35

=head1 AUTHOR
Pascal Salaun
pascal.salaun at laposte.net

=head1 LICENSE
GPLv3

=head1 NAME
Don't know at this time ;-)

=head1 APPLICABLE SYSTEMS

Postfix mail server

=head1 WHATS'S NEW
Ce script ne prend plus en compte le SGDB OBM.
Il se base sur les comptes cyrus.
Par ailleurs, le wildcard est modifié de la facon suivante :
	obm-ms_nb_from_[nom_du_domaine]:[alias_du_domaine]
	par exemple : obm-ms_nb_from_toto.com:toto.bzh	


=head1 CONFIGURATION

Ce script est adapté pour OBM
Il utilise le principe du wildcard.

Renseigner les variables $log_file et $limit et $script_name.
$log_file    = chemin vers le fichier de log postfix (mail.log)
$limit       = par défaut 5, définit les x dernières minutes du fichier de log à prendre en compte
	       A modifier en fonction de ce qui est positionné dans la crontab de munin
$script_name = nom du fichier finissant par un "_" (underscore) 
$def_name    = correspond au domaine ou a son alias devant etre affiche sur le graphe
	       valeur = 1 pour le domaine 
	       valeur = 2 pour l'alias


=head1 wilcard howto

le fichier "/etc/munin/plugin-conf.d/munin-node" doit être du style :
[obm-ms_nb_from_*]
user root
timeout 60

=head1 MAGIC MARKERS

	#%# family=auto
     	#%# capabilities=autoconf 
   
=cut




use strict;
use Cyrus::IMAP::Admin; 


#################################
#
# Definition des variables 
#
#################################

my $log_file = "/var/log/mail.log";
my $limit = 5; #ne prend en compte dans le fichier de log que les $limit dernieres minutes
my $script_name = "obm-ms_nb_from_";


# OBM Variables
#our $imap_srv = '_imap_srv_';
#our $imap_adm = '_imap_adm_' ;
#our $imap_adm_pwd = '_imap_adm_pwd_' ;

our $imap_srv = '127.0.0.1';
our $imap_adm = 'cyrus' ;
our $imap_adm_pwd = 'cyrus' ;

our %compte_imap = undef;


#Affichage par defaut du nom du domaine (1) ou de son alias (2) 
#dans le graphe de munin
my $def_name = '1';


# Do not modify after
#

my %pstfx_local_id = undef;
my %message_id = undef;
my @presence = undef ;
my %from_by_domain = undef ;
my %domain_id =  undef ;
my $domainid =  undef ;
our %domname = undef ;
my $clause_where = undef;
our %compte_imap = undef;



#######################################
# Controle  

if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) {
    if (!$?) {
	if (-f $log_file) {
            if (-r "$log_file") {
                print "yes\n";
                exit 0;
            } else {
                print "no (logfile '$log_file' not readable)\n";
            }
	} else {
	    print "no (logfile '$log_file' not found)\n";
	}
    } else {
	print "no (postfix not found)\n";
    }

    exit 1;
}


#######################################
# Importation des comptes depuis Cyrus

my $imap = Cyrus::IMAP::Admin->new("$imap_srv", 143); 


   $imap->authenticate(
           -user     => "$imap_adm",
           -mechanism => "LOGIN",
           -password => "$imap_adm_pwd",
           );

  my @list = $imap->list("*");
  my $nb = @list;
  for(my $count=0; $count < $nb;$count++)
  {

        if ( $list[$count][0] =~ m%user/([a-z0-9.-]+@[a-z0-9.-]+\.[a-z]{2,6}$)% )
        {
        my $intra = $1;
        $intra =~ s/\@/\\@/ ;
        print "$intra \n";
	$compte_imap{$intra} = "ok" ;
        };
  }; 
  
  
  
#######################################
# Initialisation des domaines 

# Case of External Domain
$domain_id{'Externe'} = 0;
$domname{0} = "Externe";
push @{$from_by_domain{0}{'nb'}},0;


# Domain name and alias name if exists
if ($0 =~ m/$script_name(\S+):(\S*)$/)
{
	my $domain = $1;
		$domname{1} = "$domain";
		$domain_id{'$domain'} = 1;
		push @{$from_by_domain{1}{'nb'}},0;
	if( $2 =~ m/\S+/)
	{
		my $alias  = $2;
		$domname{2} = "$alias";
		$domain_id{'$alias'} = 1;
	};
	
};



#######################################
# Initialisation des entetes "munin"


if ( defined $ARGV[0] and $ARGV[0] eq "config" )
{
        print "graph_title Nb de msg Emis par domaines\n";
        print "graph_args --base 1000 -l 0\n";
        print "graph_vlabel Nombre\n";
	print "graph_scale yes\n";
	print "graph_period second\n";
	print "graph_category Messagerie\n";

	print "domain0.label Externe\n";
	print "domain0.type GAUGE\n";
	
	print "domain1.label ".$domname{$def_name}."\n";
	print "domain1.type GAUGE\n";
		
	exit 0;
};




#######################################
#
# Debut du job
#
#######################################


#
# Controle de date
#


sub time_limit
{
	my @dbt = undef;
	my $x = $_[0] - 1;
	for (my $i=$x; $i>=0; $i--) 
	{
	my $dudul = time - ($i*60);
	my ($secondes, $minutes, $heures, $jour_mois, $mois,
	    $an, $jour_semaine, $jour_calendaire, $heure_ete) = localtime($dudul);

	$an +=1900;
	$mois+=1;
	$jour_calendaire+=1;
	$mois = $mois < 10 ? $mois = "0".$mois : $mois;
	$jour_mois = $jour_mois < 10 ? $jour_mois = "0".$jour_mois : $jour_mois;
	$heures = $heures < 10 ? $heures = "0".$heures : $heures;
	$minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
	my @noms_de_mois = ("","Jan","Feb","Mar","Apr","May","Jun",
	           "Jul","Aug","Sep","Oct","Nov","Dec");

		push(@dbt,"$noms_de_mois[$mois] $jour_mois $heures:$minutes");
	};
	my $trash = shift(@dbt);
	return join "|", at dbt;
};



sub from_this_imap_srv
{
	my $case1 = undef;
	my $case2 = undef;


	my $user = $_[0];

	if($user =~ m/(.*)@(.*)/ )
	{
		$case1 = $1."\\@".$domname{1};
		if($domname{2})
		{
		$case2 = $1."\\@".$domname{2};	
		};
	};		


	if ( $compte_imap{$case1} eq "ok" || $compte_imap{$case2} eq "ok" )
	{
		return 1 ;
	};
	
};



#
# Parse du LogFile
#


open(F, $log_file) || die "Error while opening : $!";
my $liste_dbt = &time_limit($limit);
#print "$liste_dbt\n" ;

while(<F>)
{
	  chomp();

	  #List of postfix_id while internal treatment (antivirus/antispam)	
	  #Aug 22 15:38:15 galadriel postfix/smtpd[29211]: 7E83C9E4318: client=localhost[127.0.0.1]
	  #              1      2      3         4          5       6   
	  if ( $_ =~ m%(.*)(:\d{2}\s)(.*)(postfix/smtpd)\[(\d+)\]: (.*): client=(unknown|localhost)\[127\.0\.0\.1\]% )
	  {
		
		$pstfx_local_id{$6} = $6;

	  };

         #List of message_id 
	 #Aug 22 20:09:21 galadriel postfix/cleanup[11415]: 6C54B9E433D: message-id=<20090822200921.9q4fg64u0wg4swkw at mail.mclabosse.fr>
	 #             1          2            3       4                 5 
	 if ( $_ =~ m%(.*)(postfix/cleanup)\[(\d+)\]: (.*): message-id=<(.*)>% )
	 {
	 	# want to keep only one "from" line per message.
	 	# the same message_id can be found twice 
	 	if(grep(/$5/,%message_id))
		{
			delete $message_id{$5};
			delete $pstfx_local_id{$4};
		}
		else
		{
	 		$message_id{$5} = $5;
			$pstfx_local_id{$4} = $4;
		};
	 };
	 
	  	

	  if($_ =~ m%^($liste_dbt)%) {
					#print "$_ \n";
	  } 
	  else {next;}
	  
	 
	 # Case of originators and volume/mail
	 # Aug 22 15:38:15 galadriel postfix/qmgr[4158]: 7E83C9E4318: from=<pascal.salaun at laposte.net>, size=1767, nrcpt=1 (queue active)
	 #              1        2          3      4            5             7    
	 if ( $_ =~ m%(.*)(postfix/.*)\[(\d+)\]: (.*): from=<(.*@.*)>, size=(\d+).*% )
	 {
	 	@presence = grep(/$4/,%pstfx_local_id);
		if(@presence) 	
		{
		

			if (&from_this_imap_srv($5) == 1 )
			{
				$domainid = "1";
			}
			else 
			{ 
				$domainid = "0" ;
			};
		
			push @{$from_by_domain{$domainid}{'nb'}},1;
			
		};
	 };
  
};
close F || die "Error while closing : $!";

# Affichage des donnees pour Munin
# Volume (in byte) sent by domain
# domain_id "0" == out of obm_domain 
	
	my $res0 = eval ( join "+",@{$from_by_domain{0}{'nb'}});
	my $res1 = eval ( join "+",@{$from_by_domain{1}{'nb'}});
	
	print "domain0.value $res0\n";
	print "domain1.value $res1\n";





More information about the Obm mailing list