Merge BIG-IP Config Files

Problem this snippet solves:

This script will take a local BIG-IP configuration file, upload it to the BIG-IP, merge it with the existing configuration, then clean up the iControl REST upload folder (/var/config/rest/downloads) by removing the file.

How to use this snippet:

macdaddy:scripts jrahm$ python merge_config.py 
usage: merge_config.py [-h] host username filepath

Code :

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)

    requests.packages.urllib3.disable_warnings()
    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


def _merge_config(host, creds, file):
    requests.packages.urllib3.disable_warnings()

    b_url = 'https://%s/mgmt/tm/sys/config' % host
    b = requests.session()
    b.auth = creds
    b.verify = False
    b.headers.update({'Content-Type': 'application/json'})


    options = {}
    options['file'] = '/var/config/rest/downloads/%s' % file
    options['merge'] = True

    payload = {}
    payload['command'] = 'load'
    payload['options'] = [options]

    try:
        merge = b.post(b_url, json.dumps(payload))
        if merge.status_code is not 200:
            print "Merge failed, check rest log file"
            exit()
    except Exception, e:
        print e


def _cleanup_mergefile(host, creds, file):
    requests.packages.urllib3.disable_warnings()

    b_url = 'https://%s/mgmt/tm/util/unix-rm' % host
    b = requests.session()
    b.auth = creds
    b.verify = False
    b.headers.update({'Content-Type': 'application/json'})

    payload = {}
    payload['command'] = 'run'
    payload['utilCmdArgs'] = '/var/config/rest/downloads/%s' % file

    try:
        cleanup = b.post(b_url, json.dumps(payload))
        if cleanup.status_code is not 200:
            print "Cleanup failed, please check system."
    except Exception, e:
        print e


if __name__ == "__main__":
    import os, requests, json, argparse, getpass

    requests.packages.urllib3.disable_warnings()

    parser = argparse.ArgumentParser(description='Merge a config file into BIG-IP config')
    parser.add_argument("host", help='BIG-IP IP or Hostname', )
    parser.add_argument("username", help='BIG-IP Username')
    parser.add_argument("filepath", help='Merge file (with Absolute Path)')
    args = vars(parser.parse_args())

    hostname = args['host']
    username = args['username']
    filepath = args['filepath']

    print "%s, enter your password: " % args['username'],
    password = getpass.getpass()

    _upload(hostname, (username, password), filepath)

    filename = os.path.basename(filepath)
    _merge_config(hostname, (username, password), filename)
    _cleanup_mergefile(hostname, (username, password), filename)

Tested this on version:

12.0
Updated Jun 06, 2023
Version 2.0
  • I cannot seem to get the cleanup to work. The post to /mgmt/tm/util/unix-rm returns a 200 but the file isn't deleted and the response says Permission Denied. I'm posting as myself and I have full administrator access. The version of BIG IP I am using is 12.0.0 Build 2.0.644 Hotfix HF2
  • is your account locally defined or remote auth? Does it work with the admin account?
  • So my account is set up via active directory. I've authenticated with the F5 and received a token and tacked the X-F5-Auth-Token header on to all of these requests to get the upload and merge work as my own account. The delete works if I run the script above as the root admin account but as you can imagine, that's not an account that I'd like the script to run as. Ideally I want to create an LDAP account that has admin access which I can manage outside of the F5 and just have it run this script.
  • to be clear, you have modified the above code to include the token but it still gives you a permission denied?
  • Correct, the first two steps work great with the token but the delete file fails with a permission denied.
  • send me your updated script to rahm -at- f5 -dot- com and I'll take a look.
  • Will take a look in the morning, it's been a crazy week!