Perl Management Folder

Problem this snippet solves:

This example illustrates how to use the Folder methods to build a console shell allowing you to navigate and manage system Folders on BIG-IP v11 and above.

Code :

#!/usr/bin/perl
#----------------------------------------------------------------------------
# The contents of this file are subject to the "END USER LICENSE AGREEMENT 
# FOR F5 Software Development Kit for iControl"; you may not use this file 
# except in compliance with the License. The License is included in the 
# iControl Software Development Kit.
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is iControl Code and related documentation
# distributed by F5.
#
# The Initial Developer of the Original Code is F5 Networks,
# Inc. Seattle, WA, USA. Portions created by F5 are Copyright (C) 1996-2015 
# F5 Networks, Inc. All Rights Reserved.  iControl (TM) is a registered 
# trademark of F5 Networks, Inc.
#
# Alternatively, the contents of this file may be used under the terms
# of the GNU General Public License (the "GPL"), in which case the
# provisions of GPL are applicable instead of those above.  If you wish
# to allow use of your version of this file only under the terms of the
# GPL and not to allow others to use your version of this file under the
# License, indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by the GPL.
# If you do not delete the provisions above, a recipient may use your
# version of this file under either the License or the GPL.
#----------------------------------------------------------------------------

#use SOAP::Lite + trace => qw(method debug);
use SOAP::Lite;
use Switch;
use File::Basename;

$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;

my $sHost = $ARGV[0];
my $sUID = $ARGV[1];
my $sPWD = $ARGV[2];

my $DEBUG = 0;
my $FOLDER = null;
my $RECURSE = null;


#----------------------------------------------------------------------------
# sub usage
#----------------------------------------------------------------------------
sub usage() {
print "Usage: ManagementFolder.pl host uid pwd\n";
exit;
}

if ( ($sHost eq "") or ($sUID eq "") or ($sPWD eq "") )
{
  usage();
}

#----------------------------------------------------------------------------
# iControl interface initialization
#----------------------------------------------------------------------------
sub SOAP::Transport::HTTP::Client::get_basic_credentials
{
  return "$sUID" => "$sPWD";
}

$Folder = SOAP::Lite
  -> uri('urn:iControl:Management/Folder')
  -> readable(1)
  -> proxy("https://$sHost/iControl/iControlPortal.cgi");
eval { $Folder->transport->http_request->header
(
  'Authorization' =>
  'Basic ' . MIME::Base64::encode("$sUID:$sPWD", '')
); };

$Session = SOAP::Lite
  -> uri('urn:iControl:System/Session')
  -> readable(1)
  -> proxy("https://$sHost/iControl/iControlPortal.cgi");

eval { $Session->transport->http_request->header
(
  'Authorization' =>
  'Basic ' . MIME::Base64::encode("$sUID:$sPWD", '')
); };

sub SOAP::Deserializer::typecast
{
  my ($self, $value, $name, $attrs, $children, $type) = @_;
  my $retval = undef;
  if ( $type eq "{urn:iControl}Common.EnabledState" )
  { $retval = $value; }
  elsif ( $type eq "{urn:iControl}LocalLB.LBMethod" )
  { $retval = $value; }
  elsif ( $type eq "{urn:iControl}LocalLB.MonitorStatus" )
  { $retval = $value; }
  elsif ( $type eq "{urn:iControl}LocalLB.AvailabilityStatus" )
  { $retval = $value; }
  elsif ( $type eq "{urn:iControl}LocalLB.EnabledStatus" )
  { $retval = $value; }
  elsif ( $type eq "{urn:iControl}LocalLB.ProfileType" )
  { $retval = $value; }
  elsif ( $type eq "{urn:iControl}LocalLB.ProfileContextType" )
  { $retval = $value; }
  return $retval;
}


#----------------------------------------------------------------------------
# sub debugMessage
#----------------------------------------------------------------------------
sub debugMessage() {
my ($msg) = (@_);
if ( $DEBUG && $msg ) {
print "${msg}\n";
}
}

