summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/network/f5/bigip_gtm_monitor_https.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/modules/network/f5/bigip_gtm_monitor_https.py')
-rw-r--r--lib/ansible/modules/network/f5/bigip_gtm_monitor_https.py960
1 files changed, 0 insertions, 960 deletions
diff --git a/lib/ansible/modules/network/f5/bigip_gtm_monitor_https.py b/lib/ansible/modules/network/f5/bigip_gtm_monitor_https.py
deleted file mode 100644
index c88b20eaae..0000000000
--- a/lib/ansible/modules/network/f5/bigip_gtm_monitor_https.py
+++ /dev/null
@@ -1,960 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright: (c) 2017, F5 Networks Inc.
-# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'certified'}
-
-DOCUMENTATION = r'''
----
-module: bigip_gtm_monitor_https
-short_description: Manages F5 BIG-IP GTM https monitors
-description:
- - Manages F5 BIG-IP GTM https monitors.
-version_added: 2.6
-options:
- name:
- description:
- - Monitor name.
- type: str
- required: True
- parent:
- description:
- - The parent template of this monitor template. Once this value has
- been set, it cannot be changed. By default, this value is the C(tcp)
- parent on the C(Common) partition.
- type: str
- default: /Common/https
- send:
- description:
- - The send string for the monitor call.
- - When creating a new monitor, if this parameter is not provided, the
- default of C(GET /\r\n) will be used.
- type: str
- receive:
- description:
- - The receive string for the monitor call.
- type: str
- ip:
- description:
- - IP address part of the IP/port definition. If this parameter is not
- provided when creating a new monitor, then the default value will be
- '*'.
- - If this value is an IP address, then a C(port) number must be specified.
- type: str
- port:
- description:
- - Port address part of the IP/port definition. If this parameter is not
- provided when creating a new monitor, then the default value will be
- '*'. Note that if specifying an IP address, a value between 1 and 65535
- must be specified.
- type: str
- interval:
- description:
- - The interval specifying how frequently the monitor instance of this
- template will run.
- - If this parameter is not provided when creating a new monitor, then
- the default value will be 30.
- - This value B(must) be less than the C(timeout) value.
- type: int
- timeout:
- description:
- - The number of seconds in which the node or service must respond to
- the monitor request. If the target responds within the set time
- period, it is considered up. If the target does not respond within
- the set time period, it is considered down. You can change this
- number to any number you want, however, it should be 3 times the
- interval number of seconds plus 1 second.
- - If this parameter is not provided when creating a new monitor, then the
- default value will be 120.
- type: int
- partition:
- description:
- - Device partition to manage resources on.
- type: str
- default: Common
- state:
- description:
- - When C(present), ensures that the monitor exists.
- - When C(absent), ensures the monitor is removed.
- type: str
- choices:
- - present
- - absent
- default: present
- probe_timeout:
- description:
- - Specifies the number of seconds after which the system times out the probe request
- to the system.
- - When creating a new monitor, if this parameter is not provided, then the default
- value will be C(5).
- type: int
- ignore_down_response:
- description:
- - Specifies that the monitor allows more than one probe attempt per interval.
- - When C(yes), specifies that the monitor ignores down responses for the duration of
- the monitor timeout. Once the monitor timeout is reached without the system receiving
- an up response, the system marks the object down.
- - When C(no), specifies that the monitor immediately marks an object down when it
- receives a down response.
- - When creating a new monitor, if this parameter is not provided, then the default
- value will be C(no).
- type: bool
- transparent:
- description:
- - Specifies whether the monitor operates in transparent mode.
- - A monitor in transparent mode directs traffic through the associated pool members
- or nodes (usually a router or firewall) to the aliased destination (that is, it
- probes the C(ip)-C(port) combination specified in the monitor).
- - If the monitor cannot successfully reach the aliased destination, the pool member
- or node through which the monitor traffic was sent is marked down.
- - When creating a new monitor, if this parameter is not provided, then the default
- value will be C(no).
- type: bool
- reverse:
- description:
- - Instructs the system to mark the target resource down when the test is successful.
- This setting is useful, for example, if the content on your web site home page is
- dynamic and changes frequently, you may want to set up a reverse ECV service check
- that looks for the string Error.
- - A match for this string means that the web server was down.
- - To use this option, you must specify values for C(send) and C(receive).
- type: bool
- target_username:
- description:
- - Specifies the user name, if the monitored target requires authentication.
- type: str
- target_password:
- description:
- - Specifies the password, if the monitored target requires authentication.
- type: str
- update_password:
- description:
- - C(always) will update passwords if the C(target_password) is specified.
- - C(on_create) will only set the password for newly created monitors.
- type: str
- choices:
- - always
- - on_create
- default: always
- cipher_list:
- description:
- - Specifies the list of ciphers for this monitor.
- - The items in the cipher list are separated with the colon C(:) symbol.
- - When creating a new monitor, if this parameter is not specified, the default
- list is C(DEFAULT:+SHA:+3DES:+kEDH).
- type: str
- compatibility:
- description:
- - Specifies, when enabled, that the SSL options setting (in OpenSSL) is set to B(all).
- - When creating a new monitor, if this value is not specified, the default is
- C(yes)
- type: bool
- client_cert:
- description:
- - Specifies a fully-qualified path for a client certificate that the monitor sends to
- the target SSL server.
- type: str
- client_key:
- description:
- - Specifies a key for a client certificate that the monitor sends to the target SSL server.
- type: str
-extends_documentation_fragment: f5
-author:
- - Tim Rupp (@caphrim007)
- - Wojciech Wypior (@wojtek0806)
-'''
-
-EXAMPLES = r'''
-- name: Create a GTM HTTPS monitor
- bigip_gtm_monitor_https:
- name: my_monitor
- ip: 1.1.1.1
- port: 80
- send: my send string
- receive: my receive string
- state: present
- provider:
- user: admin
- password: secret
- server: lb.mydomain.com
- delegate_to: localhost
-
-- name: Remove HTTPS Monitor
- bigip_gtm_monitor_https:
- name: my_monitor
- state: absent
- provider:
- user: admin
- password: secret
- server: lb.mydomain.com
- delegate_to: localhost
-
-- name: Add HTTPS monitor for all addresses, port 514
- bigip_gtm_monitor_https:
- name: my_monitor
- provider:
- user: admin
- password: secret
- server: lb.mydomain.com
- port: 514
- delegate_to: localhost
-'''
-
-RETURN = r'''
-parent:
- description: New parent template of the monitor.
- returned: changed
- type: str
- sample: https
-ip:
- description: The new IP of IP/port definition.
- returned: changed
- type: str
- sample: 10.12.13.14
-port:
- description: The new port the monitor checks the resource on.
- returned: changed
- type: str
- sample: 8080
-interval:
- description: The new interval in which to run the monitor check.
- returned: changed
- type: int
- sample: 2
-timeout:
- description: The new timeout in which the remote system must respond to the monitor.
- returned: changed
- type: int
- sample: 10
-ignore_down_response:
- description: Whether to ignore the down response or not.
- returned: changed
- type: bool
- sample: True
-send:
- description: The new send string for this monitor.
- returned: changed
- type: str
- sample: tcp string to send
-receive:
- description: The new receive string for this monitor.
- returned: changed
- type: str
- sample: tcp string to receive
-probe_timeout:
- description: The new timeout in which the system will timeout the monitor probe.
- returned: changed
- type: int
- sample: 10
-reverse:
- description: The new value for whether the monitor operates in reverse mode.
- returned: changed
- type: bool
- sample: False
-transparent:
- description: The new value for whether the monitor operates in transparent mode.
- returned: changed
- type: bool
- sample: False
-cipher_list:
- description: The new value for the cipher list.
- returned: changed
- type: str
- sample: +3DES:+kEDH
-compatibility:
- description: The new SSL compatibility setting.
- returned: changed
- type: bool
- sample: True
-client_cert:
- description: The new client cert setting.
- returned: changed
- type: str
- sample: /Common/default
-client_key:
- description: The new client key setting.
- returned: changed
- type: str
- sample: /Common/default
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.basic import env_fallback
-
-try:
- from library.module_utils.network.f5.bigip import F5RestClient
- from library.module_utils.network.f5.common import F5ModuleError
- from library.module_utils.network.f5.common import AnsibleF5Parameters
- from library.module_utils.network.f5.common import fq_name
- from library.module_utils.network.f5.common import f5_argument_spec
- from library.module_utils.network.f5.common import transform_name
- from library.module_utils.network.f5.icontrol import module_provisioned
- from library.module_utils.network.f5.ipaddress import is_valid_ip
-except ImportError:
- from ansible.module_utils.network.f5.bigip import F5RestClient
- from ansible.module_utils.network.f5.common import F5ModuleError
- from ansible.module_utils.network.f5.common import AnsibleF5Parameters
- from ansible.module_utils.network.f5.common import fq_name
- from ansible.module_utils.network.f5.common import f5_argument_spec
- from ansible.module_utils.network.f5.common import transform_name
- from ansible.module_utils.network.f5.icontrol import module_provisioned
- from ansible.module_utils.network.f5.ipaddress import is_valid_ip
-
-
-class Parameters(AnsibleF5Parameters):
- api_map = {
- 'defaultsFrom': 'parent',
- 'ignoreDownResponse': 'ignore_down_response',
- 'probeTimeout': 'probe_timeout',
- 'recv': 'receive',
- 'username': 'target_username',
- 'password': 'target_password',
- 'cipherlist': 'cipher_list',
- 'cert': 'client_cert',
- 'key': 'client_key',
- }
-
- api_attributes = [
- 'defaultsFrom',
- 'interval',
- 'timeout',
- 'destination',
- 'transparent',
- 'probeTimeout',
- 'ignoreDownResponse',
- 'reverse',
- 'send',
- 'recv',
- 'username',
- 'password',
- 'cipherlist',
- 'compatibility',
- 'cert',
- 'key',
- ]
-
- returnables = [
- 'parent',
- 'ip',
- 'port',
- 'interval',
- 'timeout',
- 'transparent',
- 'probe_timeout',
- 'ignore_down_response',
- 'send',
- 'receive',
- 'reverse',
- 'cipher_list',
- 'compatibility',
- 'client_cert',
- 'client_key',
- ]
-
- updatables = [
- 'destination',
- 'interval',
- 'timeout',
- 'transparent',
- 'probe_timeout',
- 'ignore_down_response',
- 'send',
- 'receive',
- 'reverse',
- 'ip',
- 'port',
- 'target_username',
- 'target_password',
- 'cipher_list',
- 'compatibility',
- 'client_cert',
- 'client_key',
- ]
-
-
-class ApiParameters(Parameters):
- @property
- def ip(self):
- ip, port = self._values['destination'].split(':')
- return ip
-
- @property
- def port(self):
- ip, port = self._values['destination'].split(':')
- try:
- return int(port)
- except ValueError:
- return port
-
- @property
- def ignore_down_response(self):
- if self._values['ignore_down_response'] is None:
- return None
- if self._values['ignore_down_response'] == 'disabled':
- return False
- return True
-
- @property
- def transparent(self):
- if self._values['transparent'] is None:
- return None
- if self._values['transparent'] == 'disabled':
- return False
- return True
-
- @property
- def reverse(self):
- if self._values['reverse'] is None:
- return None
- if self._values['reverse'] == 'disabled':
- return False
- return True
-
- @property
- def compatibility(self):
- if self._values['compatibility'] is None:
- return None
- if self._values['compatibility'] == 'disabled':
- return False
- return True
-
-
-class ModuleParameters(Parameters):
- @property
- def interval(self):
- if self._values['interval'] is None:
- return None
- if 1 > int(self._values['interval']) > 86400:
- raise F5ModuleError(
- "Interval value must be between 1 and 86400"
- )
- return int(self._values['interval'])
-
- @property
- def timeout(self):
- if self._values['timeout'] is None:
- return None
- return int(self._values['timeout'])
-
- @property
- def ip(self):
- if self._values['ip'] is None:
- return None
- if self._values['ip'] in ['*', '0.0.0.0']:
- return '*'
- elif is_valid_ip(self._values['ip']):
- return self._values['ip']
- else:
- raise F5ModuleError(
- "The provided 'ip' parameter is not an IP address."
- )
-
- @property
- def parent(self):
- if self._values['parent'] is None:
- return None
- result = fq_name(self.partition, self._values['parent'])
- return result
-
- @property
- def port(self):
- if self._values['port'] is None:
- return None
- elif self._values['port'] == '*':
- return '*'
- return int(self._values['port'])
-
- @property
- def destination(self):
- if self.ip is None and self.port is None:
- return None
- destination = '{0}:{1}'.format(self.ip, self.port)
- return destination
-
- @destination.setter
- def destination(self, value):
- ip, port = value.split(':')
- self._values['ip'] = ip
- self._values['port'] = port
-
- @property
- def probe_timeout(self):
- if self._values['probe_timeout'] is None:
- return None
- return int(self._values['probe_timeout'])
-
- @property
- def type(self):
- return 'https'
-
- @property
- def client_cert(self):
- if self._values['client_cert'] is None:
- return None
- if self._values['client_cert'] == '':
- return ''
- result = fq_name(self.partition, self._values['client_cert'])
- if not result.endswith('.crt'):
- result += '.crt'
- return result
-
- @property
- def client_key(self):
- if self._values['client_key'] is None:
- return None
- if self._values['client_key'] == '':
- return ''
- result = fq_name(self.partition, self._values['client_key'])
- if not result.endswith('.key'):
- result += '.key'
- return result
-
-
-class Changes(Parameters):
- def to_return(self):
- result = {}
- try:
- for returnable in self.returnables:
- result[returnable] = getattr(self, returnable)
- result = self._filter_params(result)
- except Exception:
- pass
- return result
-
-
-class UsableChanges(Changes):
- @property
- def transparent(self):
- if self._values['transparent'] is None:
- return None
- elif self._values['transparent'] is True:
- return 'enabled'
- return 'disabled'
-
- @property
- def ignore_down_response(self):
- if self._values['ignore_down_response'] is None:
- return None
- elif self._values['ignore_down_response'] is True:
- return 'enabled'
- return 'disabled'
-
- @property
- def reverse(self):
- if self._values['reverse'] is None:
- return None
- elif self._values['reverse'] is True:
- return 'enabled'
- return 'disabled'
-
- @property
- def compatibility(self):
- if self._values['compatibility'] is None:
- return None
- elif self._values['compatibility'] is True:
- return 'enabled'
- return 'disabled'
-
-
-class ReportableChanges(Changes):
- @property
- def ip(self):
- ip, port = self._values['destination'].split(':')
- return ip
-
- @property
- def port(self):
- ip, port = self._values['destination'].split(':')
- return int(port)
-
- @property
- def transparent(self):
- if self._values['transparent'] == 'enabled':
- return True
- return False
-
- @property
- def ignore_down_response(self):
- if self._values['ignore_down_response'] == 'enabled':
- return True
- return False
-
- @property
- def reverse(self):
- if self._values['reverse'] == 'enabled':
- return True
- return False
-
- @property
- def compatibility(self):
- if self._values['compatibility'] == 'enabled':
- return True
- return False
-
-
-class Difference(object):
- def __init__(self, want, have=None):
- self.want = want
- self.have = have
-
- def compare(self, param):
- try:
- result = getattr(self, param)
- return result
- except AttributeError:
- return self.__default(param)
-
- def __default(self, param):
- attr1 = getattr(self.want, param)
- try:
- attr2 = getattr(self.have, param)
- if attr1 != attr2:
- return attr1
- except AttributeError:
- return attr1
-
- @property
- def parent(self):
- if self.want.parent != self.have.parent:
- raise F5ModuleError(
- "The parent monitor cannot be changed"
- )
-
- @property
- def destination(self):
- if self.want.ip is None and self.want.port is None:
- return None
- if self.want.port is None:
- self.want.update({'port': self.have.port})
- if self.want.ip is None:
- self.want.update({'ip': self.have.ip})
-
- if self.want.port in [None, '*'] and self.want.ip != '*':
- raise F5ModuleError(
- "Specifying an IP address requires that a port number be specified"
- )
-
- if self.want.destination != self.have.destination:
- return self.want.destination
-
- @property
- def interval(self):
- if self.want.timeout is not None and self.want.interval is not None:
- if self.want.interval >= self.want.timeout:
- raise F5ModuleError(
- "Parameter 'interval' must be less than 'timeout'."
- )
- elif self.want.timeout is not None:
- if self.have.interval >= self.want.timeout:
- raise F5ModuleError(
- "Parameter 'interval' must be less than 'timeout'."
- )
- elif self.want.interval is not None:
- if self.want.interval >= self.have.timeout:
- raise F5ModuleError(
- "Parameter 'interval' must be less than 'timeout'."
- )
- if self.want.interval != self.have.interval:
- return self.want.interval
-
- @property
- def target_password(self):
- if self.want.target_password != self.have.target_password:
- if self.want.update_password == 'always':
- result = self.want.target_password
- return result
-
- @property
- def client_cert(self):
- if self.have.client_cert is None and self.want.client_cert == '':
- return None
- if self.have.client_cert != self.want.client_cert:
- return self.want.client_cert
-
- @property
- def client_key(self):
- if self.have.client_key is None and self.want.client_key == '':
- return None
- if self.have.client_key != self.want.client_key:
- return self.want.client_key
-
-
-class ModuleManager(object):
- def __init__(self, *args, **kwargs):
- self.module = kwargs.get('module', None)
- self.client = F5RestClient(**self.module.params)
- self.want = ModuleParameters(params=self.module.params)
- self.have = ApiParameters()
- self.changes = UsableChanges()
-
- def _set_changed_options(self):
- changed = {}
- for key in Parameters.returnables:
- if getattr(self.want, key) is not None:
- changed[key] = getattr(self.want, key)
- if changed:
- self.changes = UsableChanges(params=changed)
-
- def _update_changed_options(self):
- diff = Difference(self.want, self.have)
- updatables = Parameters.updatables
- changed = dict()
- for k in updatables:
- change = diff.compare(k)
- if change is None:
- continue
- else:
- if isinstance(change, dict):
- changed.update(change)
- else:
- changed[k] = change
- if changed:
- self.changes = UsableChanges(params=changed)
- return True
- return False
-
- def should_update(self):
- result = self._update_changed_options()
- if result:
- return True
- return False
-
- def _announce_deprecations(self, result):
- warnings = result.pop('__warnings', [])
- for warning in warnings:
- self.client.module.deprecate(
- msg=warning['msg'],
- version=warning['version']
- )
-
- def _set_default_creation_values(self):
- if self.want.timeout is None:
- self.want.update({'timeout': 120})
- if self.want.interval is None:
- self.want.update({'interval': 30})
- if self.want.probe_timeout is None:
- self.want.update({'probe_timeout': 5})
- if self.want.ip is None:
- self.want.update({'ip': '*'})
- if self.want.port is None:
- self.want.update({'port': '*'})
- if self.want.ignore_down_response is None:
- self.want.update({'ignore_down_response': False})
- if self.want.transparent is None:
- self.want.update({'transparent': False})
- if self.want.send is None:
- self.want.update({'send': 'GET /\r\n'})
- if self.want.cipher_list is None:
- self.want.update({'cipher_list': 'DEFAULT:+SHA:+3DES:+kEDH'})
- if self.want.compatibility is None:
- self.want.update({'compatibility': True})
-
- def exec_module(self):
- if not module_provisioned(self.client, 'gtm'):
- raise F5ModuleError(
- "GTM must be provisioned to use this module."
- )
- changed = False
- result = dict()
- state = self.want.state
-
- if state == "present":
- changed = self.present()
- elif state == "absent":
- changed = self.absent()
-
- reportable = ReportableChanges(params=self.changes.to_return())
- changes = reportable.to_return()
- result.update(**changes)
- result.update(dict(changed=changed))
- self._announce_deprecations(result)
- return result
-
- def present(self):
- if self.exists():
- return self.update()
- else:
- return self.create()
-
- def absent(self):
- if self.exists():
- return self.remove()
- return False
-
- def update(self):
- self.have = self.read_current_from_device()
- if not self.should_update():
- return False
- if self.module.check_mode:
- return True
- self.update_on_device()
- return True
-
- def remove(self):
- if self.module.check_mode:
- return True
- self.remove_from_device()
- if self.exists():
- raise F5ModuleError("Failed to delete the resource.")
- return True
-
- def create(self):
- self._set_default_creation_values()
- self._set_changed_options()
- if self.module.check_mode:
- return True
- self.create_on_device()
- return True
-
- def exists(self):
- uri = "https://{0}:{1}/mgmt/tm/gtm/monitor/https/{2}".format(
- self.client.provider['server'],
- self.client.provider['server_port'],
- transform_name(self.want.partition, self.want.name),
- )
- resp = self.client.api.get(uri)
- try:
- response = resp.json()
- except ValueError:
- return False
- if resp.status == 404 or 'code' in response and response['code'] == 404:
- return False
- return True
-
- def create_on_device(self):
- params = self.changes.api_params()
- params['name'] = self.want.name
- params['partition'] = self.want.partition
- uri = "https://{0}:{1}/mgmt/tm/gtm/monitor/https/".format(
- self.client.provider['server'],
- self.client.provider['server_port'],
- )
- resp = self.client.api.post(uri, json=params)
- try:
- response = resp.json()
- except ValueError as ex:
- raise F5ModuleError(str(ex))
-
- if 'code' in response and response['code'] in [400, 403]:
- if 'message' in response:
- raise F5ModuleError(response['message'])
- else:
- raise F5ModuleError(resp.content)
- return response['selfLink']
-
- def update_on_device(self):
- params = self.changes.api_params()
- uri = "https://{0}:{1}/mgmt/tm/gtm/monitor/https/{2}".format(
- self.client.provider['server'],
- self.client.provider['server_port'],
- transform_name(self.want.partition, self.want.name),
- )
- resp = self.client.api.patch(uri, json=params)
- try:
- response = resp.json()
- except ValueError as ex:
- raise F5ModuleError(str(ex))
-
- if 'code' in response and response['code'] == 400:
- if 'message' in response:
- raise F5ModuleError(response['message'])
- else:
- raise F5ModuleError(resp.content)
-
- def remove_from_device(self):
- uri = "https://{0}:{1}/mgmt/tm/gtm/monitor/https/{2}".format(
- self.client.provider['server'],
- self.client.provider['server_port'],
- transform_name(self.want.partition, self.want.name),
- )
- response = self.client.api.delete(uri)
- if response.status == 200:
- return True
- raise F5ModuleError(response.content)
-
- def read_current_from_device(self):
- uri = "https://{0}:{1}/mgmt/tm/gtm/monitor/https/{2}".format(
- self.client.provider['server'],
- self.client.provider['server_port'],
- transform_name(self.want.partition, self.want.name),
- )
- resp = self.client.api.get(uri)
- try:
- response = resp.json()
- except ValueError as ex:
- raise F5ModuleError(str(ex))
-
- if 'code' in response and response['code'] == 400:
- if 'message' in response:
- raise F5ModuleError(response['message'])
- else:
- raise F5ModuleError(resp.content)
- return ApiParameters(params=response)
-
-
-class ArgumentSpec(object):
- def __init__(self):
- self.supports_check_mode = True
- argument_spec = dict(
- name=dict(required=True),
- parent=dict(default='/Common/https'),
- send=dict(),
- receive=dict(),
- ip=dict(),
- port=dict(),
- interval=dict(type='int'),
- timeout=dict(type='int'),
- ignore_down_response=dict(type='bool'),
- transparent=dict(type='bool'),
- probe_timeout=dict(type='int'),
- reverse=dict(type='bool'),
- target_username=dict(),
- target_password=dict(no_log=True),
- cipher_list=dict(),
- compatibility=dict(type='bool'),
- client_cert=dict(),
- client_key=dict(),
- update_password=dict(
- default='always',
- choices=['always', 'on_create']
- ),
- state=dict(
- default='present',
- choices=['present', 'absent']
- ),
- partition=dict(
- default='Common',
- fallback=(env_fallback, ['F5_PARTITION'])
- )
- )
- self.argument_spec = {}
- self.argument_spec.update(f5_argument_spec)
- self.argument_spec.update(argument_spec)
-
-
-def main():
- spec = ArgumentSpec()
-
- module = AnsibleModule(
- argument_spec=spec.argument_spec,
- supports_check_mode=spec.supports_check_mode,
- )
-
- try:
- mm = ModuleManager(module=module)
- results = mm.exec_module()
- module.exit_json(**results)
- except F5ModuleError as ex:
- module.fail_json(msg=str(ex))
-
-
-if __name__ == '__main__':
- main()