The ConfigSync sample application demonstrates usage of the ITCMSystem::ConfigSync Web Services. It serves as an example on how to work with the controllers configuration. For example, one could use the ConfigSync interface to retrieve a configuration file list, roll up and save a specified configuration, install a configuration on a device, synchronize configuration setups, roll back a configuration, and upload or download a configuration.


 

Language: Perl

 

 

 

Contents

Introduction

SDK Components Referenced

Code Sections

  Debug Settings

  Establishing the connection

  Generating a default configuration name

  Listing available configurations

  Deleting a given configuration

  Saving the current configuration

  Installing a given configuration

  Rolling back to the previous configuration state

  Downloading a given configuration

  Uploading a configuration

  Synchronizing configuration for HA systems

  Performing a full backup to the client machine

  Performing a full restore from the client machine

Related Links


 





Introduction top

 

Basic configuration management is an import feature for disaster recovery. F5's controllers provide a mechanism for saving and installing configurations. iControl's ITCMSystem::ConfigSync interface includes these features as well as those to transfer the configurations to and from another system. This allows for another level of backup and centralized management. A typical scenario would be to categorically backup and store all configurations of all known systems in the event of a mis-configuration (operator error, etc).

This sample application demonstrates the building blocks for all of the operations associated with configuration state management. A Possible extension for this sample application could be to create a central management application to maintain known configurations as well as provision new devices.
 

 





SDK Components Referenced top

 

The following components of the iControl SDK were referenced in this sample application.

Interface:
 ITCMSystem::ConfigSync
Methods:
    void delete_configuration(
        string filename);
    void download_configuration(
        in string config_name,
        in unsigned long chunk_size, 
        inout unsigned long file_offset,
        out byte[] file_data
        out ITCMCommon::FileChainType);
    void get_configuration_checksum(
        in string filename,
        out string checksum);
    void get_configuration_list(
        out ITCMSystem::ConfigSync::ConfigFileEntry[] config_file_list);
    void install_configuration(
        in filename);
    void rollback_configuration(void);
    void save_configuration(
        in string filename,
        in ITCMSystem::ConfigSync::SaveMode save_flag);
    void synchroize_configuration(
        in ITCMSystem::ConfigSync::SyncMode sync_flag);
    void upload_configuration(
        in string config_name,
        in byte[] file_data,
        in ITCMCommon::FileChainType chain_type);

Structures:
    struct ITCMSystem::ConfigSync::ConfigFileEntry
    {
        string file_name;
        string file_datetime;
    };
Enumerations:
    enum ITCMCommon::FileChainType
    {
        FILE_UNDEFINED;
        FILE_FIRST;
        FILE_MIDDLE;
        FILE_UNUSED;
        FILE_LAST;
        FILE_FIRST_AND_LAST;
    };
    enum ITCMSystem::ConfigSync::SaveMode
    {
        SAVE_FULL;
        SAVE_COMMON;
    };
    enum ITCMSystem::ConfigSync::SyncMode
    {
        CONFIGSYNC_BASIC;
        CONFIGSYNC_RUNNING;
        CONFIGSYNC_ALL;
    };

 

 

 





Code Sections top

 

 

 





Debug settings top

 

To enable SOAP level tracing, add the "+ trace => qw(method debug)" option to the SOAP::Lite declaraion. The default is no debug tracing.

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

 

 

 





Establishing the connection top

 

Due to the authentication requirements on the iControl Web Service endpoint, the get_basic_credetials() subroutine needs to be implemented to return the username and password for the client credentials.

#----------------------------------------------------------------------------
# Transport Information
#----------------------------------------------------------------------------
sub SOAP::Transport::HTTP::Client::get_basic_credentials
{
    return "$sUID" => "$sPWD";
}
$ConfigSync = SOAP::Lite
    -> uri('urn:iControl:ITCMSystem/ConfigSync')
    -> readable(1)
    -> proxy("$sProtocol://$sHost:$sPort/iControl/iControlPortal.cgi");

 

 

 





Generating a default configuration name top

 

If no arguments are given for a configuration name a unique name is created based on the hostname and the current timestamp.

