BIGIP: Bugfix.bigip.data.group (#53968)

* Moving comparision functions to compare.py from common.py

* fixes issue with data group elements containing IPs with Route Domains
refactors main() function and module_manager to accomodate new patterns
updates doc variables
This commit is contained in:
Wojciech Wypior 2019-03-19 05:25:54 +01:00 committed by Tim Rupp
parent 2b00cb592d
commit 313e07dfd3
2 changed files with 89 additions and 51 deletions

View file

@ -24,10 +24,12 @@ options:
name:
description:
- Specifies the name of the data group.
type: str
required: True
description:
description:
- The description of the monitor.
- The description of the data group.
type: str
version_added: 2.8
type:
description:
@ -37,6 +39,7 @@ options:
to specify a list of records containing IP addresses, but label them as a C(string)
type.
- This value cannot be changed once the data group is created.
type: str
choices:
- address
- addr
@ -71,6 +74,7 @@ options:
- If this value is not provided, it will be given the value specified in C(name) and,
therefore, match the name of the data group.
- This value may only contain letters, numbers, underscores, dashes, or a period.
type: str
records:
description:
- Specifies the records that you want to add to a data group.
@ -81,15 +85,18 @@ options:
RAM.
- When C(internal) is C(no), at least one record must be specified in either C(records)
or C(records_content).
type: list
suboptions:
key:
description:
- The key describing the record in the data group.
- Your key will be used for validation of the C(type) parameter to this module.
type: str
required: True
value:
description:
- The value of the key describing the record in the data group.
type: raw
records_src:
description:
- Path to a file with records in it.
@ -108,6 +115,7 @@ options:
group file.
- When C(internal) is C(no), at least one record must be specified in either C(records)
or C(records_content).
type: path
separator:
description:
- When specifying C(records_content), this is the string of characters that will
@ -116,25 +124,31 @@ options:
- This value cannot be changed once it is set.
- This parameter is only relevant when C(internal) is C(no). It will be ignored
otherwise.
type: str
default: ":="
delete_data_group_file:
description:
- When C(yes), will ensure that the remote data group file is deleted.
- This parameter is only relevant when C(state) is C(absent) and C(internal) is C(no).
default: no
type: bool
default: no
partition:
description:
- Device partition to manage resources on.
type: str
default: Common
state:
description:
- When C(state) is C(present), ensures the data group exists.
- When C(state) is C(absent), ensures that the data group is removed.
- The use of state in this module refers to the entire data group, not its members.
type: str
choices:
- present
- absent
default: present
notes:
- This module does NOT support atomic updates of data group members in a type C(internal) data group.
extends_documentation_fragment: f5
author:
- Tim Rupp (@caphrim007)
@ -145,6 +159,7 @@ EXAMPLES = r'''
- name: Create a data group of addresses
bigip_data_group:
name: foo
internal: yes
records:
- key: 0.0.0.0/32
value: External_NAT
@ -160,6 +175,7 @@ EXAMPLES = r'''
- name: Create a data group of strings
bigip_data_group:
name: foo
internal: yes
records:
- key: caddy
value: ""
@ -268,11 +284,8 @@ 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 cleanup_tokens
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_complex_list
from library.module_utils.network.f5.compare 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_interface
from library.module_utils.compat.ipaddress import ip_network
@ -283,11 +296,8 @@ 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 cleanup_tokens
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.common import compare_complex_list
from ansible.module_utils.network.f5.compare 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_interface
from ansible.module_utils.compat.ipaddress import ip_network
@ -580,6 +590,17 @@ class Parameters(AnsibleF5Parameters):
class ApiParameters(Parameters):
def _strip_route_domain(self, item):
result = dict()
pattern = r'(?P<ip>[^%]+)%(?P<route_domain>[0-9]+)/(?P<mask>[0-9]+)'
matches = re.search(pattern, item['name'])
if matches:
result['data'] = item['data']
result['name'] = '{0}/{1}'.format(matches.group('ip'), matches.group('mask'))
return result
return item
@property
def checksum(self):
if self._values['checksum'] is None:
@ -591,7 +612,8 @@ class ApiParameters(Parameters):
def records(self):
if self._values['records'] is None:
return None
return self._values['records']
result = [self._strip_route_domain(item) for item in self._values['records']]
return result
@property
def records_list(self):
@ -740,7 +762,7 @@ class Difference(object):
class BaseManager(object):
def __init__(self, *args, **kwargs):
self.module = kwargs.get('module', None)
self.client = kwargs.get('client', None)
self.client = F5RestClient(**self.module.params)
self.want = ModuleParameters(params=self.module.params)
self.have = ApiParameters()
self.changes = UsableChanges()
@ -1226,7 +1248,6 @@ class ModuleManager(object):
def __init__(self, *args, **kwargs):
self.kwargs = kwargs
self.module = kwargs.get('module')
self.client = kwargs.get('client', None)
def exec_module(self):
if self.module.params['internal']:
@ -1283,19 +1304,16 @@ def main():
module = AnsibleModule(
argument_spec=spec.argument_spec,
supports_check_mode=spec.supports_check_mode
supports_check_mode=spec.supports_check_mode,
mutually_exclusive=spec.mutually_exclusive
)
client = F5RestClient(**module.params)
try:
mm = ModuleManager(module=module, client=client)
mm = ModuleManager(module=module)
results = mm.exec_module()
cleanup_tokens(client)
exit_json(module, results, client)
module.exit_json(**results)
except F5ModuleError as ex:
cleanup_tokens(client)
fail_json(module, ex, client)
module.fail_json(msg=str(ex))
if __name__ == '__main__':

View file

@ -116,9 +116,11 @@ class TestManager(unittest.TestCase):
separator=':=',
state='present',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -150,9 +152,11 @@ class TestManager(unittest.TestCase):
separator=':=',
state='present',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -185,9 +189,11 @@ class TestManager(unittest.TestCase):
separator=':=',
state='present',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -217,9 +223,11 @@ class TestManager(unittest.TestCase):
internal=False,
state='absent',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -249,9 +257,11 @@ class TestManager(unittest.TestCase):
internal=False,
state='absent',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -284,9 +294,11 @@ class TestManager(unittest.TestCase):
separator=':=',
state='present',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -318,9 +330,11 @@ class TestManager(unittest.TestCase):
separator=':=',
state='present',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -353,9 +367,11 @@ class TestManager(unittest.TestCase):
separator=':=',
state='present',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -387,9 +403,11 @@ class TestManager(unittest.TestCase):
separator=':=',
state='present',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(
@ -442,9 +460,11 @@ class TestManager(unittest.TestCase):
separator=':=',
state='present',
partition='Common',
server='localhost',
password='password',
user='admin'
provider=dict(
server='localhost',
password='password',
user='admin'
)
))
module = AnsibleModule(