Forum Discussion

James_Richter_1's avatar
James_Richter_1
Icon for Nimbostratus rankNimbostratus
Mar 12, 2013

multiple redirect iRules on a VS

We have a single VS that normally uses a iRule that does a redirect for / to /irj/portal/ When there is maintenance on that system, we want to have a redirect to another web server active but currently when we enable the down message iRule we get a connection reset and TCL error. Below are some specifics. Is there an easy way to get both iRules to operate on the single VS for when we do system maintenance. I'd rather not have to remove a iRule and replace it since we use an iControl to enable and disable the down iRule.

 

 

Here's the error message:

 

 

Mar 12 09:08:02 tmm2 err tmm2[8755]: 01220001:3: TCL error: /Common/Portal_URI_Redirect - Operation not supported. Multiple redirect/respond invocations not allowed (line 1) invoked from within "redirect to "/irj/portal""

 

 

And here's the problem:

 

 

ltm rule /Common/Portal_URI_Redirect {

 

when HTTP_REQUEST {

 

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

 

redirect to "/irj/portal"

 

}

 

}

 

}

 

 

ltm rule /Common/Portal_Down_Redirect_OnDemand {

 

when HTTP_REQUEST {

 

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

 

redirect to "http://site.com/portal_down/index.html"

 

}

 

}

 

}

 

10 Replies

  • nathe's avatar
    nathe
    Icon for Cirrocumulus rankCirrocumulus
    James,

     

     

    When you do maintenance do you disable the pool member(s)? If you do you could use the active_members or LB::status commands and if there are no active pool members then redirect to the other portal e.g. if {[active_members pool_name] < 1}{ etc....

     

     

    Just one option to consider.

     

     

    Hope this helps,

     

    N
  • Unfortunately the developers want to be able to bring the system back online, but not have the unwashed masses accessing it yet, so I saw that in other posts, but I don't think it'll work for us in this.

     

     

    Thanks!
  • A few things to consider:

     

     

    1. Are you just add the second iRule when you want the maintenance redirect? And not removing the first? If so, at the very least change the HTTP::redirect commands to an HTTP::respond 302 and see if that helps.

     

     

    2. If you want [all] users to go to the maintenance page, then it sort of doesn't make sense to trigger it based on the HTTP::uri. You should consider removing the URI condition completely for the maintenance redirect.

     

     

    3. Perhaps adding another iRule is not the very best approach. You could, alternatively, maintain a data group that sets or unsets maintenance mode based on the HTTP::host field:

     

     

    Example data group:

     

    www1.example.com := 0

     

    www2.example.com := 1

     

     

    iRule pseudo code:

     

    when HTTP_REQUEST {

     

    if { ( [class match [string tolower [HTTP::host]] equals host_group] ) and ( [class match -value [string tolower [HTTP::host] equals host_group] equals 1 ) } {

     

    HTTP::respond 302 Location "maintenance page URI"

     

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

     

    HTTP::respond 302 Location "/irj/portal/"

     

    }

     

    }
  • Good point on the trigger for the uir. I think in my copy and paste frenzy I just took a previous rule and resued some unnessiary code.

     

     

    Thing is, I replaced that part, and did just a HTTP::respond and I'm still getting a connection reset. I'm not sure I understand why since it's not using the same redirect method twice?
  • The problem is that you have multiple redirect invocations in the same HTTP request. When you compile the iRule the two HTTP_REQUEST events are mashed together, so you end up with something like this:

    when HTTP_REQUEST {

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

    HTTP::redirect "/irj/portal/"

    HTTP::redirect "/maintenance site"

    }

    }

    This is a bad thing. Here's a thought. Given the way that events are mashed together on compile, why not modify your iRules to look something like this:

    
    Regular iRule:
    when HTTP_REQUEST {
    if { [info exists MAINTMODE] and $MAINTMODE eq "on" } {
    HTTP::respond 302 Location "maintenance site"
    } elseif { [HTTP::uri] equals "/" } {
    HTTP::respond 302 Location "/irj/portal/"
    }
    }
    
    Maintenance mode iRule:
    when HTTP_REQUEST priority 10 {
    set MAINTMODE "on"
    }
    

    This way, the MAINTMODE variable only exists in the request when you add the maintenance mode iRule, and the higher priority ensures that it's available before the condition is checked.

  • Jnon's avatar
    Jnon
    Icon for Nimbostratus rankNimbostratus
    kevin - I"m trying to follow your logic, - James says it's working, so I trust that it does, however it looks to me like the maintenance mode will always be on. if the Maintenance irule is setting Mainmode to on, it looks like the only thing that will determine if the mode is on or off - is the priority of which the rules execute, you've set it to 10, and I think by default it's 1 if Im not mistaken, if that's the case - MaintMode I guess would be set after the other http request already executed.
  • The default priority is 500 (out of 1000), so adding the maint mode iRule would set the variable, and the existing iRule would simply check to see if it's there.
  • J I think I understand what your asking. When we have the Maintenance Mode iRule active on that VS it will do the redirect, but when we remove that iRule from the Virtual Server, it skips that line, and does the redirect to /irj/portal which is exactly what I needed it to do for the iControl we have to work correctly. We wanted the ability to add an iRule to the virtual server in order to force the sorry page to come up instead of the site. I hadn't considered what Kevin recommended...it works perfectly for us.

     

    Thanks again Kevin!

     

  • Jnon's avatar
    Jnon
    Icon for Nimbostratus rankNimbostratus
    Oh, I have you then, I was thinking you were leaving it in all the time - I get it... I just went through this exercise this last week where I had two rules ( written by someone else ) that had conflicting http::request statements, bottom line both were setting a default pool, each different, so as you can imagine it was not very predictable...

     

     

    Thanks James for the clarification