Changeset 543 for trunk/tiny-import.pl


Ignore:
Timestamp:
12/10/13 16:22:10 (10 years ago)
Author:
Kris Deugau
Message:

/trunk

Implement most of the UI and back end for handling scheduled changes
to records. See #40.

This turned out to be most of what I had vaguely imagined; only SOA
records can't sanely be set for scheduled changes yet (can't think of
a scenario where this would even be useful) and there's only a small
dusting of UI chrome left for another time.

Bumped up from projected 1.4 to 1.2 per request from Reid Sutherland.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tiny-import.pl

    r528 r543  
    2525use strict;
    2626use warnings;
     27use POSIX;
     28use Time::TAI64 qw(:tai);
    2729
    2830use lib '.';    ##uselib##
     
    125127  }
    126128
    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 (?,?,?,?,?,?,?,?,?,?,?,?,?)");
    129131
    130132  my %deleg;
     
    248250  }
    249251
     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  }
    250275
    251276  sub recslurp {
     
    274299      my $fparent = $dnsdb->_hostparent($host);
    275300      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
    276314      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);
    278316      } else {
    279317        if ($importcfg{legacy}) {
     
    282320          $rparent = 0 if !$rparent;
    283321          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);
    285323          } else {
    286324            # No parents found, cowardly refusing to add a dangling record
     
    290328        } elsif ($importcfg{conv}) {
    291329          # 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);
    293331          $converted++;
    294332        } else {
     
    310348      $loc = '' if !$loc;
    311349      $loc = '' if $loc =~ /^:+$/;
     350
     351      my $stampactive = 'n';
     352      my $expires = 'n';
     353
    312354      if ($host =~ /\.arpa$/) {
    313355        ($code,$msg) = DNSDB::_zone2cidr($host);
    314356        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        }
    316365
    317366##fixme:  automagically convert manually maintained sub-/24 delegations
     
    324373        my $fparent = $dnsdb->_hostparent($host);
    325374        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);
    327377        } else {
    328378          push @deferred, $rec unless $nodefer;
     
    344394      $loc = '' if !$loc;
    345395      $loc = '' if $loc =~ /^:+$/;
     396
     397      my $stampactive = 'n';
     398      my $expires = 'n';
     399
    346400      if ($zone =~ /\.arpa$/) {
    347401        ($code,$msg) = DNSDB::_zone2cidr($zone);
     
    352406#       if !$rparent;
    353407        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);
    355410        } else {
    356411          push @deferred, $rec unless $nodefer;
     
    360415        my $fparent = $dnsdb->_hostparent($zone);
    361416        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;
    364420        } else {
    365421          push @deferred, $rec unless $nodefer;
     
    378434      $loc = '' if !$loc;
    379435      $loc = '' if $loc =~ /^:+$/;
     436
     437      my $stampactive = 'n';
     438      my $expires = 'n';
     439
    380440      my $rparent;
    381441      if (my ($i, $z) = ($rip =~ /^(\d+)\.(\d+-(?:\d+\.){4}in-addr.arpa)$/) ) {
     
    392452      }
    393453      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);
    395456      } else {
    396457        push @deferred, $rec unless $nodefer;
     
    410471      $loc = '' if $loc =~ /^:+$/;
    411472
     473      my $stampactive = 'n';
     474      my $expires = 'n';
     475
    412476      my $domid = $dnsdb->_hostparent($host);
    413477      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);
    415480      } else {
    416481        push @deferred, $rec unless $nodefer;
     
    430495      $loc = '' if !$loc;
    431496      $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
    432514      if ($zone =~ /\.arpa$/) {
    433515        ($code,$msg) = DNSDB::_zone2cidr($zone);
     
    435517                undef, ($msg, $loc));
    436518        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);
    438524      } else {
    439525        $dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,1,1,?)",
    440526                undef, ($zone, $loc));
    441527        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);
    443533      }
    444534
     
    457547      $loc = '' if $loc =~ /^:+$/;
    458548
     549      my $stampactive = 'n';
     550      my $expires = 'n';
     551
    459552# note we don't check for reverse domains here, because MX records don't make any sense in reverse zones.
    460553# if this really ever becomes an issue for someone it can be expanded to handle those weirdos
     
    463556      my $domid = $dnsdb->_hostparent($zone);
    464557      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;
    467561      } else {
    468562        push @deferred, $rec unless $nodefer;
     
    482576      $loc = '' if $loc =~ /^:+$/;
    483577
     578      my $stampactive = 'n';
     579      my $expires = 'n';
     580
    484581      if ($fqdn =~ /\.arpa$/) {
    485582        ($code,$msg) = DNSDB::_zone2cidr($fqdn);
    486583        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);
    488586      } else {
    489587        my $domid = $dnsdb->_hostparent($fqdn);
    490588        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);
    492591        } else {
    493592          push @deferred, $rec unless $nodefer;
     
    508607      $loc = '' if !$loc;
    509608      $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');
    510624
    511625      if ($fqdn =~ /\.arpa$/) {
     
    517631                undef, ($msg, $loc));
    518632          ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')");
     633          ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, 0, 'y');
    519634# 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);
    523642##fixme:  (?)  implement full conversion of tinydns . records?
    524643# -> 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)
    526645# ...  auto-A-record simply does not make sense in reverse zones.  Functionally
    527646# I think it would work, sort of, but it's a nasty mess and anyone hosting reverse
     
    537656                undef, ($fqdn, $loc));
    538657          ($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;
    543665      }
    544666
     
    576698      $loc = '' if !$loc;
    577699      $loc = '' if $loc =~ /^:+$/;
     700
     701      my $stampactive = 'n';
     702      my $expires = 'n';
    578703
    579704      if ($type == 33) {
     
    604729        my $domid = $dnsdb->_hostparent($fqdn);
    605730        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;
    607733        } else {
    608734          push @deferred, $rec unless $nodefer;
     
    621747
    622748        my $fparent = $dnsdb->_hostparent($fqdn);
     749
    623750        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);
    625753        } else {
    626754          push @deferred, $rec unless $nodefer;
     
    636764          my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg));
    637765          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);
    639768          } else {
    640769            push @deferred, $rec unless $nodefer;
     
    644773          my $domid = $dnsdb->_hostparent($fqdn);
    645774          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);
    647777          } else {
    648778            push @deferred, $rec unless $nodefer;
     
    664794          my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg));
    665795          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 );
    667798          } else {
    668799            push @deferred, $rec unless $nodefer;
     
    672803          my $domid = $dnsdb->_hostparent($fqdn);
    673804          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);
    675807          } else {
    676808            push @deferred, $rec unless $nodefer;
     
    688820        my $domid = $dnsdb->_hostparent($fqdn);
    689821        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);
    691824        } else {
    692825          push @deferred, $rec unless $nodefer;
Note: See TracChangeset for help on using the changeset viewer.