Changeset 705 for trunk/cgi-bin


Ignore:
Timestamp:
02/25/15 18:09:13 (10 years ago)
Author:
Kris Deugau
Message:

/trunk

  • Complete internal handling for "shrink block". See #7 (more or less).
  • Add "breadcrumb" navigation fragments to split/shrink prep and do pages
  • Add link to pool IP list on edit and split/shrink prep pages
  • Shave off some useless code showing the split results
  • Catch the theoretically impossible case of "no subact value" on submitting split/shrink form

Still need to add calls to monkey rDNS on split/shrink changes

Location:
trunk/cgi-bin
Files:
2 edited

Legend:

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

    r702 r705  
    3232        &getMasterList &getTypeList &getPoolSelect &findAllocateFrom
    3333        &ipParent &subParent &blockParent &getBreadCrumbs &getRoutedCity
    34         &allocateBlock &updateBlock &splitBlock &deleteBlock &getBlockData &getBlockRDNS &getRDNSbyIP
     34        &allocateBlock &updateBlock &splitBlock &shrinkBlock &deleteBlock &getBlockData
     35        &getBlockRDNS &getRDNSbyIP
    3536        &getNodeList &getNodeName &getNodeInfo
    3637        &mailNotify
     
    4748                &getMasterList &getTypeList &getPoolSelect &findAllocateFrom
    4849                &ipParent &subParent &blockParent &getBreadCrumbs &getRoutedCity
    49                 &allocateBlock &updateBlock &splitBlock &deleteBlock &getBlockData &getBlockRDNS &getRDNSbyIP
     50                &allocateBlock &updateBlock &splitBlock &shrinkBlock &deleteBlock &getBlockData
     51                &getBlockRDNS &getRDNSbyIP
    5052                &getNodeList &getNodeName &getNodeInfo
    5153                &mailNotify
     
    15711573
    15721574
     1575## IPDB::shrinkBlock()
     1576# Shrink an allocation to the passed CIDR block
     1577# Takes an allocation ID and a new CIDR
     1578# Returns an arrayref to a list of hashrefs with the ID and CIDR of the freed block(s)
     1579# Refuses to shrink "real netblock" pool types below /30
     1580sub shrinkBlock {
     1581  my $dbh = shift;
     1582  my $id = shift;
     1583
     1584  # just take the new CIDR spec;  this way we can shrink eg .16/28 to .20/30 without extra contortions
     1585  my $newblock = new NetAddr::IP shift;
     1586
     1587  if (!$newblock) {
     1588    $errstr = "Can't shrink something that's not a netblock";
     1589    return;
     1590  }
     1591
     1592  my $binfo = getBlockData($dbh, $id);
     1593  my $pinfo = getBlockData($dbh, $binfo->{parent_id});
     1594
     1595  if ($binfo->{type} =~ /.d/ && $newblock->masklen > ($newblock->bits+2) ) {
     1596    $errstr = "Can't shrink a non-PPP pool smaller than ".($newblock->{isv6} ? '/124' : '/30');
     1597    return;
     1598  }
     1599
     1600  my $oldblock = new NetAddr::IP $binfo->{block};
     1601
     1602  # Don't try to shrink the block outside of itself, Bad Things (probably) Happen.
     1603  if (!$oldblock->contains($newblock)) {
     1604    $errstr = "Can't shrink an allocation outside of itself";
     1605    return;
     1606  }
     1607
     1608  local $dbh->{AutoCommit} = 0;
     1609  local $dbh->{RaiseError} = 1;
     1610
     1611  my $fbsth = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,vrf,parent_id,master_id) VALUES (?,?,?,?,?,?)");
     1612  my $idsth = $dbh->prepare("SELECT currval('freeblocks_id_seq')");
     1613  my $poolsth = $dbh->prepare("DELETE FROM poolips WHERE parent_id = ? AND ip << ?");
     1614  my $netsth = $dbh->prepare("DELETE FROM poolips WHERE parent_id = ? AND ip = ?");
     1615
     1616  my @ret;
     1617  eval {
     1618    $dbh->do("UPDATE allocations SET cidr = ? WHERE id = ?", undef, $newblock, $id);
     1619
     1620    # find the netblock(s) that are now free
     1621    my @workingblocks = $oldblock->split($newblock->masklen);
     1622    my @wb2;
     1623    foreach my $newsub (@workingblocks) {
     1624      next if $newsub == $newblock;
     1625      push @wb2, $newsub;
     1626    }
     1627    @wb2 = Compact(@wb2);
     1628
     1629    # set new freeblocks, and clean up any IP pool entries if needed.
     1630    foreach my $newfree (@wb2) {
     1631      # add as freeblock
     1632      $fbsth->execute($newfree, $pinfo->{city}, (split //, $pinfo->{type})[1], $pinfo->{vrf},
     1633        $binfo->{parent_id}, $binfo->{master_id});
     1634      $idsth->execute;
     1635      my ($nid) = $idsth->fetchrow_array();
     1636      # add to return list
     1637      push @ret, {fbid => $nid, newfree => "$newfree", fbparent => $binfo->{parent_id} };
     1638      # clean up pool IPs if necessary
     1639      if ($binfo->{type} =~ /.[dp]/) {
     1640        $poolsth->execute($id, $newfree);
     1641      }
     1642    }
     1643
     1644    # additional cleanup on net/gw/bcast IPs in pool
     1645    if ($binfo->{type} =~ /.d/) {
     1646      $netsth->execute($id, $newblock->addr);
     1647      $newblock++;
     1648      $netsth->execute($id, $newblock->addr);
     1649      $newblock--;
     1650      $newblock--;
     1651      $netsth->execute($id, $newblock->addr);
     1652    }
     1653
     1654    $dbh->commit;
     1655  };
     1656  if ($@) {
     1657    $errstr = "Error splitting $binfo->{block}: $@";
     1658    $dbh->rollback;
     1659    return;
     1660  }
     1661
     1662  return \@ret;
     1663} # end shrinkBlock()
     1664
     1665
    15731666## IPDB::deleteBlock()
    15741667# Removes an allocation from the database, including deleting IPs
  • trunk/cgi-bin/main.cgi

    r702 r705  
    875875  $utilbar->param(breadcrumb => \@rcrumbs);
    876876
     877  # Show link to IP list for pools
     878  $page->param(ispool => 1) if $blockinfo->{type} =~ /^.[dp]$/;
     879
    877880  # Clean up extra whitespace on alloc type.  Mainly a legacy-data cleanup.
    878881  $blockinfo->{type} =~ s/\s//;
     
    10921095  my $blockinfo = getBlockData($ip_dbh, $webvar{block});
    10931096
     1097  # Tree navigation
     1098  my $crumbs = getBreadCrumbs($ip_dbh, $blockinfo->{parent_id});
     1099  my @rcrumbs = reverse (@$crumbs);
     1100  $utilbar->param(breadcrumb => \@rcrumbs);
     1101
    10941102  if ($blockinfo->{type} =~ /^.i$/) {
    10951103    $page->param(err => "Can't split a single IP allocation");
     
    11101118  if ($blockinfo->{type} =~ /^.d$/) {
    11111119    # Non-PPP pools
     1120    $page->param(ispool => 1);
    11121121    if ($oldmask+2 >= $block->bits) {
    11131122      $page->param(err => "Can't split a standard netblock pool any further");
     
    11171126    $page->param(sp4mask => $oldmask+2) if $oldmask+2 <= $block->bits-2;
    11181127  } elsif ($blockinfo->{type} =~ /.p/) {
     1128    $page->param(ispool => 1);
    11191129    # Allow splitting PPP pools down to v4 /31
    11201130    $page->param(sp4mask => $oldmask+2) if $oldmask+2 <= $block->bits-1;
     
    11441154  my $blockinfo = getBlockData($ip_dbh, $webvar{block});
    11451155
     1156  # Tree navigation
     1157  my $crumbs = getBreadCrumbs($ip_dbh, $blockinfo->{parent_id});
     1158  my @rcrumbs = reverse (@$crumbs);
     1159  $utilbar->param(breadcrumb => \@rcrumbs);
     1160
    11461161  if ($blockinfo->{type} =~ /^.i$/) {
    11471162    $page->param(err => "Can't split a single IP allocation");
     
    11511166  if ($webvar{subact} eq 'split') {
    11521167    $page->param(issplit => 1);
    1153     my $binfo = getBlockData($ip_dbh, $webvar{block});
    1154     $page->param(cidr => $binfo->{block});
    1155     my $block = new NetAddr::IP $binfo->{block};
     1168    my $block = new NetAddr::IP $blockinfo->{block};
    11561169    my $newblocks = splitBlock($ip_dbh, $webvar{block}, 'b', $webvar{split});
    11571170    if ($newblocks) {
    11581171      $page->param(newblocks => $newblocks);
    1159       # and the backlink to the parent container
    1160       my $pinfo = getBlockData($ip_dbh, $binfo->{parent_id});
    1161       $page->param(backid => $binfo->{parent_id});
    1162       $page->param(backblock => $pinfo->{block});
    11631172    } else {
    11641173      $page->param(err => $IPDB::errstr);
    11651174    }
    11661175
     1176  } elsif ($webvar{subact} eq 'shrink') {
     1177    $page->param(nid => $webvar{block});
     1178    $page->param(newblock => $webvar{shrink});
     1179    my $newfree = shrinkBlock($ip_dbh, $webvar{block}, $webvar{shrink});
     1180    if ($newfree) {
     1181      $page->param(newfb => $newfree);
     1182    } else {
     1183      $page->param(err => $IPDB::errstr);
     1184    }
     1185
    11671186  } else {
    1168     # Shrink
    1169   }
     1187    # Your llama is on fire.
     1188    $page->param(err => "Missing form field that shouldn't be missing.");
     1189    return;
     1190  }
     1191
     1192  # common bits
     1193  $page->param(cidr => $blockinfo->{block});
     1194  # and the backlink to the parent container
     1195  my $pinfo = getBlockData($ip_dbh, $blockinfo->{parent_id});
     1196  $page->param(backid => $blockinfo->{parent_id});
     1197  $page->param(backblock => $pinfo->{block});
    11701198} # doSplit()
    11711199
Note: See TracChangeset for help on using the changeset viewer.