- Timestamp:
- 12/01/04 15:29:09 (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cgi-bin/IPDB.pm
r80 r93 22 22 @ISA = qw(Exporter); 23 23 @EXPORT_OK = qw(&initIPDBGlocals &connectDB &finish &checkDBSanity &allocateBlock 24 & mailNotify);24 &deleteBlock &mailNotify); 25 25 26 26 @EXPORT = (); # Export nothing by default. 27 27 %EXPORT_TAGS = ( ALL => [qw( &initIPDBGlocals &connectDB &finish &checkDBSanity 28 &allocateBlock & mailNotify)]28 &allocateBlock &deleteBlock &mailNotify)] 29 29 ); 30 30 … … 337 337 338 338 339 ## IPDB::deleteBlock() 340 # Removes an allocation from the database, including deleting IPs 341 # from poolips and recombining entries in freeblocks if possible 342 # Also handles "deleting" a static IP allocation, and removal of a master 343 # Requires a database handle, the block to delete, and the type of block 344 sub deleteBlock { 345 my ($dbh,undef,$type) = @_; 346 my $cidr = new NetAddr::IP $_[1]; 347 348 my $sth; 349 350 # To contain the error message, if any. 351 my $msg = "Unknown error deallocating $type $cidr"; 352 # Enable transactions and exception-on-errors... but only for this sub 353 local $dbh->{AutoCommit} = 0; 354 local $dbh->{RaiseError} = 1; 355 356 # First case. The "block" is a static IP 357 # Note that we still need some additional code in the odd case 358 # of a netblock-aligned contiguous group of static IPs 359 if ($type =~ /^.i$/) { 360 361 eval { 362 $msg = "Unable to deallocate $type $cidr"; 363 $sth = $dbh->prepare("update poolips set custid='6750400',available='y',". 364 "city=(select city from allocations ". 365 "where cidr=(select pool from poolips where ip='$cidr')),". 366 "description='',notes='',circuitid='' where ip='$cidr'"); 367 $sth->execute; 368 $dbh->commit; 369 }; 370 if ($@) { 371 eval { $dbh->rollback; }; 372 return ('FAIL',$msg); 373 } else { 374 return ('OK',"OK"); 375 } 376 377 } elsif ($type eq 'mm') { # end alloctype =~ /.i/ 378 379 $msg = "Unable to delete master block $cidr"; 380 eval { 381 $sth = $dbh->prepare("delete from masterblocks where cidr='$cidr'"); 382 $sth->execute; 383 $sth = $dbh->prepare("delete from freeblocks where cidr='$cidr'"); 384 $sth->execute; 385 $dbh->commit; 386 }; 387 if ($@) { 388 eval { $dbh->rollback; }; 389 return ('FAIL', $msg); 390 } else { 391 return ('OK',"OK"); 392 } 393 394 } else { # end alloctype master block case 395 396 ## This is a big block; but it HAS to be done in a chunk. Any removal 397 ## of a netblock allocation may result in a larger chunk of free 398 ## contiguous IP space - which may in turn be combined into a single 399 ## netblock rather than a number of smaller netblocks. 400 401 eval { 402 403 if ($type eq 'rr') { 404 $msg = "Unable to remove routing allocation $cidr"; 405 $sth = $dbh->prepare("delete from routed where cidr='$cidr'"); 406 $sth->execute; 407 # Make sure block getting deleted is properly accounted for. 408 $sth = $dbh->prepare("update freeblocks set routed='n',city='<NULL>'". 409 " where cidr='$cidr'"); 410 $sth->execute; 411 # Set up query to start compacting free blocks. 412 $sth = $dbh->prepare("select * from freeblocks where ". 413 "maskbits<=".$cidr->masklen." and routed='n' order by maskbits desc"); 414 415 } else { # end alloctype routing case 416 417 $sth = $dbh->prepare("delete from allocations where cidr='$cidr'"); 418 $sth->execute; 419 # Special case - delete pool IPs 420 if ($type =~ /^.p$/) { 421 # We have to delete the IPs from the pool listing. 422 $sth = $dbh->prepare("delete from poolips where pool='$cidr'"); 423 $sth->execute; 424 } 425 426 # Set up query for compacting free blocks. 427 $sth = $dbh->prepare("select * from freeblocks where cidr << ". 428 "(select cidr from routed where cidr >> '$cidr') ". 429 " and maskbits<=".$cidr->masklen." and routed='y' order by maskbits desc"); 430 431 } # end alloctype general case 432 433 # Now we look for larger-or-equal-sized free blocks in the same master (routed) 434 # (super)block. If there aren't any, we can't combine blocks anyway. If there 435 # are, we check to see if we can combine blocks. 436 # Execute the statement prepared in the if-else above. 437 438 $sth->execute; 439 440 # NetAddr::IP->compact() attempts to produce the smallest inclusive block 441 # from the caller and the passed terms. 442 # EG: if you call $cidr->compact($ip1,$ip2,$ip3) when $cidr, $ip1, $ip2, 443 # and $ip3 are consecutive /27's starting on .0 (.0-.31, .32-.63, 444 # .64-.95, and .96-.128), you will get an array containing a single 445 # /25 as element 0 (.0-.127). Order is not important; you could have 446 # $cidr=.32/27, $ip1=.96/27, $ip2=.0/27, and $ip3=.64/27. 447 448 my (@together, @combinelist); 449 my $i=0; 450 while (my @data = $sth->fetchrow_array) { 451 my $testIP = new NetAddr::IP $data[0]; 452 @together = $testIP->compact($cidr); 453 my $num = @together; 454 if ($num == 1) { 455 $cidr = $together[0]; 456 $combinelist[$i++] = $testIP; 457 } 458 } 459 460 # Clear old freeblocks entries - if any. $i==0 if not. 461 if ($i>0) { 462 $sth = $dbh->prepare("delete from freeblocks where cidr=?"); 463 foreach my $block (@combinelist) { 464 $sth->execute("$block"); 465 } 466 } 467 468 # insert "new" freeblocks entry 469 if ($type eq 'rr') { 470 $sth = $dbh->prepare("insert into freeblocks values ('$cidr',".$cidr->masklen. 471 ",'<NULL>','n')"); 472 } else { 473 $sth = $dbh->prepare("insert into freeblocks values ('$cidr',".$cidr->masklen. 474 ",(select city from routed where cidr >>= '$cidr'),'y')"); 475 } 476 $sth->execute; 477 478 # If we got here, we've succeeded. Whew! 479 $dbh->commit; 480 }; # end eval 481 if ($@) { 482 eval { $dbh->rollback; }; 483 return ('FAIL', $msg); 484 } else { 485 return ('OK',"OK"); 486 } 487 488 } # end alloctype != netblock 489 490 } # end deleteBlock() 491 492 339 493 ## IPDB::mailNotify() 340 494 # Sends notification mail to recipients regarding an IPDB operation
Note:
See TracChangeset
for help on using the changeset viewer.