Critical Path provisioning has been updated and can now username changes
and suspension/unsuspension.
---
-
- New export code!
- Name and company searches:
- now case-insensative
--
+complete bind import and export and edit of dns zone files
+
package FS::domain_record;
use strict;
-use vars qw( @ISA );
+use vars qw( @ISA $noserial_hack );
#use FS::Record qw( qsearch qsearchs );
use FS::Record qw( qsearchs dbh );
use FS::svc_domain;
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
+ if ( $self->rectype eq '_mstr' ) { #delete all other records
+ foreach my $domain_record ( reverse $self->svc_domain->domain_record ) {
+ my $error = $domain_record->delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+ }
+
my $error = $self->SUPER::insert;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
=cut
sub increment_serial {
+ return '' if $noserial_hack;
my $self = shift;
my $soa = qsearchs('domain_record', {
$new->replace($soa);
}
+=item svc_domain
+
+Returns the domain (see L<FS::svc_domain) for this record.
+
+=cut
+
+sub svc_domain {
+ my $self = shift;
+ qsearchs('svc_domain', { svcnum => $self->svcnum } );
+}
+
=back
=head1 VERSION
-$Id: domain_record.pm,v 1.8 2002-05-22 18:44:01 ivan Exp $
+$Id: domain_record.pm,v 1.9 2002-05-23 13:00:08 ivan Exp $
=head1 BUGS
--- /dev/null
+#!/usr/bin/perl -w
+#
+# $Id: bind.import,v 1.1 2002-05-23 13:00:08 ivan Exp $
+
+#need to manually put header in /usr/local/etc/freeside/export.<datasrc./bind/<machine>/named.conf.HEADER
+
+use strict;
+use vars qw( %d_part_svc );
+use Term::Query qw(query);
+#use BIND::Conf_Parser;
+#use DNS::ZoneParse;
+
+#use Net::SCP qw(iscp);
+use Net::SCP qw(scp);
+use FS::UID qw(adminsuidsetup datasrc);
+use FS::Record qw(qsearch); #qsearchs);
+#use FS::svc_acct_sm;
+use FS::svc_domain;
+use FS::domain_record;
+#use FS::svc_acct;
+#use FS::part_svc;
+
+my $user = shift or die &usage;
+adminsuidsetup $user;
+
+$FS::domain_record::noserial_hack = 1;
+
+use vars qw($spooldir);
+$spooldir = "/usr/local/etc/freeside/export.". datasrc. "/bind";
+mkdir $spooldir unless -d $spooldir;
+
+%d_part_svc =
+ map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_domain'});
+
+print "\n\n",
+ ( join "\n", map "$_: ".$d_part_svc{$_}->svc, sort keys %d_part_svc ),
+ "\n\n";
+use vars qw($domain_svcpart);
+$^W=0; #Term::Query isn't -w-safe
+$domain_svcpart =
+ query "Enter part number for domains: ", 'irk', [ keys %d_part_svc ];
+$^W=1;
+
+print "\n\n", <<END;
+Enter the location and name of your primary named.conf file, for example
+"ns.isp.com:/var/named/named.conf"
+END
+my($named_conf)=&getvalue(":");
+
+use vars qw($named_machine $prefix);
+$named_machine = (split(/:/, $named_conf))[0];
+$prefix = "$spooldir/$named_machine";
+mkdir $prefix unless -d $prefix;
+
+#iscp("root\@$named_conf","$prefix/named.conf.import");
+scp("root\@$named_conf","$prefix/named.conf.import");
+
+
+sub getvalue {
+ my $prompt = shift;
+ $^W=0; # Term::Query isn't -w-safe
+ my $return = query $prompt, '';
+ $^W=1;
+ $return;
+}
+
+print "\n\n";
+
+##
+
+$FS::svc_domain::whois_hack=1;
+
+my $p = Parser->new;
+$p->parse_file("$prefix/named.conf.import");
+
+print "\nBIND import completed.\n";
+
+##
+
+sub usage {
+ die "Usage:\n\n svc_domain.import user\n";
+}
+
+########
+BEGIN {
+
+ package Parser;
+ use BIND::Conf_Parser;
+ use vars qw(@ISA $named_dir);
+ @ISA = qw(BIND::Conf_Parser);
+
+ sub handle_option {
+ my($self, $option, $argument) = @_;
+ return unless $option eq "directory";
+ $named_dir = $argument;
+ }
+
+ sub handle_zone {
+ my($self, $name, $class, $type, $options) = @_;
+ return unless $class eq 'in';
+ return if grep { $name eq $_ }
+ ( qw( . localhost 127.in-addr.arpa 0.in-addr.arpa 255.in-addr.arpa ) );
+
+ my $domain = new FS::svc_domain( {
+ svcpart => $main::domain_svcpart,
+ domain => $name,
+ action => 'N',
+ } );
+ my $error = $domain->insert;
+ die $error if $error;
+
+ if ( $type eq 'slave' ) {
+
+ #use Data::Dumper;
+ #print Dumper($options);
+ #exit;
+
+ foreach my $master ( @{ $options->{masters} } ) {
+ my $domain_record = new FS::domain_record( {
+ 'svcnum' => $domain->svcnum,
+ 'reczone' => '@',
+ 'recaf' => 'IN',
+ 'rectype' => '_mstr',
+ 'recdata' => $master,
+ } );
+ my $error = $domain_record->insert;
+ die $error if $error;
+ }
+
+ } elsif ( $type eq 'master' ) {
+
+ my $file = $options->{file};
+
+ use File::Basename;
+ my $basefile = basename($file);
+ my $sourcefile = $file;
+ $sourcefile = "$named_dir/$sourcefile" unless $file =~ /^\//;
+ use Net::SCP qw(iscp scp);
+ scp("root\@$main::named_machine:$sourcefile",
+ "$main::prefix/$basefile.import");
+
+ use DNS::ZoneParse;
+ my $zone = DNS::ZoneParse->new("$main::prefix/$basefile.import");
+
+ my $dump = $zone->Dump;
+
+ #use Data::Dumper;
+ #print "$name: ". Dumper($dump);
+ #exit;
+
+ foreach my $rectype ( keys %$dump ) {
+ if ( $rectype =~ /^SOA$/i ) {
+ my $rec = $dump->{$rectype};
+ my $domain_record = new FS::domain_record( {
+ 'svcnum' => $domain->svcnum,
+ 'reczone' => $rec->{origin},
+ 'recaf' => 'IN',
+ 'rectype' => $rectype,
+ 'recdata' =>
+ $rec->{primary}. ' '. $rec->{email}. ' ( '.
+ join(' ', map $rec->{$_},
+ qw( serial refresh retry expire minimumTTL ) ).
+ ' )',
+ } );
+ my $error = $domain_record->insert;
+ die $error if $error;
+ } else {
+ #die $dump->{$rectype};
+ foreach my $rec ( @{ $dump->{$rectype} } ) {
+ my $domain_record = new FS::domain_record( {
+ 'svcnum' => $domain->svcnum,
+ 'reczone' => $rec->{name},
+ 'recaf' => $rec->{class},
+ 'rectype' => $rectype,
+ 'recdata' => ( $rectype =~ /^MX$/i
+ ? $rec->{priority}. ' '. $rec->{host}
+ : $rec->{host} ),
+ } );
+ my $error = $domain_record->insert;
+ die $error if $error;
+ }
+ }
+ }
+
+ }
+
+ }
+
+}
+#########
+
+++ /dev/null
-#!/usr/bin/perl -w
-#
-# $Id: svc_domain.import,v 1.6 2002-05-20 11:02:47 ivan Exp $
-
-#need to manually put header in /usr/local/etc/freeside/export.<datasrc./bind/<machine>/named.conf.HEADER
-
-use strict;
-use vars qw( %d_part_svc );
-use Term::Query qw(query);
-#use BIND::Conf_Parser;
-#use DNS::ZoneParse;
-
-#use Net::SCP qw(iscp);
-use Net::SCP qw(scp);
-use FS::UID qw(adminsuidsetup datasrc);
-use FS::Record qw(qsearch); #qsearchs);
-#use FS::svc_acct_sm;
-use FS::svc_domain;
-use FS::domain_record;
-#use FS::svc_acct;
-#use FS::part_svc;
-
-my $user = shift or die &usage;
-adminsuidsetup $user;
-
-use vars qw($spooldir);
-$spooldir = "/usr/local/etc/freeside/export.". datasrc. "/bind";
-mkdir $spooldir unless -d $spooldir;
-
-%d_part_svc =
- map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_domain'});
-
-print "\n\n",
- ( join "\n", map "$_: ".$d_part_svc{$_}->svc, sort keys %d_part_svc ),
- "\n\n";
-use vars qw($domain_svcpart);
-$^W=0; #Term::Query isn't -w-safe
-$domain_svcpart =
- query "Enter part number for domains: ", 'irk', [ keys %d_part_svc ];
-$^W=1;
-
-print "\n\n", <<END;
-Enter the location and name of your primary named.conf file, for example
-"ns.isp.com:/var/named/named.conf"
-END
-my($named_conf)=&getvalue(":");
-
-use vars qw($named_machine $prefix);
-$named_machine = (split(/:/, $named_conf))[0];
-$prefix = "$spooldir/$named_machine";
-mkdir $prefix unless -d $prefix;
-
-#iscp("root\@$named_conf","$prefix/named.conf.import");
-scp("root\@$named_conf","$prefix/named.conf.import");
-
-
-sub getvalue {
- my $prompt = shift;
- $^W=0; # Term::Query isn't -w-safe
- my $return = query $prompt, '';
- $^W=1;
- $return;
-}
-
-print "\n\n";
-
-##
-
-$FS::svc_domain::whois_hack=1;
-
-my $p = Parser->new;
-$p->parse_file("$prefix/named.conf.import");
-
-print "\nBIND import completed.\n";
-
-##
-
-sub usage {
- die "Usage:\n\n svc_domain.import user\n";
-}
-
-########
-BEGIN {
-
- package Parser;
- use BIND::Conf_Parser;
- use vars qw(@ISA $named_dir);
- @ISA = qw(BIND::Conf_Parser);
-
- sub handle_option {
- my($self, $option, $argument) = @_;
- return unless $option eq "directory";
- $named_dir = $argument;
- }
-
- sub handle_zone {
- my($self, $name, $class, $type, $options) = @_;
- return unless $class eq 'in';
- return if grep { $name eq $_ }
- ( qw( . localhost 127.in-addr.arpa 0.in-addr.arpa 255.in-addr.arpa ) );
-
- my $domain = new FS::svc_domain( {
- svcpart => $main::domain_svcpart,
- domain => $name,
- action => 'N',
- } );
- my $error = $domain->insert;
- die $error if $error;
-
- if ( $type eq 'slave' ) {
-
- #use Data::Dumper;
- #print Dumper($options);
- #exit;
-
- foreach my $master ( @{ $options->{masters} } ) {
- my $domain_record = new FS::domain_record( {
- 'svcnum' => $domain->svcnum,
- 'reczone' => '@',
- 'recaf' => 'IN',
- 'rectype' => '_mstr',
- 'recdata' => $master,
- } );
- my $error = $domain_record->insert;
- die $error if $error;
- }
-
- } elsif ( $type eq 'master' ) {
-
- my $file = $options->{file};
-
- use File::Basename;
- my $basefile = basename($file);
- my $sourcefile = $file;
- $sourcefile = "$named_dir/$sourcefile" unless $file =~ /^\//;
- use Net::SCP qw(iscp scp);
- scp("root\@$main::named_machine:$sourcefile",
- "$main::prefix/$basefile.import");
-
- use DNS::ZoneParse;
- my $zone = DNS::ZoneParse->new("$main::prefix/$basefile.import");
-
- my $dump = $zone->Dump;
-
- #use Data::Dumper;
- #print "$name: ". Dumper($dump);
- #exit;
-
- foreach my $rectype ( keys %$dump ) {
- if ( $rectype =~ /^SOA$/i ) {
- my $rec = $dump->{$rectype};
- my $domain_record = new FS::domain_record( {
- 'svcnum' => $domain->svcnum,
- 'reczone' => $rec->{origin},
- 'recaf' => 'IN',
- 'rectype' => $rectype,
- 'recdata' =>
- $rec->{primary}. ' '. $rec->{email}. ' ( '.
- join(' ', map $rec->{$_},
- qw( serial refresh retry expire minimumTTL ) ).
- ' )',
- } );
- my $error = $domain_record->insert;
- die $error if $error;
- } else {
- #die $dump->{$rectype};
- foreach my $rec ( @{ $dump->{$rectype} } ) {
- my $domain_record = new FS::domain_record( {
- 'svcnum' => $domain->svcnum,
- 'reczone' => $rec->{name},
- 'recaf' => $rec->{class},
- 'rectype' => $rectype,
- 'recdata' => ( $rectype =~ /^MX$/i
- ? $rec->{priority}. ' '. $rec->{host}
- : $rec->{host} ),
- } );
- my $error = $domain_record->insert;
- die $error if $error;
- }
- }
- }
-
- }
-
- }
-
-}
-#########
-
# $cgi->param('error', $error);
# print $cgi->redirect(popurl(2). "agent.cgi?". $cgi->query_string );
#no edit screen to send them back to
+%>
+<!-- mason kludge -->
+<%
eidiot($error);
} else {
my $svcnum = $new->svcnum;
my $domain = $svc_domain->domain;
-print header('Domain View', menubar(
+%>
+
+<%= header('Domain View', menubar(
( ( $pkgnum || $custnum )
? ( "View this package (#$pkgnum)" => "${p}view/cust_pkg.cgi?$pkgnum",
"View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum",
"${p}misc/cancel-unaudited.cgi?$svcnum" )
),
"Main menu" => $p,
-)),
- "Service #$svcnum",
- "<BR>Service: <B>", $part_svc->svc, "</B>",
- "<BR>Domain name: <B>$domain</B>.",
- qq!<BR>Catch all email <A HREF="${p}misc/catchall.cgi?$svcnum">(change)</A>:!,
- $email ? "<B>$email</B>." : "<I>(none)<I>",
- qq!<BR><BR><A HREF="http://www.geektools.com/cgi-bin/proxy.cgi?query=$domain;targetnic=auto">View whois information.</A>!,
- '<BR><BR>',
- '<SCRIPT>function areyousure(href) {
- if ( confirm("Remove this record?") == true )
- window.location.href = href;
- }
- </SCRIPT>',
- ntable("",2),
- '<tr><th>Zone</th><th>Type</th><th>Data</th></tr>',
-;
+)) %>
+Service #<%= $svcnum %>
+<BR>Service: <B><%= $part_svc->svc %></B>
+<BR>Domain name: <B><%= $domain %></B>
+<BR>Catch all email <A HREF="${p}misc/catchall.cgi?<%= $svcnum %>">(change)</A>:
+<%= $email ? "<B>$email</B>" : "<I>(none)<I>" %>
+<BR><BR><A HREF="http://www.geektools.com/cgi-bin/proxy.cgi?query=<%=$domain%>;targetnic=auto">View whois information.</A>
+<BR><BR>
+<SCRIPT>
+ function areyousure(href) {
+ if ( confirm("Remove this record?") == true )
+ window.location.href = href;
+ }
+</SCRIPT>
-foreach my $domain_record ( $svc_domain->domain_record ) {
- print '<tr><td>'. $domain_record->reczone. '</td>'.
- '<td>'. $domain_record->recaf. ' '. $domain_record->rectype. '</td>'.
- '<td>'. $domain_record->recdata;
- print qq! (<A HREF="javascript:areyousure('${p}misc/delete-domain_record.cgi?!
- .$domain_record->recnum. qq!')">delete</A>)!
- unless $domain_record->rectype eq 'SOA';
- print '</td></tr>';
-}
-print '</table><BR>'.
- qq!<FORM METHOD="POST" ACTION="${p}edit/process/domain_record.cgi">!.
- qq!<INPUT TYPE="hidden" NAME="svcnum" VALUE="$svcnum">!.
- '<INPUT TYPE="text" NAME="reczone"> '.
- '<INPUT TYPE="hidden" NAME="recaf" VALUE="IN">IN '.
- '<SELECT NAME="rectype">'.
- join('', map qq!<OPTION VALUE="$_">$_</OPTION>!, qw(A NS CNAME MX) ).
- '</SELECT>'.
- ' <INPUT TYPE="text" NAME="recdata"> <INPUT TYPE="submit" VALUE="Add">'.
- '<BR><BR>'. joblisting({'svcnum'=>$svcnum}, 1).
- '</BODY></HTML>';
+<% my @records; if ( @records = $svc_domain->domain_record ) { %>
+ <%= ntable("",2) %>
+ <tr><th>Zone</th><th>Type</th><th>Data</th></tr>
-%>
+ <% foreach my $domain_record ( @records ) {
+ my $type = $domain_record->rectype eq '_mstr'
+ ? "(slave)"
+ : $domain_record->recaf. ' '. $domain_record->rectype;
+ %>
+
+ <tr><td><%= $domain_record->reczone %></td>
+ <td><%= $type %></td>
+ <td><%= $domain_record->recdata %>
+
+ <% unless ( $domain_record->rectype eq 'SOA' ) { %>
+ (<A HREF="javascript:areyousure('<%=$p%>misc/delete-domain_record.cgi?<%=$domain_record->recnum%>')">delete</A>)
+ <% } %>
+ </td></tr>
+ <% } %>
+ </table>
+<% } %>
+
+<BR>
+<FORM METHOD="POST" ACTION="<%=$p%>edit/process/domain_record.cgi">
+<INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>">
+<INPUT TYPE="text" NAME="reczone">
+<INPUT TYPE="hidden" NAME="recaf" VALUE="IN"> IN
+ <SELECT NAME="rectype">
+<% foreach (qw( A NS CNAME MX) ) { %>
+ <OPTION VALUE="<%=$_%>"><%=$_%></OPTION>
+<% } %>
+ </SELECT>
+<INPUT TYPE="text" NAME="recdata"> <INPUT TYPE="submit" VALUE="Add record">
+</FORM><BR><BR>or<BR><BR>
+<FORM METHOD="POST" ACTION="<%=$p%>edit/process/domain_record.cgi">
+<INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>">
+
+<% if ( @records ) { %> Delete all records and <% } %>
+Slave from nameserver IP
+<INPUT TYPE="hidden" NAME="svcnum" VALUE="<%=$svcnum%>">
+<INPUT TYPE="hidden" NAME="reczone" VALUE="@">
+<INPUT TYPE="hidden" NAME="recaf" VALUE="IN">
+<INPUT TYPE="hidden" NAME="rectype" VALUE="_mstr">
+<INPUT TYPE="text" NAME="recdata"> <INPUT TYPE="submit" VALUE="Slave domain">
+</FORM>
+<BR><BR><%= joblisting({'svcnum'=>$svcnum}, 1) %>
+</BODY></HTML>