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