Changeset 728


Ignore:
Timestamp:
05/21/15 14:44:34 (10 years ago)
Author:
Kris Deugau
Message:

/trunk

Stub out major logic branches for mergeBlocks(), and flesh out some prep
operations. See #8.

File:
1 edited

Legend:

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

    r726 r728  
    3232        &getMasterList &getTypeList &getPoolSelect &findAllocateFrom
    3333        &ipParent &subParent &blockParent &getBreadCrumbs &getRoutedCity
    34         &allocateBlock &updateBlock &splitBlock &shrinkBlock &deleteBlock &getBlockData
     34        &allocateBlock &updateBlock &splitBlock &shrinkBlock &mergeBlocks &deleteBlock &getBlockData
    3535        &getBlockRDNS &getRDNSbyIP
    3636        &getNodeList &getNodeName &getNodeInfo
     
    4848                &getMasterList &getTypeList &getPoolSelect &findAllocateFrom
    4949                &ipParent &subParent &blockParent &getBreadCrumbs &getRoutedCity
    50                 &allocateBlock &updateBlock &splitBlock &shrinkBlock &deleteBlock &getBlockData
     50                &allocateBlock &updateBlock &splitBlock &shrinkBlock &mergeBlocks &deleteBlock &getBlockData
    5151                &getBlockRDNS &getRDNSbyIP
    5252                &getNodeList &getNodeName &getNodeInfo
     
    19981998
    19991999
     2000## IPDB::mergeBlocks()
     2001# Merges two or more adjacent allocations, optionally including relevant
     2002# free space, into one allocation.
     2003# Takes a "base" block ID and a hash with a mask length and a scope argument to decide
     2004# how much existing allocation data to delete.
     2005## Merge scope:
     2006# Merge to container
     2007#   keepall
     2008#     Move all mergeable allocations into the new block
     2009#     Move all mergeable free blocks into the new block
     2010#   mergepeer
     2011#     Move subs of mergeable containers into the updated primary.
     2012#     Reparent free blocks in mergeable containers to the updated primary.
     2013#     Convert assigned IPs from pools into subs.
     2014#     Convert unused IPs from pools into free blocks.
     2015#     Convert leaf allocations into free blocks.
     2016#   clearpeer
     2017#     Keep subs of the original
     2018#     Convert assigned IPs from pools into subs.
     2019#     Convert unused IPs from pools into free blocks.
     2020#     Convert leaf allocations into free blocks.
     2021#   clearall
     2022#     Delete all peers, subs and IPs.
     2023#     Add single free block for new container.
     2024# Merge to pool
     2025#   keepall
     2026#     Convert all leaf allocations in the merge range to groups of used IPs
     2027#   mergepeer
     2028#     Effectively equal to keepall
     2029#   clearpeer
     2030#     Only convert IPs from the original allocation to used IPs
     2031#   clearall
     2032#     Delete any existing IPs, and reinitialize the new pool entirely
     2033# Merge to leaf type
     2034#   Remove all subs
     2035sub mergeBlocks {
     2036  my $dbh = shift;
     2037  my $prime = shift;  # "base" block ID to use as a starting point
     2038  if (!$prime) {
     2039    $errstr = "Missing block ID to base merge on";
     2040    return;
     2041  }
     2042
     2043  my %args = @_;
     2044
     2045  # check key arguments.
     2046  if (!$args{scope} || $args{scope} !~ /^(keepall|mergepeer|clearpeer|clearall)$/) {
     2047    $errstr = "Bad or missing merge scope";
     2048    return;
     2049  }
     2050  if (!$args{newmask} || $args{newmask} !~ /^\d+$/) {
     2051    $errstr = "Bad or missing new netmask";
     2052    return;
     2053  }
     2054
     2055  # Retrieve info about the base allocation we're munging
     2056  my $binfo = getBlockData($dbh, $prime);
     2057  my $block = new NetAddr::IP $binfo->{block};
     2058  my ($basetype) = ($binfo->{type} =~ /^.(.)$/);
     2059  $binfo->{id} = $prime;  # preserve for later, just in case
     2060
     2061  # proposed block
     2062  my $newblock = new NetAddr::IP $block->addr."/$args{newmask}";
     2063  $newblock = $newblock->network;
     2064  $args{newtype} = $binfo->{type} if !$args{newtype};
     2065  # if the "primary" block being changed is a master, it must remain one.
     2066  $args{newtype} = 'mm' if $binfo->{type} eq 'mm';
     2067  my ($newcontainerclass) = ($args{newtype} =~ /^(.).$/);
     2068
     2069  # build an info hash for the "new" allocation we're creating
     2070  my $pinfo = {
     2071      id => $prime,
     2072      block => "$newblock",
     2073      type => $args{newtype},
     2074      parent_id =>
     2075      $binfo->{parent_id},
     2076      city => $binfo->{city},
     2077      vrf => $binfo->{vrf},
     2078      master_id => $binfo->{master_id}
     2079    };
     2080
     2081  my @retlist;
     2082
     2083  # Want to do all of the DB stuff in a transaction, to minimize data changing underfoot
     2084  eval {
     2085
     2086    # We always update the "prime" block passed in...
     2087    $dbh->do("UPDATE allocations SET cidr = ?, type = ? WHERE id = ?", undef,
     2088        ($newblock, $args{newtype}, $prime) )
     2089        # ... but only on existing container or pool types.  Leaf -> container conversions
     2090        # may need a new parent inserted instead.
     2091        if $basetype =~ /[cm]/;
     2092
     2093    # For leaf blocks, we may need to create a new parent as the "primary" instead
     2094    # of updating the existing block
     2095    my $newparent = $dbh->prepare(q{
     2096        INSERT INTO allocations (
     2097                cidr, type, city, description, notes, circuitid, createstamp, modifystamp,
     2098                privdata, custid, swip, vrf, vlan, rdns, parent_id, master_id
     2099            )
     2100        SELECT
     2101                ? AS cidr, ? AS type, city, description, notes, circuitid, createstamp, modifystamp,
     2102                privdata, custid, swip, vrf, vlan, rdns, parent_id, master_id
     2103            FROM allocations
     2104            WHERE id = ?
     2105        });
     2106
     2107    # Convert a bunch of pool IP allocations into "normal" netblock allocations
     2108    my $pool2alloc = $dbh->prepare(q{
     2109        INSERT INTO allocations (
     2110                cidr,type,city, description, notes, circuitid, createstamp, modifystamp,
     2111                privdata, custid, vrf, vlan, rdns, parent_id, master_id
     2112            )
     2113        SELECT
     2114                ip, ? AS type, city, description, notes, circuitid, createstamp, modifystamp,
     2115                privdata, custid, vrf, vlan, rdns, parent_id, master_id
     2116            FROM poolips
     2117            WHERE parent_id = ? AND available = 'n'
     2118        });
     2119
     2120    # Common actions
     2121    my $peersth = $dbh->prepare("SELECT cidr,id,type,master_id FROM allocations WHERE parent_id = ? AND cidr <<= ?");
     2122    $peersth->execute($binfo->{parent_id}, "$newblock");
     2123    my $reparentsth = $dbh->prepare("UPDATE allocations SET parent_id = ?, master_id = ? WHERE id = ?");
     2124    my $insfbsth = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,vrf,parent_id,master_id) VALUES (?,?,?,?,?,?)");
     2125
     2126    my $fbreparentsth = $dbh->prepare(q{
     2127        UPDATE freeblocks
     2128            SET parent_id = ?, master_id = ?, city = ?, routed = ?, vrf = ?
     2129            WHERE parent_id = ? AND cidr <<= ?
     2130        });
     2131
     2132    if ($args{newtype} =~ /.[cm]/) {
     2133      ## Container
     2134
     2135    } elsif ($args{newtype} =~ /.[dp]/) {
     2136      ## Pool
     2137
     2138    } elsif ($args{newtype} =~ /.[enr]/) {
     2139      ## Leaf
     2140
     2141    } # new type if()
     2142
     2143    $dbh->commit;
     2144  };
     2145  if ($@) {
     2146    my $msg = $@;
     2147    $errstr = $msg;
     2148    $dbh->rollback;
     2149    return ('FAIL',$msg);
     2150  }
     2151
     2152  return \@retlist;
     2153
     2154} # end mergeBlocks()
     2155
     2156
    20002157## IPDB::deleteBlock()
    20012158# Removes an allocation from the database, including deleting IPs
Note: See TracChangeset for help on using the changeset viewer.