20 Lines or Less #69: Port Ranges, Oracle Connections and Pool Member Toggling

What could you do with your code in 20 Lines or Less? That's the question I like to ask for the DevCentral community, and every time I do, I go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head. Thus was born the 20LoL (20 Lines or Less) series. Over the years I’ve poked at, talked about and worked to help hundreds of iRules examples proliferate, all of which were doing downright cool things in less than 21 lines of code.

In this installment we get to look at a few more killer examples brought to you by a couple of the hottest iRuling minds the world has to offer, currently. And no, none of them are from me, so I can totally say that and not be “that guy”. Kevin Stewart and the infamous Hoolio have been tearing up the new Q&A section on the fantastic “Hero” version of DevCentral and doling out the coding geekery in healthy doses. Kevin, especially, has been absolutely crushing it, already amassing over 1700 “devpoints”, which are the new currency handed out on DevCentral for answering questions and generally doing things that are hawesome. While it’s odd to see someone other than Aaron on the top of the E-ego list, it’s always good to have new blood challenging the old guard for top billing. Maybe we’ll have a race once Kevin slows down from warp-speed posting, assuming he does. For now, long live the new king, and good on him for kicking major tail for the sake of the community. Are you curious to see just what these F5 programmability hot-shots handed out as sage knowledge this week? Well let’s get to it…


Need iRule to Manage VIP & Port Range


Piecing together the somewhat sparse information in the original post, it looks like the request was for the ability to have a specific port range (8000-8020) opened on a given virtual, and to have each of those ports directed to a specific pool on the back end. I.E. domain.com:8000 –> pool1, domain.com:8001 –> pool2, and so on. While this could absolutely be done in a static, holy-cow-why-would-you-do-that-much-annoying-configuration-by-hand manner, Aaron was, not shockingly, much more clever than that. He whipped up an exceedingly small, simple iRule that makes this whole process as easy as pi. All the user needs to do is create the pools that things should be directed to with a common naming scheme, in this example “mypool_<port>”, and this iRule will play middle-man and ship the traffic to the appropriate pools without so much as a second thought. Combine this with a virtual that listens on all ports, and you’re good to go. For added security he even added a “drop” to the else clause to be sure that only the desired ports (8000-8020) are accepted and passed to the back end. Simple, elegant, efficient, awesome. We’ve grown to expect nothing less from Aaron, and he doesn’t disappoint whether dealing with extraordinarily complex, near impossible solutions or the simplest, smallest chunks of code, like this one, that still solve real world problems and make life easier. That’s what the 20LoL is all about.

   1: when CLIENT_ACCEPTED {
   2:    if {[TCP::local_port] >= 8000 && [TCP::local_port] <= 8020}{
   3:       pool mypool_[TCP::local_port]
   4:    } else {
   5:       drop
   6:    }
   7: }


Replace SID to SERVICE_NAME in Oracle connection string


For a slightly more complex look at what iRules can churn out in only a few lines of code, Kevin dove in to help a community member looking to do some in-line replacement of an Oracle connection string on the wire. This iRule is admittedly a bit more than the 7 line beauty above, but at a scant 16 lines of effective code, the below is pretty darn impressive when you think about what’s happening. The client attempts to connect to the Oracle DB, the LTM proxies the connection, inspects the data in-line, modifies the stream on the fly, makes all necessary adjustments to the content to connect with the new information, and passes things along to the back-end with no one the wiser, all at wire speed. Yeah, okay, so maybe that’s not so bad for 16 lines of code, eh? I’ll take it. This one hasn’t been fully tested yet, and it looks like there is still some chatter in the thread about how to get it 100% locked down and functional, so don’t go dumping the below into your prod environment without testing, but it’s a great example of just what can be achieved with iRules without much heavy lifting. How can you not love this stuff?

   1: when CLIENT_ACCEPTED {
   2:     TCP::collect
   3: }
   5: when CLIENT_DATA {
   6:     set sid_match 0
   7:     if { [TCP::payload] contains "CONNECT_DATA=" } {
   8:         set sid_match 1
   9:         log local0. "original payload = [TCP::payload]"
  10:         set service_name "SERVICE_NAME=MYSERVICENAME"
  11:         if { [regsub -all -nocase "SID=MYSID" [TCP::payload] "$service_name" newdata] } {
  12:             TCP::payload replace 0 [TCP::payload length] ""
  13:             TCP::payload replace 0 0 $newdata
  14:             log local0. "replaced payload = $newdata"
  15:         }
  16:     }
  17:     TCP::release   
  18:     TCP::collect
  19: }


iRule to disable a pool to new connections


Scenario: At a specific time of day, you need to selectively, automatically disable two specific members members of a pool, without disabling the entire pool as a whole, for a specific duration, denying any new connections and then re-enabling those members once the window of time during which they should be offline has passed, all without any human intervention.

Who wants to place a bet on how much scripting that would take? That’s a pretty complex list of tasks/criteria, no? 50 lines? 30? Try 16. That’s right, 16 lines of effective code executing to net you all of the above, all of which were hatched out of the fierce mind of the point hoarding, post crushing Q&A wizard that is Kevin Stewart. I’m not sure what his deal with snippets that number 16 lines, but I’m not complaining about this week’s particular trend. As to the code: its really pretty simple when you dig into it. Set up the window the things should be offline with a couple of variables. Set up the pool name and member addresses. On each new request check the time and see if we’re in that window, and if so, knock the pool members offline. Simple, effective, and super helpful to anyone trying to set up this kind of downtime window. I know we’ve seen examples similar to this before but nothing quite this style that deals with one or more individual pool members, rather than a pool at large. The difference could be very handy indeed, and we’re all about being useful pots ‘round these parts. The original thread also has some more examples and iterations that may be useful, depending on your specific needs, so take a gander.

   1: when RULE_INIT {
   2:     set static::START_OFF_TIME "09:30 AM"
   3:     set static::END_OFF_TIME "10:00 AM"
   4:     set static::DOWN_POOL "local-pool"
   5:     set static::DOWN_MEMBERS [list " 80" " 80"]
   6: }
   7: when CLIENT_ACCEPTED {
   8:     set start_off_time [clock scan $static::START_OFF_TIME]
   9:     set end_off_time [clock scan $static::END_OFF_TIME]
  10:     set now [clock seconds]
  12:     if { ( [expr $now > $start_off_time] ) and ( [expr $now < $end_off_time] ) } {
  13:         foreach x $static::DOWN_MEMBERS {
  14:             LB::down pool $static::DOWN_POOL member [lindex $x 0] [lindex $x 1]
  15:         }
  16:     }
  17: }
Published Sep 11, 2013
Version 1.0

Was this article helpful?

No CommentsBe the first to comment