Forum Discussion

Gregt_33960's avatar
Gregt_33960
Icon for Nimbostratus rankNimbostratus
Jun 11, 2008

IRule send to wrong Pool and Port

Hello,

 

 

I am hoping this is going to be an easy fix. I have several web server instances over various ports on a web server and the IRule, using URI filters, was working fine, until I needed to add one more.

 

 

I have the following pools & ports defined

 

 

train_pool port 9080

 

uat_pool port 7080

 

test_pool port 9081

 

uatpr_pool port 5080

 

 

Now my base URL for the filter is http://test.domain.com

 

and when the URI is appended at the end, the F5 Filters and sends to the proper pool and Port. For example

 

 

http://test.domain.com/uat --> the F5 sends to uat_pool on port 7080 ( this works fine)

 

 

Now when I try to do:

 

 

http://test.domain.com/uatpr I am now getting this error message:

 

 

A WebGroup/Virtual Host to handle test.domain.com:7080 has not been defined.

 

 

I have no idea why it is trying to send to port 7080? That is not the pool or port I defined for that instance. Does the f5 do some sort of pattern matching and gets confused if there are two URIs that are similar?

 

 

 

Does anyone have any insights please.

 

 

thanks

 

Greg

10 Replies

  • Hi Greg,

     

    Can you post your iRule so that we can understand the logic you are using.

     

     

    Thanks,

     

    CB

     

  • Absolutely... Please note that I did a Copy and paste and when I post I may lose the TAB formating.

    Here is my Irule:

     
      when HTTP_REQUEST {  
      log local0. "[IP::client_addr]:[TCP::client_port]:[HTTP::uri]"  
      if {[HTTP::uri] starts_with "/train" }{  
            if {([HTTP::uri] ends_with "/train") or ([HTTP::uri] ends_with "/train/")} {  
      HTTP::uri "/train/jsp/common/pgLogin.jsp"   
      }     
      pool train_pool  
      } elseif {[HTTP::uri] starts_with "/uat"}{  
            if {([HTTP::uri] ends_with "/uat") or ([HTTP::uri] ends_with "/uat/")}{  
      HTTP::uri "/uat/jsp/common/pgLogin.jsp"  
      }  
          pool uat_pool  
      } elseif {[HTTP::uri] starts_with "/uatpr"}{  
            if {([HTTP::uri] ends_with "/uatpr")  or ([HTTP::uri] ends_with "/uatpr/")}{  
      HTTP::uri "/uatpr/jsp/common/pgLogin.jsp"   
      }  
          pool uatpr_pool  
      } elseif {[HTTP::uri] starts_with "/" }{  
           if {[HTTP::uri] ends_with "/"}{  
                HTTP::uri "/uat/jsp/common/pgLogin.jsp"  
                }  
                pool uat_pool  
         }  
      }
  • You need to rearrange your If statements.

     

     

    The problem is that /uatpr matches the starts_with check for /uat, so it's not making it to /uatpr.

     

     

    Try swapping the /uat and /uatpr checks so that it checks for /uatpr before /uat.
  • HI Greg,

    I think the problem is that it's matching the UAT IF stagement first. You are using "starts_with" which means uatpr actually starts with "uat" in the string. Perhaps you might want to change the order of evaluation. Instead of evaluating UAT before UATPR, try evaluating UATPR first and then UAT.

    Another thing I noticed was the multiple IF-ELSE statements to define your logic. You might want to change that over to using a "switch" statement only to cut down on the IF-ELSEIF and avoided the nested IF statements.

    I.E.

        
        when HTTP_REQUEST {    
           switch -glob [HTTP::uri] {    
           "/train*" { pool train_pool }    
           "*/train" { HTTP::uri "/train/jsp/common/pgLogin.jsp" }    
           "/uatpr*" {pool uatpr_pool}    
           "*/uatpr" { HTTP::uri "/uatpr/jsp/common/pgLogin.jsp" }    
           "/uat*" {pool uat_pool}    
           "*/uat" { HTTP::uri "/uat/jsp/common/pgLogin.jsp" }    
           default { pool uat_pool}    
           }    
        }    
        

    Click here for more info about using switch

    Hope this helps.

    CB

  •  

     

    Thank you that was it.. I should have caught that..

     

     

    As for my logic, I would absolutely love to get rid of my if/elseif statements and clean it up..

     

     

    I looked at using switch statements, but given the inflexibility of our application did not know the syntax for matching so many variations..

     

     

    I am looking at the switch logic you provided and have some questions.I will use the "/train" logic

     

     

    1) If I understand your logic, if the F5 filters the URI "/train" or anything after "/train" send to train_pool

     

     

    if the filter ends with /train -- append the pgLogin.jsp string

     

     

    a) now I need a statement that says if F5 recieves "*/train/" then append the pgLogin.jsp as well. is that possible? Basically an or statement that states "*/train" or "*/train/" append the pg.Login.jsp else send everything to the train_pool?

     

     

     

     

  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Good call on the switch case, CB. Doesn't look like you are making the pool selection in the case of the URI re-writing, is all - the switch is a case statement, and will drop out after executing the first match body.

    Expanding on that idea a bit, and splitting up the 2 decisions that need to be made, I think this might be what you're after, Greg:

       
           when HTTP_REQUEST {   
               first set the pool for any URI containing one of the subdirs   
              switch -glob [HTTP::uri] {       
                "*/train*" { pool train_pool }   
                "*/uatpr*" { pool uatpr_pool }   
                "*/uat*"   { pool uat_pool }   
              }   
               now re-write the URI's when necessary   
               a "-" means to execute the same body as the next condition   
               The only diff betw the 2 strings is whether the leading '/" is needed   
              switch -glob [HTTP::uri] {   
                "*/train/" -   
                "*/uatpr/"  -   
                "*/uat/"    { HTTP::uri "[HTTP::uri]jsp/common/pgLogin.jsp" }   
                "*/uatpr"  -   
                "*/train"  -   
                "*/uat"    { HTTP::uri "[HTTP::uri]/jsp/common/pgLogin.jsp" }   
              }   
           }       
       

    HTH

    /deb
  • Wow... that looks pretty slick... I am going to test this in about an hour. One last question if Might.

     

     

    Desired URI to pool mapping

     

    http://test.domain.com --> uat_pool

     

    http://test.domain.com/uatpr --> uatpr_pool

     

    http://test.domain.com/train --> train_pool

     

    http://test.domain.com/sandbox --> sandbox_pool

     

     

     

    According to the syntax you sent it does not include the default correct? I also need to assign a default pool do I not so that when some one uses

     

     

    http://test/domain.com

     

     

    It also points to the uat_pool and appends that pglogin.jsp string.. my old logic, the very end of my IF ELSE Statements looks like:

     

     

    } elseif {[HTTP::uri] starts_with "/" }{

     

    if {[HTTP::uri] ends_with "/"}{

     

    HTTP::uri "/uat/jsp/common/pgLogin.jsp"

     

    }

     

    pool uat_pool

     

    }

     

    }

     

     

    To incorporate that do I just use "default" {pool train_pool) syntax at the end for setting the pool?

     

  • Did not work as planned

     

     

    Status update.. the code almost worked... I can not get this to work for these root URLs

     

     

    http://test.domain.com or http://test.domain.com/

     

     

    everytime I enter this in my browser I get page not found but all the other filters work.. For example

     

     

    http://test.domain.com/train works great.

     

     

     

    My objective is that the base URL should default to a pool and append the pgLogin.jsp string. and be redirected to that page.

     

     

     

    I tried adding another switch statement to see what happens but no luck

     

     

    Below is my code

     

     

    when HTTP_REQUEST {

     

    log local0. "[IP::client_addr]:[TCP::client_port]:[HTTP::uri]"

     

    first set the pool for any URI containing one of the subdirs

     

     

    switch -glob [HTTP::uri] {

     

    "*/sandbox*" { pool state_sandbox_pool }

     

    "*/pilot*" { pool state_pilot_pool }

     

    "*/whatif*" { pool state_whatif_pool }

     

    "*/intgtst*" { pool state_int_pool }

     

    "*/uatpr*" { pool state_uatpr_pool }

     

    "*/uat*" { pool state_uat_pool }

     

    "*/train*" { pool state_train_pool }

     

    "*/*" { pool state_uat_pool }

     

    }

     

    now re-write the URI's when necessary

     

    a "-" means to execute the same body as the next condition

     

    The only diff betw the 2 strings is whether the leading '/" needs to be included

     

     

    switch -glob [HTTP::uri] {

     

    "*/sandbox/" -

     

    "*/pilot/" -

     

    "*/whatif/" -

     

    "*/intgtst/" -

     

    "*/uatpr/" -

     

    "*/uat/" -

     

    "*/train/" -

     

    "*/sandbox" -

     

    "*/pilot" -

     

    "*/whatif" -

     

    "*/intgtst" -

     

    "*/uatpr" -

     

    "*/uat" -

     

    "*/train" { HTTP::uri "[HTTP::uri]/jsp/common/pgLogin.jsp" }

     

    }

     

    }
  • Did you try using "default { pool state_uat_pool }" instead of "*/*" { pool state_uat_pool }?

     

     

    The other idea I was thinking was simply removing "*/* and simply adding state_uat_pool in the pool list of Virtual Server.

     

     

    CB

     

     

     

  • CB,

     

     

    Thank you for the input. I may try the Virtual server idea.... Here is what I have right now that seems to be working, but I suspect it is not very good logic. I added the default pool statement and third switch statement.

     

     

    switch -glob [HTTP::uri] {

     

    "*/sandbox*" { pool state_sandbox_pool }

     

    "*/pilot*" { pool state_pilot_pool }

     

    "*/whatif*" { pool state_whatif_pool }

     

    "*/intgtst*" { pool cnsi_int_pool }

     

    "*/uatpr*" { pool state_uatpr_pool }

     

    "*/uat*" { pool state_uat_pool }

     

    "*/train*" { pool state_train_pool }

     

    default { pool state_uat_pool }

     

    }

     

    now re-write the URI's when necessary

     

    a "-" means to execute the same body as the next condition

     

    The only diff betw the 2 strings is whether the leading '/" needs to be included

     

     

    switch -glob [HTTP::uri] {

     

    "*/sandbox/" -

     

    "*/pilot/" -

     

    "*/whatif/" -

     

    "*/intgtst/" -

     

    "*/uatpr/" -

     

    "*/uat/" -

     

    "*/train/" { HTTP::uri "[HTTP::uri]jsp/common/pgLogin.jsp" }

     

    "*/sandbox" -

     

    "*/pilot" -

     

    "*/whatif" -

     

    "*/intgtst" -

     

    "*/uatpr" -

     

    "*/uat" -

     

    "*/train" { HTTP::uri "[HTTP::uri]/jsp/common/pgLogin.jsp" }

     

    }

     

    if {[HTTP::uri] equals "/" }{

     

    HTTP::uri "/uat/jsp/common/pgLogin.jsp"

     

    }

     

     

    }

     

    }