f5 python sdk
2 TopicsUsing the Python SDK with the Flask Web Framework
I received from a member of our fine community on how to make the Python SDK work with the Django web framework. I haven't worked with Django, but I do work with the Flask web framework, which is very bare bones compared to Django, but has a rich extension ecosystem. In this short screencast, I demonstrate a very simple web application that allows you to connect to a BIG-IP, view the pools and pool members configured, and add, modify, and view iRules. Note: this app is for demonstrating how to use the SDK in a web framework only. It does not implement any security features for protecting the traffic in transit or managing the BIG-IP user credentials. Clone the project to explore and learn how the SDK or Flask works, but please DO NOT implement this as is in a production environment.512Views0likes0CommentsDebugging API calls with the python sdk
In version 3.0.10 of the iControl REST python SDK, we introduced a new feature that allows you to debug the API call tracing. In this article, I’ll show you how to use it to debug an issue with pool members. Consider the following existing pool on my BIG-IP: ltm pool testpool { members { 192.168.103.20:http { address 192.168.103.20 session monitor-enabled state up } } monitor http } You can see that there is a single pool member in this pool, 192.168.103.20:80. So when I check from the SDK to see if the pool and pool member exist, I expect the answer to be true on both counts. >>> mgmt.tm.ltm.pools.pool.exists(name='testpool') True >>> pool = mgmt.tm.ltm.pools.pool.load(name='testpool') >>> pool.members_s.members.exists(name='192.168.103.20:80') False Both should be true, but the pool member exists check is returning false. This is where we can engage the debug data to see what is going on with the requests.You can set the debug attribute to true when you instantiate BIG-IP, or enable it only when you need it. >>> mgmt = ManagementRoot('ltm3.test.local', 'admin', 'admin', debug=True) # set on instantiation >>> mgmt.debug = True # turn on after instantiation >>> mgmt.debug = False # turn off Once you enable the debug attribute, the debug_output attribute will begin appending to a list the API calls made to the BIG-IP, in the format of the curl command. Note that the API is not using curl, but the debug output is formatted this way to allow you to grab the command and run it directly from the command line. For the instantiation, pool exists check, loading the pool, and then the pool member exists check, this debug output looks like this: >>> for x in mgmt.debug_output: ... print x ... curl -k -X GET https://ltm3.test.local:443/mgmt/tm/sys/ -H 'Connection: keep-alive' -H 'Accept-Encoding: gzip, deflate' -H 'Accept: */*' -H 'User-Agent: python-requests/2.18.4 f5-icontrol-rest-python/1.3.8' -H 'Content-Type: application/json' -H 'Authorization: Basic YWRtaW46YWRtaW4=' curl -k -X GET https://ltm3.test.local:443/mgmt/tm/ltm/pool/testpool -H 'Connection: keep-alive' -H 'Accept-Encoding: gzip, deflate' -H 'Accept: */*' -H 'User-Agent: python-requests/2.18.4 f5-icontrol-rest-python/1.3.8' -H 'Content-Type: application/json' -H 'Cookie: BIGIPAuthUsernameCookie=admin; BIGIPAuthCookie=3CF752E8B6DC27B20D42B9C2BBF152B10B400407' -H 'Authorization: Basic YWRtaW46YWRtaW4=' curl -k -X GET https://ltm3.test.local:443/mgmt/tm/ltm/pool/testpool -H 'Connection: keep-alive' -H 'Accept-Encoding: gzip, deflate' -H 'Accept: */*' -H 'User-Agent: python-requests/2.18.4 f5-icontrol-rest-python/1.3.8' -H 'Content-Type: application/json' -H 'Cookie: BIGIPAuthUsernameCookie=admin; BIGIPAuthCookie=3CF752E8B6DC27B20D42B9C2BBF152B10B400407' -H 'Authorization: Basic YWRtaW46YWRtaW4=' curl -k -X GET https://ltm3.test.local:443/mgmt/tm/ltm/pool/testpool/members/192.168.103.20:80 -H 'Connection: keep-alive' -H 'Accept-Encoding: gzip, deflate' -H 'Accept: */*' -H 'User-Agent: python-requests/2.18.4 f5-icontrol-rest-python/1.3.8' -H 'Content-Type: application/json' -H 'Cookie: BIGIPAuthUsernameCookie=admin; BIGIPAuthCookie=3CF752E8B6DC27B20D42B9C2BBF152B10B400407' -H 'Authorization: Basic YWRtaW46YWRtaW4=' After running the pool member curl command I get this response: {"code":404,"message":"Object not found - 192.168.103.20:80","errorStack":[],"apiError":1} Now we know why the SDK returned false, but we know this pool member exists, so what gives? If we back off and just make an API call via curl to the members collection, we can investigate the response data for clues. {"kind":"tm:ltm:pool:members:memberscollectionstate","selfLink":"https://localhost/mgmt/tm/ltm/pool/testpool/members?ver=13.1.0.5","items":[{"kind":"tm:ltm:pool:members:membersstate","name":"192.168.103.20:80","partition":"Common","fullPath":"/Common/192.168.103.20:80","generation":175,"selfLink":"https://localhost/mgmt/tm/ltm/pool/testpool/members/~Common~192.168.103.20:80?ver=13.1.0.5","address":"192.168.103.20","connectionLimit":0,"dynamicRatio":1,"ephemeral":"false","fqdn":{"autopopulate":"disabled"},"inheritProfile":"enabled","logging":"disabled","monitor":"default","priorityGroup":0,"rateLimit":"disabled","ratio":1,"session":"monitor-enabled","state":"up"}]} Notice in the selfLink field there, the pool member has the partition as part of the name of the pool member. If we update our curl command to include the partition (changing 192.168.103.20:80 to ~Common~192.168.103.20:80,) let's see if that fixes our 404 error: {"kind":"tm:ltm:pool:members:membersstate","name":"192.168.103.20:80","partition":"Common","fullPath":"/Common/192.168.103.20:80","generation":175,"selfLink":"https://localhost/mgmt/tm/ltm/pool/testpool/members/~Common~192.168.103.20:80?ver=13.1.0.5","address":"192.168.103.20","connectionLimit":0,"dynamicRatio":1,"ephemeral":"false","fqdn":{"autopopulate":"disabled"},"inheritProfile":"enabled","logging":"disabled","monitor":"default","priorityGroup":0,"rateLimit":"disabled","ratio":1,"session":"monitor-enabled","state":"up"} Woot! Now we are getting the pool member data. It turns out that the pool member call requires the partition to be submitted, even if you do not use partitions on your BIG-IP. So now, if we update our python code to include the partition parameter, it should now return true, and sure enough, that is what we get: pool.members_s.members.exists(name='192.168.103.20:80', partition='Common') True The debug tracing details are documented in the SDK documentation linked at the top of this article, happy coding!634Views0likes1Comment