deb 9
[freeside.git] / bin / bind.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. "/bind";
18 mkdir $spooldir, 0700 unless -d $spooldir;
19
20 my @exports = qsearch('part_export', { 'exporttype' => 'bind' } );
21 my @sexports = qsearch('part_export', { 'exporttype' => 'bind_slave' } );
22
23 my $rsync = File::Rsync->new({
24   rsh     => 'ssh',
25 #  dry_run => 1,
26 });
27
28 foreach my $export ( @exports ) {
29
30   my $machine = $export->machine;
31   my $prefix = "$spooldir/$machine";
32
33   my $bind_rel = $export->option('bind_release');
34   my $ndc_cmd = $export->option('reload')
35                 || ( ($bind_rel eq 'BIND9') ? 'rndc' : 'ndc' );
36   my $minttl = $export->option('bind9_minttl');
37
38   #prevent old domain files from piling up
39   #rmtree "$prefix" or die "can't rmtree $prefix.db: $!";
40
41   mkdir $prefix, 0700 unless -d $prefix;
42
43   open(NAMED_CONF,">$prefix/named.conf")
44     or die "can't open $prefix/named.conf: $!";
45
46   if ( -e "$prefix/named.conf.HEADER" ) {
47     open(CONF_HEADER,"<$prefix/named.conf.HEADER")
48       or die "can't open $prefix/named.conf.HEADER: $!";
49     while (<CONF_HEADER>) { print NAMED_CONF $_; }
50     close CONF_HEADER;
51   }
52
53   my $zonepath = $export->option('zonepath');
54   $zonepath =~ s/\/$//;
55
56   my @svc_domain = $export->svc_x;
57
58   foreach my $svc_domain ( @svc_domain ) {
59     my $domain = $svc_domain->domain;
60     my @masters = qsearch('domain_record', {
61       'svcnum' => $svc_domain->svcnum,
62       'rectype' => '_mstr',
63     } );
64     if ( @masters ) {
65       my $masters = join('; ', map { $_->recdata } @masters );
66
67       print NAMED_CONF <<END;
68 zone "$domain" {
69         type slave;
70         file "db.$domain";
71         masters { $masters; };
72 };
73
74 END
75       unlink "$prefix/db.$domain" if -e "$prefix/db.$domain";
76
77     } else {
78
79       print NAMED_CONF <<END;
80 zone "$domain" {
81         type master;
82         file "$zonepath/db.$domain";
83 };
84
85 END
86
87       open (DB_MASTER,">$prefix/db.$domain")
88         or die "can't open $prefix/db.$domain: $!";
89
90       if ($bind_rel eq 'BIND9') {
91         print DB_MASTER "\$TTL $minttl\n\$ORIGIN $domain.\n";
92       }
93
94       my @domain_records =
95         qsearch('domain_record', { 'svcnum' => $svc_domain->svcnum } );
96       foreach my $domain_record (
97         sort { $b->rectype cmp $a->rectype } @domain_records
98       ) {
99         #if ( $domain_record->rectype eq 'SOA' ) {
100         #  print DB_MASTER join("\t", $domain_record-> reczone
101         #} else {
102           print DB_MASTER join("\t",
103             map { $domain_record->getfield($_) }
104               qw( reczone recaf rectype recdata )
105           ), "\n";
106         #}
107       }
108
109       close DB_MASTER;
110
111     }
112
113   }
114
115   $rsync->exec( {
116     src       => "$prefix/",
117     recursive => 1,
118     dest      => "root\@$machine:$zonepath/",
119     exclude   => [qw( *.import named.conf.HEADER named.conf )],
120   } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
121  # warn $rsync->out;
122
123   $rsync->exec( {
124     src     => "$prefix/named.conf",
125     dest    => "root\@$machine:". $export->option('named_conf'),
126   } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
127 #  warn $rsync->out;
128
129   ssh("root\@$machine", "$ndc_cmd reload");
130
131 }
132
133 close NAMED_CONF;
134
135 foreach my $sexport ( @sexports ) { #false laziness with above
136
137   my $machine = $sexport->machine;
138   my $prefix = "$spooldir/$machine";
139
140   my $bind_rel = $sexport->option('bind_release');
141   my $ndc_cmd = ($bind_rel eq 'BIND9') ? 'rndc' : 'ndc';
142
143   #prevent old domain files from piling up
144   #rmtree "$prefix" or die "can't rmtree $prefix.db: $!";
145
146   mkdir $prefix, 0700 unless -d $prefix;
147
148   open(NAMED_CONF,">$prefix/named.conf")
149     or die "can't open $prefix/named.conf: $!";
150
151   if ( -e "$prefix/named.conf.HEADER" ) {
152     open(CONF_HEADER,"<$prefix/named.conf.HEADER")
153       or die "can't open $prefix/named.conf.HEADER: $!";
154     while (<CONF_HEADER>) { print NAMED_CONF $_; }
155     close CONF_HEADER;
156   }
157
158   my $masters = $sexport->option('master');
159
160   #false laziness with  freeside-sqlradius-reset 
161   my @svc_domain =
162     map { qsearchs('svc_domain', { 'svcnum' => $_->svcnum } ) }
163       map { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
164         grep { qsearch('cust_svc', { 'svcpart' => $_->svcpart } ) }
165           $sexport->export_svc;
166
167   foreach my $svc_domain ( @svc_domain ) {
168     my $domain = $svc_domain->domain;
169     print NAMED_CONF <<END;
170 zone "$domain" {
171         type slave;
172         file "db.$domain";
173         masters { $masters; };
174 };
175
176 END
177
178   }
179
180   $rsync->exec( {
181     src     => "$prefix/named.conf",
182     dest    => "root\@$machine:". $sexport->option('named_conf'),
183   } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err);
184 #  warn $rsync->out;
185
186   ssh("root\@$machine", "$ndc_cmd reload");
187
188 }
189 close NAMED_CONF;
190
191 # -----
192
193 sub usage {
194   die "Usage:\n  bind.export user\n"; 
195 }
196