Various f5 fixes (#44858)

* Remove sdk from modules
* Correct IP address bugs in data_group
* Correct compare_dictionary bug in several modules
This commit is contained in:
Tim Rupp 2018-08-29 16:08:37 -07:00 committed by GitHub
commit 5bdcaff921
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 359 additions and 284 deletions

View file

@ -265,7 +265,7 @@ try:
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 cleanup_tokens
from library.module_utils.network.f5.common import compare_dictionary
from library.module_utils.network.f5.common import compare_complex_list
from library.module_utils.network.f5.common import f5_argument_spec
from library.module_utils.network.f5.ipaddress import is_valid_ip
from library.module_utils.network.f5.ipaddress import is_valid_ip_network
@ -283,7 +283,7 @@ except ImportError:
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 cleanup_tokens
from ansible.module_utils.network.f5.common import compare_dictionary
from ansible.module_utils.network.f5.common import compare_complex_list
from ansible.module_utils.network.f5.common import f5_argument_spec
from ansible.module_utils.network.f5.ipaddress import is_valid_ip
from ansible.module_utils.network.f5.ipaddress import is_valid_ip_network
@ -351,33 +351,24 @@ class RecordsEncoder(object):
return self.encode_string_from_dict(record)
def encode_address_from_dict(self, record):
if is_valid_ip_network(record['key']):
key = ip_network(u"{0}".format(str(record['key'])))
elif is_valid_ip(record['key']):
key = ip_address(u"{0}".format(str(record['key'])))
elif is_valid_ip_interface(record['key']):
if is_valid_ip_interface(record['key']):
key = ip_interface(u"{0}".format(str(record['key'])))
else:
raise F5ModuleError(
"When specifying an 'address' type, the value to the left of the separator must be an IP."
)
if key and 'value' in record:
try:
# Only ip_address's have max_prefixlen
if key.max_prefixlen in [32, 128]:
return self.encode_host(str(key), record['value'])
except ValueError:
return self.encode_network(
str(key.network_address), key.prefixlen, record['value'])
if key.network.prefixlen in [32, 128]:
return self.encode_host(str(key.ip), record['value'])
return self.encode_network(
str(key.network.network_address), key.network.prefixlen, record['value']
)
elif key:
try:
# Only ip_address's have max_prefixlen
if key.max_prefixlen in [32, 128]:
return self.encode_host(str(key), str(key))
except ValueError:
return self.encode_network(
str(key.network_address), key.prefixlen, str(key.network_address)
)
if key.network.prefixlen in [32, 128]:
return self.encode_host(str(key.ip), str(key.ip))
return self.encode_network(
str(key.network.network_address), key.network.prefixlen, str(key.network.network_address)
)
def encode_integer_from_dict(self, record):
try:
@ -418,37 +409,27 @@ class RecordsEncoder(object):
else:
# 192.168.0.0/16 := "Network3",
# 2402:9400:1000:0::/64 := "Network4",
parts = record.split(self._separator)
if is_valid_ip_network(parts[0]):
key = ip_network(u"{0}".format(str(parts[0])))
elif is_valid_ip(parts[0]):
key = ip_address(u"{0}".format(str(parts[0])))
elif is_valid_ip_interface(parts[0]):
key = ip_interface(u"{0}".format(str(parts[0])))
elif parts[0] == '':
pass
else:
raise F5ModuleError(
"When specifying an 'address' type, the value to the left of the separator must be an IP."
)
parts = record.split(self._separator)
if parts[0] == '':
return
if not is_valid_ip_interface(parts[0]):
raise F5ModuleError(
"When specifying an 'address' type, the value to the left of the separator must be an IP."
)
key = ip_interface(u"{0}".format(str(parts[0])))
if len(parts) == 2:
try:
# Only ip_address's have max_prefixlen
if key.max_prefixlen in [32, 128]:
return self.encode_host(str(key), parts[1])
except ValueError:
return self.encode_network(
str(key.network_address), key.prefixlen, parts[1])
elif len(parts) == 1 and parts[0] != '':
try:
# Only ip_address's have max_prefixlen
if key.max_prefixlen in [32, 128]:
return self.encode_host(str(key), str(key))
except ValueError:
return self.encode_network(
str(key.network_address), key.prefixlen, str(key.network_address)
)
if len(parts) == 2:
if key.network.prefixlen in [32, 128]:
return self.encode_host(str(key.ip), parts[1])
return self.encode_network(
str(key.network.network_address), key.network.prefixlen, parts[1]
)
elif len(parts) == 1 and parts[0] != '':
if key.network.prefixlen in [32, 128]:
return self.encode_host(str(key.ip), str(key.ip))
return self.encode_network(
str(key.network.network_address), key.network.prefixlen, str(key.network.network_address)
)
def encode_host(self, key, value):
return 'host {0} {1} {2}'.format(str(key), self._separator, str(value))
@ -706,7 +687,7 @@ class Difference(object):
return None
if self.have.records is None:
return self.want.records
result = compare_dictionary(self.want.records, self.have.records)
result = compare_complex_list(self.want.records, self.have.records)
return result
@property

View file

@ -415,7 +415,7 @@ class Difference(object):
)
result = dict()
different = compare_dictionary([self.want.variables], [self.have.variables])
different = compare_dictionary(self.want.variables, self.have.variables)
if not different:
return None

