Ever since I first looked at Python years ago, the whitespace sensitivity kind of put me off from really using it for anything. Having made several small scripts and Django sites with Python recently though, I think that was definitely a mistake. While using whitespace instead of curly braces for structure still feels slightly strange, Python by and large has been very pleasant and straightforward to use. It feels a lot more conventional than Ruby.

The organization that I work at has a fairly large number of F5 load balancers (40+). Occasionally, we have to track down which load balancers a particular server is on. In general, this is easy, given that different load balancers serve different locations / environments. But it would be nice to have an easy way of verifying which load balancer pools / VIP’s a given server is configured on globally.

F5 has a SOAP based API for managing their devices called iControl. They also have an unofficial library for interacting with iControl in Python, bigsuds. The admittedly fairly minor need to search for a node on multiple F5’s, combined with a desire to familiarize myself with the “bigsuds” library prompted me to write some Python scripts for this.  iControl really seems pretty easy to use.  I think there’s definitely a lot of useful automation we can do with iControl in our environment, beyond little helper scripts like this.

Usage

./load_ltm_data.py <db_filename>

./search_by_node.py <db_filename> 

./search_by_vip.py <db_filename>

Once you download and extract the scripts, you’ll need to modify the ltm_list array to contain the FQDN or IP address of each of the F5’s you are wanting to scan.

ltm_list = [ "10.1.1.1", "myf5.example.com", "myf5-2.eample.com"]

When the load_ltm_data.py script is ran, it prompts for credentials, and then connects to each of the F5’s specified in the ltm_list array. By default, the admin user account is able to connect via iControl.  The root account is not.

The load_ltm_data script rebuilds the database, and stores all of the partitions / virtuals / pools / etc that it finds. The search_by scripts search the specified database and display each of the VIP’s that match, along with the related pools / etc. search_by_node.py will display all of the VIP’s that the specified node is a part of. Here is an example output from one of the search scripts:

LTM: 192.168.16.31
        VIP Name: /Common/READINGLIST-DEV
                Destination: 192.168.81.3:443
                Pool: /Common/VOYAGER-INTERNAL
                        - Member: /Common/VOYAGER-INTERNAL : 443
                                Node IP: 192.168.17.17:443
                Rules:
                        - Rule Name: /Common/READINGLIST-DEV-IRULE
                        - Rule Name: /Common/TEST2

You can search by either the full IP address, or a partial name (for instance “eading” would match the READINGLIST-DEV VIP in the output above).

Requirements

This requires Python 2.6. I don’t think the bigsuds library is compatible with Python 3.x.  It also requires SQLite 3. That works with Python out of the box on RHEL 6 based distros for me.

The F5 “bigsuds” library is available here.  After downloading and extracting that, you can run “python setup.py install” to install the module.

On the F5 side, this should work with 11.x F5’s.  Interacting with version 10 requires using different methods in bigsuds.  There’s no reason it couldn’t be modified to work with 10.x, but I don’t use 10.x devices enough myself for it to be worthwhile.

Download

I’ve created a GitHub repo for this.  You can also download a .zip file.