Changeset 371 for trunk/cgi-bin/extras


Ignore:
Timestamp:
11/27/07 12:27:45 (16 years ago)
Author:
Kris Deugau
Message:

/trunk

Merge bugfixes and enhancements from /branches/stable r360 through r369

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/cgi-bin/extras/db2rwhois.pl

    r341 r371  
    1010# Last update by $Author$
    1111###
    12 # Copyright (C) 2004,2005 - Kris Deugau
     12# Copyright (C) 2004-2007 - Kris Deugau
    1313
    1414use strict;
     
    1717use NetAddr::IP;
    1818use MyIPDB;
     19use File::Path 'rmtree';
    1920
    2021$ENV{"PATH"} = "/bin;/usr/bin";
    2122
    2223my $rwhoisDataPath = "/etc/rwhoisd";
     24
     25my @autharea;
     26my $authrw;
     27# Use the template file to allow us to keep persistent nodes aside from netblock data
     28open AUTHTEMPLATE, "<$rwhoisDataPath/rwhoisd.auth_template";
     29my $template_persist;
     30while (<AUTHTEMPLATE>) {
     31  next if /^##/;
     32  $template_persist = 1 if /^[a-z]/i;
     33  $autharea[0] .= $_;
     34}
    2335
    2436my ($dbh,$msg) = connectDB_My;
     
    3143my %def_custids;
    3244
     45# Get the list of live directories for potential deletion
     46opendir RWHOISROOT, $rwhoisDataPath;
     47my %rwhoisdirs;
     48foreach (readdir RWHOISROOT) {
     49  $rwhoisdirs{$_} = 1 if /^net-/;
     50}
     51closedir RWHOISROOT;
     52
     53# prefetch alloctype data
     54my $sth = $dbh->prepare("select type,def_custid,arin_netname from alloctypes");
     55$sth->execute;
     56while (my @data = $sth->fetchrow_array) {
     57  $netnameprefix{$data[0]} = $data[2];
     58}
     59
     60# Get the list of masters to export
     61my $msth = $dbh->prepare("select cidr,ctime,mtime from masterblocks where rwhois='y'");
     62$msth->execute;
     63
     64# Prepare to select subblocks for each master
     65# Make sure to remove the private netblocks from this,
     66# no use or point in broadcasting our use of them.
     67# Also remove the details of our "reserved CORE/WAN" blocks;  they're not critical.
     68my $ssth = $dbh->prepare("select cidr,custid,type,city,description,createstamp,modifystamp,swip ".
     69        "from allocations where ".
     70        "not (cidr <<= '192.168.0.0/16') and ".
     71        "not (cidr <<= '172.16.0.0/12') and ".
     72        "not (cidr <<= '10.0.0.0/8') and ".
     73        "not (type = 'wr') and ".
     74        "masklen(cidr) <=30 and ".
     75        "cidr <<= ?");
     76
     77# Customer data, for those rare blocks we really need to delegate.
     78my $custsth = $dbh->prepare("select name,street,city,province,country,pocode,phone,tech_handle,special ".
     79        "from customers where custid=?");
     80
    3381# Fill in data about our master blocks as allocated from ARIN
    3482# We open separate files for each of these as appropriate.
    35 # Note that this ASS-U-MEs that we do not add master IP blocks-
    36 # there should probably be a separate system for doing that.
    37 my $sth = $dbh->prepare("select cidr,ctime,mtime from masterblocks;");
    38 $sth->execute;
     83# Changes in master blocks are treated as complete new masters - since we're exporting
     84# all data every time, this isn't so terrible as it might seem.
    3985my $i=0;
    40 GETMASTERS: while (my @data = $sth->fetchrow_array()) {
    41 
    42 # Techically, we only need to exclude 204.138.172.0/24, as we "own" all of the other blocks.
    43 # However, 205.207.184.0/23 and 206.130.64.0/24 are, um, awkward.
    44   if ($data[0] =~ /^(192.168.0.0|172.16.0.0|10.0.0.0|20[456])/) {
    45     next GETMASTERS;
    46   }
     86while (my @data = $msth->fetchrow_array()) {
     87
    4788  $masterblocks[$i] = new NetAddr::IP $data[0];
    4889  my ($ctime,undef) = split /\s/, $data[1];
    4990  my ($mtime,undef) = split /\s/, $data[2];
    50 print "$masterblocks[$i] $ctime $mtime\n";
     91
     92  print "$masterblocks[$i] $ctime $mtime\n";
    5193
    5294  my $date;
    5395  chomp ($date = `/bin/date +"%Y-%m-%d"`);
    5496
    55 # Whew!  Ugly little varmint.
    56   my $masterfilename = "net-".$masterblocks[$i]->addr."-".$masterblocks[$i]->masklen.
    57     "/data/network/".$masterblocks[$i]->addr."-".$masterblocks[$i]->masklen.".txt";
    58 
    59 # Need check here to create tree for netblock?
     97  my $rwnet = "net-".$masterblocks[$i]->addr."-".$masterblocks[$i]->masklen;
     98
     99  # unflag the directory for deletion.  Whee!  Roundabout!
     100  delete $rwhoisdirs{$rwnet};
     101
     102# Hokay.  Gonna do checks *here* to see if we need to create new master trees
     103  my $netdatadir = "$rwhoisDataPath/$rwnet";
     104  if (! -e $netdatadir) {
     105    print " New master $masterblocks[$i]!\n";
     106    print "  Creating directories...\n";
     107    mkdir $netdatadir;
     108    mkdir "$netdatadir/attribute_defs";
     109    mkdir "$netdatadir/data";
     110    mkdir "$netdatadir/data/network";
     111    mkdir "$netdatadir/data/org";
     112    mkdir "$netdatadir/data/referral";
     113
     114    my $serial;
     115    chomp ($serial = `/bin/date '+%Y%m%d'000000000`);
     116
     117    print "  Creating SOA...\n";
     118    open SOAFILE, ">$netdatadir/soa";
     119    print SOAFILE qq(Serial-Number: $serial
     120Refresh-Interval: 3600
     121Increment-Interval: 1800
     122Retry-Interval: 1800
     123Time-To-Live: 86400
     124Primary-Server: rwhois.example.com:4321
     125Hostmaster: dns\@example.com
     126);
     127    close SOAFILE;
     128
     129    print "  Creating Schema...\n";
     130    open SCHEMAFILE, ">$netdatadir/schema";
     131    print SCHEMAFILE qq(name: network
     132attributedef: $rwnet/attribute_defs/network.tmpl
     133dbdir: $rwnet/data/network
     134Schema-Version: $serial
     135---
     136name: organization
     137attributedef: $rwnet/attribute_defs/org.tmpl
     138dbdir: $rwnet/data/org
     139description: Organization object
     140Schema-Version: $serial
     141---
     142name: referral
     143attributedef:$rwnet/attribute_defs/referral.tmpl
     144dbdir:$rwnet/data/referral
     145Schema-Version: $serial
     146);
     147    close SCHEMAFILE;
     148
     149    print "  Copying template files...\n";
     150    qx { /bin/cp $rwhoisDataPath/skel/attribute_defs/* $netdatadir/attribute_defs/ };
     151
     152    print "  Creating org data...\n";
     153    open ORGDATAFILE, ">$netdatadir/data/org/friendlyisp.txt";
     154    print ORGDATAFILE qq(ID: NETBLK-ISP.$masterblocks[$i]
     155Auth-Area: $masterblocks[$i]
     156Org-Name: Friendly ISP
     157Street-Address: 123 4th Street
     158City: Anytown
     159State: ON
     160Postal-Code: H0H 0H0
     161Country-Code: CA
     162Phone: 000-555-1234
     163Created: 20040308
     164Updated: 20040308
     165);
     166    close ORGDATAFILE;
     167
     168    # Generate auth_area record, and add it to the array.
     169    $authrw = 1;        # Flag for rewrite and daemon reload/restart
     170
     171  } # new master
     172
     173  # do this for all masters, so that we can use this array to export the data
     174  # to rwhoisd.auth_area later if we need to
     175  push @autharea, qq(type:master
     176name:$masterblocks[$i]
     177data-dir: $rwnet/data
     178schema-file: $rwnet/schema
     179soa-file: $rwnet/soa
     180);
     181
     182  # Recreate the net-nnn.nnn.nnn.nnn-nn.txt data file
     183  my $masterfilename = "$rwnet/data/network/".$masterblocks[$i]->addr."-".$masterblocks[$i]->masklen.".txt";
    60184
    61185  open MASTERFILE,">$rwhoisDataPath/$masterfilename";
     
    77201        "Updated-By: noc\@example.com\n";
    78202
    79   close MASTERFILE;
    80   $i++;
    81 }
    82 
    83 # prefetch alloctype data
    84 $sth = $dbh->prepare("select type,def_custid,arin_netname from alloctypes");
    85 $sth->execute;
    86 while (my @data = $sth->fetchrow_array) {
    87   $netnameprefix{$data[0]} = $data[2];
    88   $def_custids{$data[0]} = $data[1];
    89 }
    90 
    91 # Now read out the data in the "main" delegation list, and check it
    92 # with the master blocks.  We need to do this to decide which rWHOIS
    93 # "net-xxx.xxx.xxx.xxx-mask" tree the data belongs in.
    94 
    95 # Make sure to remove the private netblocks from this.
    96 # No use or point in broadcasting our use of them.
    97 # Also remove the details of our "reserved CORE/WAN" blocks;  they're not critical.
    98 $sth = $dbh->prepare("select cidr,custid,type,city,description,createstamp,modifystamp,swip ".
    99         "from allocations where ".
    100         "not (cidr <<= '192.168.0.0/16') and ".
    101         "not (cidr <<= '172.16.0.0/12') and ".
    102         "not (cidr <<= '10.0.0.0/8') and ".
    103         "not (type = 'wr') and ".
    104         "masklen(cidr) <=30");
    105 #" and (custid='6750400' or custid like '%-RES' or custid like '%-BUS')");
    106 $sth->execute;
    107 
    108 my $custsth = $dbh->prepare("select name,street,city,province,country,pocode,phone,tech_handle,special from customers where custid=?");
    109 
    110 $i=0;
    111 while (my ($cidr, $custid, $type, $city, $desc, $ctime, $mtime, $swip) = $sth->fetchrow_array) {
     203  # And now the subblocks
     204  $ssth->execute("$masterblocks[$i]");
     205  while (my ($cidr, $custid, $type, $city, $desc, $ctime, $mtime, $swip) = $ssth->fetchrow_array) {
    112206
    113207# We get master block info from @masterblocks.
     
    124218 # Updated-By: noc@example.com
    125219
    126   # Get the "full" network number
    127   my $net = new NetAddr::IP $cidr;
     220    # Get the "full" network number
     221    my $net = new NetAddr::IP $cidr;
    128222
    129223# Assumptions:  All data in ipdb is public
    130224# If not, we need another field to indicate "public/private".
    131225
    132   foreach my $master (@masterblocks) {
    133     if ($master->contains($net)) {
    134 
    135 # Whew!  Ugly little varmint.
    136       my $masterfilename = "net-".$master->addr."-".$master->masklen.
    137         "/data/network/".$master->addr."-".$master->masklen.".txt";
    138 
    139       open MASTERFILE,">>$rwhoisDataPath/$masterfilename"
    140         or print "File open error: '$!' on '$rwhoisDataPath/$masterfilename'\n";
    141 
    142226# cidr custid type city description notes maskbits
    143227
     
    145229if ($desc =~ /^\s*$/) { $desc = 'Friendly ISP'; }
    146230
    147       # Fix up datestamps.  We don't *really* need sub-microsecond resolution on our exports...
    148       ($ctime) = ($ctime =~ /^(\d+-\d+-\d+)\s+/);
    149       ($mtime) = ($mtime =~ /^(\d+-\d+-\d+)\s+/);
     231    # Fix up datestamps.  We don't *really* need sub-microsecond resolution on our exports...
     232    ($ctime) = ($ctime =~ /^(\d+-\d+-\d+)\s+/);
     233    ($mtime) = ($mtime =~ /^(\d+-\d+-\d+)\s+/);
    150234
    151235# Notes:
     
    166250#  network:Class-Name:network                   [Provided by rWHOIS protocol]
    167251
    168       my $netname = $netnameprefix{$type};
    169 
    170       if ($swip eq 'y' && $def_custids{$type} eq '') {
    171         # def_custids{$type} should only be blank on types that are
    172         # allocated direct to customers.  i are sMart!!11!!oneone!
    173         $custsth->execute($custid);
    174         my ($name, $street, $city, $prov, $country, $pocode, $phone, $tech, $special) = $custsth->fetchrow_array;
    175         $custsth->finish;
    176         if ($special && $special =~ /NetName/ && $special =~ /$cidr/) {
    177           ($netname) = ($special =~ /NetName$cidr: ([A-Z0-9_-]+)/);
    178         } else {
    179           $netname .= "-".$net->network;
    180         }
    181         print MASTERFILE "---\nID: NETBLK-ISP.$master\n".
    182                 "Auth-Area: $master\n".
    183                 "Network-Name: $netname\n".
    184                 "IP-Network: $net\n".
    185                 "IP-Network-Block: ".$net->range."\n".
    186                 "Org-Name: $name\n".
    187                 "Street-Address: $street\n".
    188                 "City: $city\n".
    189                 "StateProv: $prov\n".
    190                 "Postal-Code: $pocode\n".
    191                 "Country-Code: $country\n".
    192                 "Tech-Contact: $tech\n".
    193                 "Created: $ctime\n".
    194                 "Updated: $mtime\n".
    195                 "Updated-By: noc\@example.com\n";
     252    my $netname = $netnameprefix{$type};
     253
     254    if ($swip eq 'n') {
     255      print MASTERFILE "---\nID: NETBLK-ISP.$masterblocks[$i]\n".
     256        "Auth-Area: $masterblocks[$i]\n".
     257        "Network-Name: $netname-".$net->network."\n".
     258        "IP-Network: $net\n".
     259        "IP-Network-Block: ".$net->range."\n".
     260        "Org-Name: Friendly ISP\n".
     261        "Street-Address: 123 4th Street\n".
     262        "City: Anytown\n".
     263        "StateProv: Ontario\n".
     264        "Postal-Code: H0H 0H0\n".
     265        "Country-Code: CA\n".
     266        "Tech-Contact: ISP-ARIN-HANDLE\n".
     267        "Created: $ctime\n".
     268        "Updated: $mtime\n".
     269        "Updated-By: noc\@example.com\n";
     270    } else {
     271      $custsth->execute($custid);
     272      my ($name, $street, $city, $prov, $country, $pocode, $phone, $tech, $special) = $custsth->fetchrow_array;
     273      $custsth->finish;
     274      if ($special && $special =~ /NetName/ && $special =~ /$cidr/) {
     275        ($netname) = ($special =~ /NetName$cidr: ([A-Z0-9_-]+)/);
    196276      } else {
    197         print MASTERFILE "---\nID: NETBLK-ISP.$master\n".
    198                 "Auth-Area: $master\n".
    199                 "Network-Name: $netname-".$net->network."\n".
    200                 "IP-Network: $net\n".
    201                 "IP-Network-Block: ".$net->range."\n".
    202                 "Org-Name: Friendly ISP\n".
    203                 "Street-Address: 123 4th Street\n".
    204                 "City: Anytown\n".
    205                 "StateProv: Ontario\n".
    206                 "Postal-Code: H0H 0H0\n".
    207                 "Country-Code: CA\n".
    208                 "Tech-Contact: ISP-ARIN-HANDLE\n".
    209                 "Created: $ctime\n".
    210                 "Updated: $mtime\n".
    211                 "Updated-By: noc\@example.com\n";
    212       } # decide which contact data to use (cust data only on swip==y && def custid=='')
    213     } # net in master
    214   } # foreach master
    215 
    216 
    217 
    218   #  print "$data[0]\t| $data[1]\t| $data[2]\t| $data[3]\t| $data[4]\t| ".
    219   #     "$data[5]\t| $data[6]\t| $data[7]\t| $data[8]\t| $data[9]\n";
    220   #  print "$data[0]\t| $data[1]\t| $data[2]\t| $data[3]\t| $data[4]\t| ".
    221   #     "$data[5]\t| $data[6]\t| $data[7]\t| $data[8]\n";
     277        $netname .= "-".$net->network;
     278      }
     279      print MASTERFILE "---\nID: NETBLK-ISP.$masterblocks[$i]\n".
     280        "Auth-Area: $masterblocks[$i]\n".
     281        "Network-Name: $netname\n".
     282        "IP-Network: $net\n".
     283        "IP-Network-Block: ".$net->range."\n".
     284        "Org-Name: $name\n".
     285        "Street-Address: $street\n".
     286        "City: $city\n".
     287        "StateProv: $prov\n".
     288        "Postal-Code: $pocode\n".
     289        "Country-Code: $country\n".
     290        "Tech-Contact: $tech\n".
     291        "Created: $ctime\n".
     292        "Updated: $mtime\n".
     293        "Updated-By: noc\@example.com\n";
     294    } # swip
     295
     296  } # while $ssth->fetchrow_array()
     297
     298  close MASTERFILE;
     299
    222300  $i++;
    223 } # while fetchrow_array()
    224 
    225 
     301} # while $msth->fetchrow_array()
     302
     303# Now we see if there's obsolete netdata directories to be deleted,
     304# and therefore an auth-area file to regenerate
     305foreach my $netdir (keys %rwhoisdirs) {
     306  print "deleting obsolete directory $netdir...\n";
     307  rmtree ( "$rwhoisDataPath/$netdir", { verbose => 1, error => \my $errlist } );
     308  for my $diag (@$errlist) {
     309    my ($file, $message) = each %$diag;
     310    if ($file eq '') {
     311      print "general error: $message\n";
     312    }
     313  }
     314  $authrw = 1;  # there's probably a more efficient place to put this.  Feh.
     315}
     316
     317# Regenerate rwhoisd.auth_area if needed
     318if ($authrw) {
     319  print "Regenerating auth_area\n";
     320  open RWHOISDAUTH, ">$rwhoisDataPath/rwhoisd.auth_area";
     321  print RWHOISDAUTH "# WARNING: This file is autogenerated!  Any static nodes should\n".
     322                "# be entered in /etc/rwhoisd/rwhoisd.auth_template\n";
     323  if ($template_persist) {
     324    print RWHOISDAUTH shift @autharea;
     325    print RWHOISDAUTH "---\n";
     326  }
     327  # feh.  we need to know when we're at the end of the loop, because then
     328  # we DON'T want to write the separator...
     329  for (;@autharea;) {   # my head hurts.
     330    print RWHOISDAUTH shift @autharea;
     331    print RWHOISDAUTH "---\n" if @autharea;
     332  }
     333  close RWHOISDAUTH;
     334
     335  # restart/reload rwhoisd
     336  if (-e "$rwhoisDataPath/rwhoisd.pid") {       # no pidfile, no restart.
     337    print "Restarting rwhoisd\n";
     338    open PIDFILE, "<$rwhoisDataPath/rwhoisd.pid";
     339    my ($rwpid) = (<PIDFILE> =~ /^(\d+)/);
     340    close PIDFILE;
     341    kill 'HUP', $rwpid;
     342  }
     343}
     344
     345# and finally
    226346$dbh->disconnect;
Note: See TracChangeset for help on using the changeset viewer.