View file

@ -244,13 +244,14 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback
try:
from library.module_utils.compat.ipaddress import ip_address
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
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 cleanup_tokens
from library.module_utils.network.f5.common import fq_name
from library.module_utils.network.f5.common import compare_dictionary
from library.module_utils.network.f5.common import compare_complex_list
from library.module_utils.network.f5.common import f5_argument_spec
from library.module_utils.network.f5.ipaddress import is_valid_ip
from library.module_utils.network.f5.ipaddress import validate_ip_v6_address
@ -260,13 +261,14 @@ try:
except ImportError:
HAS_F5SDK = False
except ImportError:
from ansible.module_utils.compat.ipaddress import ip_address
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
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 cleanup_tokens
from ansible.module_utils.network.f5.common import fq_name
from ansible.module_utils.network.f5.common import compare_dictionary
from ansible.module_utils.network.f5.common import compare_complex_list
from ansible.module_utils.network.f5.common import f5_argument_spec
from ansible.module_utils.network.f5.ipaddress import is_valid_ip
from ansible.module_utils.network.f5.ipaddress import validate_ip_v6_address
@ -534,7 +536,8 @@ class ModuleParameters(Parameters):
if self._values['address'] is None:
return None
if is_valid_ip(self._values['address']):
return self._values['address']
ip = str(ip_address(u'{0}'.format(self._values['address'])))
return ip
raise F5ModuleError(
"Specified 'address' is not an IP address."
)
@ -758,7 +761,8 @@ class Difference(object):
return None
if self.want.virtual_server_dependencies is None:
return None
return compare_dictionary(self.want.virtual_server_dependencies, self.have.virtual_server_dependencies)
result = compare_complex_list(self.want.virtual_server_dependencies, self.have.virtual_server_dependencies)
return result
@property
def enabled(self):

View file

