There’s a plethora (yes, a plethora.  The Three Amigos taught me well.) of quality information constantly flowing here at DevCentral.  And whereas I might not have El Guapo’s superior intellect, I do have enough smarts to lean on my many peers in this community that have performed some serious heavy lifting when it comes to iRules and iControl.  iRules and iControl live in separate planes, and rightfully so.  iRules work on the live data between client and server, and iControl works on the management plane out of band to collect information or to modify or create configuration objects.  However, what if you could combine forces, wholly contained on your BIG-IP LTM?  That’s the scenario I hope to tackle.  In this first part, I’ll take a look at a few different tech tips that highlight components I’ll use in the final solution.

Laying the Foundation

I’m going to need a mechanism to get user input from an HTTP request to a listener that can act on that request.  The pieces are already in place for messages to be logged, utilizing the log command in iRules to send data to syslog.  But how do I extract that information real-time?  Beginning in version 10, python began shipping with BIG-IP LTM.  A simple socket listening for syslog messages would work, wouldn’t it?  Why yes, it would.  The workflow for the provisioning process within the BIG-IP is shown below.

image

Preparing Syslog

So the first step in this project is to visit MVP smp’s tech tip on custom syslog files.  The rotation can be worked out later, but for functionality, this should get me where I want to go:

Custom Syslog Configuration

 

tmsh modify sys syslog include '"
filter f_local0 {
    facility(local0) and not match(\": #prov\");
};
 
filter f_local0_customlog {
    facility(local0) and match(\": #prov\");
};
 
destination d_provlog {
    file(\"/var/log/provlog\" create_dirs(yes));
    udp(\"127.0.0.20\" port (514));
};
 
log {
    source(local);
    filter(f_local0_customlog);
    destination(d_provlog);
};
"'

tmsh save / sys config
tmsh restart sys service syslog-ng

 

I don’t want the listener to be overwhelmed with messages, so by splitting off the messages beginning with “#prov#, I’ll make sure that I only see the provisioning messages on my socket.  For a destination, I’m using a local log file for auditing, and a loopback address for my socket to listen on. 

Preparing the Socket

The python code to create this listener is actually pretty simple, as gleaned here from the python wiki:

Python Syslog Socket

 

#!/usr/bin/python 
from socket import * 

addr = ("127.0.0.20",514) 

syslog_socket = socket(AF_INET,SOCK_DGRAM) 
syslog_socket.bind(addr) 

# Receive messages 
while True: 
    data,addr = syslog_socket.recvfrom(1024) 
    print "\nReceived message '", data,"'" 

syslog_socket.close()

 

So now that I have syslog sending messages arriving with “#prov” to a destination of 127.0.0.20:514(udp) and I have a socket listening on said destination, I should in theory have a working path.  For now, I’ll just use a simple iRule to generate the log entry to test the path:

Simple Path Testing iRule

 

when HTTP_REQUEST {
  if { [HTTP::uri] equals "/provision" } {
    log local0. "#prov Virtual is [IP::local_addr]."
  }
}

So after firing up the browser and grabbing http://10.10.20.50/provision, my socket appears to be working just fine:

[root@golgotha:Active] tmp # python ltm_prov.py

Received message ' <134>Oct  1 12:45:45 tmm tmm[5114]: Rule ltmprov-rule <HTTP_REQUEST>: #prov Virtual is 10.10.20.50

Good stuff!  Now, printing the information to the console is pretty boring, and frankly, the data has already been sent to a local file.  So what might I be able to do with that data?  What if I wanted to send some pool member information in and do something with that?  I’d probably need iControl, right?  Well, I’m already using python for the socket, so why not use it for pyControl as well?  But, you say, pyControl is not available on the BIG-IP LTM.  This is true, but a while back I wrote a tech tip on installing pyControl on BIG-IP LTM, so that’s the next archive I’ll visit.

Preparing the BIG-IP for pyControl

The first thing I need to do is remount my /usr file system as read-write.  Looking at my /etc/mtab file, I see that my /usr is on /dev/bg-db-sda, so I need to remount with this command:

[root@golgotha:Active] tmp # mount -o remount,rw /dev/bg-db-sda /usr

Now I can upload my packages and build pyControl.  Python version on BIG-IP is 2.4, so I’ll use the 2.4 setuptools egg.

C:\downloads>pscp setuptools-0.6c11-py2.4.egg root@10.10.20.5:/var/tmp/
C:\downloads>pscp python-suds-0.4.tar.gz root@10.10.20.5:/var/tmp/
C:\downloads>pscp pycontrol-2.0.1_b83.tar.gz root@10.10.20.5:/var/tmp/
[root@golgotha:Active] tmp # sh setuptools-0.6c11-py2.4.egg
[root@golgotha:Active] tmp # tar xvfz python-suds-0.4.tar.gz
[root@golgotha:Active] tmp # cd python-suds-0.4
[root@golgotha:Active] python-suds-0.4 # python setup.py install
[root@golgotha:Active] python-suds-0.4 # cd ..
[root@golgotha:Active] tmp # tar xvfz pycontrol-2.0.1_b83.tar.gz
[root@golgotha:Active] tmp # cd trunk
[root@golgotha:Active] trunk # python setup.py install

And just to make sure pyControl is working as expected, I enter the python shell and initialize the BIG-IP LTM:

[root@golgotha:Active] tmp # python
Python 2.4.3 (#1, Apr  8 2010, 19:04:08)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pycontrol.pycontrol as pc
>>> b = pc.BIGIP(hostname="localhost", username="admin", password="admin", fromurl = True, wsdls=['LocalLB.Pool'])
>>> p = b.LocalLB.Pool
>>> p.get_list()
[andrew-pool, att_rtr, cacti-pool, canada, dnsserver, erac_pool, jacob-pool, mexico, northamerica, uPool, usa, testco-pool]

Next Week

Now that the bones are in place, next week I’ll focus on building the iRule necessary to pass data through to the listener.  I’ll be using code from George’s excellent HTTP Basic Authentication article as I wouldn’t want to allow provisioning on the box without some authentication in place.