iControl File Download

When working on my Config Backup for F5 project, I needed to download UCS files from BigIP devices. iControl provides an API call that allows for downloading files (System.ConfigSync.download_file). However, the download_file call is does not download the entire file but only a small “chunk” of a file. It is up to the API user to write logic that will download all chunks of the file and combine them to the destination file.

Below is the Python function I wrote for downloading files. It was developed and tested with python 2.6 and you will need the bigsuds library available here on DevCentral.

import sys
import time
import bigsuds
import os
from base64 import b64decode
 
def file_download(bigip_obj,src_file,dst_file,chunk_size,buff = 1048576):
   '''
file_download - Download file from F5 via iControl
Usage - file_download(bigip_obj,src_file,dst_file,chunk_size,buff = n)
    @param bigip_obj: the bigsuds icontol object
    @param src_file: file on F5
    @param dst_file: local file
    @param chunk_size: download size for each chunk
    @param buff: (optional) size of file write buffer, default 1MB
Returns - returns file size in bytes if job completed
Raises exceptions if job failed
   '''
   # Set begining vars
   foffset = 0
   timeout_error = 0
   fbytes = 0
    
   # Open temp file for writing, default buffer size is 1MB
   f_dst = open(dst_file + '.tmp','w',buff)
 
   # Main loop
   while True:
      # Try to download chunk
      try:
         chunk = bigip_obj.System.ConfigSync.download_file(file_name = src_file,
                                                         chunk_size = chunk_size,
                                                         file_offset = foffset)
      except:
         timeout_error += 1
         # is this the 3rd connection attempt?
         if (timeout_error >= 3):
            # Close tmp file & delete, raise error
            f_dst.close()
            os.remove(dst_file + '.tmp')
            raise
         else:
            # Otherwise wait 2 seconds before retry
            time.sleep(2)
            continue
      # reset error counter after a good connect
      timeout_error = 0
       
      # Write contents to file
      fchunk = b64decode(chunk['return']['file_data'])
      f_dst.write(fchunk)
      fbytes += sys.getsizeof(fchunk) - 40
       
      # Check to see if chunk is end of file
      fprogress = chunk['return']['chain_type']
      if (fprogress == 'FILE_FIRST_AND_LAST')  or (fprogress == 'FILE_LAST' ):
         # Close file, rename from name.tmp to name
         f_dst.close()
         os.rename(dst_file + '.tmp' , dst_file)
         return fbytes
       
      # set new file offset
      foffset = chunk['file_offset']

Here is an example of how to use the function –

>>> host = '192.168.1.245'
>>> user = 'admin'
>>> passwd = 'admin'
>>> b = bigsuds.BIGIP(hostname = host, username = user, password = passwd)
>>> file_download(b,'/var/local/ucs/configbackup.ucs','bigip.conf',65535)
92163176
>>>
Tagged , , , . Bookmark the permalink.