#----------------------------------------------------------------------------
# sub generateConfigName
#----------------------------------------------------------------------------
sub generateConfigName()
{
    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    $year += 1900;
    $sName = sprintf("%s-%04d%02d%02d_%02d%02d%02d.ucs", $sHost, $year, $mon, $mday, $hour, $min, $sec);
    return $sName;
}

 

 

 





Listing available configurations top

 

For the list command the get_configuration_list() method is called. Each configuration, along with it's timestamp, are displayed to the user.

#----------------------------------------------------------------------------
# sub listConfigurations
#----------------------------------------------------------------------------
sub listConfigurations()
{
    $soap_response = $ConfigSync->get_configuration_list();
    if ( $soap_response->fault )
    {
        print $soap_response->faultcode, " ", $soap_response->faultstring, "
";
    }
    else
    {
        my @ConfigFileEntryList = @{$soap_response->result};
        print "Available Configurations:
";
        my $configNumber = 0;
        foreach my $ConfigFileEntry (@ConfigFileEntryList)
        {
            print "    (",
                substr($ConfigFileEntry->{"file_datetime"}, 0, -1),
                ") : '",
                $ConfigFileEntry->{"file_name"},
                "'
";
            $configNumber++;
        }
    }
}

 

 

 





Deleting a given configuration top

 

For the delete command, the delete_configuration() method is called. It will remove the named configuration from the target controller.

#----------------------------------------------------------------------------
# sub deleteConfiguration
#----------------------------------------------------------------------------
sub deleteConfiguration()
{
    my ($configName, $quiet) = (@_);
    my $success = 0;
    if ( "" eq $configName )
    {
        &usage("delete");
    }
 
    eval
    {
        $soap_response = $ConfigSync->delete_configuration
        (
            SOAP::Data->name(filename => $configName)
        );
    };
    if ( $soap_response and $soap_response->fault )
    {
        if ( 1 != $quiet )
        {
            print $soap_response->faultcode, " ", $soap_response->faultstring, "
";
        }
    }
    else
    {
        $success = 1;
        if ( 1 != $quiet )
        {
            print "Configuration '$sConfigName' deleted successfully!
";
        }
    }
    return $success;
}

 

 

 





Saving the current configuration top

 

For the save command, the save_configuration() method is called. It will save the current configuration on the controller to a named configuration file.

#----------------------------------------------------------------------------
# sub saveConfiguration
#----------------------------------------------------------------------------
sub saveConfiguration()
{
    my ($configName, $saveMode, $quiet) = (@_);
    my $success = 0;
    
    if ( ("" eq $configName) or ("" eq $saveMode) )
    {
        &usage("save");
    }
    
    $soap_response = $ConfigSync->save_configuration
    (
        SOAP::Data->name(filename => $configName),
        SOAP::Data->name(save_flag => $saveMode)
    );
    if ( $soap_response->fault )
    {
        if ( 1 != $quiet )
        {
            print $soap_response->faultcode, " ", $soap_response->faultstring, "
";
        }
    }
    else
    {
        $success = 1;
        if ( 1 != $quiet )
        {
            print "Configuration '$configName' saved successfully!
";
        }
    }
    return $success;
}

 

 

 





Installing a given configuration top

 

For the install command, the install_configuration() method is called. It will install a named configuration file on the controller.

#----------------------------------------------------------------------------
# sub installConfiguration
#----------------------------------------------------------------------------
sub installConfiguration()
{
    my ($configName, $quiet) = (@_);
    my $success = 0;
    if ( "" eq $configName )
    {
       &usage("install");
    }
    eval
    {
       $soap_response = $ConfigSync->install_configuration
       (
          SOAP::Data->name(filename => $configName)
       );
    };
    if ( $soap_response and $soap_response->fault )
    {
       if ( 1 != $quiet )
       {
          print $soap_response->faultcode, " ", $soap_response->faultstring, "
";
       }
    }
    else
    {
       $success = 1;
       if ( 1 != $quiet )
       {
          print "Configuration '$configName' installed successfully!
";
       }
    }
    return $success;
}

 

 

 





