Forum Discussion
Chris_Day_10331
Nimbostratus
Dec 27, 2005iRules for Individual Testing of Farm Servers
Hello wonderful people at DevCentral!
I have a follow-up to an earlier post I had made “iRule for Server Testing” (http://devcentral.f5.com/default.aspx/Default.aspx?tabid=28&forumid=5&postid=4603&view=topic) regarding the re-writing of URLs to facilitate testing of individual pool members for a particular application.
I was not successful in getting this to work, primarily because I believe I may have approached the problem from the wrong angle. I wanted to start this from the “top down” to see what all you smart people think is the best approach to achieve the end result.
THE PROBLEM:
We now have 16 web servers (among 16 app servers, db servers, etc) each of which services a number of applications (currently 6 but not likely to exceed 50 to 100). The applications are distinguished from one another only by HTTP/1.1 host header. As a new server is brought into production it is very difficult to ensure that it is responding properly for each of the 6 applications (and some other reasons beyond the scope of this post). As this number grows linearly, it is increasingly difficult and time consuming to test and more importantly locate issues with the deployment of the app to each of the boxes. A sample application served by each of the 16 boxes would be:
http://application1.company.com/
THE GOAL:
I was hoping to make it such that we could provision an additional VS (with either an internal or external IP) and enable testers to test a particular application on a particular server as follows:
http://application1.test.company.com/web001/ OR
http://application1.test.company.com/10.10.20.54/
This would require minimal DNS maintenance as new applications were added since it could be achieved by creating a single wildcard sub-domain (*.test.company.com pointing to VS IP Address). My goal was then to have the BIG-IP parse the “/web001/” portion and determine from a lookup table of some kind that I, the tester, was trying to load “application1.company.com” from server “web001”. In the latter example, it would obviously determine that I wanted to have the specified application served by the server who's IP address I provided.
The critical part was that the server be unaware of all the fancy rewriting going on and believe that the client was actually requesting http://application1.company.com/ (without the “/web001/”). I wanted the URLs back to the client to be re-written with the “/web001/” to enable the site to best tested/navigated seamlessly (i.e. not just the initial request).
As I am not a developer or particularly strong with iRules, I was hoping that someone could pick this up and help. There is no real rush on this, but needless to say the current solution which involves the continuous editing of hosts files is quite ugly.
I really appreciate all the help you guys have provided in the past (I still owe some beers) and thank you in advance for reading this post.
Cheers,
Chris
- JRahm
Admin
if using the server IP address, you could do something like this. Note that this is untested, but should get you started.when HTTP_REQUEST { if { [HTTP::uri] > 1 } { set uri_index [ split [HTTP::uri] "/" ] set myserver [ string trimleft [ lindex $uri_index 0 ] "/" ] set myuri [ lindex $uri_index 1 ] HTTP::uri "/$myuri" use node $myserver } } when HTTP_RESPONSE { if { $myserver != "" } { HTTP::uri "/$myserver[HTTP::uri]" } }
- JRahm
Admin
You might add some error checking to make sure the server provided in the URL is actually a server known by the big ip:when HTTP_REQUEST { if { [HTTP::uri] > 1 } { set uri_index [ split [HTTP::uri] "/" ] set myserver [ string trimleft [ lindex $uri_index 0 ] "/" ] set myuri [ lindex $uri_index 1 ] HTTP::uri "/$myuri" if { [catch { use node $myserver } ] } { log "Invalid node $myserver - does not exist" reject return } else { use node $myserver } } } when HTTP_RESPONSE { if { $myserver != "" } { HTTP::uri "/$myserver[HTTP::uri]" } }
- Chris_Day_10331
Nimbostratus
Hey, this looks great but how does it deal with the re-writing of the host headers. Previously, I had a chunk that looked something like this:when HTTP_REQUEST { Search for host mapping in the lookup list set new_host [findclass [HTTP::host] $::HostMap_External " "] if { "" ne $new_host } { if mapping is found, replace the Host header log local0. "Replacing host from [HTTP::host] to $new_host" HTTP::header replace "Host" $new_host Pull out the node name as the first element of the uri ie. /web001/foo/bar -> web001 set node_name [lindex [split [HTTP::uri] "/"] 1] if { "" ne $node_name } { Now look for the node address in the lookup list log local0. "Searching for node: $node_name" set node_addr [findclass $node_name $::NodeMap_External " "] if { "" ne $node_addr } { log local0. "Routing to node: $node_addr " node $node_addr } else { log local0. "Didn't find node '$node_name' in lookup class" } } else { log local0. "No node name passed in URI" } } else { log local0. "Didn't find [HTTP::host] in lookup class" } }
- Simon_Knox_1115
Nimbostratus
Hi, we do a similar thing for testing web apps on specific servers but use TCP port numbers to differentiate them: - Chris_Day_10331
Nimbostratus
First off -- thanks to everyone whoh participates for the ongoing support... - Deb_Allen_18Historic F5 AccountAssuming you want the rest of the traffic to fall into myPool, the following should work for you:
when HTTP_REQUEST { set myNode [findstr [HTTP::uri] "node=" 5 "&"] if {[catch {node $myNode}]}{ pool myPool } else { node $myNode } }
- Chris_Day_10331
Nimbostratus
Thanks Deb -when HTTP_REQUEST { set myNode [findstr [HTTP::uri] "node=" 5 "&"] if {[catch {use node $myNode}]}{ log "Node not found." pool http-pool-mypool } else { log "Node found." node $myNode } }
- Deb_Allen_18Historic F5 AccountI was assuming that command worked for you in the earlier example. Try this instead, then, adjusting port on the pool member if necessary:
when HTTP_REQUEST { set myNode [findstr [HTTP::uri] "node=" 5 "&"] if {($myNode ne "") \ and ([LB::status pool http-pool-mypool member $myNode:80 eq "up")}{ log "Node found." pool http-pool-mypool member $myNode:80 } else { log "Node not found." pool http-pool-mypool } }
- unRuleY_95363Historic F5 AccountI'd like to re-iterate some notes about the use of the "catch" command:
- This fixes a few compile errors:
when HTTP_REQUEST { set myNode [findstr [HTTP::uri] "node=" 5 "&"] if {($myNode ne "") \ and ([LB::status pool xpbert-http member $myNode 80] eq "up")}{ log "Node found." pool http-pool-mypool member $myNode:80 } else { log "Node not found." pool http-pool-mypool } }
Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects