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:
parent
773c0982b0
commit
5bdcaff921
8 changed files with 359 additions and 284 deletions
|
@ -335,28 +335,34 @@ def transform_name(partition='', name='', sub_path=''):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def dict2tuple(items):
|
def compare_complex_list(want, have):
|
||||||
"""Convert a dictionary to a list of tuples
|
"""Performs a complex list comparison
|
||||||
|
|
||||||
This method is used in cases where dictionaries need to be compared. Due
|
A complex list is a list of dictionaries
|
||||||
to dictionaries inherently having no order, it is easier to compare list
|
|
||||||
of tuples because these lists can be converted to sets.
|
|
||||||
|
|
||||||
This conversion only supports dicts of simple values. Do not give it dicts
|
|
||||||
that contain sub-dicts. This will not give you the result you want when using
|
|
||||||
the returned tuple for comparison.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
items (dict): The dictionary of items that should be converted
|
want (list): List of dictionaries to compare with second parameter.
|
||||||
|
have (list): List of dictionaries compare with first parameter.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: Returns a list of tuples upon success. Otherwise, an empty list.
|
bool:
|
||||||
"""
|
"""
|
||||||
result = []
|
if want == [] and have is None:
|
||||||
for x in items:
|
return None
|
||||||
|
if want is None:
|
||||||
|
return None
|
||||||
|
w = []
|
||||||
|
h = []
|
||||||
|
for x in want:
|
||||||
tmp = [(str(k), str(v)) for k, v in iteritems(x)]
|
tmp = [(str(k), str(v)) for k, v in iteritems(x)]
|
||||||
result += tmp
|
w += tmp
|
||||||
return result
|
for x in have:
|
||||||
|
tmp = [(str(k), str(v)) for k, v in iteritems(x)]
|
||||||
|
h += tmp
|
||||||
|
if set(w) == set(h):
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return want
|
||||||
|
|
||||||
|
|
||||||
def compare_dictionary(want, have):
|
def compare_dictionary(want, have):
|
||||||
|
@ -369,12 +375,12 @@ def compare_dictionary(want, have):
|
||||||
Returns:
|
Returns:
|
||||||
bool:
|
bool:
|
||||||
"""
|
"""
|
||||||
if want == [] and have is None:
|
if want == {} and have is None:
|
||||||
return None
|
return None
|
||||||
if want is None:
|
if want is None:
|
||||||
return None
|
return None
|
||||||
w = dict2tuple(want)
|
w = [(str(k), str(v)) for k, v in iteritems(want)]
|
||||||
h = dict2tuple(have)
|
h = [(str(k), str(v)) for k, v in iteritems(have)]
|
||||||
if set(w) == set(h):
|
if set(w) == set(h):
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -265,7 +265,7 @@ try:
|
||||||
from library.module_utils.network.f5.common import F5ModuleError
|
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 AnsibleF5Parameters
|
||||||
from library.module_utils.network.f5.common import cleanup_tokens
|
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.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
|
||||||
from library.module_utils.network.f5.ipaddress import is_valid_ip_network
|
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 F5ModuleError
|
||||||
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
|
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 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.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
|
||||||
from ansible.module_utils.network.f5.ipaddress import is_valid_ip_network
|
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)
|
return self.encode_string_from_dict(record)
|
||||||
|
|
||||||
def encode_address_from_dict(self, record):
|
def encode_address_from_dict(self, record):
|
||||||
if is_valid_ip_network(record['key']):
|
if is_valid_ip_interface(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']):
|
|
||||||
key = ip_interface(u"{0}".format(str(record['key'])))
|
key = ip_interface(u"{0}".format(str(record['key'])))
|
||||||
else:
|
else:
|
||||||
raise F5ModuleError(
|
raise F5ModuleError(
|
||||||
"When specifying an 'address' type, the value to the left of the separator must be an IP."
|
"When specifying an 'address' type, the value to the left of the separator must be an IP."
|
||||||
)
|
)
|
||||||
if key and 'value' in record:
|
if key and 'value' in record:
|
||||||
try:
|
if key.network.prefixlen in [32, 128]:
|
||||||
# Only ip_address's have max_prefixlen
|
return self.encode_host(str(key.ip), record['value'])
|
||||||
if key.max_prefixlen in [32, 128]:
|
return self.encode_network(
|
||||||
return self.encode_host(str(key), record['value'])
|
str(key.network.network_address), key.network.prefixlen, record['value']
|
||||||
except ValueError:
|
)
|
||||||
return self.encode_network(
|
|
||||||
str(key.network_address), key.prefixlen, record['value'])
|
|
||||||
elif key:
|
elif key:
|
||||||
try:
|
if key.network.prefixlen in [32, 128]:
|
||||||
# Only ip_address's have max_prefixlen
|
return self.encode_host(str(key.ip), str(key.ip))
|
||||||
if key.max_prefixlen in [32, 128]:
|
return self.encode_network(
|
||||||
return self.encode_host(str(key), str(key))
|
str(key.network.network_address), key.network.prefixlen, str(key.network.network_address)
|
||||||
except ValueError:
|
)
|
||||||
return self.encode_network(
|
|
||||||
str(key.network_address), key.prefixlen, str(key.network_address)
|
|
||||||
)
|
|
||||||
|
|
||||||
def encode_integer_from_dict(self, record):
|
def encode_integer_from_dict(self, record):
|
||||||
try:
|
try:
|
||||||
|
@ -418,37 +409,27 @@ class RecordsEncoder(object):
|
||||||
else:
|
else:
|
||||||
# 192.168.0.0/16 := "Network3",
|
# 192.168.0.0/16 := "Network3",
|
||||||
# 2402:9400:1000:0::/64 := "Network4",
|
# 2402:9400:1000:0::/64 := "Network4",
|
||||||
parts = record.split(self._separator)
|
parts = record.split(self._separator)
|
||||||
if is_valid_ip_network(parts[0]):
|
if parts[0] == '':
|
||||||
key = ip_network(u"{0}".format(str(parts[0])))
|
return
|
||||||
elif is_valid_ip(parts[0]):
|
if not is_valid_ip_interface(parts[0]):
|
||||||
key = ip_address(u"{0}".format(str(parts[0])))
|
raise F5ModuleError(
|
||||||
elif is_valid_ip_interface(parts[0]):
|
"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])))
|
)
|
||||||
elif parts[0] == '':
|
key = ip_interface(u"{0}".format(str(parts[0])))
|
||||||
pass
|
|
||||||
else:
|
|
||||||
raise F5ModuleError(
|
|
||||||
"When specifying an 'address' type, the value to the left of the separator must be an IP."
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(parts) == 2:
|
if len(parts) == 2:
|
||||||
try:
|
if key.network.prefixlen in [32, 128]:
|
||||||
# Only ip_address's have max_prefixlen
|
return self.encode_host(str(key.ip), parts[1])
|
||||||
if key.max_prefixlen in [32, 128]:
|
return self.encode_network(
|
||||||
return self.encode_host(str(key), parts[1])
|
str(key.network.network_address), key.network.prefixlen, parts[1]
|
||||||
except ValueError:
|
)
|
||||||
return self.encode_network(
|
elif len(parts) == 1 and parts[0] != '':
|
||||||
str(key.network_address), key.prefixlen, parts[1])
|
if key.network.prefixlen in [32, 128]:
|
||||||
elif len(parts) == 1 and parts[0] != '':
|
return self.encode_host(str(key.ip), str(key.ip))
|
||||||
try:
|
return self.encode_network(
|
||||||
# Only ip_address's have max_prefixlen
|
str(key.network.network_address), key.network.prefixlen, str(key.network.network_address)
|
||||||
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)
|
|
||||||
)
|
|
||||||
|
|
||||||
def encode_host(self, key, value):
|
def encode_host(self, key, value):
|
||||||
return 'host {0} {1} {2}'.format(str(key), self._separator, str(value))
|
return 'host {0} {1} {2}'.format(str(key), self._separator, str(value))
|
||||||
|
@ -706,7 +687,7 @@ class Difference(object):
|
||||||
return None
|
return None
|
||||||
if self.have.records is None:
|
if self.have.records is None:
|
||||||
return self.want.records
|
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
|
return result
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -415,7 +415,7 @@ class Difference(object):
|
||||||
)
|
)
|
||||||
result = dict()
|
result = dict()
|
||||||
|
|
||||||
different = compare_dictionary([self.want.variables], [self.have.variables])
|
different = compare_dictionary(self.want.variables, self.have.variables)
|
||||||
if not different:
|
if not different:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -244,13 +244,14 @@ from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.basic import env_fallback
|
from ansible.module_utils.basic import env_fallback
|
||||||
|
|
||||||
try:
|
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 HAS_F5SDK
|
||||||
from library.module_utils.network.f5.bigip import F5Client
|
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 F5ModuleError
|
||||||
from library.module_utils.network.f5.common import AnsibleF5Parameters
|
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 cleanup_tokens
|
||||||
from library.module_utils.network.f5.common import fq_name
|
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.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
|
||||||
from library.module_utils.network.f5.ipaddress import validate_ip_v6_address
|
from library.module_utils.network.f5.ipaddress import validate_ip_v6_address
|
||||||
|
@ -260,13 +261,14 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_F5SDK = False
|
HAS_F5SDK = False
|
||||||
except ImportError:
|
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 HAS_F5SDK
|
||||||
from ansible.module_utils.network.f5.bigip import F5Client
|
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 F5ModuleError
|
||||||
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
|
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 cleanup_tokens
|
||||||
from ansible.module_utils.network.f5.common import fq_name
|
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.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
|
||||||
from ansible.module_utils.network.f5.ipaddress import validate_ip_v6_address
|
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:
|
if self._values['address'] is None:
|
||||||
return None
|
return None
|
||||||
if is_valid_ip(self._values['address']):
|
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(
|
raise F5ModuleError(
|
||||||
"Specified 'address' is not an IP address."
|
"Specified 'address' is not an IP address."
|
||||||
)
|
)
|
||||||
|
@ -758,7 +761,8 @@ class Difference(object):
|
||||||
return None
|
return None
|
||||||
if self.want.virtual_server_dependencies is None:
|
if self.want.virtual_server_dependencies is None:
|
||||||
return 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
|
@property
|
||||||
def enabled(self):
|
def enabled(self):
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
'status': ['preview'],
|
'status': ['preview'],
|
||||||
'supported_by': 'community'}
|
'supported_by': 'community'}
|
||||||
|
@ -159,7 +158,6 @@ timeout:
|
||||||
sample: 10
|
sample: 10
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
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
|
from ansible.module_utils.six import iteritems
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.module_utils.network.f5.bigip import HAS_F5SDK
|
from library.module_utils.network.f5.bigip import F5RestClient
|
||||||
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 F5ModuleError
|
||||||
from library.module_utils.network.f5.common import AnsibleF5Parameters
|
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 cleanup_tokens
|
||||||
from library.module_utils.network.f5.common import fq_name
|
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 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.common import compare_dictionary
|
||||||
from library.module_utils.network.f5.ipaddress import is_valid_ip
|
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:
|
except ImportError:
|
||||||
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
|
from ansible.module_utils.network.f5.bigip import F5RestClient
|
||||||
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 F5ModuleError
|
||||||
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
|
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 cleanup_tokens
|
||||||
from ansible.module_utils.network.f5.common import fq_name
|
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 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 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
|
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):
|
class Parameters(AnsibleF5Parameters):
|
||||||
|
@ -201,33 +195,24 @@ class Parameters(AnsibleF5Parameters):
|
||||||
'defaultsFrom': 'parent',
|
'defaultsFrom': 'parent',
|
||||||
'apiRawValues': 'variables',
|
'apiRawValues': 'variables',
|
||||||
'run': 'external_program',
|
'run': 'external_program',
|
||||||
'args': 'arguments'
|
'args': 'arguments',
|
||||||
}
|
}
|
||||||
|
|
||||||
api_attributes = [
|
api_attributes = [
|
||||||
'defaultsFrom', 'interval', 'timeout', 'destination', 'run', 'args', 'description'
|
'defaultsFrom', 'interval', 'timeout', 'destination', 'run', 'args',
|
||||||
|
'description',
|
||||||
]
|
]
|
||||||
|
|
||||||
returnables = [
|
returnables = [
|
||||||
'parent', 'ip', 'port', 'interval', 'timeout', 'variables', 'external_program',
|
'parent', 'ip', 'port', 'interval', 'timeout', 'variables', 'external_program',
|
||||||
'arguments', 'description'
|
'arguments', 'description',
|
||||||
]
|
]
|
||||||
|
|
||||||
updatables = [
|
updatables = [
|
||||||
'destination', 'interval', 'timeout', 'variables', 'external_program',
|
'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
|
@property
|
||||||
def destination(self):
|
def destination(self):
|
||||||
if self.ip is None and self.port is None:
|
if self.ip is None and self.port is None:
|
||||||
|
@ -285,11 +270,7 @@ class Parameters(AnsibleF5Parameters):
|
||||||
def parent(self):
|
def parent(self):
|
||||||
if self._values['parent'] is None:
|
if self._values['parent'] is None:
|
||||||
return None
|
return None
|
||||||
if self._values['parent'].startswith('/'):
|
result = fq_name(self.partition, self._values['parent'])
|
||||||
parent = os.path.basename(self._values['parent'])
|
|
||||||
result = '/{0}/{1}'.format(self.partition, parent)
|
|
||||||
else:
|
|
||||||
result = '/{0}/{1}'.format(self.partition, self._values['parent'])
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -426,8 +407,7 @@ class Difference(object):
|
||||||
variables=self.want.variables
|
variables=self.want.variables
|
||||||
)
|
)
|
||||||
result = dict()
|
result = dict()
|
||||||
|
different = compare_dictionary(self.want.variables, self.have.variables)
|
||||||
different = compare_dictionary([self.want.variables], [self.have.variables])
|
|
||||||
if not different:
|
if not different:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -491,13 +471,10 @@ class ModuleManager(object):
|
||||||
result = dict()
|
result = dict()
|
||||||
state = self.want.state
|
state = self.want.state
|
||||||
|
|
||||||
try:
|
if state == "present":
|
||||||
if state == "present":
|
changed = self.present()
|
||||||
changed = self.present()
|
elif state == "absent":
|
||||||
elif state == "absent":
|
changed = self.absent()
|
||||||
changed = self.absent()
|
|
||||||
except iControlUnexpectedHTTPError as e:
|
|
||||||
raise F5ModuleError(str(e))
|
|
||||||
|
|
||||||
reportable = ReportableChanges(params=self.changes.to_return())
|
reportable = ReportableChanges(params=self.changes.to_return())
|
||||||
changes = reportable.to_return()
|
changes = reportable.to_return()
|
||||||
|
@ -520,19 +497,19 @@ class ModuleManager(object):
|
||||||
else:
|
else:
|
||||||
return self.create()
|
return self.create()
|
||||||
|
|
||||||
def create(self):
|
def exists(self):
|
||||||
self._set_changed_options()
|
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/external/{2}".format(
|
||||||
if self.want.timeout is None:
|
self.client.provider['server'],
|
||||||
self.want.update({'timeout': 16})
|
self.client.provider['server_port'],
|
||||||
if self.want.interval is None:
|
transform_name(self.want.partition, self.want.name)
|
||||||
self.want.update({'interval': 5})
|
)
|
||||||
if self.want.ip is None:
|
resp = self.client.api.get(uri)
|
||||||
self.want.update({'ip': '*'})
|
try:
|
||||||
if self.want.port is None:
|
response = resp.json()
|
||||||
self.want.update({'port': '*'})
|
except ValueError:
|
||||||
if self.module.check_mode:
|
return False
|
||||||
return True
|
if resp.status == 404 or 'code' in response and response['code'] == 404:
|
||||||
self.create_on_device()
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
@ -544,70 +521,132 @@ class ModuleManager(object):
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def absent(self):
|
|
||||||
if self.exists():
|
|
||||||
return self.remove()
|
|
||||||
return False
|
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.module.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
self.remove_from_device()
|
self.remove_from_device()
|
||||||
if self.exists():
|
if self.exists():
|
||||||
raise F5ModuleError("Failed to delete the monitor.")
|
raise F5ModuleError("Failed to delete the resource.")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def read_current_from_device(self):
|
def create(self):
|
||||||
resource = self.client.api.tm.ltm.monitor.externals.external.load(
|
self._set_changed_options()
|
||||||
name=self.want.name,
|
self._set_default_creation_values()
|
||||||
partition=self.want.partition
|
if self.module.check_mode:
|
||||||
)
|
return True
|
||||||
result = resource.attrs
|
self.create_on_device()
|
||||||
return ApiParameters(params=result)
|
return True
|
||||||
|
|
||||||
def exists(self):
|
def _set_default_creation_values(self):
|
||||||
result = self.client.api.tm.ltm.monitor.externals.external.exists(
|
if self.want.timeout is None:
|
||||||
name=self.want.name,
|
self.want.update({'timeout': 16})
|
||||||
partition=self.want.partition
|
if self.want.interval is None:
|
||||||
)
|
self.want.update({'interval': 5})
|
||||||
return result
|
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()
|
params = self.changes.api_params()
|
||||||
result = self.client.api.tm.ltm.monitor.externals.external.load(
|
params['name'] = self.want.name
|
||||||
name=self.want.name,
|
params['partition'] = self.want.partition
|
||||||
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:
|
resp = self.client.api.post(uri, json=params)
|
||||||
result.modify(**params)
|
try:
|
||||||
if self.changes.variables:
|
response = resp.json()
|
||||||
self.set_variable_on_device(self.changes.variables)
|
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):
|
def set_variable_on_device(self, commands):
|
||||||
command = ' '.join(['user-defined {0} \\\"{1}\\\"'.format(k, v) for k, v in iteritems(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)
|
command = 'tmsh modify ltm monitor external {0} {1}'.format(self.want.name, command)
|
||||||
self.client.api.tm.util.bash.exec_cmd(
|
uri = "https://{0}:{1}/mgmt/tm/util/bash".format(
|
||||||
'run',
|
self.client.provider['server'],
|
||||||
|
self.client.provider['server_port'],
|
||||||
|
)
|
||||||
|
args = dict(
|
||||||
|
command='run',
|
||||||
utilCmdArgs='-c "{0}"'.format(command)
|
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):
|
def update_on_device(self):
|
||||||
params = self.want.api_params()
|
params = self.changes.api_params()
|
||||||
self.client.api.tm.ltm.monitor.externals.external.create(
|
if params:
|
||||||
name=self.want.name,
|
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/external/{2}".format(
|
||||||
partition=self.want.partition,
|
self.client.provider['server'],
|
||||||
**params
|
self.client.provider['server_port'],
|
||||||
)
|
transform_name(self.want.partition, self.want.name)
|
||||||
if self.want.variables:
|
)
|
||||||
self.set_variable_on_device(self.want.variables)
|
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):
|
def remove_from_device(self):
|
||||||
result = self.client.api.tm.ltm.monitor.externals.external.load(
|
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/external/{2}".format(
|
||||||
name=self.want.name,
|
self.client.provider['server'],
|
||||||
partition=self.want.partition
|
self.client.provider['server_port'],
|
||||||
|
transform_name(self.want.partition, self.want.name)
|
||||||
)
|
)
|
||||||
if result:
|
resp = self.client.api.delete(uri)
|
||||||
result.delete()
|
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):
|
class ArgumentSpec(object):
|
||||||
|
@ -643,20 +682,19 @@ def main():
|
||||||
|
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
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:
|
try:
|
||||||
client = F5Client(**module.params)
|
|
||||||
mm = ModuleManager(module=module, client=client)
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
module.exit_json(**results)
|
exit_json(module, results, client)
|
||||||
except F5ModuleError as ex:
|
except F5ModuleError as ex:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
module.fail_json(msg=str(ex))
|
fail_json(module, ex, client)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -478,12 +478,6 @@ class ModuleManager(object):
|
||||||
self.update_on_device()
|
self.update_on_device()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def should_update(self):
|
|
||||||
result = self._update_changed_options()
|
|
||||||
if result:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
if self.module.check_mode:
|
if self.module.check_mode:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -155,69 +155,57 @@ time_until_up:
|
||||||
sample: 2
|
sample: 2
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.basic import env_fallback
|
from ansible.module_utils.basic import env_fallback
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from library.module_utils.network.f5.bigip import HAS_F5SDK
|
from library.module_utils.network.f5.bigip import F5RestClient
|
||||||
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 F5ModuleError
|
||||||
from library.module_utils.network.f5.common import AnsibleF5Parameters
|
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 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 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
|
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:
|
except ImportError:
|
||||||
from ansible.module_utils.network.f5.bigip import HAS_F5SDK
|
from ansible.module_utils.network.f5.bigip import F5RestClient
|
||||||
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 F5ModuleError
|
||||||
from ansible.module_utils.network.f5.common import AnsibleF5Parameters
|
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 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 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
|
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):
|
class Parameters(AnsibleF5Parameters):
|
||||||
api_map = {
|
api_map = {
|
||||||
'timeUntilUp': 'time_until_up',
|
'timeUntilUp': 'time_until_up',
|
||||||
'defaultsFrom': 'parent',
|
'defaultsFrom': 'parent',
|
||||||
'recv': 'receive'
|
'recv': 'receive',
|
||||||
}
|
}
|
||||||
|
|
||||||
api_attributes = [
|
api_attributes = [
|
||||||
'timeUntilUp', 'defaultsFrom', 'interval', 'timeout', 'recv', 'send',
|
'timeUntilUp', 'defaultsFrom', 'interval', 'timeout', 'recv', 'send',
|
||||||
'destination', 'description'
|
'destination', 'description',
|
||||||
]
|
]
|
||||||
|
|
||||||
returnables = [
|
returnables = [
|
||||||
'parent', 'send', 'receive', 'ip', 'port', 'interval', 'timeout',
|
'parent', 'send', 'receive', 'ip', 'port', 'interval', 'timeout',
|
||||||
'time_until_up', 'description'
|
'time_until_up', 'description',
|
||||||
]
|
]
|
||||||
|
|
||||||
updatables = [
|
updatables = [
|
||||||
'destination', 'send', 'receive', 'interval', 'timeout', 'time_until_up',
|
'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
|
@property
|
||||||
def destination(self):
|
def destination(self):
|
||||||
if self.ip is None and self.port is None:
|
if self.ip is None and self.port is None:
|
||||||
|
@ -281,11 +269,7 @@ class Parameters(AnsibleF5Parameters):
|
||||||
def parent(self):
|
def parent(self):
|
||||||
if self._values['parent'] is None:
|
if self._values['parent'] is None:
|
||||||
return None
|
return None
|
||||||
if self._values['parent'].startswith('/'):
|
result = fq_name(self.partition, self._values['parent'])
|
||||||
parent = os.path.basename(self._values['parent'])
|
|
||||||
result = '/{0}/{1}'.format(self.partition, parent)
|
|
||||||
else:
|
|
||||||
result = '/{0}/{1}'.format(self.partition, self._values['parent'])
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -293,7 +277,31 @@ class Parameters(AnsibleF5Parameters):
|
||||||
return 'udp'
|
return 'udp'
|
||||||
|
|
||||||
|
|
||||||
|
class ApiParameters(Parameters):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleParameters(Parameters):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Changes(Parameters):
|
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
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -368,9 +376,9 @@ class ModuleManager(object):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.module = kwargs.get('module', None)
|
self.module = kwargs.get('module', None)
|
||||||
self.client = kwargs.get('client', None)
|
self.client = kwargs.get('client', None)
|
||||||
self.have = None
|
self.want = ModuleParameters(params=self.module.params)
|
||||||
self.want = Parameters(params=self.module.params)
|
self.have = ApiParameters()
|
||||||
self.changes = Changes()
|
self.changes = UsableChanges()
|
||||||
|
|
||||||
def _set_changed_options(self):
|
def _set_changed_options(self):
|
||||||
changed = {}
|
changed = {}
|
||||||
|
@ -378,7 +386,7 @@ class ModuleManager(object):
|
||||||
if getattr(self.want, key) is not None:
|
if getattr(self.want, key) is not None:
|
||||||
changed[key] = getattr(self.want, key)
|
changed[key] = getattr(self.want, key)
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Changes(params=changed)
|
self.changes = UsableChanges(params=changed)
|
||||||
|
|
||||||
def _update_changed_options(self):
|
def _update_changed_options(self):
|
||||||
diff = Difference(self.want, self.have)
|
diff = Difference(self.want, self.have)
|
||||||
|
@ -394,7 +402,7 @@ class ModuleManager(object):
|
||||||
else:
|
else:
|
||||||
changed[k] = change
|
changed[k] = change
|
||||||
if changed:
|
if changed:
|
||||||
self.changes = Changes(params=changed)
|
self.changes = UsableChanges(params=changed)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -409,15 +417,13 @@ class ModuleManager(object):
|
||||||
result = dict()
|
result = dict()
|
||||||
state = self.want.state
|
state = self.want.state
|
||||||
|
|
||||||
try:
|
if state == "present":
|
||||||
if state == "present":
|
changed = self.present()
|
||||||
changed = self.present()
|
elif state == "absent":
|
||||||
elif state == "absent":
|
changed = self.absent()
|
||||||
changed = self.absent()
|
|
||||||
except iControlUnexpectedHTTPError as e:
|
|
||||||
raise F5ModuleError(str(e))
|
|
||||||
|
|
||||||
changes = self.changes.to_return()
|
reportable = ReportableChanges(params=self.changes.to_return())
|
||||||
|
changes = reportable.to_return()
|
||||||
result.update(**changes)
|
result.update(**changes)
|
||||||
result.update(dict(changed=changed))
|
result.update(dict(changed=changed))
|
||||||
self._announce_deprecations(result)
|
self._announce_deprecations(result)
|
||||||
|
@ -426,7 +432,7 @@ class ModuleManager(object):
|
||||||
def _announce_deprecations(self, result):
|
def _announce_deprecations(self, result):
|
||||||
warnings = result.pop('__warnings', [])
|
warnings = result.pop('__warnings', [])
|
||||||
for warning in warnings:
|
for warning in warnings:
|
||||||
self.module.deprecate(
|
self.client.module.deprecate(
|
||||||
msg=warning['msg'],
|
msg=warning['msg'],
|
||||||
version=warning['version']
|
version=warning['version']
|
||||||
)
|
)
|
||||||
|
@ -437,31 +443,20 @@ class ModuleManager(object):
|
||||||
else:
|
else:
|
||||||
return self.create()
|
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):
|
def exists(self):
|
||||||
result = self.client.api.tm.ltm.monitor.udps.udp.exists(
|
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/{2}".format(
|
||||||
name=self.want.name,
|
self.client.provider['server'],
|
||||||
partition=self.want.partition
|
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):
|
def update(self):
|
||||||
self.have = self.read_current_from_device()
|
self.have = self.read_current_from_device()
|
||||||
|
@ -480,21 +475,66 @@ class ModuleManager(object):
|
||||||
raise F5ModuleError("Failed to delete the resource.")
|
raise F5ModuleError("Failed to delete the resource.")
|
||||||
return True
|
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):
|
def create_on_device(self):
|
||||||
params = self.want.api_params()
|
params = self.changes.api_params()
|
||||||
self.client.api.tm.ltm.monitor.udps.udp.create(
|
params['name'] = self.want.name
|
||||||
name=self.want.name,
|
params['partition'] = self.want.partition
|
||||||
partition=self.want.partition,
|
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/".format(
|
||||||
**params
|
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):
|
def update_on_device(self):
|
||||||
params = self.want.api_params()
|
params = self.changes.api_params()
|
||||||
resource = self.client.api.tm.ltm.monitor.udps.udp.load(
|
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/{2}".format(
|
||||||
name=self.want.name,
|
self.client.provider['server'],
|
||||||
partition=self.want.partition
|
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):
|
def absent(self):
|
||||||
if self.exists():
|
if self.exists():
|
||||||
|
@ -502,20 +542,33 @@ class ModuleManager(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def remove_from_device(self):
|
def remove_from_device(self):
|
||||||
resource = self.client.api.tm.ltm.monitor.udps.udp.load(
|
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/{2}".format(
|
||||||
name=self.want.name,
|
self.client.provider['server'],
|
||||||
partition=self.want.partition
|
self.client.provider['server_port'],
|
||||||
|
transform_name(self.want.partition, self.want.name)
|
||||||
)
|
)
|
||||||
if resource:
|
resp = self.client.api.delete(uri)
|
||||||
resource.delete()
|
if resp.status == 200:
|
||||||
|
return True
|
||||||
|
|
||||||
def read_current_from_device(self):
|
def read_current_from_device(self):
|
||||||
resource = self.client.api.tm.ltm.monitor.udps.udp.load(
|
uri = "https://{0}:{1}/mgmt/tm/ltm/monitor/udp/{2}".format(
|
||||||
name=self.want.name,
|
self.client.provider['server'],
|
||||||
partition=self.want.partition
|
self.client.provider['server_port'],
|
||||||
|
transform_name(self.want.partition, self.want.name)
|
||||||
)
|
)
|
||||||
result = resource.attrs
|
resp = self.client.api.get(uri)
|
||||||
return Parameters(params=result)
|
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):
|
class ArgumentSpec(object):
|
||||||
|
@ -552,20 +605,19 @@ def main():
|
||||||
|
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=spec.argument_spec,
|
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:
|
try:
|
||||||
client = F5Client(**module.params)
|
|
||||||
mm = ModuleManager(module=module, client=client)
|
mm = ModuleManager(module=module, client=client)
|
||||||
results = mm.exec_module()
|
results = mm.exec_module()
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
module.exit_json(**results)
|
exit_json(module, results, client)
|
||||||
except F5ModuleError as ex:
|
except F5ModuleError as ex:
|
||||||
cleanup_tokens(client)
|
cleanup_tokens(client)
|
||||||
module.fail_json(msg=str(ex))
|
fail_json(module, ex, client)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -152,7 +152,7 @@ try:
|
||||||
from library.module_utils.network.f5.common import cleanup_tokens
|
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 fq_name
|
||||||
from library.module_utils.network.f5.common import f5_argument_spec
|
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:
|
try:
|
||||||
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
except ImportError:
|
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 cleanup_tokens
|
||||||
from ansible.module_utils.network.f5.common import fq_name
|
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 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:
|
try:
|
||||||
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError
|
||||||
except ImportError:
|
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]
|
have = [tuple(x.pop('destination_ports')) for x in self.have.rules if 'destination_ports' in x]
|
||||||
if set(want) != set(have):
|
if set(want) != set(have):
|
||||||
return self.want.rules
|
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
|
return self.want.rules
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue