Technical Articles
F5 SMEs share good practice.
cancel
Showing results for 
Search instead for 
Did you mean: 
JRahm
Community Manager
Community Manager

I got a question on how to retrieve the status of pool members on F5 DNS objects via the iControl REST interface. In the GUI you get fancy red, yellow, black, blue, and green painted circles, diamonds, squares, and triangles to communicate availability. At the command line, however, it’s harder to map that visual data. There are two important settings underlying an object’s availability: availability state and enabled state. You can see when using the field-fmt option on the tmsh command to show the pool member status that both GTM and LTM objects report the same data (the remaining fields are removed for brevity):

gtm pool pool gslb_pool_1:A {
    members {
        testvip:ltm3 {
            status.availability-state available
            status.enabled-state enabled
            status.status-reason Available
        }
    }
    status.availability-state available
    status.enabled-state enabled
    status.status-reason Available
}

ltm pool testpool {
    members {
        192.168.103.20:80 {
            status.availability-state available
            status.enabled-state enabled
            status.status-reason Pool member is available
        }
    }
    status.availability-state available
    status.enabled-state enabled
    status.status-reason The pool is available
}

Through the REST interface, both status fields are available in the LTM pool object. Calling the pool member and selecting on session and state, the following request returns the data as expected:

GET https://ltm3.test.local/mgmt/tm/ltm/pool/testpool/members/~Common~192.168.103.20:80?$select=session,state
{
    "session": "monitor-enabled",
    "state": "up"
}

However, these same status fields are not available on GTM pool/pool member REST objects. Calling a GTM pool member, the following request returns no information on monitor status (that's the availability-state field from above) but does indicate the enabled state, albeit unconventionally by changing the field name:

GET https://ltm3.test.local/mgmt/tm/gtm/pool/a/~Common~gslb_pool_1/members/~Common~ltm3:~Common~front_door
# when enabled:
{
    "name": "front_door",
    "enabled": true,
}
# when disabled:
{
    "name": "front_door",
    "disabled": true,
}

So if the information is not available directly from the REST interface, how do you get it? Well, you have options. The newest approach (and one I am currently investigating for things like this) is writing your own API via the iControl LX extensions. That's not the approach I'll take here, however. Instead, I'll use a tmsh script to return the appropriate data via a bash call from iControl REST.

The tmsh script is quite simple. It takes an argument for the type of GTM pool you wish to query, and then the pool name. It will then iterate through the members and return for each member the pool member name, its availability state, and its enabled state.

proc script::run {} {
    if { $tmsh::argc != 3 } {
      puts "A pool type and name must be provided"
      exit
    }
    set pool_type [lindex $tmsh::argv 1]
    set pool_name [lindex $tmsh::argv 2]
    foreach obj [tmsh::get_status /gtm pool $pool_type $pool_name detail] {
      foreach member [tmsh::get_field_value $obj members] {
        puts "[tmsh::get_name $member],[tmsh::get_field_value $member status.availability-state],[tmsh::get_field_value $member status.enabled-state]"
      }
    }
  }
    total-signing-status not-all-signed
}

Running the script from bash on the BIG-IP, I get the following results:

[root@ltm3:Active:Standalone] tmp # tmsh run cli script pool-status.tcl a gslb_pool_1
front_door:ltm3,available,disabled
testvip:ltm3,available,enabled
testvip2:ltm3,available,enabled

And finally, calling this with the F5 python SDK returns the same results:

>>> from f5.bigip import ManagementRoot
>>> mgmt = ManagementRoot('ltm3.test.local', 'admin', 'admin', token=True)
>>> ps = mgmt.tm.util.bash.exec_cmd('run', utilCmdArgs='-c "tmsh run cli script pool-status.tcl a gslb_pool_1"')
>>> ps.commandResult
u'front_door:ltm3,available,disabled\ntestvip:ltm3,available,enabled\ntestvip2:ltm3,available,enabled\n'

You can of course modify the tmsh script to return the data in a different format, I opted for quick and dirty here to model the problem and solution. Thanks go to community member Aaron Murray for the question and the inspiration, happy coding out there!

Comments
IRONMAN
Cirrostratus
Cirrostratus

Thanks, Now i can add this feature to my API Kit, to do some features in tmsh & Bash apart from Rest calls.

 

John_Allen
Altostratus
Altostratus

Is there a way to SET the state of a BIG-IP DNS Pool? In my downstream LTMs, I can intercept error conditions for nodes using an iRule, and if the local Pool has no other members up, I want to signal the BIG-IP DNS that the service is down right away, so I can respond to the client to re-query DNS and pick up another data center. The problem I have is that if I have to wait for all the Health Checks to timeout (both locally on the LTM, and then up on the DNS), the BIG-IP DNS could re-pick the data center with the down service in the meantime, and cause my request to loop.

 

JRahm
Community Manager
Community Manager

Hi John, you can use bash to run tmsh commands, so state is indeed possible by using tmsh modify on the pool member:

 tmsh show gtm pool a gslb_pool_1 members | grep State
  State        : enabled
  |   State        : enabled
 tmsh modify gtm pool a gslb_pool_1 members modify { ltm3:/Common/testvip { disabled }}
 tmsh show gtm pool a gslb_pool_1 members | grep State
  State        : enabled
  |   State        : disabled
