diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py index b6ae7a0d46e00da00e34579ffb6294957da12bf7..90b3235fc60d49b657871992a7510ba29d039509 100644 --- a/plugins/module_utils/ansible_freeipa_module.py +++ b/plugins/module_utils/ansible_freeipa_module.py @@ -88,9 +88,15 @@ else: """ Split a version string A.B.C, into a tuple. - This will not work for `rc`, `dev` or similar version string. + This will not work for `rc`, `dev` or similar. """ - return tuple(re.split("[-_.]", version_str)) # noqa: W605 + try: + _version = tuple( + (int(x) for x in re.split("[-_.]", version_str)) + ) + except ValueError: + _version = tuple(re.split("[-_.]", version_str)) + return _version from ipalib import api from ipalib import errors as ipalib_errors # noqa @@ -866,7 +872,10 @@ else: # Check if param_name is actually a param if param_name in self.ansible_module.params: value = self.ansible_module.params_get(param_name) - if isinstance(value, bool): + if ( + self.ansible_module.ipa_check_version("<", "4.9.10") + and isinstance(value, bool) + ): value = "TRUE" if value else "FALSE" # Since param wasn't a param check if it's a method name diff --git a/plugins/modules/ipaconfig.py b/plugins/modules/ipaconfig.py index f7901f2c23817c5016f832f86158db205875226b..6731e37df6bfdc71049c5c986c747294b3db82c7 100644 --- a/plugins/modules/ipaconfig.py +++ b/plugins/modules/ipaconfig.py @@ -441,7 +441,11 @@ def main(): elif ( isinstance(value, (tuple, list)) and arg_type == "bool" ): - exit_args[k] = (value[0] == "TRUE") + # FreeIPA 4.9.10+ and 4.10 use proper mapping for + # boolean values, so we need to convert it to str + # for comparison. + # See: https://github.com/freeipa/freeipa/pull/6294 + exit_args[k] = (str(value[0]).upper() == "TRUE") else: if arg_type not in type_map: raise ValueError( diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py index 99aa226da9d37656f47554e1d119fd2030829077..f4c6c634c5f45fbc3fdae564f2b52102b2d028cb 100644 --- a/plugins/modules/ipadnsforwardzone.py +++ b/plugins/modules/ipadnsforwardzone.py @@ -344,7 +344,13 @@ def main(): if state in ['enabled', 'disabled']: if existing_resource is not None: - is_enabled = existing_resource["idnszoneactive"][0] + # FreeIPA 4.9.10+ and 4.10 use proper mapping for + # boolean values, so we need to convert it to str + # for comparison. + # See: https://github.com/freeipa/freeipa/pull/6294 + is_enabled = ( + str(existing_resource["idnszoneactive"][0]).upper() + ) else: ansible_module.fail_json( msg="dnsforwardzone '%s' not found." % (name)) diff --git a/plugins/modules/ipadnszone.py b/plugins/modules/ipadnszone.py index ae9b75163cb4470f968744619fe672c7cf9d0352..d64e6e0ad2e6f44cb1bb4a2e1a97c0235f07a09f 100644 --- a/plugins/modules/ipadnszone.py +++ b/plugins/modules/ipadnszone.py @@ -418,7 +418,11 @@ class DNSZoneModule(IPAAnsibleModule): is_zone_active = False else: zone = response["result"] - is_zone_active = "TRUE" in zone.get("idnszoneactive") + # FreeIPA 4.9.10+ and 4.10 use proper mapping for boolean vaalues. + # See: https://github.com/freeipa/freeipa/pull/6294 + is_zone_active = ( + str(zone.get("idnszoneactive")[0]).upper() == "TRUE" + ) return zone, is_zone_active diff --git a/plugins/modules/ipahbacrule.py b/plugins/modules/ipahbacrule.py index 002004ad23f67be1e89048bda72bb78c56bc5006..f1e0a5c49500f4d2f0d55c7290a666b99dce18f7 100644 --- a/plugins/modules/ipahbacrule.py +++ b/plugins/modules/ipahbacrule.py @@ -472,18 +472,26 @@ def main(): # hbacrule_enable is not failing on an enabled hbacrule # Therefore it is needed to have a look at the ipaenabledflag # in res_find. - if "ipaenabledflag" not in res_find or \ - res_find["ipaenabledflag"][0] != "TRUE": + # FreeIPA 4.9.10+ and 4.10 use proper mapping for + # boolean values, so we need to convert it to str + # for comparison. + # See: https://github.com/freeipa/freeipa/pull/6294 + enabled_flag = str(res_find.get("ipaenabledflag", [False])[0]) + if enabled_flag.upper() != "TRUE": commands.append([name, "hbacrule_enable", {}]) elif state == "disabled": if res_find is None: ansible_module.fail_json(msg="No hbacrule '%s'" % name) - # hbacrule_disable is not failing on an disabled hbacrule + # hbacrule_disable is not failing on an enabled hbacrule # Therefore it is needed to have a look at the ipaenabledflag # in res_find. - if "ipaenabledflag" not in res_find or \ - res_find["ipaenabledflag"][0] != "FALSE": + # FreeIPA 4.9.10+ and 4.10 use proper mapping for + # boolean values, so we need to convert it to str + # for comparison. + # See: https://github.com/freeipa/freeipa/pull/6294 + enabled_flag = str(res_find.get("ipaenabledflag", [False])[0]) + if enabled_flag.upper() != "FALSE": commands.append([name, "hbacrule_disable", {}]) else: diff --git a/plugins/modules/ipasudorule.py b/plugins/modules/ipasudorule.py index 7d6cd860c6b2cebf294100f24826a30ddc0735a1..fd3671edbbf56eb44c8cce42cf2b592d006cde58 100644 --- a/plugins/modules/ipasudorule.py +++ b/plugins/modules/ipasudorule.py @@ -656,8 +656,12 @@ def main(): # sudorule_enable is not failing on an enabled sudorule # Therefore it is needed to have a look at the ipaenabledflag # in res_find. - if "ipaenabledflag" not in res_find or \ - res_find["ipaenabledflag"][0] != "TRUE": + # FreeIPA 4.9.10+ and 4.10 use proper mapping for + # boolean values, so we need to convert it to str + # for comparison. + # See: https://github.com/freeipa/freeipa/pull/6294 + enabled_flag = str(res_find.get("ipaenabledflag", [False])[0]) + if enabled_flag.upper() != "TRUE": commands.append([name, "sudorule_enable", {}]) elif state == "disabled": @@ -666,8 +670,12 @@ def main(): # sudorule_disable is not failing on an disabled sudorule # Therefore it is needed to have a look at the ipaenabledflag # in res_find. - if "ipaenabledflag" not in res_find or \ - res_find["ipaenabledflag"][0] != "FALSE": + # FreeIPA 4.9.10+ and 4.10 use proper mapping for + # boolean values, so we need to convert it to str + # for comparison. + # See: https://github.com/freeipa/freeipa/pull/6294 + enabled_flag = str(res_find.get("ipaenabledflag", [False])[0]) + if enabled_flag.upper() != "FALSE": commands.append([name, "sudorule_disable", {}]) else: diff --git a/tests/pytests/dnszone/test_dnszone.py b/tests/pytests/dnszone/test_dnszone.py index 00978f0fd917f4ef6c256b77489ea497dfa34c1d..67a985482de2b0ae96e84eeff83d76214572095a 100644 --- a/tests/pytests/dnszone/test_dnszone.py +++ b/tests/pytests/dnszone/test_dnszone.py @@ -64,18 +64,26 @@ class TestDNSZone(AnsibleFreeIPATestCase): def test_dnszone_disable(self): """TC-30: Disable DNS Zone.""" zone26 = "26testzone.test" - self.check_details(["Active zone: TRUE"], "dnszone-find", [zone26]) + self.check_details( + ["Active zone: (TRUE|True)"], "dnszone-find", [zone26] + ) # Disable dns zone self.run_playbook(BASE_PATH + "dnszone_disable.yaml") - self.check_details(["Active zone: FALSE"], "dnszone-find", [zone26]) + self.check_details( + ["Active zone: (FALSE|False)"], "dnszone-find", [zone26] + ) def test_dnszone_enable(self): """TC-31: Enable DNS Zone.""" zone26 = "26testzone.test" - self.check_details(["Active zone: FALSE"], "dnszone-find", [zone26]) + self.check_details( + ["Active zone: (FALSE|False)"], "dnszone-find", [zone26] + ) # Enable dns zone self.run_playbook(BASE_PATH + "dnszone_enable.yaml") - self.check_details(["Active zone: TRUE"], "dnszone-find", [zone26]) + self.check_details( + ["Active zone: (TRUE|True)"], "dnszone-find", [zone26] + ) def test_dnszone_name_from_ip(self): """TC-35: Add dns zone with reverse zone IP. Bug#1845056.""" diff --git a/tests/utils.py b/tests/utils.py index db22f9735fdea6939e00d45ff71912c77d5f934a..c7e630a5fd6f2099e53c7a22344310a5226ad22f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -21,6 +21,7 @@ import os import pytest +import re import subprocess import tempfile import testinfra @@ -314,6 +315,10 @@ class AnsibleFreeIPATestCase(TestCase): expected_msg in result.stderr.decode("utf8") ) + @staticmethod + def __is_text_on_data(text, data): + return re.search(text, data) is not None + def check_details(self, expected_output, cmd, extra_cmds=None): cmd = "ipa " + cmd if extra_cmds: @@ -322,10 +327,16 @@ class AnsibleFreeIPATestCase(TestCase): res = self.master.run(cmd) if res.rc != 0: for output in expected_output: - assert output in res.stderr + assert self.__is_text_on_data(output, res.stderr), ( + f"\n{'='*40}\nExpected: {output}\n{'='*40}\n" + + f"Output:\n{res.stderr}{'='*40}\n" + ) else: for output in expected_output: - assert output in res.stdout + assert self.__is_text_on_data(output, res.stdout), ( + f"\n{'='*40}\nExpected: {output}\n{'='*40}\n" + + f"Output:\n{res.stdout}{'='*40}\n" + ) kdestroy(self.master) def check_notexists(self, members, cmd, extra_cmds=None): @@ -335,7 +346,10 @@ class AnsibleFreeIPATestCase(TestCase): kinit_admin(self.master) res = self.master.run(cmd) for member in members: - assert member not in res.stdout + assert not self.__is_text_on_data(member, res.stdout), ( + f"\n{'='*40}\nExpected: {member}\n{'='*40}\n" + + f"Output:\n{res.stdout}{'='*40}\n" + ) kdestroy(self.master) def mark_xfail_using_ansible_freeipa_version(self, version, reason):