#----------------------------------------------------------------------------
# sub getCurrentFolder
#----------------------------------------------------------------------------
sub getCurrentFolder() {
my ($force) = (@_);
$folder = $FOLDER;

if ( ($FOLDER == null) || $force ) {
$soapResponse = $Session->get_active_folder();
&checkResponse($soapResponse);
$folder =  $soapResponse->result;
}
return $folder;
}

#----------------------------------------------------------------------------
# sub getChildFolders
#----------------------------------------------------------------------------
sub getChildFolders() {
my ($recurse, $long) = (@_);

&debugMessage("RECURSE: ${recurse}");
&debugMessage("LONG: ${long}");

#if ( null == $recurse ) { $recurse = 0; }
#if ( null == $long ) { $long = 1; }

if ( $recurse ) {
$soapResponse = $Session->get_recursive_query_state();
&checkResponse($soapResponse);
$oldstate = $soapResponse->result;
$soapResponse = $Session->set_recursive_query_state(
SOAP::Data->name(state => "STATE_ENABLED")
);
&checkResponse($soapResponse);
}
$soapResponse = $Folder->get_list();
&checkResponse($soapResponse);
@folders_unsorted = @{$soapResponse->result};
@folders = sort @folders_unsorted;



if ( $recurse && ($oldstate ne "STATE_ENABLED") ) {
$soapResponse = $Session->set_recursive_query_state(
SOAP::Data->name(state => $oldstate)
);
&checkResponse($soapResponse);
}

$soapResponse = $Folder->get_description(
SOAP::Data->name(folders => [@folders])
);
&checkResponse($soapResponse);
@descriptions = @{$soapResponse->result};

$soapResponse = $Folder->get_device_group(
SOAP::Data->name(folders => [@folders])
);
&checkResponse($soapResponse);
@groups = @{$soapResponse->result};

$curfolder = &getCurrentFolder();
if ( $curfolder eq "/" ) { $curfolder = "ZZZZZZZZZ"; }

if ( $long ) {
printf "%-20s %-20s %-20s\n", "Folder", "Description", "Group";
printf "-------------------- -------------------- --------------------\n";
} else {
printf "Description\n";
printf "--------------------\n";
}

for $i (0 .. $#folders) {
$f = $folders[$i];
$f =~ s/$curfolder//g;
if ( $long ) {
printf "%-20s %-20s %-20s\n", $f, &trimString(@descriptions[$i]), &trimString(@groups[$i]);
} else {
printf "%s\n", &trimString($f);
}
}
}

#----------------------------------------------------------------------------
# sub changeFolder
#----------------------------------------------------------------------------
sub changeFolder() {
my ($folder) = (@_);

&debugMessage("Setting active folder to $folder");

if ( $folder eq ".." ) {
moveUp();
} else {
$soapResponse = $Session->set_active_folder(
SOAP::Data->name(folder => $folder)
);
&checkResponse($soapResponse);
}
$f = &getCurrentFolder(true);

return $f;
}

#----------------------------------------------------------------------------
# sub moveUp
#----------------------------------------------------------------------------
sub moveUp() {
$folder = getCurrentFolder();
@tokens = fileparse($folder);
$f = $tokens[0];
$parent = $tokens[1];

if ( $parent ne "" ) {
&debugMessage("Setting active folder to ${parent}");

$soapResponse = $Session->set_active_folder(
SOAP::Data->name(folder => $parent)
);
&checkResponse($soapResponse);
}
$f = &getCurrentFolder(true);
return $f;
}

#----------------------------------------------------------------------------
# sub createFolder
#----------------------------------------------------------------------------
sub createFolder() {
my ($folder) = (@_);

$folder = trimString($folder);

&debugMessage("Creating folder ${folder}\n");

$soapResponse = $Folder->create(
SOAP::Data->name(folders => [$folder])
);
&checkResponse($soapResponse);
print "Folder $folder successfully created\n";
}

