Forum Discussion
pools members status using icontrol
Hi Experts,
we are in situation where our clients want to check the pool members status and we are not willing to give them a ready only access of our F5s. I searched little bit and found that it can be done by icontrol but could not find any details. if anyone ran into this situation before can you please share the solution details.
Thanks
4 Replies
This is an interesting subject, and I'd also love to hear other peoples answers. If we're talking real-time checks you might be better off with SNMP.
Reason being that giving people access through iControl basically gives them access to the GUI of the F5, as they have to be able to access it via https to query via iControl. REST is even worse at the moment as it needs full admin access on top of that.
I did see one company use a combination or REST and an XML gateway. They then could filter which REST methods that was allowed through the XML gateway and they could also use the Active directory to grant permissions.
Generally I'd recommend against letting people do polling against the F5s since it really does not take much to bring them down with a simple configuration mistake in ie. "SoapUI". I saw this happen during a demonstration once and it was pretty scary.
With SNMP you could let the chosen monitoring software, ie Zabbix poll the pool members while the clients poll Zabbix via SOAP.
OR you can use a virtual server and let them poll that instead. I wrote this iRule to add status information from Office clients (some of the information actually includes pool member statuses). Maybe you can rewrite it to your liking? Please note that I'm not sure how TMOS gets the pool member statuses and the performance impact in doing so may times. We've had no performance issues at all though.
when CLIENT_ACCEPTED { set originaluri "" set urisenttoserver "" set originalhost "" set hostsenttoserver "" set chosenpool "" set memberstatus "" if { [class match [IP::remote_addr] equals OurOffices] || [IP::addr [IP::remote_addr] equals "192.168.0.0/16"] } { set internal 1 } else { set internal 0 } } when HTTP_REQUEST { if { $internal eq 1 } { set httpreqstarttime [clock clicks -milliseconds] set originaluri [HTTP::uri] set originalhost [HTTP::host] } } when LB_SELECTED { if { $internal eq 1 } { set selectedpool [LB::server pool] set selectedserver [LB::server addr] set selectedport [LB::server port] Get the members of the currently selected pool set mbrs [members -list $selectedpool] Get the status for each member foreach mbr $mbrs { set mbrlist [split $mbr " "] set memberip [lindex $mbrlist 0] set memberport [lindex $mbrlist 1] set status [LB::status pool $selectedpool member $memberip $memberport] set memberstatus "$memberstatus$mbr $status;" } } } when HTTP_REQUEST_RELEASE { if { $internal eq 1 } { set urisenttoserver [HTTP::uri] set hostsenttoserver [HTTP::host] } } when HTTP_REQUEST_SEND { if { $internal eq 1 } { set httpreqsenttime [clock clicks -milliseconds] } } when HTTP_RESPONSE { if { $internal eq 1 } { set timetakenserver [expr {[clock clicks -milliseconds] - $httpreqsenttime}] HTTP::header insert X-TimeTaken-Server "$timetakenserver" HTTP::header insert X-Original-URI $originaluri HTTP::header insert X-URI-Sent-To-Server $urisenttoserver HTTP::header insert X-Virtual-Server-Name [virtual name] if { $selectedpool eq "" } { HTTP::header insert X-Selected-Pool "No pool selected" } else { HTTP::header insert X-Selected-Pool $selectedpool HTTP::header insert X-Active-Members [active_members $selectedpool] } if { $selectedserver eq "" } { HTTP::header insert X-Selected-Server "No server selected" } else { HTTP::header insert X-Selected-Server $selectedserver } if { $selectedport eq "" } { HTTP::header insert X-Selected-Port "No port selected" } else { HTTP::header insert X-Selected-Port $selectedport } if { $memberstatus eq "" } { HTTP::header insert X-Member-Status "No members" } else { HTTP::header insert X-Member-Status $memberstatus } HTTP::header insert X-Original-Host $originalhost HTTP::header insert X-Host-Sent-To-Server $hostsenttoserver } } when HTTP_RESPONSE_RELEASE { if { $internal eq 1 } { set timetakenbigip [expr {[clock clicks -milliseconds] - $httpreqstarttime - $timetakenserver}] HTTP::header insert X-TimeTaken-BigIP "$timetakenbigip" } }Hope that helps. If you did not ask for real-time information there is already pre-made tools to generate a report of the current configuration in the code share. 🙂
/Patrik
- Anush
Nimbostratus
Hi Patrick,
Thank you very much for your response. can you please explain me this irule little bit more? how does it work? what client needs to do on their side to get pool status info?
Thanks
Hi!
Sorry for the late reply, I've been a bit busy. 🙂
I guess the iRule did a bit more than you asked, and might seem overwhelming at first. I wrote another one, more aligned to the scope of your question.
If you create a data group list and add ie. 192.168.0.0/16 as a network for internal requests and/or your Office external IP you can show the status of any pool with this iRule.
So steps to implement it:
- Create the data group list called Office_IPs (or rename it according to your liking)
- Create iRule (see code below).
- Create a virtual server with an HTTP profile
- Assign the iRule to the virtual server
How to use it:
- Open a browser.
- Navigate to the virtual server and add a query string:
If the pool exists you'll get the answer in XML
session_disabled upOtherwise you'll get this:
The pool /Partition/Mypool-443_pool does not exist.Please note that you have to add the partition when using the pool name. If you don't use partitions and store everything in /Common you could always rewrite the rule to use /Common as default and skip the partition part.
The actual iRule:
when CLIENT_ACCEPTED { Check if the request is internal or not. Office IPs are a data group list with the IPs you want to allow. if { [class match [IP::remote_addr] equals Office_IPs] } { set internal 1 } else { set internal 0 } } when HTTP_REQUEST { if { $internal eq 1 } { Save the content of the query string into selectedpool set selectedpool [URI::query [HTTP::uri] showstatus] Check if the showstatus query parameter exists or not if { $selectedpool ne "" } { Decode the parameter into readable format set selectedpool [URI::decode $selectedpool] Check if the pool exists, otherwise reply with a message if { [catch { set mbrs [members -list $selectedpool] } ] } { The pool did not exist HTTP::respond 200 content "The pool $selectedpool does not exist." Content-Type "text/plain" Connection "Close" } else { The pool existed Prepare the xml content set xml "\n" Get the status for each member of the pool foreach mbr $mbrs { set mbrlist [split $mbr " "] set memberip [lindex $mbrlist 0] set memberport [lindex $mbrlist 1] set status [LB::status pool $selectedpool member $memberip $memberport] Append the member information into the file set xml "$xml\t$status\n" } Add the XML footer set xml "$xml" Reply with the data HTTP::respond 200 content $xml Content-Type "text/plain" Connection "Close" } } } }No, if the VIP is 1.1.1.1 the URL would be http://1.1.1.1/?showstatus=%2FPartition%2FMypool-443_pool (or https://1.1.1.1/?showstatus=%2FPartition%2FMypool-443_pool if you use an SSL client profile.
To know the status of pool /Common/abc.com you would then enter http://1.1.1.1/?showstatus=%2FCommon%2Fabc.com
Do you use partitions? Otherwise you can rewrite the iRule to be simpler.
/Patrik
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com