Python script for updating data group

Problem this snippet solves:

Updating data group via Python. From the article: Routing HTTP by request headers

Currently when you need to update a data group via iControl REST it requires you to retrieve a copy of all of the records, make your changes, and then re-submit all the records to make any changes. The following Python script takes care of the process of extracting all of the records, turning them into a dictionary, and then allowing the data group to be updated by passing a dictionary.

How to use this snippet:

This code can be imported as a class or run from the command-line. From the command-line:

% ./cgp.py add www.mycompany.example 10.10.1.11:80
added: www.mycompany.example
% ./cgp.py get www.mycompany.example
www.mycompany.example: 10.10.1.11:80
% ./cgp.py update www.mycompany.example 10.10.1.11:8000
updated: www.mycompany.example
% ./cgp.py del www.mycompany.example
deleted: www.mycompany.example

From code

from cgp import CGP
BIGIP_ADDRESS = '[BIGIP MGMT HOST]'
BIGIP_USER = '[admin user]'
BIGIP_PASS = '[admin password]'

DATA_GROUP = '~Common~[data-group name]'
cgp = CGP(BIGIP_ADDRESS, BIGIP_USER, BIGIP_PASS)
# get record
data =  cgp.get_data_group(DATA_GROUP)

# add record
data['www.mycompany.example'] = '10.10.1.10:80'
cgp.set_data_group(DATA_GROUP, data)

# update record
data =  cgp.get_data_group(DATA_GROUP)
data['www.mycompany.example'] = '10.10.1.10:80'
cgp.set_data_group(DATA_GROUP, data)

# delete record
data =  cgp.get_data_group(DATA_GROUP)
del data['www.mycompany.example']
cgp.set_data_group(DATA_GROUP, data)

Code :

#!/usr/bin/python
#
# Chen Gateway Protocol
#
# Example of using iControl REST
# From: https://devcentral.f5.com/s/articles/routing-http-by-request-headers
#
# Requires iControl REST > 11.5.0
#
# The following script allows one to dynamically update a data-group via
# iControl REST
#
import requests
import json

BIGIP_ADDRESS = '[BIGIP MGMT HOST]'
BIGIP_USER = '[admin user]'
BIGIP_PASS = '[admin password]'

DATA_GROUP = '~Common~[data-group name]'

class CGP(object):
    def __init__(self, host, user, passwd):
        self.host = host
        self.user = user
        self.passwd = passwd
        self.mgmt_url = "https://%s/mgmt/tm" %(host)

        self.session = requests.session()
        self.session.auth = (user, passwd)
        self.session.verify = False
        self.session.headers.update({'Content-Type':'application/json'})

    def get_data_group(self, datagroup):
        req_url = "%s/ltm/data-group/internal/%s" %(self.mgmt_url, datagroup)
        req = self.session.get(req_url)
        return dict([(a['name'],a['data']) for a in req.json()['records']])
        "return contents of data-group as dictionary"

    def set_data_group(self, datagroup, data):
        req_url = "%s/ltm/data-group/internal/%s" %(self.mgmt_url, datagroup)
        records = {'records': [{'data':r[1],'name':r[0]} for r in  data.items()]}
        req = self.session.put(req_url,data = json.dumps(records) )
        "update contents of data-group as dictionary"
        

if __name__ == "__main__":
    import argparse
    import sys
    parser = argparse.ArgumentParser()
    parser.add_argument('action')
    parser.add_argument('host_header')
    parser.add_argument('node_ip_port',nargs='?')
    args = parser.parse_args()

    cgp = CGP(BIGIP_ADDRESS, BIGIP_USER, BIGIP_PASS)
    data =  cgp.get_data_group(DATA_GROUP)
    if args.action == 'del':
        if args.host_header in data:        
            del data[args.host_header]
            print "deleted:", args.host_header
        else:
            print "error: %s does not exist" %(args.host_header)
            sys.exit(1)
    elif args.action == 'add':
        if args.host_header in data:
            print "error: %s already exists" %(args.host_header)
            sys.exit(1)
        else:
            data[args.host_header] = args.node_ip_port
            print "added: %s" %(args.host_header)
    elif args.action == 'update':
        if args.host_header in data:        
            data[args.host_header] = args.node_ip_port
            print "updated:", args.host_header
        else:
            print "error: %s does not exist" %(args.host_header)
            sys.exit(1)
    elif args.action == 'get':
        print "%s: %s" %(args.host_header,data.get(args.host_header,"DOES NOT EXIST"))
    cgp.set_data_group(DATA_GROUP, data)

Tested this on version:

11.5
Updated Jun 06, 2023
Version 2.0
  • it needs to replace all values in the datagroup when add/delete/update? any other better way?
  • Robert, I'm not aware of a method to perform an incremental update of a datagroup at this time. There was a similar question on DevCentral: https://devcentral.f5.com/s/feed/0D51T00006i7Y1FSAU
  • thanks,Eric I have completed my python version yeah, there is no way to perform an incremental update of a datagroup
  • why i got a problem which said "keyerror:'records'"?how can i resolve the question? tks