#----------------------------------------------------------------------------
# sub removeFolder
#----------------------------------------------------------------------------
sub removeFolder() {
my ($folder) = (@_);

&debugMessage("Removing folder ${folder}\n");

$soapResponse = $Folder->delete_folder(
SOAP::Data->name(folders => [$folder])
);
&checkResponse($soapResponse);
print "Folder $folder successfully removed\n";
}

#----------------------------------------------------------------------------
# sub setFolderDescription
#----------------------------------------------------------------------------
sub setFolderDescription() {
my ($cmd) = (@_);

&debugMessage("setFolderDescription: ${cmd}");

my @tokens = split(/ /, $cmd);
if ( $#tokens == 1 ) {
$f = $cmd;
$d = "";

&debugMessage("Setting folder ${folder} description to ${d}");

$soapResponse = $Folder->set_description(
SOAP::Data->name(folders => [$f]),
SOAP::Data->name(descriptions => [$d])
);
&checkResponse($soapResponse);
} elsif ( $#tokens > 1 ) {
$f = @tokens[0];
$d = @tokens[1];

for $i (2 .. $#tokens ) {
$tok = @tokens[$i];
$d = "${d} ${tok}";
}

$d =~ s/^"|"$//g;

&debugMessage("Setting folder ${f} description to '${d}'");
$soapResponse = $Folder->set_description(
SOAP::Data->name(folders => [$f]),
SOAP::Data->name(descriptions => [$d])
);
&checkResponse($soapResponse);
} else {
showHelp();
}
}

#----------------------------------------------------------------------------
# sub getFolderDescription
#----------------------------------------------------------------------------
sub getFolderDescription() {
my ($folder) = (@_);

&debugMessage("Retrieving folder description for ${folder}");

$soapResponse = $Folder->get_description(
SOAP::Data->name(folders => [$folder])
);
&checkResponse($soapResponse);
@descriptions = @{$soapResponse->result};
$desc =  @descriptions[0];
print "${folder} -> ${desc}\n";
}

#----------------------------------------------------------------------------
# sub getRecursiveState
#----------------------------------------------------------------------------
sub getRecursiveState() {
$soapResponse = $Session->get_recursive_query_state();
&checkResponse($soapResponse);
$oldState = $soapResponse->result;
$RECURSE = $oldState;
return $oldState;

}

#----------------------------------------------------------------------------
# sub setRecursiveState
#----------------------------------------------------------------------------
sub setRecursiveState() {
my ($state) = (@_);

$newState = "STATE_DISABLED";
if ( $state ) {
$oldState = &getRecursiveState();
if ( $oldState eq "STATE_DISABLED" ) {
$newState = "STATE_ENABLED";
}
} else {
$lcstate = lc $state;
if ( index($lcstate, "enable") != -1 ) {
$newState = "STATE_ENABLED";
}
}

$RECURSE = $newState;
$soapResponse = $Session->set_recursive_query_state(
SOAP::Data->name(state => $newState)
);
&checkResponse($soapResponse);
print "Recursive State set to $newState\n";
}

#----------------------------------------------------------------------------
# sub showHelp
#----------------------------------------------------------------------------
sub showHelp() {
my $indent = "     ";

my $HELPTEXT = << "ENDTEXT";

$indent ====================================================================
$indent                       iControl Folder Shell
$indent ====================================================================
 
$indent Commands
$indent --------
$indent cd folder        - change active folder
$indent d                - toggle script debugging
$indent dir,ls           - List child folders
$indent gd folder        - Get folder description
$indent h                - Show this help
$indent ls -l            - List child folders and their properties
$indent ls -r            - List recursive listing of child folders
$indent ls -lr           - List recursive listing of child folders
$indent                      and their properties
$indent md,mkdir         - create folder
$indent pwd              - Get current folder
$indent r enable|disable - Set the recursive state.  Omitting a 
$indent                      state value will toggle it.
$indent rd,rmdir         - remove folder
$indent sd folder desc   - Set folder description
$indent q                - quit the shell
$indent ..               - Move to parent folder

ENDTEXT

print $HELPTEXT;
}

