handle missing customer records without erroring out
[freeside.git] / bin / postfix.export
1 #!/usr/bin/perl -w
2
3 use strict;
4 #use File::Path;
5 use File::Rsync;
6 use Net::SSH qw(ssh);
7 use FS::UID qw(adminsuidsetup datasrc);
8 use FS::Record qw(qsearch); # qsearchs);
9 use FS::part_export;
10 #use FS::cust_pkg;
11 use FS::cust_svc;
12 #use FS::svc_domain;
13
14 my $user = shift or die &usage;
15 adminsuidsetup $user;
16
17 my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/postfix";
18 mkdir $spooldir, 0700 unless -d $spooldir;
19
20 my @exports = qsearch('part_export', { 'exporttype' => 'postfix' } );
21
22 my $rsync = File::Rsync->new({
23   rsh     => 'ssh',
24 #  dry_run => 1,
25 });
26
27 foreach my $export ( @exports ) {
28
29   my $machine = $export->machine;
30   my $prefix = "$spooldir/$machine";
31   mkdir $prefix, 0700 unless -d $prefix;
32
33   #construct %domain hash
34
35   my $mydomain = $export->option('mydomain');
36   my %domain;
37   foreach my $svc_forward ( $export->svc_x ) {
38
39     my( $username, $domain );
40     my $srcsvc_acct = $svc_forward->srcsvc_acct;
41     if ( $srcsvc_acct ) {
42       ( $username, $domain ) = ( $srcsvc_acct->username, $srcsvc_acct->domain );
43     } elsif ( $svc_forward->src =~ /([^@]*)\@([^@]+)$/ ) {
44       ( $username, $domain ) = ( $1, $2 );
45     } else {
46       die "bad svc_forward record?  svcnum ". $svc_forward->svcnum. "\n";
47     }
48
49     my( $dusername, $ddomain );
50     my $dstsvc_acct = $svc_forward->dstsvc_acct;
51     if ( $dstsvc_acct ) {
52       $dusername = $dstsvc_acct->username;
53       $ddomain = $dstsvc_acct->domain;
54     } elsif ( $svc_forward->dst =~ /([^@]+)\@([^@]+)$/ ) {
55       ( $dusername, $ddomain ) = ( $1, $2 );
56     } else {
57       die "bad svc_forward record?  svcnum ". $svc_forward->svcnum. "\n";
58     }
59     my $dest;
60     if ( $ddomain eq $mydomain ) {
61       $dest = $dusername;
62     } else {
63       $dest = "$dusername\@$ddomain";
64     }
65
66     push @{$domain{$domain}{$username}}, $dest;
67
68   }
69
70   #write aliases
71
72   my $aliases = delete $domain{$mydomain};
73   open(ALIASES, ">$prefix/aliases") or die "can't open $prefix/aliases: $!";
74   foreach my $alias ( keys %$aliases ) {
75     print ALIASES "$alias: ". join(',', @{ $aliases->{$alias} } ). "\n";
76   }
77   close ALIASES;
78
79   #write virtual
80
81   open(VIRTUAL, ">$prefix/virtual") or die "can't open $prefix/virtual: $!";
82   foreach my $domain ( keys %domain ) {
83     print VIRTUAL "$domain DOMAIN\n";
84     #foreach my $virtual ( sort { $a ne '' <=> $b ne '' } keys %{$domain{$domain}} ) {
85     foreach my $virtual ( sort { ( ($b ne '') <=> ($a ne '') ) || $a cmp $b } keys %{$domain{$domain}} ) {
86       print VIRTUAL "$virtual\@$domain ".
87                     join(',', @{ $domain{$domain}{$virtual} } ). "\n";
88     }
89     print VIRTUAL "\n";
90   }
91   close VIRTUAL;
92
93   #rsync
94
95   my $user = $export->option('user');
96   $rsync->exec( {
97     src     => "$prefix/aliases",
98     dest    => "$user\@$machine:". $export->option('aliases'),
99   } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
100 #  warn $rsync->out;
101
102   ssh("$user\@$machine", "newaliases");
103 #  ssh("$user\@$machine", "postfix reload");
104
105   $rsync->exec( {
106     src     => "$prefix/virtual",
107     dest    => "$user\@$machine:". $export->option('virtual'),
108   } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
109 #  warn $rsync->out;
110   ssh("$user\@$machine", "postmap hash:/etc/postfix/virtual");
111   ssh("$user\@$machine", "postfix reload");
112
113 }
114
115 # -----
116
117 sub usage {
118   die "Usage:\n  postfix.export user\n"; 
119 }
120
121