From 845afc0f80254dc84a0ad170acf4244aff90d295 Mon Sep 17 00:00:00 2001 From: Rafael Guterres Jeffman <rjeffman@redhat.com> Date: Thu, 19 Nov 2020 19:13:03 -0300 Subject: [PATCH] ipadnszone: Fix modification o SOA serial with other attributes. Due to an issue with FreeIPA, when modifying the SOA serial attribute along with other attributes, the value is ignored. In order to have the value provided, the attribute is set is a later call to dnszone-mod allowing it to retain the desired value. Ref: https://pagure.io/freeipa/issue/8489 --- plugins/modules/ipadnszone.py | 47 +++++++++++-------- tests/dnszone/test_dnszone_mod.yml | 74 ++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 20 deletions(-) diff --git a/plugins/modules/ipadnszone.py b/plugins/modules/ipadnszone.py index 093eac42..8660997d 100644 --- a/plugins/modules/ipadnszone.py +++ b/plugins/modules/ipadnszone.py @@ -214,6 +214,7 @@ from ansible.module_utils.ansible_freeipa_module import ( is_ipv6_addr, is_valid_port, ) # noqa: E402 +import ipalib.errors import netaddr import six @@ -404,13 +405,14 @@ class DNSZoneModule(FreeIPABaseModule): def get_zone(self, zone_name): get_zone_args = {"idnsname": zone_name, "all": True} - response = self.api_command("dnszone_find", args=get_zone_args) - zone = None - is_zone_active = False - - if response["count"] == 1: - zone = response["result"][0] + try: + response = self.api_command("dnszone_show", args=get_zone_args) + except ipalib.errors.NotFound: + zone = None + is_zone_active = False + else: + zone = response["result"] is_zone_active = zone.get("idnszoneactive") == ["TRUE"] return zone, is_zone_active @@ -448,7 +450,10 @@ class DNSZoneModule(FreeIPABaseModule): # Look for existing zone in IPA zone, is_zone_active = self.get_zone(zone_name) args = self.get_ipa_command_args(zone=zone) - just_added = False + set_serial = self.ipa_params.serial is not None + + if set_serial: + del args["idnssoaserial"] if self.ipa_params.state in ["present", "enabled", "disabled"]: if not zone: @@ -456,7 +461,7 @@ class DNSZoneModule(FreeIPABaseModule): # with given args self.add_ipa_command("dnszone_add", zone_name, args) is_zone_active = True - just_added = True + # just_added = True else: # Zone already exist so we need to verify if given args @@ -464,22 +469,24 @@ class DNSZoneModule(FreeIPABaseModule): if self.require_ipa_attrs_change(args, zone): self.add_ipa_command("dnszone_mod", zone_name, args) - if self.ipa_params.state == "enabled" and not is_zone_active: - self.add_ipa_command("dnszone_enable", zone_name) + if self.ipa_params.state == "enabled" and not is_zone_active: + self.add_ipa_command("dnszone_enable", zone_name) - if self.ipa_params.state == "disabled" and is_zone_active: - self.add_ipa_command("dnszone_disable", zone_name) + if self.ipa_params.state == "disabled" and is_zone_active: + self.add_ipa_command("dnszone_disable", zone_name) - if self.ipa_params.state == "absent": - if zone: - self.add_ipa_command("dnszone_del", zone_name) + if self.ipa_params.state == "absent" and zone is not None: + self.add_ipa_command("dnszone_del", zone_name) # Due to a bug in FreeIPA dnszone-add won't set - # SOA Serial. The good news is that dnszone-mod does the job. - # See: https://pagure.io/freeipa/issue/8227 - # Because of that, if the zone was just added with a given serial - # we run mod just after to workaround the bug - if just_added and self.ipa_params.serial is not None: + # SOA Serial in the creation of a zone, or if + # another field is modified along with it. + # As a workaround, we set only the SOA serial, + # with dnszone-mod, after other changes. + # See: + # - https://pagure.io/freeipa/issue/8227 + # - https://pagure.io/freeipa/issue/8489 + if set_serial: args = { "idnssoaserial": self.ipa_params.serial, } diff --git a/tests/dnszone/test_dnszone_mod.yml b/tests/dnszone/test_dnszone_mod.yml index 4cff8ee3..80e70c6a 100644 --- a/tests/dnszone/test_dnszone_mod.yml +++ b/tests/dnszone/test_dnszone_mod.yml @@ -11,6 +11,80 @@ include_tasks: env_setup.yml # Tests + - name: Verify if zone can be created with a specific SOA serial. + block: + - name: Create zone with serial, refresh, retry and expire. + ipadnszone: + ipaadmin_password: SomeADMINpassword + name: testzone.local + serial: 4567 + refresh: 70 + retry: 89 + expire: 200 + + - name: Verify zone was created with correct values. + shell: | + echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin + KRB5CCNAME={{ KRB5CCNAME }} ipa dnszone-show testzone.local + kdestroy -A -q -c {{ KRB5CCNAME }} + register: result + failed_when: | + result.failed or not ( + "serial: 4567" in result.stdout + and "refresh: 70" in result.stdout + and "retry: 89" in result.stdout + and "expire: 200" in result.stdout + ) + + - name: Remove test zone. + ipadnszone: + ipaadmin_password: SomeADMINpassword + name: testzone.local + state: absent + + vars: + KRB5CCNAME: verify_bz_1876896 + + - name: Verify if a zone can have the the SOA serial modified to a specific value. + block: + - name: Create zone. + ipadnszone: + ipaadmin_password: SomeADMINpassword + name: testzone.local + state: present + + - name: Modify zone with serial, refresh, retry and expire. + ipadnszone: + ipaadmin_password: SomeADMINpassword + name: testzone.local + serial: 4567 + refresh: 70 + retry: 89 + expire: 200 + + - name: Verify zone was modified to the correct values + shell: | + echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin + KRB5CCNAME={{ KRB5CCNAME }} ipa dnszone-show testzone.local + kdestroy -A -q -c {{ KRB5CCNAME }} + register: result + failed_when: | + result.failed or not ( + "serial: 4567" in result.stdout + and "refresh: 70" in result.stdout + and "retry: 89" in result.stdout + and "expire: 200" in result.stdout + ) + + - name: Remove test zone. + ipadnszone: + ipaadmin_password: SomeADMINpassword + name: testzone.local + state: absent + + vars: + KRB5CCNAME: verify_bz_1876896 + - name: Ensure zone is present. ipadnszone: ipaadmin_password: SomeADMINpassword -- GitLab