- Timestamp:
- 05/11/16 18:20:05 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cgi-bin/IPDB.pm
r868 r872 729 729 my $dbh = shift; 730 730 # 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 732 736 my %args = @_; 733 737 … … 747 751 # Wrap all the SQL in a transaction 748 752 eval { 749 # First check - does the master exist ? Ignore VRFs until we can see a sane UI753 # First check - does the master exist in this VRF? 750 754 my ($mcontained) = $dbh->selectrow_array("SELECT cidr FROM allocations WHERE cidr >>= ? AND type = 'mm' AND vrf = ?", 751 755 undef, ($cidr, $args{vrf}) ); … … 780 784 else { 781 785 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 782 794 # 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. 783 798 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}); 786 801 my @cmasters; 787 802 my @oldmids; … … 792 807 $smallmask = $master->masklen if $master->masklen > $smallmask; 793 808 } 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); 794 814 795 815 # split the new master, and keep only those blocks not part of an existing master … … 805 825 ##fixme: master_id 806 826 # 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).")"); 808 828 $sth->execute($smallmask, $cidr); 809 829 while (my @data = $sth->fetchrow_array) { … … 815 835 @blocklist = Compact(@blocklist); 816 836 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. 828 838 $sth = $dbh->prepare("DELETE FROM freeblocks WHERE cidr <<= ? AND parent_id IN (".join(',', @oldmids).")"); 839 840 # insert new combined freeblocks. 829 841 my $sth2 = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,parent_id,vrf,master_id)". 830 842 " VALUES (?,'<NULL>','m',?,?,?)"); … … 835 847 836 848 # Update immediate allocations, and remove the old parents 837 $sth = $dbh->prepare("UPDATE allocations SET parent_id = ? WHERE parent_id = ?");838 849 $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 = ?"); 839 855 foreach my $old (@oldmids) { 840 $sth->execute($mid, $old);841 856 $sth2->execute($old); 857 $fbfix->execute($mid, $old); 858 $fbfix2->execute($mid, $old); 859 $allocfix->execute($mid, $old); 860 $allocfix2->execute($mid, $old); 842 861 } 843 862
Note:
See TracChangeset
for help on using the changeset viewer.