Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

Persist iRule based on URI

Hi there I'm trying to write an iRule that will allow us Admins the choice of selecting a pool member and have persistence with that member.

At the moment we have a persistance profile or source_addr on the virtual server which holds for 15 minutes. This works great.

The pool is made up for 4 members

here is my first attempt


when HTTP_REQUEST {
if { [URI::decode [string tolower [HTTP::uri]]] contains "lbmember=3" } {
persist none
pool pool_name member 1.1.1.1 80
persist source_addr 1800
}
}


Would someone be able to help me out with how I should go about setting this up.

To test I connect from my machine to the pool then view the persisent records in statistics find out which member I'm going to (not member 3) , then I refresh my page with lbmember=3 in the URL, but my persistence record still points to the old server and not 3

TIA

Gary
0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
I think you probably want an else statement in there for the src_addr persist statement, otherwise, the persist none is reset to src_addr before the condition is completed.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Me again

I can't seem to get the F5 to drop the old persist rule and create a new one.

From my testing the request does get routed to the webserver but no persist is setup to redirect any of my other requests that dont have gb=3 in the URI

Does anyone know if this kind of this can be done?


 when HTTP_REQUEST {
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=" } {
persist none
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=3" } {
use pool webpool member 1.1.1.3 80
persist source_addr 1800
}
}
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Wouldn't you want it the other way around? If you find gb=3, persist none because there's only one server to send you to so you don't need to persist.
Also, add some logging to make sure the logic is catching.


when HTTP_REQUEST {
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=" } {
persist source_addr 1800
log "Persist"
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=3" } {
use pool webpool member 1.1.1.3 80
persist none
log "NO -- Persist"
}
}

I think persistence takes precedence over selecting a pool member directly. Can anyone confirm that?
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
There are three member in the pool

The logic for the iRule (in my mind (could be completely wrong)

Was, iRule processes a request with gb= in the URI remove any persistence already setup, if any

Then based on the number create a persistence rule with a particular webserver.

As my persistence is set for 15mins I would have up until that time to forward any requests at the virtual server knowing that it will end up at my desired webserver until such time till my persistence timed out or I sent through another request with gb= in the URI.


At the moment it does seem to process the iRule and for each request with gb=1 in the URI direct that request to member 1 but it doesn't setup the persistence.

if I then make another request it will send to any member in the pool.



when HTTP_REQUEST {
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=" } {
persist none
log "Persist Turn Off"
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=3" } {
use pool webpool member 1.1.1.3 80
persist source_addr 1800
log "Persist Setup to Member 3"
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=2" } {
use pool webpool member 1.1.1.2 80
persist source_addr 1800
log "Persist Setup to Member 2"
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=1" } {
use pool webpool member 1.1.1.1 80
persist source_addr 1800
log "Persist Setup to Member 1"
}

}
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Since you are trying to insert a persistence record, rather than use an existing one, I think you need to use "persist add", and place the command AFTER the load balancing decision, so it can add the results of the load balancing decision to the persistence table:


if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=3" } {
pool webpool member 1.1.1.3 80
persist add source_addr 1800
log "Persist Setup to Member 3"
}


(also, FYI: "use pool X" is legacy v4 syntax which at some point will be deprecated. For forward compatibility, use instead "pool X")

HTH
/d
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Thanks for all your replys

I did some more testing today and have come up with some interesting finds

rather then specify a member in a pool I created 4 new pools each with one member and then rewrote the iRule to look like this


when HTTP_REQUEST {
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=" } {
persist none
log "Persist Turn Off"
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=4" } {
# pool member_www_04 member 4.4.4.4 80
pool member_www_04
persist source_addr 1800
log "Persist Setup to Member 4"
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=3" } {
# pool member_www_03 member 3.3.3.3 80
pool member_www_03
persist source_addr 1800
log "Persist Setup to Member 3"
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=2" } {
# pool member_www_02 member 2.2.2.2 80
pool member_www_02
persist source_addr 1800
log "Persist Setup to Member 2"
}
if { [URI::decode [string tolower [HTTP::uri]]] contains "gb=1" } {
# pool member_www_01 member 1.1.1.1 80
pool member_www_01
persist source_addr 1800
log "Persist Setup to Member 1"
}
}


This worked first time, using the Statistics page to view persistence records I saw them update and I then had my persistence to my specific webserver.

As soon as I change the line to specify a member in the pool (even thought there is only one) it stopped working.

Nothing in the logs,

Do you think this could be a bug?

TIA

Gary
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Oh, yep. That is a bug. Using direct pool member selection doesn't cause a persistence record to be created (or a persist cookie to be inserted). You can add the persist record in an LB_SELECTED event like so (I've also made a few other optimizations):
when HTTP_REQUEST {
switch -glob [URI::decode [string tolower [HTTP::uri]]] {
*gb=1* {
pool webpool member 1.1.1.1 80
set need_add_persist 1
}
*gb=2* {
pool webpool member 2.2.2.2 80
set need_add_persist 1
}
*gb=3* {
pool webpool member 3.3.3.3 80
set need_add_persist 1
}
*gb=4* {
pool webpool member 4.4.4.4 80
set need_add_persist 1
}
*gb=* {
persist none
log "Persist Turn Off"
}
}
}
when LB_SELECTED {
if {[info exists need_add_persist]} {
persist add source_addr [IP::client_addr] 1800
unset need_add_persist
}
}

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Thank You very much for your help
0