GTM type A and AAAA wideip NetworkMap to generate a json with python f5-sdk
Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’.
Short Description
GTM type A and AAAA NetworkMap to a json with python f5-sdk, code support check AS3 wideip.
test well in BIGIP VE V14.1.5 and V16.1.2, code should work on version V12+ BIGIP
Important: gtm/ltm server name can not contains character ":" and "\" and "/"
and gtm server virtual server name(VS NAME) also can not contains character ":" and "\", because I use fullPath.split(':') to read GTM-Server Name and Virtual server name(correct example such as
"fullPath":"/Common/DC-2-GTM-ipv4:/Common/vs_cmcc_99_22"
)
otherwise it will raise HTTP 404, below is the error format example:
GTM Server name ZSCTEST:DC-1-LTM-ZSC-ipv4
GTM Server Virtual Server Name(VS NAME) test:vs
"name":"ZSCTEST\\:DC-1-LTM-ZSC-ipv4:test:vs","partition":"Common","fullPath":"/Common/ZSCTEST\\:DC-1-LTM-ZSC-ipv4:test:vs"
Problem solved by this Code Snippet
collect GTM type A and AAAA data and generate a json file
How to use this Code Snippet
Firstly, install python f5 sdk
pip install f5-sdk
Secondly, modify the following IP, account and password corresponding to your BIGIP GTM device
mgmt = ManagementRoot('192.168.5.109', 'admin', 'xt32112300')
python f5-sdk send a GET request to GTM in the form of ~partition~name, but the format of the GET request for the AS3 published wideip should be ~partition~Folder~name, so when retrieving the AS3 published wideip, the URL constructed will report HTTP 404. After reading the error source code sitepackages\icontrol\session.py There is a function def _ validate_ name_ partition_ Subpath (element):
def _validate_name_partition_subpath(element):
# '/' and '~' are illegal characters in most cases, however there are
# few exceptions (GTM Regions endpoint being one of them where the
# validation of name should not apply.
"""
if '~' in element:
error_message =\
"instance names and partitions cannot contain '~', but it's: %s"\
% element
raise InvalidInstanceNameOrFolder(error_message)
"""
the determination of whether the name carries the character ~ will cause the structure of AS3 name=i.subPath + '~' + i.name doesn't work.
so, delete the judgment of ~ or use """ """ notes code will support AS3 wideip check
Finally, if the code runs no error, it will generate a "F5-GTM-Wideip-XXX(date format)-NetworkMap.json" file in your local working directory
Code Snippet Meta Information
- Version: 1.0
- Coding Language: python
Full Code Snippet
from f5.bigip import ManagementRoot
import json
import time
wideip_NetworkMap = {}
mgmt = ManagementRoot('192.168.5.109', 'admin', 'xt32112300')
gtm_wideip = []
"""
author: xuwen
email: 1099061067@qq.com
date: 2022/12/16
"""
# GTM A Wideip
for i in mgmt.tm.gtm.wideips.a_s.get_collection():
try:
type_A_wideip = mgmt.tm.gtm.wideips.a_s.a.load(name=i.subPath + '~' + i.name if hasattr(i, 'subPath') else i.name, partition=i.partition)
except Exception as e:
print('type A widip name {} error msg is '.format(i.name) + str(e))
else:
gtm_A_wideip = {}
type_A_wideip_name = i.name
type_A_wideip_partition = i.partition
if hasattr(type_A_wideip, 'aliases'):
gtm_A_wideip['aliases'] = type_A_wideip.aliases
if hasattr(type_A_wideip, 'rules'):
gtm_A_wideip['iRules'] = type_A_wideip.rules
if hasattr(type_A_wideip, 'enabled'):
gtm_A_wideip['enabled'] = True
else:
gtm_A_wideip['disabled'] = True
if hasattr(type_A_wideip, 'subPath'):
gtm_A_wideip['subPath'] = type_A_wideip.subPath
gtm_A_wideip.update(name=type_A_wideip_name, partition=type_A_wideip_partition, wideip_type='A',
poolLbMode=type_A_wideip.poolLbMode, persistence=type_A_wideip.persistence,
lastResortPool=type_A_wideip.lastResortPool, fullPath=type_A_wideip.fullPath)
# print(gtm_A_wideip)
if hasattr(type_A_wideip, 'pools'):
gtm_A_wideip['pools'] = []
for pool_name in type_A_wideip.pools:
gtm_A_pool = {}
# gtm_A_pool_name = pool_name['name']
gtm_A_pool['name'] = pool_name['name']
gtm_A_pool['partition'] = pool_name['partition']
gtm_A_pool['type'] = 'A'
gtm_A_pool['order'] = pool_name['order']
gtm_A_pool['ratio'] = pool_name['ratio']
if 'subPath' in pool_name.keys():
gtm_A_pool['subPath'] = pool_name['subPath']
gslb_A_pool = mgmt.tm.gtm.pools.a_s.a.load(name=pool_name['subPath'] + '~' + pool_name['name'], partition=pool_name['partition'])
# gslb_A_pool = mgmt.tm.gtm.pools.a_s.a.load(name=pool_name['subPath'] + '~' + pool_name['name'] if 'subPath' in pool_name.keys() else pool_name['name'], partition=pool_name['partition'])
else:
gslb_A_pool = mgmt.tm.gtm.pools.a_s.a.load(name=pool_name['name'], partition=pool_name['partition'])
gtm_A_pool['fullPath'] = gslb_A_pool.fullPath
gtm_A_pool['ttl'] = gslb_A_pool.ttl
gtm_A_pool['loadBalancingMode'] = gslb_A_pool.loadBalancingMode
gtm_A_pool['alternateMode'] = gslb_A_pool.alternateMode
gtm_A_pool['fallbackMode'] = gslb_A_pool.fallbackMode
gtm_A_pool['fallbackIp'] = gslb_A_pool.fallbackIp
gtm_A_pool['Members'] = []
# gslb_pool_members_vs_name_list = [str(mem.raw) for mem in gslb_A_pool.members_s.get_collection()]
gslb_pool_members_vs_fullPath_list = [(mem.memberOrder, mem.fullPath, mem.ratio) for mem in
gslb_A_pool.members_s.get_collection()]
for pool_memberOrder, pool_member_fullPath, pool_member_ratio in gslb_pool_members_vs_fullPath_list:
# print(pool_member_fullPath)
# "fullPath":"/Common/DC-2-GTM-ipv4:/Common/vs_cmcc_99_22"
gtm_server_name = pool_member_fullPath.split(':')[0]
gtm_pool_members_member_name = pool_member_fullPath.split(':')[1]
dc_gtm_virtualserver = mgmt.tm.gtm.servers.server.load(name=gtm_server_name.split('/')[2],
partition=gtm_server_name.split('/')[1])
virtualservers_virtualserver = dc_gtm_virtualserver.virtual_servers_s.virtual_server.load(
name=gtm_pool_members_member_name
)
virtualserver_destination = virtualservers_virtualserver.destination
virtualserver_Member_Address = virtualserver_destination.split(':')[0]
virtualserver_Service_Port = virtualserver_destination.split(':')[1]
gtm_A_pool['Members'].append({
'Member': gtm_pool_members_member_name,
'Member Order': pool_memberOrder,
'ratio': pool_member_ratio,
'Member Address': virtualserver_Member_Address,
'Service Port': virtualserver_Service_Port,
'Translation Address': virtualservers_virtualserver.translationAddress,
'Translation Service Port': virtualservers_virtualserver.translationPort
})
gtm_A_wideip['pools'].append(gtm_A_pool)
if hasattr(type_A_wideip, 'poolsCname'):
gtm_A_wideip['poolsCname'] = []
for pool_name in type_A_wideip.poolsCname:
gtm_A_cnamepool = {}
# gtm_A_pool_name = pool_name['name']
gtm_A_cnamepool['name'] = pool_name['name']
gtm_A_cnamepool['partition'] = pool_name['partition']
gtm_A_cnamepool['type'] = 'CNAME'
gtm_A_cnamepool['order'] = pool_name['order']
gtm_A_cnamepool['ratio'] = pool_name['ratio']
if 'subPath' in pool_name.keys():
gtm_A_cnamepool['subPath'] = pool_name['subPath']
gslb_A_cnamepool = mgmt.tm.gtm.pools.cnames.cname.load(name=pool_name['subPath'] + '~' + pool_name['name'], partition=pool_name['partition'])
else:
gslb_A_cnamepool = mgmt.tm.gtm.pools.cnames.cname.load(name=pool_name['name'], partition=pool_name['partition'])
gtm_A_cnamepool['fullPath'] = gslb_A_cnamepool.fullPath
gtm_A_cnamepool['ttl'] = gslb_A_cnamepool.ttl
gtm_A_cnamepool['loadBalancingMode'] = gslb_A_cnamepool.loadBalancingMode
gtm_A_cnamepool['alternateMode'] = gslb_A_cnamepool.alternateMode
gtm_A_cnamepool['fallbackMode'] = gslb_A_cnamepool.fallbackMode
gtm_A_cnamepool['Members'] = []
gslb_pool_members_domainname_fullPath_list = [(mem.name, mem.memberOrder, mem.fullPath, mem.ratio)
for mem in gslb_A_cnamepool.members_s.get_collection()]
for pool_member_name, pool_memberOrder, pool_member_fullPath, pool_member_ratio in gslb_pool_members_domainname_fullPath_list:
gtm_A_cnamepool['Members'].append({
'Member': pool_member_name,
'Member Order': pool_memberOrder,
'ratio': pool_member_ratio,
'fullPath': pool_member_fullPath
})
gtm_A_wideip['poolsCname'].append(gtm_A_cnamepool)
# print(gtm_A_wideip)
gtm_wideip.append(gtm_A_wideip)
# GTM AAAA Wideip
for i in mgmt.tm.gtm.wideips.aaaas.get_collection():
try:
type_AAAA_wideip = mgmt.tm.gtm.wideips.aaaas.aaaa.load(name=i.subPath + '~' + i.name if hasattr(i, 'subPath') else i.name, partition=i.partition)
except Exception as e:
print('type AAAA widip name {} error msg is '.format(i.name) + str(e))
else:
gtm_AAAA_wideip = {}
type_AAAA_wideip_name = i.name
type_AAAA_wideip_partition = i.partition
if hasattr(type_AAAA_wideip, 'aliases'):
gtm_AAAA_wideip['aliases'] = type_AAAA_wideip.aliases
if hasattr(type_AAAA_wideip, 'rules'):
gtm_AAAA_wideip['iRules'] = type_AAAA_wideip.rules
if hasattr(type_AAAA_wideip, 'enabled'):
gtm_AAAA_wideip['enabled'] = True
else:
gtm_AAAA_wideip['disabled'] = True
if hasattr(type_AAAA_wideip, 'subPath'):
gtm_AAAA_wideip['subPath'] = type_AAAA_wideip.subPath
gtm_AAAA_wideip.update(name=type_AAAA_wideip_name, partition=type_AAAA_wideip_partition, wideip_type='AAAA',
poolLbMode=type_AAAA_wideip.poolLbMode, persistence=type_AAAA_wideip.persistence,
lastResortPool=type_AAAA_wideip.lastResortPool, fullPath=type_AAAA_wideip.fullPath)
if hasattr(type_AAAA_wideip, 'pools'):
gtm_AAAA_wideip['pools'] = []
for pool_name in type_AAAA_wideip.pools:
gtm_AAAA_pool = {}
# gtm_A_pool_name = pool_name['name']
gtm_AAAA_pool['name'] = pool_name['name']
gtm_AAAA_pool['partition'] = pool_name['partition']
gtm_AAAA_pool['type'] = 'AAAA'
gtm_AAAA_pool['order'] = pool_name['order']
gtm_AAAA_pool['ratio'] = pool_name['ratio']
if 'subPath' in pool_name.keys():
gtm_AAAA_pool['subPath'] = pool_name['subPath']
gslb_AAAA_pool = mgmt.tm.gtm.pools.aaaas.aaaa.load(name=pool_name['subPath'] + '~' + pool_name['name'], partition=pool_name['partition'])
else:
gslb_AAAA_pool = mgmt.tm.gtm.pools.aaaas.aaaa.load(name=pool_name['name'], partition=pool_name['partition'])
gtm_AAAA_pool['fullPath'] = gslb_AAAA_pool.fullPath
gtm_AAAA_pool['ttl'] = gslb_AAAA_pool.ttl
gtm_AAAA_pool['loadBalancingMode'] = gslb_AAAA_pool.loadBalancingMode
gtm_AAAA_pool['alternateMode'] = gslb_AAAA_pool.alternateMode
gtm_AAAA_pool['fallbackMode'] = gslb_AAAA_pool.fallbackMode
gtm_AAAA_pool['fallbackIp'] = gslb_AAAA_pool.fallbackIp
gtm_AAAA_pool['Members'] = []
# gslb_pool_members_vs_name_list = [str(mem.raw) for mem in gslb_A_pool.members_s.get_collection()]
gslb_pool_members_vs_fullPath_list = [(mem.memberOrder, mem.fullPath, mem.ratio) for mem in
gslb_AAAA_pool.members_s.get_collection()]
for pool_memberOrder, pool_member_fullPath, pool_member_ratio in gslb_pool_members_vs_fullPath_list:
# print(pool_member_fullPath)
# "fullPath":"/Common/DC-2-GTM-ipv4:/Common/vs_cmcc_99_22"
gtm_server_name = pool_member_fullPath.split(':')[0]
gtm_pool_members_member_name = pool_member_fullPath.split(':')[1]
dc_gtm_virtualserver = mgmt.tm.gtm.servers.server.load(name=gtm_server_name.split('/')[2],
partition=gtm_server_name.split('/')[1])
virtualservers_virtualserver = dc_gtm_virtualserver.virtual_servers_s.virtual_server.load(
name=gtm_pool_members_member_name
)
virtualserver_destination = virtualservers_virtualserver.destination
virtualserver_Member_Address = virtualserver_destination.split('.')[0]
virtualserver_Service_Port = virtualserver_destination.split('.')[1]
gtm_AAAA_pool['Members'].append({
'Member': gtm_pool_members_member_name,
'Member Order': pool_memberOrder,
'ratio': pool_member_ratio,
'Member Address': virtualserver_Member_Address,
'Service Port': virtualserver_Service_Port,
'Translation Address': virtualservers_virtualserver.translationAddress,
'Translation Service Port': virtualservers_virtualserver.translationPort
})
gtm_AAAA_wideip['pools'].append(gtm_AAAA_pool)
if hasattr(type_AAAA_wideip, 'poolsCname'):
gtm_AAAA_wideip['poolsCname'] = []
for pool_name in type_AAAA_wideip.poolsCname:
gtm_AAAA_cnamepool = {}
gtm_AAAA_cnamepool['name'] = pool_name['name']
gtm_AAAA_cnamepool['partition'] = pool_name['partition']
gtm_AAAA_cnamepool['type'] = 'CNAME'
gtm_AAAA_cnamepool['order'] = pool_name['order']
gtm_AAAA_cnamepool['ratio'] = pool_name['ratio']
if 'subPath' in pool_name.keys():
gtm_AAAA_cnamepool['subPath'] = pool_name['subPath']
gslb_AAAA_cnamepool = mgmt.tm.gtm.pools.cnames.cname.load(name=pool_name['subPath'] + '~' + pool_name['name'], partition=pool_name['partition'])
else:
gslb_AAAA_cnamepool = mgmt.tm.gtm.pools.cnames.cname.load(name=pool_name['name'], partition=pool_name['partition'])
gtm_AAAA_cnamepool['fullPath'] = gslb_AAAA_cnamepool.fullPath
gtm_AAAA_cnamepool['ttl'] = gslb_AAAA_cnamepool.ttl
gtm_AAAA_cnamepool['loadBalancingMode'] = gslb_AAAA_cnamepool.loadBalancingMode
gtm_AAAA_cnamepool['alternateMode'] = gslb_AAAA_cnamepool.alternateMode
gtm_AAAA_cnamepool['fallbackMode'] = gslb_AAAA_cnamepool.fallbackMode
gtm_AAAA_cnamepool['Members'] = []
gslb_pool_members_domainname_fullPath_list = [(mem.name, mem.memberOrder, mem.fullPath, mem.ratio)
for mem in gslb_AAAA_cnamepool.members_s.get_collection()]
for pool_member_name, pool_memberOrder, pool_member_fullPath, pool_member_ratio in gslb_pool_members_domainname_fullPath_list:
gtm_AAAA_cnamepool['Members'].append({
'Member': pool_member_name,
'Member Order': pool_memberOrder,
'ratio': pool_member_ratio,
'fullPath': pool_member_fullPath
})
gtm_AAAA_wideip['poolsCname'].append(gtm_AAAA_cnamepool)
# print(gtm_AAAA_wideip)
gtm_wideip.append(gtm_AAAA_wideip)
gtm_networkmap = {}
gtm_networkmap.update(wideips=gtm_wideip)
print(gtm_networkmap)
with open(r"./F5-GTM-Wideip-{}-NetworkMap.json".format(time.strftime("%Y-%m-%d", time.localtime())), "w") as f:
f.write(json.dumps(gtm_networkmap, indent=4, ensure_ascii=False))