Vincent_95972
Nimbostratus
Nimbostratus

I can't seem to get that JSON data from your instructions above.

 

I get the expected results from running the script from bash on the BIG-IP:

 

[me@BIGIPDNS1:Active:Standalone] ~ tmsh run cli script BIGIPDNSpoolmemberstatus.tcl a MY_POOL VIRTUAL_SERVER_1_443:LTMSFRML1ab,available,enabled VIRTUAL_SERVER_2_443:LTMSFRML1ab,available,enabled

 

However, calling it from a Python file that I created didn't give me the JSON results like what you were able to demonstrate above. Below is my code in my Python file:

 

 

mgmt = ManagementRoot( mydevice, myuser, mypassword) ps = mgmt.tm.util.bash.exec_cmd('run', utilCmdArgs='-c "tmsh run cli script BIGIPDNSpoolmemberstatus.tcl a MY_POOL"')

 

ps.commandResult

 

No errors are shown when executing the above but I am unable to print the JSON data. For example, it would result in an error if I do a "print ps.commandResult". The errors I always get say that "The requested shell script (/Common/BIGIPDNSpoolmemberstatus.tcl) was not found". Again, I am able to run this TMSH script from the BIG-IP in success.

 

Not sure what I am missing or doing wrong.

 

JRahm
Community Manager
Community Manager

are partitions enabled on your device? Try updating your call from REST with the partition on the object.

 

Vincent_95972
Nimbostratus
Nimbostratus

Thank you for your prompt response. Here's an update for you. I was able to successfully post it and get the results (i.e.\commandResult) in Postman using the following:

 

POST:

 

Body: { "command":"run", "utilCmdArgs":"-c 'tmsh run cli script BIGIPDNSpoolmemberstatus.tcl a MY_POOL'" }

 

So... I'm now just trying to translate that into my Python code. I'm quite new to the F5 SDK as I just started working on it this week so I'm not sure how to get that written into my Python code. What you provided above makes sense but I'm not sure what else is missing or in question in my Python code?

 

I think it's safe to rule out partitions given that I'm now able to get the expected results from a different means (being Postman).

 

JRahm
Community Manager
Community Manager

running same user permissions from postman, tmsh, and python? if it's not seeing the script, that seems like either a partition or permission problem, but I'm not sure where the issue is based on your feedback.

 

Vincent_95972
Nimbostratus
Nimbostratus

I see. I did use my user account when following the instructions you provided for creating the tcl file above and testing the results. Running the APIs in all cases were done using the admin account. Looking into it now to see if that may be the underlying issue.

 

JRahm
Community Manager
Community Manager

If you have a remote authentication configured on BIG-IP, you could try adding token=True as a kwarg to your ManagementRoot call to see if that fixes things.

 

Vincent_95972
Nimbostratus
Nimbostratus

Created the TCL file and tested it in BASH using the admin account. I'm still unable to get that JSON data when running my Python code. I'm getting 400 code errors now. Will look into adding token=True.

 

Vincent_95972
Nimbostratus
Nimbostratus

Everything is good now. The instructions that you have provided above works for me.

 

BTW, one can able to get the BIG-IP DNS pool member status by entering, for example, the following:

 

Our BIG-IP DNS is running on Version 12.1.2.

 

Thank you for your help.

 

prt1969
Nimbostratus
Nimbostratus

So with the stats command above, there should be a way to filter the output with a ?$select= . Something that would just give back status.availabilityState, status.statusReason, poolName, and serverName? I have tried a few iterations with no luck.

 

Stephen_Briggs
F5 Employee
F5 Employee

The equivalent of show gtm pool is available if /stats is appended to the REST query:

 

curl -skL --tlsv1 -u admin:admin -X GET https://10.10.10.1/mgmt/tm/gtm/pool/a/testpool/stats | jq .

{

"kind": "tm:gtm:pool:a:astats",

"generation": 195,

"selfLink": "https://localhost/mgmt/tm/gtm/pool/a/testpool/stats?ver=12.1.4.1",

"entries": {

"https://localhost/mgmt/tm/gtm/pool/a/testpool/~Common~testpool:A/stats": {

"nestedStats": {

"kind": "tm:gtm:pool:a:astats",

"selfLink": "https://localhost/mgmt/tm/gtm/pool/a/testpool/~Common~testpool:A/stats?ver=12.1.4.1",

"entries": {

"alternate": {

"value": 0

},

"dropped": {

"value": 0

},

"fallback": {

"value": 0

},

"tmName": {

"description": "/Common/testpool"

},

"poolType": {

"description": "A"

},

"preferred": {

"value": 0

},

"returnFromDns": {

"value": 0

},

"returnToDns": {

"value": 0

},

"status.availabilityState": {

"description": "offline"

},

"status.enabledState": {

"description": "enabled"

},

"status.statusReason": {

"description": "No enabled pool members available"

}

}

}

}

}

}

 

Version history
Last update:
‎27-Dec-2017 07:56
Updated by:
Contributors