Forum Discussion

nik_65678's avatar
nik_65678
Icon for Nimbostratus rankNimbostratus
Oct 30, 2009

irule-based redirection & maintenance page

i'm trying to figure out a good irule-based solution for an irule-based downtime/maintence page. i already have the code for my downtime page done, however i'm wondering how to implement it on many pools. we use very few vips for many sites and an irule will send traffic to the appropriate pool. the issue comes into play when i want to add the downtime page. currently i'm doing something like this:

 

 

switch [string tolower [HTTP::host]] { 
   "www.host.com" { 
     if { [active_members www.host.com_80] > 0 } { use pool www.host.com_80 } 
     else { use pool downtime_pool_80 } 
   } 
   "www.host.com" { 
     if { [active_members www.host3.com_80] > 0 } { use pool www.host3.com_80 } 
     else { use pool downtime_pool_80 } 
   } 
   "www.host.com" { 
     if { [active_members www.host3.com_80] > 0 } { use pool www.host3.com_80 } 
     else { use pool downtime_pool_80 } 
   } 
 }

 

 

so in my irule i have a whole bunch of these, all identical. now, i have a rule that looks something like this to return a maintenance/down page:

 

 

switch -glob [string tolower [HTTP::uri]] { 
   "/" { HTTP::respond 200 content [b64decode [class element -value 0 maint_fxcm]] "Content-Type" "text/html" } 
   "/logo.gif" { HTTP::respond 200 content [b64decode [class element -value 1 maint_fxcm]] "Content-Type" "image/gif" } 
   "/top.jpg" { HTTP::respond 200 content [b64decode [class element -value 2 maint_fxcm]] "Content-Type" "image/jpeg" } 
   default { HTTP::redirect "/" } 
 }

 

 

previously i would use the downtime_pool to send customers when we took nodes down for maintenance, it was automatic and worked fine. the issue i've run into is what happens when the server that hosts downtime_pool is broken? then there's no maintenance page.

 

 

does anyone have an idea how to replace the "use pool downtime" with "generate a page on the LB" so i don't have to repeat it for every single host? my only idea is to do something like this but it seems kind of expensive (excuse the psudo code):

 

 

if { [host == "www.host1.com"] and [active_members host1.pool] > 0 } { use pool host1 } 
 elseif  { [host == "www.host2.com"] and [active_members host2.pool] > 0 } { use pool host2} 
 else { generate maintenance page }

 

 

anyway, i'd appreciate any suggestions that you guys may have on how to improve my situation. the number of sites we host only increases and these rules are getting pretty big. thanks!

3 Replies

  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    If your iRule really is that simple, then I have two suggestions. First, you could use variables:

     
     switch [string tolower [HTTP::host]] { 
       "www.host.com" { 
          set uppool www.host.com_80 
          set dnpool downtime_pool_80 
        } 
        "www.host2.com" { 
          set uppool www.host2.com_80 
          set dnpool downtime_pool_80 
        } 
        "www.host2.com" { 
          set uppool www.host3.com_80 
          set dnpool downtime2_pool_80 
        } 
     } 
     if { [active_members $uppool] > 0 } { 
        use pool $uppool 
     } else if { [active_members $dnpool] > 0 } { 
        use pool $dnpool 
     } else { 
         Server up LB-hosted maintenance page 
     } 
     

    The second suggestion would be to replace the switch statement with datagroups. This would help if you start getting large numbers of sites and want to keep your logic separate from your configuration.

  • that's a great idea, i like separating the config from the logic. something else i can probably do is add a third variable that would specify which maintenance page to use in the case that i have more than one.
  • i worked on this a bit this morning and came up with the following to fit my needs:

    when HTTP_REQUEST {  
         make sure $dn is an actual pool  
        set dn "empty_pool"  
        
         choose a vhost based on requested site name  
        switch [string tolower [HTTP::host]] {  
          www.sitename1.com { set up www.sitename.com; set dn www.sitename.com_down }  
          www.sitename2.com { set up www.sitename.com_80 }  
          www.complexsite.com { set up www.complexsite.com }  
        }  
        
         check for sites that need special treatment first, then sites that are up  
         then down sites (with a down pool), then down sites (with no down pool)  
        if { $up equals "www.complexsite.com" and [active_members $up] > 0 } {  
          switch -glob [string tolower [HTTP::uri]] {  
            "/uri1*" - "/uri2*" - "/uri3/pagename.html" { use pool $up }  
            default { HTTP::uri "/append/to/beginning[HTTP::uri]"; use pool $up }  
          }  
        }  
        elseif { [active_members $up] > 0 } { use pool $up }  
        elseif { [active_members $dn] > 0 } { use pool $dn }  
        else {  
          switch -glob [string tolower [HTTP::uri]] {  
            "/" { HTTP::respond 200 content [b64decode [class element -value 0 maint_fxcm]] "Content-Type" "text/html" }  
            "/logo.gif" { HTTP::respond 200 content [b64decode [class element -value 1 maint_fxcm]] "Content-Type" "image/gif" }  
            "/top-backbanner.jpg" { HTTP::respond 200 content [b64decode [class element -value 2 maint_fxcm]] "Content-Type" "image/jpeg" }  
            default { HTTP::redirect "/" }  
          }  
        }   
      }

    thanks again for the suggestions.