Skip to content

Instantly share code, notes, and snippets.

@f5-rahm
Created January 9, 2021 04:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save f5-rahm/a1f631579df98e185d575e3e7f156b53 to your computer and use it in GitHub Desktop.
Save f5-rahm/a1f631579df98e185d575e3e7f156b53 to your computer and use it in GitHub Desktop.
This script was created for managing individual or multiple data-group records on BIG-IP without having to update the entire record set. It uses a combination of a tmsh script on BIG-IP with a python script executed remotely.
###################################################################################
# dgmgmt.py
#
# author: jason rahm
# tmsh script author: john alam
#
# usage: dgmgmt.py [-h] host user {add,modify,delete} datagroup dgvalues
#
# positional arguments:
# host BIG-IP IP/FQDN
# user BIG-IP Username
# {add,modify,delete} add | modify | delete
# datagroup Data-Group name you wish to change
# dgvalues Key or KV Pairs, in this format: "k1,k2,k3=v3,k4=v4,k5"
#
# optional arguments:
# -h, --help show this help message and exit
###################################################################################
from bigrest.bigip import BIGIP
from time import sleep
import argparse
import getpass
import sys
DGMGMT_SCRIPT = 'proc script::init {} {\n}\n\nproc script::run {} {\nset record_data [lindex $tmsh::argv 3]\n\n' \
'switch [lindex $tmsh::argv 1] {\n "add-record" {\n tmsh::modify ltm data-group internal ' \
'[lindex $tmsh::argv 2] type string records add $record_data\n ' \
'puts "Record [lindex $tmsh::argv 3] added."\n }\n "modify-record" {\n ' \
'tmsh::modify ltm data-group internal [lindex $tmsh::argv 2] type string records modify' \
' $record_data\n puts "Record changed [lindex $tmsh::argv 3]."\n }\n "delete-record" {\n' \
' tmsh::modify ltm data-group internal [lindex $tmsh::argv 2] type string records delete' \
' $record_data\n puts "Record [lindex $tmsh::argv 3] deleted."\n }\n "save" {\n ' \
' tmsh::save sys config\n puts "Config saved."\n }\n}\n}\n' \
'proc script::help {} {\n}\n\nproc script::tabc {} {\n}\n'
def build_parser():
parser = argparse.ArgumentParser()
parser.add_argument("host", help="BIG-IP IP/FQDN")
parser.add_argument("user", help="BIG-IP Username")
parser.add_argument(
"action", help="add | modify | delete", choices=["add", "modify", "delete"]
)
parser.add_argument("datagroup", help="Data-Group name you wish to change")
parser.add_argument(
"dgvalues", help='Key or KV Pairs, in this format: "k1,k2,k3=v3,k4=v4,k5"'
)
return parser.parse_args()
def deploy_tmsh_script(bigip):
try:
cli_script = {"name": "dgmgmt", "apiAnonymous": DGMGMT_SCRIPT}
bigip.create("/mgmt/tm/cli/script", cli_script)
except Exception as e:
print(f"Failed to create the tmsh script due to {type(e).__name__}:\n")
print(f"{e}")
sys.exit()
def format_records(action, name, records):
recs = ""
for record in records.split(","):
x = record.split("=")
record_key = x[0]
if len(x) == 1 and action != 'modify':
recs += f"{record_key} "
elif len(x) == 1 and action == 'modify':
recs += f'{record_key} {{ data \\\"\\\" }} '
elif len(x) == 2:
record_value = x[1]
recs += f'{record_key} {{ data \\\"{record_value}\\\" }} '
else:
raise ValueError("Max record items is 2: key or key/value pair.")
return f"{action}-record {name} '{{ {recs} }}'"
def dg_update(bigip, cli_args):
try:
dg_mods = {"command": "run", "name": "/Common/dgmgmt", "utilCmdArgs": cli_args}
bigip.command("/mgmt/tm/cli/script", dg_mods)
except Exception as e:
print(f"Failed to modify the data-group due to {type(e).__name__}:\n")
print(f"{e}")
sys.exit()
def instantiate_bigip(host, user):
pw = getpass.getpass(prompt=f"\n\tWell hello {user}, please enter your password: ")
try:
obj = BIGIP(host, user, pw)
except Exception as e:
print(f"Failed to connect to {args.host} due to {type(e).__name__}:\n")
print(f"{e}")
sys.exit()
return obj
def dg_listing(bigip, dgname):
dg = b.load(f'/mgmt/tm/ltm/data-group/internal/{dgname}')
print(f'\n\t{args.datagroup}\'s updated record set: ')
for i in dg.properties['records']:
print(f'\t\tkey: {i["name"]}, value: {i["data"]}')
print('\n\n')
if __name__ == "__main__":
args = build_parser()
b = instantiate_bigip(args.host, args.user)
if not b.exist("/mgmt/tm/cli/script/dgmgmt"):
print(
"\n\tThe data-group management tmsh script is not yet on your system, installing..."
)
deploy_tmsh_script(b)
sleep(2)
if not b.exist(f"/mgmt/tm/ltm/data-group/internal/{args.datagroup}"):
print(
f"\n\tThe {args.datagroup} data-group doesn't exist. Please specify an existing data-group.\n"
)
sys.exit()
cli_arguments = format_records(args.action, args.datagroup, args.dgvalues)
dg_update(b, cli_arguments)
dg_listing(b, args.datagroup)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment