20 Lines or Less #46: DNS, RPC and Classes

What could you do with your code in 20 Lines or Less? That's the question I ask (almost) every week for the devcentral community, and every week I go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head.

Continuing the long standing tradition, this week’s 20LoL brings to you DNS lookups with variable resolvers, avoiding RPC issues with ASM, and some advanced pool selection logic by way of class searching. Thanks go out to user Kent Perrier, mbamusa and ichalis for the examples or inspiration. Now let’s get to the code:

 

Advanced Pool Selection

http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/aft/1177260/showtab/groupforums/Default.aspx

Kent was looking for a way to dynamically select the pool to which traffic would be directed by searching through a class, but didn’t have much experience dealing with classes. Since he’s running v10.2.1 he gets to make use of the awesome class command for searching/matching, and was able to piece together his own solution pretty quickly with a little care and feeding by way of link sharing from the community. His iRule checks for the class, compares the beginning of the incoming URI with the entries from the class, and selects a pool based on the results.Here’s what he ended up with.

when RULE_INIT {
  # Log debug to /var/log/ltm? 1=yes, 0=no
  set static::debug 0
}
when CLIENT_ACCEPTED {
  # Save the VS default pool name before it's changed
  set default_pool "defpool01"

  # set the data group name
  set clname "AppVersion[virtual name]"
}

when HTTP_REQUEST {
  # if there isn't a data group with the above name, set the pool to default and exit
  if {[class exists $clname]} {

    # Search the datagroup for a name that starts with the URI
    set pool_name [class search -value $clname starts_with [HTTP::uri]]

    if { $pool_name eq ""} {
      # we don't match the context roots in the data class
      if { $static::debug } { log local0. "fell through to the default pool" }
      pool $default_pool
    } else {
      if { $static::debug } { log local0. "Matched $app_pool" }
        pool $app_pool
      }
    } else {
      if { $static::debug } { log local0. "Data group $clame not found, using default_pool $default_pool"
        pool $default_pool
    }
}

 

RPC avoidance and ASM

http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/aft/1178414/showtab/groupforums/Default.aspx

User mbamusa deals with OWA, ActiveSync, and Outlook anywhere through a single VIP. When putting ASM in front of this VIP to protect these applications he needed a way to send RPC traffic elsewhere or disable ASM somehow. Fortunately he’s on version 10.2.1 so he’s able to use the ASM::disable/ASM::enable commands, which makes this trivial. Not a difficult iRule, but something good to keep in mind that can solve a major problem with a simple solution.

when HTTP_CLASS_SELECTED {
  if { [string tolower [HTTP::uri]] starts_with "/rpc" } {
    ASM::disable
  } else {
    ASM::enable
  }
}

 

Selective DNS lookups via iRules

http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/afpg/2/aft/8487/showtab/groupforums/Default.aspx

We’ve covered doing DNS queries via iRule before. The difference this time is that the requirement is to check one of two different resolvers, based on which is available. This is a pretty common concept, backup resolvers, so I figured it was worth noting here. The solution is pretty straight-forward (until RESOLV::lookup interacts properly with a VIP as a target, then it' gets dead simple) with a couple of variables and an if statement doing the tiny amount of lifting necessary. Again, a simple iRule, but a problem that’s tough to resolve otherwise.

set status1 [LB::status pool   member ]
set status2 [LB::status pool   member ]

if {$status1 eq "up"} {
  set ips [RESOLV::lookup @$static::DNS_RESOLVER $host]
  set _ipaddress [lindex $ips 0]
} elseif {$status2 eq "up"}{
  set ips [RESOLV::lookup @$static::DNS_RESOLVER_BACKUP $host]
  set _ipaddress [lindex $ips 0]
}

#Colin

Published Mar 23, 2011
Version 1.0

Was this article helpful?

No CommentsBe the first to comment