Created
January 9, 2021 04:16
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################### | |
# 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