From 355438cea9dcb748c3a158a7c3a9be44fe2607a7 Mon Sep 17 00:00:00 2001 From: Rafael Guterres Jeffman Date: Tue, 26 Aug 2025 09:10:48 -0300 Subject: [PATCH] ipadnsrecord: Allow setting any IP address if create_reverse is false Adding an A/AAAA record to a host fails if there's not a reverse zone set that the resulting PTR record can be added to, even if create_reverse is false. Changing the rule to create the reverse record fixes the issue. Fixes: #1381 Signed-off-by: Rafael Guterres Jeffman --- plugins/modules/ipadnsrecord.py | 7 ++++--- tests/dnsrecord/env_cleanup.yml | 2 -- tests/dnsrecord/env_setup.yml | 2 -- tests/dnsrecord/env_vars.yml | 7 +++++-- tests/dnsrecord/test_dnsrecord.yml | 22 ++++++++++++++++++++++ tests/host/test_host_reverse.yml | 25 +++++++++---------------- 6 files changed, 40 insertions(+), 25 deletions(-) diff --git a/plugins/modules/ipadnsrecord.py b/plugins/modules/ipadnsrecord.py index c8559c49..06ab43da 100644 --- a/plugins/modules/ipadnsrecord.py +++ b/plugins/modules/ipadnsrecord.py @@ -1454,11 +1454,13 @@ def define_commands_for_present_state(module, zone_name, entry, res_find): # Create reverse records for existing records for ipv in ['a', 'aaaa']: record = '%srecord' % ipv - if record in args and ('%s_extra_create_reverse' % ipv) in args: + if ( + record in args + and args.pop('%s_extra_create_reverse' % ipv, False) + ): cmds = create_reverse_ip_record( module, zone_name, name, args[record]) _commands.extend(cmds) - del args['%s_extra_create_reverse' % ipv] for record, fields in _RECORD_PARTS.items(): part_fields = [f for f in fields if f in args] if part_fields: @@ -1620,7 +1622,6 @@ def main(): commands.extend(cmds) # Execute commands - changed = ansible_module.execute_ipa_commands( commands, exception_handler=exception_handler) diff --git a/tests/dnsrecord/env_cleanup.yml b/tests/dnsrecord/env_cleanup.yml index b74aca35..70d3a019 100644 --- a/tests/dnsrecord/env_cleanup.yml +++ b/tests/dnsrecord/env_cleanup.yml @@ -134,11 +134,9 @@ name: "{{ item }}" state: absent with_items: - - "{{ zone_prefix_reverse }}" - "{{ zone_prefix_reverse_24 }}" - "{{ zone_prefix_reverse_16 }}" - "{{ zone_prefix_reverse_8 }}" - - "{{ zone_ipv6_reverse }}" - "{{ zone_ipv6_reverse_workaround }}" - "{{ testzone }}" - "{{ safezone }}" diff --git a/tests/dnsrecord/env_setup.yml b/tests/dnsrecord/env_setup.yml index 73e9f305..79d0b81e 100644 --- a/tests/dnsrecord/env_setup.yml +++ b/tests/dnsrecord/env_setup.yml @@ -15,13 +15,11 @@ skip_nameserver_check: yes skip_overlap_check: yes with_items: - - "{{ zone_prefix_reverse }}" - "{{ zone_prefix_reverse_24 }}" - "{{ zone_prefix_reverse_16 }}" - "{{ zone_prefix_reverse_8 }}" - "{{ zone_ipv6_reverse_workaround }}" - "{{ testzone }}" - - "{{ zone_ipv6_reverse }}" - name: Ensure DNSSEC zone '"{{ safezone }}"' is present. ipadnszone: diff --git a/tests/dnsrecord/env_vars.yml b/tests/dnsrecord/env_vars.yml index c2e180bc..d6f61559 100644 --- a/tests/dnsrecord/env_vars.yml +++ b/tests/dnsrecord/env_vars.yml @@ -7,14 +7,17 @@ ipv4_reverse: "{{ ansible_facts['default_ipv4'].address.split('.')[:-1] | reverse | join('.') }}" + # The 'external_ipv4_address' represents an IP address that + # is not part of the expected CIDR zones managed by the IPA + # deployment. It is used to test the cases were the the reverse + # DNS zone must not be available in the embedded DNS nameserver. + external_ipv4_address: "1.2.3.4" - name: Set zone prefixes. ansible.builtin.set_fact: testzone: 'testzone.test' safezone: 'safezone.test' - zone_ipv6_reverse: "ip6.arpa." zone_ipv6_reverse_workaround: "d.f.ip6.arpa." - zone_prefix_reverse: "in-addr.arpa." zone_prefix_reverse_24: "{{ ipv4_reverse.split('.')[:] | join('.') }}.in-addr.arpa." zone_prefix_reverse_16: "{{ ipv4_reverse.split('.')[1:] | join('.') }}.in-addr.arpa." zone_prefix_reverse_8: "{{ ipv4_reverse.split('.')[2:] | join('.') }}.in-addr.arpa." diff --git a/tests/dnsrecord/test_dnsrecord.yml b/tests/dnsrecord/test_dnsrecord.yml index b7f83d3b..74bc4781 100644 --- a/tests/dnsrecord/test_dnsrecord.yml +++ b/tests/dnsrecord/test_dnsrecord.yml @@ -1545,6 +1545,28 @@ register: result failed_when: result.changed or result.failed + - name: Ensure host has IP in subnet not managed by IPA, without PTR record + ipadnsrecord: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + zone_name: "{{ testzone }}" + name: host01 + a_rec: "{{ external_ipv4_address }}" + a_create_reverse: false + register: result + failed_when: not result.changed or result.failed + + - name: Ensure host has IP in subnet not managed by IPA, without PTR record, again + ipadnsrecord: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + zone_name: "{{ testzone }}" + name: host01 + a_rec: "{{ external_ipv4_address }}" + a_create_reverse: false + register: result + failed_when: result.changed or result.failed + # cleanup - name: Cleanup test environment. ansible.builtin.include_tasks: env_cleanup.yml diff --git a/tests/host/test_host_reverse.yml b/tests/host/test_host_reverse.yml index 1b05d071..2f90d527 100644 --- a/tests/host/test_host_reverse.yml +++ b/tests/host/test_host_reverse.yml @@ -1,8 +1,16 @@ --- -- name: Test host +- name: Test host reverse attribute hosts: ipaserver become: true + module_defaults: + ipahost: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + ipadnszone: + ipaadmin_password: SomeADMINpassword + ipaapi_context: "{{ ipa_context | default(omit) }}" + tasks: - name: Get Domain from server name ansible.builtin.set_fact: @@ -15,7 +23,6 @@ - name: Host absent ipahost: - ipaadmin_password: SomeADMINpassword name: - "{{ host1_fqdn }}" update_dns: yes @@ -28,30 +35,24 @@ - name: Set zone prefixes. ansible.builtin.set_fact: - zone_ipv6_reverse: "ip6.arpa." zone_ipv6_reverse_workaround: "d.f.ip6.arpa." - zone_prefix_reverse: "in-addr.arpa" zone_prefix_reverse_8: "{{ ipv4_prefix.split('.')[2::-1] | join('.') }}.in-addr.arpa" zone_prefix_reverse_16: "{{ ipv4_prefix.split('.')[1::-1] | join('.') }}.in-addr.arpa" zone_prefix_reverse_24: "{{ ipv4_prefix.split('.')[::-1] | join('.') }}.in-addr.arpa" - name: Set zone for reverse address. ipadnszone: - ipaadmin_password: SomeADMINpassword name: "{{ item }}" skip_nameserver_check: yes skip_overlap_check: yes with_items: - - "{{ zone_ipv6_reverse }}" - "{{ zone_ipv6_reverse_workaround }}" - - "{{ zone_prefix_reverse }}" - "{{ zone_prefix_reverse_8 }}" - "{{ zone_prefix_reverse_16 }}" - "{{ zone_prefix_reverse_24 }}" - name: Host "{{ host1_fqdn }}" present ipahost: - ipaadmin_password: SomeADMINpassword name: "{{ host1_fqdn }}" ip_address: "{{ ipv4_prefix + '.201' }}" update_dns: yes @@ -61,7 +62,6 @@ - name: Host "{{ host1_fqdn }}" present, again. ipahost: - ipaadmin_password: SomeADMINpassword name: "{{ host1_fqdn }}" ip_address: "{{ ipv4_prefix + '.201' }}" update_dns: yes @@ -71,7 +71,6 @@ - name: Hosts host1 absent ipahost: - ipaadmin_password: SomeADMINpassword name: - "{{ host1_fqdn }}" update_dns: yes @@ -81,7 +80,6 @@ - name: Host "{{ host1_fqdn }}" present with IPv6 ipahost: - ipaadmin_password: SomeADMINpassword name: "{{ host1_fqdn }}" ip_address: "fd00::0001" update_dns: yes @@ -91,7 +89,6 @@ - name: Host "{{ host1_fqdn }}" present with IPv6, again. ipahost: - ipaadmin_password: SomeADMINpassword name: "{{ host1_fqdn }}" ip_address: "fd00::0001" update_dns: yes @@ -101,7 +98,6 @@ - name: Hosts host1 absent ipahost: - ipaadmin_password: SomeADMINpassword name: - "{{ host1_fqdn }}" update_dns: yes @@ -111,13 +107,10 @@ - name: Delete zone for reverse address. ipadnszone: - ipaadmin_password: SomeADMINpassword name: "{{ item }}" state: absent with_items: - - "{{ zone_ipv6_reverse }}" - "{{ zone_ipv6_reverse_workaround }}" - - "{{ zone_prefix_reverse }}" - "{{ zone_prefix_reverse_8 }}" - "{{ zone_prefix_reverse_16 }}" - "{{ zone_prefix_reverse_24 }}"