Changeset 543
- Timestamp:
- 12/10/13 16:22:10 (11 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r542 r543 31 31 use POSIX; 32 32 use Fcntl qw(:flock); 33 use Time::TAI64 qw(:tai64); 33 34 34 35 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); … … 3536 3537 my $id = shift; 3537 3538 3539 ##fixme: do we need a knob to twist to switch between unix epoch and postgres time string? 3538 3540 my $sql = "SELECT record_id,host,type,val,ttl". 3539 3541 ($defrec eq 'n' ? ',location' : ''). 3540 3542 ($revrec eq 'n' ? ',distance,weight,port' : ''). 3541 (($defrec eq 'y') ? ',group_id FROM ' : ',domain_id,rdns_id FROM ').3543 (($defrec eq 'y') ? ',group_id FROM ' : ',domain_id,rdns_id,stamp,stamp < now() AS ispast,expires,stampactive FROM '). 3542 3544 _rectable($defrec,$revrec)." WHERE record_id=?"; 3543 3545 my $ret = $dbh->selectrow_hashref($sql, undef, ($id) ); … … 3608 3610 $newsort =~ s/^,//; 3609 3611 3612 ##fixme: do we need a knob to twist to switch from unix epoch to postgres time string? 3610 3613 my $sql = "SELECT r.record_id,r.host,r.type,r.val,r.ttl"; 3611 $sql .= ",l.description AS locname" if $args{defrec} eq 'n'; 3614 $sql .= ",l.description AS locname,stamp,r.stamp < now() AS ispast,r.expires,r.stampactive" 3615 if $args{defrec} eq 'n'; 3612 3616 $sql .= ",r.distance,r.weight,r.port" if $args{revrec} eq 'n'; 3613 3617 $sql .= " FROM "._rectable($args{defrec},$args{revrec})." r "; … … 3627 3631 my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, (@bindvars) ); 3628 3632 $errstr = "Error retrieving records: ".$dbh->errstr if !$ret; 3633 3629 3634 return $ret; 3630 3635 } # end getRecList() … … 3685 3690 my $location = shift; 3686 3691 $location = '' if !$location; 3692 3693 my $expires = shift; 3694 $expires = 1 if $expires eq 'until'; # Turn some special values into the appropriate booleans. 3695 $expires = 0 if $expires eq 'after'; 3696 my $stamp = shift; 3697 $stamp = '' if !$stamp; # Timestamp should be a string at this point. 3687 3698 3688 3699 # Spaces are evil. … … 3745 3756 push @vallist, ($$host,$$rectype,$$val,$ttl,$id); 3746 3757 3747 # locations are not for default records, silly coder!3748 3758 if ($defrec eq 'n') { 3759 # locations are not for default records, silly coder! 3749 3760 $fields .= ",location"; 3750 3761 push @vallist, $location; 3751 } 3762 # timestamps are rare. 3763 if ($stamp) { 3764 $fields .= ",stamp,expires,stampactive"; 3765 push @vallist, $stamp, $expires, 'y'; 3766 } else { 3767 $fields .= ",stampactive"; 3768 push @vallist, 'n'; 3769 } 3770 } 3771 3772 # a little magic to get the right number of ? placeholders based on how many values we're providing 3752 3773 my $vallen = '?'.(',?'x$#vallist); 3753 3774 … … 3777 3798 $logdata{entry} .= "', TTL $ttl"; 3778 3799 $logdata{entry} .= ", location ".$self->getLoc($location)->{description} if $location; 3800 $logdata{entry} .= ($expires eq 'after' ? ', valid after ' : ', expires at ').$stamp if $stamp; 3779 3801 3780 3802 # Allow transactions, and raise an exception on errors so we can catch it later. … … 3830 3852 $location = '' if !$location; 3831 3853 3854 my $expires = shift; 3855 $expires = 1 if $expires eq 'until'; # Turn some special values into the appropriate booleans. 3856 $expires = 0 if $expires eq 'after'; 3857 my $stamp = shift; 3858 $stamp = '' if !$stamp; # Timestamp should be a string at this point. 3859 3832 3860 # just set it to an empty string; failures will be caught later. 3833 3861 $$host = '' if !$$host; … … 3901 3929 ($defrec eq 'y' ? $oldrec->{group_id} : ($revrec eq 'n' ? $oldrec->{domain_id} : $oldrec->{rdns_id})) ); 3902 3930 3903 # locations are not for default records, silly coder!3904 3931 if ($defrec eq 'n') { 3932 # locations are not for default records, silly coder! 3905 3933 $fields .= ",location"; 3906 3934 push @vallist, $location; 3935 # timestamps are rare. 3936 if ($stamp) { 3937 $fields .= ",stamp,expires,stampactive"; 3938 push @vallist, $stamp, $expires, 'y'; 3939 } else { 3940 $fields .= ",stampactive"; 3941 push @vallist, 'n'; 3942 } 3907 3943 } 3908 3944 … … 3958 3994 $logdata{entry} .= "', TTL $oldrec->{ttl}"; 3959 3995 $logdata{entry} .= ", location ".$self->getLoc($oldrec->{location})->{description} if $oldrec->{location}; 3996 $logdata{entry} .= ($oldrec->{expires} ? ', expires at ' : ', valid after ').$oldrec->{stamp} 3997 if $oldrec->{stampactive}; 3960 3998 $logdata{entry} .= "\nto\n"; 3961 3999 # More NS special … … 3969 4007 $logdata{entry} .= "', TTL $ttl"; 3970 4008 $logdata{entry} .= ", location ".$self->getLoc($location)->{description} if $location; 4009 $logdata{entry} .= ($expires eq 'after' ? ', valid after ' : ', expires at ').$stamp if $stamp; 3971 4010 3972 4011 local $dbh->{AutoCommit} = 0; … … 4975 5014 my $soasth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ". 4976 5015 "FROM records WHERE rdns_id=? AND type=6"); 4977 my $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".5016 my $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ". 4978 5017 "FROM records WHERE rdns_id=? AND not type=6 ". 4979 5018 "ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet)"); … … 5008 5047 5009 5048 $recsth->execute($revid); 5010 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc ) = $recsth->fetchrow_array) {5049 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc,$stamp,$expires,$stampactive) = $recsth->fetchrow_array) { 5011 5050 next if $recflags{$recid}; 5012 5051 5013 $loc = '' if !$loc; # de-nullify - just in case 5014 ##fixme: handle case of record-with-location-that-doesn't-exist better. 5015 # note this currently fails safe (tested) - records with a location that 5016 # doesn't exist will not be sent to any client 5017 # $loc = '' if !$lochash->{$loc}; 5018 5019 ##fixme: record validity timestamp. tinydns supports fiddling with timestamps. 5020 # note $ttl must be set to 0 if we want to use tinydns's auto-expiring timestamps. 5021 # timestamps are TAI64 5022 # ~~ 2^62 + time() 5023 my $stamp = ''; 5024 5025 # support tinydns' auto-TTL 5026 $ttl = '' if $ttl == -1; 5052 # not sure this is necessary for revzones. 5053 # # Spaces are evil. 5054 # $val =~ s/^\s+//; 5055 # $val =~ s/\s+$//; 5056 # if ($typemap{$type} ne 'TXT') { 5057 # # Leading or trailng spaces could be legit in TXT records. 5058 # $host =~ s/^\s+//; 5059 # $host =~ s/\s+$//; 5060 # } 5027 5061 5028 5062 _printrec_tiny(*ZONECACHE, 'y', \%recflags, $revzone, 5029 $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp )5063 $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive) 5030 5064 if *ZONECACHE; 5031 5065 … … 5062 5096 5063 5097 my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1"); 5064 $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".5098 $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ". 5065 5099 "FROM records WHERE domain_id=?"); # Just exclude all types relating to rDNS 5066 5100 # "FROM records WHERE domain_id=? AND type < 65280"); # Just exclude all types relating to rDNS … … 5083 5117 5084 5118 $recsth->execute($domid); 5085 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc ) = $recsth->fetchrow_array) {5119 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc,$stamp,$expires,$stampactive) = $recsth->fetchrow_array) { 5086 5120 next if $recflags{$recid}; 5087 5088 $loc = '' if !$loc; # de-nullify - just in case5089 ##fixme: handle case of record-with-location-that-doesn't-exist better.5090 # note this currently fails safe (tested) - records with a location that5091 # doesn't exist will not be sent to any client5092 # $loc = '' if !$lochash->{$loc};5093 5094 ##fixme: record validity timestamp. tinydns supports fiddling with timestamps.5095 # note $ttl must be set to 0 if we want to use tinydns's auto-expiring timestamps.5096 # timestamps are TAI645097 # ~~ 2^62 + time()5098 my $stamp = '';5099 5100 # support tinydns' auto-TTL5101 $ttl = '' if $ttl == -1;5102 5121 5103 5122 # Spaces are evil. … … 5111 5130 5112 5131 _printrec_tiny(*ZONECACHE, 'n', \%recflags, 5113 $dom, $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp )5132 $dom, $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive) 5114 5133 if *ZONECACHE; 5115 5134 … … 5150 5169 # Utility sub for __export_tiny above 5151 5170 sub _printrec_tiny { 5152 my ($datafile,$revrec,$recflags,$zone,$host,$type,$val,$dist,$weight,$port,$ttl,$loc,$stamp) = @_; 5171 my ($datafile,$revrec,$recflags,$zone,$host,$type,$val,$dist,$weight,$port,$ttl,$loc,$stamp,$expires,$stampactive) = @_; 5172 5173 $loc = '' if !$loc; # de-nullify - just in case 5174 ##fixme: handle case of record-with-location-that-doesn't-exist better. 5175 # note this currently fails safe (tested) - records with a location that 5176 # doesn't exist will not be sent to any client 5177 # $loc = '' if !$lochash->{$loc}; 5178 5179 5180 ## Records that are valid only before or after a set time 5181 5182 # record due to expire sometime is the complex case. we don't want to just 5183 # rely on tinydns' auto-adjusting TTLs, because the default TTL in that case 5184 # is one day instead of the SOA minttl as BIND might do. 5185 5186 # consider the case where a record is set to expire a week ahead, but the next 5187 # day later you want to change it NOW (or as NOWish as you get with your DNS 5188 # management practice). but now you're stuck, because someone, somewhere, 5189 # has just done a lookup before your latest change was published, and they'll 5190 # be caching that old, broken record for 1 day instead of your zone default 5191 # TTL. 5192 5193 # $stamp-$ttl is the *latest* we can publish the record with the defined TTL 5194 # to still have the expiry happen as scheduled, but we need to find some 5195 # *earlier* point. We can maybe guess, and 2x TTL is probably reasonable, 5196 # but we need info on the export frequency. 5197 5198 # export the normal, non-expiring record up until $stamp-<guesstimate>, then 5199 # switch to exporting a record with the TAI64 stamp and a 0 TTL so tinydns 5200 # takes over TTL management. 5201 5202 if ($stampactive) { 5203 if ($expires) { 5204 # record expires at $stamp; decide if we need to keep the TTL and ignore 5205 # the stamp for a time or if we need to change the TTL to 0 and convert 5206 # $stamp to TAI64 so tinydns can use $stamp to autoadjust the TTL on the fly. 5207 # extra hack, optimally needs more knowledge of data export frequency 5208 # smack the idiot customer who insists on 0 TTLs; they can suck up and 5209 # deal with a 10-minute TTL. especially on scheduled changes. note this 5210 # should be (export freq * 2), but we don't know the actual export frequency. 5211 $ttl = 300 if $ttl == 0; #hack phtui 5212 my $ahead = (86400 < $ttl*2 ? 86400 : $ttl*2); 5213 if ((time() + $ahead) < $stamp) { 5214 # more than 2x TTL OR more than one day (whichever is less) from expiry time; publish normal record 5215 $stamp = ''; 5216 } else { 5217 # less than 2x TTL from expiry time, let tinydns take over TTL management and publish the TAI64 stamp. 5218 $ttl = 0; 5219 $stamp = unixtai64($stamp); 5220 $stamp =~ s/\@//; 5221 } 5222 } else { 5223 # record is "active after"; convert epoch from database to TAI64, publish, and collect $200. 5224 $stamp = unixtai64($stamp); 5225 $stamp =~ s/\@//; 5226 } 5227 } else { 5228 # flag for active timestamp is false; don't actually put a timestamp in the output 5229 $stamp = ''; 5230 } 5231 5232 # support tinydns' auto-TTL 5233 $ttl = '' if $ttl == -1; 5234 # these are WAY FREAKING HIGH - higher even than most TLD registry TTLs! 5235 # NS 259200 => 3d 5236 # all others 86400 => 1d 5153 5237 5154 5238 if ($revrec eq 'y') { -
trunk/dns-1.0-1.2.sql
r507 r543 72 72 ALTER TABLE records ADD COLUMN rdns_id INTEGER DEFAULT 0 NOT NULL; 73 73 ALTER TABLE records ADD COLUMN location character varying (4) DEFAULT '' NOT NULL; 74 -- Scheduled changes. 75 ALTER TABLE records ADD COLUMN stamp TIMESTAMP WITH TIME ZONE DEFAULT 'epoch' NOT NULL; 76 ALTER TABLE records ADD COLUMN expires boolean DEFAULT 'n' NOT NULL; 77 ALTER TABLE records ADD COLUMN stampactive boolean DEFAULT 'n' NOT NULL; 74 78 75 79 -- ~120s -> 75s performance boost on 100K records when always exporting all records -
trunk/dns-rpc.cgi
r516 r543 475 475 476 476 my @recargs = ($args{defrec}, $args{revrec}, $args{parent_id}, 477 \$args{name}, \$args{type}, \$args{address}, $args{ttl}, $args{location}); 477 \$args{name}, \$args{type}, \$args{address}, $args{ttl}, $args{location}, 478 $args{expires}, $args{stamp}); 478 479 if ($args{type} == $DNSDB::reverse_typemap{MX} or $args{type} == $DNSDB::reverse_typemap{SRV}) { 479 480 push @recargs, $args{distance}; … … 497 498 _reccheck(\%args); 498 499 500 # put some caller-friendly names in their rightful DB column places 501 $args{val} = $args{address}; 502 $args{host} = $args{name}; 503 499 504 # get old line, so we can update only the bits that the caller passed to change 500 # note we subbed address for val since it's a little more caller-friendly501 505 my $oldrec = $dnsdb->getRecLine($args{defrec}, $args{revrec}, $args{id}); 502 foreach my $field (qw( name type address ttl locationdistance weight port)) {506 foreach my $field (qw(host type val ttl location expires distance weight port)) { 503 507 $args{$field} = $oldrec->{$field} if !$args{$field} && defined($oldrec->{$field}); 504 508 } 509 # stamp has special handling when blank or 0. "undefined" from the caller should mean "don't change" 510 $args{stamp} = $oldrec->{stamp} if !defined($args{stamp}) && defined($oldrec->{stamp}); 505 511 506 512 # allow passing text types rather than DNS integer IDs … … 510 516 # parent_id is the "primary" zone we're updating; necessary for forward/reverse voodoo 511 517 my ($code, $msg) = $dnsdb->updateRec($args{defrec}, $args{revrec}, $args{id}, $args{parent_id}, 512 \$args{name}, \$args{type}, \$args{address}, $args{ttl}, $args{location}, 518 \$args{host}, \$args{type}, \$args{val}, $args{ttl}, $args{location}, 519 $args{expires}, $args{stamp}, 513 520 $args{distance}, $args{weight}, $args{port}); 514 521 -
trunk/dns.cgi
r533 r543 30 30 use Net::DNS; 31 31 use DBI; 32 32 33 use Data::Dumper; 33 34 … … 721 722 722 723 my @recargs = ($webvar{defrec}, $webvar{revrec}, $webvar{parentid}, 723 \$webvar{name}, \$webvar{type}, \$webvar{address}, $webvar{ttl}, $webvar{location}); 724 \$webvar{name}, \$webvar{type}, \$webvar{address}, $webvar{ttl}, $webvar{location}, 725 $webvar{expires}, $webvar{stamp}); 724 726 if ($webvar{type} == $reverse_typemap{MX} or $webvar{type} == $reverse_typemap{SRV}) { 725 727 push @recargs, $webvar{distance}; … … 769 771 $page->param(ttl => $recdata->{ttl}); 770 772 $page->param(typelist => $dnsdb->getTypelist($webvar{revrec}, $recdata->{type})); 771 773 if ($recdata->{stampactive}) { 774 $page->param(stamp => $recdata->{stamp}); 775 $page->param(stamp_until => $recdata->{expires}); 776 } 772 777 if ($webvar{defrec} eq 'n') { 773 778 fill_loclist($curgroup, $recdata->{location}); … … 785 790 my ($code,$msg) = $dnsdb->updateRec($webvar{defrec}, $webvar{revrec}, $webvar{id}, $webvar{parentid}, 786 791 \$webvar{name}, \$webvar{type}, \$webvar{address}, $webvar{ttl}, $webvar{location}, 792 $webvar{expires}, $webvar{stamp}, 787 793 $webvar{distance}, $webvar{weight}, $webvar{port}); 788 794 … … 2002 2008 $rec->{record_delete} = ($permissions{admin} || $permissions{record_delete}); 2003 2009 $rec->{locname} = '' unless ($permissions{admin} || $permissions{location_view}); 2010 # Timestamps 2011 if ($rec->{expires}) { 2012 $rec->{stamptype} = $rec->{ispast} ? 'expired at' : 'expires at'; 2013 } else { 2014 $rec->{stamptype} = 'valid after'; 2015 } 2016 # strip seconds and timezone? no, not yet. could probably offer a config knob on this display at some point. 2017 # $rec->{stamp} =~ s/:\d\d-\d+$//; 2018 delete $rec->{expires}; 2019 delete $rec->{ispast}; 2004 2020 } 2005 2021 $page->param(reclist => $foo2); … … 2032 2048 my $soa = $dnsdb->getSOA($webvar{defrec}, $webvar{revrec}, $webvar{parentid}); 2033 2049 $page->param(ttl => ($webvar{ttl} ? $webvar{ttl} : $soa->{minttl})); 2050 $page->param(stamp_until => ($webvar{expires} eq 'until')); 2051 $page->param(stamp => $webvar{stamp}); 2034 2052 } 2035 2053 -
trunk/dns.sql
r507 r543 166 166 description text, 167 167 rdns_id integer NOT NULL DEFAULT 0, 168 location character varying (4) DEFAULT '' NOT NULL 168 location character varying (4) DEFAULT '' NOT NULL, 169 stamp TIMESTAMP WITH TIME ZONE DEFAULT 'epoch' NOT NULL, 170 expires boolean DEFAULT 'n' NOT NULL, 171 stampactive boolean DEFAULT 'n' NOT NULL 169 172 ); 170 173 CREATE INDEX rec_domain_index ON records USING btree (domain_id); -
trunk/templates/dns.css
r532 r543 165 165 text-align: center; 166 166 padding: 5px; 167 width: 5 0%;167 width: 55%; 168 168 } 169 169 .warning { -
trunk/templates/reclist.tmpl
r538 r543 61 61 <tr class="row<TMPL_IF __odd__>0<TMPL_ELSE>1</TMPL_IF>"> 62 62 <TMPL_IF fwdzone> 63 <td><TMPL_IF record_edit><a href="<TMPL_VAR NAME=script_self>&page=record&parentid=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=edit&id=<TMPL_VAR NAME=record_id>"><TMPL_VAR NAME=host></a><TMPL_IF locname> (<TMPL_VAR NAME=locname>)</TMPL_IF><TMPL_ELSE><TMPL_VAR NAME=host><TMPL_IF locname> (<TMPL_VAR NAME=locname>)</TMPL_IF></TMPL_IF></td> 63 <td><TMPL_IF record_edit><a href="<TMPL_VAR NAME=script_self>&page=record&parentid=<TMPL_VAR 64 NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=edit&id=<TMPL_VAR 65 NAME=record_id>"><TMPL_VAR NAME=host></a><TMPL_IF locname> (<TMPL_VAR 66 NAME=locname>)</TMPL_IF><TMPL_ELSE><TMPL_VAR NAME=host><TMPL_IF locname> (<TMPL_VAR 67 NAME=locname>)</TMPL_IF></TMPL_IF><TMPL_IF stampactive><br />(<TMPL_VAR NAME=stamptype> <TMPL_VAR 68 NAME=stamp>)</TMPL_IF></td> 64 69 <td><TMPL_VAR NAME=type></td> 65 70 <td><TMPL_VAR NAME=val></td> … … 68 73 <td><TMPL_VAR NAME=port></td> 69 74 <TMPL_ELSE> 70 <td><TMPL_IF record_edit><a href="<TMPL_VAR NAME=script_self>&page=record&parentid=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=edit&id=<TMPL_VAR NAME=record_id>"><TMPL_VAR NAME=val></a><TMPL_IF locname> (<TMPL_VAR NAME=locname>)</TMPL_IF><TMPL_ELSE><TMPL_VAR NAME=val><TMPL_IF locname> (<TMPL_VAR NAME=locname>)</TMPL_IF></TMPL_IF></td> 75 <td><TMPL_IF record_edit><a href="<TMPL_VAR NAME=script_self>&page=record&parentid=<TMPL_VAR 76 NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=edit&id=<TMPL_VAR 77 NAME=record_id>"><TMPL_VAR NAME=val></a><TMPL_IF locname> (<TMPL_VAR 78 NAME=locname>)</TMPL_IF><TMPL_ELSE><TMPL_VAR NAME=val><TMPL_IF locname> (<TMPL_VAR 79 NAME=locname>)</TMPL_IF></TMPL_IF><TMPL_IF stampactive><br />(<TMPL_VAR NAME=stamptype> <TMPL_VAR 80 NAME=stamp>)</TMPL_IF></td> 71 81 <td><TMPL_VAR NAME=type></td> 72 82 <td><TMPL_VAR NAME=host></td> -
trunk/templates/record.tmpl
r532 r543 18 18 <input type="hidden" name="recact" value="<TMPL_VAR NAME=recact>" /> 19 19 20 <table class="container" width=" 450">20 <table class="container" width="520"> 21 21 <tr><td> 22 22 … … 81 81 </tr> 82 82 </TMPL_IF> 83 <TMPL_UNLESS is_default> 84 <tr class="datalinelight"> 85 <td>Timestamp<br />(blank or 0 disables timestamp)</td> 86 <td>Valid <input type="radio" name="expires" value="until"<TMPL_IF stamp_until> checked="checked"</TMPL_IF>>until 87 <input type="radio" name="expires" value="after"<TMPL_UNLESS stamp_until> checked="checked"</TMPL_UNLESS>>after: 88 <input type="text" name="stamp" value="<TMPL_VAR NAME=stamp>" /> 89 </td> 90 </tr> 91 </TMPL_UNLESS> 83 92 <tr class="datalinelight"> 84 93 <td colspan="2" align="center"><input type="submit" value=" <TMPL_VAR NAME=todo> " /></td> -
trunk/tiny-import.pl
r528 r543 25 25 use strict; 26 26 use warnings; 27 use POSIX; 28 use Time::TAI64 qw(:tai); 27 29 28 30 use lib '.'; ##uselib## … … 125 127 } 126 128 127 our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location ) ".128 " VALUES (?,?,?,?,?,?,?,?,?,? )");129 our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location,stamp,expires,stampactive) ". 130 " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"); 129 131 130 132 my %deleg; … … 248 250 } 249 251 252 sub calcstamp { 253 my $stampin = shift; 254 my $ttl = shift; 255 my $pzone = shift; 256 my $revrec = shift; 257 258 return ($ttl, 'n', 'n', '1970-01-01 00:00:00 -0') if !$stampin; 259 260 ##fixme Yes, this fails for records in 2038 sometime. No, I'm not going to care for a while. 261 $stampin = "\@$stampin"; # Time::TAI64 needs the leading @. Feh. 262 my $u = tai2unix($stampin); 263 $stampin = strftime("%Y-%m-%d %H:%M:%S %z", localtime($u)); 264 my $expires = 'n'; 265 if ($ttl) { 266 # TTL can stay put. 267 } else { 268 # TTL on import is 0, almost certainly wrong. Get the parent zone's SOA and use the minttl. 269 my $soa = $dnsdb->getSOA('n', $revrec, $pzone); 270 $ttl = $soa->{minttl}; 271 $expires = 'y'; 272 } 273 return ($ttl, 'y', $expires, $stampin); 274 } 250 275 251 276 sub recslurp { … … 274 299 my $fparent = $dnsdb->_hostparent($host); 275 300 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($ip)); 301 302 my $stampactive = 'n'; 303 my $expires = 'n'; 304 305 # can't set a timestamp on an orphaned record. we'll actually fail import of this record a little later. 306 if ($fparent || $rparent) { 307 if ($fparent) { 308 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n'); 309 } else { 310 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 311 } 312 } 313 276 314 if ($fparent && $rparent) { 277 $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc );315 $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 278 316 } else { 279 317 if ($importcfg{legacy}) { … … 282 320 $rparent = 0 if !$rparent; 283 321 if ($fparent || $rparent) { 284 $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc );322 $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 285 323 } else { 286 324 # No parents found, cowardly refusing to add a dangling record … … 290 328 } elsif ($importcfg{conv}) { 291 329 # downconvert A+PTR if forward zone is not found 292 $recsth->execute(0, $rparent, $host, 12, $ip, 0, 0, 0, $ttl, $loc );330 $recsth->execute(0, $rparent, $host, 12, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 293 331 $converted++; 294 332 } else { … … 310 348 $loc = '' if !$loc; 311 349 $loc = '' if $loc =~ /^:+$/; 350 351 my $stampactive = 'n'; 352 my $expires = 'n'; 353 312 354 if ($host =~ /\.arpa$/) { 313 355 ($code,$msg) = DNSDB::_zone2cidr($host); 314 356 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 315 $recsth->execute(0, $rparent, $targ, 5, $msg->addr, 0, 0, 0, $ttl, $loc); 357 if ($rparent) { 358 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 359 $recsth->execute(0, $rparent, $targ, 5, $msg->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 360 } else { 361 push @deferred, $rec unless $nodefer; 362 $impok = 0; 363 # print "$tmporig deferred; can't find parent zone\n"; 364 } 316 365 317 366 ##fixme: automagically convert manually maintained sub-/24 delegations … … 324 373 my $fparent = $dnsdb->_hostparent($host); 325 374 if ($fparent) { 326 $recsth->execute($fparent, 0, $host, 5, $targ, 0, 0, 0, $ttl, $loc); 375 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n'); 376 $recsth->execute($fparent, 0, $host, 5, $targ, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 327 377 } else { 328 378 push @deferred, $rec unless $nodefer; … … 344 394 $loc = '' if !$loc; 345 395 $loc = '' if $loc =~ /^:+$/; 396 397 my $stampactive = 'n'; 398 my $expires = 'n'; 399 346 400 if ($zone =~ /\.arpa$/) { 347 401 ($code,$msg) = DNSDB::_zone2cidr($zone); … … 352 406 # if !$rparent; 353 407 if ($rparent) { 354 $recsth->execute(0, $rparent, $ns, 2, $msg, 0, 0, 0, $ttl, $loc); 408 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 409 $recsth->execute(0, $rparent, $ns, 2, $msg, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 355 410 } else { 356 411 push @deferred, $rec unless $nodefer; … … 360 415 my $fparent = $dnsdb->_hostparent($zone); 361 416 if ($fparent) { 362 $recsth->execute($fparent, 0, $zone, 2, $ns, 0, 0, 0, $ttl, $loc); 363 $recsth->execute($fparent, 0, $ns, 2, $ip, 0, 0, 0, $ttl, $loc) if $ip; 417 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n'); 418 $recsth->execute($fparent, 0, $zone, 2, $ns, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 419 $recsth->execute($fparent, 0, $ns, 2, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip; 364 420 } else { 365 421 push @deferred, $rec unless $nodefer; … … 378 434 $loc = '' if !$loc; 379 435 $loc = '' if $loc =~ /^:+$/; 436 437 my $stampactive = 'n'; 438 my $expires = 'n'; 439 380 440 my $rparent; 381 441 if (my ($i, $z) = ($rip =~ /^(\d+)\.(\d+-(?:\d+\.){4}in-addr.arpa)$/) ) { … … 392 452 } 393 453 if ($rparent) { 394 $recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc); 454 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 455 $recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 395 456 } else { 396 457 push @deferred, $rec unless $nodefer; … … 410 471 $loc = '' if $loc =~ /^:+$/; 411 472 473 my $stampactive = 'n'; 474 my $expires = 'n'; 475 412 476 my $domid = $dnsdb->_hostparent($host); 413 477 if ($domid) { 414 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc); 478 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 479 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 415 480 } else { 416 481 push @deferred, $rec unless $nodefer; … … 430 495 $loc = '' if !$loc; 431 496 $loc = '' if $loc =~ /^:+$/; 497 498 my $stampactive = 'n'; 499 my $expires = 'n'; 500 501 ##fixme er... what do we do with an SOA with a timestamp? O_o 502 # fail for now, since there's no clean way I can see to handle this (yet) 503 # maybe (ab)use the -l flag to import as-is? 504 if ($stamp) { 505 push @deferred, $rec unless $nodefer; 506 return 0; 507 } 508 509 ##fixme: need more magic on TTL, so we can decide whether to use the minttl or newttl 510 # my $newttl; 511 # ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n'); 512 # $ttl = $newttl if !$ttl; 513 432 514 if ($zone =~ /\.arpa$/) { 433 515 ($code,$msg) = DNSDB::_zone2cidr($zone); … … 435 517 undef, ($msg, $loc)); 436 518 my ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')"); 437 $recsth->execute(0, $rdns, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, $loc); 519 my $newttl; 520 ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'y'); 521 $ttl = $newttl if !$ttl; 522 $recsth->execute(0, $rdns, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, 523 $loc, $stamp, $expires, $stampactive); 438 524 } else { 439 525 $dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,1,1,?)", 440 526 undef, ($zone, $loc)); 441 527 my ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')"); 442 $recsth->execute($domid, 0, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, $loc); 528 my $newttl; 529 ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n'); 530 $ttl = $newttl if !$ttl; 531 $recsth->execute($domid, 0, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, 532 $loc, $stamp, $expires, $stampactive); 443 533 } 444 534 … … 457 547 $loc = '' if $loc =~ /^:+$/; 458 548 549 my $stampactive = 'n'; 550 my $expires = 'n'; 551 459 552 # note we don't check for reverse domains here, because MX records don't make any sense in reverse zones. 460 553 # if this really ever becomes an issue for someone it can be expanded to handle those weirdos … … 463 556 my $domid = $dnsdb->_hostparent($zone); 464 557 if ($domid) { 465 $recsth->execute($domid, 0, $zone, 15, $host, $dist, 0, 0, $ttl, $loc); 466 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc) if $ip; 558 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 559 $recsth->execute($domid, 0, $zone, 15, $host, $dist, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 560 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip; 467 561 } else { 468 562 push @deferred, $rec unless $nodefer; … … 482 576 $loc = '' if $loc =~ /^:+$/; 483 577 578 my $stampactive = 'n'; 579 my $expires = 'n'; 580 484 581 if ($fqdn =~ /\.arpa$/) { 485 582 ($code,$msg) = DNSDB::_zone2cidr($fqdn); 486 583 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 487 $recsth->execute(0, $rparent, $rdata, 16, "$msg", 0, 0, 0, $ttl, $loc); 584 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 585 $recsth->execute(0, $rparent, $rdata, 16, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 488 586 } else { 489 587 my $domid = $dnsdb->_hostparent($fqdn); 490 588 if ($domid) { 491 $recsth->execute($domid, 0, $fqdn, 16, $rdata, 0, 0, 0, $ttl, $loc); 589 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 590 $recsth->execute($domid, 0, $fqdn, 16, $rdata, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 492 591 } else { 493 592 push @deferred, $rec unless $nodefer; … … 508 607 $loc = '' if !$loc; 509 608 $loc = '' if $loc =~ /^:+$/; 609 610 my $stampactive = 'n'; 611 my $expires = 'n'; 612 613 ##fixme er... what do we do with an SOA with a timestamp? O_o 614 # fail for now, since there's no clean way I can see to handle this (yet) 615 # maybe (ab)use the -l flag to import as-is? 616 if ($stamp) { 617 push @deferred, $rec unless $nodefer; 618 return 0; 619 } 620 621 ##fixme: need more magic on TTL, so we can decide whether to use the minttl or newttl 622 # my $newttl; 623 # ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n'); 510 624 511 625 if ($fqdn =~ /\.arpa$/) { … … 517 631 undef, ($msg, $loc)); 518 632 ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')"); 633 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, 0, 'y'); 519 634 # this would probably make a lot more sense to do hostmaster.$config{admindomain} 520 $recsth->execute(0, $rdns, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", $loc); 521 } 522 $recsth->execute(0, $rdns, $ns, 2, "$msg", 0, 0, 0, $ttl, $loc); 635 # otherwise, it's as per the tinydns defaults that work tolerably well on a small scale 636 # serial -> modtime of data file, ref -> 16384, ret -> 2048, exp -> 1048576, min -> 2560 637 $recsth->execute(0, $rdns, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", 638 $loc, $stamp, $expires, $stampactive); 639 } 640 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, $rdns, 'y') if !$stamp; 641 $recsth->execute(0, $rdns, $ns, 2, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 523 642 ##fixme: (?) implement full conversion of tinydns . records? 524 643 # -> problem: A record for NS must be added to the appropriate *forward* zone, not the reverse 525 #$recsth->execute(0, $rdns, $ns, 1, $ip, 0, 0, 0, $ttl )644 #$recsth->execute(0, $rdns, $ns, 1, $ip, 0, 0, 0, $ttl, $stamp, $expires, $stampactive) 526 645 # ... auto-A-record simply does not make sense in reverse zones. Functionally 527 646 # I think it would work, sort of, but it's a nasty mess and anyone hosting reverse … … 537 656 undef, ($fqdn, $loc)); 538 657 ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')"); 539 $recsth->execute($domid, 0, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", $loc); 540 } 541 $recsth->execute($domid, 0, $fqdn, 2, $ns, 0, 0, 0, $ttl, $loc); 542 $recsth->execute($domid, 0, $ns, 1, $ip, 0, 0, 0, $ttl, $loc) if $ip; 658 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, 0, 'n'); 659 $recsth->execute($domid, 0, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", 660 $loc, $stamp, $expires, $stampactive); 661 } 662 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n') if !$stamp; 663 $recsth->execute($domid, 0, $fqdn, 2, $ns, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 664 $recsth->execute($domid, 0, $ns, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip; 543 665 } 544 666 … … 576 698 $loc = '' if !$loc; 577 699 $loc = '' if $loc =~ /^:+$/; 700 701 my $stampactive = 'n'; 702 my $expires = 'n'; 578 703 579 704 if ($type == 33) { … … 604 729 my $domid = $dnsdb->_hostparent($fqdn); 605 730 if ($domid) { 606 $recsth->execute($domid, 0, $fqdn, 33, $target, $prio, $weight, $port, $ttl, $loc) if $domid; 731 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 732 $recsth->execute($domid, 0, $fqdn, 33, $target, $prio, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive) if $domid; 607 733 } else { 608 734 push @deferred, $rec unless $nodefer; … … 621 747 622 748 my $fparent = $dnsdb->_hostparent($fqdn); 749 623 750 if ($fparent) { 624 $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc); 751 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n'); 752 $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 625 753 } else { 626 754 push @deferred, $rec unless $nodefer; … … 636 764 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 637 765 if ($rparent) { 638 $recsth->execute(0, $rparent, $txtstring, 16, "$msg", 0, 0, 0, $ttl, $loc); 766 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 767 $recsth->execute(0, $rparent, $txtstring, 16, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 639 768 } else { 640 769 push @deferred, $rec unless $nodefer; … … 644 773 my $domid = $dnsdb->_hostparent($fqdn); 645 774 if ($domid) { 646 $recsth->execute($domid, 0, $fqdn, 16, $txtstring, 0, 0, 0, $ttl, $loc); 775 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 776 $recsth->execute($domid, 0, $fqdn, 16, $txtstring, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 647 777 } else { 648 778 push @deferred, $rec unless $nodefer; … … 664 794 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 665 795 if ($rparent) { 666 $recsth->execute(0, $rparent, "$email $txtrec", 17, "$msg", 0, 0, 0, $ttl, $loc); 796 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 797 $recsth->execute(0, $rparent, "$email $txtrec", 17, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive ); 667 798 } else { 668 799 push @deferred, $rec unless $nodefer; … … 672 803 my $domid = $dnsdb->_hostparent($fqdn); 673 804 if ($domid) { 674 $recsth->execute($domid, 0, $fqdn, 17, "$email $txtrec", 0, 0, 0, $ttl, $loc); 805 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 806 $recsth->execute($domid, 0, $fqdn, 17, "$email $txtrec", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 675 807 } else { 676 808 push @deferred, $rec unless $nodefer; … … 688 820 my $domid = $dnsdb->_hostparent($fqdn); 689 821 if ($domid) { 690 $recsth->execute($domid, 0, $fqdn, 44, $sshfp, 0, 0, 0, $ttl, $loc); 822 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 823 $recsth->execute($domid, 0, $fqdn, 44, $sshfp, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 691 824 } else { 692 825 push @deferred, $rec unless $nodefer;
Note:
See TracChangeset
for help on using the changeset viewer.