Forum Discussion

Patrick_McGlyn1's avatar
Patrick_McGlyn1
Icon for Nimbostratus rankNimbostratus
Jun 15, 2010

Application migration iRule

I am trying to write an iRule to migrate applications from an old web farm pool to a new web farm pool. The web servers are setup to run multiple application instances on the same IP and Port. For example,

 

VIP 2.1.1.1:443 with SSL termination and cookie persistence

 

 

Old Web Pool

 

APP1 – 1.1.1.1:80/APP1/login.html, 1.1.1.2:80/APP1/login.html

 

APP2 – 1.1.1.1:80/APP2/login.html, 1.1.1.2:80/APP2/login.html

 

APP3 – 1.1.1.1:80/APP3/login.html, 1.1.1.2:80/APP3/login.html

 

 

 

New Web Pool

 

APP1 – 1.1.1.10:8080/APP1/login.html, 1.1.1.11:8080/APP1/login.html

 

APP2 – 1.1.1.10:8080/APP2/login.html, 1.1.1.11:8080/APP2/login.html

 

APP3 – 1.1.1.10:8080/APP3/login.html, 1.1.1.11:8080/APP3/login.html

 

 

 

I wrote the iRule to select the pool base on the URI as follows:

 

 

when HTTP_REQUEST {

 

set time_out 3600

 

if {[findclass [HTTP::uri] $::old_server_pool " "] ne "" } {

 

pool old_server_pool-80

 

} elseif {[findclass [HTTP::uri] $::new_server_pool " "] ne "" } {

 

pool new_server_pool-8001

 

}

 

}

 

 

It is not working as I thought it would. The web servers are doing a redirect from VIPIP/APP1/login.html to VIPIP/psp/APP1/?cmd=login. I have to put the redirect URI in the data group instead of the original URI. Why isn’t the original URI evaluated? Is there a better way of doing this?

 

 

 

  • Hi Patrick,

     

    can you post the structure of your data group?

     

     

    Bhattman
  • I think that it might be because you are using findclass instead of matchclass.

    In your example you are saying:

    If the [HTTP::uri] is equal to a value that I have stored in my data group, replace that value with the second data group value. If that value is not equal to "" nothing, then direct traffic to pool "old_server_pool-80.

    findclass is best used for a Match and Replace.

    Searches a data group list for a member whose key matches the specified string, and if a match is found, returns the data-group member string.

    http://devcentral.f5.com/wiki/default.aspx/iRules/findclass.html

    Try matchclass:

    
    when HTTP_REQUEST {
    if { [matchclass [HTTP::uri] equals $::old_server_pool] } {
    pool old_server_pool-80
    }
    elseif { [matchclass [HTTP::uri] equals $::new_server_pool] } {
    pool new_server_pool-8001
    }
    }
    
  • Sure. I should have thought to include it. I started with the following:

     

     

    class old_server_pool {

     

    "/app1/login.html"

     

    }

     

     

    I had to change it to the redirect URL to get it to work.

     

     

    class old_server_pool {

     

    "/psp/app1/?cmd=login"

     

    }

     

     

  • Michael,

     

     

    Thanks for the information. I tried the matchclass and it didn't work. I logged the URI before it hits the if statement. It is being logged as the redirected URI.

     

     

    log local0. "uri_string is => [HTTP::uri]"

     

     

    Result:

     

     

    Jun 15 17:25:14 tmm tmm[700]: Rule test-pool-select-irule : uri_string is => /psp/app1/?cmd=login

     

     

    I am not sure why.

     

  • Hi Patrick,

    From what I can tell you could do the following

    
    class redirectapp {
    "/app1/login.html  /psp/app1/?cmd=login"
    "/app2/login.html  /psp/app2/?cmd=login"
    "/app3/login.html  /psp/app3/?cmd=login"
    }
    

    
    when HTTP_REQUEST {
      set uriredirected [findclass [string tolower[HTTP::uri]] $::redirectapp " "]  
       if {$uriredirected ne "" } {
               HTTP::redirect "http://www.domain.com/$uriredirected"
               pool new_server_pool-8001
      }
    }
    

    This means if someone enters

    http://something.com/app1/login.html it will be redirected to /psp/app1/?cmd=logi

    or if someone enters

    http://something.com/app2/login.html it will be redirected to /psp/app2/?cmd=logi

    or if someone enters

    http://something.com/app3/login.html it will be redirected to /psp/app3/?cmd=logi

    is this what were looking for?

    Bhattman

  • Made a correction on the code

     

     

    when HTTP_REQUEST {
       switch -glob [string tolower [HTTP::uri] {
               "/psp/app*" { 
                          pool new_server_pool-8001 
               }
               default  {
                     set redirectapp [findclass [string tolower[HTTP::uri]] $::redirectapp " "]  
                     if {$redirectapp ne "" } {
                         HTTP::redirect "http://www.domain.com/$redirectapp"
                     }
                }
       }
    }
    

     

     

     

    Bhattman

     

  • Thanks Bhattman. I think it should work but I am still confused. Why does the URI show up in the log as the redirect URI received from the web server and not the original URI enter by the client?

     

     

    I thought I would see the URI as /app1/login.html if https://VIPIP/app1/login.html was entered in the browser instead of /psp/app1/?cmd=login which is the redirected URI sent back by the web server.