Forum Discussion
irule to pick a number out of a URI and make it the port
I have developers who want to tie everything off the same URL and have it go to different ports on the same group of hosts. If you have been following my posts, it is almost the exact opposite problem I had before but hey that's what keeps it interesting right?
So I want to write an Irule that takes URLs like this
joe.test.com/8050/someapp/someoption
joe.test.com/8060/otherapp/differentoption
and convert them to
insidepool:8050/someapp/someoption
insidepool:8060/otherapp/differentoption
I would like it to just be a general take the number make it a variable and then put it in the same URI as a port. Or even if I can just say take everything after my original URL joe.test.com and put it after the inside vip with a colon for port.
Or do I have to create a pool for each and port and then do an if then else kind of thing? What I would like to do if I can is keep it from being a long rule where everything has to go through this long 20 if then statement to find the right pool.
Anyone do anything like this? If so how do you setup the pool? 1.1.1.1:* ??
Thank you in advance for your help!
Joe
20 Replies
- What_Lies_Bene1
Cirrostratus
It's not ideal but if you configure multiple Pools accordingly, with the Pool name ending in the port number it supports then the following pretty short rule should work as long as a four digit port number is always used. It is probably worth adding in some checks to ensure you have a valid value before rewriting the URI and Host and specifying the Pool.when HTTP_REQUEST { Find the first / in the URI, skip 4 characters and match the rest of the string, set this as variable newuri set newuri [findstr [HTTP::uri] "/" "4"] Find the first / in the URI, skip 0 characters and match until the next /, this this as variable newport set newport [findstr [HTTP::uri] "/" "0" "/"] Change the URI before we send this request to a real server HTTP::uri "$newuri" Change the HTTP Host header HTTP::header replace Host "[HTTP::host]:$newport" Use the relevant Pool pool pool_$newport } - sundogbrew
Altocumulus
Thank you Steve! So no way to use one pool and just go to different ports right? I am a bit lazy but I can just create a bunch of pools up front. Or write a script that creates them with the right naming convention and just run it when I get requests for more.
Thanks
Joe - What_Lies_Bene1
Cirrostratus
You could setup a wildcard Pool (I think) but you can't specify a Pool and port in an iRule, only a Pool or a Pool Member and port which doesn't really meet your requirements unfortunately.
- Kevin_Stewart
Employee
A wildcard pool suggest no port translation at the VIP, but then you probably are translating the port number (from port 80/443 to something else internal). Your BEST bet, if you have control over the total number of ports/pools is to create a pool for each. In this way you have better control over load balancing and monitors. The alternative is to use a node command, which brings with it the complexity of some manual load balancing and persistence work. - sundogbrew
Altocumulus
Not to look a gift horse in the mouth but I can't get this script to work.
the only modification I made was to change the name of the pools to chuckpool_8080
but this is the error I get
TCL error: /Common/test-portredirect - no such pool: chuckpool_ (line 10) invoked from within "pool chuckpool_$newport" - What_Lies_Bene1
Cirrostratus
Do you get this error at runtime or just when saving the rule? - sundogbrew
Altocumulus
At runtime. The rule saves fine and when I put it in it is like it isn't getting the value from the variable for newport? - What_Lies_Bene1
Cirrostratus
OK, thought so. I've added some logging and a Variable check to help troubleshoot;when HTTP_REQUEST { set newuri [findstr [HTTP::uri] "/" "4"] log local0. "New URI is: $newuri" set newport [findstr [HTTP::uri] "/" "0" "/"] HTTP::uri "$newuri" log local0. "New Port is: $newport" HTTP::header replace Host "[HTTP::host]:$newport" if { $newport ne "" } { Use the relevant Pool pool pool_$newport } else { log local0. "Newport Variable was empty" } } - sundogbrew
Altocumulus
OK so I changed the url to .test.com the rest is the same. The only thing I changed in your script above is the line pool pool_$newport
my pools are chuckpool_number the rest I left. It is showing the port as 0, 1, 2, 4 I
tried chucktest.test.com/8080/ESB/App1
chucktest.test.com/8081/ESB/App2
chucktest.test.com/8082/ESB/App3
Then just for giggles I tried
chucktest.test.com/8084/ESB/App3 which has no pool
What I am trying to get is
chucktest.test.com/8080/ESB/App1 to convert to chucktest.insidehost:8080/ESB/App1
I have three pools setup
chucktest_8080
chucktest_8081
chucktest_8082
And would like it to take the /8080 and convert it to the pool it is being sent to
Below are the errors:
Mon Apr 22 14:33:54 EDT 2013 info tmm tmm[8659] Rule /Common/log-test : chucktest.test.com::
Mon Apr 22 14:33:54 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : Newport Variable was empty
Mon Apr 22 14:33:54 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : New Port is:
Mon Apr 22 14:33:54 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : New URI is: 4/ESB/App3
Mon Apr 22 14:33:46 EDT 2013 info tmm1 tmm1[8660] Rule /Common/log-test : chucktest.test.com::
Mon Apr 22 14:33:46 EDT 2013 info tmm1 tmm1[8660] Rule /Common/jose-portredirect-test : Newport Variable was empty
Mon Apr 22 14:33:46 EDT 2013 info tmm1 tmm1[8660] Rule /Common/jose-portredirect-test : New Port is:
Mon Apr 22 14:33:46 EDT 2013 info tmm1 tmm1[8660] Rule /Common/jose-portredirect-test : New URI is: 2/ESB/App3
Mon Apr 22 14:33:33 EDT 2013 info tmm tmm[8659] Rule /Common/log-test : chucktest.test.com::
Mon Apr 22 14:33:33 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : Newport Variable was empty
Mon Apr 22 14:33:33 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : New Port is:
Mon Apr 22 14:33:33 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : New URI is: 1/ESB/App2
Mon Apr 22 14:33:23 EDT 2013 info tmm tmm[8659] Rule /Common/log-test : chucktest.test.com::
Mon Apr 22 14:33:23 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : Newport Variable was empty
Mon Apr 22 14:33:23 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : New Port is:
Mon Apr 22 14:33:23 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : New URI is: 0/ESB/App1
Mon Apr 22 14:30:28 EDT 2013 info tmm tmm[8659] Rule /Common/log-test : chucktest.test.com::
Mon Apr 22 14:30:28 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : Newport Variable was empty
Mon Apr 22 14:30:28 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : New Port is:
Mon Apr 22 14:30:28 EDT 2013 info tmm tmm[8659] Rule /Common/jose-portredirect-test : New URI is: 0/ESB/App1
Thank you
Joe - What_Lies_Bene1
Cirrostratus
:I wonder if this is because we're relating to the Host rather than the URI. Is an absolute path being used in the request? Can you log local0. "[HTTP:uri] and confirm? Also, perhaps this should be 5; set newuri [findstr [HTTP::uri] "/" "4"]
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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
