Forum Discussion
Help with iRule
Hi everyone
I'm trying to unpick someone elses iRule but failing miserably. From what I can tell this seems to be a very long winded way to essentially read the requested URI of a request, and match that to a value in a DGL (the "uriPoolMapClass" variable below). However, I cannot be certain and wondered whether someone here - a dab hand in iRuleology, could provide some insight?
Thank you.
when HTTP_REQUEST priority 100 {
set poolId [string range [HTTP::uri] 1 [expr [string first "/" [HTTP::uri] 1]-1]]
set poolIdLen [string length $poolId]
set newUri "[string range [HTTP::uri] [expr $poolIdLen+1] end]"
set uriPoolMapClass "[string range [virtual name] 0 end-2]uri_pool_map_class"
set dstPool [class lookup [string tolower $poolId] $uriPoolMapClass]
if {$dstPool ne ""} {
Hash out next line to disable logging
log local0.debug "poolId: $poolId | poolIdLen: $poolIdLen | newUri: $newUri | dgl_name: $uriPoolMapClass dstPool: $dstPool"
HTTP::uri $newUri
pool $dstPool
} else {
Hash out next line to disable logging
log local0.debug "poolId: $poolId | poolIdLen: $poolIdLen | newUri: $newUri | no pool set"
TODO this needs to be changed to reject if there isn't another iRule which ends in a deny_all
return
}
}
- Kevin_Stewart
Employee
Okay, so basically it looks like this. Let's assume the incoming URI is /pool1/foo/bar and the virtual server is test_vs.
when HTTP_REQUEST priority 100 { set poolId [string range [HTTP::uri] 1 [expr [string first "/" [HTTP::uri] 1]-1]] This grabs the first part of the URI ("pool1") and assigns it to a variable. So string range, starting at the second character (/ is 0), and stopping at the first occurrence of "/". set poolIdLen [string length $poolId] This sets the length of the above string, in this case 5. set newUri "[string range [HTTP::uri] [expr $poolIdLen+1] end]" This grabs everything after the first section (/foo/bar), which will become the new URI that gets passed to the application. So string range, starting at character 6 (5 + 1), going all the way to the end. set uriPoolMapClass "[string range [virtual name] 0 end-2]uri_pool_map_class" This creates a string based on the virtual server name (test_vs), minus the last two characters in the name (so "test_"), then appends that to the string "uri_pool_map_class", which should in this case derive the string "test_uri_pool_map_class". Presumably there's a data group named this, and inside the data group is a key-value pair, where the key is the poolId value and the value is the actual pool name. set dstPool [class lookup [string tolower $poolId] $uriPoolMapClass] This grabs the real pool name from the data group based on the poolId value passed in the URI. if {$dstPool ne ""} { Hash out next line to disable logging log local0.debug "poolId: $poolId | poolIdLen: $poolIdLen | newUri: $newUri | dgl_name: $uriPoolMapClass dstPool: $dstPool" HTTP::uri $newUri pool $dstPool Assuming there's a data group match, change the inbound URI to the server to newURI value (/foo/bar), and pool to the matched pool name. } else { Hash out next line to disable logging log local0.debug "poolId: $poolId | poolIdLen: $poolIdLen | newUri: $newUri | no pool set" TODO this needs to be changed to reject if there isn't another iRule which ends in a deny_all return Otherwise just use the pool that's assigned to the VIP. } }
The whole point of this iRule is to allow an application to dictate which pool to send traffic to by injecting the pool into the URL.
- Stanislas_Piro2
Cumulonimbus
Hi,
here are some improvements of the code with comments
when CLIENT_ACCEPTED { define the datagroup name based on virtual server. It is recommended to do it once per TCP connection (event CLIENT_ACCEPTED) instead of per request (event HTTP_REQUEST) set uriPoolMapClass "[string range [virtual name] 0 end-2]uri_pool_map_class" } when HTTP_REQUEST priority 100 { decode URI to provision both poolId and newUri variables. switch [scan [HTTP::uri] {/%[^/]%s} poolId newUri] { 0 { Pool ID not available return } 1 { Pool ID available, but newUri not set. setting newUri to / this happens when URI is like "/poolId" and not "/poolId/path1/path2" set newUri "/" } 2 { Everything seems OK. continue. } } if {[set dstPool [class lookup [string tolower $poolId] $uriPoolMapClass]] ne ""} { HTTP::uri $newUri if {[catch {pool $dstPool}] { Pool assignment fails. it may not exist and create a TCL error if not inside catch command. define action here for this behavior. this happens if poolId is already created in Datagroup but the pool is not created yet. } } else { TODO this needs to be changed to reject if there isn't another iRule which ends in a deny_all return } }
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com