Index: trunk/dns-rpc.cgi
===================================================================
--- trunk/dns-rpc.cgi	(revision 680)
+++ trunk/dns-rpc.cgi	(revision 681)
@@ -89,5 +89,5 @@
 	'dnsdb.updateRevSet'	=> \&updateRevSet,
 	'dnsdb.splitTemplate'	=> \&splitTemplate,
-#	'dnsdb.shrinkTemplate'	=> \&shrinkTemplate,
+	'dnsdb.resizeTemplate'	=> \&resizeTemplate,
 	'dnsdb.delRec'		=> \&delRec,
 	'dnsdb.delByCIDR'	=> \&delByCIDR,
@@ -683,4 +683,68 @@
 } # done splitTemplate()
 
+# Resize a template according to an old/new CIDR pair
+# Takes the old cidr in $args{oldcidr} and the new in $args{newcidr}
+sub resizeTemplate {
+  my %args = @_;
+
+  _commoncheck(\%args, 'y');
+
+  my $oldcidr = new NetAddr::IP $args{oldcidr};
+  my $newcidr = new NetAddr::IP $args{newcidr};
+  die "$oldcidr and $newcidr do not overlap"
+      unless $oldcidr->contains($newcidr) || $newcidr->contains($oldcidr);
+  $args{cidr} = $args{oldcidr};
+
+  my $up_res;
+
+  my $zonelist = $dnsdb->getZonesByCIDR(%args);
+  if (scalar(@$zonelist) == 0) {
+    # enhh....  WTF?
+
+  } elsif (scalar(@$zonelist) == 1) {
+    my $zone = new NetAddr::IP $zonelist->[0]->{revnet};
+    if ($zone->contains($oldcidr)) {
+      # Find record(s) matching the old and new CIDR
+
+      my $sql = q(
+          SELECT record_id,host,val
+          FROM records
+          WHERE rdns_id = ?
+              AND type IN (12, 65280, 65281, 65282, 65283, 65284)
+              AND (val = ? OR val = ?)
+          ORDER BY masklen(inetlazy(val)) ASC
+      );
+      my $sth = $dnsdb->{dbh}->prepare($sql);
+      $sth->execute($zonelist->[0]->{rdns_id}, "$oldcidr", "$newcidr");
+      my $upd_id;
+      my $oldhost;
+      while (my ($recid, $host, $val) = $sth->fetchrow_array) {
+        my $tcidr = NetAddr::IP->new($val);
+        if ($tcidr == $newcidr) {
+          # Match found for new CIDR.  Delete this record.
+          $up_res = $dnsdb->delRec('n', 'y', $recid);
+        } else {
+          # Update this record, then exit the loop
+          $up_res = rpc_updateRec(%args, val => $newcidr, id => $recid, defrec => 'n', revrec => 'y');
+          last;
+        }
+        # Your llama is on fire
+      }
+      $sth->finish;
+
+      return "Template record for $oldcidr changed to $newcidr.";
+
+    } else {  # $cidr > $zone but we only have one zone
+      # ebbeh?  CIDR is only partly represented in DNS.  This needs manual intervention.
+      return "Warning:  $args{cidr} is only partly represented in DNS.  Check and update DNS records manually.";
+    } # done single-zone-contains-$cidr
+
+  } else {
+    # multiple zones nominally "contain" $cidr
+  }
+
+  return $up_res;
+} # done resizeTemplate()
+
 sub delRec {
   my %args = @_;
