Changeset 680 for trunk


Ignore:
Timestamp:
02/27/15 18:09:45 (9 years ago)
Author:
Kris Deugau
Message:

/trunk

  • Add new RPC sub "splitTemplate" so IPDB doesn't have to make many round trips retrieving and setting data when splitting an allocation. This non-transactionally takes a CIDR to look up, and splits the template record (if any) according to a new netmask by way of one update and 1 or more adds.
  • Fine-tune some argument munging in rpc_updateRec() in case the caller *does* have a clue and sets certain fields directly; we don't want to overwrite these with nothing...
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/dns-rpc.cgi

    r678 r680  
    8888        'dnsdb.addOrUpdateRevRec'       => \&addOrUpdateRevRec,
    8989        'dnsdb.updateRevSet'    => \&updateRevSet,
     90        'dnsdb.splitTemplate'   => \&splitTemplate,
     91#       'dnsdb.shrinkTemplate'  => \&shrinkTemplate,
    9092        'dnsdb.delRec'          => \&delRec,
    9193        'dnsdb.delByCIDR'       => \&delByCIDR,
     
    502504
    503505  # put some caller-friendly names in their rightful DB column places
    504   $args{val} = $args{address};
    505   $args{host} = $args{name};
     506  $args{val} = $args{address} if !$args{val};
     507  $args{host} = $args{name} if !$args{host};
    506508
    507509  # get old line, so we can update only the bits that the caller passed to change
     
    525527  die "$msg\n" if $code eq 'FAIL';
    526528  return $msg;
    527 }
     529} # rpc_updateRec
    528530
    529531# Takes a passed CIDR block and DNS pattern;  adds a new record or updates the record(s) affected
     
    618620} # done updateRevSet()
    619621
     622# Split a template record as per a passed CIDR.
     623# Requires the CIDR and the new mask length
     624sub splitTemplate {
     625  my %args = @_;
     626
     627  _commoncheck(\%args, 'y');
     628
     629  my $cidr = new NetAddr::IP $args{cidr};
     630
     631  my $zonelist = $dnsdb->getZonesByCIDR(%args);
     632
     633  if (scalar(@$zonelist) == 0) {
     634    # enhh....  WTF?
     635
     636  } elsif (scalar(@$zonelist) == 1) {
     637    my $zone = new NetAddr::IP $zonelist->[0]->{revnet};
     638    if ($zone->contains($cidr)) {
     639      # Find the first record in the reverse zone that matches the CIDR we're splitting...
     640      my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y',
     641        id => $zonelist->[0]->{rdns_id}, filter => $cidr, sortby => 'val', sortorder => 'DESC');
     642      my $oldrec;
     643      foreach my $rec (@$reclist) {
     644        my $reccidr = new NetAddr::IP $rec->{val};
     645        next unless $cidr->contains($reccidr);  # not sure this is needed here
     646        # ... and is a reverse-template type.
     647        # Could arguably trim the list below to just 65282, 65283, 65284
     648        next unless $rec->{type} == 12 || $rec->{type} == 65280 || $rec->{type} == 65281 ||
     649            $rec->{type} == 65282 || $rec->{type} == 65283 ||$rec->{type} == 65284;
     650        # snag old record so we can copy its data
     651        $oldrec = $dnsdb->getRecLine('n', 'y', $rec->{record_id});
     652        last;  # we've found one record that meets our criteria;  Extras Are Irrelevant
     653      }
     654
     655      my @newblocks = $cidr->split($args{newmask});
     656      # Change the existing record with the new CIDR
     657      my $up_res = rpc_updateRec(%args, val => $newblocks[0], id => $oldrec->{record_id}, defrec => 'n', revrec => 'y');
     658      my @ret;
     659      # the update is assumed to have succeeded if it didn't fail.
     660##fixme:  find a way to save and return "warning" states?
     661      push @ret, {block => "$newblocks[0]", code => "OK", msg => $up_res};
     662      # And now add new record(s) for each of the new CIDR entries, reusing the old data
     663      for (my $i = 1; $i <= $#newblocks; $i++) {
     664        my $newval = "$newblocks[$i]";
     665        my @recargs = ('n', 'y', $oldrec->{rdns_id}, \$oldrec->{host}, \$oldrec->{type}, \$newval,
     666          $oldrec->{ttl}, $oldrec->{location}, 0, '');
     667        my ($code, $msg) = $dnsdb->addRec(@recargs);
     668        # Note failures here are not fatal;  this should typically only ever be called by IPDB
     669        push @ret, {block => "$newblocks[$i]", code => $code, msg => $up_res};
     670      }
     671      # return an info hash in case of warnings doing the update or add(s)
     672      return \@ret;
     673
     674    } else {  # $cidr > $zone but we only have one zone
     675      # ebbeh?  CIDR is only partly represented in DNS.  This needs manual intervention.
     676      return "Warning:  $args{cidr} is only partly represented in DNS.  Check and update DNS records manually.";
     677    } # done single-zone-contains-$cidr
     678
     679  } else {
     680    # multiple zones nominally "contain" $cidr
     681  } # done $cidr-contains-zones
     682
     683} # done splitTemplate()
     684
    620685sub delRec {
    621686  my %args = @_;
Note: See TracChangeset for help on using the changeset viewer.