Changeset 832


Ignore:
Timestamp:
04/08/16 16:36:06 (9 years ago)
Author:
Kris Deugau
Message:

/trunk

Rollup commit for many collective refinements. See #54, mostly:

  • reference variable for DNSAdmin link URL
  • remove stale fields from listSubs() return
  • docucomments in getTypeList()
  • accept "description" as an alias for "desc" in allocateBlock(), to better match updateBlock()
  • refine selection of the IP to assign based on the VRF when called with a bare IP - mainly useful for RPC where the pool ID might be hard to come by
  • further refinements in keeping the VRF tagged on allocations more like the master_id; invariant once originally set rather than a freeform per-allocation field
  • refine RPC calls for DNS updates on successful allocation
  • add a hook/flag to allow assignment-by-update on pool IPs, mainly for RPC
  • refine RPC calls on allocation updates
  • make deleteBlock() smarter so that the caller can just pass the type in
  • refine returns from getBlockData() for various call points
  • tweak internal lookup chain retrieving rDNS info and reference pointers
  • add a sub to retrieve the rDNS zone ID (or IDs) that matches an allocation
File:
1 edited

Legend:

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

    r831 r832  
    2121use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
    2222
    23 $VERSION        = 2; ##VERSION##
     23$VERSION        = 3; ##VERSION##
    2424@ISA            = qw(Exporter);
    2525@EXPORT_OK    = qw(
     
    3333        &ipParent &subParent &blockParent &getBreadCrumbs &getRoutedCity
    3434        &allocateBlock &updateBlock &splitBlock &shrinkBlock &mergeBlocks &deleteBlock &getBlockData
    35         &getBlockRDNS &getRDNSbyIP
     35        &getBlockRDNS &getRDNSbyIP &getRevID
    3636        &getNodeList &getNodeName &getNodeInfo
    3737        &mailNotify
     
    4949                &ipParent &subParent &blockParent &getBreadCrumbs &getRoutedCity
    5050                &allocateBlock &updateBlock &splitBlock &shrinkBlock &mergeBlocks &deleteBlock &getBlockData
    51                 &getBlockRDNS &getRDNSbyIP
     51                &getBlockRDNS &getRDNSbyIP &getRevID
    5252                &getNodeList &getNodeName &getNodeInfo
    5353                &mailNotify
     
    115115
    116116our $rpc_url = '';
     117our $dnsadmin_url;      # needs to be modified later
    117118our $revgroup = 1;      # should probably be configurable somewhere
    118119our $rpccount = 0;
     
    566567#  $ENV{HTML_TEMPLATE_ROOT} = 'foo/bar';
    567568
     569  # fix up DNSAdmin remote link based on RPC URL
     570  if ($rpc_url) {
     571    ($dnsadmin_url = $rpc_url) =~ s{/dns-rpc\.f?cgi}{};
     572  }
     573
    568574  return (1,"OK");
    569575} # end initIPDBGlobals
     
    10081014    my %row = (
    10091015        block => $cidr,
    1010         subcontainers => $cont,
    1011         suballocs => $alloc,
    10121016        subfree => $free,
    10131017        lfree => $lfree,
     
    10151019        type => $disp_alloctypes{$type},
    10161020        custid => $custid,
    1017         swip => ($swip eq 'y' ? 'Yes' : 'No'),
    1018         partswip => ($swip eq 'y' && $ncust == 0 ? 1 : 0),
    10191021        desc => $desc,
    10201022        hassubs => ($type eq 'rm' || $type =~ /.c/ ? 1 : 0),
     
    12601262  my $sql = "SELECT type,listname,type=? AS sel FROM alloctypes WHERE listorder <= 500";
    12611263  if ($tgroup eq 'n') {
    1262     # grouping 'p' - all netblock types.  These include routed blocks, containers (_c)
     1264    # grouping 'n' - all netblock types.  These include routed blocks, containers (_c)
    12631265    # and contained (_r) types, dynamic-allocation ranges (_e), static IP pools (_d and _p),
    12641266    # and the "miscellaneous" cn, in, and en types.
     1267    # Or in other words, everything but master and static IP types.
    12651268    $sql .= " AND type NOT LIKE '_i'";
    12661269  } elsif ($tgroup eq 'p') {
     
    15131516  }
    15141517
     1518  $args{desc} = $args{description} if $args{description};
    15151519  $args{desc} = '' if !$args{desc};
    15161520  $args{notes} = '' if !$args{notes};
    15171521  $args{circid} = '' if !$args{circid};
    15181522  $args{privdata} = '' if !$args{privdata};
     1523##fixme:  VRF should trickle down like master_id
    15191524  $args{vrf} = '' if !$args{vrf};
    15201525  $args{vlan} = '' if !$args{vlan};
     
    15491554    $msg = "Unable to assign static IP $args{cidr} to $args{custid}";
    15501555    eval {
     1556##fixme:  IP pools across VRFs, need to use the IP ID instead of the CIDR
     1557# ...  or the VRF itself?
    15511558      if ($args{cidr}) {        # IP specified
    1552         my ($isavail) = $dbh->selectrow_array("SELECT available FROM poolips WHERE ip=?", undef, ($args{cidr}) );
     1559        my ($isavail) = $dbh->selectrow_array(
     1560          "SELECT available FROM poolips WHERE ip=?".($args{vrf} ? " AND vrf=?" : ''),
     1561          undef, ($args{vrf} ? ($args{cidr},$args{vrf}) : $args{cidr}) );
    15531562        die "IP is not in an IP pool.\n"
    15541563          if !$isavail;
     
    15791588      # finally assign the IP
    15801589      $dbh->do("UPDATE poolips SET custid = ?, city = ?, available='n', description = ?, notes = ?, ".
    1581         "circuitid = ?, privdata = ?, vrf = ?, rdns = ?, backup_id = ? ".
     1590        "circuitid = ?, privdata = ?, rdns = ?, backup_id = ? ".
    15821591        "WHERE ip = ? AND parent_id = ?", undef,
    15831592                ($args{custid}, $args{city}, $args{desc}, $args{notes},
    1584                 $args{circid}, $args{privdata}, $args{vrf}, $args{rdns}, $backupid,
     1593                $args{circid}, $args{privdata}, $args{rdns}, $backupid,
    15851594                $args{cidr}, $args{parent}) );
    15861595
     
    16401649        $dbh->do("INSERT INTO allocations ".
    16411650                "(cidr,parent_id,master_id,vrf,vlan,custid,type,city,description,notes,circuitid,privdata,rdns,backup_id)".
    1642                 " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)", undef,
    1643                 ($args{cidr}, $fbparent, $fbmaster, $args{vrf}, $args{vlan}, $args{custid}, $args{type}, $args{city},
     1651                " VALUES (?,?,?,(SELECT vrf FROM allocations WHERE id=?),?,?,?,?,?,?,?,?,?,?)", undef,
     1652                ($args{cidr}, $fbparent, $fbmaster, $fbmaster, $args{vlan}, $args{custid}, $args{type}, $args{city},
    16441653                $args{desc}, $args{notes}, $args{circid}, $args{privdata}, $args{rdns}, $backupid) );
    16451654        my ($bid) = $dbh->selectrow_array("SELECT currval('allocations_id_seq')");
     
    17161725        $dbh->do("INSERT INTO allocations ".
    17171726                "(cidr,parent_id,master_id,vrf,vlan,custid,type,city,description,notes,circuitid,privdata,rdns)".
    1718                 " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", undef,
    1719                 ($args{cidr}, $fbparent, $fbmaster, $args{vrf}, $args{vlan}, $args{custid}, $args{type}, $args{city},
     1727                " VALUES (?,?,?,(SELECT vrf FROM allocations WHERE id=?),?,?,?,?,?,?,?,?,?)", undef,
     1728                ($args{cidr}, $fbparent, $fbmaster, $fbmaster, $args{vlan}, $args{custid}, $args{type}, $args{city},
    17201729                $args{desc}, $args{notes}, $args{circid}, $args{privdata}, $args{rdns}) );
    17211730        my ($bid) = $dbh->selectrow_array("SELECT currval('allocations_id_seq')");
     
    17671776    # Snag the parent info
    17681777    my $pinfo = getBlockData($dbh, $fbparent);
    1769     # Only try to update rDNS when the pool is flagged as "rDNS available"
    1770     if ($pinfo->{revavail} || $pinfo->{revpartial}) {
    1771       # now we do the DNS dance for netblocks, if we have an RPC server to do it with and a pattern to use.
    1772       _rpc('addOrUpdateRevRec', cidr => "$args{cidr}", name => $args{rdns}, rpcuser => $args{user})
    1773         if $args{rdns};
    1774 
    1775       # and the per-IP set, if there is one.
    1776       _rpc('updateRevSet', %{$args{iprev}}, rpcuser => $args{user});
     1778    # Only try to update rDNS when the block is flagged as "rDNS available"
     1779    if (($pinfo->{revavail} || $pinfo->{revpartial}) && $args{rdns}) {
     1780      # the netblock/allocation...
     1781      _rpc('addOrUpdateRevRec', cidr => "$args{cidr}", name => $args{rdns}, rpcuser => $args{user});
     1782      # ...and the per-IP set, if there is one.
     1783      _rpc('updateRevSet', %{$args{iprev}}, rpcuser => $args{user})
     1784         if keys (%{$args{iprev}});
    17771785    }
    17781786
     
    19131921    $updtable = 'poolips';
    19141922    $binfo = getBlockData($dbh, $args{block}, 'i');
     1923    # allow allocating an IP by update.  mainly for RPC, may simplify matters for caller
     1924    if ($args{assignIP_on_update}) {
     1925      push @fieldlist, 'available';
     1926      push @vallist, 'n';
     1927    }
    19151928  } else {
    19161929## fixme:  there's got to be a better way...
     
    20332046    $sql .= " = ? WHERE $keyfield = ?";
    20342047
     2048##fixme:  don't do the update on pool IPs if the IP is available and assignIP_on_update is not set
    20352049    # do the update
    20362050    $dbh->do($sql, undef, @vallist);
     
    20812095
    20822096  } else {
    2083     $binfo->{block} =~ s|/32$||;
    2084     _rpc('addOrUpdateRevRec', cidr => $binfo->{block}, name => $args{rdns}, rpcuser => $args{user});
     2097    $binfo->{block} =~ s{/(?:32|128)$}{};
     2098    # Only insert a record for IPv4, or actual single v6 IPs
     2099    _rpc('addOrUpdateRevRec', cidr => $binfo->{block}, name => $args{rdns}, rpcuser => $args{user})
     2100        if !$cidr->{isv6} || ($cidr->{isv6} && $cidr->masklen == 128);
    20852101
    20862102    # and the per-IP set, if there is one.
    2087     _rpc('updateRevSet', %{$args{iprev}}, rpcuser => $args{user}) if keys (%{$args{iprev}});
     2103    _rpc('updateRevSet', cidr => $binfo->{block}, %{$args{iprev}}, rpcuser => $args{user}, location => $pinfo->{location})
     2104        if keys (%{$args{iprev}});
    20882105
    20892106    # and fix up the template's CIDR if required
     
    28832900  my ($dbh,$id,$basetype,$delfwd,$user) = @_;
    28842901
     2902  # reset $basetype so caller can just pass the complete allocation type
     2903  if ($basetype =~ /.i/) {
     2904    $basetype = 'i';
     2905  } else {
     2906    $basetype = 'b';
     2907  }
     2908
    28852909  # Collect info about the block we're going to delete
    28862910  my $binfo = getBlockData($dbh, $id, $basetype);
     
    31963220  my $type = shift || 'b';      # default to netblock for lazy callers
    31973221
     3222# catch some errors, someday
     3223#  if (!$id || $id !~ /^\d+$/) {
     3224#    $errstr = "Allocation ID must be numeric
     3225#  }
     3226
    31983227  # netblocks are in the allocations table;  pool IPs are in the poolips table.
    31993228  # If we try to look up a CIDR in an integer field we should just get back nothing.
     
    32093238    my $binfo = $dbh->selectrow_hashref(qq(
    32103239        SELECT a.id, a.ip AS block, a.city, a.vrf, a.parent_id, a.master_id, $commonfields,
    3211                 d.zone >> a.ip AS revavail,
     3240                d.zone >> a.ip AS revavail, d.location,
    32123241                $bkfields,
    3213                 v.location
     3242                v.location AS vrfloc
    32143243        FROM poolips a
    32153244        LEFT JOIN dnsavail d ON a.master_id = d.parent_alloc AND a.ip << d.zone
     
    32233252        SELECT a.id, a.cidr AS block, a.city, a.vrf, a.parent_id, a.master_id, a.swip, $commonfields,
    32243253                f.cidr AS reserve, f.id as reserve_id,
    3225                 d.zone >>= a.cidr AS revavail, d.zone << a.cidr AS revpartial,
     3254                d.zone >>= a.cidr AS revavail, d.zone << a.cidr AS revpartial, d.location,
    32263255                $bkfields,
    3227                 v.location
     3256                v.location AS vrfloc
    32283257        FROM allocations a
    32293258        LEFT JOIN freeblocks f ON a.id=f.reserve_for
     
    32523281
    32533282  # snag entry from database
    3254   my ($rdns,$rfrom,$pid);
     3283  my ($rdns,$rfrom,$pid,$mid);
    32553284  if ($args{type} =~ /.i/) {
    3256     ($rdns, $rfrom, $pid) = $dbh->selectrow_array("SELECT rdns,ip,parent_id FROM poolips WHERE id = ?",
     3285    ($rdns, $rfrom, $pid, $mid) = $dbh->selectrow_array("SELECT rdns,ip,parent_id,master_id FROM poolips WHERE id = ?",
    32573286        undef, ($args{id}) );
    32583287  } else {
    3259     ($rdns, $rfrom, $pid) = $dbh->selectrow_array("SELECT rdns,cidr,parent_id FROM allocations WHERE id = ?",
     3288    ($rdns, $rfrom, $pid, $mid) = $dbh->selectrow_array("SELECT rdns,cidr,parent_id,master_id FROM allocations WHERE id = ?",
    32603289        undef, ($args{id}) );
    32613290  }
     
    32883317        cidr => "$rpcblock",
    32893318        );
     3319
     3320#    # Retrieve the VRF's location by way of the master block
     3321#    ($rpcargs{location}) = $dbh->selectrow_array("SELECT v.location FROM vrfs v".
     3322#        " JOIN allocations a ON a.vrf = v.vrf".
     3323#        " WHERE a.id = ?", undef, $mid);
     3324
     3325## ... is there something more needed here?
     3326# order by so that we get the narrowest entry
     3327    ($rpcargs{location}) = $dbh->selectrow_array("SELECT d.location FROM dnsavail d".
     3328        " WHERE d.parent_alloc = ? ORDER BY zone DESC", undef, $mid) or print "foo? ".$dbh->errstr;
    32903329
    32913330    $errstr = '';
     
    33203359  }
    33213360
     3361  my $binfo = getBlockData($dbh, $args{id}, $args{type});
     3362
    33223363  my @ret = ();
    33233364  # special case:  single IP.  Check if it's an allocation or in a pool, then do the RPC call for fresh data.
     
    33253366    my ($ip, $localrev) = $dbh->selectrow_array("SELECT ip, rdns FROM poolips WHERE id = ?", undef, ($args{id}) );
    33263367    push @ret, { 'r_ip' => $ip, 'iphost' => $localrev };
     3368##fixme:  rpc call?
    33273369  } else {
    33283370    if ($rpc_url) {
     
    33333375        );
    33343376
     3377#    # Retrieve the VRF's DNS location by way of the master block
     3378#    ($rpcargs{location}) = $dbh->selectrow_array("SELECT v.location FROM vrfs v".
     3379#        " JOIN allocations a ON a.vrf = v.vrf JOIN allocations b ON a.id = b.master_id".
     3380#        " WHERE b.id = ?", undef, $args{id});
     3381
     3382## ... is there something more needed here?
     3383# order by so that we get the narrowest entry
     3384    ($rpcargs{location}) = $dbh->selectrow_array("SELECT d.location FROM dnsavail d".
     3385        " WHERE d.parent_alloc = ? ORDER BY zone DESC", undef, $binfo->{master_id});
     3386
    33353387      my $remote_rdns = _rpc('getRevSet', %rpcargs);
    33363388      return $remote_rdns;
     
    33413393  return \@ret;
    33423394} # end getRDNSbyIP()
     3395
     3396
     3397## IPDB::getRevID()
     3398# Get the reverse zone ID(s) for an allocation
     3399# Takes a hash with cidr, location and user elements
     3400# Returns a hashref to a list of zones and zone IDs (in case of large
     3401# allocations effectively split across multiple DNS zones)
     3402##fixme: arguably should be integrated in some other related sub that
     3403# does RPC to minimize the number of RPC calls somehow
     3404sub getRevID {
     3405  my $dbh = shift;
     3406  my %args = @_;
     3407
     3408##fixme:  build a local cache for mapping allocations to DNS zone IDs
     3409#  my ($revlocal) = $dbh->selectrow_array("SELECT revzones[0] AS zone,revzones[1] AS revid FROM dnsavail WHERE
     3410#zone >>= ? AND location = ?", undef, $args{cidr}, $args{location});
     3411#use Data::Dumper;
     3412#print "rezone array?<pre>".Dumper($revlocal)."</pre>\n";
     3413
     3414  my $revzones = _rpc('getZonesByCIDR', rpcuser => $args{user},
     3415        cidr => $args{cidr},
     3416        return_location => 0,
     3417        location => $args{location},
     3418        );
     3419  return $revzones;
     3420} # end getRevID()
    33433421
    33443422
Note: See TracChangeset for help on using the changeset viewer.