Python module to post and retrieve IControl Rest JSON objects for AVR statistics
Problem this snippet solves:
This module simplifies making Python dictionary objects that are converted to IControl rest AVR JSON objects. It also handles making AVR requests and retrieving results as well allowing multiple AVR requests to be queued, posted and retrieved. It also has some basis type checking for the elements of a AVR request. This module requires Bigip 12.1 on the target that statistics are retrieved.
How to use this snippet:
The main class is rest_avr.avr_req. It is a dictionary class that maps directly to an IControl Rest AVR JSON request as translated by json.dumps. Each dictionary element is an object derived from a customer class for each part of the request. The element classes have add() and clear() functions. if the element class only allows one entry the add() function will replace the existing entry, otherwise it will append the entry to the request element. The rest_avr.avr_req class also has functions to populate the HTTP host and authentication values for the target system.
rest_avr.avr_req.post_and_response
returns the Python representation of the JSON result of the query.
rest_avr.avr_req.add_to_queue()
adds the currently constructed request to a queue of requests to post.
rest_avr.avr_req.post_and_response_queue()
returns a python list of results of queued queries.
The following code sample constructs, posts and returns results for an AVR statistics request for specific DNS records and a specificrecord type, then queues multiple quests and posts and returns results.
#!/usr/bin/python
import json
import sys
import time
import rest_avr
#print rest_avr.ShowAVRJsonApi
#Populate the url
avr_dns_req=rest_avr.avr_req()
avr_dns_req.auth('admin','admin')
avr_dns_req.url_base('10.10.2.113','dns')
#Populate the json object
avr_dns_req['analyticsModule'].add('dns')
avr_dns_req['reportFeatures'].add('time-aggregated')
avr_dns_req['entityFilters'].add('domain-name', 'OPERATOR_TYPE_EQUAL', ['test2.test1.com','test1.test1.com'])
avr_dns_req['entityFilters'].add('query-type', 'OPERATOR_TYPE_EQUAL', ['a'])
avr_dns_req['viewMetrics'].add('packets')
avr_dns_req['viewDimensions'].add('domain-name')
avr_dns_req['metricFilters'].add('packets', 'OPERATOR_TYPE_GREATER_THAN', 0)
avr_dns_req['sortByMetrics'].add('packets', 'ascending')
avr_dns_req['pagination'].add(20, 0)
avr_dns_req['timeRange'].add(1461778251000000, None)
#Post and retrieve results.
result_py=avr_dns_req.post_and_response()
if result_py != None:
print ('\n' + result_py['results']['timeAggregated'][0]['dimensions'][0]['value'] + " " + result_py['results']['timeAggregated'][0]['metricValues'][0]['value'] + '\n')
else:
print result_py.error_layer
print result_py.error_code
print result_py.error_text
# Now add multiple requests to a queue
avr_dns_req.add_to_queue()
avr_dns_req['entityFilters'].clear()
avr_dns_req['entityFilters'].add('query-type', 'OPERATOR_TYPE_EQUAL', ['aaaa'])
avr_dns_req.add_to_queue()
#post and retrieve queued results
result_py_q=avr_dns_req.post_and_response_queue()
for result_py in result_py_q:
if result_py != None:
print ('\n' + result_py['results']['timeAggregated'][0]['dimensions'][0]['value'] + " " + result_py['results']['timeAggregated'][0]['metricValues'][0]['value'] + '\n')
else:
print result_py.error_layer
print result_py.error_code
print result_py.error_text
Code :
"""
rest_avr provides a python interface to Bigip AVR statistics using the REST API. The main Python rest_avr.avr_req
object is a Python dictionary that maps to a JSON object that can be processed with the json.dumps() function
An IControl Rest AVR JSON request and response can be initiated with avr_req.post_and_response
The simple description of the API can is available at avr_req.ShowJsonApi()
Each of these modules has a method to add single or multiple elements as appropriate to the specific module.
Once these elements are are populated a RestAPI request can be made with results returned as a python
representation.
avr_req.auth(user, passw)
avr_req.url_base(host, module)
avr_req['analyticsModule'].add(module)
avr_req['analyticsModule'].clear()
avr_req['reportFeatures'].add(metric_name, predicate, value)
avr_req['reportFeatures'].clear()
avr_req['entityFilters'].add(dimension_name, predicate, values)
avr_req['entityFilters'].clear()
avr_req['viewMetrics'].add(metric_name)
avr_req['viewMetrics'].clear()
avr_req['viewDimensions'].add(metric_name, order)
avr_req['viewDimensions'].clear()
avr_req['metricFilters'].add(metric_name, predicate, valu)
avr_req['metricFilters'].clear()
avr_req['sortByMetrics'].add(metric_name, orde)
avr_req['sortByMetrics'].clear()
avr_req['pagination'].add(num_results, skip_result)
avr_req['pagination'].clear()
avr_req['timeRange'].add(t_from, t_to)
avr_req['timeRange'].clear()
After a request in constructed a REST API call is initiated with initiated with:
avr_req.post_and_response()
The response is a python dictionary data structure of the results as processed by json.loads
"""
from copy import deepcopy
import requests
import json
import sys
import time
import warnings
__author__ = 'Mark Lloyd'
__version__ = '1.0'
# 05/24/2016
import json
import requests
import time
class BadDictElement(Exception):
def __init__(self, key, value, expl):
Exception.__init__(self, '{0} {1} {2} '.format(key, value, expl))
class BadTime(Exception):
def __init__(self, variable, value):
Exception.__init__(self, '{0} {1} should be 16 char decimal in microseconds '.format('a', 'b'))
class RequestFailure(Exception):
def __init__(self, key, value):
Exception.__init__(self, '{0} {1} '.format(key, value))
class analyticsModule(str):
"""
This class is tied to the structure of the parent class.
parent() get's the parent object so we can make the string pseudo-mutable.
accessed from within an avr request
['analyticsModule'].add(module)
Adds a single string to analyticsModule element . If one exists it is replaced.
['analyticsModule'].clear()
Send a null value to the analyticsModule element.
See rest_avr.ShowAVRJsonApi for more details
"""
def parent(self, parent):
self.parent = parent
def add(self, module):
"""
avr_req.['analyticsModule'].add(module)
Adds a single string to analyticsModule element . If one already exists it is replaced.
This should be the same as the module string in avr_req.url_base.
"""
self.parent['analyticsModule'] = analyticsModule(module)
self.parent['analyticsModule'].parent = self.parent
def clear(self):
"""
avr_req.['analyticsModule'].add(module)
replaces the analyticsModule mddule with a null string
"""
self.parent['analyticsModule'] = analyticsModule('')
self.parent['analyticsModule'].parent = self.parent
class metricFilters(list):
"""
avr_req.['metricFilters'].add(metric_name, predicate, value)
metric name is a string, value is an integer
Valid predicates strings are ['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN',
OPERATOR_TYPE_LOWER_THAN','OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL'])
avr_req['metricFilters'].clear()
Clears metricFilters elements
See rest_avr.ShowAVRJsonApi for more details.
"""
def __init__(self):
self.append([])
self.valid_metric_predicate = (
['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN', 'OPERATOR_TYPE_LOWER_THAN',
'OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL'])
def add(self, metric_name, predicate, value):
"""
avr_req.['metricFilters'].add(metric_name, predicate, value)
metric name is a string, value is an integer
Valid predicates strings are ['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN',
OPERATOR_TYPE_LOWER_THAN','OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL']
"""
if type(value) is not int:
raise BadDictElement(metric_name, value, 'value should be integer')
if predicate in self.valid_metric_predicate:
# first check if it is already there
for metric in self[0]:
if metric['metricName'] == metric_name:
metric['predicate'] = predicate
metric['value'] = value
return 0
# if it is not there then just add it.
self[0].append({'metricName': metric_name, 'predicate': predicate, 'value': value})
else:
raise BadDictElement(metric_name, predicate, 'invalid predicate')
def clear(self):
"""
avr_req['metricFilters'].clear()
Clears metricFilters elements
"""
del self[0][:]
class entityFilters(list):
"""
avr_req.['entityFilters'].add(dimension_name, predicate, values):
All values are strings
valid predicate is 'OPERATOR_TYPE_EQUAL'
['entityFilters'].clear()
Clears the entityFilters element
See rest_avr.ShowJsonApi for more details
"""
def __init__(self):
self.append([])
def add(self, dimension_name, predicate, values):
"""
avr_req.['entityFilters'].add(dimension_name, predicate, values):
All values are strings
valid predicate is 'OPERATOR_TYPE_EQUAL'
"""
if predicate is 'OPERATOR_TYPE_EQUAL':
# then loop throuth to see if the dimenson name already exists, if so replace
for entity in self[0]:
if entity['dimensionName'] == dimension_name:
entity['predicate'] = predicate
entity['values'] = values
return 0
# if it is not there then just add it.
self[0].append({'dimensionName': dimension_name, 'predicate': predicate, 'values': values})
else:
raise BadDictElement(dimension_name, predicate, 'predicate must be OPERATOR_TYPE_EQUAL')
def clear(self):
"""
['entityFilters'].clear()
Clears the entityFilters element
"""
del self[0][:]
class reportFeatures(list):
"""
avr_req.['reportFeatures'].add( feature)
adds report feature string. Multiple features are permitted.
['reportFeatures'].clear()
Clears the analyticsModule element.
See rest_avr.ShowAVRJsonApi for more details.
"""
def add(self, feature):
"""
avr_req.['reportFeatures'].add( feature)
adds report feature string. Multiple features are permitted
."""
if feature not in self:
self.append(feature)
def clear(self):
"""
['reportFeatures'].clear()
Clears the entityFilters element
"""
del self[:]
class sortByMetrics(list):
"""
avr_req.['sortByMetrics'].add(metric_name, order)
valid order names are 'ascending' and 'descending'
sortByMetrics is optional in an AVR request.
avr_req['sortByMetrics'].clear()
Clears the sortByMetrics element.
See rest_avr.ShowAVRJsonApi for more details.
"""
def __init__(self):
self.metric_list = []
def add(self, metric_name, order):
if metric_name not in self.metric_list:
self.append({'metricName': metric_name, 'order': order})
self.metric_list.append(metric_name)
def clear(self):
"""
['sortByMetrics'].clear()
Clears the sortByMetrics element
"""
del self[:]
del self.metric_list[:]
class viewDimensions(list):
"""
avr_req.['viewDimensions'].add(dimension_name):
adds view dimension, only one dimension is allowed
add will replace element if it already exists
avr_req['viewDimensions'].clear()
Clears the viewDimensions element.
See rest_avr.ShowAVRJsonApi for more details.
"""
def __init__(self):
self.append([])
self[0] = {}
def add(self, dimension_name):
"""
avr_req.['viewDimensions'].add(dimension_name):
adds view dimension string, only one dimension is allowed
add will replace element if it already exists
"""
self[0]['dimensionName'] = dimension_name
def clear(self, dimension_name):
"""
['viewDimensions'].clear()
Clears the viewDimensions element
"""
del self[0][:]
class viewMetrics(list):
"""
avr_req.['viewMetrics'].add(metric_name):
appends metric_name string to list. The specification
allows multiple view metric elements
avr_req['viewMetrics'].clear()
Clears the viewMetrics elements
See rest_avr.ShowAVRJsonApi for more details.
"""
def __init__(self):
self.metric_list = []
def add(self, metric_name):
"""
avr_req.['viewMetrics'].add(metric_name):
appends metric_name string to list. The specification
allows multiple viewMetric elements
"""
if metric_name not in self.metric_list:
self.append({'metricName': metric_name})
self.metric_list.append(metric_name)
def clear(self):
"""
['viewMetrics'].clear()
Clears the viewMetrics elements
"""
del self[:]
del self.metric_list[:]
class timeRange(dict):
"""
avr_req.['timeRange'].add( t_from, t_to)
both values are 16 digit numeric value in microseconds
of unix/linux time. t_to is optional and can be replace by None
timeRange is an optional.
avr_req['timeRange'].clear()
Clears the timeRange elements
See rest_avr.ShowAVRJsonApi for more details.
"""
def add(self, t_from, t_to):
"""
avr_req.['timeRange'].add( t_from, t_to)
both values are 16 digit numeric value in microseconds
of unix/linux time. t_to is optional and can be replace by None
timeRange is optional.
"""
if type(t_from) is long and len(str(t_from)) == 16:
self['from'] = t_from
else:
raise BadTime(t_from + " is 16 digit numeric value in microseconds")
if t_to != '' and t_to != 0 and t_to != None:
if type(t_to) is long and len(str(t_from)) == 16:
self['to'] = t_to
else:
raise BadTime(t_to + " is 16 digit numeric value in microseconds")
else:
if 'to' in self.keys():
del self['to']
def clear(self):
"""
['timeRange'].clear()
Clears the timeRange element
"""
del self[:]
class pagination(dict):
"""
avr_req.['pagination'].add(num_results, skip_results)
both are integer values.
avr_req['pagination'].clear()
Clears the pagination elements
See rest_avr.ShowAVRJsonApi for more details.
"""
def add(self, num_results, skip_results):
"""
avr_req.['pagination'].add(num_results, skip_results)
both arguments are integers.
"""
if type(num_results) is int:
self['numberOfResults'] = num_results
else:
raise BadDictElement('number of Results ', num_results, 'must be integer')
if type(skip_results) is int:
self['skipResults'] = skip_results
else:
raise BadDictElement('skipResults ', skip_results, 'must be integer')
def clear(self):
"""
['pagination'].clear()
Clears the pagination element
"""
del self[:]
class avr_resp(dict):
"""
python response error is applicable.
"""
def __init__(self):
self.error_layer = None
self.error_code = None
self.error_text = None
class avr_req(dict):
"""
The main class for rest_avr.
avr_req contains a dictionary that maps to the elements of a Icontrol REST AVR request along with capability of
posting that request and receiving a response.
The dictionary values are object instances of python classes that correspond to the the JSON values of the
object's name/value pair.
Each value has two public methods:
avr_req.['objectName']add(): adds an element to the appropriate object with type checking.
If an element allows more then one instance the add function will append the element
If an element allows only one instance the add function will replace the element
avr_req.['objectName'].clear()r: clears all elements in the object.
printing rest_avr.ShowAVRJsonApi provides documentation for the AVR JASON elements. Further documentation is
available on devcentral.f5.com
To post an AVR Rest request there are two functions to populate the HTTP/HTTPS request.
avr_req.auth(user, passw):
provides the username and password
avr_req.url_base(host, module)
provides the host and the bigip module AVR queries to construct the URL to make the request.
Then to post the request and return results in a python representation of the JSON response.
avr_req.post_and_response()
"""
def __init__(self):
self['analyticsModule'] = analyticsModule()
self['analyticsModule'].parent = self
self['pagination'] = pagination()
self['metricFilters'] = metricFilters()
self['entityFilters'] = entityFilters()
self['reportFeatures'] = reportFeatures()
self['sortByMetrics'] = sortByMetrics()
self['viewDimensions'] = viewDimensions()
self['viewMetrics'] = viewMetrics()
self['timeRange'] = timeRange()
self.avr_session = requests.session()
self.avr_session.verify = False
self.avr_session.headers.update({'Content-Type': 'application/json'})
# for multiple queued request handling.
self.req_queue = []
self.generate_id = None
self.done = None
self.result = None
self.num_requests = 0
self.res_queue = []
def post_and_response(self):
"""
returns a python representation of the json response to the request.
failure returns array ['ERROR','component',error]
"""
warnings.filterwarnings("ignore")
self.generate_request = self.avr_session.post(self.req_url_base + "/generate-report/",
data=json.dumps(self))
self.generate_request_py = json.loads(self.generate_request.text)
self.result_guid = self.generate_request_py['id']
self.results_status_url = self.req_url_base + "/generate-report/" + self.result_guid + "/?$select=status,reportResultsLink"
self.results_url = self.req_url_base + "/report-results/" + self.result_guid
self.sleeptime = .5
for i in range(5):
time.sleep(self.sleeptime)
self.sleeptime *= 2 # double backoff period each time.
self.status_results_json = self.avr_session.get(self.results_status_url)
self.status_results = json.loads(self.status_results_json.text)
if self.status_results['status'] == 'FAILED':
self.result = avr_resp()
self.result_error_layer = 'REST'
self.result_error_code = self.status_results['status']
self.result.error_text = self.status_results
if self.status_results['status'] == 'FINISHED':
self.raw_results_url = self.status_results['reportResultsLink']
self.results_url = self.raw_results_url.replace('localhost', self.host_name)
self.results = self.avr_session.get(self.results_url)
if self.results.status_code == 200:
self.result = avr_resp()
self.result.update(json.loads(self.results.text))
return self.result
else:
self.result = avr_resp()
self.result.error_layer = 'HTTP'
self.result.error_code = self.results.status_code
self.result.error_text = self.results
return self.result
else:
continue
self.result = avr_resp()
self.result.error_layer = 'REST_AVR'
self.result.error_code = '408'
self.result.error_text = 'TIMEOUT'
def auth(self, user, passw):
"""
avr_req.auth(user, passw):
username and password
"""
self.avr_session.auth = (user, passw)
def url_base(self, host, module):
"""
avr_req.url_base(host, module)
host and bigip module AVR queries to construct the URL to make the request.
"""
self.host_name = host
self.req_url_base = 'https://%s/mgmt/tm/analytics/%s' % (host, module)
self.module_py = {'analyticsModule': module}
def add_to_queue(self):
"adds request as currently constructed to queue"
self.req_queue.append(deepcopy(self))
def clear_queue(self):
""""
clears request queue
"""
del self.req_queue[:]
def post_and_response_queue(self):
"""
posts and sends response to from queue of requests.
"""
warnings.filterwarnings("ignore")
for req in self.req_queue:
req.generate_request = req.avr_session.post(req.req_url_base + "/generate-report/",
data=json.dumps(req))
req.generate_request_py = json.loads(req.generate_request.text)
req.generate_id = (req.generate_request_py['id'])
req.results_status_url = self.req_url_base + "/generate-report/" + req.generate_id + "/?$select=status,reportResultsLink"
self.sleeptime = .5
self.num_requests = len(self.req_queue)
for i in range(5):
for req in self.req_queue:
if req.done is None:
time.sleep(self.sleeptime)
self.sleeptime *= 2 # double backoff period each time.
req.status_results_json = req.avr_session.get(req.results_status_url)
req.status_results = json.loads(req.status_results_json.text)
if req.status_results['status'] == 'FAILED':
req.result = avr_resp()
req.result_error['layer'] = 'REST'
req.result_error['error'] = req.status_results['status']
req.result_error['text'] = req.status_results
if req.status_results['status'] == 'FINISHED':
req.raw_results_url = req.status_results['reportResultsLink']
req.results_url = req.raw_results_url.replace('localhost', self.host_name)
req.results = self.avr_session.get(req.results_url)
if req.results.status_code == 200:
req.result = avr_resp()
req.result.update(json.loads(req.results.text))
req.done = True
self.res_queue.append(req.result)
self.num_requests -= 1
else:
req.result = avr_resp()
req.result_error.layer = 'HTTP'
req.result_error.code = req.results.status_code
req.result_error.text = req.results
self.res_queue.append(req.result)
if i == 5:
if req.result == False:
req.result = avr_resp()
req.result.error_layer = 'REST_AVR'
req.result.error_error = '408'
req.result.error_text = 'TIMEOUT'
if self.num_requests == 0:
break
return self.res_queue
ShowAVRJsonApi = """
reportFeatures
--------------
Specifies the kind of information that appears in a
response from AVR. You may specify one or more of the
following values:
existing-entities
time-aggregated
time-series
entities-count
viewDimensions
--------------
Specifies the dimensions for which to calculate a report,
such as:
{"dimensionName": "domain-name"}
You may only specify a single dimension. You may omit
this field in a report generation request.
viewMetrics
-----------
Specifies the list of metrics by which to sort results, such
as:
{ "metricName": "average-tps" },
{ "metricName": "transactions" }
If you specify either time-aggregated or
time-series features, you must specify one metric in
a report generation request.
sortByMetrics
--------------
Specifies the list of metrics to sort by, such as:
[{ metricName: "average-tps", order:"descending" } ]
Valid values are ascending and descending. Sorting
only applies to the time-aggregated feature. You do
not need to specify this field in a report generation request.
timeRange
---------
Specifies the time range, in microseconds, for which to
calculate a report, such as:
{"from": 1410420888000000, "to": 1410424488000000 }
You do not need to specify this field in a report generation
request.
entityFilters
=============
Specifies the entities and values for which to calculate a
report. You can specify a single entity with a second level
of dimension filters that describe an aspect of the entity.
If you specify multiple entity types, the results include
only the entities that match all of the criteria. You do not
need to specify this field in a report generation request.
The following snippet contains two entities with
corresponding values:
[[{
"dimensionName" : "virtual",
"predicate": "OPERATOR_TYPE_EQUAL",
"values : ["phpAuction_VS_1"] },
{
"dimensionName : "response-code",
"predicate": "OPERATOR_TYPE_EQUAL",
"values" : ["200"] }
]]
metricFilters
-------------
Specifies the metric filters for which to calculate a report,
such as:
[{ "metricName": "transactions",
"predicate" :
metricFilters
"OPERATOR_TYPE_GREATER_THAN" "value":
100 }]
You do not need to specify this field in a report generation
request. For the existing-entities feature, AVR
supports the OPERATOR_TYPE_LIKE predicate. AVR also
supports the following predicates:
OPERATOR_TYPE_EQUAL
OPERATOR_TYPE_NOT_EQUAL
OPERATOR_TYPE_GREATER_THAN
OPERATOR_TYPE_LOWER_THAN
OPERATOR_TYPE_GREATER_THAN_OR_EQUAL
OPERATOR_TYPE_LOWER_THAN_OR_EQUAL
pagination
----------
Specifies the number of results to return, and the number
of results to skip, such as:
{ numberOfResults : 10, skipResults : 10}
To see the second set of ten results, use the example
shown here. AVR does not implement the OData query
parameters top or skip. In order to see a specific set of
results, you must set the number of results to return and
then determine how many results to skip. You do not need
to specify this field in a report generation request.
"""
Could you please help me find the rest_avr library? Also, could you confirm whether the script is working correctly? I would really appreciate your assistance with this!
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Beta_Footer\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"board:codeshare\",\"message:290993\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/codeshare/python-module-to-post-and-retrieve-icontrol-rest-json-objects-for-avr-statistics/290993\"}}})":{"__typename":"ComponentRenderResult","html":" "}},"componentScriptGroups({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"board:codeshare\",\"message:290993\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/codeshare/python-module-to-post-and-retrieve-icontrol-rest-json-objects-for-avr-statistics/290993\"}}})":{"__typename":"ComponentRenderResult","html":""}},"componentScriptGroups({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageView/MessageViewStandard\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/ThreadedReplyList\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyCallToAction\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/guides/GuideBottomNavigation\"]})":[{"__ref":"CachedAsset:text:en_US-components/guides/GuideBottomNavigation-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/customComponent/CustomComponent\"]})":[{"__ref":"CachedAsset:text:en_US-components/customComponent/CustomComponent-1743097589715"}],"message({\"id\":\"message:337897\"})":{"__ref":"TkbReplyMessage:message:337897"},"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1743097589715"}],"cachedText({\"lastModified\":\"1743097589715\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1743097589715"}]},"CachedAsset:pages-1742464555655":{"__typename":"CachedAsset","id":"pages-1742464555655","value":[{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.MvpProgram","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/mvp-program","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.AdvocacyProgram","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/advocacy-program","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetHelp.NonCustomer","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/non-customer","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetHelp.F5Customer","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/f5-customer","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetInvolved","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.Learn","type":"COMMUNITY","urlPath":"/c/how-do-i/learn","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1739501996000,"localOverride":null,"page":{"id":"Test","type":"CUSTOM","urlPath":"/custom-test-2","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetHelp.Community","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/community","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.ContributeCode","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/contribute-code","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.Learn.AboutIrules","type":"COMMUNITY","urlPath":"/c/how-do-i/learn/about-irules","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetHelp.F5Support","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/f5-support","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetHelp","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI.GetHelp.SecurityIncident","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/security-incident","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1742464555655,"localOverride":null,"page":{"id":"HowDoI","type":"COMMUNITY","urlPath":"/c/how-do-i","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Former Member","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"dd-MMM-yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":null,"possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bi04Ny0xOTQ1NWk4ODNCOUNEMkFDNDZCQjI0\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bi04Ny0xOTQ1NWk4ODNCOUNEMkFDNDZCQjI0","mimeType":"image/png"},"Category:category:CrowdSRC":{"__typename":"Category","id":"category:CrowdSRC","entityType":"CATEGORY","displayId":"CrowdSRC","nodeType":"category","depth":1,"title":"CrowdSRC","shortTitle":"CrowdSRC","parent":{"__ref":"Category:category:top"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top","entityType":"CATEGORY","shortTitle":"Top"},"Tkb:board:codeshare":{"__typename":"Tkb","id":"board:codeshare","entityType":"TKB","displayId":"codeshare","nodeType":"board","depth":2,"conversationStyle":"TKB","title":"CodeShare","description":"Have some code. Share some code.","avatar":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bi04Ny0xOTQ1NWk4ODNCOUNEMkFDNDZCQjI0\"}"},"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:CrowdSRC"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:zihoc95639"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:CrowdSRC"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}},"canReadNode":{"__typename":"PolicyResult","failureReason":null}},"shortTitle":"CodeShare","isManualSortOrderAvailable":false,"tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"repliesProperties":{"__typename":"RepliesProperties","sortOrder":"PUBLISH_TIME","repliesFormat":"threaded"},"eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/","tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"FREEFORM_AND_PRESET"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMjgtQ3U0RXo2\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/cmstMjgtQ3U0RXo2","height":0,"width":0,"mimeType":"image/svg+xml"},"Rank:rank:28":{"__typename":"Rank","id":"rank:28","position":5,"name":"Employee","color":"C20025","icon":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMjgtQ3U0RXo2\"}"},"rankStyle":"OUTLINE"},"User:user:195323":{"__typename":"User","id":"user:195323","uid":195323,"login":"Mark_Lloyd","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-7.svg?time=0"},"rank":{"__ref":"Rank:rank:28"},"email":"","messagesCount":5,"biography":null,"topicsCount":5,"kudosReceivedCount":4,"kudosGivenCount":0,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2011-05-25T01:00:00.000-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":0},"TkbTopicMessage:message:290993":{"__typename":"TkbTopicMessage","uid":290993,"subject":"Python module to post and retrieve IControl Rest JSON objects for AVR statistics","id":"message:290993","revisionNum":2,"repliesCount":1,"author":{"__ref":"User:user:195323"},"depth":0,"hasGivenKudo":false,"helpful":null,"board":{"__ref":"Tkb:board:codeshare"},"conversation":{"__ref":"Conversation:conversation:290993"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:290993"},"teaser":"","body":"
Problem this snippet solves:
This module simplifies making Python dictionary objects that are converted to IControl rest AVR JSON objects. It also handles making AVR requests and retrieving results as well allowing multiple AVR requests to be queued, posted and retrieved. It also has some basis type checking for the elements of a AVR request. This module requires Bigip 12.1 on the target that statistics are retrieved.
How to use this snippet:
The main class is rest_avr.avr_req. It is a dictionary class that maps directly to an IControl Rest AVR JSON request as translated by json.dumps. Each dictionary element is an object derived from a customer class for each part of the request. The element classes have add() and clear() functions. if the element class only allows one entry the add() function will replace the existing entry, otherwise it will append the entry to the request element. The rest_avr.avr_req class also has functions to populate the HTTP host and authentication values for the target system.
\n
rest_avr.avr_req.post_and_response
returns the Python representation of the JSON result of the query.\n
rest_avr.avr_req.add_to_queue()
adds the currently constructed request to a queue of requests to post.\n
rest_avr.avr_req.post_and_response_queue()
returns a python list of results of queued queries. \n
The following code sample constructs, posts and returns results for an AVR statistics request for specific DNS records and a specificrecord type, then queues multiple quests and posts and returns results.
\n
#!/usr/bin/python\nimport json\nimport sys\nimport time\nimport rest_avr\n\n#print rest_avr.ShowAVRJsonApi\n\n#Populate the url\n\navr_dns_req=rest_avr.avr_req()\navr_dns_req.auth('admin','admin')\navr_dns_req.url_base('10.10.2.113','dns')\n\n#Populate the json object\n\navr_dns_req['analyticsModule'].add('dns')\navr_dns_req['reportFeatures'].add('time-aggregated')\navr_dns_req['entityFilters'].add('domain-name', 'OPERATOR_TYPE_EQUAL', ['test2.test1.com','test1.test1.com'])\navr_dns_req['entityFilters'].add('query-type', 'OPERATOR_TYPE_EQUAL', ['a'])\navr_dns_req['viewMetrics'].add('packets')\navr_dns_req['viewDimensions'].add('domain-name')\navr_dns_req['metricFilters'].add('packets', 'OPERATOR_TYPE_GREATER_THAN', 0)\navr_dns_req['sortByMetrics'].add('packets', 'ascending')\navr_dns_req['pagination'].add(20, 0)\navr_dns_req['timeRange'].add(1461778251000000, None)\n\n#Post and retrieve results.\n\nresult_py=avr_dns_req.post_and_response()\n\nif result_py != None:\n print ('\\n' + result_py['results']['timeAggregated'][0]['dimensions'][0]['value'] + \" \" + result_py['results']['timeAggregated'][0]['metricValues'][0]['value'] + '\\n')\n\nelse:\n print result_py.error_layer\n print result_py.error_code\n print result_py.error_text\n\n# Now add multiple requests to a queue\navr_dns_req.add_to_queue()\n\navr_dns_req['entityFilters'].clear()\navr_dns_req['entityFilters'].add('query-type', 'OPERATOR_TYPE_EQUAL', ['aaaa'])\navr_dns_req.add_to_queue()\n\n#post and retrieve queued results\nresult_py_q=avr_dns_req.post_and_response_queue()\n\nfor result_py in result_py_q:\n\n if result_py != None:\n print ('\\n' + result_py['results']['timeAggregated'][0]['dimensions'][0]['value'] + \" \" + result_py['results']['timeAggregated'][0]['metricValues'][0]['value'] + '\\n')\n else:\n print result_py.error_layer\n print result_py.error_code\n print result_py.error_text\n
Code :
\"\"\"\nrest_avr provides a python interface to Bigip AVR statistics using the REST API. The main Python rest_avr.avr_req\nobject is a Python dictionary that maps to a JSON object that can be processed with the json.dumps() function\n\nAn IControl Rest AVR JSON request and response can be initiated with avr_req.post_and_response\n\nThe simple description of the API can is available at avr_req.ShowJsonApi()\n\nEach of these modules has a method to add single or multiple elements as appropriate to the specific module.\nOnce these elements are are populated a RestAPI request can be made with results returned as a python\nrepresentation.\n\n\navr_req.auth(user, passw)\navr_req.url_base(host, module)\n\navr_req['analyticsModule'].add(module)\navr_req['analyticsModule'].clear()\n\navr_req['reportFeatures'].add(metric_name, predicate, value)\navr_req['reportFeatures'].clear()\n\navr_req['entityFilters'].add(dimension_name, predicate, values)\navr_req['entityFilters'].clear()\n\navr_req['viewMetrics'].add(metric_name)\navr_req['viewMetrics'].clear()\n\navr_req['viewDimensions'].add(metric_name, order)\navr_req['viewDimensions'].clear()\n\navr_req['metricFilters'].add(metric_name, predicate, valu)\navr_req['metricFilters'].clear()\n\navr_req['sortByMetrics'].add(metric_name, orde)\navr_req['sortByMetrics'].clear()\n\navr_req['pagination'].add(num_results, skip_result)\navr_req['pagination'].clear()\n\navr_req['timeRange'].add(t_from, t_to)\navr_req['timeRange'].clear()\n\n\nAfter a request in constructed a REST API call is initiated with initiated with:\n\navr_req.post_and_response()\n\nThe response is a python dictionary data structure of the results as processed by json.loads\n\n\"\"\"\n\n\n\nfrom copy import deepcopy\nimport requests\nimport json\nimport sys\nimport time\nimport warnings\n\n__author__ = 'Mark Lloyd'\n__version__ = '1.0'\n\n# 05/24/2016\nimport json\nimport requests\nimport time\n\n\nclass BadDictElement(Exception):\n def __init__(self, key, value, expl):\n Exception.__init__(self, '{0} {1} {2} '.format(key, value, expl))\n\n\nclass BadTime(Exception):\n def __init__(self, variable, value):\n Exception.__init__(self, '{0} {1} should be 16 char decimal in microseconds '.format('a', 'b'))\n\n\nclass RequestFailure(Exception):\n def __init__(self, key, value):\n Exception.__init__(self, '{0} {1} '.format(key, value))\n\n\nclass analyticsModule(str):\n \"\"\"\n This class is tied to the structure of the parent class.\n parent() get's the parent object so we can make the string pseudo-mutable.\n accessed from within an avr request\n\n ['analyticsModule'].add(module)\n Adds a single string to analyticsModule element . If one exists it is replaced.\n\n ['analyticsModule'].clear()\n Send a null value to the analyticsModule element.\n\n See rest_avr.ShowAVRJsonApi for more details\n\n\n \"\"\"\n\n def parent(self, parent):\n self.parent = parent\n\n def add(self, module):\n \"\"\"\n avr_req.['analyticsModule'].add(module)\n Adds a single string to analyticsModule element . If one already exists it is replaced.\n This should be the same as the module string in avr_req.url_base.\n \"\"\"\n self.parent['analyticsModule'] = analyticsModule(module)\n self.parent['analyticsModule'].parent = self.parent\n\n def clear(self):\n \"\"\"\n avr_req.['analyticsModule'].add(module)\n replaces the analyticsModule mddule with a null string\n \"\"\"\n self.parent['analyticsModule'] = analyticsModule('')\n self.parent['analyticsModule'].parent = self.parent\n\n\nclass metricFilters(list):\n \"\"\"\n avr_req.['metricFilters'].add(metric_name, predicate, value)\n\n metric name is a string, value is an integer\n\n Valid predicates strings are ['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN',\n OPERATOR_TYPE_LOWER_THAN','OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL'])\n\n avr_req['metricFilters'].clear()\n Clears metricFilters elements\n\n See rest_avr.ShowAVRJsonApi for more details.\n\n \"\"\"\n\n def __init__(self):\n self.append([])\n self.valid_metric_predicate = (\n ['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN', 'OPERATOR_TYPE_LOWER_THAN',\n 'OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL'])\n\n def add(self, metric_name, predicate, value):\n \"\"\"\n avr_req.['metricFilters'].add(metric_name, predicate, value)\n\n metric name is a string, value is an integer\n\n Valid predicates strings are ['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN',\n OPERATOR_TYPE_LOWER_THAN','OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL']\n \"\"\"\n\n if type(value) is not int:\n raise BadDictElement(metric_name, value, 'value should be integer')\n\n if predicate in self.valid_metric_predicate:\n # first check if it is already there\n for metric in self[0]:\n if metric['metricName'] == metric_name:\n metric['predicate'] = predicate\n metric['value'] = value\n return 0\n # if it is not there then just add it.\n self[0].append({'metricName': metric_name, 'predicate': predicate, 'value': value})\n else:\n raise BadDictElement(metric_name, predicate, 'invalid predicate')\n\n def clear(self):\n \"\"\"\n avr_req['metricFilters'].clear()\n Clears metricFilters elements\n \"\"\"\n del self[0][:]\n\n\nclass entityFilters(list):\n \"\"\"\n avr_req.['entityFilters'].add(dimension_name, predicate, values):\n All values are strings\n valid predicate is 'OPERATOR_TYPE_EQUAL'\n\n ['entityFilters'].clear()\n Clears the entityFilters element\n\n See rest_avr.ShowJsonApi for more details\n \"\"\"\n\n def __init__(self):\n self.append([])\n\n def add(self, dimension_name, predicate, values):\n \"\"\"\n avr_req.['entityFilters'].add(dimension_name, predicate, values):\n All values are strings\n valid predicate is 'OPERATOR_TYPE_EQUAL'\n \"\"\"\n if predicate is 'OPERATOR_TYPE_EQUAL':\n # then loop throuth to see if the dimenson name already exists, if so replace\n for entity in self[0]:\n if entity['dimensionName'] == dimension_name:\n entity['predicate'] = predicate\n entity['values'] = values\n return 0\n # if it is not there then just add it.\n self[0].append({'dimensionName': dimension_name, 'predicate': predicate, 'values': values})\n\n else:\n raise BadDictElement(dimension_name, predicate, 'predicate must be OPERATOR_TYPE_EQUAL')\n\n def clear(self):\n \"\"\"\n ['entityFilters'].clear()\n Clears the entityFilters element\n \"\"\"\n del self[0][:]\n\n\nclass reportFeatures(list):\n \"\"\"\n avr_req.['reportFeatures'].add( feature)\n adds report feature string. Multiple features are permitted.\n\n ['reportFeatures'].clear()\n Clears the analyticsModule element.\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def add(self, feature):\n \"\"\"\n avr_req.['reportFeatures'].add( feature)\n adds report feature string. Multiple features are permitted\n .\"\"\"\n if feature not in self:\n self.append(feature)\n\n def clear(self):\n \"\"\"\n ['reportFeatures'].clear()\n Clears the entityFilters element\n \"\"\"\n del self[:]\n\n\nclass sortByMetrics(list):\n \"\"\"\n avr_req.['sortByMetrics'].add(metric_name, order)\n\n valid order names are 'ascending' and 'descending'\n sortByMetrics is optional in an AVR request.\n\n avr_req['sortByMetrics'].clear()\n Clears the sortByMetrics element.\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def __init__(self):\n self.metric_list = []\n\n def add(self, metric_name, order):\n if metric_name not in self.metric_list:\n self.append({'metricName': metric_name, 'order': order})\n self.metric_list.append(metric_name)\n\n def clear(self):\n \"\"\"\n ['sortByMetrics'].clear()\n Clears the sortByMetrics element\n \"\"\"\n del self[:]\n del self.metric_list[:]\n\n\nclass viewDimensions(list):\n \"\"\"\n avr_req.['viewDimensions'].add(dimension_name):\n adds view dimension, only one dimension is allowed\n add will replace element if it already exists\n\n avr_req['viewDimensions'].clear()\n Clears the viewDimensions element.\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def __init__(self):\n self.append([])\n self[0] = {}\n\n def add(self, dimension_name):\n \"\"\"\n avr_req.['viewDimensions'].add(dimension_name):\n adds view dimension string, only one dimension is allowed\n add will replace element if it already exists\n \"\"\"\n self[0]['dimensionName'] = dimension_name\n\n def clear(self, dimension_name):\n \"\"\"\n ['viewDimensions'].clear()\n Clears the viewDimensions element\n \"\"\"\n del self[0][:]\n\n\nclass viewMetrics(list):\n \"\"\"\n avr_req.['viewMetrics'].add(metric_name):\n appends metric_name string to list. The specification\n allows multiple view metric elements\n\n avr_req['viewMetrics'].clear()\n Clears the viewMetrics elements\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def __init__(self):\n self.metric_list = []\n\n def add(self, metric_name):\n \"\"\"\n avr_req.['viewMetrics'].add(metric_name):\n appends metric_name string to list. The specification\n allows multiple viewMetric elements\n \"\"\"\n\n if metric_name not in self.metric_list:\n self.append({'metricName': metric_name})\n self.metric_list.append(metric_name)\n\n def clear(self):\n \"\"\"\n ['viewMetrics'].clear()\n Clears the viewMetrics elements\n \"\"\"\n del self[:]\n del self.metric_list[:]\n\n\nclass timeRange(dict):\n \"\"\"\n avr_req.['timeRange'].add( t_from, t_to)\n both values are 16 digit numeric value in microseconds\n of unix/linux time. t_to is optional and can be replace by None\n\n timeRange is an optional.\n\n avr_req['timeRange'].clear()\n Clears the timeRange elements\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def add(self, t_from, t_to):\n \"\"\"\n avr_req.['timeRange'].add( t_from, t_to)\n both values are 16 digit numeric value in microseconds\n of unix/linux time. t_to is optional and can be replace by None\n\n timeRange is optional.\n \"\"\"\n if type(t_from) is long and len(str(t_from)) == 16:\n self['from'] = t_from\n else:\n raise BadTime(t_from + \" is 16 digit numeric value in microseconds\")\n\n if t_to != '' and t_to != 0 and t_to != None:\n if type(t_to) is long and len(str(t_from)) == 16:\n self['to'] = t_to\n else:\n raise BadTime(t_to + \" is 16 digit numeric value in microseconds\")\n else:\n if 'to' in self.keys():\n del self['to']\n\n def clear(self):\n \"\"\"\n ['timeRange'].clear()\n Clears the timeRange element\n \"\"\"\n del self[:]\n\n\nclass pagination(dict):\n \"\"\"\n avr_req.['pagination'].add(num_results, skip_results)\n both are integer values.\n\n avr_req['pagination'].clear()\n Clears the pagination elements\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def add(self, num_results, skip_results):\n \"\"\"\n avr_req.['pagination'].add(num_results, skip_results)\n both arguments are integers.\n \"\"\"\n if type(num_results) is int:\n self['numberOfResults'] = num_results\n else:\n raise BadDictElement('number of Results ', num_results, 'must be integer')\n if type(skip_results) is int:\n self['skipResults'] = skip_results\n else:\n raise BadDictElement('skipResults ', skip_results, 'must be integer')\n\n def clear(self):\n \"\"\"\n ['pagination'].clear()\n Clears the pagination element\n \"\"\"\n del self[:]\n\n\nclass avr_resp(dict):\n \"\"\"\n python response error is applicable.\n \"\"\"\n\n def __init__(self):\n self.error_layer = None\n self.error_code = None\n self.error_text = None\n\nclass avr_req(dict):\n \"\"\"\n The main class for rest_avr.\n\n avr_req contains a dictionary that maps to the elements of a Icontrol REST AVR request along with capability of\n posting that request and receiving a response.\n\n The dictionary values are object instances of python classes that correspond to the the JSON values of the\n object's name/value pair.\n\n Each value has two public methods:\n\n avr_req.['objectName']add(): adds an element to the appropriate object with type checking.\n If an element allows more then one instance the add function will append the element\n If an element allows only one instance the add function will replace the element\n\n avr_req.['objectName'].clear()r: clears all elements in the object.\n\n printing rest_avr.ShowAVRJsonApi provides documentation for the AVR JASON elements. Further documentation is\n available on devcentral.f5.com\n\n To post an AVR Rest request there are two functions to populate the HTTP/HTTPS request.\n\n avr_req.auth(user, passw):\n provides the username and password\n avr_req.url_base(host, module)\n provides the host and the bigip module AVR queries to construct the URL to make the request.\n\n Then to post the request and return results in a python representation of the JSON response.\n\n avr_req.post_and_response()\n\n \"\"\"\n\n def __init__(self):\n self['analyticsModule'] = analyticsModule()\n self['analyticsModule'].parent = self\n self['pagination'] = pagination()\n self['metricFilters'] = metricFilters()\n self['entityFilters'] = entityFilters()\n self['reportFeatures'] = reportFeatures()\n self['sortByMetrics'] = sortByMetrics()\n self['viewDimensions'] = viewDimensions()\n self['viewMetrics'] = viewMetrics()\n self['timeRange'] = timeRange()\n\n self.avr_session = requests.session()\n self.avr_session.verify = False\n self.avr_session.headers.update({'Content-Type': 'application/json'})\n\n # for multiple queued request handling.\n self.req_queue = []\n self.generate_id = None\n self.done = None\n self.result = None\n self.num_requests = 0\n self.res_queue = []\n\n def post_and_response(self):\n \"\"\"\n returns a python representation of the json response to the request.\n failure returns array ['ERROR','component',error]\n \"\"\"\n\n warnings.filterwarnings(\"ignore\")\n self.generate_request = self.avr_session.post(self.req_url_base + \"/generate-report/\",\n data=json.dumps(self))\n self.generate_request_py = json.loads(self.generate_request.text)\n self.result_guid = self.generate_request_py['id']\n self.results_status_url = self.req_url_base + \"/generate-report/\" + self.result_guid + \"/?$select=status,reportResultsLink\"\n self.results_url = self.req_url_base + \"/report-results/\" + self.result_guid\n self.sleeptime = .5\n for i in range(5):\n time.sleep(self.sleeptime)\n self.sleeptime *= 2 # double backoff period each time.\n\n self.status_results_json = self.avr_session.get(self.results_status_url)\n self.status_results = json.loads(self.status_results_json.text)\n\n if self.status_results['status'] == 'FAILED':\n self.result = avr_resp()\n self.result_error_layer = 'REST'\n self.result_error_code = self.status_results['status']\n self.result.error_text = self.status_results\n\n if self.status_results['status'] == 'FINISHED':\n self.raw_results_url = self.status_results['reportResultsLink']\n self.results_url = self.raw_results_url.replace('localhost', self.host_name)\n self.results = self.avr_session.get(self.results_url)\n\n if self.results.status_code == 200:\n self.result = avr_resp()\n self.result.update(json.loads(self.results.text))\n return self.result\n else:\n self.result = avr_resp()\n self.result.error_layer = 'HTTP'\n self.result.error_code = self.results.status_code\n self.result.error_text = self.results\n return self.result\n\n else:\n\n continue\n\n self.result = avr_resp()\n self.result.error_layer = 'REST_AVR'\n self.result.error_code = '408'\n self.result.error_text = 'TIMEOUT'\n\n\n def auth(self, user, passw):\n \"\"\"\n avr_req.auth(user, passw):\n username and password\n \"\"\"\n self.avr_session.auth = (user, passw)\n\n def url_base(self, host, module):\n \"\"\"\n avr_req.url_base(host, module)\n host and bigip module AVR queries to construct the URL to make the request.\n \"\"\"\n self.host_name = host\n self.req_url_base = 'https://%s/mgmt/tm/analytics/%s' % (host, module)\n self.module_py = {'analyticsModule': module}\n\n def add_to_queue(self):\n \"adds request as currently constructed to queue\"\n self.req_queue.append(deepcopy(self))\n\n def clear_queue(self):\n \"\"\"\"\n clears request queue\n \"\"\"\n del self.req_queue[:]\n\n def post_and_response_queue(self):\n \"\"\"\n posts and sends response to from queue of requests.\n \"\"\"\n warnings.filterwarnings(\"ignore\")\n for req in self.req_queue:\n req.generate_request = req.avr_session.post(req.req_url_base + \"/generate-report/\",\n data=json.dumps(req))\n req.generate_request_py = json.loads(req.generate_request.text)\n req.generate_id = (req.generate_request_py['id'])\n req.results_status_url = self.req_url_base + \"/generate-report/\" + req.generate_id + \"/?$select=status,reportResultsLink\"\n\n self.sleeptime = .5\n self.num_requests = len(self.req_queue)\n\n for i in range(5):\n\n for req in self.req_queue:\n\n if req.done is None:\n\n time.sleep(self.sleeptime)\n self.sleeptime *= 2 # double backoff period each time.\n req.status_results_json = req.avr_session.get(req.results_status_url)\n req.status_results = json.loads(req.status_results_json.text)\n\n if req.status_results['status'] == 'FAILED':\n req.result = avr_resp()\n req.result_error['layer'] = 'REST'\n req.result_error['error'] = req.status_results['status']\n req.result_error['text'] = req.status_results\n if req.status_results['status'] == 'FINISHED':\n req.raw_results_url = req.status_results['reportResultsLink']\n req.results_url = req.raw_results_url.replace('localhost', self.host_name)\n req.results = self.avr_session.get(req.results_url)\n if req.results.status_code == 200:\n req.result = avr_resp()\n req.result.update(json.loads(req.results.text))\n req.done = True\n self.res_queue.append(req.result)\n self.num_requests -= 1\n\n else:\n\n req.result = avr_resp()\n req.result_error.layer = 'HTTP'\n req.result_error.code = req.results.status_code\n req.result_error.text = req.results\n self.res_queue.append(req.result)\n if i == 5:\n if req.result == False:\n req.result = avr_resp()\n req.result.error_layer = 'REST_AVR'\n req.result.error_error = '408'\n req.result.error_text = 'TIMEOUT'\n\n\n if self.num_requests == 0:\n break\n\n\n\n return self.res_queue\n\n\nShowAVRJsonApi = \"\"\"\nreportFeatures\n--------------\nSpecifies the kind of information that appears in a\nresponse from AVR. You may specify one or more of the\nfollowing values:\n\nexisting-entities\ntime-aggregated\ntime-series\nentities-count\n\nviewDimensions\n--------------\nSpecifies the dimensions for which to calculate a report,\nsuch as:\n\n{\"dimensionName\": \"domain-name\"}\n\nYou may only specify a single dimension. You may omit\nthis field in a report generation request.\n\nviewMetrics\n-----------\nSpecifies the list of metrics by which to sort results, such\nas:\n\n{ \"metricName\": \"average-tps\" },\n{ \"metricName\": \"transactions\" }\n\nIf you specify either time-aggregated or\ntime-series features, you must specify one metric in\na report generation request.\n\nsortByMetrics\n--------------\nSpecifies the list of metrics to sort by, such as:\n[{ metricName: \"average-tps\", order:\"descending\" } ]\n\nValid values are ascending and descending. Sorting\nonly applies to the time-aggregated feature. You do\nnot need to specify this field in a report generation request.\n\ntimeRange\n---------\nSpecifies the time range, in microseconds, for which to\ncalculate a report, such as:\n\n{\"from\": 1410420888000000, \"to\": 1410424488000000 }\n\nYou do not need to specify this field in a report generation\nrequest.\n\nentityFilters\n=============\nSpecifies the entities and values for which to calculate a\nreport. You can specify a single entity with a second level\nof dimension filters that describe an aspect of the entity.\nIf you specify multiple entity types, the results include\nonly the entities that match all of the criteria. You do not\nneed to specify this field in a report generation request.\nThe following snippet contains two entities with\ncorresponding values:\n\n[[{\n\"dimensionName\" : \"virtual\",\n\"predicate\": \"OPERATOR_TYPE_EQUAL\",\n\"values : [\"phpAuction_VS_1\"] },\n{\n\"dimensionName : \"response-code\",\n\"predicate\": \"OPERATOR_TYPE_EQUAL\",\n\"values\" : [\"200\"] }\n]]\n\nmetricFilters\n-------------\nSpecifies the metric filters for which to calculate a report,\nsuch as:\n\n[{ \"metricName\": \"transactions\",\n\"predicate\" :\nmetricFilters\n\"OPERATOR_TYPE_GREATER_THAN\" \"value\":\n100 }]\n\nYou do not need to specify this field in a report generation\nrequest. For the existing-entities feature, AVR\nsupports the OPERATOR_TYPE_LIKE predicate. AVR also\nsupports the following predicates:\n\nOPERATOR_TYPE_EQUAL\nOPERATOR_TYPE_NOT_EQUAL\nOPERATOR_TYPE_GREATER_THAN\nOPERATOR_TYPE_LOWER_THAN\nOPERATOR_TYPE_GREATER_THAN_OR_EQUAL\nOPERATOR_TYPE_LOWER_THAN_OR_EQUAL\n\npagination\n----------\nSpecifies the number of results to return, and the number\nof results to skip, such as:\n\n{ numberOfResults : 10, skipResults : 10}\n\nTo see the second set of ten results, use the example\nshown here. AVR does not implement the OData query\nparameters top or skip. In order to see a specific set of\nresults, you must set the number of results to return and\nthen determine how many results to skip. You do not need\nto specify this field in a report generation request.\n\"\"\"
Tested this on version:
12.0","body@stringLength":"27586","rawBody":"
Problem this snippet solves:
This module simplifies making Python dictionary objects that are converted to IControl rest AVR JSON objects. It also handles making AVR requests and retrieving results as well allowing multiple AVR requests to be queued, posted and retrieved. It also has some basis type checking for the elements of a AVR request. This module requires Bigip 12.1 on the target that statistics are retrieved.
How to use this snippet:
The main class is rest_avr.avr_req. It is a dictionary class that maps directly to an IControl Rest AVR JSON request as translated by json.dumps. Each dictionary element is an object derived from a customer class for each part of the request. The element classes have add() and clear() functions. if the element class only allows one entry the add() function will replace the existing entry, otherwise it will append the entry to the request element. The rest_avr.avr_req class also has functions to populate the HTTP host and authentication values for the target system.
\n
rest_avr.avr_req.post_and_response returns the Python representation of the JSON result of the query.
\n
rest_avr.avr_req.add_to_queue() adds the currently constructed request to a queue of requests to post.
\n
rest_avr.avr_req.post_and_response_queue() returns a python list of results of queued queries.
\n
The following code sample constructs, posts and returns results for an AVR statistics request for specific DNS records and a specificrecord type, then queues multiple quests and posts and returns results.
\n
#!/usr/bin/python\nimport json\nimport sys\nimport time\nimport rest_avr\n\n#print rest_avr.ShowAVRJsonApi\n\n#Populate the url\n\navr_dns_req=rest_avr.avr_req()\navr_dns_req.auth('admin','admin')\navr_dns_req.url_base('10.10.2.113','dns')\n\n#Populate the json object\n\navr_dns_req['analyticsModule'].add('dns')\navr_dns_req['reportFeatures'].add('time-aggregated')\navr_dns_req['entityFilters'].add('domain-name', 'OPERATOR_TYPE_EQUAL', ['test2.test1.com','test1.test1.com'])\navr_dns_req['entityFilters'].add('query-type', 'OPERATOR_TYPE_EQUAL', ['a'])\navr_dns_req['viewMetrics'].add('packets')\navr_dns_req['viewDimensions'].add('domain-name')\navr_dns_req['metricFilters'].add('packets', 'OPERATOR_TYPE_GREATER_THAN', 0)\navr_dns_req['sortByMetrics'].add('packets', 'ascending')\navr_dns_req['pagination'].add(20, 0)\navr_dns_req['timeRange'].add(1461778251000000, None)\n\n#Post and retrieve results.\n\nresult_py=avr_dns_req.post_and_response()\n\nif result_py != None:\n print ('\\n' + result_py['results']['timeAggregated'][0]['dimensions'][0]['value'] + \" \" + result_py['results']['timeAggregated'][0]['metricValues'][0]['value'] + '\\n')\n\nelse:\n print result_py.error_layer\n print result_py.error_code\n print result_py.error_text\n\n# Now add multiple requests to a queue\navr_dns_req.add_to_queue()\n\navr_dns_req['entityFilters'].clear()\navr_dns_req['entityFilters'].add('query-type', 'OPERATOR_TYPE_EQUAL', ['aaaa'])\navr_dns_req.add_to_queue()\n\n#post and retrieve queued results\nresult_py_q=avr_dns_req.post_and_response_queue()\n\nfor result_py in result_py_q:\n\n if result_py != None:\n print ('\\n' + result_py['results']['timeAggregated'][0]['dimensions'][0]['value'] + \" \" + result_py['results']['timeAggregated'][0]['metricValues'][0]['value'] + '\\n')\n else:\n print result_py.error_layer\n print result_py.error_code\n print result_py.error_text\n
Code :
\"\"\"\nrest_avr provides a python interface to Bigip AVR statistics using the REST API. The main Python rest_avr.avr_req\nobject is a Python dictionary that maps to a JSON object that can be processed with the json.dumps() function\n\nAn IControl Rest AVR JSON request and response can be initiated with avr_req.post_and_response\n\nThe simple description of the API can is available at avr_req.ShowJsonApi()\n\nEach of these modules has a method to add single or multiple elements as appropriate to the specific module.\nOnce these elements are are populated a RestAPI request can be made with results returned as a python\nrepresentation.\n\n\navr_req.auth(user, passw)\navr_req.url_base(host, module)\n\navr_req['analyticsModule'].add(module)\navr_req['analyticsModule'].clear()\n\navr_req['reportFeatures'].add(metric_name, predicate, value)\navr_req['reportFeatures'].clear()\n\navr_req['entityFilters'].add(dimension_name, predicate, values)\navr_req['entityFilters'].clear()\n\navr_req['viewMetrics'].add(metric_name)\navr_req['viewMetrics'].clear()\n\navr_req['viewDimensions'].add(metric_name, order)\navr_req['viewDimensions'].clear()\n\navr_req['metricFilters'].add(metric_name, predicate, valu)\navr_req['metricFilters'].clear()\n\navr_req['sortByMetrics'].add(metric_name, orde)\navr_req['sortByMetrics'].clear()\n\navr_req['pagination'].add(num_results, skip_result)\navr_req['pagination'].clear()\n\navr_req['timeRange'].add(t_from, t_to)\navr_req['timeRange'].clear()\n\n\nAfter a request in constructed a REST API call is initiated with initiated with:\n\navr_req.post_and_response()\n\nThe response is a python dictionary data structure of the results as processed by json.loads\n\n\"\"\"\n\n\n\nfrom copy import deepcopy\nimport requests\nimport json\nimport sys\nimport time\nimport warnings\n\n__author__ = 'Mark Lloyd'\n__version__ = '1.0'\n\n# 05/24/2016\nimport json\nimport requests\nimport time\n\n\nclass BadDictElement(Exception):\n def __init__(self, key, value, expl):\n Exception.__init__(self, '{0} {1} {2} '.format(key, value, expl))\n\n\nclass BadTime(Exception):\n def __init__(self, variable, value):\n Exception.__init__(self, '{0} {1} should be 16 char decimal in microseconds '.format('a', 'b'))\n\n\nclass RequestFailure(Exception):\n def __init__(self, key, value):\n Exception.__init__(self, '{0} {1} '.format(key, value))\n\n\nclass analyticsModule(str):\n \"\"\"\n This class is tied to the structure of the parent class.\n parent() get's the parent object so we can make the string pseudo-mutable.\n accessed from within an avr request\n\n ['analyticsModule'].add(module)\n Adds a single string to analyticsModule element . If one exists it is replaced.\n\n ['analyticsModule'].clear()\n Send a null value to the analyticsModule element.\n\n See rest_avr.ShowAVRJsonApi for more details\n\n\n \"\"\"\n\n def parent(self, parent):\n self.parent = parent\n\n def add(self, module):\n \"\"\"\n avr_req.['analyticsModule'].add(module)\n Adds a single string to analyticsModule element . If one already exists it is replaced.\n This should be the same as the module string in avr_req.url_base.\n \"\"\"\n self.parent['analyticsModule'] = analyticsModule(module)\n self.parent['analyticsModule'].parent = self.parent\n\n def clear(self):\n \"\"\"\n avr_req.['analyticsModule'].add(module)\n replaces the analyticsModule mddule with a null string\n \"\"\"\n self.parent['analyticsModule'] = analyticsModule('')\n self.parent['analyticsModule'].parent = self.parent\n\n\nclass metricFilters(list):\n \"\"\"\n avr_req.['metricFilters'].add(metric_name, predicate, value)\n\n metric name is a string, value is an integer\n\n Valid predicates strings are ['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN',\n OPERATOR_TYPE_LOWER_THAN','OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL'])\n\n avr_req['metricFilters'].clear()\n Clears metricFilters elements\n\n See rest_avr.ShowAVRJsonApi for more details.\n\n \"\"\"\n\n def __init__(self):\n self.append([])\n self.valid_metric_predicate = (\n ['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN', 'OPERATOR_TYPE_LOWER_THAN',\n 'OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL'])\n\n def add(self, metric_name, predicate, value):\n \"\"\"\n avr_req.['metricFilters'].add(metric_name, predicate, value)\n\n metric name is a string, value is an integer\n\n Valid predicates strings are ['OPERATOR_TYPE_EQUAL', 'OPERATOR_TYPE_NOT_EQUAL', 'OPERATOR_TYPE_GREATER_THAN',\n OPERATOR_TYPE_LOWER_THAN','OPERATOR_TYPE_GREATER_THAN_OR_EQUAL', 'OPERATOR_TYPE_LOWER_THAN_OR_EQUAL']\n \"\"\"\n\n if type(value) is not int:\n raise BadDictElement(metric_name, value, 'value should be integer')\n\n if predicate in self.valid_metric_predicate:\n # first check if it is already there\n for metric in self[0]:\n if metric['metricName'] == metric_name:\n metric['predicate'] = predicate\n metric['value'] = value\n return 0\n # if it is not there then just add it.\n self[0].append({'metricName': metric_name, 'predicate': predicate, 'value': value})\n else:\n raise BadDictElement(metric_name, predicate, 'invalid predicate')\n\n def clear(self):\n \"\"\"\n avr_req['metricFilters'].clear()\n Clears metricFilters elements\n \"\"\"\n del self[0][:]\n\n\nclass entityFilters(list):\n \"\"\"\n avr_req.['entityFilters'].add(dimension_name, predicate, values):\n All values are strings\n valid predicate is 'OPERATOR_TYPE_EQUAL'\n\n ['entityFilters'].clear()\n Clears the entityFilters element\n\n See rest_avr.ShowJsonApi for more details\n \"\"\"\n\n def __init__(self):\n self.append([])\n\n def add(self, dimension_name, predicate, values):\n \"\"\"\n avr_req.['entityFilters'].add(dimension_name, predicate, values):\n All values are strings\n valid predicate is 'OPERATOR_TYPE_EQUAL'\n \"\"\"\n if predicate is 'OPERATOR_TYPE_EQUAL':\n # then loop throuth to see if the dimenson name already exists, if so replace\n for entity in self[0]:\n if entity['dimensionName'] == dimension_name:\n entity['predicate'] = predicate\n entity['values'] = values\n return 0\n # if it is not there then just add it.\n self[0].append({'dimensionName': dimension_name, 'predicate': predicate, 'values': values})\n\n else:\n raise BadDictElement(dimension_name, predicate, 'predicate must be OPERATOR_TYPE_EQUAL')\n\n def clear(self):\n \"\"\"\n ['entityFilters'].clear()\n Clears the entityFilters element\n \"\"\"\n del self[0][:]\n\n\nclass reportFeatures(list):\n \"\"\"\n avr_req.['reportFeatures'].add( feature)\n adds report feature string. Multiple features are permitted.\n\n ['reportFeatures'].clear()\n Clears the analyticsModule element.\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def add(self, feature):\n \"\"\"\n avr_req.['reportFeatures'].add( feature)\n adds report feature string. Multiple features are permitted\n .\"\"\"\n if feature not in self:\n self.append(feature)\n\n def clear(self):\n \"\"\"\n ['reportFeatures'].clear()\n Clears the entityFilters element\n \"\"\"\n del self[:]\n\n\nclass sortByMetrics(list):\n \"\"\"\n avr_req.['sortByMetrics'].add(metric_name, order)\n\n valid order names are 'ascending' and 'descending'\n sortByMetrics is optional in an AVR request.\n\n avr_req['sortByMetrics'].clear()\n Clears the sortByMetrics element.\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def __init__(self):\n self.metric_list = []\n\n def add(self, metric_name, order):\n if metric_name not in self.metric_list:\n self.append({'metricName': metric_name, 'order': order})\n self.metric_list.append(metric_name)\n\n def clear(self):\n \"\"\"\n ['sortByMetrics'].clear()\n Clears the sortByMetrics element\n \"\"\"\n del self[:]\n del self.metric_list[:]\n\n\nclass viewDimensions(list):\n \"\"\"\n avr_req.['viewDimensions'].add(dimension_name):\n adds view dimension, only one dimension is allowed\n add will replace element if it already exists\n\n avr_req['viewDimensions'].clear()\n Clears the viewDimensions element.\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def __init__(self):\n self.append([])\n self[0] = {}\n\n def add(self, dimension_name):\n \"\"\"\n avr_req.['viewDimensions'].add(dimension_name):\n adds view dimension string, only one dimension is allowed\n add will replace element if it already exists\n \"\"\"\n self[0]['dimensionName'] = dimension_name\n\n def clear(self, dimension_name):\n \"\"\"\n ['viewDimensions'].clear()\n Clears the viewDimensions element\n \"\"\"\n del self[0][:]\n\n\nclass viewMetrics(list):\n \"\"\"\n avr_req.['viewMetrics'].add(metric_name):\n appends metric_name string to list. The specification\n allows multiple view metric elements\n\n avr_req['viewMetrics'].clear()\n Clears the viewMetrics elements\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def __init__(self):\n self.metric_list = []\n\n def add(self, metric_name):\n \"\"\"\n avr_req.['viewMetrics'].add(metric_name):\n appends metric_name string to list. The specification\n allows multiple viewMetric elements\n \"\"\"\n\n if metric_name not in self.metric_list:\n self.append({'metricName': metric_name})\n self.metric_list.append(metric_name)\n\n def clear(self):\n \"\"\"\n ['viewMetrics'].clear()\n Clears the viewMetrics elements\n \"\"\"\n del self[:]\n del self.metric_list[:]\n\n\nclass timeRange(dict):\n \"\"\"\n avr_req.['timeRange'].add( t_from, t_to)\n both values are 16 digit numeric value in microseconds\n of unix/linux time. t_to is optional and can be replace by None\n\n timeRange is an optional.\n\n avr_req['timeRange'].clear()\n Clears the timeRange elements\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def add(self, t_from, t_to):\n \"\"\"\n avr_req.['timeRange'].add( t_from, t_to)\n both values are 16 digit numeric value in microseconds\n of unix/linux time. t_to is optional and can be replace by None\n\n timeRange is optional.\n \"\"\"\n if type(t_from) is long and len(str(t_from)) == 16:\n self['from'] = t_from\n else:\n raise BadTime(t_from + \" is 16 digit numeric value in microseconds\")\n\n if t_to != '' and t_to != 0 and t_to != None:\n if type(t_to) is long and len(str(t_from)) == 16:\n self['to'] = t_to\n else:\n raise BadTime(t_to + \" is 16 digit numeric value in microseconds\")\n else:\n if 'to' in self.keys():\n del self['to']\n\n def clear(self):\n \"\"\"\n ['timeRange'].clear()\n Clears the timeRange element\n \"\"\"\n del self[:]\n\n\nclass pagination(dict):\n \"\"\"\n avr_req.['pagination'].add(num_results, skip_results)\n both are integer values.\n\n avr_req['pagination'].clear()\n Clears the pagination elements\n\n See rest_avr.ShowAVRJsonApi for more details.\n \"\"\"\n\n def add(self, num_results, skip_results):\n \"\"\"\n avr_req.['pagination'].add(num_results, skip_results)\n both arguments are integers.\n \"\"\"\n if type(num_results) is int:\n self['numberOfResults'] = num_results\n else:\n raise BadDictElement('number of Results ', num_results, 'must be integer')\n if type(skip_results) is int:\n self['skipResults'] = skip_results\n else:\n raise BadDictElement('skipResults ', skip_results, 'must be integer')\n\n def clear(self):\n \"\"\"\n ['pagination'].clear()\n Clears the pagination element\n \"\"\"\n del self[:]\n\n\nclass avr_resp(dict):\n \"\"\"\n python response error is applicable.\n \"\"\"\n\n def __init__(self):\n self.error_layer = None\n self.error_code = None\n self.error_text = None\n\nclass avr_req(dict):\n \"\"\"\n The main class for rest_avr.\n\n avr_req contains a dictionary that maps to the elements of a Icontrol REST AVR request along with capability of\n posting that request and receiving a response.\n\n The dictionary values are object instances of python classes that correspond to the the JSON values of the\n object's name/value pair.\n\n Each value has two public methods:\n\n avr_req.['objectName']add(): adds an element to the appropriate object with type checking.\n If an element allows more then one instance the add function will append the element\n If an element allows only one instance the add function will replace the element\n\n avr_req.['objectName'].clear()r: clears all elements in the object.\n\n printing rest_avr.ShowAVRJsonApi provides documentation for the AVR JASON elements. Further documentation is\n available on devcentral.f5.com\n\n To post an AVR Rest request there are two functions to populate the HTTP/HTTPS request.\n\n avr_req.auth(user, passw):\n provides the username and password\n avr_req.url_base(host, module)\n provides the host and the bigip module AVR queries to construct the URL to make the request.\n\n Then to post the request and return results in a python representation of the JSON response.\n\n avr_req.post_and_response()\n\n \"\"\"\n\n def __init__(self):\n self['analyticsModule'] = analyticsModule()\n self['analyticsModule'].parent = self\n self['pagination'] = pagination()\n self['metricFilters'] = metricFilters()\n self['entityFilters'] = entityFilters()\n self['reportFeatures'] = reportFeatures()\n self['sortByMetrics'] = sortByMetrics()\n self['viewDimensions'] = viewDimensions()\n self['viewMetrics'] = viewMetrics()\n self['timeRange'] = timeRange()\n\n self.avr_session = requests.session()\n self.avr_session.verify = False\n self.avr_session.headers.update({'Content-Type': 'application/json'})\n\n # for multiple queued request handling.\n self.req_queue = []\n self.generate_id = None\n self.done = None\n self.result = None\n self.num_requests = 0\n self.res_queue = []\n\n def post_and_response(self):\n \"\"\"\n returns a python representation of the json response to the request.\n failure returns array ['ERROR','component',error]\n \"\"\"\n\n warnings.filterwarnings(\"ignore\")\n self.generate_request = self.avr_session.post(self.req_url_base + \"/generate-report/\",\n data=json.dumps(self))\n self.generate_request_py = json.loads(self.generate_request.text)\n self.result_guid = self.generate_request_py['id']\n self.results_status_url = self.req_url_base + \"/generate-report/\" + self.result_guid + \"/?$select=status,reportResultsLink\"\n self.results_url = self.req_url_base + \"/report-results/\" + self.result_guid\n self.sleeptime = .5\n for i in range(5):\n time.sleep(self.sleeptime)\n self.sleeptime *= 2 # double backoff period each time.\n\n self.status_results_json = self.avr_session.get(self.results_status_url)\n self.status_results = json.loads(self.status_results_json.text)\n\n if self.status_results['status'] == 'FAILED':\n self.result = avr_resp()\n self.result_error_layer = 'REST'\n self.result_error_code = self.status_results['status']\n self.result.error_text = self.status_results\n\n if self.status_results['status'] == 'FINISHED':\n self.raw_results_url = self.status_results['reportResultsLink']\n self.results_url = self.raw_results_url.replace('localhost', self.host_name)\n self.results = self.avr_session.get(self.results_url)\n\n if self.results.status_code == 200:\n self.result = avr_resp()\n self.result.update(json.loads(self.results.text))\n return self.result\n else:\n self.result = avr_resp()\n self.result.error_layer = 'HTTP'\n self.result.error_code = self.results.status_code\n self.result.error_text = self.results\n return self.result\n\n else:\n\n continue\n\n self.result = avr_resp()\n self.result.error_layer = 'REST_AVR'\n self.result.error_code = '408'\n self.result.error_text = 'TIMEOUT'\n\n\n def auth(self, user, passw):\n \"\"\"\n avr_req.auth(user, passw):\n username and password\n \"\"\"\n self.avr_session.auth = (user, passw)\n\n def url_base(self, host, module):\n \"\"\"\n avr_req.url_base(host, module)\n host and bigip module AVR queries to construct the URL to make the request.\n \"\"\"\n self.host_name = host\n self.req_url_base = 'https://%s/mgmt/tm/analytics/%s' % (host, module)\n self.module_py = {'analyticsModule': module}\n\n def add_to_queue(self):\n \"adds request as currently constructed to queue\"\n self.req_queue.append(deepcopy(self))\n\n def clear_queue(self):\n \"\"\"\"\n clears request queue\n \"\"\"\n del self.req_queue[:]\n\n def post_and_response_queue(self):\n \"\"\"\n posts and sends response to from queue of requests.\n \"\"\"\n warnings.filterwarnings(\"ignore\")\n for req in self.req_queue:\n req.generate_request = req.avr_session.post(req.req_url_base + \"/generate-report/\",\n data=json.dumps(req))\n req.generate_request_py = json.loads(req.generate_request.text)\n req.generate_id = (req.generate_request_py['id'])\n req.results_status_url = self.req_url_base + \"/generate-report/\" + req.generate_id + \"/?$select=status,reportResultsLink\"\n\n self.sleeptime = .5\n self.num_requests = len(self.req_queue)\n\n for i in range(5):\n\n for req in self.req_queue:\n\n if req.done is None:\n\n time.sleep(self.sleeptime)\n self.sleeptime *= 2 # double backoff period each time.\n req.status_results_json = req.avr_session.get(req.results_status_url)\n req.status_results = json.loads(req.status_results_json.text)\n\n if req.status_results['status'] == 'FAILED':\n req.result = avr_resp()\n req.result_error['layer'] = 'REST'\n req.result_error['error'] = req.status_results['status']\n req.result_error['text'] = req.status_results\n if req.status_results['status'] == 'FINISHED':\n req.raw_results_url = req.status_results['reportResultsLink']\n req.results_url = req.raw_results_url.replace('localhost', self.host_name)\n req.results = self.avr_session.get(req.results_url)\n if req.results.status_code == 200:\n req.result = avr_resp()\n req.result.update(json.loads(req.results.text))\n req.done = True\n self.res_queue.append(req.result)\n self.num_requests -= 1\n\n else:\n\n req.result = avr_resp()\n req.result_error.layer = 'HTTP'\n req.result_error.code = req.results.status_code\n req.result_error.text = req.results\n self.res_queue.append(req.result)\n if i == 5:\n if req.result == False:\n req.result = avr_resp()\n req.result.error_layer = 'REST_AVR'\n req.result.error_error = '408'\n req.result.error_text = 'TIMEOUT'\n\n\n if self.num_requests == 0:\n break\n\n\n\n return self.res_queue\n\n\nShowAVRJsonApi = \"\"\"\nreportFeatures\n--------------\nSpecifies the kind of information that appears in a\nresponse from AVR. You may specify one or more of the\nfollowing values:\n\nexisting-entities\ntime-aggregated\ntime-series\nentities-count\n\nviewDimensions\n--------------\nSpecifies the dimensions for which to calculate a report,\nsuch as:\n\n{\"dimensionName\": \"domain-name\"}\n\nYou may only specify a single dimension. You may omit\nthis field in a report generation request.\n\nviewMetrics\n-----------\nSpecifies the list of metrics by which to sort results, such\nas:\n\n{ \"metricName\": \"average-tps\" },\n{ \"metricName\": \"transactions\" }\n\nIf you specify either time-aggregated or\ntime-series features, you must specify one metric in\na report generation request.\n\nsortByMetrics\n--------------\nSpecifies the list of metrics to sort by, such as:\n[{ metricName: \"average-tps\", order:\"descending\" } ]\n\nValid values are ascending and descending. Sorting\nonly applies to the time-aggregated feature. You do\nnot need to specify this field in a report generation request.\n\ntimeRange\n---------\nSpecifies the time range, in microseconds, for which to\ncalculate a report, such as:\n\n{\"from\": 1410420888000000, \"to\": 1410424488000000 }\n\nYou do not need to specify this field in a report generation\nrequest.\n\nentityFilters\n=============\nSpecifies the entities and values for which to calculate a\nreport. You can specify a single entity with a second level\nof dimension filters that describe an aspect of the entity.\nIf you specify multiple entity types, the results include\nonly the entities that match all of the criteria. You do not\nneed to specify this field in a report generation request.\nThe following snippet contains two entities with\ncorresponding values:\n\n[[{\n\"dimensionName\" : \"virtual\",\n\"predicate\": \"OPERATOR_TYPE_EQUAL\",\n\"values : [\"phpAuction_VS_1\"] },\n{\n\"dimensionName : \"response-code\",\n\"predicate\": \"OPERATOR_TYPE_EQUAL\",\n\"values\" : [\"200\"] }\n]]\n\nmetricFilters\n-------------\nSpecifies the metric filters for which to calculate a report,\nsuch as:\n\n[{ \"metricName\": \"transactions\",\n\"predicate\" :\nmetricFilters\n\"OPERATOR_TYPE_GREATER_THAN\" \"value\":\n100 }]\n\nYou do not need to specify this field in a report generation\nrequest. For the existing-entities feature, AVR\nsupports the OPERATOR_TYPE_LIKE predicate. AVR also\nsupports the following predicates:\n\nOPERATOR_TYPE_EQUAL\nOPERATOR_TYPE_NOT_EQUAL\nOPERATOR_TYPE_GREATER_THAN\nOPERATOR_TYPE_LOWER_THAN\nOPERATOR_TYPE_GREATER_THAN_OR_EQUAL\nOPERATOR_TYPE_LOWER_THAN_OR_EQUAL\n\npagination\n----------\nSpecifies the number of results to return, and the number\nof results to skip, such as:\n\n{ numberOfResults : 10, skipResults : 10}\n\nTo see the second set of ten results, use the example\nshown here. AVR does not implement the OData query\nparameters top or skip. In order to see a specific set of\nresults, you must set the number of results to return and\nthen determine how many results to skip. You do not need\nto specify this field in a report generation request.\n\"\"\"
Tested this on version:
12.0","kudosSumWeight":0,"postTime":"2016-06-26T14:05:08.000-07:00","images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:avr","text":"avr","time":"2022-01-24T02:30:17.940-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDI","node":{"__typename":"Tag","id":"tag:devops","text":"devops","time":"2011-10-19T17:50:55.000-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDM","node":{"__typename":"Tag","id":"tag:iControl","text":"iControl","time":"2022-01-24T02:29:45.068-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDQ","node":{"__typename":"Tag","id":"tag:iControlREST","text":"iControlREST","time":"2022-01-24T02:29:46.488-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDU","node":{"__typename":"Tag","id":"tag:programmability contest","text":"programmability contest","time":"2022-01-24T02:33:24.992-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMnwyLjF8b3wxMHxfTlZffDY","node":{"__typename":"Tag","id":"tag:python","text":"python","time":"2022-01-24T02:30:07.130-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":13,"rawTeaser":"","introduction":"","currentRevision":{"__ref":"Revision:revision:290993_2"},"latestVersion":{"__typename":"FriendlyVersion","major":"2","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":397},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"tkbMessagePolicies":{"__typename":"TkbMessagePolicies","canDoAuthoringActionsOnTkb":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.tkb.policy_can_do_authoring_action.accessDenied","key":"error.lithium.policies.tkb.policy_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[{"__typename":"MessageEdge","cursor":"MjUuMnwyLjF8aXwxMHwzOTowfGludCwzMzc4OTcsMzM3ODk3","node":{"__ref":"TkbReplyMessage:message:337897"}}],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":2}},"Conversation:conversation:290993":{"__typename":"Conversation","id":"conversation:290993","solved":false,"topic":{"__ref":"TkbTopicMessage:message:290993"},"lastPostingActivityTime":"2024-11-21T03:23:59.412-08:00","lastPostTime":"2024-11-21T03:23:59.412-08:00","unreadReplyCount":1,"isSubscribed":false},"ModerationData:moderation_data:290993":{"__typename":"ModerationData","id":"moderation_data:290993","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"Revision:revision:290993_2":{"__typename":"Revision","id":"revision:290993_2","lastEditTime":"2023-06-05T22:51:27.504-07:00"},"CachedAsset:theme:customTheme1-1742464555214":{"__typename":"CachedAsset","id":"theme:customTheme1-1742464555214","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["custom"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"JimmyPackets-512-1702592938213.png","imageLastModified":"1702592945815","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"f5_logo_fix-1704824537976.svg","imageLastModified":"1704824540697","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1600px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_PAGE_CONTENT","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"5px","borderRadius":"5px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"14px","paddingXHero":"42px","fontStyle":"NORMAL","fontWeight":"400","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-400)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-400-h), var(--lia-bs-gray-400-s), calc(var(--lia-bs-gray-400-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-400-h), var(--lia-bs-gray-400-s), calc(var(--lia-bs-gray-400-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-300)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"NONE","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.06)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.15)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.15)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-primary)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#0C5C8D","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#62C026","blogColor":"#730015","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#C20025","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#F3704B","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#EE4B5B","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#491B62","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#949494","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0C5C8D","secondary":"#333333","bodyText":"#222222","bodyBg":"#F5F5F5","info":"#1D9CD3","success":"#62C026","warning":"#FFD651","danger":"#C20025","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#C20025","#081B85","#009639","#B3C6D7","#7CC0EB","#F29A36"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Inter","fontStyle":"NORMAL","fontWeight":"600","h1FontSize":"30px","h2FontSize":"25px","h3FontSize":"20px","h4FontSize":"18px","h5FontSize":"16px","h6FontSize":"16px","lineHeight":"1.2","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":null,"imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"14px","defaultMessageHeaderMarginBottom":"10px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"14px","specialMessageHeaderMarginBottom":"10px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Atkinson Hyperlegible","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.3","fontSizeBase":"15px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"13px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1743097589715","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:f5.prod:pages/kbs/TkbMessagePage:board:codeshare-1743097590664":{"__typename":"CachedAsset","id":"quilt:f5.prod:pages/kbs/TkbMessagePage:board:codeshare-1743097590664","value":{"id":"TkbMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"message-list","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":true,"showDescription":true,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[{"id":"tkbs.widget.tkbArticleWidget","className":"lia-tkb-container","props":{"contributorListType":"panel","showHelpfulness":false,"showTimestamp":true,"showGuideNavigationSection":true,"showVersion":true,"lazyLoad":false,"editLevel":"CONFIGURE"},"__typename":"QuiltComponent"}],"side":[{"id":"featuredWidgets.widget.featuredContentWidget","className":null,"props":{"instanceId":"featuredWidgets.widget.featuredContentWidget-1702666556326","layoutProps":{"layout":"card","layoutOptions":{"useRepliesCount":false,"useAuthorRank":false,"useTimeToRead":true,"useKudosCount":false,"useViewCount":true,"usePreviewMedia":true,"useBody":false,"useCenteredCardContent":false,"useTags":true,"useTimestamp":false,"useBoardLink":true,"useAuthorLink":false,"useSolvedBadge":true}},"titleSrOnly":false,"showPager":true,"pageSize":3,"lazyLoad":true},"__typename":"QuiltComponent"},{"id":"messages.widget.relatedContentWidget","className":null,"props":{"hideIfEmpty":true,"enablePagination":true,"useTitle":true,"listVariant":{"type":"listGroup"},"pageSize":3,"style":"list","pagerVariant":{"type":"loadMore"},"viewVariant":{"type":"inline","props":{"useRepliesCount":true,"useMedia":true,"useAuthorRank":false,"useNode":true,"useTimeToRead":true,"useSpoilerFreeBody":true,"useKudosCount":true,"useNodeLink":true,"useViewCount":true,"usePreviewMedia":false,"useBody":false,"timeStampType":"postTime","useTags":true,"clampSubjectLines":2,"useBoardIcon":false,"useMessageTimeLink":true,"clampBodyLines":3,"useTextBody":true,"useSolvedBadge":true,"useAvatar":true,"useAuthorLogin":true,"useUnreadCount":true}},"lazyLoad":true,"panelType":"divider"},"__typename":"QuiltComponent"}],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1743097589715","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-pages/kbs/TkbMessagePage-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-pages/kbs/TkbMessagePage-1743097589715","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This article cannot be found","name":"TKB Message Page","section.message-list.title":"","archivedMessageTitle":"This Content Has Been Archived","section.erPqcf.title":"","section.erPqcf.description":"","section.message-list.description":""},"localOverride":false},"CachedAsset:quiltWrapper:f5.prod:Common:1742464464749":{"__typename":"CachedAsset","id":"quiltWrapper:f5.prod:Common:1742464464749","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":"header.jpg","backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"LEFT_CENTER","lastModified":"1702932449000","__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.Beta_MetaNav","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"community.widget.navbarWidget","props":{"showUserName":false,"showRegisterLink":true,"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","linkFontWeight":"700","controllerHighlightColor":"hsla(30, 100%, 50%)","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkFontSize":"15px","linkBoxShadowHover":"none","backgroundOpacity":0.4,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","linkTextBorderBottom":"none","hamburgerColor":"var(--lia-nav-controller-icon-color)","brandLogoHeight":"48px","linkLetterSpacing":"normal","linkBgHoverColor":"transparent","collapseMenuDividerOpacity":0.16,"paddingBottom":"10px","dropdownPaddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"0","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","linkJustifyContent":"center","linkColor":"var(--lia-bs-primary)","collapseMenuDividerBg":"var(--lia-nav-link-color)","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-primary)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid #0C5C8D","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","linkPaddingX":"10px","paddingTop":"10px","linkPaddingY":"5px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkBgColor":"transparent","linkDropdownPaddingY":"9px","controllerIconColor":"#0C5C8D","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"#0C5C8D"},"links":{"sideLinks":[],"mainLinks":[{"children":[{"linkType":"INTERNAL","id":"migrated-link-1","params":{"boardId":"TechnicalForum","categoryId":"Forums"},"routeName":"ForumBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-2","params":{"boardId":"WaterCooler","categoryId":"Forums"},"routeName":"ForumBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-0","params":{"categoryId":"Forums"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-4","params":{"boardId":"codeshare","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-5","params":{"boardId":"communityarticles","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-3","params":{"categoryId":"CrowdSRC"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-7","params":{"boardId":"TechnicalArticles","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"article-series","params":{"boardId":"article-series","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"security-insights","params":{"boardId":"security-insights","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-8","params":{"boardId":"DevCentralNews","categoryId":"Articles"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-6","params":{"categoryId":"Articles"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-10","params":{"categoryId":"CommunityGroups"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"migrated-link-11","params":{"categoryId":"F5-Groups"},"routeName":"CategoryPage"}],"linkType":"INTERNAL","id":"migrated-link-9","params":{"categoryId":"GroupsCategory"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-12","params":{"boardId":"Events","categoryId":"top"},"routeName":"EventBoardPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-13","params":{"boardId":"Suggestions","categoryId":"top"},"routeName":"IdeaBoardPage"},{"children":[],"linkType":"EXTERNAL","id":"Common-external-link","url":"https://community.f5.com/c/how-do-i","target":"SELF"}]},"className":"QuiltComponent_lia-component-edit-mode__lQ9Z6","showSearchIcon":false},"__typename":"QuiltComponent"},{"id":"community.widget.bannerWidget","props":{"backgroundColor":"transparent","visualEffects":{"showBottomBorder":false},"backgroundImageProps":{"backgroundSize":"COVER","backgroundPosition":"CENTER_CENTER","backgroundRepeat":"NO_REPEAT"},"fontColor":"#222222"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"var(--lia-bs-primary)","linkHighlightColor":"#FFFFFF","visualEffects":{"showBottomBorder":false},"backgroundOpacity":60,"linkTextColor":"#FFFFFF"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"var(--lia-bs-body-color)","items":[{"id":"custom.widget.Beta_Footer","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Tag_Manager_Helper","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Consent_Blackbar","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1743097589715","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.Beta_MetaNav-en-1742464571141":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_MetaNav-en-1742464571141","value":{"component":{"id":"custom.widget.Beta_MetaNav","template":{"id":"Beta_MetaNav","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_MetaNav","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Beta_Footer-en-1742464571141":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_Footer-en-1742464571141","value":{"component":{"id":"custom.widget.Beta_Footer","template":{"id":"Beta_Footer","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"description":"DevCentral´s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_Footer","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"DevCentral´s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Tag_Manager_Helper-en-1742464571141":{"__typename":"CachedAsset","id":"component:custom.widget.Tag_Manager_Helper-en-1742464571141","value":{"component":{"id":"custom.widget.Tag_Manager_Helper","template":{"id":"Tag_Manager_Helper","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Tag_Manager_Helper","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Consent_Blackbar-en-1742464571141":{"__typename":"CachedAsset","id":"component:custom.widget.Consent_Blackbar-en-1742464571141","value":{"component":{"id":"custom.widget.Consent_Blackbar","template":{"id":"Consent_Blackbar","markupLanguage":"HTML","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Consent_Blackbar","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"TEXTHTML","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1743097589715","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1743097589715","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"CachedAsset:text:en_US-components/tkbs/TkbArticleWidget-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/tkbs/TkbArticleWidget-1743097589715","value":{},"localOverride":false},"Category:category:Forums":{"__typename":"Category","id":"category:Forums","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:TechnicalForum":{"__typename":"Forum","id":"board:TechnicalForum","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:WaterCooler":{"__typename":"Forum","id":"board:WaterCooler","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Articles":{"__typename":"Category","id":"category:Articles","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:TechnicalArticles":{"__typename":"Tkb","id":"board:TechnicalArticles","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:DevCentralNews":{"__typename":"Tkb","id":"board:DevCentralNews","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:GroupsCategory":{"__typename":"Category","id":"category:GroupsCategory","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:F5-Groups":{"__typename":"Category","id":"category:F5-Groups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:CommunityGroups":{"__typename":"Category","id":"category:CommunityGroups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Occasion:board:Events":{"__typename":"Occasion","id":"board:Events","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"occasionPolicies":{"__typename":"OccasionPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Idea:board:Suggestions":{"__typename":"Idea","id":"board:Suggestions","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"ideaPolicies":{"__typename":"IdeaPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:communityarticles":{"__typename":"Tkb","id":"board:communityarticles","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:security-insights":{"__typename":"Tkb","id":"board:security-insights","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:article-series":{"__typename":"Tkb","id":"board:article-series","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"CachedAsset:text:en_US-components/community/Navbar-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1743097589715","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","migrated-link-9":"Groups","migrated-link-7":"Technical Articles","migrated-link-8":"DevCentral News","migrated-link-1":"Technical Forum","migrated-link-10":"Community Groups","migrated-link-2":"Water Cooler","migrated-link-11":"F5 Groups","Common-external-link":"How Do I...?","migrated-link-0":"Forums","article-series":"Article Series","migrated-link-5":"Community Articles","migrated-link-6":"Articles","security-insights":"Security Insights","migrated-link-3":"CrowdSRC","migrated-link-4":"CodeShare","migrated-link-12":"Events","migrated-link-13":"Suggestions"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1743097589715","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1743097589715","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1743097589715","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1743097589715","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1743097589715","value":{"place":"Place {name}"},"localOverride":false},"QueryVariables:TopicReplyList:message:290993:2":{"__typename":"QueryVariables","id":"TopicReplyList:message:290993:2","value":{"id":"message:290993","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1743097589715","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1743097589715","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1743097589715","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solved","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1743097589715","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1743097589715","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstNDEtSzFzVEth\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/cmstNDEtSzFzVEth","height":0,"width":0,"mimeType":"image/svg+xml"},"Rank:rank:41":{"__typename":"Rank","id":"rank:41","position":18,"name":"Nimbostratus","color":"CCCCCC","icon":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstNDEtSzFzVEth\"}"},"rankStyle":"FILLED"},"User:user:433674":{"__typename":"User","id":"user:433674","uid":433674,"login":"Shamatulskii","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2024-11-21T03:18:34.308-08:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-6.svg?time=0"},"rank":{"__ref":"Rank:rank:41"},"entityType":"USER","eventPath":"community:zihoc95639/user:433674"},"ModerationData:moderation_data:337897":{"__typename":"ModerationData","id":"moderation_data:337897","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"TkbReplyMessage:message:337897":{"__typename":"TkbReplyMessage","author":{"__ref":"User:user:433674"},"id":"message:337897","revisionNum":1,"uid":337897,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Tkb:board:codeshare"},"parent":{"__ref":"TkbTopicMessage:message:290993"},"conversation":{"__ref":"Conversation:conversation:290993"},"subject":"Re: Python module to post and retrieve IControl Rest JSON objects for AVR statistics","moderationData":{"__ref":"ModerationData:moderation_data:337897"},"body":"
Hi Mark_Lloyd,
Could you please help me find the rest_avr library? Also, could you confirm whether the script is working correctly? I would really appreciate your assistance with this!
Thank you!
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"199","kudosSumWeight":0,"repliesCount":0,"postTime":"2024-11-21T03:23:59.412-08:00","lastPublishTime":"2024-11-21T03:23:59.412-08:00","metrics":{"__typename":"MessageMetrics","views":17},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"TKB_REPLY","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:290993/message:337897","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"CachedAsset:text:en_US-components/messages/MessageSubject-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1743097589715","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1743097589715","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1743097589715","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1743097589715","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1743097589715","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1743097589715","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-components/guides/GuideBottomNavigation-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/guides/GuideBottomNavigation-1743097589715","value":{"nav.label":"Previous/Next Page","nav.previous":"Previous","nav.next":"Next"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1743097589715","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1743097589715","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1743097589715","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/customComponent/CustomComponent-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/customComponent/CustomComponent-1743097589715","value":{"errorMessage":"Error rendering component id: {customComponentId}","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1743097589715","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1743097589715","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1743097589715","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1743097589715":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1743097589715","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false}}}},"page":"/kbs/TkbMessagePage/TkbMessagePage","query":{"autoScroll":"true","topicRepliesSort":"postTimeDesc","boardId":"codeshare","messageSubject":"python-module-to-post-and-retrieve-icontrol-rest-json-objects-for-avr-statistics","messageId":"290993"},"buildId":"q_bLpq2mflH0BeZigxpj6","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"f5","openTelemetryServiceVersion":"25.2.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/customComponent/CustomComponent/CustomComponent.tsx","./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/tkbs/TkbArticleWidget/TkbArticleWidget.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","./components/customComponent/CustomComponentContent/TemplateContent.tsx","../shared/client/components/common/List/UnstyledList/UnstyledList.tsx","./components/messages/MessageView/MessageView.tsx","./components/customComponent/CustomComponentContent/HtmlContent.tsx","./components/customComponent/CustomComponentContent/CustomComponentScripts.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx"],"appGip":true,"scriptLoader":[]}