Changeset 638 for trunk/cgi-bin
- Timestamp:
- 10/09/14 18:13:22 (10 years ago)
- Location:
- trunk/cgi-bin
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cgi-bin/IPDB.pm
r637 r638 1247 1247 # as well as the reverse entry 1248 1248 sub deleteBlock { 1249 my ($dbh,undef,$rdepth,$vrf,$delfwd,$user) = @_; 1250 my $cidr = new NetAddr::IP $_[1]; 1249 my ($dbh,$id,$basetype,$delfwd,$user) = @_; 1250 1251 # Collect info about the block we're going to delete 1252 my $binfo = getBlockData($dbh, $id, $basetype); 1253 my $cidr = new NetAddr::IP $binfo->{block}; 1251 1254 1252 1255 # For possible auto-VRF-ignoring (since public IPs shouldn't usually be present in more than one VRF) … … 1267 1270 my $con_type; 1268 1271 1269 # Collect info about the block we're going to delete1270 my $binfo = getBlockData($dbh, $cidr, $rdepth, $vrf);1271 1272 1272 1273 # temporarily forced null, until a sane UI for VRF tracking can be found. 1273 $vrf = '';# if !$vrf; # as with SQL, the null value is not equal to ''. *sigh*1274 # $vrf = '';# if !$vrf; # as with SQL, the null value is not equal to ''. *sigh* 1274 1275 1275 1276 # To contain the error message, if any. … … 1281 1282 local $dbh->{RaiseError} = 1; 1282 1283 1283 # First case. The "block" is a static IP1284 # Note that we still need some additional code in the odd case1285 # of a netblock-aligned contiguous group of static IPs1286 1284 if ($binfo->{type} =~ /^.i$/) { 1285 # First case. The "block" is a static IP 1286 # Note that we still need some additional code in the odd case 1287 # of a netblock-aligned contiguous group of static IPs 1287 1288 1288 1289 eval { 1289 1290 $msg = "Unable to deallocate $disp_alloctypes{$binfo->{type}} $cidr"; 1290 my ($pool,$pcust,$pvrf) = $dbh->selectrow_array("SELECT pool,custid,vrf FROM poolips WHERE ip=?", undef, ($cidr));1291 my $pinfo = getBlockData($dbh, $binfo->{parent_id}, 'b'); 1291 1292 ##fixme: VRF and rdepth 1292 $dbh->do("UPDATE poolips SET custid =?,available='y',".1293 "city =(SELECT city FROM allocations WHERE cidr=?),".1294 "description ='',notes='',circuitid='',vrf=? WHERE ip=?", undef, ($pcust, $pool, $pvrf, $cidr) );1295 $goback = $pool;1293 $dbh->do("UPDATE poolips SET custid = ?, available = 'y',". 1294 "city = (SELECT city FROM allocations WHERE id = ?),". 1295 "description = '', notes = '', circuitid = '', vrf = ? WHERE id = ?", undef, 1296 ($pinfo->{custid}, $binfo->{parent_id}, $pinfo->{vrf}, $id) ); 1296 1297 $dbh->commit; 1297 1298 }; … … 1302 1303 } else { 1303 1304 ##fixme: RPC return code? 1304 _rpc('delByCIDR', cidr => "$cidr", user => $user, delforward => $delfwd );1305 _rpc('delByCIDR', cidr => "$cidr", user => $user, delforward => $delfwd, rpcuser => $user); 1305 1306 return ('OK',"OK"); 1306 1307 } 1307 1308 1308 1309 } elsif ($binfo->{type} eq 'mm') { # end alloctype =~ /.i/ 1310 # Second case. The block is a full master block 1309 1311 1310 1312 ##fixme: VRF limit 1311 1313 $msg = "Unable to delete master block $cidr"; 1312 1314 eval { 1313 $dbh->do("DELETE FROM masterblocks WHERE cidr = ?", undef, ($cidr) ); 1314 $dbh->do("DELETE FROM allocations WHERE cidr <<= ?", undef, ($cidr) ); 1315 $dbh->do("DELETE FROM freeblocks WHERE cidr <<= ?", undef, ($cidr) ); 1315 $dbh->do("DELETE FROM allocations WHERE cidr <<= ? AND master_id = ?", undef, ($cidr, $binfo->{master_id}) ); 1316 $dbh->do("DELETE FROM freeblocks WHERE cidr <<= ? AND master_id = ?", undef, ($cidr, $binfo->{master_id}) ); 1316 1317 $dbh->commit; 1317 1318 }; … … 1335 1336 my @fails; 1336 1337 foreach my $subzone (@zonelist) { 1337 if ($rpc_url && !_rpc('delZone', zone => "$subzone", revrec => 'y', user => $user, delforward => $delfwd) ) {1338 if ($rpc_url && !_rpc('delZone', zone => "$subzone", revrec => 'y', rpcuser => $user, delforward => $delfwd) ) { 1338 1339 push @fails, ("$subzone" => $errstr); 1339 1340 } … … 1352 1353 1353 1354 my $retcode = 'OK'; 1354 my ($ptype,$pcity,$ppatt );1355 my ($ptype,$pcity,$ppatt,$p_id); 1355 1356 1356 1357 eval { … … 1359 1360 # explicitly deleting any suballocations of the block to be deleted. 1360 1361 1361 # find the current parent of the block we're deleting 1362 my ($parent) = $dbh->selectrow_array("SELECT parent FROM allocations WHERE cidr=? AND rdepth=?", 1363 undef, ($cidr, $rdepth) ); 1362 # get parent info of the block we're deleting 1363 my $pinfo = getBlockData($dbh, $binfo->{parent_id}); 1364 $ptype = $pinfo->{type}; 1365 $pcity = $pinfo->{city}; 1366 $ppatt = $pinfo->{rdns}; 1367 $p_id = $binfo->{parent_id}; 1364 1368 1365 1369 # Delete the block 1366 $dbh->do("DELETE FROM allocations WHERE cidr=? AND rdepth=?", undef, ($cidr, $rdepth) ); 1367 1368 ##fixme: we could maybe eliminate a special case if we put masterblocks in the allocations table...? 1369 if ($rdepth == 1) { 1370 # parent is a master block. 1371 $ptype = 'mm'; 1372 $pcity = '<NULL>'; 1373 $ppatt = $dbh->selectrow_array("SELECT rdns FROM masterblocks WHERE cidr=?", undef, ($parent) ); 1374 } else { 1375 # get that parent's details 1376 ($ptype,$pcity,$ppatt) = $dbh->selectrow_array("SELECT type,city,rdns FROM allocations ". 1377 "WHERE cidr=? AND rdepth=?", undef, ($parent, $rdepth-1) ); 1378 } 1370 $dbh->do("DELETE FROM allocations WHERE id = ?", undef, ($id) ); 1379 1371 1380 1372 # munge the parent type a little 1381 $ptype = (split //, $ptype)[ 0];1373 $ptype = (split //, $ptype)[1]; 1382 1374 1383 1375 ##fixme: you can't... CAN NOT.... assign the same public IP to multiple things. … … 1385 1377 # -> $isprivnet flag from start of sub 1386 1378 1387 my $fbrdepth = $rdepth;1388 1389 1379 # check to see if any container allocations could be the "true" parent 1390 my ($tparent,$trdepth,$trtype,$tcity) = $dbh->selectrow_array("SELECT cidr,rdepth,type,city FROM allocations ". 1391 "WHERE (type='rm' OR type LIKE '_c') AND cidr >> ? ". 1392 "ORDER BY masklen(cidr) DESC", undef, ($cidr) ); 1393 1394 my $fparent; 1395 if ($tparent && $tparent ne $parent) { 1396 # found an alternate parent; reset some parent-info bits 1397 $parent = $tparent; 1398 $ptype = (split //, $trtype)[0]; 1399 $pcity = $tcity; 1400 ##fixme: hmm. collect $rdepth into $goback here before vanishing? 1401 $retcode = 'WARNMERGE'; # may be redundant 1402 $goback = $tparent; 1403 # munge freeblock rdepth and parent to match true parent 1404 $dbh->do("UPDATE freeblocks SET rdepth = ?, parent = ?, routed = ? WHERE cidr <<= ? AND rdepth = ?", undef, 1405 ($trdepth+1, $parent, $ptype, $cidr, $rdepth) ); 1406 $rdepth = $trdepth; 1407 $fbrdepth = $trdepth+1; 1408 } 1409 1410 $parent = new NetAddr::IP $parent; 1411 $goback = "$parent,$fbrdepth"; # breadcrumb in case of live-parent-is-not-true-parent 1412 1413 # Special case - delete pool IPs 1414 if ($binfo->{type} =~ /^.[pd]$/) { 1415 # We have to delete the IPs from the pool listing. 1416 ##fixme: rdepth? vrf? 1417 $dbh->do("DELETE FROM poolips WHERE pool = ?", undef, ($cidr) ); 1418 } 1419 1420 # Find out if the block we're deallocating is within a DSL pool (legacy goo) 1421 my ($pool,$poolcity,$pooltype,$pooldepth) = $dbh->selectrow_array( 1422 "SELECT cidr,city,type,rdepth FROM allocations WHERE type LIKE '_p' AND cidr >>= ?", 1423 undef, ($cidr) ); 1424 1425 # If so, return the block's IPs to the pool, instead of to freeblocks 1426 ## NB: not possible to currently cause this even via admin tools, only legacy data. 1427 if ($pool) { 1428 ## Deallocate legacy blocks stashed in the middle of a static IP pool 1429 ## This may be expandable to an even more general case of contained netblock, or other pool types. 1430 $retcode = 'WARNPOOL'; 1431 $goback = "$pool,$pooldepth"; 1432 # We've already deleted the block, now we have to stuff its IPs into the pool. 1433 $pooltype =~ s/p$/i/; # change type to static IP 1434 my $sth2 = $dbh->prepare("INSERT INTO poolips (pool,ip,city,type,custid) VALUES ". 1435 "('$pool',?,'$poolcity','$pooltype','$defcustid')"); 1436 # don't insert .0 1380 my ($tparent,$tpar_id,$trtype,$tcity); 1381 $tpar_id = 0; 1382 1383 ##fixme: this is far simpler in the strict VRF case; we "know" that any allocation 1384 # contained by a container is a part of the same allocation tree when the VRF fields are equal. 1385 1386 # logic: 1387 # For each possible container of $cidr 1388 # note the parent id 1389 # walk the chain up the parents 1390 # if we intersect $cidr's current parent, break 1391 # if we've intersected $cidr's current parent 1392 # set some variables to track that block 1393 # break 1394 1395 # Set up part of "is it in the middle of a pool?" check 1396 my $wuzpool = $dbh->selectrow_hashref("SELECT cidr,parent_id,type,city,custid,id FROM allocations ". 1397 "WHERE (type LIKE '_d' OR type LIKE '_p') AND cidr >> ? AND master_id = ?", { Slice => {} }, 1398 ($cidr, $binfo->{master_id}) ); 1399 1400 ##fixme? 1401 # edge cases not handled, or handled badly: 1402 # -> $cidr managed to get to be the entirety of an IP pool 1403 1404 if ($wuzpool && $wuzpool->{id} != $id) { 1405 # we have legacy goo to be purified 1406 # going to ignore nested pools; not possible to create them via API and no current legacy data includes any. 1407 1408 # for convenience 1409 my $poolid = $wuzpool->{id}; 1410 my $pool = $wuzpool->{cidr}; 1411 my $poolcity = $wuzpool->{city}; 1412 my $pooltype = $wuzpool->{type}; 1413 my $poolcustid = $wuzpool->{custid}; 1414 1415 $retcode = 'WARNPOOL'; 1416 $goback = "$poolid,$pool"; 1417 # We've already deleted the block, now we have to stuff its IPs into the pool. 1418 $pooltype =~ s/[dp]$/i/; # change type to static IP 1419 my $sth2 = $dbh->prepare("INSERT INTO poolips (ip,city,type,custid,parent_id) VALUES ". 1420 "(?,'$poolcity','$pooltype','$poolcustid',$poolid)"); 1437 1421 ##fixme: need to not insert net, gateway, and bcast on "real netblock" pools (DHCPish) 1438 $sth2->execute($cidr->addr) unless $cidr->addr =~ m|\.0$|; 1439 foreach my $ip ($cidr->hostenum) { 1440 $sth2->execute($ip); 1441 } 1442 $cidr--; 1443 # don't insert .255 1444 $sth2->execute($cidr->addr) unless $cidr->addr =~ m|\.255$|; 1445 } else { # done returning IPs from a block to a static DSL pool 1422 # don't insert .0 1423 $sth2->execute($cidr->addr) unless $cidr->addr =~ m|\.0$|; 1424 foreach my $ip ($cidr->hostenum) { 1425 $sth2->execute($ip); 1426 } 1427 $cidr--; 1428 # don't insert .255 1429 $sth2->execute($cidr->addr) unless $cidr->addr =~ m|\.255$|; 1430 } 1431 1432 ## important! 1433 # ... or IS IT? 1434 # we may have undef'ed $wuzpool above, if the allocation tree $cidr is in doesn't intersect the pool we found 1435 #if (!$wuzpool) { 1436 1437 else { 1438 1439 # Get all possible (and probably a number of impossible) containers for $cidr 1440 $sth = $dbh->prepare("SELECT cidr,parent_id,type,city,id FROM allocations ". 1441 "WHERE (type LIKE '_m' OR type LIKE '_c') AND cidr >>= ? AND master_id = ? ". 1442 "ORDER BY masklen(cidr) DESC"); 1443 $sth->execute($cidr, $binfo->{master_id}); 1444 1445 # Quickly get certain fields (simpler than getBlockData() 1446 my $sth2 = $dbh->prepare("SELECT cidr,parent_id,type,city FROM allocations ". 1447 "WHERE (type LIKE '_m' OR type LIKE '_c') AND id = ? AND master_id = ?"); 1448 1449 # For each possible container of $cidr... 1450 while (my @data = $sth->fetchrow_array) { 1451 my $i = 0; 1452 # Save some state and set a start point - parent ID of container we're checking 1453 $tparent = $data[0]; 1454 my $ppid = $data[1]; 1455 $trtype = $data[2]; 1456 $tcity = $data[3]; 1457 $tpar_id = $data[4]; 1458 last if $data[4] == $binfo->{parent_id}; # Preemptively break if we're already in the right place 1459 last if $ppid == $binfo->{parent_id}; # ... or if the parent of the container is the block's parent 1460 while (1) { 1461 # Retrieve bits on that parent ID 1462 $sth2->execute($ppid, $binfo->{master_id}); 1463 my @container = $sth2->fetchrow_array; 1464 $ppid = $container[1]; 1465 last if $container[1] == 0; # Break if we've hit a master block 1466 last if $ppid == $binfo->{parent_id}; # Break if we've reached the block $cidr is currently in 1467 } 1468 last if $ppid == $binfo->{parent_id}; 1469 } 1470 1471 # found an alternate parent; reset some parent-info bits 1472 if ($tpar_id != $binfo->{parent_id}) { 1473 $ptype = (split //, $trtype)[1]; 1474 $pcity = $tcity; 1475 $retcode = 'WARNMERGE'; # may be redundant 1476 $p_id = $tpar_id; 1477 } 1478 1479 $goback = "$p_id,$tparent"; # breadcrumb, currently only used in case of live-parent-is-not-true-parent 1480 1481 # Special case - delete pool IPs 1482 if ($binfo->{type} =~ /^.[pd]$/) { 1483 # We have to delete the IPs from the pool listing. 1484 $dbh->do("DELETE FROM poolips WHERE parent_id = ?", undef, ($id) ); 1485 } 1486 1487 $pinfo = getBlockData($dbh, $p_id); 1446 1488 1447 1489 # If the block wasn't legacy goo embedded in a static pool, we check the … … 1452 1494 # move the freeblocks into the parent 1453 1495 # we don't insert a new freeblock because there could be a live reparented sub. 1454 $dbh->do("UPDATE freeblocks SET rdepth=rdepth-1,parent=?,routed=?,city=? ". 1455 "WHERE parent=? AND rdepth=?", undef, 1456 ($parent, $ptype, $pcity, $cidr, $rdepth+1) ); 1496 $dbh->do("UPDATE freeblocks SET parent_id = ?, routed = ?, city = ? WHERE parent_id = ?", undef, 1497 ($p_id, $ptype, $pcity, $id) ); 1457 1498 } else { 1458 1499 # ... otherwise, add the freeblock 1459 $dbh->do("INSERT INTO freeblocks (cidr, city, routed, parent , rdepth) VALUES (?,?,?,?,?)", undef,1460 ($cidr, $pcity, $ptype, $p arent, $rdepth) );1500 $dbh->do("INSERT INTO freeblocks (cidr, city, routed, parent_id, master_id) VALUES (?,?,?,?,?)", undef, 1501 ($cidr, $pcity, $ptype, $p_id, $binfo->{master_id}) ); 1461 1502 } 1462 1503 1463 1504 ##fixme: vrf 1505 ##fixme: simplify since all containers now represent different "layers"/"levels"? 1464 1506 # set up the query to get the list of blocks to try to merge. 1465 $sth = $dbh->prepare("SELECT cidr FROM freeblocks ".1466 "WHERE parent = ? AND routed = ? AND rdepth= ? ".1507 $sth = $dbh->prepare("SELECT cidr,id FROM freeblocks ". 1508 "WHERE parent_id = ? ". 1467 1509 "ORDER BY masklen(cidr) DESC"); 1468 1510 1469 $sth->execute($p arent, $ptype, $fbrdepth);1511 $sth->execute($p_id); 1470 1512 1471 1513 # NetAddr::IP->compact() attempts to produce the smallest inclusive block … … 1477 1519 # $cidr=.32/27, $ip1=.96/27, $ip2=.0/27, and $ip3=.64/27. 1478 1520 1479 my (@rawfb, @combinelist );1521 my (@rawfb, @combinelist, %rawid); 1480 1522 my $i=0; 1481 1523 # for each free block under $parent, push a NetAddr::IP object into one list, and … … 1484 1526 my $testIP = new NetAddr::IP $data[0]; 1485 1527 push @rawfb, $testIP; 1528 $rawid{$data[0]} = $data[1]; 1486 1529 @combinelist = $testIP->compact(@combinelist); 1487 1530 } … … 1489 1532 # now that we have the full list of "compacted" freeblocks, go back over 1490 1533 # the list of raw freeblocks, and delete the ones that got merged. 1491 $sth = $dbh->prepare("DELETE FROM freeblocks WHERE cidr=? AND parent=? AND rdepth=?");1534 $sth = $dbh->prepare("DELETE FROM freeblocks WHERE id = ?"); 1492 1535 foreach my $rawfree (@rawfb) { 1493 1536 next if grep { $rawfree == $_ } @combinelist; # skip if the raw block is in the compacted list 1494 $sth->execute($raw free, $parent, $fbrdepth);1537 $sth->execute($rawid{$rawfree}); 1495 1538 } 1496 1539 1497 1540 # now we walk the new list of compacted blocks, and see which ones we need to insert 1498 $sth = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,parent ,rdepth) VALUES (?,?,?,?,?)");1541 $sth = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,parent_id,master_id) VALUES (?,?,?,?,?)"); 1499 1542 foreach my $cme (@combinelist) { 1500 1543 next if grep { $cme == $_ } @rawfb; # skip if the combined block was in the raw list 1501 $sth->execute($cme, $pcity, $ptype, $p arent, $fbrdepth);1544 $sth->execute($cme, $pcity, $ptype, $p_id, $binfo->{master_id}); 1502 1545 } 1503 1546 … … 1513 1556 } else { 1514 1557 ##fixme: RPC return code? 1515 _rpc('delByCIDR', cidr => "$cidr", user => $user, delforward => $delfwd, delsubs => 'y', parpatt => $ppatt);1558 _rpc('delByCIDR', cidr => "$cidr", rpcuser => $user, delforward => $delfwd, delsubs => 'y', parpatt => $ppatt); 1516 1559 return ($retcode, $goback); 1517 1560 } -
trunk/cgi-bin/main.cgi
r634 r638 821 821 822 822 my $blockdata; 823 824 if ($webvar{rdepth} == 0) { # $webvar{alloctype} eq 'mm' 825 826 $blockdata->{block} = $webvar{block}; 823 $blockdata = getBlockData($ip_dbh, $webvar{block}, $webvar{basetype}); 824 825 if ($blockdata->{parent_id} == 0) { # $webvar{alloctype} eq 'mm' 827 826 $blockdata->{city} = "N/A"; 828 827 $blockdata->{custid} = "N/A"; 829 $blockdata->{type} = 'mm';830 828 $blockdata->{circuitid} = "N/A"; 831 829 $blockdata->{description} = "N/A"; 832 830 $blockdata->{notes} = "N/A"; 833 831 $blockdata->{privdata} = "N/A"; 834 $blockdata->{rdepth} = 0;835 836 } else {837 838 $blockdata = getBlockData($ip_dbh, $webvar{block}, $webvar{rdepth});839 840 832 } # end cases for different alloctypes 841 833 834 $page->param(blockid => $webvar{block}); 835 $page->param(basetype => $webvar{basetype}); 836 842 837 $page->param(block => $blockdata->{block}); 843 844 838 $page->param(rdns => $blockdata->{rdns}); 845 839 … … 853 847 } 854 848 855 $page->param(rdepth => $blockdata->{rdepth});856 849 $page->param(disptype => $disp_alloctypes{$blockdata->{type}}); 857 # $page->param(type => $blockdata->{type});858 850 $page->param(city => $blockdata->{city}); 859 851 $page->param(custid => $blockdata->{custid}); … … 883 875 884 876 # need to retrieve block data before deleting so we can notify on that 885 my $blockinfo = getBlockData($ip_dbh, $webvar{block}, $webvar{rdepth}); 886 887 my ($code,$msg) = deleteBlock($ip_dbh, $webvar{block}, $webvar{rdepth}, $webvar{vrf}, $webvar{delforward}, $authuser); 888 889 $page->param(block => $webvar{block}); 890 $page->param(delparent => $blockinfo->{parent}) if $webvar{rdepth}; 891 $page->param(prdepth => $webvar{rdepth}); 877 my $blockinfo = getBlockData($ip_dbh, $webvar{block}, $webvar{basetype}); 878 my $pinfo = getBlockData($ip_dbh, $blockinfo->{parent_id}, 'b'); 879 880 my ($code,$msg) = deleteBlock($ip_dbh, $webvar{block}, $webvar{basetype}, $webvar{delforward}, $authuser); 881 882 $page->param(block => $blockinfo->{block}); 883 $page->param(delparent_id => $blockinfo->{parent_id});# if $webvar{rdepth}; 884 $page->param(delparent => $pinfo->{block}); 885 $page->param(returnpool => ($webvar{basetype} eq 'i') ); 892 886 if ($code =~ /^WARN(POOL|MERGE)/) { 893 my ($ bp,$bd) = split /,/, $msg;894 $page->param( bparent => $bp);895 $page->param( brdepth => $bd);887 my ($pid,$pcidr) = split /,/, $msg; 888 $page->param(parent_id => $pid); 889 $page->param(parent => $pcidr); 896 890 $page->param(mergeip => $code eq 'WARNPOOL'); 897 891 } … … 901 895 } 902 896 if ($code eq 'OK' || $code =~ /^WARN/) { 903 syslog "notice", "$authuser deallocated ' $webvar{alloctype}'-type netblock $webvar{block} ".897 syslog "notice", "$authuser deallocated '".$blockinfo->{type}."'-type netblock $webvar{block} ". 904 898 $blockinfo->{custid}.", ".$blockinfo->{city}.", desc='".$blockinfo->{description}."'"; 905 mailNotify($ip_dbh, 'da', "REMOVED: $disp_alloctypes{$webvar{alloctype}}$webvar{block}",906 "$disp_alloctypes{$webvar{alloctype}}$webvar{block} deallocated by $authuser\n".899 mailNotify($ip_dbh, 'da', "REMOVED: ".$disp_alloctypes{$blockinfo->{type}}." $webvar{block}", 900 $disp_alloctypes{$blockinfo->{type}}." $webvar{block} deallocated by $authuser\n". 907 901 "CustID: ".$blockinfo->{custid}."\nCity: ".$blockinfo->{city}. 908 902 "\nDescription: ".$blockinfo->{description}."\n");
Note:
See TracChangeset
for help on using the changeset viewer.