Rolling back to the previous configuration state top

 

For the rollback command, the rollback_configuration() method is called. It will signal a rollback to the previous configuration state before the last configuration install.

#----------------------------------------------------------------------------
# sub rollbackConfiguration
#----------------------------------------------------------------------------
sub rollbackConfiguration()
{
    my ($quiet) = (@_);
    my $success = 0;
    eval
    {
        $soap_response = $ConfigSync->rollback_configuration();
    };
    if ( $soap_response and $soap_response->fault )
    {
        if ( 1 != $quiet )
        {
            print $soap_response->faultcode, " ", $soap_response->faultstring, "
";
        }
    }
    else
    {
        $success = 1;
        if ( 1 != $quiet )
        {
            print "Configuration rollback successful!
";
        }
    }
    return $success;
}

 

 

 





Downloading a given configuration top

 

For the download command, the download_configuration() method is called. It will perform a file transfer of the given configuration file on the controller to the given local file name.

#----------------------------------------------------------------------------
# sub downloadConfiguration
#----------------------------------------------------------------------------
sub downloadConfiguration()
{
    my ($configName, $localFile, $quiet) = (@_);
    $success = 0;
    if ( "" eq $localFile )
    {
        $localFile = $configName;
    }
    if ( "" eq $configName )
    {
        &usage("download");
    }
    open (LOCAL_FILE, ">$localFile") or die("Can't open $localFile for output: $!");
    binmode(LOCAL_FILE);
    my $file_offset = 0;
    my $chunk_size = $defaultChunkSize;
    my $chain_type = 0;
    my $bContinue = 1;
    while ( 1 == $bContinue )
    {
        $soap_response = $ConfigSync->download_configuration
        (
            SOAP::Data->name(config_name => $configName),
            SOAP::Data->name(chunk_size => $chunk_size),
            SOAP::Data->name(file_offset => $file_offset)
        );
        if ( $soap_response->fault )
        {
            if ( 1 != $quiet )
            {
                print $soap_response->faultcode, " ", $soap_response->faultstring, "
";
            }
            $bContinue = 0;
        }
        else
        {
            $file_offset = $soap_response->result;
            @params = $soap_response->paramsout;
            $file_data = @params[0];
            $chain_type = @params[1];
            # Append Data to File
            print LOCAL_FILE $file_data;
            print "Bytes Transferred: $file_offset";
            if ( ("FILE_LAST" eq $FileChainType->{$chain_type}) or
                 ("FILE_FIRST_AND_LAST" eq $FileChainType->{$chain_type}) )
            {
                $bContinue = 0;
                $success = 1;
            }
        }
    }
    print "
";
    close(LOCAL_FILE);
    return $success;
}

 

 

 





Uploading a configuration top

 

For the upload command, the upload_configuration() method is called. It will perform a file transfer of the given local file name to the given configuration name on the controller.

#----------------------------------------------------------------------------
# sub uploadConfiguration
#----------------------------------------------------------------------------
sub uploadConfiguration()
{
    my ($localFile, $configName, $quiet) = (@_);
    $success = 0;
    if ( "" eq $configName )
    {
        $configName = $localFile;
    }
    if ( "" eq $localFile )
    {
        &usage("upload");
    }
    $bContinue = 1;
    $chain_type = $FileChainTypeValue->{"FILE_FIRST"};
    $preferred_chunk_size = $defaultChunkSize;
    $chunk_size = $defaultChunkSize;
    $total_bytes = 0;
    open(LOCAL_FILE, "<$localFile") or die("Can't open $localFile for input: $!");
    binmode(LOCAL_FILE);
    while (1 == $bContinue )
    {
        $file_data = "";
        $bytes_read = read(LOCAL_FILE, $file_data, $chunk_size);
        if ( $preferred_chunk_size != $bytes_read )
        {
            $chain_type = $FileChainTypeValue->{"FILE_LAST"};
            $bContinue = 0;
        }
        $total_bytes += $bytes_read;
        $soap_response = $ConfigSync->upload_configuration
        (
            SOAP::Data->name(config_name => $configName),
            SOAP::Data->name(file_data => $file_data),
            SOAP::Data->name(chain_type => $chain_type)
        );
        if ( $soap_response->fault )
        {
            print $soap_response->faultcode, " ", $soap_response->faultstring, "
";
            $success = 0;
            $bContinue = 0;
        }
        else
        {
            print "Uploaded $total_bytes bytes";
            $success = 1;
        }
        $chain_type = $FileChainTypeValue->{"FILE_MIDDLE"};
    }
    print "
";
    close(LOCAL_FILE);
    return $success;
}

 

 

 





