For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Pool Member Status Page on a Virtual Server v10

Problem this snippet solves:

This iRule will create a dynamic updated HTML page and/or xml rss page of all the pools and their members address and ports and indicate UP/DOWN or Disabled Status. It uses an external datagroup file, + cron to make the list dynamic.

You apply the iRule to a virtual server with the HTTP profile. This will allow clients or other IT personal see pools and their member status w/o logging into the LTM. The page is useful if you have separate monitors that can look at the content of the page.

Note: This was only tested on Version 10.0.1 HF3 and 10.2.0

  1. Create a file in the following path on the LTM
/etc/cron.daily/pool_member_status_list.cron

which contains: "b db bigpipe.displayservicenames false" was added in because the b load command changes it to true.

#!/bin/bash 
b db bigpipe.displayservicenames false
b pool all |grep "POOL MEMBER" | awk '{sub(":any",":0",$4);print "\""$4"\","}' | sort >/var/class/pool_member_status_list.class

if [ "`cat /var/prompt/ps1`" == "Active" ]; then
   b load
fi

exit 0

Alternately, you can use the following script, which does not require a configuration load post-execution (works better on HA systems) - contributed by joelmoses:

#!/bin/bash

# Handle a first-run situation
if [ ! -e /var/class/pool_member_status_list.class ]; then
   touch /var/class/pool_member_status_list.class
fi

# Grab the node list from bigpipe
nodelist=`b pool all |grep "POOL MEMBER" | awk '{sub(":any",":0",$4);print "\""$4"\","}' | sort`
for i in $nodelist; do
   # Get the service from the bigpipe output for the pool member
   service=`echo $i | cut -f2 -d : - | sed s/\",// -`
   # Determine whether the service is a numeric value or not; if not, we'll look it up in /etc/services.
   echo -n $service | egrep -q "^6553[0-5]|655[0-2][0-9]\d|65[0-4](\d){2}|6[0-4](\d){3}|[1-5](\d){4}|[1-9](\d){0,3}$"
   if [ $? == 0 ]; then
       servicenumber=$service
   else
       servicenumber=`cat /etc/services | tr '\011' ',' | sed s/,,/,/ | grep "^$service,.*\/tcp" | cut -f2 -d, | cut -f1 -d/`
   fi
   # Write it to a temp file in the class directory.
   echo $i | sed s/$service\"\,/$servicenumber\"\,/ >> /var/class/pool_member_status_list.class.tmp.$$
done

# Move the temp file to the active position.
mv /var/class/pool_member_status_list.class.tmp.$$ /var/class/pool_member_status_list.class

# Only load the config to update with the new class file if I am in HA Active mode (avoids getting out of sync if 
# this happens on the Standby unit).
if [ "`cat /var/prompt/ps1`" == "Active" ]; then
   b load
fi

exit 0
  1. Change the permissions by entering:
chmod +755 /etc/cron.daily/pool_member_status_list.cron
or
chmod +x /etc/cron.daily/pool_member_status_list.cron
  1. Create a external datagroup
Main >> Local Traffic >> iRules 
Select Data Group List
Click create
enter name: pool_member_status_list
enter Type: External
Path / Filename: /var/class/pool_member_status_list.class
File Content: String

Code :

when HTTP_REQUEST {
if { [HTTP::uri] eq "/status" } {
set response "BIGIP Pool Member Status - \
[clock format [clock seconds]]

BIGIP Pool Member Status - [clock format [clock seconds]]

\ " foreach { selectedpool } [class get pool_member_status_list] { if { [catch { scan $selectedpool {%[^/]/%[^:]:%s} poolname addr port switch -glob [LB::status pool $poolname member $addr $port] { "up" { append response "\ " } "down" { append response "\ " } "session_enabled" { append response "\ " } "session_disabled" { append response "\ " } Default { append response "\ " } } #SWITCH END } errmsg] } { append response "\ " } } append response "
StatusPool NameMemberPort
UP[string tolower $poolname]$addr$port
DOWN[string tolower $poolname]$addr$port
ENABLED[string tolower $poolname]$addr$port
DISABLED[string tolower $poolname]$addr$port
INVALID[string tolower $poolname]$addr$port
INVALID[string tolower $poolname]$addr$port
" HTTP::respond 200 content $response "Content-Type" "text/html" "Cache-Control" "no-cache, must-revalidate" "Expires" "Mon, 26 Jul 1997 05 } if { [HTTP::uri] eq "/rss" } { set response " \ BigIP Server Pool StatusServer Pool Status \ en[clock format [clock seconds]]\60" foreach { selectedpool } [class get pool_member_status_list] { if { [catch { scan $selectedpool {%[^/]/%[^:]:%s} poolname addr port switch -glob [LB::status pool $poolname member $addr $port] { "up" { append response "[string tolower $poolname] Status \ Member $addr:$port is UP" } "down" { append response "[string tolower $poolname] Status \ Member $addr:$port is DOWN" } "session_enabled" { append response "[string tolower $poolname] Status \ Member $addr:$port is ENABLED" } "session_disabled" { append response "[string tolower $poolname] Status \ Member $addr:$port is DISABLED" } Default { append response "[string tolower $poolname] Status \ Member $addr:$port is INVALID" } } #SWITCH END } errmsg] } { append response "[string tolower $poolname] StatusMember $addr:$port is \ INVALID" } } append response "" HTTP::respond 200 content $response "Content-Type" "text/xml" "Cache-Control" "no-cache, must-revalidate" "Expires" "Mon, 26 Jul 1997 05 } }
Published Mar 18, 2015
Version 1.0

1 Comment