Changeset 579


Ignore:
Timestamp:
01/02/14 10:11:12 (10 years ago)
Author:
Kris Deugau
Message:

/trunk

Add another option to tiny-import.pl to merge matching PTR and A or AAAA
records.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tiny-import.pl

    r575 r579  
    4040        trial   => 0,
    4141        legacy  => 0,
     42        merge   => 0,
    4243        group   => 1,
    4344        );
     
    4647while ($ARGV[0] =~ /^-/) {
    4748  my $arg = shift @ARGV;
    48   usage() if $arg !~ /^-(?:[rclt]+|g\d*)$/;
     49  usage() if $arg !~ /^-(?:[rclmt]+|g\d*)$/;
    4950  # -r  rewrite imported files to comment imported records
    5051  # -c  coerce/downconvert A+PTR = records to PTR
    5152  # -l  swallow A+PTR as-is
     53  # -m  merge PTR and A/AAAA as possible
    5254  # -t  trial mode;  don't commit to DB or actually rewrite flatfile (disables -r)
    5355  # -g  import to specified group (name or ID) instead of group 1
     
    6870      $importcfg{conv} = 1 if $_ eq 'c';
    6971      $importcfg{legacy} = 1 if $_ eq 'l';
     72      $importcfg{merge} = 1 if $_ eq 'm';
    7073      $importcfg{trial} = 1 if $_ eq 't';
    7174    }
     
    97100        -l  (for "legacy")  Force import of A+PTR records as-is.  Mutually exclusive
    98101            with -c.  -l takes precedence as -c is lossy.
     102        -m  Merge PTR and A or AAAA records to A+PTR or AAAA+PTR records where possible
    99103        -gnnn or -g nnn or -g name
    100104            Import new zones into this group (group name or ID accepted) instead of
     
    111115my $code;
    112116my $dbh = $dnsdb->{dbh};
     117
     118# collect some things for logging
     119($dnsdb->{logusername}, undef, undef, undef, undef, undef, $dnsdb->{logfullname}) = getpwuid($<);
     120$dnsdb->{loguserid} = 0;        # not worth setting up a pseudouser the way the RPC system does
     121$dnsdb->{logusername} = $dnsdb->{logusername}."/tiny-import.pl";
     122$dnsdb->{logfullname} = $dnsdb->{logusername} if !$dnsdb->{logfullname};
    113123
    114124$dbh->{AutoCommit} = 0;
     
    157167  our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location,stamp,expires,stampactive) ".
    158168        " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");
     169
     170  # for A/AAAA records
     171  our $revcheck = $dbh->prepare("SELECT rdns_id,record_id,ttl FROM records WHERE host=? AND val=? AND type=12");
     172  our $mergefwd = $dbh->prepare("UPDATE records SET type=?,domain_id=?,ttl=? WHERE record_id=?");
     173  # for PTR records
     174  our $fwdcheck = $dbh->prepare("SELECT domain_id,record_id,ttl FROM records WHERE host=? AND val=? AND (type=1 OR type=28)");
     175  our $mergerev = $dbh->prepare("UPDATE records SET type=?,rdns_id=?,ttl=? WHERE record_id=?");
    159176
    160177  my %deleg;
     
    479496        ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ("$msg"));
    480497      }
     498
    481499      if ($rparent) {
    482         ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
    483         $recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
     500##fixme:  really want to pull this DB call inside an if $importcfg{merge},
     501# but then we need to duplicate the insert for the case where the matching
     502# reverse doesn't exist.
     503        $host =~ s/\.$//g;   # pure sytactic sugar, we don't store this trailing dot.
     504        $fwdcheck->execute($host, $msg->addr);
     505        my ($domid, $recid, $rttl) = $fwdcheck->fetchrow_array;
     506        if ($importcfg{merge} && $domid) {
     507          $ttl = ($rttl < $ttl ? $rttl : $ttl);        # Take the shorter TTL
     508          $mergerev->execute(($msg->{isv6} ? 65281 : 65280), $rparent, $ttl, $recid);
     509          $dnsdb->_log(rdns_id => $rparent, domain_id => $domid, group_id => $importcfg{group},
     510            entry => "[ import ] PTR ".$msg->addr." -> $host merged with matching ".
     511                  ($msg->{isv6} ? 'AAAA' : 'A')." record");
     512        } else {
     513          ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
     514          $recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
     515        }
    484516      } else {
    485517        push @deferred, $rec unless $nodefer;
     
    504536      my $domid = $dnsdb->_hostparent($host);
    505537      if ($domid) {
    506         ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
    507         $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
     538##fixme:  really want to pull this DB call inside an if $importcfg{merge},
     539# but then we need to duplicate the insert for the case where the matching
     540# reverse doesn't exist.
     541        $revcheck->execute($host, $ip);
     542        my ($revid, $recid, $rttl) = $revcheck->fetchrow_array;
     543        if ($importcfg{merge} && $revid) {
     544          $ttl = ($rttl < $ttl ? $rttl : $ttl); # Take the shorter TTL
     545          $mergefwd->execute(65280, $domid, $ttl, $recid);
     546          $dnsdb->_log(rdns_id => $revid, domain_id => $domid, group_id => $importcfg{group},
     547            entry => "[ import ] ".($msg->{isv6} ? 'AAAA' : 'A')." record $host -> $ip".
     548                  " merged with matching PTR record");
     549        } else {
     550          ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
     551          $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
     552        }
    508553      } else {
    509554        push @deferred, $rec unless $nodefer;
     
    776821        my $fparent = $dnsdb->_hostparent($fqdn);
    777822
    778         if ($fparent) {
    779           ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n');
    780           $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
    781         } else {
    782           push @deferred, $rec unless $nodefer;
    783           $impok = 0;
    784         }
     823##fixme:  really want to pull this DB call inside an if $importcfg{merge},
     824# but then we need to duplicate the insert for the case where the matching
     825# reverse doesn't exist.
     826        $revcheck->execute($fqdn, $val);
     827        my ($revid, $recid, $rttl) = $revcheck->fetchrow_array;
     828
     829        # If we have a revzone and merging is enabled, update the existing
     830        # record with a reverse ID, set the type to one of the internal
     831        # pseudotypes, and set the TTL to the lower of the two.
     832        if ($importcfg{merge} && $revid) {
     833          $ttl = ($rttl < $ttl ? $rttl : $ttl); # Take the shorter TTL
     834          $mergefwd->execute(65281, $fparent, $ttl, $recid);
     835          $dnsdb->_log(rdns_id => $revid, domain_id => $fparent, group_id => $importcfg{group},
     836            entry => "[ import ] ".($msg->{isv6} ? 'AAAA' : 'A')." record $fqdn -> $val".
     837                  " merged with matching PTR record");
     838        } else {
     839          if ($fparent) {
     840            ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n');
     841            $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
     842          } else {
     843            push @deferred, $rec unless $nodefer;
     844            $impok = 0;
     845          }
     846        }
    785847
    786848      } elsif ($type == 16) {
Note: See TracChangeset for help on using the changeset viewer.