Changeset 818


Ignore:
Timestamp:
12/03/20 13:53:22 (3 years ago)
Author:
Kris Deugau
Message:

/trunk

Eleventh sampled iteration of bind-import

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/bind-import

    r817 r818  
    11#!/usr/bin/perl
    22# Import a BIND zone file
     3# Note we are not using Net:DNS::ZoneFile, because we want to convert $GENERATE
     4# directives straight into PTR template or A+PTR template metarecords
    35##
    46# Copyright 2020 Kris Deugau <kdeugau@deepnet.cx>
     
    5759  $zid = $dnsdb->revID($zname,':ANY:');
    5860  if ($zid) {
    59     die "zone $origzone already present, not merging records\n";
     61#    die "zone $origzone already present, not merging records\n";
    6062#$zname = new NetAddr::IP $zname;
    6163#    $zname = DNSDB::_ZONE($zname, 'ZONE', 'r', '.').($zname->{isv6} ? '.ip6.arpa' : '.in-addr.arpa');
    6264  }
    63   $zid = $dnsdb->{dbh}->do("INSERT INTO revzones (revnet,group_id,status,default_location,zserial) VALUES (?,?,?,?,?) RETURNING rnds_id",
    64                 undef, ($zname, $group, $status, $location, $serial));
     65#  $zid = $dnsdb->{dbh}->do("INSERT INTO revzones (revnet,group_id,status,default_location,zserial) VALUES (?,?,?,?,?) RETURNING rnds_id",
     66#                undef, ($zname, $group, $status, $location, $serial));
    6567
    6668} else {
    6769  $zid = $dnsdb->domainID($zname,':ANY:');
    6870  if ($zid) {
    69     die "zone $origzone already present, not merging records\n";
    70   }
    71   $zid = $dnsdb->{dbh}->do("INSERT INTO domains (domain,group_id,status,default_location,zserial) VALUES (?,?,?,?,?) RETURNING domain_id",
    72                 undef, ($zname, $group, $status, $location, $serial));
     71#    die "zone $origzone already present, not merging records\n";
     72  }
     73#  $zid = $dnsdb->{dbh}->do("INSERT INTO domains (domain,group_id,status,default_location,zserial) VALUES (?,?,?,?,?) RETURNING domain_id",
     74#                undef, ($zname, $group, $status, $location, $serial));
    7375}
    7476
     
    8587my $defttl = $zonettl;
    8688my $origin = "$zname."; # to append to unqualified names
     89my %foundtypes;
    8790
    8891# need to spin up a full state machine-ish thing, because BIND zone files are all about context
     
    100103                                # arguably should do some more targeted voodoo when parsing the SOA details
    101104
     105##fixme:  use external skiplist
    102106  # skip stale records that have no value
    103107  next if /^ip-192-168-1(12|20)-\d+/;
    104108  next if /ip.add.re.\d+\s*$/;
    105109
    106 #last if ++$i > 4;
    107 print "($rec)\n";
     110$i++;
     111#last if $i > 4;
     112#print "line $i: ($rec)\n";
    108113  if (my ($macro,$mdetail) = ($rec =~ /^\s*\$(TTL|ORIGIN|INCLUDE|GENERATE)\s+(.+)/) ) {
    109114    # macro sort of thing;  $TTL and $ORIGIN most common.  $INCLUDE is a thing, expect it to be rare in live use tho
     
    138143
    139144    }
     145    elsif ($macro eq 'GENERATE') {
     146# needs to generate CIDR range(s) as needed to match the start/stop points
     147    }
    140148    # not handling $INCLUDE or $GENERATE (altho the latter seems to be mostly a less-flexible version of the template types)
    141149    next;
     
    159167  # append $ORIGIN if name is not fully qualified.
    160168  if ($curlabel !~ /\.$/) {
    161     $curlabel .= ".$origin";
     169    $curlabel .= ($origin eq '.' ? '.' : ".$origin");
    162170  }
    163171print "  expanded '$curlabel'\n";
    164172
     173# hack pthbptt
     174#$curlabel =~ s/\.\.$/./;
    165175  # check for zone scope.  skip bad records.
    166176  if ($curlabel !~ /$zname.$/) {
     
    192202#  }
    193203
    194 print "$i ($rec)\n";#\t$curlabel";
     204#print "$i ($rec)\n";#\t$curlabel";
    195205
    196206
     
    211221  my $nc = 0;
    212222  my $class = 'IN';
     223  my $type;
    213224  my $ttl;
    214   my $type;
     225  my $distance;
     226  my $weight;
     227  my $port;
    215228  my $badrec;
    216229  my $curatom = 'class';
     
    269282  }
    270283
     284##todo:  BIND conflates a repeated label with repeating the TTL too.  Matter of opinion whether that's really correct or not.
    271285  # set default TTL here so we can detect a TTL in the loop above
    272286  $ttl = $defttl if !defined($ttl);
     
    278292#$curlabel = $name;
    279293$prevlabel = $curlabel;
    280 ##todo:  BIND conflates a repeated label with repeating the TTL too.  Matter of opinion whether that's really correct or not.
    281294
    282295
     
    335348  #$ORIGIN example.invalid.
    336349  #foo                     A       192.168.16.45
     350$foundtypes{$type}++;
     351
     352##fixme:  strip trailing . here?  dnsadmin's normalized internal format omits it, some validation fails or may go funky
    337353
    338354  if ($type eq 'SOA') {
     
    366382      }
    367383    }
     384#  $dnsdb->{dbh}->do("UPDATE [zonetable] SET serial = ? WHERE [idfield] = ?");
     385#  $dnsdb->{dbh}->do("INSERT INTO records () VALUES ()");
     386#  next;
     387#Zfqdn:mname:rname:ser:ref:ret:exp:min:ttl:timestamp:lo
     388#print "Z$zname:$ns:$adminmail:$soabits[0]:$soabits[1]:$soabits[2]:$soabits[3]:$soabits[4]:$ttl\n";
    368389  } # SOA
    369390
    370   # Quotes may arguably be syntactically required, but they're not actually part of the record data
     391
     392  # we're using DNSDB::addrec(), so we'll skip detailed validation of other records.  Most won't need further breakdown
     393
     394  elsif ($type eq 'A') {
     395#print "+$curlabel:$rdata:$ttl\n";
     396  }
     397
     398  elsif ($type eq 'NS') {
     399#print "\&$curlabel::$rdata:$ttl\n";
     400  }
     401
     402  elsif ($type eq 'CNAME') {
     403#print "C$curlabel:$rdata:$ttl\n";
     404  }
     405
     406  elsif ($type eq 'PTR') {
     407  }
     408
     409  elsif ($type eq 'MX') {
     410    ($distance) = ($rdata =~ /^(\d+)\s+/);
     411    if (!defined($distance)) {
     412      warn "malformed MX record: $origrec, skipping\n";
     413      next;
     414    }
     415    $rdata =~ s/^\d+\s+//;
     416  }
     417
    371418  elsif ($type eq 'TXT') {
     419    # Quotes may arguably be syntactically required, but they're not actually part of the record data
    372420    $rdata =~ s/^"//;
    373421    $rdata =~ s/"$//;
    374   }
    375 
    376 # temp hack for hosts file
    377 elsif ($type eq 'A') {
    378 #  if ($amap{$name}) {
    379 #    print "urp:  dupe name $name $rdata\n";
    380 #  } else {
    381     push @{$amap{$curlabel}}, $rdata;
    382 #  }
    383   push @{$namemap{$rdata}}, $curlabel;
    384 }
    385 elsif ($type eq 'CNAME') {
    386   push @{$cmap{$rdata}}, $curlabel;
    387 }
     422#print "'$curlabel:$rdata:$ttl\n";
     423  }
     424
     425  elsif ($type eq 'RP') {
     426  }
     427
     428  elsif ($type eq 'AAAA') {
     429  }
     430
     431  elsif ($type eq 'SRV') {
     432    ($distance, $weight, $port) = ($rdata =~ /^(\d+)\s+(\d+)\s+(\d+)\s+/);
     433    if ( !defined($distance) || !defined($weight) || !defined($port) ) {
     434      warn "malformed SRV record: $origrec, skipping\n";
     435      next;
     436    }
     437    $rdata =~ s/^\d+\s+\d+\s+\d+\s+//;
     438  }
     439
     440  # basically a dedicated clone of TXT, not sure anything actually looks up type SPF.
     441  # BIND autogenerates them from SPF TXT records.
     442  elsif ($type eq 'SPF') {
     443    # Quotes may arguably be syntactically required, but they're not actually part of the record data
     444    $rdata =~ s/^"//;
     445    $rdata =~ s/"$//;
     446  }
     447
     448#  elsif ($type eq 'TXT') {
     449#  elsif ($type eq 'TXT') {
     450
     451  else {
     452    warn "unsupported type $type, may not import correctly\n";
     453  }
    388454
    389455no warnings qw(uninitialized);
    390 #print "parsed: '$name' '$class' '$ttl' '$type'->'$itype' '$rdata'\n";
     456#print "parsed: '$curlabel' '$class' '$ttl' '$type'->'$itype' '$rdata'\n";
    391457#print;
    392458#;imap   IN      900     CNAME   deepnet.cx.
     
    395461    my ($code, $msg);
    396462    if ($rev eq 'n') {
    397       ($code,$msg) = $dnsdb->addRec('n', $rev, $zid, \$curlabel, \$itype, \$rdata, $ttl);
     463      ($code,$msg) = $dnsdb->addRec('n', $rev, $zid, \$curlabel, \$itype, \$rdata, $ttl,
     464        $location, undef, undef, $distance, $weight, $port);
    398465    } else {
    399       ($code,$msg) = $dnsdb->addRec('n', $rev, $zid, \$rdata, \$itype, \$curlabel, $ttl);
     466      ($code,$msg) = $dnsdb->addRec('y', $rev, $zid, \$rdata, \$itype, \$curlabel, $ttl,
     467        $location, undef, undef, $distance, $weight, $port);
    400468    }
    401469    print "$code: $msg\n";
     
    409477#print Dumper \%cmap;
    410478
    411 foreach my $n (keys %amap) {
    412   foreach my $ip (@{$amap{$n}}) {
    413 #print "$ip     $n\n";
    414     push @{$namemap{$ip}}, $n unless grep $n, @{$namemap{$ip}};
    415   }
    416 }
    417 
    418 foreach my $c (keys %cmap) {
    419   if ($amap{$c}) {
    420     print Dumper(\@{$amap{$c}});
    421   }
    422 #  print $amap{$c};
    423 }
     479#foreach my $n (keys %amap) {
     480#  foreach my $ip (@{$amap{$n}}) {
     481##print "$ip    $n\n";
     482#    push @{$namemap{$ip}}, $n unless grep $n, @{$namemap{$ip}};
     483#  }
     484#}
     485
     486#foreach my $c (keys %cmap) {
     487#  if ($amap{$c}) {
     488#    print Dumper(\@{$amap{$c}});
     489#  }
     490##  print $amap{$c};
     491#}
    424492
    425493# cname targ -> IP
     
    430498
    431499$dnsdb->{dbh}->rollback;
     500
     501foreach my $t (keys %foundtypes) {
     502  print "found $t: $foundtypes{$t}\n";
     503}
Note: See TracChangeset for help on using the changeset viewer.