iControl
241 TopicsPython 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. """ Tested this on version: 12.0373Views0likes1CommentBIG-IP Report
Problem this snippet solves: Overview This is a script which will generate a report of the BIG-IP LTM configuration on all your load balancers making it easy to find information and get a comprehensive overview of virtual servers and pools connected to them. This information is used to relay information to NOC and developers to give them insight in where things are located and to be able to plan patching and deploys. I also use it myself as a quick way get information or gather data used as a foundation for RFC's, ie get a list of all external virtual servers without compression profiles. The script has been running on 13 pairs of load balancers, indexing over 1200 virtual servers for several years now and the report is widely used across the company and by many companies and governments across the world. It's easy to setup and use and only requires auditor (read-only) permissions on your devices. Demo/Preview Interactive demo http://loadbalancing.se/bigipreportdemo/ Screen shots The main report: The device overview: Certificate details: How to use this snippet: Installation instructions BigipReport REST This is the only branch we're updating since middle of 2020 and it supports 12.x and upwards (maybe even 11.6). Downloads: https://loadbalancing.se/downloads/bigipreport-v5.7.13.zip Documentation, installation instructions and troubleshooting:https://loadbalancing.se/bigipreport-rest/ Docker support https://loadbalancing.se/2021/01/05/running-bigipreport-on-docker/ Kubernetes support https://loadbalancing.se/2021/04/16/bigipreport-on-kubernetes/ BIG-IP Report (Legacy) Older version of the report that only runs on Windows and is depending on a Powershell plugin originally written by Joe Pruitt (F5) BIG-IP Report (only download this if you have v10 devices): https://loadbalancing.se/downloads/bigipreport-5.4.0-beta.zip iControl Snapin https://loadbalancing.se/downloads/f5-icontrol.zip Documentation and Installation Instructions https://loadbalancing.se/bigip-report/ Upgrade instructions Protect the report using APM and active directory Written by DevCentral member Shann_P: https://loadbalancing.se/2018/04/08/protecting-bigip-report-behind-an-apm-by-shannon-poole/ Got issues/problems/feedback? Still have issues? Drop a comment below. We usually reply quite fast. Any bugs found, issues detected or ideas contributed makes the report better for everyone, so it's always appreciated. --- Join us on Discord: https://discord.gg/7JJvPMYahA Code : BigIP Report Tested this on version: 12, 13, 14, 15, 1613KViews20likes96CommentsGenerate private key w/ CSR via iControl REST
Problem this snippet solves: Generate a private key w/ CSR How to use this snippet: To create a private key with a CSR via iControl REST: POST URL:https://10.1.1.165/mgmt/tm/sys/crypto/key Use the data below as your payload. For the name field, it must end in .key or you will get a false 404! Code : { "name":"www.testing.com.key", "commonName":"www.testing.com", "keySize":"4096", "keyType":"rsa-private", "options":[{"gen-csr":"www.testing.com"}], "organization":"Let It Snow Corp.", "ou":"Ice Engineering", "city":"Calhoun", "state":"AZ", "admin-email-address":"jerry@letit.snow", "email-address":"beth@letit.snow", "subject-alternative-name":"DNS:www.testing.com", "challenge-password":"myP4ssword" } Tested this on version: 13.02KViews3likes11CommentsPython Bigsuds - License BIG-IP
Problem this snippet solves: This bigsuds script will license a BIGIP How to use this snippet: This bigsuds script will license a BIGIP It's a port of some of Erick's: https://devcentral.f5.com/wiki/icontrol.BigIpLicensingCommandLineTool.ashx and update of the pycontrol v2: pyControl v2 - License BIGIP - DevCentral Still missing the proxy functionality in Erick's though. Usage: license-bigip.py --bigip < IP|hostname> --username < username> --server < license_server_hostname> --reg_keys < regkeys> --license < license_file> --eula < eula_file> Ex. From CLI: (virt1)user1@desktop:python $./license-bigip.py --help Usage: license-bigip.py [options] Options: -h, --help show this help message and exit -b BIGIP, --bigip=BIGIP -u UNAME, --username=UNAME -s SERVER_HOSTNAME, --server=SERVER_HOSTNAME -r REG_KEYS_STRING, --reg_keys=REG_KEYS_STRING -l LOCAL_LICENSE_FILE_NAME, --license=LOCAL_LICENSE_FILE_NAME -e LOCAL_EULA_FILE_NAME, --eula=LOCAL_EULA_FILE_NAME Providing New Keys: (virt1)user1@desktop:python $./license-bigip.py --server activate.f5.com --bigip 10.11.50.201 --username admin --reg_keys "B6907-36850-30441-96521-8395199" Enter your password for username: admin Password: Attempting to get license online. License server requires you to submit EULA. reg keys provided ['B6907-36850-30441-96521-8395172'] Getting dossier using keys:['B6907-36850-30441-96521-8395199'] License Found. Attempting to installing License on BIGIP: License status = STATE_ENABLED Use Existing Keys: (virt1)user1@desktop:python $./license-bigip.py --server activate.f5.com --bigip 10.11.50.201 --username admin Enter your password for username: admin Password: Attempting to get license online. License server requires you to submit EULA. Reg Key list is empty, attempting to retrieve existing keys from the unit Getting dossier using keys:[B6907-36850-30441-96521-8395199, P459718-6102942, B273271-7144254, N123537-7304104] License Found. Attempting to installing License on BIGIP: License status = STATE_ENABLED Script license-bigip.py Code : #!/usr/bin/env python ''' ---------------------------------------------------------------------------- The contents of this file are subject to the "END USER LICENSE AGREEMENT FOR F5 Software Development Kit for iControl"; you may not use this file except in compliance with the License. The License is included in the iControl Software Development Kit. Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is iControl Code and related documentation distributed by F5. The Initial Developer of the Original Code is F5 Networks, Inc. Seattle, WA, USA. Portions created by F5 are Copyright (C) 1996-2004 F5 Networks, Inc. All Rights Reserved. iControl (TM) is a registered trademark of F5 Networks, Inc. Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the License, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the License or the GPL. ---------------------------------------------------------------------------- ''' def usage (): print "Usage:" print "%s --bigip --username --server \ --reg_keys --license --eula " % sys.argv[0] print "ex. " print " Will attempt to re-license with existing keys on unit using license server activate.f5.com" print " %s --bigip 192.168.1.245 --username admin" % sys.argv[0] print " Will attempt to re-license with provided reg_keys CSV string using license server activate.f5.com" print " %s --bigip 192.168.1.245 --username admin --reg_keys \"XXXX-XXXX-XXXX-XXXX,XXXX-XXXX,XXXX-XXXX\" " % sys.argv[0] def get_license_from_F5_License_Server ( server_hostname, dossier_string, eula_string, email, firstName, lastName, companyName, phone, jobTitle, address, city, stateProvince, postalCode, country ): try: license_string = "" # Unfortunately, F5 wsdl on license server references http but F5 only accepts https so as an ugly workaround need to # download wsdl, save to disk, replace links http with https, and have SUDS client reference local file instead #(eg. url = "file:///home/admin/f5wsdl.xml") download_url = "https://" + server_hostname + "/license/services/urn:com.f5.license.v5b.ActivationService?wsdl" # Check to see if there's a copy of wsdl file on disk first # Careful with this behavior if you switch server hostnames. local_wsdl_file_name = str(server_hostname) + '-f5wsdl-w-https.xml' wsdl_data = [] try: with open(local_wsdl_file_name, 'r') as fh_wsdl: wsdl_data = fh_wsdl.read() except: print "Can't find a locally stored WSDL file." if not wsdl_data: print "Attempting to fetch wsdl online." f5wsdl = urllib2.urlopen(download_url) newlines = [] for line in f5wsdl: # do the replacing here newlines.append(line.replace('http://' + server_hostname , 'https://' + server_hostname)) fh_local = open(local_wsdl_file_name,'w') fh_local.writelines(newlines) fh_local.close() # put url going to pass to client in file format url = "file:" + urllib.pathname2url(os.getcwd()) + "/" + local_wsdl_file_name #Now create client object using wsdl from disk instead of the interwebs. client = Client(url) # NOT using below as will just try actually licensing and fail then if needed # try: # # ping() method should return string containing date # print "Checking License Service Reachability..." # return_ping_date = client.service.ping() # except: # print "License SOAP service unreachable. Check network connectivity." # return transaction = client.factory.create('ns0:LicenseTransaction') # If eula isn't present on first call to getLicense, transaction will fail # but it will return a eula after first attempt transaction = client.service.getLicense( dossier = dossier_string, eula = eula_string, email = email, firstName = firstName , lastName = lastName, companyName = companyName, phone = phone, jobTitle = jobTitle, address = address, city = city, stateProvince = stateProvince, postalCode = postalCode, country = country, ) #Extract the eula offered from first try eula_string = transaction.eula if transaction.state == "EULA_REQUIRED": #Try again, this time with eula populated transaction = client.service.getLicense( dossier = dossier_string, eula = eula_string, email = email, firstName = firstName , lastName = lastName, companyName = companyName, phone = phone, jobTitle = jobTitle, address = address, city = city, stateProvince = stateProvince, postalCode = postalCode, country = country, ) if transaction.state == "LICENSE_RETURNED": license_string = transaction.license else: print "Can't retrieve license from Licensing server" print "License server returned error: Number:" + str(transaction.fault.faultNumber) + " Text: " + str(transaction.fault.faultText) return license_string except: print "Can't retrieve License from Server" traceback.print_exc(file=sys.stdout) def get_reg_keys(obj): try: reg_keys = [] reg_keys = obj.Management.LicenseAdministration.get_registration_keys() return reg_keys except: print "Get Reg Keys error. Check log." traceback.print_exc(file=sys.stdout) def get_dossier (obj, reg_keys ): try: dossier_string = obj.Management.LicenseAdministration.get_system_dossier ( reg_keys ) return dossier_string except: print "Get Dossier error. Check log." traceback.print_exc(file=sys.stdout) def get_eula_file (obj): try: eula_char_array = obj.Management.LicenseAdministration.get_eula_file( ) eula_string = base64.b64decode(eula_char_array) return eula_string except: print "Get eula_file. Check log." traceback.print_exc(file=sys.stdout) def install_license (obj, license_string ): try: license_char_array = base64.b64encode(license_string) obj.Management.LicenseAdministration.install_license ( license_file_data = license_char_array ) except: print "Install License error. Check log." traceback.print_exc(file=sys.stdout) def get_license_status (obj): try: license_status = obj.Management.LicenseAdministration.get_license_activation_status() return license_status except: print "Get License Status error. Check log." traceback.print_exc(file=sys.stdout) ### IMPORT MODULES ### import os import sys import time import traceback import base64 import urllib import urllib2 import getpass from suds.client import Client from optparse import OptionParser import bigsuds # from suds import WebFault # import logging # logging.getLogger('suds.client').setLevel(logging.DEBUG) # logging.getLogger('suds.metrics').setLevel(logging.DEBUG) # logging.getLogger('suds').setLevel(logging.DEBUG) #### SET CONFIG VARIABLES #### #Misc EULA Variables email = "example.icontrol@f5.com" firstName = "example" lastName = "iControl" companyName = "F5" phone = "2062725555" jobTitle = "DEV OPS" address = "111 EXAMPLE ICONTROL RD" city = "Seattle" stateProvince = "WA" postalCode = "98119" country = "United States" parser = OptionParser() parser.add_option("-b", "--bigip", action="store", type="string", dest="bigips", default="192.168.1.245") parser.add_option("-u", "--username", action="store", type="string", dest="uname", default="admin") parser.add_option("-s", "--server", action="store", type="string", dest="server_hostname", default="activate.f5.com" ) parser.add_option("-r", "--reg_keys", action="store", type="string", dest="reg_keys_string" ) parser.add_option("-l", "--license", action="store", type="string", dest="local_license_file_name") parser.add_option("-e", "--eula", action="store", type="string", dest="local_eula_file_name") (options, args) = parser.parse_args() ### INITIALIZE BIGIP OBJECT ### if options.bigip and options.uname: print "Enter your password for username: %s" % options.uname upass = getpass.getpass() else: usage() sys.exit() #hardcoded so don't have to provide any arguments. #print "Enter your password for username: %s" % options.uname #upass = getpass.getpass() # Can re-license a list of BIG-IPs IF you don't provide a list of regkeys on CLI. # As reg key split function does not accommodate list of keys for multiple devices. if options.bigips: bigip_list = options.bigips.split(",") for i in bigip_list: print "\nAttempting to License BIGIP " + i reg_keys = [] license_string = "" eula_string = "" reg_keys_string = "" local_license_file_name = "" local_eula_file_name = "" server_hostname = "authem.f5net.com" uname = "admin" b = bigsuds.BIGIP( hostname = i, username = uname, password = upass, ) ########## START MAIN LOGIC ###### if local_license_file_name: try: print "Attempting to retrive License from local disk ..." with open(local_license_file_name, 'r') as fh_license: license_string = fh_license.read() except: print "Can't Open license file named: \"" + local_license_file_name + "\" on disk." #sys.exit() print "No worries. Will attempt to retrieve one from online." if not license_string: print "Attempting to get license online." print "License server requires you to submit EULA." if options.local_eula_file_name: print "Attempting to retrive EULA from local disk first..." try: with open(options.local_eula_file_name, 'r') as fh_eula: eula_string = fh_eula.read() except: print "Can't find EULA file named : \"" + options.local_eula_file_name + "\" on disk." print "No worries. Will attempt to retrieve one during transaction with License Server." # Could also try seeing if Target BIG-IP has one stored # eula_file = get_eula_file(b) if options.reg_keys_string: reg_keys = options.reg_keys_string.split(",") print "reg keys provided" print reg_keys if len(reg_keys) < 1: print "Reg Key list is empty, attempting to retrieve existing keys from the unit" reg_keys = get_reg_keys(b) print "Getting dossier using keys:" + str(reg_keys) dossier_string = get_dossier( b, reg_keys ) # print "dossier = " + str(dossier_output) license_string = get_license_from_F5_License_Server( options.server_hostname, dossier_string, eula_string, email, firstName, lastName, companyName, phone, jobTitle, address, city, stateProvince, postalCode, country ) if license_string: print "License Found. Attempting to installing License on BIGIP:" install_license ( b, license_string ) else: print "Sorry. Could not retrieve License. Check your connection" license_status = get_license_status ( b ) print "License status = " + str(license_status)366Views0likes0CommentsPerl ARX ManualMigrateRule
Problem this snippet solves: This script is an example of how to use the iControl interfaces provided by an ARX to use manual migration rule to migrate files on an ARX. How to use this snippet: ARXManualMigrateRuleExample.pl --url --user --pass Prerequisites SOAP::Lite perl module An F5 ARX system running release V6.02.000 or later and configured with at least one manual migrate rule. Management access on the ARX must be permitted for HTTPs-API or HTTP-API services. Code : #!/usr/bin/perl #------------------------------------------------------------------------------- # The contents of this file are subject to the "END USER LICENSE AGREEMENT # FOR F5 Software Development Kit for iControl"; you may not use this file # except in compliance with the License. The License is included in the # iControl Software Development Kit. # # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. # # The Original Code is iControl Code and related documentation # distributed by F5. # # The Initial Developer of the Original Code is F5 Networks, # Inc. Seattle, WA, USA. Portions created by F5 are Copyright (C) 1996-2012 # F5 Networks, Inc. All Rights Reserved. iControl (TM) is a registered # trademark of F5 Networks, Inc. # # Alternatively, the contents of this file may be used under the terms # of the GNU General Public License (the "GPL"), in which case the # provisions of GPL are applicable instead of those above. If you wish # to allow use of your version of this file only under the terms of the # GPL and not to allow others to use your version of this file under the # License, indicate your decision by deleting the provisions above and # replace them with the notice and other provisions required by the GPL. # If you do not delete the provisions above, a recipient may use your # version of this file under either the License or the GPL. #------------------------------------------------------------------------------- # # Description # # This script is an example of how to use the iControl interfaces provided by # an ARX to use manual migration rule to migrate files on an ARX. # # Usage: ARXManualMigrateRuleExample.pl --url --user --pass --op # # Prerequisites: # # This script requires the following: # # * SOAP::Lite perl module # * An F5 ARX system configured with at least one configured manual migrate rule. # * Management access on the ARX must be permitted for HTTP-API and HTTPS-API # services. # # For more information on ARX configuration, please consult the # documentation that was provided with your ARX system. #------------------------------------------------------------------------------- # SOAP::Lite lets us send SOAP requests and parse them use SOAP::Lite autotype => 0, default_ns => 'urn:iControl'; # If you need to debug problems with your script, you can use the +trace # option with SOAP::Lite and it will print the XML sent to and received from # the server: # # use SOAP::Lite # autotype => 0, # default_ns => 'urn:iControl' + trace; # Getopt::Long lets us easily parse command line options use Getopt::Long; use POSIX qw(strftime); use Carp; use strict; use warnings; #------------------------------------------------------------------------------- # Main program logic #------------------------------------------------------------------------------- our ($url, $user, $pass, $op); # Load command line options - if the load fails, then we print the usage # instructions and exit. if (!GetOptions("url=s" => \$url, "user=s" => \$user, "pass=s" => \$pass, "op=s" => \$op)) { usage(); exit(1); } # If any arguments were skipped, print the usage instructions and exit. if (!defined $url || !defined $user || !defined $pass || !defined $op) { usage(); exit(1); } # The service path for interface "Interface" is this: # # http:// : /api/services/Interface # my $manualMigrateRuleServiceUrl = $url . "/api/services/ManualMigrateRule"; # In order for SOAP to access a web service, it needs to read the WSDL # for the interface you want to use. The WSDL file for an interface # called "Interface" is available via http/https on the ARX at: # # http:// : /api/services/Interface?wsdl # # If you need a WSDL 2.0 version, that is also available at: # # http:// : /arx-api/wsdl/Interface.wsdl2 # # In this case, we're using the ManualMigrateRule interface and we're # interested in using the WSDL 1.1 version. # my $manualMigrateRuleWsdlUrl = $manualMigrateRuleServiceUrl . "?wsdl"; # Now we build our SOAP::Lite object using the service and WSDL # URLs my $manualMigrateRuleSoap = SOAP::Lite->new(proxy => $manualMigrateRuleServiceUrl, service => $manualMigrateRuleWsdlUrl); print "Please specify a namespace:\n\n"; chomp(my $namespace = <>); print "\n"; print "Please specify a volume:\n\n"; chomp(my $volume = <>); print "\n"; if ($op eq "get_list") { get_list($namespace, $volume); } elsif ($op eq "get_configuration") { get_configuration($namespace, $volume); } elsif ($op eq "get_status") { get_status($namespace, $volume); } elsif ($op eq "create") { create($namespace, $volume); } elsif ($op eq "set_migrate_close_file") { set_migrate_close_file($namespace, $volume); } elsif ($op eq "set_report") { set_report($namespace, $volume); } elsif ($op eq "set_enable") { set_enable($namespace, $volume); } elsif ($op eq "create_and_configure") { create_and_configure($namespace, $volume); } elsif ($op eq "remove") { remove($namespace, $volume); } elsif ($op eq "migrate_files") { migrate_files($namespace, $volume); } #------------------------------------------------------------------------------- # End of main program logic #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # sub usage #------------------------------------------------------------------------------- sub usage { print "\nUsage: ARXManualMigrateRuleExample.pl --url --user --pass --op \n"; print "\n"; print "Argument Description\n"; print "-------- -----------\n"; print "--url The base URL of the web service on the ARX. Both http and https\n"; print " are supported. The format is:\n"; print "\n"; print " http(s):// : \n"; print "\n"; print " : DNS resolvable hostname or IP address\n"; print " : 83 for http or 843 for https\n"; print "\n"; print "--user The username for authentication.\n"; print "--pass The password for authentication.\n"; print "\n"; print "--op The ARXManualMigrateRule API method that will be called:\n"; print "\n"; print " create\n"; print " create_and_configure\n"; print " set_migrate_close_file\n"; print " set_report\n"; print " set_enable\n"; print " get_list\n"; print " get_configuration\n"; print " get_status\n"; print " migrate_files\n"; print " remove\n"; print "\n"; } #------------------------------------------------------------------------------- # sub getSecurityHeader(user, pass) # # This subroutine builds a security header that will be used for # authentication. This type of security header is required for all calls to # iControl::ARX interfaces, so it makes sense to have this subroutine stored in # a library for common access. #------------------------------------------------------------------------------- sub getSecurityHeader { my $user = shift; my $pass = shift; my $now = time(); my $then = time() + 60; my $created = strftime("%Y-%m-%dT%H:%M:%S", gmtime($now)) . 'Z'; my $expires = strftime("%Y-%m-%dT%H:%M:%S", gmtime($then)) . 'Z'; my $secExt = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'; my $secUtil = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'; my $securityHeader = SOAP::Header->name("wsse:Security")->attr( { 'xmlns:wsse'=> $secExt, 'xmlns:wsu'=> $secUtil } ); my $timestamp = SOAP::Data->name("wsu:Timestamp" => \SOAP::Data->value( SOAP::Data->name('wsu:Created')->value($created) ->type(''), SOAP::Data->name('wsu:Expires')->value($expires) ->type(''))); my $usernameTokenType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"; my $usernameToken = SOAP::Data->name("wsse:UsernameToken" => \SOAP::Data->value( SOAP::Data->name('wsse:Username')->value($user) ->type(''), SOAP::Data->name('wsse:Password')->value($pass) ->type('') ->attr({'Type'=>$usernameTokenType}))); $securityHeader->value(\SOAP::Data->value($timestamp, $usernameToken)); return $securityHeader; } sub create { my ($namespace, $volume) = @_; print "Please specify a rule name:\n\n"; chomp(my $manualMigrateRule = <>); print "\n"; print "Calling the \"create\" method of the ARX ManualMigrateRule interface with the following parameters:\n\n"; print "namespace: $namespace\n"; print "volume: $volume\n"; print "rule: $manualMigrateRule\n\n"; # Build a security header my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->create(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), SOAP::Data->name('rule')->value($manualMigrateRule), $securityHeader); # Check if there were any faults encountered during the operation. # We find this by checking if the fault member of the result object # is set. If there is a fault, then we can print the detailed # fault text using the faultstring member of the result object. if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } } sub create_and_configure { my ($namespace, $volume) = @_; print "Please specify a rule name:\n\n"; chomp(my $manualMigrateRule = <>); print "\n"; print "Please specify a report prefix:\n\n"; chomp(my $prefix = <>); print "\n"; print "Please specify either 'true' or 'false' for 'verbose':\n\n"; chomp(my $verbose = <>); print "\n"; print "Please specify either 'ARX_POLICY_REPORT_DELETE_UNKNOWN', 'ARX_POLICY_REPORT_DELETE_EMPTY', or 'ARX_POLICY_REPORT_ERROR_ONLY' for 'delete_report':\n\n"; chomp(my $delete_report = <>); print "\n"; print "Please specify either 'ARX_POLICY_REPORT_INTERVAL_UNKNOWN', 'ARX_POLICY_REPORT_INTERVAL_HOURLY', or 'ARX_POLICY_REPORT_INTERVAL_DAILY' for 'interval':\n\n"; chomp(my $interval = <>); print "\n"; print "Please specify either 'true' or 'false' for 'migrate_close_file':\n\n"; chomp(my $migrateCloseFileValue = <>); print "\n"; print "Please specify files to be included in the 'exclude_file_set':\n\n"; chomp(my $excludeFileSetValue = <>); print "\n"; print "Please specify either 'true' or 'false' for 'enable':\n\n"; chomp(my $enable = <>); print "\n"; if ($migrateCloseFileValue ne "true" && $migrateCloseFileValue ne "false") { confess("migrate_close_file value must be either 'true' or 'false'.\n"); } my $baseReport = SOAP::Data->name('report' => \SOAP::Data->value(SOAP::Data->name('prefix' => $prefix), SOAP::Data->name('verbose' => $verbose), SOAP::Data->name('delete_report' => $delete_report))); my $intervalReport = SOAP::Data->name('report' => \SOAP::Data->value(SOAP::Data->name('interval' => $interval), $baseReport)); my $migrateCloseFile = SOAP::Data->name('migrate_close_file' => \SOAP::Data->value(SOAP::Data->name('migrate_close_file' => $migrateCloseFileValue), SOAP::Data->name('exclude_file_set' => $excludeFileSetValue))); my $configuration = SOAP::Data->name('configuration' => \SOAP::Data->value(SOAP::Data->name('rule_name' => $manualMigrateRule), SOAP::Data->name('enable' => $enable), SOAP::Data->name('report' => $intervalReport), $migrateCloseFile)); print "Calling the \"create_and_configure\" method of the ARX ManualMigrateRule interface with the following parameters:\n\n"; print "namespace: $namespace\n"; print "volume: $volume\n"; print "rule_name: $manualMigrateRule\n"; print "enable: $enable\n"; print "report:\n"; print " interval: $interval\n"; print " report: \n"; print " prefix: $prefix\n"; print " verbose: $verbose\n"; print " delete_report: $delete_report\n"; print "migrate_close_file:\n"; print " migrate_close_file: $migrateCloseFileValue\n"; print " exclude_file_set: $excludeFileSetValue\n\n"; my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->create_and_configure(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), $configuration, $securityHeader); if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } } sub set_migrate_close_file { my ($namespace, $volume) = @_; print "Please specify a rule name:\n\n"; chomp(my $manualMigrateRule = <>); print "\n"; print "Please specify either 'true' or 'false' for 'migrate_close_file':\n\n"; chomp(my $migrateCloseFileValue = <>); print "\n"; print "Please specify files to be included in the 'exclude_file_set':\n\n"; chomp(my $excludeFileSetValue = <>); print "\n"; if ($migrateCloseFileValue ne "true" && $migrateCloseFileValue ne "false") { confess("migrate_close_file value must be either 'true' or 'false'.\n"); } my $migrateCloseFile = SOAP::Data->name('migrate_close_file' => \SOAP::Data->value(SOAP::Data->name('migrate_close_file' => $migrateCloseFileValue), SOAP::Data->name('exclude_file_set' => $excludeFileSetValue))); print "Calling the \"set_migrate_close_file\" method of the ARX ManualMigrateRule interface with the following parameters:\n\n"; print "namespace: $namespace\n"; print "volume: $volume\n"; print "rule: $manualMigrateRule\n"; print "migrate_close_file:\n"; print " migrate_close_file: $migrateCloseFileValue\n"; print " exclude_file_set: $excludeFileSetValue\n\n"; my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->set_migrate_close_file(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), SOAP::Data->name('rule')->value($manualMigrateRule), $migrateCloseFile, $securityHeader); if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } } sub set_report { my ($namespace, $volume) = @_; print "Please specify a rule name:\n\n"; chomp(my $manualMigrateRule = <>); print "\n"; print "Please specify a report prefix:\n\n"; chomp(my $prefix = <>); print "\n"; print "Please specify either 'true' or 'false' for 'verbose':\n\n"; chomp(my $verbose = <>); print "\n"; print "Please specify either 'ARX_POLICY_REPORT_DELETE_UNKNOWN', 'ARX_POLICY_REPORT_DELETE_EMPTY', or 'ARX_POLICY_REPORT_ERROR_ONLY' for 'delete_report':\n\n"; chomp(my $delete_report = <>); print "\n"; print "Please specify either 'ARX_POLICY_REPORT_INTERVAL_UNKNOWN', 'ARX_POLICY_REPORT_INTERVAL_HOURLY', or 'ARX_POLICY_REPORT_INTERVAL_DAILY' for 'interval':\n\n"; chomp(my $interval = <>); print "\n"; my $baseReport = SOAP::Data->name('report' => \SOAP::Data->value(SOAP::Data->name('prefix' => $prefix), SOAP::Data->name('verbose' => $verbose), SOAP::Data->name('delete_report' => $delete_report))); my $intervalReport = SOAP::Data->name('report' => \SOAP::Data->value(SOAP::Data->name('interval' => $interval), $baseReport)); print "Calling the \"set_report\" method of the ARX ManualMigrateRule interface with the following parameters:\n\n"; print "namespace: $namespace\n"; print "volume: $volume\n"; print "rule: $manualMigrateRule\n"; print "report:\n"; print " interval: $interval\n"; print " report: \n"; print " prefix: $prefix\n"; print " verbose: $verbose\n"; print " delete_report: $delete_report\n\n"; my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->set_report(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), SOAP::Data->name('rule')->value($manualMigrateRule), $intervalReport, $securityHeader); if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } } sub set_enable { my ($namespace, $volume) = @_; print "Please specify a rule name:\n\n"; chomp(my $manualMigrateRule = <>); print "\n"; print "Please specify either 'true' or 'false' for 'enable':\n\n"; chomp(my $enable = <>); print "\n"; print "Calling the \"set_enable\" method of the ARX ManualMigrateRule interface with the following parameters:\n\n"; print "namespace: $namespace\n"; print "volume: $volume\n"; print "rule: $manualMigrateRule\n"; print "enable: $enable\n\n"; my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->set_enable(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), SOAP::Data->name('rule')->value($manualMigrateRule), SOAP::Data->name('enable' => $enable), $securityHeader); if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } } sub get_list { my ($namespace, $volume) = @_; # Get a list of manual migrate rules configured on the ARX. print "Calling the \"get_list\" method of the ARX ManualMigrateRule interface.\n\n"; # Build a security header my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->get_list(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), $securityHeader); # Check if there were any faults encountered during the operation. # We find this by checking if the fault member of the result object # is set. If there is a fault, then we can print the detailed # fault text using the faultstring member of the result object. if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } print "Printing the results of the call to the \"get_list\" method of the ARX ManualMigrateRule interface.\n\n"; # The get_list() call did not fail, so we build a list of manual migrate rule # names from the result. Note that the full result is a # concatenation of the result and paramsout members of the SOAP # result object. my @manualMigrateRuleList = ($manualMigrateRuleSoapResult->result, $manualMigrateRuleSoapResult->paramsout); if ($#manualMigrateRuleList < 0) { print("The list of manual migrate rules returned from the call to the \"get_list\" method of the ARX ManualMigrateRule interface was empty.\n"); exit(0); } # We can now print the list of manual migrate rules print "Manual Migrate Rule list:\n"; foreach my $mmr (@manualMigrateRuleList) { print " ", $mmr, "\n"; } } sub get_configuration { my ($namespace, $volume) = @_; # Get a list of manual migrate rules configured on the ARX. # Build a security header my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->get_list(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), $securityHeader); # Check if there were any faults encountered during the operation. # We find this by checking if the fault member of the result object # is set. If there is a fault, then we can print the detailed # fault text using the faultstring member of the result object. if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } # The get_list() call did not fail, so we build a list of manual migrate rule # names from the result. Note that the full result is a # concatenation of the result and paramsout members of the SOAP # result object. my @manualMigrateRuleList = ($manualMigrateRuleSoapResult->result, $manualMigrateRuleSoapResult->paramsout); if ($#manualMigrateRuleList < 0) { print("The list of manual migrate rules returned from the call to the \"get_list\" method of the ARX ManualMigrateRule interface was empty.\n"); exit(0); } # get manual migrate rule configuration from API print "Calling the \"get_configuration\" method of the ARX ManualMigrateRule interface.\n\n"; # Build a security header $securityHeader = getSecurityHeader($user, $pass); # In addition to printing the list of manual migrate rules, we can actually # use that list to retrieve configuration information # for all of the manual migrate rules using the same list by calling # get_configuration(). $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->get_configuration(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), SOAP::Data->name('rules')->value(@manualMigrateRuleList), $securityHeader); if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } print "Printing the results of the call to the \"get_configuration\" method of the ARX ManualMigrateRule interface.\n\n"; my @manualMigrateRuleConfigs = ($manualMigrateRuleSoapResult->result, $manualMigrateRuleSoapResult->paramsout); foreach my $manualMigrateRuleConfig (@manualMigrateRuleConfigs) { my $rule_name = $manualMigrateRuleConfig->{'rule_name'}; print "----------------------------------------------\n"; print "Manual Migrate Rule: ", $rule_name, "\n"; print "----------------------------------------------\n\n"; print "rule_name: ", $rule_name, "\n"; my $enable = $manualMigrateRuleConfig->{'enable'}; print "enable: ", $enable, "\n"; if (exists $manualMigrateRuleConfig->{'report'}) { my $interval_report_config = $manualMigrateRuleConfig->{'report'}; print "report:\n"; my $interval = $interval_report_config->{'interval'}; print " interval: ", $interval, "\n"; if (exists $interval_report_config->{'report'}) { my $base_report_config = $interval_report_config->{'report'}; print " report:\n"; my $prefix = $base_report_config->{'prefix'}; print " prefix: ", $prefix, "\n"; my $verbose = $base_report_config->{'verbose'}; print " verbose: ", $verbose, "\n"; my $delete_report = $base_report_config->{'delete_report'}; print " delete_report: ", $delete_report, "\n"; } } if (exists $manualMigrateRuleConfig->{'migrate_close_file'}) { my $migrate_close_file_config = $manualMigrateRuleConfig->{'migrate_close_file'}; print "migrate_close_file:\n"; my $migrate_close_file = $migrate_close_file_config->{'migrate_close_file'}; print " migrate_close_file: ", $migrate_close_file, "\n"; my $exclude_file_set = $migrate_close_file_config->{'exclude_file_set'}; print " exclude_file_set: ", $exclude_file_set, "\n"; } print "\n"; } } sub get_status { my ($namespace, $volume) = @_; # Get a list of manual migrate rules configured on the ARX. # Build a security header my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->get_list(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), $securityHeader); # Check if there were any faults encountered during the operation. # We find this by checking if the fault member of the result object # is set. If there is a fault, then we can print the detailed # fault text using the faultstring member of the result object. if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } # The get_list() call did not fail, so we build a list of manual migrate rule # names from the result. Note that the full result is a # concatenation of the result and paramsout members of the SOAP # result object. my @manualMigrateRuleList = ($manualMigrateRuleSoapResult->result, $manualMigrateRuleSoapResult->paramsout); if ($#manualMigrateRuleList < 0) { print("The list of manual migrate rules returned from the call to the \"get_list\" method of the ARX ManualMigrateRule interface was empty.\n"); exit(0); } # get manual migrate rule status from API print "Calling the \"get_status\" method of the ARX ManualMigrateRule interface.\n\n"; # Build a security header $securityHeader = getSecurityHeader($user, $pass); # In addition to printing the list of volumes, we can actually # use that list to retrieve status information for all of the volumes # using the same list by calling get_status(). $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->get_status(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), SOAP::Data->name('rules')->value(@manualMigrateRuleList), $securityHeader); if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } print "Printing the results of the call to the \"get_status\" method of the ARX ManualMigrateRule interface.\n\n"; my @manualMigrateRuleStatuses = ($manualMigrateRuleSoapResult->result, $manualMigrateRuleSoapResult->paramsout); foreach my $manualMigrateRuleStatus (@manualMigrateRuleStatuses) { my $mmr_status_rule_name = $manualMigrateRuleStatus->{'rule_name'}; print "----------------------------------------------\n"; print "Manual Migrate Rule: ", $mmr_status_rule_name, "\n"; print "----------------------------------------------\n\n"; print "rule_name: ", $mmr_status_rule_name, "\n"; my $available_request_slots = $manualMigrateRuleStatus->{'available_request_slots'}; print "available_request_slots: ", $available_request_slots, "\n"; } } sub migrate_files { my ($namespace, $volume) = @_; print "Please specify a rule name:\n\n"; chomp(my $manualMigrateRule = <>); print "\n"; print "Please specify a file list:\n\n"; chomp(my $fileList = <>); my @fileListArray = ($fileList); print "\n"; print "Please specify a target share (hit to specify a target share farm instead):\n\n"; chomp(my $share = <>); print "\n"; print "Please specify a target share farm (hit if a target share was previously specified):\n\n"; chomp(my $shareFarm = <>); print "\n"; print "Calling the \"migrate_files\" method of the ARX ManualMigrateRule interface with the following parameters:\n\n"; print "namespace: $namespace\n"; print "volume: $volume\n"; print "rule: $manualMigrateRule\n"; print "files: $fileList\n"; print "share: $share\n"; print "share_farm: $shareFarm\n\n"; # Build a security header my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->migrate_files(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), SOAP::Data->name('rule')->value($manualMigrateRule), SOAP::Data->name('files')->value(@fileListArray), SOAP::Data->name('share')->value($share), SOAP::Data->name('share_farm')->value($shareFarm), $securityHeader); # Check if there were any faults encountered during the operation. # We find this by checking if the fault member of the result object # is set. If there is a fault, then we can print the detailed # fault text using the faultstring member of the result object. if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } } sub remove { my ($namespace, $volume) = @_; print "Please specify a rule name:\n\n"; chomp(my $manualMigrateRule = <>); print "\n"; print "Calling the \"remove\" method of the ARX ManualMigrateRule interface with the following parameters:\n\n"; print "namespace: $namespace\n"; print "volume: $volume\n"; print "rule: $manualMigrateRule\n\n"; # Build a security header my $securityHeader = getSecurityHeader($user, $pass); my $manualMigrateRuleSoapResult = $manualMigrateRuleSoap->remove(SOAP::Data->name('namespace')->value($namespace), SOAP::Data->name('volume')->value($volume), SOAP::Data->name('rule')->value($manualMigrateRule), $securityHeader); # Check if there were any faults encountered during the operation. # We find this by checking if the fault member of the result object # is set. If there is a fault, then we can print the detailed # fault text using the faultstring member of the result object. if (defined $manualMigrateRuleSoapResult->fault && $manualMigrateRuleSoapResult->fault) { confess("SOAP request failed:\n" . objdump($manualMigrateRuleSoapResult->fault) . "\n"); } } sub objdump { my ($obj, $indent) = @_; my $content = ''; if (!defined $obj) { return $content; } if (!defined $indent) { $indent = ' '; } my $type = ref $obj; if (!defined $type || $type eq '' || $type eq 'SCALAR') { $content = $content . $indent . $obj . "\n"; } elsif ($type eq 'ARRAY') { foreach my $node (@$obj) { $content = $content . objdump($node, $indent); } } else { my $key; my $value; while (($key, $value) = each %$obj) { my $type2 = ref $value; if (!defined $type2 || $type2 eq '' || $type2 eq 'SCALAR') { $content = $content . $indent . "\'$key\' => $value;\n"; } else { $content = $content . $indent . "\'$key\' => {\n"; $content = $content . objdump($value, $indent.' '); $content = $content . $indent . "}\n"; } } } return $content; }306Views0likes0CommentsPerl ARX Network
Problem this snippet solves: This script is an example of how to use the iControl interfaces provided by an ARX to retrieve all networks and their configurations, statuses and statistics on an ARX. How to use this snippet: ARXNetworkExample.pl --url --user --pass Prerequisites SOAP::Lite perl module An F5 ARX system running release V6.02.000 or later and configured with at least one configured network. Management access on the ARX must be permitted for HTTPs-API or HTTP-API services. Code : #!/usr/bin/perl #------------------------------------------------------------------------------- # The contents of this file are subject to the "END USER LICENSE AGREEMENT # FOR F5 Software Development Kit for iControl"; you may not use this file # except in compliance with the License. The License is included in the # iControl Software Development Kit. # # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. # # The Original Code is iControl Code and related documentation # distributed by F5. # # The Initial Developer of the Original Code is F5 Networks, # Inc. Seattle, WA, USA. Portions created by F5 are Copyright (C) 1996-2012 # F5 Networks, Inc. All Rights Reserved. iControl (TM) is a registered # trademark of F5 Networks, Inc. # # Alternatively, the contents of this file may be used under the terms # of the GNU General Public License (the "GPL"), in which case the # provisions of GPL are applicable instead of those above. If you wish # to allow use of your version of this file only under the terms of the # GPL and not to allow others to use your version of this file under the # License, indicate your decision by deleting the provisions above and # replace them with the notice and other provisions required by the GPL. # If you do not delete the provisions above, a recipient may use your # version of this file under either the License or the GPL. #------------------------------------------------------------------------------- # # Description # # This script is an example of how to use the iControl interfaces provided by # an ARX to retrieve all networks and their configurations, statuses and # statistics on an ARX. # # Usage: ARXNetworkExample.pl --url --user --pass # # Prerequisites: # # This script requires the following: # # * SOAP::Lite perl module # * An F5 ARX system configured with at least one configured network. # * Management access on the ARX must be permitted for HTTP-API and HTTPS-API # services. # # For more information on ARX configuration, please consult the # documentation that was provided with your ARX system. #------------------------------------------------------------------------------- # SOAP::Lite lets us send SOAP requests and parse them use SOAP::Lite autotype => 0, default_ns => 'urn:iControl'; # If you need to debug problems with your script, you can use the +trace # option with SOAP::Lite and it will print the XML sent to and received from # the server: # # use SOAP::Lite # autotype => 0, # default_ns => 'urn:iControl' + trace; # Getopt::Long lets us easily parse command line options use Getopt::Long; use POSIX qw(strftime); use Carp; use strict; use warnings; #------------------------------------------------------------------------------- # Main program logic #------------------------------------------------------------------------------- our ($url, $user, $pass); # Load command line options - if the load fails, then we print the usage # instructions and exit. if (!GetOptions("url=s" => \$url, "user=s" => \$user, "pass=s" => \$pass)) { usage(); exit(1); } # If any arguments were skipped, print the usage instructions and exit. if (!defined $url || !defined $user || !defined $pass) { usage(); exit(1); } # The service path for interface "Interface" is this: # # http:// : /api/services/Interface # my $networkServiceUrl = $url . "/api/services/Network"; # In order for SOAP to access a web service, it needs to read the WSDL # for the interface you want to use. The WSDL file for an interface # called "Interface" is available via http/https on the ARX at: # # http:// : /api/services/Interface?wsdl # # If you need a WSDL 2.0 version, that is also available at: # # http:// : /arx-api/wsdl/Interface.wsdl2 # # In this case, we're using the Network interface and we're # interested in using the WSDL 1.1 version. # my $networkWsdlUrl = $networkServiceUrl . "?wsdl"; # Now we build our SOAP::Lite object using the service and WSDL # URLs my $networkSoap = SOAP::Lite->new(proxy => $networkServiceUrl, service => $networkWsdlUrl); #------------------------------------------------------------------------------- # get_list #------------------------------------------------------------------------------- my @networkList = (); print "Calling the \"get_list\" method of the ARX Network interface.\n\n"; # Build a security header our $securityHeader = getSecurityHeader($user, $pass); my $networkSoapResult = $networkSoap->get_list($securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { print("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_list\" method of the ARX Network interface.\n\n"; @networkList = ($networkSoapResult->result, $networkSoapResult->paramsout); if ($#networkList < 0) { print("The list of networks returned from the call to the \"get_list\" method of the ARX Network interface was empty.\n"); } else { print "Networks:\n"; foreach my $network (@networkList) { print "$network\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_stats #------------------------------------------------------------------------------- print "Calling the \"get_stats\" method of the ARX Network interface.\n\n"; if ($#networkList < 0) { print("The list of networks returned from the call to the \"get_list\" method of the ARX Network interface was empty.\n"); } else { # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_stats(SOAP::Data->name('interface_ids')->value(@networkList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_stats\" method of the ARX Network interface.\n\n"; my @networkStats = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $networkStat (@networkStats) { my $id = $networkStat->{'id'}; print "----------------------------------------------\n"; print "Network: ", $id, "\n"; print "----------------------------------------------\n\n"; print "id: ", $id, "\n"; my $collisions = $networkStat->{'collisions'}; print "collisions: ", $collisions, "\n"; my $crc_errors = $networkStat->{'crc_errors'}; print "crc_errors: ", $crc_errors, "\n"; my $discarded = $networkStat->{'discarded'}; print "discarded: ", $discarded, "\n"; my $rx_broadcast = $networkStat->{'rx_broadcast'}; print "rx_broadcast: ", $rx_broadcast, "\n"; my $rx_multicast = $networkStat->{'rx_multicast'}; print "rx_multicast: ", $rx_multicast, "\n"; my $rx_octets = $networkStat->{'rx_octets'}; print "rx_octets: ", $rx_octets, "\n"; my $rx_total = $networkStat->{'rx_total'}; print "rx_total: ", $rx_total, "\n"; my $rx_unicast = $networkStat->{'rx_unicast'}; print "rx_unicast: ", $rx_unicast, "\n"; my $tx_broadcast = $networkStat->{'tx_broadcast'}; print "tx_broadcast: ", $tx_broadcast, "\n"; my $tx_multicast = $networkStat->{'tx_multicast'}; print "tx_multicast: ", $tx_multicast, "\n"; my $tx_octets = $networkStat->{'tx_octets'}; print "tx_octets: ", $tx_octets, "\n"; my $tx_total = $networkStat->{'tx_total'}; print "tx_total: ", $tx_total, "\n"; my $tx_unicast = $networkStat->{'tx_unicast'}; print "tx_unicast: ", $tx_unicast, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_gigabit_interface_list #------------------------------------------------------------------------------- my @gigabitNetworkList = (); print "Calling the \"get_gigabit_interface_list\" method of the ARX Network interface.\n\n"; # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_gigabit_interface_list($securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { print("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_gigabit_interface_list\" method of the ARX Network interface.\n\n"; @gigabitNetworkList = ($networkSoapResult->result, $networkSoapResult->paramsout); if ($#gigabitNetworkList < 0) { print("The list of networks returned from the call to the \"get_gigabit_interface_list\" method of the ARX Network interface was empty.\n"); } else { print "Gigabit Network Ports:\n"; foreach my $gigabitNetworkPort (@gigabitNetworkList) { my $slot = $gigabitNetworkPort->{'slot'}; print "slot: ", $slot, "\n"; my $port = $gigabitNetworkPort->{'port'}; print "port: ", $port, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_gigabit_interface_configuration #------------------------------------------------------------------------------- print "Calling the \"get_gigabit_interface_configuration\" method of the ARX Network interface.\n\n"; if ($#gigabitNetworkList < 0) { print("The list of networks returned from the call to the \"get_gigabit_interface_list\" method of the ARX Network interface was empty.\n"); } else { my @soapGigabitNetworkList = ConvertNetworkPortToSoapData(\@gigabitNetworkList); # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_gigabit_interface_configuration(SOAP::Data->name('ports')->value(@soapGigabitNetworkList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_gigabit_interface_configuration\" method of the ARX Network interface.\n\n"; my @gigabitInterfaceConfigs = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $gigabitInterfaceConfig (@gigabitInterfaceConfigs) { if (exists $gigabitInterfaceConfig->{'port'}) { my $gigabitInterfacePort = $gigabitInterfaceConfig->{'port'}; my $slot = $gigabitInterfacePort->{'slot'}; my $port = $gigabitInterfacePort->{'port'}; print "----------------------------------------------\n"; print "Gigabit Interface: slot: ", $slot, ", port: ", $port, "\n"; print "----------------------------------------------\n\n"; print "port:\n"; print " slot: ", $slot, "\n"; print " port: ", $port, "\n"; } my $description = $gigabitInterfaceConfig->{'description'}; print "description: ", $description, "\n"; my $flow_control_receive = $gigabitInterfaceConfig->{'flow_control_receive'}; print "flow_control_receive: ", $flow_control_receive, "\n"; my $flow_control_send = $gigabitInterfaceConfig->{'flow_control_send'}; print "flow_control_send: ", $flow_control_send, "\n"; my $redundancy_protocol = $gigabitInterfaceConfig->{'redundancy_protocol'}; print "redundancy_protocol: ", $redundancy_protocol, "\n"; my $speed = $gigabitInterfaceConfig->{'speed'}; print "speed: ", $speed, "\n"; my $enable = $gigabitInterfaceConfig->{'enable'}; print "enable: ", $enable, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_gigabit_interface_status #------------------------------------------------------------------------------- print "Calling the \"get_gigabit_interface_status\" method of the ARX Network interface.\n\n"; if ($#gigabitNetworkList < 0) { print("The list of networks returned from the call to the \"get_gigabit_interface_list\" method of the ARX Network interface was empty.\n"); } else { my @soapGigabitNetworkList = ConvertNetworkPortToSoapData(\@gigabitNetworkList); # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_gigabit_interface_status(SOAP::Data->name('ports')->value(@soapGigabitNetworkList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_gigabit_interface_status\" method of the ARX Network interface.\n\n"; my @gigabitInterfaceStatuses = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $gigabitInterfaceStatus (@gigabitInterfaceStatuses) { if (exists $gigabitInterfaceStatus->{'port'}) { my $gigabitInterfacePort = $gigabitInterfaceStatus->{'port'}; my $slot = $gigabitInterfacePort->{'slot'}; my $port = $gigabitInterfacePort->{'port'}; print "----------------------------------------------\n"; print "Gigabit Interface: slot: ", $slot, ", port: ", $port, "\n"; print "----------------------------------------------\n\n"; print "port:\n"; print " slot: ", $slot, "\n"; print " port: ", $port, "\n"; } my $type = $gigabitInterfaceStatus->{'type'}; print "type: ", $type, "\n"; my $mode = $gigabitInterfaceStatus->{'mode'}; print "mode: ", $mode, "\n"; my $enabled = $gigabitInterfaceStatus->{'enabled'}; print "enabled: ", $enabled, "\n"; my $link_status = $gigabitInterfaceStatus->{'link_status'}; print "link_status: ", $link_status, "\n"; my $speed = $gigabitInterfaceStatus->{'speed'}; print "speed: ", $speed, "\n"; my $mac = $gigabitInterfaceStatus->{'mac'}; print "mac: ", $mac, "\n"; my $accept_all_frame = $gigabitInterfaceStatus->{'accept_all_frame'}; print "accept_all_frame: ", $accept_all_frame, "\n"; my $mtu_size = $gigabitInterfaceStatus->{'mtu_size'}; print "mtu_size: ", $mtu_size, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_ten_gigabit_interface_list #------------------------------------------------------------------------------- my @tenGigabitNetworkList = (); print "Calling the \"get_ten_gigabit_interface_list\" method of the ARX Network interface.\n\n"; # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_ten_gigabit_interface_list($securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { print("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_ten_gigabit_interface_list\" method of the ARX Network interface.\n\n"; @tenGigabitNetworkList = ($networkSoapResult->result, $networkSoapResult->paramsout); if ($#tenGigabitNetworkList < 0) { print("The list of networks returned from the call to the \"get_ten_gigabit_interface_list\" method of the ARX Network interface was empty.\n"); } else { print "Ten Gigabit Network Ports:\n"; foreach my $tenGigabitNetworkPort (@tenGigabitNetworkList) { my $slot = $tenGigabitNetworkPort->{'slot'}; print "slot: ", $slot, "\n"; my $port = $tenGigabitNetworkPort->{'port'}; print "port: ", $port, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_ten_gigabit_interface_configuration #------------------------------------------------------------------------------- print "Calling the \"get_ten_gigabit_interface_configuration\" method of the ARX Network interface.\n\n"; if ($#tenGigabitNetworkList < 0) { print("The list of networks returned from the call to the \"get_ten_gigabit_interface_list\" method of the ARX Network interface was empty.\n"); } else { my @soapTenGigabitNetworkList = ConvertNetworkPortToSoapData(\@tenGigabitNetworkList); # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_ten_gigabit_interface_configuration(SOAP::Data->name('ports')->value(@soapTenGigabitNetworkList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_ten_gigabit_interface_configuration\" method of the ARX Network interface.\n\n"; my @tenGigabitInterfaceConfigs = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $tenGigabitInterfaceConfig (@tenGigabitInterfaceConfigs) { if (exists $tenGigabitInterfaceConfig->{'port'}) { my $tenGigabitInterfacePort = $tenGigabitInterfaceConfig->{'port'}; my $slot = $tenGigabitInterfacePort->{'slot'}; my $port = $tenGigabitInterfacePort->{'port'}; print "----------------------------------------------\n"; print "Ten Gigabit Interface: slot: ", $slot, ", port: ", $port, "\n"; print "----------------------------------------------\n\n"; print "port:\n"; print " slot: ", $slot, "\n"; print " port: ", $port, "\n"; } my $description = $tenGigabitInterfaceConfig->{'description'}; print "description: ", $description, "\n"; my $flow_control_receive = $tenGigabitInterfaceConfig->{'flow_control_receive'}; print "flow_control_receive: ", $flow_control_receive, "\n"; my $flow_control_send = $tenGigabitInterfaceConfig->{'flow_control_send'}; print "flow_control_send: ", $flow_control_send, "\n"; my $redundancy_protocol = $tenGigabitInterfaceConfig->{'redundancy_protocol'}; print "redundancy_protocol: ", $redundancy_protocol, "\n"; my $enable = $tenGigabitInterfaceConfig->{'enable'}; print "enable: ", $enable, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_ten_gigabit_interface_status #------------------------------------------------------------------------------- print "Calling the \"get_ten_gigabit_interface_status\" method of the ARX Network interface.\n\n"; if ($#tenGigabitNetworkList < 0) { print("The list of networks returned from the call to the \"get_ten_gigabit_interface_list\" method of the ARX Network interface was empty.\n"); } else { my @soapTenGigabitNetworkList = ConvertNetworkPortToSoapData(\@tenGigabitNetworkList); # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_ten_gigabit_interface_status(SOAP::Data->name('ports')->value(@soapTenGigabitNetworkList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_ten_gigabit_interface_status\" method of the ARX Network interface.\n\n"; my @tenGigabitInterfaceStatuses = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $tenGigabitInterfaceStatus (@tenGigabitInterfaceStatuses) { if (exists $tenGigabitInterfaceStatus->{'port'}) { my $tenGigabitInterfacePort = $tenGigabitInterfaceStatus->{'port'}; my $slot = $tenGigabitInterfacePort->{'slot'}; my $port = $tenGigabitInterfacePort->{'port'}; print "----------------------------------------------\n"; print "Ten Gigabit Interface: slot: ", $slot, ", port: ", $port, "\n"; print "----------------------------------------------\n\n"; print "port:\n"; print " slot: ", $slot, "\n"; print " port: ", $port, "\n"; } my $type = $tenGigabitInterfaceStatus->{'type'}; print "type: ", $type, "\n"; my $mode = $tenGigabitInterfaceStatus->{'mode'}; print "mode: ", $mode, "\n"; my $enabled = $tenGigabitInterfaceStatus->{'enabled'}; print "enabled: ", $enabled, "\n"; my $link_status = $tenGigabitInterfaceStatus->{'link_status'}; print "link_status: ", $link_status, "\n"; my $speed = $tenGigabitInterfaceStatus->{'speed'}; print "speed: ", $speed, "\n"; my $mac = $tenGigabitInterfaceStatus->{'mac'}; print "mac: ", $mac, "\n"; my $accept_all_frame = $tenGigabitInterfaceStatus->{'accept_all_frame'}; print "accept_all_frame: ", $accept_all_frame, "\n"; my $mtu_size = $tenGigabitInterfaceStatus->{'mtu_size'}; print "mtu_size: ", $mtu_size, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_interface_spanning_tree_configuration #------------------------------------------------------------------------------- print "Calling the \"get_interface_spanning_tree_configuration\" method of the ARX Network interface.\n\n"; if ($#gigabitNetworkList < 0) { print("The list of networks returned from the call to the \"get_interface_spanning_tree_configuration\" method of the ARX Network interface was empty.\n"); } else { my @soapGigabitNetworkList = ConvertNetworkPortToSoapData(\@gigabitNetworkList); # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_interface_spanning_tree_configuration(SOAP::Data->name('ports')->value(@soapGigabitNetworkList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_interface_spanning_tree_configuration\" method of the ARX Network interface.\n\n"; my @networkIfSpanningTreeConfigs = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $networkIfSpanningTreeConfig (@networkIfSpanningTreeConfigs) { if (exists $networkIfSpanningTreeConfig->{'port'}) { my $networkIfSpanningTreePort = $networkIfSpanningTreeConfig->{'port'}; my $slot = $networkIfSpanningTreePort->{'slot'}; my $port = $networkIfSpanningTreePort->{'port'}; print "----------------------------------------------\n"; print "Gigabit Interface: slot: ", $slot, ", port: ", $port, "\n"; print "----------------------------------------------\n\n"; print "port:\n"; print " slot: ", $slot, "\n"; print " port: ", $port, "\n"; } my $spanning_tree_cost = $networkIfSpanningTreeConfig->{'spanning_tree_cost'}; print "spanning_tree_cost: ", $spanning_tree_cost, "\n"; my $spanning_tree_priority = $networkIfSpanningTreeConfig->{'spanning_tree_priority'}; print "spanning_tree_priority: ", $spanning_tree_priority, "\n"; my $spanning_tree_edgeport = $networkIfSpanningTreeConfig->{'spanning_tree_edgeport'}; print "spanning_tree_edgeport: ", $spanning_tree_edgeport, "\n"; my $spanning_tree_force_migration = $networkIfSpanningTreeConfig->{'spanning_tree_force_migration'}; print "spanning_tree_force_migration: ", $spanning_tree_force_migration, "\n"; my $spanning_tree_enable = $networkIfSpanningTreeConfig->{'spanning_tree_enable'}; print "spanning_tree_enable: ", $spanning_tree_enable, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_interface_spanning_tree_configuration #------------------------------------------------------------------------------- print "Calling the \"get_interface_spanning_tree_configuration\" method of the ARX Network interface.\n\n"; if ($#tenGigabitNetworkList < 0) { print("The list of networks returned from the call to the \"get_interface_spanning_tree_configuration\" method of the ARX Network interface was empty.\n"); } else { my @soapTenGigabitNetworkList = ConvertNetworkPortToSoapData(\@tenGigabitNetworkList); # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_interface_spanning_tree_configuration(SOAP::Data->name('ports')->value(@soapTenGigabitNetworkList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_interface_spanning_tree_configuration\" method of the ARX Network interface.\n\n"; my @networkIfSpanningTreeConfigs = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $networkIfSpanningTreeConfig (@networkIfSpanningTreeConfigs) { if (exists $networkIfSpanningTreeConfig->{'port'}) { my $networkIfSpanningTreePort = $networkIfSpanningTreeConfig->{'port'}; my $slot = $networkIfSpanningTreePort->{'slot'}; my $port = $networkIfSpanningTreePort->{'port'}; print "----------------------------------------------\n"; print "Ten Gigabit Interface: slot: ", $slot, ", port: ", $port, "\n"; print "----------------------------------------------\n\n"; print "port:\n"; print " slot: ", $slot, "\n"; print " port: ", $port, "\n"; } my $spanning_tree_cost = $networkIfSpanningTreeConfig->{'spanning_tree_cost'}; print "spanning_tree_cost: ", $spanning_tree_cost, "\n"; my $spanning_tree_priority = $networkIfSpanningTreeConfig->{'spanning_tree_priority'}; print "spanning_tree_priority: ", $spanning_tree_priority, "\n"; my $spanning_tree_edgeport = $networkIfSpanningTreeConfig->{'spanning_tree_edgeport'}; print "spanning_tree_edgeport: ", $spanning_tree_edgeport, "\n"; my $spanning_tree_force_migration = $networkIfSpanningTreeConfig->{'spanning_tree_force_migration'}; print "spanning_tree_force_migration: ", $spanning_tree_force_migration, "\n"; my $spanning_tree_enable = $networkIfSpanningTreeConfig->{'spanning_tree_enable'}; print "spanning_tree_enable: ", $spanning_tree_enable, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_mgmt_interface_configuration #------------------------------------------------------------------------------- print "Calling the \"get_mgmt_interface_configuration\" method of the ARX Network interface.\n\n"; # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_mgmt_interface_configuration($securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { print("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_mgmt_interface_configuration\" method of the ARX Network interface.\n\n"; my $mgmtIfConfig = $networkSoapResult->result; if (exists $mgmtIfConfig->{'port'}) { my $mgmtIfPort = $mgmtIfConfig->{'port'}; my $slot = $mgmtIfPort->{'slot'}; my $port = $mgmtIfPort->{'port'}; print "----------------------------------------------\n"; print "Management Interface: slot: ", $slot, ", port: ", $port, "\n"; print "----------------------------------------------\n\n"; print "port:\n"; print " slot: ", $slot, "\n"; print " port: ", $port, "\n"; } my $description = $mgmtIfConfig->{'description'}; print "description: ", $description, "\n"; my $ip_address = $mgmtIfConfig->{'ip_address'}; print "ip_address: ", $ip_address, "\n"; my $ip_mask = $mgmtIfConfig->{'ip_mask'}; print "ip_mask: ", $ip_mask, "\n"; my $speed = $mgmtIfConfig->{'speed'}; print "speed: ", $speed, "\n"; my $enable = $mgmtIfConfig->{'enable'}; print "enable: ", $enable, "\n"; print "\n"; } #------------------------------------------------------------------------------- # get_mgmt_interface_status #------------------------------------------------------------------------------- print "Calling the \"get_mgmt_interface_status\" method of the ARX Network interface.\n\n"; # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_mgmt_interface_status($securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { print("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_mgmt_interface_status\" method of the ARX Network interface.\n\n"; my $mgmtIfStatus = $networkSoapResult->result; if (exists $mgmtIfStatus->{'port'}) { my $mgmtIfPort = $mgmtIfStatus->{'port'}; my $slot = $mgmtIfPort->{'slot'}; my $port = $mgmtIfPort->{'port'}; print "----------------------------------------------\n"; print "Management Interface: slot: ", $slot, ", port: ", $port, "\n"; print "----------------------------------------------\n\n"; print "port:\n"; print " slot: ", $slot, "\n"; print " port: ", $port, "\n"; } my $type = $mgmtIfStatus->{'type'}; print "type: ", $type, "\n"; my $mode = $mgmtIfStatus->{'mode'}; print "mode: ", $mode, "\n"; my $enabled = $mgmtIfStatus->{'enabled'}; print "enabled: ", $enabled, "\n"; my $link_status = $mgmtIfStatus->{'link_status'}; print "link_status: ", $link_status, "\n"; my $speed = $mgmtIfStatus->{'speed'}; print "speed: ", $speed, "\n"; my $mac = $mgmtIfStatus->{'mac'}; print "mac: ", $mac, "\n"; my $accept_all_frame = $mgmtIfStatus->{'accept_all_frame'}; print "accept_all_frame: ", $accept_all_frame, "\n"; my $mtu_size = $mgmtIfStatus->{'mtu_size'}; print "mtu_size: ", $mtu_size, "\n"; print "\n"; } #------------------------------------------------------------------------------- # get_vlan_interface_list #------------------------------------------------------------------------------- my @vlanList = (); print "Calling the \"get_vlan_interface_list\" method of the ARX Network interface.\n\n"; # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_vlan_interface_list($securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { print("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_vlan_interface_list\" method of the ARX Network interface.\n\n"; @vlanList = ($networkSoapResult->result, $networkSoapResult->paramsout); if ($#vlanList < 0) { print("The list of VLAN interfaces returned from the call to the \"get_vlan_interface_list\" method of the ARX Network interface was empty.\n"); } else { print "VLAN Interfaces:\n"; foreach my $vlan (@vlanList) { print "$vlan\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_vlan_interface_configuration #------------------------------------------------------------------------------- print "Calling the \"get_vlan_interface_configuration\" method of the ARX Network interface.\n\n"; if ($#vlanList < 0) { print("The list of VLAN interfaces returned from the call to the \"get_vlan_interface_list\" method of the ARX Network interface was empty.\n"); } else { # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_vlan_interface_configuration(SOAP::Data->name('ids')->value(@vlanList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_vlan_interface_configuration\" method of the ARX Network interface.\n\n"; my @vlanConfigs = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $vlanConfig (@vlanConfigs) { my $id = $vlanConfig->{'id'}; print "----------------------------------------------\n"; print "VLAN Interface: ", $id, "\n"; print "----------------------------------------------\n\n"; print "id: ", $id, "\n"; my $description = $vlanConfig->{'description'}; print "description: ", $description, "\n"; my $ip_address = $vlanConfig->{'ip_address'}; print "ip_address: ", $ip_address, "\n"; my $ip_mask = $vlanConfig->{'ip_mask'}; print "ip_mask: ", $ip_mask, "\n"; my $redundancy = $vlanConfig->{'redundancy'}; print "redundancy: ", $redundancy, "\n"; my $enable = $vlanConfig->{'enable'}; print "enable: ", $enable, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_ip_proxy_list #------------------------------------------------------------------------------- my @ipProxyList = (); print "Calling the \"get_ip_proxy_list\" method of the ARX Network interface.\n\n"; # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_ip_proxy_list($securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { print("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_ip_proxy_list\" method of the ARX Network interface.\n\n"; @ipProxyList = ($networkSoapResult->result, $networkSoapResult->paramsout); if ($#ipProxyList < 0) { print("The list of IP Proxies returned from the call to the \"get_ip_proxy_list\" method of the ARX Network interface was empty.\n"); } else { print "IP Proxies:\n"; foreach my $ipProxy (@ipProxyList) { print "$ipProxy\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_ip_proxy_configuration #------------------------------------------------------------------------------- print "Calling the \"get_ip_proxy_configuration\" method of the ARX Network interface.\n\n"; if ($#ipProxyList < 0) { print("The list of IP Proxies returned from the call to the \"get_ip_proxy_list\" method of the ARX Network interface was empty.\n"); } else { # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_ip_proxy_configuration(SOAP::Data->name('ip_address')->value(@ipProxyList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_ip_proxy_configuration\" method of the ARX Network interface.\n\n"; my @ipProxyConfigs = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $ipProxyConfig (@ipProxyConfigs) { my $proxy_address = $ipProxyConfig->{'proxy_address'}; print "----------------------------------------------\n"; print "IP Proxy Address: ", $proxy_address, "\n"; print "----------------------------------------------\n\n"; print "proxy_address: ", $proxy_address, "\n"; my $mask = $ipProxyConfig->{'mask'}; print "mask: ", $mask, "\n"; my $mac = $ipProxyConfig->{'mac'}; print "mac: ", $mac, "\n"; if (exists $ipProxyConfig->{'processor'}) { my $ipProxyProc = $ipProxyConfig->{'processor'}; print "processor:\n"; my $slot = $ipProxyProc->{'slot'}; print " slot: ", $slot, "\n"; my $processor = $ipProxyProc->{'processor'}; print " processor: ", $processor, "\n"; print "\n"; } my $vlan = $ipProxyConfig->{'vlan'}; print "vlan: ", $vlan, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # get_ip_proxy_status #------------------------------------------------------------------------------- print "Calling the \"get_ip_proxy_status\" method of the ARX Network interface.\n\n"; if ($#ipProxyList < 0) { print("The list of IP Proxies returned from the call to the \"get_ip_proxy_list\" method of the ARX Network interface was empty.\n"); } else { # Build a security header $securityHeader = getSecurityHeader($user, $pass); $networkSoapResult = $networkSoap->get_ip_proxy_status(SOAP::Data->name('ip_address')->value(@ipProxyList), $securityHeader); if (defined $networkSoapResult->fault && $networkSoapResult->fault) { confess("SOAP request failed:\n" . objdump($networkSoapResult->fault) . "\n"); } else { print "Printing the results of the call to the \"get_ip_proxy_status\" method of the ARX Network interface.\n\n"; my @ipProxyStatuses = ($networkSoapResult->result, $networkSoapResult->paramsout); foreach my $ipProxyStatus (@ipProxyStatuses) { my $proxy_address = $ipProxyStatus->{'proxy_address'}; print "proxy_address: ", $proxy_address, "\n"; my $mac = $ipProxyStatus->{'mac'}; print "mac: ", $mac, "\n"; my $owner = $ipProxyStatus->{'owner'}; print "owner: ", $owner, "\n"; my $in_use_by = $ipProxyStatus->{'in_use_by'}; print "in_use_by: ", $in_use_by, "\n"; print "\n"; } print "\n"; } } #------------------------------------------------------------------------------- # End of main program logic #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # sub usage #------------------------------------------------------------------------------- sub usage { print "\nUsage: ARXNetworkExample.pl --url --user --pass \n"; print "\n"; print "Argument Description\n"; print "-------- -----------\n"; print "--url The base URL of the web service on the ARX. Both http and https\n"; print " are supported. The format is:\n"; print "\n"; print " http(s):// : \n"; print "\n"; print " : DNS resolvable hostname or IP address\n"; print " : 83 for http or 843 for https\n"; print "\n"; print "--user The username for authentication.\n"; print "--pass The password for authentication.\n"; print "\n"; } #------------------------------------------------------------------------------- # sub getSecurityHeader(user, pass) # # This subroutine builds a security header that will be used for # authentication. This type of security header is required for all calls to # iControl::ARX interfaces, so it makes sense to have this subroutine stored in # a library for common access. #------------------------------------------------------------------------------- sub getSecurityHeader { my $user = shift; my $pass = shift; my $now = time(); my $then = time() + 60; my $created = strftime("%Y-%m-%dT%H:%M:%S", gmtime($now)) . 'Z'; my $expires = strftime("%Y-%m-%dT%H:%M:%S", gmtime($then)) . 'Z'; my $secExt = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'; my $secUtil = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'; my $securityHeader = SOAP::Header->name("wsse:Security")->attr( { 'xmlns:wsse'=> $secExt, 'xmlns:wsu'=> $secUtil } ); my $timestamp = SOAP::Data->name("wsu:Timestamp" => \SOAP::Data->value( SOAP::Data->name('wsu:Created')->value($created) ->type(''), SOAP::Data->name('wsu:Expires')->value($expires) ->type(''))); my $usernameTokenType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"; my $usernameToken = SOAP::Data->name("wsse:UsernameToken" => \SOAP::Data->value( SOAP::Data->name('wsse:Username')->value($user) ->type(''), SOAP::Data->name('wsse:Password')->value($pass) ->type('') ->attr({'Type'=>$usernameTokenType}))); $securityHeader->value(\SOAP::Data->value($timestamp, $usernameToken)); return $securityHeader; } sub objdump { my ($obj, $indent) = @_; my $content = ''; if (!defined $obj) { return $content; } if (!defined $indent) { $indent = ' '; } my $type = ref $obj; if (!defined $type || $type eq '' || $type eq 'SCALAR') { $content = $content . $indent . $obj . "\n"; } elsif ($type eq 'ARRAY') { foreach my $node (@$obj) { $content = $content . objdump($node, $indent); } } else { my $key; my $value; while (($key, $value) = each %$obj) { my $type2 = ref $value; if (!defined $type2 || $type2 eq '' || $type2 eq 'SCALAR') { $content = $content . $indent . "\'$key\' => $value;\n"; } else { $content = $content . $indent . "\'$key\' => {\n"; $content = $content . objdump($value, $indent.' '); $content = $content . $indent . "}\n"; } } } return $content; } sub ConvertNetworkPortToSoapData { my ($portListRef) = @_; my @dataArray; foreach my $port (@$portListRef) { my $sport = SOAP::Data->name("ports")->value(\SOAP::Data->value( SOAP::Data->name("slot")->value($port->{'slot'}), SOAP::Data->name("port")->value($port->{'port'}))); push(@dataArray, $sport); } return @dataArray; }348Views0likes0Commentspython bigsuds - Get Orphaned iRules
Problem this snippet solves: This python bigsuds script will get a list of all iRules that are not associated with a virtual server (orphaned). How to use this snippet: orphanedrules.py <hostname> <username> Script will prompt for password. Script orphanedrules.py Code : #!/usr/bin/env python __author__ = 'buzzsurfr' __version__ = '0.1' def get_orphaned_rules(obj, recursive = True): ''' Gets a list of orphaned rules. Prototype String [] get_orphaned_rules( BIGIP.bigip obj, bool recursive = True ); Parameters obj of type BIGIP.bigip contains the established connection. recursive of type boolean indicates whether to perform a recursive search throughout the entire configuration. Defaults to True. Return Type String [] containing the list of all orphaned rules. ''' # Get current values to override for search active_folder = obj.System.Session.get_active_folder() recursive_query_state = obj.System.Session.get_recursive_query_state() # Enable fully-recursive search if recursive: obj.System.Session.set_active_folder('/') obj.System.Session.set_recursive_query_state("STATE_ENABLED") # Get list of iRules rules = obj.LocalLB.Rule.get_list() # Create starting list of orphaned iRules. These will be removed from # list as they are found to be in use. orphaned_rules = rules # Get list of all iRules associated on virtual servers vs_rules = obj.LocalLB.VirtualServer.get_rule(obj.LocalLB.VirtualServer.get_list()) # Check each virtual server for iRules and remove from orphaned if exists for virtual_server in vs_rules: for rule in virtual_server: if rule['rule_name'] in rules: # If found, remove from orphaned_rules orphaned_rules.remove(rule['rule_name']) # Reset values overridden for search if recursive: obj.System.Session.set_active_folder(active_folder) obj.System.Session.set_recursive_query_state(recursive_query_state) return orphaned_rules # Instance Mode (Run as script) if __name__ == "__main__": # Standard Library import sys # Related Third-Party import getpass # Local Application/Library Specific import bigsuds if len(sys.argv) < 3: print "\n\n\tUsage: %s ip_address username" % sys.argv[0] sys.exit() # Get password from CLI userpass = getpass.getpass() # Connect to BIG-IP try: bigconn = bigsuds.BIGIP( hostname = sys.argv[1], username = sys.argv[2], password = userpass ) except Exception as e: print e orphans = get_orphaned_rules(bigconn) print "Orphaned iRules" for orphan in orphans: print "\t" + orphan Tested this on version: 11.5206Views0likes0Commentspython bigsuds - Reverse Lookup (Node -> Pool)
Problem this snippet solves: This python bigsuds script prints the list of pools using a specific node. How to use this snippet: rlookup-node.py <hostname> <username> <nodename> This will only search the Common partition. Code : #!/usr/bin/env python __author__ = 'buzzsurfr' __version__ = '0.1' # Standard Library import sys import re # Related Third-Party import getpass # Local Application/Library Specific import bigsuds if len(sys.argv) < 4: print "\n\n\tUsage: %s host user node" % sys.argv[0] sys.exit() # Get login password from CLI userpass = getpass.getpass() # Connect to BIG-IP b = bigsuds.BIGIP(sys.argv[1], sys.argv[2], userpass) # Get list of pools and pool members pools = b.LocalLB.Pool.get_list() pool_members = b.LocalLB.Pool.get_member_v2(pools) # Node to search for node = sys.argv[3] if len(node) < 8 or node[:8] != '/Common/': node = '/Common/'+node print "Pools using Node "+node # Iterate through pool member list (has a list of members per pool referenced) looking for node for i, pool in enumerate(pool_members): for member in pool: if node == member['address']: print "\t"+pools[i] Tested this on version: 11.5194Views0likes0Commentspython bigsuds - Reverse Lookup (Pool -> Virtual Server)
Problem this snippet solves: This python bigsuds script prints the list of virtual servers using a specific pool. How to use this snippet: rlookup-pool.py <hostname> <username> <poolname> This will only search the Common partition. This also does not check for policies or iRules that may change the value of pool. Code : #!/usr/bin/env python __author__ = 'buzzsurfr' __version__ = '0.1' # Standard Library import sys import re # Related Third-Party import getpass # Local Application/Library Specific import bigsuds if len(sys.argv) < 4: print "\n\n\tUsage: %s host user pool" % sys.argv[0] sys.exit() # Get login password from CLI userpass = getpass.getpass() # Connect to BIG-IP b = bigsuds.BIGIP(sys.argv[1], sys.argv[2], userpass) pool = sys.argv[3] if len(pool) < 8 or pool[:8] != '/Common/': pool = '/Common/'+pool print "Virtual Servers using Pool "+pool # Get list of pools and pool members virtual_servers = b.LocalLB.VirtualServer.get_list() vs_pools = b.LocalLB.VirtualServer.get_default_pool_name(virtual_servers) # Iterate through pool member list (has a list of members per pool referenced) looking for node for i, vs_pool in enumerate(vs_pools): if pool == vs_pool: print "\t"+virtual_servers[i] Tested this on version: 11.5233Views0likes0Commentspython bigsuds - Connect to Active Device
Problem this snippet solves: Connects to the active member of a Device Group regardless of the original hostname. Can be used as a function or as a command-line call. How to use this snippet: bigip-active.py <hostname> <username> Script will prompt for password. Code : #!/usr/bin/env python # # bigip_active: Connects to the active member of a Device Group regardless of # the original hostname. __author__ = 'buzzsurfr' __version__ = '0.1' # Standard Library import sys import itertools # Related Third-Party import getpass # Local Application/Library Specific import bigsuds def bigip_active(hostname, username='admin', password='admin', debug=False, cachedir=None, verify=False, timeout=90): # Connect to specified BIG-IP b = bigsuds.BIGIP(hostname, username, password, debug, cachedir, verify, timeout) # Determine whether device is active if(b.Management.DeviceGroup.get_failover_status()['status'] != 'ACTIVE'): local_device = b.Management.Device.get_local_device() new_device = False for device in list(set(itertools.chain.from_iterable(b.Management.DeviceGroup.get_device(b.Management.DeviceGroup.get_list())))).remove(local_device): if(b.Management.Device.get_failover_state(device) == 'HA_STATE_ACTIVE'): new_device = device if(new_device): print b.Management.Device.get_local_device()[8:]+" is not active. Switching to "+new_device[8:] b = bigsuds.BIGIP(new_device[8:], username, password, debug, cachedir, verify, timeout) return b if __name__ == '__main__': bigip_active(sys.argv[1], sys.argv[2], getpass.getpass()) Tested this on version: 11.5224Views0likes0Comments