Forum Discussion

Rob_Wotton_8024's avatar
Rob_Wotton_8024
Icon for Nimbostratus rankNimbostratus
Oct 21, 2009

Multiple Pool Redirection Based on IP

Hi

 

 

I am struggling with an iRule at the moment, in simple English when the URI starts with /product1 and is from IP address 1.1.1.1 we need to use pool product1-CustomerA. If the URI starts with /product1 and is requested by any other IP address then it needs to use pool product1.

 

 

I have written the below iRule but it only works if the IP is 1.1.1.1, the else statement doesn't seem to work, I am also not sure the rest of my syntax is correct as sometimes it works and other times it doesn't.

 

 

Anyhelp would be appreciated.

 

 

Thanks

 

 

Rob

 

 

 

 

 

 

when HTTP_REQUEST {

 

 

 

if { [IP::addr [IP::client_addr]/32 equals 1.1.1.1] } {

 

switch [string tolower [HTTP::uri]] {

 

"/product1" {

 

pool product1-CustomerA

 

}

 

"/product2" {

 

pool product2-CustomerA

 

}

 

"/product3" {

 

pool product2-CustomerA

 

}

 

default {

 

pool standardpool-CustomerA

 

}

 

else {

 

switch [string tolower [HTTP::uri]] {

 

"/product1" {

 

pool product1

 

}

 

"/product2" {

 

pool product2

 

}

 

"/product3" {

 

pool product2

 

}

 

default {

 

pool standardpool-CustomerB

 

}

 

}

 

}

 

}

 

}

 

}

 

}

 

 

7 Replies

  • Hi Rob,

    That looks pretty close. Can you try this version with some debug logging added? I used the -glob flag on switch to group of few of the cases together. The curly braces also needed a tweak.

     
     when HTTP_REQUEST { 
        log local0. "[IP::client_addr]:[TCP::client_port]: New [HTTP::method] request to [HTTP::host][HTTP::uri]" 
        if { [IP::addr [IP::client_addr]/32 equals 1.1.1.1] } { 
      
           log local0. "[IP::client_addr]:[TCP::client_port]: Matched IP check for 1.1.1.1" 
      
           switch -glob [string tolower [HTTP::uri]] { 
              "/product[1-3]" { 
                 log local0. "[IP::client_addr]:[TCP::client_port]: Matched /product1-3 check" 
                 pool product1-CustomerA 
              } 
              default { 
                 log local0. "[IP::client_addr]:[TCP::client_port]: No match on /product1-3 check" 
                 pool standardpool-CustomerA 
              } 
           } 
        } else { 
           switch -glob [string tolower [HTTP::uri]] { 
              "/product1" { 
                 log local0. "[IP::client_addr]:[TCP::client_port]: No IP match. Matched /product1 check" 
                 pool product1 
              } 
              "/product[2-3]" { 
                 log local0. "[IP::client_addr]:[TCP::client_port]: No IP match. Matched /product2-3 check" 
                 pool product2 
              } 
              default { 
                 log local0. "[IP::client_addr]:[TCP::client_port]: No IP match. No product check" 
                 pool standardpool-CustomerB 
              } 
           } 
        } 
     } 
     

    Aaron
  • One other thing I meant to ask about: the URI tokens you have listed in the switch cases are equals comparisons. I assume the URIs won't always be exactly /product. Do you want to select the pool based on the URI starting with /product? If so, try adding a * to the end of each switch case:

     

     

    /product[1-3] would be /product[1-3]*

     

    and

     

    /product1 would be /product1*

     

     

    Aaron
  • You can view the logs in the GUI under System | Logs | Local Traffic. Or more ideally, access the CLI via SSH and run 'tail -f /var/log/ltm' without the single quotes to follow the end of the ltm log file. You can type Ctrl+c to stop the tail from running.

    Also, I think * will match 0 or more characters. So /test* would match /test:

     
     when RULE_INIT { 
      
        switch -glob "/test" { 
           "/test*" {log local0. "matched"} 
           default {log local0. "no match"} 
        } 
     } 
     

    Log output:

    : matched

    And using string match to test:

    % string match /test* /test

    1

    Or is that not what you meant?

    Aaron
  • Thanks for the logs, have found those.

     

     

    I am still a little confussed by the * part.

     

     

    If I enter "http://10.44.17.90/product1" into a browser, I get a 404 page not found error.

     

    If I enter "http://10.44.17.90/product1/default.htm" it returns the page.

     

     

    The iRule part of this is:-

     

     

    switch -glob [string tolower [HTTP::uri]] {

     

    "/product1*" {

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Matched /product1 check"

     

    pool product1

     

    }

     

     

    I am not sure if it matters as the pages are called explicitly from our main portal, it would just be nice to have it work.
  • Hi Rob,

     

     

    LTM isn't modifying the requested URI in your iRule--just selecting the pool based on the URI. If you make the same request for /product1 direct to the web server, I expect that you'll see the same 404 response.

     

     

    If you want to rewrite requests made to /product1 to /product1/default.htm, you could use HTTP::uri "/product1/default.htm" to do this. Or if you want the client to see the update, you could redirect them using HTTP::redirect "http://[HTTP::host]/product1/default.htm".

     

     

    Aaron
  • Hi Aaron.

     

     

    Many thanks for your help, we have now been able to get this through our test environment. Next stop production!

     

     

    Thanks

     

     

    Rob