BIG-IP File Transfers
Problem this snippet solves:
This python script allows you to transfer files to/from BIG-IP/BIG-IQ. Note that all downloads come from /shared/images, so if you need to download files that are not .iso images, you'll need to copy them to /shared/images and then clean up afterward.
How to use this snippet:
# Download from BIG-IP (Files must be in /shared/images/)
python f_xfer.py download bigip.test.local admin /path/you/want/on/your/system/example.txt
# Upload to BIG-IP (Files placed in /var/config/rest/downloads unless extension is .iso, and then it will be placed in /shared/images/)
python f_xfer.py upload bigip.test.local admin /path/file/exists/on/your/system/example.txt
Code :
import os, requests, argparse, getpass
def _download(host, creds, fp):
    chunk_size = 512 * 1024
    headers = {
        'Content-Type': 'application/octet-stream'
    }
    filename = os.path.basename(fp)
    uri = 'https://%s/mgmt/cm/autodeploy/software-image-downloads/%s' % (host, filename)
    with open(fp, 'wb') as f:
        start = 0
        end = chunk_size - 1
        size = 0
        current_bytes = 0
        while True:
            content_range = "%s-%s/%s" % (start, end, size)
            headers['Content-Range'] = content_range
            #print headers
            resp = requests.get(uri,
                                auth=creds,
                                headers=headers,
                                verify=False,
                                stream=True)
            if resp.status_code == 200:
                # If the size is zero, then this is the first time through the
                # loop and we don't want to write data because we haven't yet
                # figured out the total size of the file.
                if size > 0:
                    current_bytes += chunk_size
                    for chunk in resp.iter_content(chunk_size):
                        f.write(chunk)
                # Once we've downloaded the entire file, we can break out of
                # the loop
                if end == size:
                    break
            crange = resp.headers['Content-Range']
            # Determine the total number of bytes to read
            if size == 0:
                size = int(crange.split('/')[-1]) - 1
                # If the file is smaller than the chunk size, BIG-IP will
                # return an HTTP 400. So adjust the chunk_size down to the
                # total file size...
                if chunk_size > size:
                    end = size
                # ...and pass on the rest of the code
                continue
            start += chunk_size
            if (current_bytes + chunk_size) > size:
                end = size
            else:
                end = start + chunk_size - 1
def _upload(host, creds, fp):
    chunk_size = 512 * 1024
    headers = {
        'Content-Type': 'application/octet-stream'
    }
    fileobj = open(fp, 'rb')
    filename = os.path.basename(fp)
    if os.path.splitext(filename)[-1] == '.iso':
        uri = 'https://%s/mgmt/cm/autodeploy/software-image-uploads/%s' % (host, filename)
    else:
        uri = 'https://%s/mgmt/shared/file-transfer/uploads/%s' % (host, filename)
    size = os.path.getsize(fp)
    start = 0
    while True:
        file_slice = fileobj.read(chunk_size)
        if not file_slice:
            break
        current_bytes = len(file_slice)
        if current_bytes < chunk_size:
            end = size
        else:
            end = start + current_bytes
        content_range = "%s-%s/%s" % (start, end - 1, size)
        headers['Content-Range'] = content_range
        requests.post(uri,
                      auth=creds,
                      data=file_slice,
                      headers=headers,
                      verify=False)
        start += current_bytes
if __name__ == "__main__":
    import os, requests, argparse, getpass
    requests.packages.urllib3.disable_warnings()
    parser = argparse.ArgumentParser(description='Transfer files to/from BIG-IP')
    parser.add_argument("transfer_status", help='upload | download')
    parser.add_argument("host", help='BIG-IP IP or Hostname', )
    parser.add_argument("username", help='BIG-IP Username')
    parser.add_argument("filepath", help='Appropriate Src/Dest Filename with Absolute Path')
    args = vars(parser.parse_args())
    tstat = args['transfer_status']
    hostname = args['host']
    username = args['username']
    filepath = args['filepath']
    print('{}, enter your password: '.format(args['username']))
    password = getpass.getpass()
    if tstat == 'upload':
        _upload(hostname, (username, password), filepath)
    elif tstat == 'download':
        _download(hostname, (username, password), filepath)Tested this on version:
13.0Published Jun 25, 2019
Version 1.0JRahm Admin
Admin
Christ Follower, Husband, Father, Technologist. I love community and I especially love THIS community. My background is networking, but I've dabbled in all the F5 iStuff, I'm a recovering Perl guy, and am very much a python enthusiast. Learning alongside all of you in this accelerating industry toward modern apps and architectures.JRahm Admin
Admin
Christ Follower, Husband, Father, Technologist. I love community and I especially love THIS community. My background is networking, but I've dabbled in all the F5 iStuff, I'm a recovering Perl guy, and am very much a python enthusiast. Learning alongside all of you in this accelerating industry toward modern apps and architectures.No CommentsBe the first to comment