Forum Discussion
F5 Python SDK: How to get virtual server availability?
Due to my limited Python and SDK experience I am finding it difficult to easily obtain the availability state of a virtual server. Given a 'virtual' object, what is the best/easiest way to return the value of that VS' 'Availability' state (offline, available, unknown, etc)?
I can do the following:
my_virtual = mgmt.tm.ltm.virtuals.virtual.load(name='some_virtual')
stats = my_virtual.stats.load()
Printing the stats.raw shows that there is a nested dictionary entry keyed 'status.availibityState' that appears to hold the value I'm looking for. Forgive my inexperience, but what is the easiest way to get the availability state of a virtual using the SDK? Perhaps a method I'm missing that retrieves the value above, or the value is easily obtained elsewhere.
Appreciate any assitance!
- Hannes_RappNimbostratus
Great to see more people opting to use the SDK!
You can work with the output normally, as with any dict-type, using
. Add in a set of square-brackets, if the extracted value is yet another key-value pair, and if you're looking for a very specific match:dict.get('something')
.dict.get('something')['something']
Note: In the for-loop, I'm using
- this extraction works without use ofvirtual.name
because 'name' is a 1st-level extraction - no nesting is involved. For the same reason, I can do.get('name')
in my function, instead ofstate = stats.entries...
state = stats.get('entries')...
f5-sdk v2.2.0 ; py3.4.3 ; 11.5.4
from f5.bigip import ManagementRoot def get_vs_state(vs_name): virtual_s = API_ROOT.tm.ltm.virtuals.virtual.load(name=vs_name) stats = virtual_s.stats.load() state = stats.entries.get('status.availabilityState')['description'] return state API_ROOT = ManagementRoot("bip-01", "admin", "admin") VIRTUALS = API_ROOT.tm.ltm.virtuals.get_collection() EXAMPLE OF USE: Print AvailabilityState of all Virtual Servers for virtual in VIRTUALS: print("Name: '%s' AvailabilityState: '%s'" % (virtual.name, get_vs_state(virtual.name)))
- Ed_SummersNimbostratus
Thank you for your help and patience! Much appreciated...
Not sure if there is a difference in the data structures between our versions: F5 SDK v2.0.2 BIGIP 12.1.1 Python 3.3.2
When I run the stats.entries.get method you outlined above, I get a return of 'None'. However there is a value for status.availibilityState buried in nested dicts for stats.entries.
Here's a test I ran in interactive shell (I have a module that obtains a token and base object of 'mgmt'):
>>> virtuals = mgmt.tm.ltm.virtuals.virtual.load(name='my_virtual_name') >>> stats = virtuals.stats.load() >>> state = stats.entries.get('status.availabilityState')['description'] Traceback (most recent call last): File "", line 1, in TypeError: 'NoneType' object is not subscriptable >>> stats.entries {'https://localhost/mgmt/tm/ltm/virtual/my_virtual_name/~Common~my_virtual_name/stats': {'nestedStats': {'selfLink': 'https://localhost/mgmt/tm/ltm/virtual/my_virtual_name/~Common~my_virtual_name/stats?ver=12.1.1', 'kind': 'tm:ltm:virtual:virtualstats', 'entries': {'totRequests': {'value': 0}, 'status.statusReason': {'description': 'The virtual server is available'}, 'csMinConnDur': {'value': 0}, 'fiveMinAvgUsageRatio': {'value': 0}, 'syncookie.syncookies': {'value': 0}, 'csMeanConnDur': {'value': 0}, 'tmName': {'description': '/Common/my_virtual_name'}, 'clientside.slowKilled': {'value': 0}, 'syncookie.hwSyncookies': {'value': 0}, 'ephemeral.bitsOut': {'value': 0}, 'syncookie.rejects': {'value': 0}, 'ephemeral.curConns': {'value': 0}, 'clientside.pktsOut': {'value': 0}, 'syncookie.syncacheCurr': {'value': 0}, 'clientside.bitsIn': {'value': 0}, 'ephemeral.pktsOut': {'value': 0}, 'destination': {'description': '192.168.1.1:443'}, 'syncookieStatus': {'description': 'not-activated'}, 'syncookie.hwsyncookieInstance': {'value': 0}, 'syncookie.swsyncookieInstance': {'value': 0}, 'clientside.evictedConns': {'value': 0}, 'clientside.curConns': {'value': 0}, 'clientside.totConns': {'value': 0}, 'clientside.bitsOut': {'value': 0}, 'oneMinAvgUsageRatio': {'value': 0}, 'ephemeral.totConns': {'value': 0}, 'syncookie.accepts': {'value': 0}, 'status.availabilityState': {'description': 'available'}, 'syncookie.syncacheOver': {'value': 0}, 'syncookie.hwAccepts': {'value': 0}, 'ephemeral.bitsIn': {'value': 0}, 'status.enabledState': {'description': 'enabled'}, 'ephemeral.evictedConns': {'value': 0}, 'fiveSecAvgUsageRatio': {'value': 0}, 'clientside.maxConns': {'value': 0}, 'csMaxConnDur': {'value': 0}, 'ephemeral.pktsIn': {'value': 0}, 'ephemeral.slowKilled': {'value': 0}, 'clientside.pktsIn': {'value': 0}, 'ephemeral.maxConns': {'value': 0}, 'cmpEnabled': {'description': 'enabled'}, 'cmpEnableMode': {'description': 'all-cpus'}}}}}
I'm not sure if your version is the same, but it appears the stats are nested three levels deep, first key being a link, second 'nestedStats', then 'entries'. If I follow the entire path I do get the value:
>>> print(stats.entries.get('https://localhost/mgmt/tm/ltm/virtual/my_virtual_name/~Common~my_virtual_name/stats')['nestedStats']['entries']['status.availabilityState']['description']) available
Am I running something incorrectly or are the returned structures different between our versions? I can run through the nest like you mentioned and get the value, though the first key (formatted as a URL) throws me off as I'm not sure if there is an elegant way to reference it. I could get it by listing the keys for that level of dict but that seems kludge-y.
- Hannes_RappNimbostratus
Code was tested on BigIP 11.5.4. Will update answer for 12.1.1 in 15 min.
- Hannes_RappNimbostratus
You're right. The response structure of virtual stats is different in 12.1.1, and it's absolutely dreadful. Best I could offer now is a hack so that this insignificant part at the beginning would be cut out
, then everything will work exactly the same as in my 11.5.4 sample, but it's kind of a dirty approach.{'https://localhost/mgmt/tm/ltm/virtual/my_virtual_name/~Common~my_virtual_name/stats': {'nestedStats': {
Will look further into cleaner solutions tomorrow.
- Hannes_Rapp_162Nacreous
Great to see more people opting to use the SDK!
You can work with the output normally, as with any dict-type, using
. Add in a set of square-brackets, if the extracted value is yet another key-value pair, and if you're looking for a very specific match:dict.get('something')
.dict.get('something')['something']
Note: In the for-loop, I'm using
- this extraction works without use ofvirtual.name
because 'name' is a 1st-level extraction - no nesting is involved. For the same reason, I can do.get('name')
in my function, instead ofstate = stats.entries...
state = stats.get('entries')...
f5-sdk v2.2.0 ; py3.4.3 ; 11.5.4
from f5.bigip import ManagementRoot def get_vs_state(vs_name): virtual_s = API_ROOT.tm.ltm.virtuals.virtual.load(name=vs_name) stats = virtual_s.stats.load() state = stats.entries.get('status.availabilityState')['description'] return state API_ROOT = ManagementRoot("bip-01", "admin", "admin") VIRTUALS = API_ROOT.tm.ltm.virtuals.get_collection() EXAMPLE OF USE: Print AvailabilityState of all Virtual Servers for virtual in VIRTUALS: print("Name: '%s' AvailabilityState: '%s'" % (virtual.name, get_vs_state(virtual.name)))
- Ed_SummersNimbostratus
Thank you for your help and patience! Much appreciated...
Not sure if there is a difference in the data structures between our versions: F5 SDK v2.0.2 BIGIP 12.1.1 Python 3.3.2
When I run the stats.entries.get method you outlined above, I get a return of 'None'. However there is a value for status.availibilityState buried in nested dicts for stats.entries.
Here's a test I ran in interactive shell (I have a module that obtains a token and base object of 'mgmt'):
>>> virtuals = mgmt.tm.ltm.virtuals.virtual.load(name='my_virtual_name') >>> stats = virtuals.stats.load() >>> state = stats.entries.get('status.availabilityState')['description'] Traceback (most recent call last): File "", line 1, in TypeError: 'NoneType' object is not subscriptable >>> stats.entries {'https://localhost/mgmt/tm/ltm/virtual/my_virtual_name/~Common~my_virtual_name/stats': {'nestedStats': {'selfLink': 'https://localhost/mgmt/tm/ltm/virtual/my_virtual_name/~Common~my_virtual_name/stats?ver=12.1.1', 'kind': 'tm:ltm:virtual:virtualstats', 'entries': {'totRequests': {'value': 0}, 'status.statusReason': {'description': 'The virtual server is available'}, 'csMinConnDur': {'value': 0}, 'fiveMinAvgUsageRatio': {'value': 0}, 'syncookie.syncookies': {'value': 0}, 'csMeanConnDur': {'value': 0}, 'tmName': {'description': '/Common/my_virtual_name'}, 'clientside.slowKilled': {'value': 0}, 'syncookie.hwSyncookies': {'value': 0}, 'ephemeral.bitsOut': {'value': 0}, 'syncookie.rejects': {'value': 0}, 'ephemeral.curConns': {'value': 0}, 'clientside.pktsOut': {'value': 0}, 'syncookie.syncacheCurr': {'value': 0}, 'clientside.bitsIn': {'value': 0}, 'ephemeral.pktsOut': {'value': 0}, 'destination': {'description': '192.168.1.1:443'}, 'syncookieStatus': {'description': 'not-activated'}, 'syncookie.hwsyncookieInstance': {'value': 0}, 'syncookie.swsyncookieInstance': {'value': 0}, 'clientside.evictedConns': {'value': 0}, 'clientside.curConns': {'value': 0}, 'clientside.totConns': {'value': 0}, 'clientside.bitsOut': {'value': 0}, 'oneMinAvgUsageRatio': {'value': 0}, 'ephemeral.totConns': {'value': 0}, 'syncookie.accepts': {'value': 0}, 'status.availabilityState': {'description': 'available'}, 'syncookie.syncacheOver': {'value': 0}, 'syncookie.hwAccepts': {'value': 0}, 'ephemeral.bitsIn': {'value': 0}, 'status.enabledState': {'description': 'enabled'}, 'ephemeral.evictedConns': {'value': 0}, 'fiveSecAvgUsageRatio': {'value': 0}, 'clientside.maxConns': {'value': 0}, 'csMaxConnDur': {'value': 0}, 'ephemeral.pktsIn': {'value': 0}, 'ephemeral.slowKilled': {'value': 0}, 'clientside.pktsIn': {'value': 0}, 'ephemeral.maxConns': {'value': 0}, 'cmpEnabled': {'description': 'enabled'}, 'cmpEnableMode': {'description': 'all-cpus'}}}}}
I'm not sure if your version is the same, but it appears the stats are nested three levels deep, first key being a link, second 'nestedStats', then 'entries'. If I follow the entire path I do get the value:
>>> print(stats.entries.get('https://localhost/mgmt/tm/ltm/virtual/my_virtual_name/~Common~my_virtual_name/stats')['nestedStats']['entries']['status.availabilityState']['description']) available
Am I running something incorrectly or are the returned structures different between our versions? I can run through the nest like you mentioned and get the value, though the first key (formatted as a URL) throws me off as I'm not sure if there is an elegant way to reference it. I could get it by listing the keys for that level of dict but that seems kludge-y.
- Hannes_Rapp_162Nacreous
Code was tested on BigIP 11.5.4. Will update answer for 12.1.1 in 15 min.
- Hannes_Rapp_162Nacreous
You're right. The response structure of virtual stats is different in 12.1.1, and it's absolutely dreadful. Best I could offer now is a hack so that this insignificant part at the beginning would be cut out
, then everything will work exactly the same as in my 11.5.4 sample, but it's kind of a dirty approach.{'https://localhost/mgmt/tm/ltm/virtual/my_virtual_name/~Common~my_virtual_name/stats': {'nestedStats': {
Will look further into cleaner solutions tomorrow.
- JRahmAdmin
We'll need to clean up stats for sure, the nested stuff is not easy access. For all keys/values, you can get at them a little cleaner (note that if you supply partition as an argument, the self link with be /~Common~vip/~Common~vip/stats):
name = ‘testvip’ selflink = 'https://localhost/mgmt/tm/ltm/virtual/{0}/~Common~{0}/stats'.format(name) vip = b.tm.ltm.virtuals.virtual.load(name=name) vipstats = vip.stats.load() d = vipstats.entries.get(selflink).get('nestedStats').get('entries') for i in d: print '{0}: {1}'.format(i, d[i].get('value'))
for your specific key, given you have set the selflink above, you can get that with:
vipstats.entries.get(selflink). get('nestedStats'). get('entries'). get('status.availabilityState'). get('description')
- Wojciech_WypiorNimbostratus
This will be addressed soon, watch this issue:
https://github.com/F5Networks/f5-common-python/issues/628
- Ed_SummersNimbostratus
Thank you!
- Ed_SummersNimbostratus
I wanted to follow-up to thank you for the amazingly fast attention to this. I checked out the development branch of the SDK and was able to pound out a quick script that takes advantage of the new stats handler. Appears to be working at least in the small test case I did testing connections and availability. Thanks kindly!
- rathidNimbostratus
@ed summers can you paste the connection and availability code for virtual here and i am looking similar things for individual members as well
- DMA_95966Nimbostratus
Hi, I am still facing issue for ver 11.6.0. I am trying to get virtual server availability status .
Appreciate any assistance .
- Rob_74473Cirrus
I'm also struggling with this:
partition = 'C25' pool_name = 'temp_test' {u'https://localhost/mgmt/tm/ltm/pool/~C25~temp_test/~C25~temp_test/stats': {u'nestedStats': {u'entries': {u'activeMemberCnt': {u'value': 1}, pool = mgmt.tm.ltm.pools.pool.load(name=pool_name, partition=partition) stats = pool.stats.load() print("{}".format(pformat(stats.entries))) selflink = "https://{0}/mgmt/tm/ltm/pool/~{1}~{2}/~{1}~{2}/stats".format(bigip,partition,pool_name) slink = stats.entries.get(selflink) nested = slink.get('nestedStats') entries = nested.get('entries') activeMemberCnt = entries.get('activeMemberCnt').get('value')
Output:
Traceback (most recent call last): File "test_f5.py", line 46, in nested = slink.get('nestedStats') AttributeError: 'NoneType' object has no attribute 'get'
So, using the example above, I am not able to get the selflink, but I have created the selflink string from what's given in the raw output. I'm working against: BIG-IP 12.1.3 Build 0.0.378 Final
- Rob_74473Cirrus
Directly testing the code above:
name = 'DHCP_RELAY_255.255.255.255_VIP' selflink = 'https://{0}/mgmt/tm/ltm/virtual/{1}/~Common~{1}/stats'.format(bigip,name) vip = mgmt.tm.ltm.virtuals.virtual.load(name=name) vipstats = vip.stats.load() d = vipstats.entries.get(selflink).get('nestedStats').get('entries') for i in d: print("{0}: {1}".format(i, d[i].get('value')))
I get the same error:
Traceback (most recent call last): File "test_f5.py", line 39, in d = vipstats.entries.get(selflink).get('nestedStats').get('entries') AttributeError: 'NoneType' object has no attribute 'get'
- Rob_74473Cirrus
See answer below...
- Rob_74473Cirrus
This is brutal to work with!
partition = 'C25' pool_name = 'temp_test' pool = mgmt.tm.ltm.pools.pool.load(name=pool_name, partition=partition) stats = pool.stats.load() for item in stats.entries: params = stats.entries.get(item).get('nestedStats').get('entries') stuff = ['activeMemberCnt','curSessions','serverside.curConns','serverside.maxConns','serverside.totConns','status.enabledState','status.availabilityState'] for item in stuff: for key in ('value','description'): if key in params[item]: print("'{}': {}".format(item,params[item][key])) OUTPUT: 'activeMemberCnt': 1 'curSessions': 0 'serverside.curConns': 0 'serverside.maxConns': 0 'serverside.totConns': 0 'status.enabledState': enabled 'status.availabilityState': available
- DMA_95966Nimbostratus
Thanks a lot Rob , let me test it as well ..will update you on this..
- JRahmAdmin
Have you tried the Stats module?
>>> from f5.utils.responses.handlers import Stats >>> p = b.tm.ltm.pools.pool.load(name='testpool') >>> ps = Stats(p.stats.load()) >>> ps.stat.curSessions['value'] 0 >>> ps.stat.status_availabilityState['description'] u'offline' >>> ps.stat.status_enabledState['description'] u'enabled'
- DMA_95966Nimbostratus
Hi Jason ,
I am going to test this and update the thread shortly .
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