Index: trunk/cgi-bin/IPDB.pm
===================================================================
--- trunk/cgi-bin/IPDB.pm	(revision 582)
+++ trunk/cgi-bin/IPDB.pm	(revision 585)
@@ -25,5 +25,5 @@
 @EXPORT_OK    = qw(
 	%disp_alloctypes %list_alloctypes %def_custids @citylist @poplist
-	%IPDBacl %aclmsg
+	%IPDBacl %aclmsg $errstr
 	&initIPDBGlobals &connectDB &finish &checkDBSanity
 	&addMaster &touchMaster
@@ -31,5 +31,5 @@
 	&getMasterList &getTypeList &getPoolSelect &findAllocateFrom
 	&ipParent &subParent &blockParent &getRoutedCity
-	&allocateBlock &updateBlock &deleteBlock &getBlockData
+	&allocateBlock &updateBlock &deleteBlock &getBlockData &getBlockRDNS
 	&getNodeList &getNodeName &getNodeInfo
 	&mailNotify
@@ -39,5 +39,5 @@
 %EXPORT_TAGS	= ( ALL => [qw(
 		%disp_alloctypes %list_alloctypes %def_custids @citylist @poplist
-		%IPDBacl %aclmsg
+		%IPDBacl %aclmsg $errstr
 		&initIPDBGlobals &connectDB &finish &checkDBSanity
 		&addMaster &touchMaster
@@ -45,5 +45,5 @@
 		&getMasterList &getTypeList &getPoolSelect &findAllocateFrom
 		&ipParent &subParent &blockParent &getRoutedCity
-		&allocateBlock &updateBlock &deleteBlock &getBlockData
+		&allocateBlock &updateBlock &deleteBlock &getBlockData &getBlockRDNS
 		&getNodeList &getNodeName &getNodeInfo
 		&mailNotify
@@ -68,4 +68,7 @@
 	delblock	=> 'delete an allocation',
 	);
+
+# error reporting
+our $errstr = '';
 
 our $org_name = 'Example Corp';
@@ -89,4 +92,40 @@
 
 our $rpc_url = '';
+our $revgroup = 1;	# should probably be configurable somewhere
+our $rpccount = 0;
+
+##
+## Internal utility functions
+##
+
+## IPDB::_rpc
+# Make an RPC call for DNS changes
+sub _rpc {
+  return if !$rpc_url;	# Just In Case
+  my $rpcsub = shift;
+  my %args = @_;
+
+  # Make an object to represent the XML-RPC server.
+  my $server = Frontier::Client->new(url => $rpc_url, debug => 0);
+  my $result;
+
+  my %rpcargs = (
+	rpcsystem => 'ipdb',
+	rpcuser => $args{user},
+	);
+
+  eval {
+    $result = $server->call("dnsdb.$rpcsub", %rpcargs, %args);
+  };
+  if ($@) {
+    $errstr = $@;
+    $errstr =~ s/Fault returned from XML RPC Server, fault code 4: error executing RPC `dnsdb.$rpcsub'\.\s//;
+print "error!  $errstr\n";
+  }
+  $rpccount++;
+
+  return $result if $result;
+} # end _rpc()
+
 
 # Let's initialize the globals.
@@ -316,7 +355,4 @@
     # Only attempt rDNS if the IPDB side succeeded
     if ($rpc_url) {
-      # Make an object to represent the XML-RPC server.
-      my $server = Frontier::Client->new(url => $rpc_url, debug => 0);
-      my $result;
 
 # Note *not* splitting reverse zones negates any benefit from caching the exported data.
@@ -339,18 +375,12 @@
         my %rpcargs = (
           rpcuser => $args{user},
-          rpcsystem => 'ipdb',
           revzone => "$subzone",
           revpatt => $args{rdns},
           defloc => $args{defloc},
-          group => 1,	# not sure how these two could sanely be exposed, tbh...
+          group => $revgroup,	# not sure how these two could sanely be exposed, tbh...
           state => 1,	# could make them globally configurable maybe
         );
-        eval {
-          $result = $server->call('dnsdb.addRDNS', %rpcargs);
-        };
-        if ($@) {
-          my $msg = $@;
-          $msg =~ s/Fault returned from XML RPC Server, fault code 4: error executing RPC `dnsdb.addRDNS'\.\s//;
-          push @fails, ("$subzone" => $msg);
+        if (!_rpc('addRDNS', %rpcargs)) {
+          push @fails, ("$subzone" => $errstr);
         }
       }
@@ -815,4 +845,5 @@
   $args{privdata} = '' if !$args{privdata};
   $args{vrf} = '' if !$args{vrf};
+  $args{rdns} = '' if !$args{rdns};
 
   my $sth;
@@ -843,7 +874,7 @@
 		undef, ($args{alloc_from}) );
       }
-      $dbh->do("UPDATE poolips SET custid=?,city=?,available='n',description=?,notes=?,circuitid=?,privdata=?,vrf=? ".
+      $dbh->do("UPDATE poolips SET custid=?,city=?,available='n',description=?,notes=?,circuitid=?,privdata=?,vrf=?,rdns=? ".
 	"WHERE ip=?", undef, ($args{custid}, $args{city}, $args{desc}, $args{notes}, $args{circid},
-		$args{privdata}, $args{vrf}, $args{cidr}) );
+		$args{privdata}, $args{vrf}, $args{rdns}, $args{cidr}) );
 
 # node hack
@@ -860,4 +891,5 @@
       return ('FAIL', $msg);
     } else {
+      _rpc('addOrUpdateRevRec', cidr => "$args{cidr}", name => $args{rdns}, rpcuser => $args{user});
       return ('OK', $args{cidr});
     }
