Changeset 633 for trunk/cgi-bin
- Timestamp:
- 10/08/14 18:01:55 (10 years ago)
- Location:
- trunk/cgi-bin
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cgi-bin/IPDB.pm
r632 r633 738 738 my $failmsg = "No suitable free block found\n"; 739 739 740 my @vallist; 741 my $sql; 742 743 # Free pool IPs should be easy. 744 if ($type =~ /^.i$/) { 745 # User may get an IP from the wrong VRF. User should not be using admin tools to allocate static IPs. 746 $sql = "SELECT id, ip, parent_id FROM poolips WHERE ip = ?"; 747 @vallist = ($optargs{gimme}); 748 } else { 749 740 750 ## Set up the SQL to find out what freeblock we can (probably) use for an allocation. 741 751 ## Very large systems will require development of a reserve system (possibly an extension … … 743 753 ## Also populate a value list for the DBI call. 744 754 745 my@vallist = ($maskbits);746 my $sql = "SELECT cidr,rdepthFROM freeblocks WHERE masklen(cidr) <= ?";755 @vallist = ($maskbits); 756 $sql = "SELECT id,cidr,parent_id FROM freeblocks WHERE masklen(cidr) <= ?"; 747 757 748 758 # cases, strict rules … … 765 775 ##fixme: strict-or-not flag 766 776 777 ##fixme: config or UI flag for "Strict" mode 778 # if ($strictmode) { 779 if (0) { 767 780 if ($type =~ /^(.)r$/) { 768 781 push @vallist, $1; … … 773 786 $sql .= " AND routed = 'r'"; 774 787 } 775 776 # for PPP(oE) and container types, the POP city is the one attached to the pool. 777 # individual allocations get listed with the customer city site. 778 ##fixme: chain cities to align roughly with a full layer-2 node graph 779 $city = $pop if $type !~ /^.[pc]$/; 780 if ($type ne 'rm' && $city) { 781 $sql .= " AND city = ?"; 782 push @vallist, $city; 783 } 784 # Allow specifying an arbitrary full block, instead of a master 785 if ($optargs{gimme}) { 786 $sql .= " AND cidr >>= ?"; 787 push @vallist, $optargs{gimme}; 788 } 789 # if a specific master was requested, allow the requestor to self->shoot(foot) 790 if ($optargs{master} && $optargs{master} ne '-') { 791 $sql .= " AND cidr <<= ?" if $optargs{master} ne '-'; 792 push @vallist, $optargs{master}; 793 } else { 794 # if a specific master was NOT requested, filter out the RFC 1918 private networks 795 if (!$optargs{allowpriv}) { 796 $sql .= " AND NOT (cidr <<= '192.168.0.0/16' OR cidr <<= '10.0.0.0/8' OR cidr <<= '172.16.0.0/12')"; 797 } 798 } 799 # Sorting and limiting, since we don't (currently) care to provide a selection of 800 # blocks to carve up. This preserves something resembling optimal usage of the IP 801 # space by forcing contiguous allocations and free blocks as much as possible. 802 $sql .= " ORDER BY maskbits DESC,cidr LIMIT 1"; 803 804 my ($fbfound,$fbdepth) = $dbh->selectrow_array($sql, undef, @vallist); 805 return $fbfound,$fbdepth; 788 } 789 790 # for PPP(oE) and container types, the POP city is the one attached to the pool. 791 # individual allocations get listed with the customer city site. 792 ##fixme: chain cities to align roughly with a full layer-2 node graph 793 $city = $pop if $type !~ /^.[pc]$/; 794 if ($type ne 'rm' && $city) { 795 $sql .= " AND city = ?"; 796 push @vallist, $city; 797 } 798 # Allow specifying an arbitrary full block, instead of a master 799 if ($optargs{gimme}) { 800 $sql .= " AND cidr >>= ?"; 801 push @vallist, $optargs{gimme}; 802 } 803 # if a specific master was requested, allow the requestor to self->shoot(foot) 804 if ($optargs{master} && $optargs{master} ne '-') { 805 $sql .= " AND master_id = ?"; 806 # if $optargs{master} ne '-'; 807 push @vallist, $optargs{master}; 808 } else { 809 # if a specific master was NOT requested, filter out the RFC 1918 private networks 810 if (!$optargs{allowpriv}) { 811 $sql .= " AND NOT (cidr <<= '192.168.0.0/16' OR cidr <<= '10.0.0.0/8' OR cidr <<= '172.16.0.0/12')"; 812 } 813 } 814 # Sorting and limiting, since we don't (currently) care to provide a selection of 815 # blocks to carve up. This preserves something resembling optimal usage of the IP 816 # space by forcing contiguous allocations and free blocks as much as possible. 817 $sql .= " ORDER BY masklen(cidr) DESC,cidr LIMIT 1"; 818 } # done setting up SQL for free CIDR block 819 820 my ($fbid,$fbfound,$fbparent) = $dbh->selectrow_array($sql, undef, @vallist); 821 return $fbid,$fbfound,$fbparent; 806 822 } # end findAllocateFrom() 807 823 … … 872 888 873 889 $args{cidr} = new NetAddr::IP $args{cidr}; 874 $args{alloc_from} = new NetAddr::IP $args{alloc_from};875 890 876 891 $args{desc} = '' if !$args{desc}; … … 883 898 my $sth; 884 899 885 # Snag the "type" of the freeblock (alloc_from) "just in case" 886 $sth = $dbh->prepare("select routed from freeblocks where cidr='$args{alloc_from}'"); 887 $sth->execute; 888 my ($alloc_from_type) = $sth->fetchrow_array; 900 # Snag the "type" of the freeblock and its CIDR 901 my ($alloc_from_type, $alloc_from, $fbparent, $fcity, $fbmaster) = 902 $dbh->selectrow_array("SELECT routed,cidr,parent_id,city,master_id FROM freeblocks WHERE id = ?", 903 undef, $args{fbid}); 904 $alloc_from = new NetAddr::IP $alloc_from; 889 905 890 906 # To contain the error message, if any. … … 908 924 undef, ($args{alloc_from}) ); 909 925 } 910 $dbh->do("UPDATE poolips SET custid=?,city=?,available='n',description=?,notes=?,circuitid=?,privdata=?,vrf=?,rdns=? ". 911 "WHERE ip=?", undef, ($args{custid}, $args{city}, $args{desc}, $args{notes}, $args{circid}, 912 $args{privdata}, $args{vrf}, $args{rdns}, $args{cidr}) ); 926 $dbh->do("UPDATE poolips SET custid = ?, city = ?,available='n', description = ?, notes = ?, ". 927 "circuitid = ?, privdata = ?, vrf = ?, rdns = ? ". 928 "WHERE ip = ? AND parent_id = ?", undef, 929 ($args{custid}, $args{city}, $args{desc}, $args{notes}, 930 $args{circid}, $args{privdata}, $args{vrf}, $args{rdns}, 931 $args{cidr}, $args{parent}) ); 913 932 914 933 # node hack … … 931 950 } else { # end IP-from-pool allocation 932 951 933 if ($args{cidr} == $a rgs{alloc_from}) {952 if ($args{cidr} == $alloc_from) { 934 953 # Easiest case- insert in one table, delete in the other, and go home. More or less. 935 954 # insert into allocations values (cidr,custid,type,city,desc) and … … 940 959 $msg = "Unable to allocate $args{cidr} as '$disp_alloctypes{$args{type}}'"; 941 960 942 # Get old freeblocks parent/depth/routed for new entries... before we delete it. 943 my ($fparent) = $dbh->selectrow_array("SELECT parent FROM freeblocks WHERE cidr=? AND rdepth=?", 944 undef, ($args{alloc_from}, $args{rdepth}) ); 961 # Insert the allocations entry 962 $dbh->do("INSERT INTO allocations ". 963 "(cidr,parent_id,master_id,vrf,custid,type,city,description,notes,circuitid,privdata,rdns)". 964 " VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", undef, 965 ($args{cidr}, $fbparent, $fbmaster, $args{vrf}, $args{custid}, $args{type}, $args{city}, 966 $args{desc}, $args{notes}, $args{circid}, $args{privdata}, $args{rdns}) ); 967 my ($bid) = $dbh->selectrow_array("SELECT currval('allocations_id_seq')"); 945 968 946 969 # Munge freeblocks … … 948 971 # special case - block is a routed or container/"reserve" block 949 972 my $rtype = $1; 950 $dbh->do("UPDATE freeblocks SET routed =?,rdepth=rdepth+1,city=?,parent=? WHERE cidr=? AND rdepth=?",951 undef, ($rtype, $args{city}, $ args{cidr}, $args{cidr}, $args{rdepth}) );973 $dbh->do("UPDATE freeblocks SET routed = ?,city = ?,parent_id = ? WHERE id = ?", 974 undef, ($rtype, $args{city}, $bid, $args{fbid}) ); 952 975 } else { 953 976 # "normal" case 954 $dbh->do("DELETE FROM freeblocks WHERE cidr=? AND rdepth=?", undef, ($args{cidr}, $args{rdepth}));977 $dbh->do("DELETE FROM freeblocks WHERE id = ?", undef, ($args{fbid}) ); 955 978 } 956 957 # Insert the allocations entry958 $dbh->do("INSERT INTO allocations ".959 "(cidr,parent,vrf,rdepth,custid,type,city,description,notes,circuitid,privdata,rdns)".960 " VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", undef,961 ($args{cidr}, $fparent, $args{vrf}, $args{rdepth}, $args{custid}, $args{type}, $args{city},962 $args{desc}, $args{notes}, $args{circid}, $args{privdata}, $args{rdns}) );963 979 964 980 # And initialize the pool, if necessary … … 967 983 if ($args{type} =~ /^.p$/) { 968 984 $msg = "Could not initialize IPs in new $disp_alloctypes{$args{type}} $args{cidr}"; 969 my ($code,$rmsg) = initPool($dbh, $args{cidr}, $args{type}, $args{city}, "all", $ args{rdepth}+1);985 my ($code,$rmsg) = initPool($dbh, $args{cidr}, $args{type}, $args{city}, "all", $bid); 970 986 die $rmsg if $code eq 'FAIL'; 971 987 } elsif ($args{type} =~ /^.d$/) { 972 988 $msg = "Could not initialize IPs in new $disp_alloctypes{$args{type}} $args{cidr}"; 973 my ($code,$rmsg) = initPool($dbh, $args{cidr}, $args{type}, $args{city}, "normal", $ args{rdepth}+1);989 my ($code,$rmsg) = initPool($dbh, $args{cidr}, $args{type}, $args{city}, "normal", $bid); 974 990 die $rmsg if $code eq 'FAIL'; 975 991 } … … 992 1008 993 1009 # Hard case. Allocation is smaller than free block. 1010 1011 # make sure new allocation is in fact within freeblock. *sigh* 1012 return ('FAIL',"Requested allocation $args{cidr} is not within $alloc_from") 1013 if !$alloc_from->contains($args{cidr}); 994 1014 my $wantmaskbits = $args{cidr}->masklen; 995 my $maskbits = $a rgs{alloc_from}->masklen;1015 my $maskbits = $alloc_from->masklen; 996 1016 997 1017 my @newfreeblocks; # Holds free blocks generated from splitting the source freeblock. … … 1001 1021 # block is in, and repeat until the wanted block is equal to one of the halves. 1002 1022 my $i=0; 1003 my $tmp_from = $a rgs{alloc_from}; # So we don't munge $args{alloc_from}1023 my $tmp_from = $alloc_from; # So we don't munge $args{alloc_from} 1004 1024 while ($maskbits++ < $wantmaskbits) { 1005 1025 my @subblocks = $tmp_from->split($maskbits); … … 1012 1032 $msg = "Unable to allocate $args{cidr} as '$disp_alloctypes{$args{type}}'"; 1013 1033 1014 # Get old freeblocks parent/depth/routed for new entries1015 my ($fparent,$fcity,$wasrouted) = $dbh->selectrow_array("SELECT parent,city,routed FROM freeblocks".1016 " WHERE cidr=? AND rdepth=?", undef, ($args{alloc_from}, $args{rdepth}) );1017 1018 1034 # Delete old freeblocks entry 1019 $dbh->do("DELETE FROM freeblocks WHERE cidr=? AND rdepth=?", undef, ($args{alloc_from}, $args{rdepth}) );1035 $dbh->do("DELETE FROM freeblocks WHERE id = ?", undef, ($args{fbid}) ); 1020 1036 1021 1037 # Insert new list of smaller free blocks left over 1022 $sth = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,vrf,parent ,rdepth) VALUES (?,?,?,?,?,?)");1038 $sth = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,vrf,parent_id,master_id) VALUES (?,?,?,?,?,?)"); 1023 1039 foreach my $block (@newfreeblocks) { 1024 $sth->execute($block, $fcity, $ wasrouted, $args{vrf}, $fparent, $args{rdepth});1040 $sth->execute($block, $fcity, $alloc_from_type, $args{vrf}, $fbparent, $fbmaster); 1025 1041 } 1042 1043 # Insert the allocations entry 1044 $dbh->do("INSERT INTO allocations ". 1045 "(cidr,parent_id,master_id,vrf,custid,type,city,description,notes,circuitid,privdata,rdns)". 1046 " VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", undef, 1047 ($args{cidr}, $fbparent, $fbmaster, $args{vrf}, $args{custid}, $args{type}, $args{city}, 1048 $args{desc}, $args{notes}, $args{circid}, $args{privdata}, $args{rdns}) ); 1049 my ($bid) = $dbh->selectrow_array("SELECT currval('allocations_id_seq')"); 1026 1050 1027 1051 # For routed/container types, add a freeblock within the allocated block so we can subdivide it further 1028 1052 if ($args{type} =~ /(.)[mc]/) { # rm and .c types - containers 1029 1053 my $rtype = $1; 1030 $sth->execute($args{cidr}, $args{city}, $rtype, $args{vrf}, $ args{cidr}, $args{rdepth}+1);1054 $sth->execute($args{cidr}, $args{city}, $rtype, $args{vrf}, $bid, $fbmaster); 1031 1055 } 1032 1033 # Insert the allocations entry1034 $dbh->do("INSERT INTO allocations ".1035 "(cidr,parent,vrf,rdepth,custid,type,city,description,notes,circuitid,privdata,rdns)".1036 " VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", undef,1037 ($args{cidr}, $fparent, $args{vrf}, $args{rdepth}, $args{custid}, $args{type}, $args{city},1038 $args{desc}, $args{notes}, $args{circid}, $args{privdata}, $args{rdns}) );1039 1056 1040 1057 # And initialize the pool, if necessary … … 1043 1060 if ($args{type} =~ /^.p$/) { 1044 1061 $msg = "Could not initialize IPs in new $disp_alloctypes{$args{type}} $args{cidr}"; 1045 my ($code,$rmsg) = initPool($dbh, $args{cidr}, $args{type}, $args{city}, "all", $ args{rdepth}+1);1062 my ($code,$rmsg) = initPool($dbh, $args{cidr}, $args{type}, $args{city}, "all", $bid); 1046 1063 die $rmsg if $code eq 'FAIL'; 1047 1064 } elsif ($args{type} =~ /^.d$/) { 1048 1065 $msg = "Could not initialize IPs in new $disp_alloctypes{$args{type}} $args{cidr}"; 1049 my ($code,$rmsg) = initPool($dbh, $args{cidr}, $args{type}, $args{city}, "normal", $ args{rdepth}+1);1066 my ($code,$rmsg) = initPool($dbh, $args{cidr}, $args{type}, $args{city}, "normal", $bid); 1050 1067 die $rmsg if $code eq 'FAIL'; 1051 1068 } … … 1086 1103 # function and should ONLY EVER get called from allocateBlock() 1087 1104 sub initPool { 1088 my ($dbh,undef,$type,$city,$class,$ rdepth) = @_;1105 my ($dbh,undef,$type,$city,$class,$parent) = @_; 1089 1106 my $pool = new NetAddr::IP $_[1]; 1090 1107 … … 1095 1112 return ('FAIL',"Refusing to create oversized static IP pool") if $pool->masklen <= 20; 1096 1113 1097 ##fixme Need to just replace 2nd char of type with i rather than capturing 1st char of type 1114 my ($pcustid) = $dbh->selectrow_array("SELECT def_custid FROM alloctypes WHERE type=?", undef, ($type) ); 1098 1115 $type =~ s/[pd]$/i/; 1099 1116 my $sth; … … 1108 1125 eval { 1109 1126 # have to insert all pool IPs into poolips table as "unallocated". 1110 $sth = $dbh->prepare("INSERT INTO poolips (pool,ip,custid,city,type,rdepth)". 1111 " VALUES ('$pool', ?, '$defcustid', ?, '$type', $rdepth)"); 1127 $sth = $dbh->prepare("INSERT INTO poolips (ip,custid,city,type,parent_id) VALUES (?,?,?,?,?)"); 1112 1128 my @poolip_list = $pool->hostenum; 1113 1129 if ($class eq 'all') { # (DSL-ish block - *all* IPs available 1114 1130 if ($pool->addr !~ /\.0$/) { # .0 causes weirdness. 1115 $sth->execute($pool->addr, $ city);1131 $sth->execute($pool->addr, $pcustid, $city, $type, $parent); 1116 1132 } 1117 1133 for (my $i=0; $i<=$#poolip_list; $i++) { 1118 $sth->execute($poolip_list[$i]->addr, $ city);1134 $sth->execute($poolip_list[$i]->addr, $pcustid, $city, $type, $parent); 1119 1135 } 1120 1136 $pool--; 1121 1137 if ($pool->addr !~ /\.255$/) { # .255 can cause weirdness. 1122 $sth->execute($pool->addr, $ city);1138 $sth->execute($pool->addr, $pcustid, $city, $type, $parent); 1123 1139 } 1124 1140 } else { # (real netblock) 1125 1141 for (my $i=1; $i<=$#poolip_list; $i++) { 1126 $sth->execute($poolip_list[$i]->addr, $city); 1127 } 1128 } 1129 $dbh->commit; 1142 $sth->execute($poolip_list[$i]->addr, $pcustid, $city, $type, $parent); 1143 } 1144 } 1145 # don't commit here! the caller may not be done. 1146 # $dbh->commit; 1130 1147 }; 1131 1148 if ($@) { 1132 1149 $msg = $@; 1133 eval { $dbh->rollback; }; 1150 # Don't roll back! It's up to the caller to handle this. 1151 # eval { $dbh->rollback; }; 1134 1152 return ('FAIL',$msg); 1135 1153 } else { -
trunk/cgi-bin/main.cgi
r631 r633 300 300 301 301 # hack pthbttt eww 302 $webvar{parent} = 0 if !$webvar{parent}; 302 303 $webvar{block} = '' if !$webvar{block}; 303 304 … … 307 308 $page->param(allocfrom => $webvar{block}); # fb-assign flag, if block is set, we're in fb-assign 308 309 309 if ($webvar{ block} ne '') {310 if ($webvar{fbid} || $webvar{fbtype}) { 310 311 311 312 # Common case, according to reported usage. Block to assign is specified. 312 313 my $block = new NetAddr::IP $webvar{block}; 313 $page->param(rdepth => $webvar{rdepth}); 314 315 my $rdns = getBlockRDNS($ip_dbh, $webvar{block}, $webvar{rdepth}, vrf => $webvar{vrf}, user => $authuser); 314 315 my $rdns = getBlockRDNS($ip_dbh, id => $webvar{parent}, type => $webvar{fbtype}, user => $authuser); 316 316 $page->param(rdns => $rdns) if $rdns; 317 $page->param(parent => $webvar{parent}); 318 $page->param(fbid => $webvar{fbid}); 317 319 318 320 $webvar{fbtype} = '' if !$webvar{fbtype}; 319 321 if ($webvar{fbtype} eq 'i') { 320 my $ipinfo = getBlockData($ip_dbh, $block); 322 my $ipinfo = getBlockData($ip_dbh, $webvar{block}, 'i'); 323 my $pinfo = getBlockData($ip_dbh, $webvar{parent}); 321 324 $page->param( 322 325 fbip => 1, 323 block => $ block,326 block => $ipinfo->{block}, 324 327 fbdisptype => $list_alloctypes{$ipinfo->{type}}, 325 328 type => $ipinfo->{type}, 326 allocfrom => $ ipinfo->{pool},329 allocfrom => $pinfo->{block}, 327 330 ); 328 331 } else { … … 340 343 341 344 my @pops; 342 foreach my $pop (@ poplist) {345 foreach my $pop (@citylist) { 343 346 my %row = (pop => $pop); 344 347 push (@pops, \%row); … … 378 381 my $cidr; 379 382 my $alloc_from; 383 my $fbid = $webvar{fbid}; 384 my $p_id = $webvar{parent}; 380 385 381 386 # Going to manually validate some items. … … 428 433 429 434 ## fixme: add rdepth? 430 ($ cidr,$webvar{rdepth}) = findAllocateFrom($ip_dbh, $webvar{maskbits}, $webvar{alloctype}, $webvar{city},431 $webvar{ pop}, (master => $webvar{allocfrom}, allowpriv => $webvar{allowpriv}) );435 ($fbid,$cidr,$p_id) = findAllocateFrom($ip_dbh, $webvar{maskbits}, $webvar{alloctype}, 436 $webvar{city}, $webvar{pop}, (master => $webvar{allocfrom}, allowpriv => $webvar{allowpriv}) ); 432 437 if (!$cidr) { 433 438 $page->param(err => $failmsg); … … 464 469 $page->param(typefull => $q->escapeHTML($disp_alloctypes{$webvar{alloctype}})); 465 470 $page->param(alloc_from => $alloc_from); 466 $page->param(rdepth => $webvar{rdepth}); 471 $page->param(parent => $p_id); 472 $page->param(fbid => $fbid); 467 473 $page->param(cidr => $cidr); 468 474 $page->param(rdns => $webvar{rdns}); … … 514 520 # IP, or the error message if an error occurred. 515 521 516 my ($code,$msg) = allocateBlock($ip_dbh, cidr => $webvar{fullcidr}, alloc_from => $webvar{alloc_from},517 rdepth => $webvar{rdepth}, custid => $webvar{custid}, type => $webvar{alloctype}, city => $webvar{city},522 my ($code,$msg) = allocateBlock($ip_dbh, cidr => $webvar{fullcidr}, fbid => $webvar{fbid}, 523 parent => $webvar{parent}, custid => $webvar{custid}, type => $webvar{alloctype}, city => $webvar{city}, 518 524 desc => $webvar{desc}, notes => $webvar{notes}, circid => $webvar{circid}, 519 525 privdata => $webvar{privdata}, nodeid => $webvar{node}, rdns => $webvar{rdns}, user => $authuser); … … 524 530 $page->param(staticip => $msg); 525 531 $page->param(custid => $webvar{custid}); 526 $page->param(parent => $webvar{ alloc_from}, rdepth => $webvar{rdepth}-1);532 $page->param(parent => $webvar{parent}, pool => $webvar{alloc_from}); 527 533 $page->param(billinguser => $webvar{billinguser}); 528 534 mailNotify($ip_dbh, "a$webvar{alloctype}", "ADDED: $disp_alloctypes{$webvar{alloctype}} allocation", … … 535 541 $page->param(custid => $webvar{custid}); 536 542 # breadcrumbs lite! provide at least a link to the parent of the block we just allocated. 537 my $binfo = getBlockData($ip_dbh, $webvar{fullcidr}, $webvar{rdepth}); 538 $page->param(parent => $binfo->{parent}, rdepth => $binfo->{rdepth}); 543 my $binfo = getBlockData($ip_dbh, $webvar{parent}); 544 $page->param(parentid => $webvar{parent}); 545 $page->param(parentblock => $binfo->{block}); 539 546 if ($webvar{alloctype} eq 'pr' && $webvar{billinguser}) { 540 547 $page->param(billinguser => $webvar{billinguser});
Note:
See TracChangeset
for help on using the changeset viewer.