Changeset 872


Ignore:
Timestamp:
05/11/16 18:20:05 (8 years ago)
Author:
Kris Deugau
Message:

/trunk

Review and update addMaster() to properly handle new data structures
and VRF as a top-level entity (see #54)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/cgi-bin/IPDB.pm

    r868 r872  
    729729  my $dbh = shift;
    730730        # warning!  during testing, this somehow generated a "Bad file descriptor" error.  O_o
    731   my $cidr = new NetAddr::IP shift;
     731  my $ctext = shift;
     732  my $cidr = new NetAddr::IP $ctext;
     733
     734  return ('FAIL',"$ctext is not a valid CIDR address") if !$cidr;
     735
    732736  my %args = @_;
    733737
     
    747751  # Wrap all the SQL in a transaction
    748752  eval {
    749     # First check - does the master exist?  Ignore VRFs until we can see a sane UI
     753    # First check - does the master exist in this VRF?
    750754    my ($mcontained) = $dbh->selectrow_array("SELECT cidr FROM allocations WHERE cidr >>= ? AND type = 'mm' AND vrf = ?",
    751755        undef, ($cidr, $args{vrf}) );
     
    780784    else {
    781785
     786      # insert the new master
     787      $dbh->do("INSERT INTO allocations (cidr,type,swip,vrf,rdns) VALUES (?,?,?,?,?)", undef,
     788        ($cidr, 'mm', 'y', $args{vrf}, $args{rdns}) );
     789      ($mid) = $dbh->selectrow_array("SELECT currval('allocations_id_seq')");
     790
     791      # master should be its own master, so deletes directly at the master level work
     792      $dbh->do("UPDATE allocations SET master_id = ? WHERE id = ?", undef, ($mid, $mid) );
     793
    782794      # collect the master(s) we're going to absorb, and snag the longest netmask while we're at it.
     795# note << is accurate and complete because our first check just into the eval is "is the new master
     796# entirely contained or equal to an existing one?" - so, by definition, if it's not contained, and
     797# it's not equal, it's larger.  this also lets us insert the new master without picking it up again here.
    783798      my $smallmask = $cidr->masklen;
    784       my $sth = $dbh->prepare("SELECT cidr,id FROM allocations WHERE cidr <<= ? AND type='mm' AND parent_id=0");
    785       $sth->execute($cidr);
     799      my $sth = $dbh->prepare("SELECT cidr,id FROM allocations WHERE cidr << ? AND type = 'mm' AND parent_id = 0 AND vrf = ? ");
     800      $sth->execute($cidr, $args{vrf});
    786801      my @cmasters;
    787802      my @oldmids;
     
    792807        $smallmask = $master->masklen if $master->masklen > $smallmask;
    793808      }
     809
     810      # update existing DNS refs.  do this unconditionally Just In Case
     811      $dbh->do("UPDATE dnsavail SET parent_alloc = ? WHERE zone << ?"
     812        " AND parent_alloc IN (".join(',', @oldmids).")",
     813        undef, $mid, $cidr);
    794814
    795815      # split the new master, and keep only those blocks not part of an existing master
     
    805825##fixme:  master_id
    806826      # collect the unrouted free blocks within the new master
    807       $sth = $dbh->prepare("SELECT cidr FROM freeblocks WHERE masklen(cidr) <= ? AND cidr <<= ? AND routed = 'm'");
     827      $sth = $dbh->prepare("SELECT cidr FROM freeblocks WHERE masklen(cidr) <= ? AND cidr <<= ? AND routed = 'm' AND master_id IN (".join(',',@oldmids).")");
    808828      $sth->execute($smallmask, $cidr);
    809829      while (my @data = $sth->fetchrow_array) {
     
    815835      @blocklist = Compact(@blocklist);
    816836
    817       # master
    818       $dbh->do("INSERT INTO allocations (cidr,type,swip,vrf,rdns) VALUES (?,?,?,?,?)", undef,
    819         ($cidr, 'mm', 'y', $args{vrf}, $args{rdns}) );
    820       ($mid) = $dbh->selectrow_array("SELECT currval('allocations_id_seq')");
    821 
    822       # master should be its own master, so deletes directly at the master level work
    823       $dbh->do("UPDATE allocations SET master_id = ? WHERE id = ?", undef, ($mid, $mid) );
    824 
    825       # and now insert the new data.  Make sure to delete old masters too.
    826 
    827       # freeblocks
     837      # delete freeblocks that have been absorbed.  this is probably rare.
    828838      $sth = $dbh->prepare("DELETE FROM freeblocks WHERE cidr <<= ? AND parent_id IN (".join(',', @oldmids).")");
     839
     840      # insert new combined freeblocks.
    829841      my $sth2 = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,parent_id,vrf,master_id)".
    830842        " VALUES (?,'<NULL>','m',?,?,?)");
     
    835847
    836848      # Update immediate allocations, and remove the old parents
    837       $sth = $dbh->prepare("UPDATE allocations SET parent_id = ? WHERE parent_id = ?");
    838849      $sth2 = $dbh->prepare("DELETE FROM allocations WHERE id = ?");
     850      # sigh.  going to have to churn things, since we need to do different updates to different sets of blocks.
     851      my $fbfix = $dbh->prepare("UPDATE freeblocks SET master_id = ? WHERE master_id = ?");
     852      my $fbfix2 = $dbh->prepare("UPDATE freeblocks SET parent_id = ? WHERE parent_id = ?");
     853      my $allocfix = $dbh->prepare("UPDATE allocations SET master_id = ? WHERE master_id = ?");
     854      my $allocfix2 = $dbh->prepare("UPDATE allocations SET parent_id = ? WHERE parent_id = ?");
    839855      foreach my $old (@oldmids) {
    840         $sth->execute($mid, $old);
    841856        $sth2->execute($old);
     857        $fbfix->execute($mid, $old);
     858        $fbfix2->execute($mid, $old);
     859        $allocfix->execute($mid, $old);
     860        $allocfix2->execute($mid, $old);
    842861      }
    843862
Note: See TracChangeset for help on using the changeset viewer.