#----------------------------------------------------------------------------
# sub getArgs
#----------------------------------------------------------------------------
sub getArgs() {
my ($cmd) = (@_);

my @tokens = split(/ /, $cmd);
$cmd = @tokens[0];
$args = @tokens[1];
for $i (2 .. $#tokens) {
$newtok = @tokens[$i];
$args = "${args} ${newtok}";
}
return $args;
}

#----------------------------------------------------------------------------
# sub trimString
#----------------------------------------------------------------------------
sub trimString() {
my ($s) = (@_);

$s =~ s/^\s+|\s+$//g;
return $s;
}

#----------------------------------------------------------------------------
# sub ProcessInput
#----------------------------------------------------------------------------
sub processInput() {
my ($i) = (@_);

&debugMessage("Processing input for ${i}");

$i = &trimString($i);

switch(lc($i)) {
case /cd */ { 
&changeFolder(&getArgs($i)); 
}
case "cd" {
&getCurrentFolder();
 }
case "d" {
$DEBUG = ! $DEBUG;
}
case "dir" {
&getChildFolders();
}
case /gd */ {
&getFolderDescription(&getArgs($i));
}
case "h" {
&showHelp();
}
case "ls" {
&getChildFolders(0, 0);
}
case "ls -l" {
&getChildFolders(0, 1);
}
case "ls -lr" {
&getChildFolders(1, 1);
}
case "ls -r" {
&getChildFolders(1, 0);
}
case /md\s */ {
&createFolder(&getArgs($i));
}
case /mkdir */ {
&createFolder(&getArgs($i));
}
case "pwd" {
$f = &getCurrentFolder();
print "Current Folder: $f\n";
}
case "r" {
&setRecursiveState();
}
case /r\s */ {
&setRecursiveState(&getArgs($i));
}
case /rd */ {
&removeFolder(&getArgs($i));
}
case /rmdir */ {
&removeFolder(&getArgs($i));
}
case /sd */ {
&setFolderDescription(&getArgs($i));
}
case "q" {
exit;
}
case ".." {
moveUp();
}
else {
showHelp();
}
}
}

#----------------------------------------------------------------------------
# sub getPrompt
#----------------------------------------------------------------------------
sub getPrompt() {
$prefix = "";
if ( $DEBUG or ($RECURSE eq "STATE_ENABLED") ) {
$prefix = "(";
if ( $DEBUG ) {
$prefix = "${prefix}d";
}
if ( $RECURSE eq "STATE_ENABLED" ) {
if ( $prefix ne "(" ) { $prefix = "${prefix},"; }
$prefix = "${prefix}r";
}
$prefix = "${prefix})";
}
$folder = &getCurrentFolder();
return "[${prefix}${folder}] ";
}

#----------------------------------------------------------------------------
# sub checkResponse
#----------------------------------------------------------------------------
sub checkResponse()
{
  my ($soapResponse) = (@_);
  if ( $soapResponse->fault )
  {
    print $soapResponse->faultcode, " ", $soapResponse->faultstring, "\n";
    exit();
  }
}

#============================================================================
# Main application logic
#============================================================================
while(1) {
my $prompt = getPrompt();
print $prompt;
my $i = ;
&processInput($i);
}

Tested this on version:

11.0
Published May 29, 2015
Version 1.0
  • Very good. Thank you. On 12.x had to replace the

    use Switch
    by
    use feature "switch";
    and then adapt all "
    switch ... case ... else
    " by "
    given ... when () ... default
    "

  • Hi Joe,

     

    Thanks for the code. Here, you use a session and a folder objects to navigate. Great.

     

    But how to change folder when doing operations on other objects like pools, nodes, virutals, … ?

     

    Thank you, Best Olivier