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

Was this article helpful?