Forum Discussion

jokragly's avatar
jokragly
Icon for Nimbostratus rankNimbostratus
Jul 22, 2016

iRule for sorry page with pool and path

So I have an iRule that identifies if the LB server pool is equal to 0 then call a different pool which is the server hosting the Sorry Page. The issue is the Sorry page is not at the root of this pool, its at /mov. Anyone know how I can modify my iRule so that when LB equals 0 it would direct traffic to the new pool/mov?

 

The reason I am calling a pool is because we are required to maintain the URL's domain, so a redirect doesn't work.

 

when HTTP_REQUEST { if { [active_members [LB::server pool]] == 0 } { pool mov_maintenance_page} { return }

 

5 Replies

  • Untested:

    when HTTP_REQUEST { 
    if { [active_members [LB::server pool]] == 0 } { 
    HTTP::uri /mov
    pool mov_maintenance_page 
    } { return }
    
  • I would use the LB_FAILED event instead. Also, I might insert a connection close to make sure that the user gets a new iRule flow upon any retry:

    when LB_FAILED {
            set failed 1
            HTTP::uri "/maintenance/maintenance.html"
            pool mov_maintenance_page
        }
    }
    
    when HTTP_RESPONSE {
        if { [info exists failed] && $failed== 1 } {
            HTTP::close
        } 
    }
    

    /Patrik

  • Hi again!

    Here's some comments:

        when LB_FAILED {
                LB failed is triggered when the load balancer
                is unable to choose a member for the connection (no available 
                members, or too many retries due to server connection issues
    
                Set the variable failed to 1 so we can check it later in the response
                set failed 1
    
                Rewrite the uri to whatever you want it to be. 
                The client would still see whatever they had from before
    
                HTTP::uri "/maintenance/maintenance.html"
    
                Select the pool you want to serve the maintenance page
                pool mov_maintenance_page
            }
        }
    
        when HTTP_RESPONSE {
            Check if the LB failed event has been triggered by checking if
            the variable failed exists and is set to 1
            if { [info exists failed] && $failed == 1 } {
                Close the connection to make sure that the user makes a new connection
                HTTP::close
            } 
        }
    `
    
    
    The problem with this setup, which I might mention too, is that you would be unable to send any pictures with the sorry page, unless you encode them with base64 within the html content OR use a CDN to deliver them.
    
    Reason:
    

    ol

    Instead you might want to qualify incoming requests for the sorry page content directory before rewriting the uri:
    
    `    when LB_FAILED {
                LB failed is triggered when the load balancer
                is unable to choose a member for the connection (no available 
                members, or too many retries due to server connection issues
    
                Set the variable failed to 1 so we can check it later in the response
                set failed 1
    
                If the client does not request resources in the maintenance
                folder, then rewrite the uri. Otherwise, let it pass through as the 
                content reqests belongs to the maintenance page
    
                if { !([HTTP::uri starts_with "/mov") } {
                    HTTP::uri "/mov"
                }
    
                Select the pool you want to serve the maintenance page
                pool mov_maintenance_page
            }
        }
    
        when HTTP_RESPONSE {
            Check if the LB failed event has been triggered by checking if
            the variable failed exists and is set to 1
            if { [info exists failed] && $failed == 1 } {
                Close the connection to make sure that the user makes a new connection
                HTTP::close
            } 
        }
    
    
    From a design perspective I would consider delivering the sorry page content directly from the F5 though using HTTP::respond and content from the CDN, because when there's a server side problem, there's also a risk that your sorry pool members is affected too.
    /Patrik
  • Silly me. Freestyling iRules is not working out so good it seems. Try this?

        when LB_FAILED {
            LB failed is triggered when the load balancer
            is unable to choose a member for the connection (no available 
            members, or too many retries due to server connection issues
    
            Set the variable failed to 1 so we can check it later in the response
            set failed 1
    
            If the client does not request resources in the maintenance
            folder, then rewrite the uri. Otherwise, let it pass through as the 
            content reqests belongs to the maintenance page
    
            if { !([HTTP::uri starts_with "/maintenance/") } {
                HTTP::uri "/maintenance/maintenance.html"
            }
    
            Select the pool you want to serve the maintenance page
            pool mov_maintenance_page
        }
    
        when HTTP_RESPONSE {
            Check if the LB failed event has been triggered by checking if
            the variable failed exists and is set to 1
            if { [info exists failed] && $failed == 1 } {
                Close the connection to make sure that the user makes a new connection
                HTTP::close
            }
        }
    

    /Patrik

  • About the question on how to host the page on the f5, there's ton's of articles on how to do that on DC. These should send you down the right track:

     

    Here's the article about HTTP respond:

     

    https://devcentral.f5.com/wiki/iRules.HTTP__respond.ashx

     

    Here's a few examples:

     

    https://devcentral.f5.com/questions/serve-status-page-with-images-on-ltm-v102

     

    https://devcentral.f5.com/questions/irule-maintanance-page-with-ifile

     

    You can manually trigger LB_FAILED by creating a pool with mock members, or disable all members in a pool and then test it out.

     

    You can always write back if you run into trouble. :)

     

    /Patrik