39 posts categorized "bigip"


iControl Perl - Getting Started

After having the BigIP's in house for a while now and spending a bit of time writing iRules, I felt like it was time to give iControl a try. My intentions were noble: Kill two birds with one stone by learning iControl and Java. Something about it keeps drawing me back to Perl though. It is hard to explain but, for me, Perl is like a sketchpad. I can scribble away at a script until I have something that works. It might not be museum-worthy but it still looks good and conveys what I'm trying to do rather nicely. I like the sigils, too.

Back when I was a kid, I was a huge comics fan and I loved to draw. One of the best books I had ever bought at the time was How To Draw Comics The Marvel Way. In it, Stan Lee and John Buscema outlined some techniques that comic illustrators commonly use and the technique that I found that worked best for me was the scribbling/scuplting technique. Instead of drawing a human form based on circles and cylinders, you'd get a basic stick figure in place and then start scribbling lightly around it until you got the form you wanted. Once your superhero's form was correct, you'd then work out the hard parts like the face or hands.

For me, I like Perl when writing scripts because you can fairly quickly "sketch" out the main outline of your program and get all the forms together, then sweat over the face and hands once you've figured out the main form of the script. Ruby and Python could do this too but, as I alluded to earlier, Perl has the sigils that syntax highlighters easily catch and Perl's "There's more than one way to do it" let's me get something in place that then invites helpful critique from the community.

iControl is useful but the Perl examples can be frustrating for someone just getting started with iControl and SOAP. Does no one run Perl scripts with warnings turned on like everyone suggests they do? Getting started with Perl, SOAP::Lite, and iControl can be a bit frustrating if you're purely going by what's documented in the SDK or on DevCentral. If you are also just getting started, here are a couple of pointers that should go in every script before you start sketching further:

