LTM Maintenance Window

Problem this snippet solves:

This iRule uses the STATS profile to manage an LTM maintenance page response during maintenance windows.

Implementation details here: DevCentral - An F5 Technical Community

Code :

when HTTP_REQUEST {
  set TITLE "iRule Maintenance Window Control"
  set PROFILE_NAME "maintenance_window"

  # Look for embedded commands to control the maintenance window.

  switch -glob [string tolower [HTTP::uri]] {
    "/enable*" {

      # Extract the maintenance window day, start time, and end time from the URI. 
      # If not there, return an error message.

      set params [split [HTTP::uri] "/"]
      if { [llength $params] < 5 } {
        HTTP::respond 200 content "
          <center>
<title>$TITLE</title>
          <h1 id="community-277779-toc-hId-1847774792">Usage: http://[HTTP::host]/enable/day_number/start_hour/end_hour</h1>
          "
      } else {

        # Update the maintenance window values in the statistics profile.

        STATS::set $PROFILE_NAME "day" [lindex $params 2]
        STATS::set $PROFILE_NAME "start_time" [lindex $params 3]
        STATS::set $PROFILE_NAME "end_time" [lindex $params 4]
        HTTP::respond 200 content "
          <center>
<title>$TITLE</title>
          <h1 id="community-277779-toc-hId--704382169">Maintenance Window enabled</h1>
          "
      }
    }
    "/disable" {

      # By zero'ing out the values in the statistics profile, the maintenance window is not enforced.

      STATS::set $PROFILE_NAME "day" 0
      STATS::set $PROFILE_NAME "start_time" 0
      STATS::set $PROFILE_NAME "end_time" 0
      HTTP::respond 200 content "
        <center>
<title>$TITLE</title>
        <h1 id="community-277779-toc-hId-1038428166">Maintenance Window disabled</h1>
        "
    }
    "/check" {

      # Return the current time and the current settings for the maintenance window

      set day [STATS::get $PROFILE_NAME "day"]
      set start_time [STATS::get $PROFILE_NAME "start_time"]
      set end_time [STATS::get $PROFILE_NAME "end_time"]
      set l [split [clock format [clock seconds] -format {%u %H %M}] " "]
      set cur_day [lindex $l 0]
      set cur_time [expr [expr [lindex $l 1]*100] + [lindex $l 2]]
        HTTP::respond 200 content "
          <center>
<title>$TITLE</title>
          <h1 id="community-277779-toc-hId--1513728795">Current Date and time: $cur_day, $cur_time</h1>
            <h1 id="community-277779-toc-hId-229081540">Maintenance Window: $day, $start_time - $end_time</h1>
          "
    }
    "/usage" {

        # Usage instructions for the commands

        HTTP::respond 200 content "
          <center>
<title>$TITLE</title>
          <h1 id="community-277779-toc-hId-1971891875">Usage: http://[HTTP::host]/\[command\]</h1>
          <table><tbody><tr><td><ul>
            <li>/enable/day_of_week_number(1:mon-7:sun)/start_time(hhmm)/end_time(hhmm) - enable maintenance window.</li>
            <li>/disable - disable maintenance window.</li>
            <li>/check - check if in maintenance window.</li>
            <li>/usage - display this usage message</li>
          </ul></td></tr></tbody></table>
          "
    }
    default {

      # no secret command entered, so check the maintenance window

      # Get the values from the statistics profile.
      set day [STATS::get $PROFILE_NAME "day"]
      set start_time [STATS::get $PROFILE_NAME "start_time"]
      set end_time [STATS::get $PROFILE_NAME "end_time"]

      if { ($day ne 0) and ($start_time ne 0) and ($end_time ne 0) } {

        # Use the TCL "clock" command to get the current time settings.
        set l [split [clock format [clock seconds] -format {%u %H %M}] " "]
        set cur_day [lindex $l 0]
        set cur_time [expr [expr [lindex $l 1]*100] + [lindex $l 2]]
        if { ($cur_day eq $day) &&
           ($cur_time >= $start_time) &&
           ($cur_time <= $end_time) } {

          # The current time is in the maintenance window, so either issue a HTTP::redirect here to a
          # prettied up page, or you can do as I've done here, and return a HTML response direction
          # to the client.

          HTTP::respond 200 content "
            <center>
<title>$TITLE</title>
            <h1 id="community-277779-toc-hId--580265086">This site is down for maintenance, please come back at $end_time ...</h1>
            "

        } else {

          # Not in maintenance window, so allow connection to continue to application.

        }
      }
    }
  }
}</center>
</center>
</center>
</center>
</center>
</center>