@ -7,7 +7,6 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
@ -159,7 +158,6 @@ timeout:
sample: 10
'''
import os
import re
from ansible.module_utils.basic import AnsibleModule
@ -167,33 +165,29 @@ from ansible.module_utils.basic import env_fallback
from ansible.module_utils.six import iteritems
try:
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
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 cleanup_tokens
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.common import exit_json
from library.module_utils.network.f5.common import fail_json
from library.module_utils.network.f5.common import compare_dictionary
from library.module_utils.network.f5.ipaddress import is_valid_ip
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
except ImportError:
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
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 cleanup_tokens
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.common import compare_dictionary
from ansible.module_utils.network.f5.common import exit_json
from ansible.module_utils.network.f5.common import fail_json
from ansible.module_utils.network.f5.ipaddress import is_valid_ip
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
class Parameters(AnsibleF5Parameters):
@ -201,33 +195,24 @@ class Parameters(AnsibleF5Parameters):
'defaultsFrom': 'parent',
'apiRawValues': 'variables',
'run': 'external_program',
'args': 'arguments'
'args': 'arguments',
}
api_attributes = [
'defaultsFrom', 'interval', 'timeout', 'destination', 'run', 'args', 'description'
'defaultsFrom', 'interval', 'timeout', 'destination', 'run', 'args',
'description',
]
returnables = [
'parent', 'ip', 'port', 'interval', 'timeout', 'variables', 'external_program',
'arguments', 'description'
'arguments', 'description',
]
updatables = [
'destination', 'interval', 'timeout', 'variables', 'external_program',
'arguments', 'description'
'arguments', 'description',
]
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
@property
def destination(self):
if self.ip is None and self.port is None:
@ -285,11 +270,7 @@ class Parameters(AnsibleF5Parameters):
def parent(self):
if self._values['parent'] is None:
return None
if self._values['parent'].startswith('/'):
parent = os.path.basename(self._values['parent'])
result = '/{0}/{1}'.format(self.partition, parent)
else:
result = '/{0}/{1}'.format(self.partition, self._values['parent'])
result = fq_name(self.partition, self._values['parent'])
return result
@property
@ -426,8 +407,7 @@ class Difference(object):
variables=self.want.variables
)
result = dict()
different = compare_dictionary([self.want.variables], [self.have.variables])
different = compare_dictionary(self.want.variables, self.have.variables)
if not different:
return None
@ -491,13 +471,10 @@ class ModuleManager(object):
result = dict()
state = self.want.state
try:
if state == "present":
changed = self.present()
elif state == "absent":
changed = self.absent()
except iControlUnexpectedHTTPError as e:
raise F5ModuleError(str(e))
if state == "present":
changed = self.present()
elif state == "absent":
changed = self.absent()
reportable = ReportableChanges(params=self.changes.to_return())
changes = reportable.to_return()
@ -520,19 +497,19 @@ class ModuleManager(object):
else:
return self.create()
def create(self):
self._set_changed_options()
if self.want.timeout is None:
self.want.update({'timeout': 16})
if self.want.interval is None:
self.want.update({'interval': 5})
if self.want.ip is None:
self.want.update({'ip': '*'})
if self.want.port is None:
self.want.update({'port': '*'})
if self.module.check_mode:
return True
self.create_on_device()
def exists(self):
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/external/{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 update(self):
@ -544,70 +521,132 @@ class ModuleManager(object):
self.update_on_device()
return True
def absent(self):
if self.exists():
return self.remove()
return False
def remove(self):
if self.module.check_mode:
return True
self.remove_from_device()
if self.exists():
raise F5ModuleError("Failed to delete the monitor.")
raise F5ModuleError("Failed to delete the resource.")
return True
def read_current_from_device(self):
resource = self.client.api.tm.ltm.monitor.externals.external.load(
name=self.want.name,
partition=self.want.partition
)
result = resource.attrs
return ApiParameters(params=result)
def create(self):
self._set_changed_options()
self._set_default_creation_values()
if self.module.check_mode:
return True
self.create_on_device()
return True
def exists(self):
result = self.client.api.tm.ltm.monitor.externals.external.exists(
name=self.want.name,
partition=self.want.partition
)
return result
def _set_default_creation_values(self):
if self.want.timeout is None:
self.want.update({'timeout': 16})
if self.want.interval is None:
self.want.update({'interval': 5})
if self.want.ip is None:
self.want.update({'ip': '*'})
if self.want.port is None:
self.want.update({'port': '*'})
def update_on_device(self):
def create_on_device(self):
params = self.changes.api_params()
result = self.client.api.tm.ltm.monitor.externals.external.load(
name=self.want.name,
partition=self.want.partition
params['name'] = self.want.name
params['partition'] = self.want.partition
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/external/".format(
self.client.provider['server'],
self.client.provider['server_port']
)
if params:
result.modify(**params)
if self.changes.variables:
self.set_variable_on_device(self.changes.variables)
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)
if self.want.variables:
self.set_variable_on_device(self.want.variables)
def set_variable_on_device(self, commands):
command = ' '.join(['user-defined {0} \\\"{1}\\\"'.format(k, v) for k, v in iteritems(commands)])
command = 'tmsh modify ltm monitor external {0} {1}'.format(self.want.name, command)
self.client.api.tm.util.bash.exec_cmd(
'run',
uri = "https://{0}:{1}/mgmt/tm/util/bash".format(
self.client.provider['server'],
self.client.provider['server_port'],
)
args = dict(
command='run',
utilCmdArgs='-c "{0}"'.format(command)
)
resp = self.client.api.post(uri, json=args)
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 create_on_device(self):
params = self.want.api_params()
self.client.api.tm.ltm.monitor.externals.external.create(
name=self.want.name,
partition=self.want.partition,
**params
)
if self.want.variables:
self.set_variable_on_device(self.want.variables)
def update_on_device(self):
params = self.changes.api_params()
if params:
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/external/{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)
if self.changes.variables:
self.set_variable_on_device(self.changes.variables)
def absent(self):
if self.exists():
return self.remove()
return False
def remove_from_device(self):
result = self.client.api.tm.ltm.monitor.externals.external.load(
name=self.want.name,
partition=self.want.partition
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/external/{2}".format(
self.client.provider['server'],
self.client.provider['server_port'],
transform_name(self.want.partition, self.want.name)
)
if result:
result.delete()
resp = self.client.api.delete(uri)
if resp.status == 200:
return True
def read_current_from_device(self):
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/external/{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):
@ -643,20 +682,19 @@ def main():
module = AnsibleModule(
argument_spec=spec.argument_spec,
supports_check_mode=spec.supports_check_mode
supports_check_mode=spec.supports_check_mode,
)
if not HAS_F5SDK:
module.fail_json(msg="The python f5-sdk module is required")
client = F5RestClient(**module.params)
try:
client = F5Client(**module.params)
mm = ModuleManager(module=module, client=client)
results = mm.exec_module()
cleanup_tokens(client)
module.exit_json(**results)
exit_json(module, results, client)
except F5ModuleError as ex:
cleanup_tokens(client)
module.fail_json(msg=str(ex))
fail_json(module, ex, client)
if __name__ == '__main__':

View file

@ -478,12 +478,6 @@ class ModuleManager(object):
self.update_on_device()
return True
def should_update(self):
result = self._update_changed_options()
if result:
return True
return False
def remove(self):
if self.module.check_mode:
return True

View file

@ -155,69 +155,57 @@ time_until_up:
sample: 2
'''
import os
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback
try:
from library.module_utils.network.f5.bigip import HAS_F5SDK
from library.module_utils.network.f5.bigip import F5Client
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 cleanup_tokens
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.common import exit_json
from library.module_utils.network.f5.common import fail_json
from library.module_utils.network.f5.ipaddress import is_valid_ip
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
except ImportError:
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
from ansible.module_utils.network.f5.bigip import F5Client
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 cleanup_tokens
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.common import exit_json
from ansible.module_utils.network.f5.common import fail_json
from ansible.module_utils.network.f5.ipaddress import is_valid_ip
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
class Parameters(AnsibleF5Parameters):
api_map = {
'timeUntilUp': 'time_until_up',
'defaultsFrom': 'parent',
'recv': 'receive'
'recv': 'receive',
}
api_attributes = [
'timeUntilUp', 'defaultsFrom', 'interval', 'timeout', 'recv', 'send',
'destination', 'description'
'destination', 'description',
]
returnables = [
'parent', 'send', 'receive', 'ip', 'port', 'interval', 'timeout',
'time_until_up', 'description'
'time_until_up', 'description',
]
updatables = [
'destination', 'send', 'receive', 'interval', 'timeout', 'time_until_up',
'description'
'description',
]
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
@property
def destination(self):
if self.ip is None and self.port is None:
@ -281,11 +269,7 @@ class Parameters(AnsibleF5Parameters):
def parent(self):
if self._values['parent'] is None:
return None
if self._values['parent'].startswith('/'):
parent = os.path.basename(self._values['parent'])
result = '/{0}/{1}'.format(self.partition, parent)
else:
result = '/{0}/{1}'.format(self.partition, self._values['parent'])
result = fq_name(self.partition, self._values['parent'])
return result
@property
@ -293,7 +277,31 @@ class Parameters(AnsibleF5Parameters):
return 'udp'
class ApiParameters(Parameters):
pass
class ModuleParameters(Parameters):
pass
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):
pass
class ReportableChanges(Changes):
pass
@ -368,9 +376,9 @@ class ModuleManager(object):
def __init__(self, *args, **kwargs):
self.module = kwargs.get('module', None)
self.client = kwargs.get('client', None)
self.have = None
self.want = Parameters(params=self.module.params)
self.changes = Changes()
self.want = ModuleParameters(params=self.module.params)
self.have = ApiParameters()
self.changes = UsableChanges()
def _set_changed_options(self):
changed = {}
@ -378,7 +386,7 @@ class ModuleManager(object):
if getattr(self.want, key) is not None:
changed[key] = getattr(self.want, key)
if changed:
self.changes = Changes(params=changed)
self.changes = UsableChanges(params=changed)
def _update_changed_options(self):
diff = Difference(self.want, self.have)
@ -394,7 +402,7 @@ class ModuleManager(object):
else:
changed[k] = change
if changed:
self.changes = Changes(params=changed)
self.changes = UsableChanges(params=changed)
return True
return False
@ -409,15 +417,13 @@ class ModuleManager(object):
result = dict()
state = self.want.state
try:
if state == "present":
changed = self.present()
elif state == "absent":
changed = self.absent()
except iControlUnexpectedHTTPError as e:
raise F5ModuleError(str(e))
if state == "present":
changed = self.present()
elif state == "absent":
changed = self.absent()
changes = self.changes.to_return()
reportable = ReportableChanges(params=self.changes.to_return())
changes = reportable.to_return()
result.update(**changes)
result.update(dict(changed=changed))
self._announce_deprecations(result)
@ -426,7 +432,7 @@ class ModuleManager(object):
def _announce_deprecations(self, result):
warnings = result.pop('__warnings', [])
for warning in warnings:
self.module.deprecate(
self.client.module.deprecate(
msg=warning['msg'],
version=warning['version']
)
@ -437,31 +443,20 @@ class ModuleManager(object):
else:
return self.create()
def create(self):
self._set_changed_options()
if self.want.timeout is None:
self.want.update({'timeout': 16})
if self.want.interval is None:
self.want.update({'interval': 5})
if self.want.time_until_up is None:
self.want.update({'time_until_up': 0})
if self.want.ip is None:
self.want.update({'ip': '*'})
if self.want.port is None:
self.want.update({'port': '*'})
if self.want.send is None:
self.want.update({'send': 'default send string'})
if self.module.check_mode:
return True
self.create_on_device()
return True
def exists(self):
result = self.client.api.tm.ltm.monitor.udps.udp.exists(
name=self.want.name,
partition=self.want.partition
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/{2}".format(
self.client.provider['server'],
self.client.provider['server_port'],
transform_name(self.want.partition, self.want.name)
)
return result
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 update(self):
self.have = self.read_current_from_device()
@ -480,21 +475,66 @@ class ModuleManager(object):
raise F5ModuleError("Failed to delete the resource.")
return True
def create(self):
self._set_changed_options()
self._set_default_creation_values()
if self.module.check_mode:
return True
self.create_on_device()
return True
def _set_default_creation_values(self):
if self.want.timeout is None:
self.want.update({'timeout': 16})
if self.want.interval is None:
self.want.update({'interval': 5})
if self.want.time_until_up is None:
self.want.update({'time_until_up': 0})
if self.want.ip is None:
self.want.update({'ip': '*'})
if self.want.port is None:
self.want.update({'port': '*'})
if self.want.send is None:
self.want.update({'send': 'default send string'})
def create_on_device(self):
params = self.want.api_params()
self.client.api.tm.ltm.monitor.udps.udp.create(
name=self.want.name,
partition=self.want.partition,
**params
params = self.changes.api_params()
params['name'] = self.want.name
params['partition'] = self.want.partition
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/".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)
def update_on_device(self):
params = self.want.api_params()
resource = self.client.api.tm.ltm.monitor.udps.udp.load(
name=self.want.name,
partition=self.want.partition
params = self.changes.api_params()
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/{2}".format(
self.client.provider['server'],
self.client.provider['server_port'],
transform_name(self.want.partition, self.want.name)
)
resource.modify(**params)
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 absent(self):
if self.exists():
@ -502,20 +542,33 @@ class ModuleManager(object):
return False
def remove_from_device(self):
resource = self.client.api.tm.ltm.monitor.udps.udp.load(
name=self.want.name,
partition=self.want.partition
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/{2}".format(
self.client.provider['server'],
self.client.provider['server_port'],
transform_name(self.want.partition, self.want.name)
)
if resource:
resource.delete()
resp = self.client.api.delete(uri)
if resp.status == 200:
return True
def read_current_from_device(self):
resource = self.client.api.tm.ltm.monitor.udps.udp.load(
name=self.want.name,
partition=self.want.partition
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/{2}".format(
self.client.provider['server'],
self.client.provider['server_port'],
transform_name(self.want.partition, self.want.name)
)
result = resource.attrs
return Parameters(params=result)
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):
@ -552,20 +605,19 @@ def main():
module = AnsibleModule(
argument_spec=spec.argument_spec,
supports_check_mode=spec.supports_check_mode
supports_check_mode=spec.supports_check_mode,
)
if not HAS_F5SDK:
module.fail_json(msg="The python f5-sdk module is required")
client = F5RestClient(**module.params)
try:
client = F5Client(**module.params)
mm = ModuleManager(module=module, client=client)
results = mm.exec_module()
cleanup_tokens(client)
module.exit_json(**results)
exit_json(module, results, client)
except F5ModuleError as ex:
cleanup_tokens(client)
module.fail_json(msg=str(ex))
fail_json(module, ex, client)
if __name__ == '__main__':

View file

@ -152,7 +152,7 @@ try:
from library.module_utils.network.f5.common import cleanup_tokens
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 compare_dictionary
from library.module_utils.network.f5.common import compare_complex_list
try:
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
@ -165,7 +165,7 @@ except ImportError:
from ansible.module_utils.network.f5.common import cleanup_tokens
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 compare_dictionary
from ansible.module_utils.network.f5.common import compare_complex_list
try:
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
except ImportError:
@ -371,7 +371,7 @@ class Difference(object):
have = [tuple(x.pop('destination_ports')) for x in self.have.rules if 'destination_ports' in x]
if set(want) != set(have):
return self.want.rules
if compare_dictionary(self.want.rules, self.have.rules):
if compare_complex_list(self.want.rules, self.have.rules):
return self.want.rules