@@ -891,8 +923,8 @@
 	# Insert the allocations entry
 	$dbh->do("INSERT INTO allocations ".
-		"(cidr,parent,vrf,rdepth,custid,type,city,description,notes,circuitid,privdata)".
-		" VALUES (?,?,?,?,?,?,?,?,?,?,?)", undef,
+		"(cidr,parent,vrf,rdepth,custid,type,city,description,notes,circuitid,privdata,rdns)".
+		" VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", undef,
 		($args{cidr}, $fparent, $args{vrf}, $args{rdepth}, $args{custid}, $args{type}, $args{city},
-		$args{desc}, $args{notes}, $args{circid}, $args{privdata}) );
+		$args{desc}, $args{notes}, $args{circid}, $args{privdata}, $args{rdns}) );
 
 	# And initialize the pool, if necessary
@@ -921,6 +953,4 @@
 	eval { $dbh->rollback; };
 	return ('FAIL',$msg);
-      } else {
-	return ('OK',"OK");
       }
 
@@ -969,8 +999,8 @@
 	# Insert the allocations entry
 	$dbh->do("INSERT INTO allocations ".
-		"(cidr,parent,vrf,rdepth,custid,type,city,description,notes,circuitid,privdata)".
-		" VALUES (?,?,?,?,?,?,?,?,?,?,?)", undef,
+		"(cidr,parent,vrf,rdepth,custid,type,city,description,notes,circuitid,privdata,rdns)".
+		" VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", undef,
 		($args{cidr}, $fparent, $args{vrf}, $args{rdepth}, $args{custid}, $args{type}, $args{city},
-		$args{desc}, $args{notes}, $args{circid}, $args{privdata}) );
+		$args{desc}, $args{notes}, $args{circid}, $args{privdata}, $args{rdns}) );
 
 	# And initialize the pool, if necessary
@@ -999,9 +1029,13 @@
 	eval { $dbh->rollback; };
 	return ('FAIL',$msg);
-      } else {
-	return ('OK',"OK");
       }
 
     } # end fullcidr != alloc_from
+
+    # now we do the DNS dance for netblocks, if we have an RPC server to do it with.
+    _rpc('addOrUpdateRevRec', cidr => "$args{cidr}", name => $args{rdns}, rpcuser => $args{user})
+      if $rpc_url;
+
+    return ('OK', 'OK');
 
   } # end static-IP vs netblock allocation
@@ -1442,4 +1476,52 @@
 
 
+## IPDB::getBlockRDNS()
+# Gets reverse DNS pattern for a block or IP.  Note that this will also
+# retrieve any default pattern following the parent chain up, and check via
+# RPC (if available) to see what the narrowest pattern for the requested block is
+# Returns the current pattern for the block or IP.
+sub getBlockRDNS {
+  my $dbh = shift;
+  my $block = shift;
+  my $rdepth = shift;	# do we really need this?
+  my %args = @_;
+
+  $args{vrf} = '' if !$args{vrf};
+
+  my $cidr = new NetAddr::IP $block;
+
+  my ($rdns,$rfrom) = $dbh->selectrow_array("SELECT rdns,cidr FROM allocations WHERE cidr >>= ? UNION ".
+	"SELECT rdns,cidr FROM masterblocks WHERE cidr >>= ? ORDER BY cidr", undef, ($cidr,$cidr) );
+
+  if ($rpc_url) {
+    # Make an object to represent the XML-RPC server.
+    my $server = Frontier::Client->new(url => $rpc_url, debug => 0);
+    my $result;
+
+    # Use the first /16 or /24, rather than dithering over which sub-/14 /16
+    # or sub-/19 /24 to retrieve - it's the least-wrong way to do things.
+
+    my ($rpcblock) = $cidr->split( ($cidr->masklen <= 16 ? 16 : 24) );
+    my %rpcargs = (
+	rpcuser => $args{user},
+	rpcsystem => 'ipdb',
+	group => $revgroup,	# not sure how this could sanely be exposed, tbh...
+	cidr => "$rpcblock",
+	);
+
+    eval {
+      $result = $server->call('dnsdb.getRevPattern', %rpcargs);
+    };
+    if ($@) {
+      my $msg = $@;
+      $msg =~ s/Fault returned from XML RPC Server, fault code 4: error executing RPC `dnsdb.addRDNS'\.\s//;
+    }
+  }
+
+  # hmm.  do we care about where it actually came from?
+  return $rdns;
+} # end getBlockRDNS()
+
+
 ## IPDB::getNodeList()
 # Gets a list of node ID+name pairs as an arrayref to a list of hashrefs