Synchronizing configuration for HA systems top

 

For the sync command, the synchronize_configuraion() method is called. It will signal the controller to synchronize it's configuration with it's peer's in a HA group.

#----------------------------------------------------------------------------
# sub syncConfiguration
#----------------------------------------------------------------------------
sub syncConfiguration()
{
    my ($syncFlag, $quiet) = (@_);
    my $success = 0;
    if ( "" eq $syncFlag )
    {
        &usage("sync");
    }
    $soap_response = $ConfigSync->synchronize_configuration
    (
        SOAP::Data->name(sync_flag => $syncFlag)
    );
    if ( $soap_response->fault )
    {
        if ( 1 != $quiet )
        {
            print $soap_response->faultcode, " ", $soap_response->faultstring, "
";
        }
    }
    else
    {
        $success = 1;
        if ( 1 != $quiet )
        {
            print "Configuration synchronized successfully!
";
        }
    }
    return $success;
}

 

 

 





Performing a full backup to the client machine top

 

The backup command, the code creates a unique configuration name based on the hostname and current time stamp. It then uses this name to perform a save to create a temporary configuration file. It follows with a download of the configuration and then a delete of the temporary configuration file.

#----------------------------------------------------------------------------
# sub backupConfiguration
#----------------------------------------------------------------------------
sub backupConfiguration()
{
    my ($configName, $localFile, $quiet) = (@_);
    if ( "" eq $configName )
    {
        $configName = generateConfigName();
    }
    if ( "" eq $localFile )
    {
        $localFile = $configName;
    }
    if ( ("" eq $configName) or ("" eq $localFile) )
    {
        &usage("backup");
    }
    sleep(1);
    $success = &saveConfiguration($configName, $SaveModeValue->{"SAVE_FULL"}, $quiet);
    if ( 1 == $success )
    {
        sleep(1);
        $success = &downloadConfiguration($configName, $localFile, $quiet);
        if ( 1 == $success )
        {
            if ( 1 != $quiet )
            {
                print "Configuration file $configName successfully backed up.
";
            }
        }
        sleep(1);
        $success = &deleteConfiguration($configName, $quiet);
    }
    return $success;
}

 

 

 





Performing a full restore from the client machine top

 

The restore command, the code takes the given local file name and performs an upload of the file to a temporary configuration file on the controller. It then issues an install command to apply the configuration to the system. If the option for syncronizing configuration was given, it will then issue a sync command and follow this all up with a delete to remove the temporary configuration file.

#----------------------------------------------------------------------------
# sub restoreConfiguration
#----------------------------------------------------------------------------
sub restoreConfiguration()
{
    my ($localFile, $doSync, $quiet) = (@_);
    $configName = $localFile;
    if ( ("" eq $configName) or ("" eq $localFile) )
    {
        &usage("restore");
    }
    sleep(1);
    $success = &uploadConfiguration($localFile, $configName, $quiet);
    if ( 1 == $success )
    {
        sleep(1);
        $success = &installConfiguration($configName, $quiet);
        if ( 1 == $success )
        {
            if ( ("1" eq $doSync) or ("y" eq $doSync) or ("Y" eq $doSync) )
            {
                # Give server time to recover from restart.
                sleep(5);
                $success = &syncConfiguration(&syncModeFromArg("all"), $quiet);
            }
        }
        sleep(1);
        &deleteConfiguration($configName, $quiet);
    }
    return $success;
}

 

 

 





Related Links top

 

Sample appliation source (ConfigSync.pl)
iControl Developer
http://www.perl.com
http://www.soaplite.com