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 >>>