After starting off each script with the shebang (I use #!/usr/bin/env perl always instead of naming a specific perl location because I'd rather install perlbrew everywhere instead of relying upon the Unix admin installed system perl), add the following:

#!/usr/bin/env perl

use Modern::Perl;
use Mozilla::CA;
#use Data::Dumper;
#use SOAP::Lite +trace => [ qw (all -transport) ];
use SOAP::Lite;
use MIME::Base64;

use iControlTypeCast;

# It's always easier if you just use Mozilla::CA
# for your certificate store
$ENV{HTTPS_CA_FILE} = Mozilla::CA::SSL_ca_file();

# Add any variable declarations like:
my $uid = "my_bigip_userid";
my $pwd = "my_bigip_password"

# Set up request's transport info
sub SOAP::Transport::HTTP::Client::get_basic_credentials {
    return "$uid" => "$pwd";

use Modern::Perl;, among other things, sets "strict" and "warnings" and automatically enables a bunch of modern Perl-ly things like letting you use features like say without havng to bother setting a bunch of use feature declarations in your script.

use Mozilla::CA; because it's the same set of CA certificates that Firefox uses. You don't need to worry about handling the self signed certificate the BigIP uses. Just set $ENV{HTTPS_CA_FILE} = Mozilla::CA::SSL_ca_file(); in your script and you're good to go.

use Data::Dumper; and use SOAP::Lite +trace => [qw (all -transport) ]; are for debugging purposes. The [qw (all -transport) ]; line will give you some helpful data that displays the SOAP request and response while stripping out some of the http portions of the request and response. Uncomment then when you want to use them.

use SOAP::Lite because you have to and use MIME::Base64 because you need to encode your Basic Auth userid and password if you want to avoid an initial reject coming from your BigIP due to the userid and password not being present in the request header.

use iControlTypeCast; is special. It is a custom perl module included with and referenced by almost every script in the SDK. The Perl docs don't state that you need it but you need it. Without it, you end up generating "Unrecognized type" errors if you execute a method that returns data referencing a type that resides outside of the type of request you are executing. For example, my requests for get_member_monitor_state()ended up generating Unrecognized Type warnings because the type returned was iControl::LocalLB/SessionStatus while the request was within iControl::LocalLB/Pool. use iControlTypeCast;needs to follow use SOAP::Lite; because SOAP::Lite is a dependency and if you use warnings; like we all are supposed to, iControlTypeCast.pm needs the following edits:

#Implement Typecast for iControl enumeration Elements
no warnings qw(redefine);
sub SOAP::Deserializer::typecast
	my ($self, $value, $name, $attrs, $children, $type) = @_;
	my $retval = undef;
        if (defined($type) && exists($urnMap->{$type}) && $urnMap->{$type} == 1)
	#if ( 1 == $urnMap->{$type} )
		$retval = $value;
	return $retval;
use warnings qw(redefine);
# End Of File

One additional note on use iControlTypeCast. Some scripts I've written that contain iControlTypeCast.pm in the same directory as the script ended up not being able to find it, especially when run from my Ubuntu box. If that happens, a quick workaround is to create a "modules" directory somewhere, copy iControlTypeCast.pm to it, and then use use lib '/path/to/your/modules'; instead of use iControlTypeCast;.

Replace the information between #Implement Typecast for iControl enumeration Elements and # End Of File with the data above, which will help with those scripts written to use warnings;.

Next Post in This Series

Next >> iControl Perl - User Accounts


Useful tmsh Command

There is an awful lot of stuff you can do in the BigIP web console but one of the things you can't seem to do is get a list of all the client IP's connected to a particular VIP. In the past, this might be something you would execute a tcpdump on and then run through the trace in wireshark but this isn't really necessary if you're just looking for a quick snapshot of currently attached IP addresses to a particular virtual server.

Luckily, as long as you have tmsh access to your BigIP, just execute the following command to generate a list of client IPs attached to a partucular VIP:

tmsh show sys connection cs-server-addr <ip_address>

This will generate a tabular list including the following:

  • The Client IP Address and Port
  • The Virtual Server IP Address and Port
  • The SelfIP (SNAT) Address and Port
  • The IP Address and Port of the Member Server the request went to
  • The tmm process processing the connection

Pretty useful thing to use for those instances where you just want to see what is currenty hitting your VIP without having to run a trace!


BigIP: Fixing MQ Read and Write 104 X('68') Errors

F5 published a Deployment Guide "Deploying the BigIP LTM with IBM WebSphere MQ", which provides a very good HowTo guide for load-balancing MQ with a BigIP and provides all the steps necessary to get up and running quickly.

I followed all these steps myself and my developers were off and running. The problems started a little later, however, when the application was unable to read messages off of the queue. Errors like the following were showing up in the MQ "client" logs:

AMQ9208: Error on receive from host 10.X.Y.Z (10.X.Y.Z).
An error occurred receiving data from 10.X.Y.Z (10.X.Y.Z) over
TCP/IP. This may be due to a communications failure.
The return code from the TCP/IP read() call was 104 (X'68'). Record these
values and tell the systems administrator.

In addition, we would see the following errors on the MQ "server" logs:

AMQ9206: Error sending data to host 10.a.b.c
An error occurred sending data over TCP/IP to 10.a.b.c
(10.a.b.c)(port#). This may be due to a communications failure.
The return code from the TCP/IP(write) call was 104 X('68'). Record these
values and tell your systems administrator.

If the BigIP VIP was bypassed, the errors on both ends of the connection would go away. No firewalls separated one mq node from another. Other than citing a "network failure", IBM support wasn't much assistance here. Initial network traces indicated that I had not followed the deployment guide recommendations verbatim, as the traces were showing keep-alive requests every 300 seconds from the MQ nodes, which also matched the 300 second tcp idle timeout on the BigIP. It was somewhat easy to assume then that the bigip was issuing a connection reset on the idle tcp connection at around the same time the mq heartbeat was getting issued but reducing the MQ Heartbeat interval to below the BigIP's TCP Idle Timeout value did not resolve the issue.

The resolution was found with the help from this F5 Solution Article: "SOL8049: Implementing TCP Keep-Alives for server-client communication using TCP profiles". Add a Keep Alive Interval to the TCP profile (or create a new tcp profile) and assign the value to half of what your tcp timeout is set to (or an even smaller value), restart the MQ channels, and these errors should go away.