Ignore:
Timestamp:
01/02/14 13:26:38 (10 years ago)
Author:
Kris Deugau
Message:

/branches/stable

Merge forward bugfixes and option additions from /trunk r570 through r581

Location:
branches/stable
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/stable

  • branches/stable/tiny-import.pl

    r548 r582  
    3939        conv    => 0,
    4040        trial   => 0,
    41         legacy  => 0,
     41        legacy  => 0,
     42        merge   => 0,
     43        group   => 1,
    4244        );
     45my $gnum = '';
    4346# Handle some command-line arguments
    4447while ($ARGV[0] =~ /^-/) {
    4548  my $arg = shift @ARGV;
    46   usage() if $arg !~ /^-[rclt]+$/;
     49  usage() if $arg !~ /^-(?:[rclmt]+|g\d*)$/;
    4750  # -r  rewrite imported files to comment imported records
    4851  # -c  coerce/downconvert A+PTR = records to PTR
    4952  # -l  swallow A+PTR as-is
     53  # -m  merge PTR and A/AAAA as possible
    5054  # -t  trial mode;  don't commit to DB or actually rewrite flatfile (disables -r)
     55  # -g  import to specified group (name or ID) instead of group 1
    5156  $arg =~ s/^-//;
    52   my @tmp = split //, $arg;
    53   foreach (@tmp) {
    54     $importcfg{rw} = 1 if $_ eq 'r';
    55     $importcfg{conv} = 1 if $_ eq 'c';
    56     $importcfg{legacy} = 1 if $_ eq 'l';
    57     $importcfg{trial} = 1 if $_ eq 't';
    58   }
     57# for Reasons (none clear), $arg is undefined yet defined, but only when number characters are involved.  Ebbeh?
     58no warnings qw(uninitialized);
     59  if ($arg =~ /^g/) {
     60    if ($arg eq 'g') {
     61      $importcfg{group} = shift @ARGV;
     62    } else {
     63      $arg =~ s/^g//;
     64      $importcfg{group} = $arg;
     65    }
     66  } else {
     67    my @tmp = split //, $arg;
     68    foreach (@tmp) {
     69      $importcfg{rw} = 1 if $_ eq 'r';
     70      $importcfg{conv} = 1 if $_ eq 'c';
     71      $importcfg{legacy} = 1 if $_ eq 'l';
     72      $importcfg{merge} = 1 if $_ eq 'm';
     73      $importcfg{trial} = 1 if $_ eq 't';
     74    }
     75  }
     76  use warnings qw(uninitialized);
    5977}
    6078$importcfg{rw} = 0 if $importcfg{trial};
    6179
     80# allow group names
     81if ($importcfg{group} =~ /^\d+$/) {
     82  $importcfg{groupname} = $dnsdb->groupName($importcfg{group});
     83} else {
     84  $importcfg{groupname} = $importcfg{group};
     85  $importcfg{group} = $dnsdb->groupID($importcfg{groupname});
     86}
     87
     88die usage() if $importcfg{group} !~ /^\d+$/;
     89
    6290sub usage {
    63   die q(usage:  tiny-import.pl [-r] [-c] datafile1 datafile2 ... datafileN ...
     91  die q(usage:  tiny-import.pl [-rclt] [-gnn] [-g name] datafile1 datafile2 ... datafileN ...
    6492        -r  Rewrite all specified data files with a warning header indicating the
    6593            records are now managed by web, and commenting out all imported records.
     
    72100        -l  (for "legacy")  Force import of A+PTR records as-is.  Mutually exclusive
    73101            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
     103        -gnnn or -g nnn or -g name
     104            Import new zones into this group (group name or ID accepted) instead of
     105            the root/default group 1
    74106        -t  Trial run mode;  spits out records that would be left unimported.
    75107            Disables -r if set.
     
    83115my $code;
    84116my $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};
    85123
    86124$dbh->{AutoCommit} = 0;
     
    129167  our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location,stamp,expires,stampactive) ".
    130168        " 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=?");
    131176
    132177  my %deleg;
     
    451496        ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ("$msg"));
    452497      }
     498
    453499      if ($rparent) {
    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);
     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        }
    456516      } else {
    457517        push @deferred, $rec unless $nodefer;
     
    476536      my $domid = $dnsdb->_hostparent($host);
    477537      if ($domid) {
    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);
     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        }
    480553      } else {
    481554        push @deferred, $rec unless $nodefer;
     
    514587      if ($zone =~ /\.arpa$/) {
    515588        ($code,$msg) = DNSDB::_zone2cidr($zone);
    516         $dbh->do("INSERT INTO revzones (revnet,group_id,status,default_location) VALUES (?,1,1,?)",
    517                 undef, ($msg, $loc));
     589        $dbh->do("INSERT INTO revzones (revnet,group_id,status,default_location) VALUES (?,?,1,?)",
     590                undef, ($msg, $importcfg{group}, $loc));
    518591        my ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')");
    519592        my $newttl;
     
    523596                $loc, $stamp, $expires, $stampactive);
    524597      } else {
    525         $dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,1,1,?)",
    526                 undef, ($zone, $loc));
     598        $dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,?,1,?)",
     599                undef, ($zone, $importcfg{group}, $loc));
    527600        my ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')");
    528601        my $newttl;
     
    748821        my $fparent = $dnsdb->_hostparent($fqdn);
    749822
    750         if ($fparent) {
    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);
    753         } else {
    754           push @deferred, $rec unless $nodefer;
    755           $impok = 0;
    756         }
     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        }
    757847
    758848      } elsif ($type == 16) {
Note: See TracChangeset for help on using the changeset viewer.