From 260716b9a46a1b157e20106cd40730222490a294 Mon Sep 17 00:00:00 2001 From: stratus-ss Date: Sat, 15 Mar 2025 09:33:09 -0500 Subject: [PATCH 1/3] [pfsense_dns_resolver_config] updated module so that when using preserve: true, the current dns settings will be preserved and appended to and not overwritten --- plugins/modules/pfsense_dns_resolver.py | 108 +- .../fixtures/pfsense_dns_resolver_config.xml | 1842 +++++++++++++++++ 2 files changed, 1945 insertions(+), 5 deletions(-) create mode 100644 tests/unit/plugins/modules/fixtures/pfsense_dns_resolver_config.xml diff --git a/plugins/modules/pfsense_dns_resolver.py b/plugins/modules/pfsense_dns_resolver.py index ff527c1c..b744ee77 100644 --- a/plugins/modules/pfsense_dns_resolver.py +++ b/plugins/modules/pfsense_dns_resolver.py @@ -270,6 +270,11 @@ default: 1 choices: [ 0, 1, 2, 3, 4, 5 ] type: int + preserve: + description: Preserve the current DNS entries instead of overriding them. + required: false + default: false + type: bool """ EXAMPLES = """ @@ -375,7 +380,8 @@ infra_host_ttl=dict(default=900, type='int', choices=[60, 120, 300, 600, 900]), infra_cache_numhosts=dict(default=10000, type='int', choices=[1000, 5000, 10000, 20000, 50000, 100000, 200000]), unwanted_reply_threshold=dict(default="disabled", type='str', choices=["disabled", "5000000", "10000000", "20000000", "40000000", "50000000"]), - log_verbosity=dict(default=1, type='int', choices=[0, 1, 2, 3, 4, 5]) + log_verbosity=dict(default=1, type='int', choices=[0, 1, 2, 3, 4, 5]), + preserve=dict(default=False, type='bool'), # TODO: Disable Auto-added Access Control # TODO: Disable Auto-added Host Entries # TODO: Experimental Bit 0x20 Support @@ -431,6 +437,62 @@ def _params_to_obj(self): params = self.params obj = dict() + # Initialize with existing configuration_merg + if self.root_elt is not None: + # Preserve existing hosts + existing_hosts = [] + # Preserve existing custom options + existing_custom_options = [] + custom_options_elt = self.root_elt.find("custom_options") + + if custom_options_elt is not None and custom_options_elt.text: + # Decode the base64-encoded custom options + decoded_custom_options = base64.b64decode(custom_options_elt.text).decode('utf-8') + # Split into lines for comparison + existing_custom_options = [line.strip() for line in decoded_custom_options.strip().split("\n")] + + if params.get("custom_options"): + new_custom_options = [line.strip() for line in params["custom_options"].strip().split("\n")] + merged_custom_options = existing_custom_options.copy() + for option in new_custom_options: + if "view:" or "server:" in option: + merged_custom_options.append(option) + elif option not in existing_custom_options: + merged_custom_options.append(option) + else: + pass + + custom_opts_base64 = base64.b64encode(bytes("\n".join(merged_custom_options), "utf-8")).decode() + + else: + # If no new custom options are provided, retain the existing ones + custom_opts_base64 = custom_options_elt.text if custom_options_elt is not None else "" + + if params.get("preserve"): + for host_elt in self.root_elt.findall("hosts"): + host_entry = {} + for child in host_elt: + if child.tag == "aliases" and child.text is not None: + # Handle aliases as a string if it's not an XML element + host_entry["aliases"] = child.text + else: + host_entry[child.tag] = child.text + existing_hosts.append(host_entry) + existing_hosts.extend(params.get("hosts")) + # exit() + + # Preserve existing domain overrides + existing_overrides = [] + for override_elt in self.root_elt.findall("domainoverrides"): + override_entry = {} + for child in override_elt: + override_entry[child.tag] = child.text + existing_overrides.append(override_entry) + + if existing_hosts: + obj["hosts"] = existing_hosts + if existing_overrides: + obj["domainoverrides"] = existing_overrides if params["state"] == "present": @@ -467,10 +529,41 @@ def _params_to_obj(self): self._get_ansible_param(obj, "infra_cache_numhosts") self._get_ansible_param(obj, "unwanted_reply_threshold") self._get_ansible_param(obj, "log_verbosity") - self._get_ansible_param(obj, "hosts") self._get_ansible_param(obj, "domainoverrides") for domainoverride in obj.get("domainoverrides", []): self._get_ansible_param_bool(domainoverride, "forward_tls_upstream", value="", params=domainoverride) + obj["custom_options"] = base64.b64encode(bytes(params['custom_options'], 'utf-8')).decode() + if params.get("preserve"): + obj["hosts"] = existing_hosts + if existing_overrides: + obj["domainoverrides"] = existing_overrides + if existing_custom_options: + obj["custom_options"] = custom_opts_base64 + + # Append new hosts if provided + if params.get("hosts"): + if "hosts" not in obj: + obj["hosts"] = [] + + # Process new hosts + for new_host in params["hosts"]: + # Format aliases for the new host + if new_host.get("aliases"): + new_host["aliases"] = {"item": new_host["aliases"]} + else: + new_host["aliases"] = "\n\t\t\t" + + existing_host_index = self._find_host_index(obj, new_host) + + if existing_host_index is not None: + obj["hosts"][existing_host_index] = new_host + else: + obj["hosts"].append(new_host) + # Append new domain overrides if provided + if params.get("domainoverrides"): + if "domainoverrides" not in obj: + obj["domainoverrides"] = [] + obj["domainoverrides"].extend(params["domainoverrides"]) if ((self.pfsense.config_get_path('system/dnslocalhost') != 'remote') and ("lo0" not in obj['active_interface']) and ("all" not in obj['active_interface'])): @@ -485,11 +578,17 @@ def _params_to_obj(self): "item": tmp_aliases } else: - # Default is an empty element host["aliases"] = "" - return obj + def _find_host_index(self, obj, new_host): + for index, nested_dict in enumerate(obj["hosts"]): + existing_host = f"{nested_dict.get('host')}.{nested_dict.get('domain')}" + new_host_fqdn = f"{new_host.get('host')}.{new_host.get('domain')}" + if existing_host == new_host_fqdn: + return index + return None + def _validate_params(self): """ do some extra checks on input parameters """ params = self.params @@ -585,7 +684,6 @@ def _log_fields(self, before=None): # todo: hosts and domainoverrides is not logged return values - def main(): module = AnsibleModule( argument_spec=DNS_RESOLVER_ARGUMENT_SPEC, diff --git a/tests/unit/plugins/modules/fixtures/pfsense_dns_resolver_config.xml b/tests/unit/plugins/modules/fixtures/pfsense_dns_resolver_config.xml new file mode 100644 index 00000000..031bdb7f --- /dev/null +++ b/tests/unit/plugins/modules/fixtures/pfsense_dns_resolver_config.xml @@ -0,0 +1,1842 @@ + + 18.9 + + + normal + pfSense + acme.com + on + + all + All Users + system + 1998 + + + admins + System Administrators + system + 1999 + 0 + page-all + + + + system + + test + + + + + system + + groupe1 + + + + + system + + groupe2 + + + + admin + System Administrator + system + admins + xxx + 0 + user-shell-access + + 2 + + + pfSense.css + + 2000 + 2000 + 0.pfsense.pool.ntp.org + + http + + 5c00e5f9029df + 2 + + yes + + + + 400000 + hadp + hadp + hadp + + monthly + + + + enabled + + Etc/UTC + + + + + vmx0 + + wan + + 192.168.240.137 + + + 32 + + + + + + + + SavedCfg + + + + + + + + 24 + + + + + + + + vmx1 + lan + 192.168.1.242 + 24 + + + 2001::2001:22 + 64 + + + + vmx2 + pub + + + 10.0.0.1 + 24 + + + vmx3 + vt1 + + + 10.10.0.1 + 16 + + + lan_1100 + vmx1.1100 + + + 172.16.151.210 + 24 + + + lan_1200 + vmx1.1200 + + + 172.16.152.210 + 24 + + + vmx4 + vt2 + + dhcp + + + + + + + + + + 192.168.1.100 + 192.168.1.199 + + + + + + 10.0.0.2 + 10.0.0.99 + + + + + + + + + + + + + + hmac-md5 + + + + allow + + + + + + + + + + + + + ab:ab:ab:ab:ab:ab + dhcphostid + 10.0.0.100 + dhcphostname + + + + + + + + + + + + + hmac-md5 + + + + + + + + + + + + + + + 10.10.0.2 + 10.10.0.99 + + + + + + + + + + + + + + hmac-md5 + + + + allow + + + + + + + + + + + + + + + 172.16.152.2 + 172.16.152.99 + + + + + + + + + + + + + + hmac-md5 + + + + allow + + + + + + + + + + + + + + + + + ::1000 + ::2000 + + disabled + medium + + + + + + public + + + + + + + + 1 + + 50 + + ipv4 + + + + advanced + + + any + + + + + + + wan + + + + + + + + + + + + + + + + + + + + + + wanip + 22022 + + tcp + 10.255.1.20 + 22 + wan + + + + + + + + + + + + + + + + + + fr1 + test_separator + bg-info + lan + + + + + + + 1560930241 + match + lan + inet + + + in + yes + yes + + + + + + + + tcp + + + port_ssh + + + + + + floating_rule_1 + + + + 1560930241 + match + lan,wan,opt3 + inet + + + in + yes + yes + + + + + + + + tcp + + + + + + port_ssh + + + floating_rule_2 + + + + + + + tcp + + antilock_out_1 + + + + + + + port_ssh + + keep state + + + + 1545574416 + wan + inet + pass + + + + + + + + tcp + + antilock_out_2 + + + + + + + port_http + + keep state + + + + 1545574416 + wan + inet + pass + + + + + + + + tcp + + antilock_out_3 + + + + + + + 443 + + keep state + + + + 1545574416 + wan + inet + pass + + + + + + + + tcp + + antilock_out_1 + + + + + + + port_ssh + + keep state + + + + 1545574416 + lan + inet + pass + + + + + + + + tcp + + antilock_out_2 + + + + + + + port_http + + keep state + + + + 1545574416 + lan + inet + pass + + + + + + + + tcp + + antilock_out_3 + + + + + + + 443 + + keep state + + + + 1545574416 + lan + inet + pass + + + + + + + + tcp + + antilock_out_1 + + + + + + + port_ssh + + keep state + + + + 1545574416 + opt3 + inet + pass + + + + + + + + tcp + + antilock_out_2 + + + + + + + port_http + + keep state + + + + 1545574416 + opt3 + inet + pass + + + + + + + + tcp + + antilock_out_3 + + + + + + + 443 + + keep state + + + + 1545574416 + opt3 + inet + pass + + + + + + + + udp + + void_conf_tftp_1 + + + + + + 69 +
lan_voip_poc2
+
+ keep state + +
ipbx_poc3
+ + 1545602758 + opt3 + inet + pass + +
+ + + + + + icmp + + ping_from_poc3_2 + + + + + +
srv_admin
+
+ keep state + +
lan_voip_poc3
+ + 1545602758 + opt3 + inet + pass + +
+ + + + + + udp + + void_conf_tftp_2 + + + + + + 69 +
lan_voip_poc1
+
+ keep state + +
ipbx_poc3
+ + 1545602758 + opt3 + inet + pass + +
+ + + + + + tcp + + antilock_out_1 + + + + + + + port_ssh + + keep state + + + + 1545574416 + opt1 + inet + pass + + + + + + + + tcp + + antilock_out_2 + + + + + + + port_http + + keep state + + + + 1545574416 + opt1 + inet + pass + + + + + + + + tcp + + antilock_out_3 + + + + + + + 443 + + keep state + + + + 1545574416 + opt1 + inet + pass + + + + + + + + udp + + void_conf_tftp_3 + + + + + + 69 +
lan_voip_poc3
+
+ keep state + +
ipbx_poc2
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + udp + + ads_to_ads_udp_3_1 + + + + + + port_dns +
ad_poc3
+
+ keep state + +
ad_poc2
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + udp + + ads_to_ads_udp_3_2 + + + + + + port_ldap +
ad_poc3
+
+ keep state + +
ad_poc2
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + udp + + ads_to_ads_udp_4_1 + + + + + + port_dns +
ad_poc3
+
+ keep state + +
ad_poc1
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + udp + + ads_to_ads_udp_4_2 + + + + + + port_ldap +
ad_poc3
+
+ keep state + +
ad_poc1
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + udp + + void_conf_tftp_4 + + + + + + 69 +
lan_voip_poc3
+
+ keep state + +
ipbx_poc1
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + tcp + + ads_to_ads_tcp_4_1 + + + + + + port_dns +
ad_poc3
+
+ keep state + +
ad_poc1
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + tcp + + ads_to_ads_tcp_4_2 + + + + + + port_ldap +
ad_poc3
+
+ keep state + +
ad_poc1
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + tcp + + ads_to_ads_tcp_4_3 + + + + + + port_ldap_ssl +
ad_poc3
+
+ keep state + +
ad_poc1
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + + admin_bypass + + + + + + + + keep state + +
srv_admin
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + tcp + + ads_to_ads_tcp_3_1 + + + + + + port_dns +
ad_poc3
+
+ keep state + +
ad_poc2
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + tcp + + ads_to_ads_tcp_3_2 + + + + + + port_ldap +
ad_poc3
+
+ keep state + +
ad_poc2
+ + 1545602758 + opt1 + inet + pass + +
+ + + + + + tcp + + ads_to_ads_tcp_3_3 + + + + + + port_ldap_ssl +
ad_poc3
+
+ keep state + +
ad_poc2
+ + 1545602758 + opt1 + inet + pass + +
+
+ + + + + + port + port_ssh + +
22
+
+ + + port + port_http + +
80
+
+ + + host + srv_admin + +
192.168.1.165
+
+ + + port + port_dns + +
51
+
+ + + port + port_ldap + +
389
+
+ + + port + port_ldap_ssl + +
636
+
+ + + network + lan_voip_poc2 + +
172.16.2.0/24
+
+ + + network + lan_voip_poc3 + +
172.16.3.0/24
+
+ + + network + lan_voip_poc1 + +
172.16.1.0/24
+
+ + + host + ad_poc3 + +
192.168.3.3
+
+ + + host + ad_poc2 + +
192.168.2.3
+
+ + + host + ad_poc1 + +
192.168.1.3
+
+ + + network + lan_data_poc3 + +
192.168.3.0/24
+
+ + + host + ipbx_poc3 + +
172.16.3.3
+
+ + + host + ipbx_poc2 + +
172.16.2.3
+
+ + + host + ipbx_poc1 + +
172.16.1.3
+
+ +
http://www.acme-corp.com
+ urltable + 10 + http://www.acme-corp.com + + acme_corp + +
+
+ + + + 1,31 + 0-5 + * + * + * + root + /usr/bin/nice -n20 adjkerntz -a + + + 1 + 3 + 1 + * + * + root + /usr/bin/nice -n20 /etc/rc.update_bogons.sh + + + */60 + * + * + * + * + root + /usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 sshguard + + + */60 + * + * + * + * + root + /usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 webConfiguratorlockout + + + 1 + 1 + * + * + * + root + /usr/bin/nice -n20 /etc/rc.dyndns.update + + + */60 + * + * + * + * + root + /usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 virusprot + + + 30 + 12 + * + * + * + root + /usr/bin/nice -n20 /etc/rc.update_urltables + + + 1 + 0 + * + * + * + root + /usr/bin/nice -n20 /etc/rc.update_pkg_metadata + + + 0 + 0 + * + * + * + root + /usr/local/sbin/squid -k rotate -f /usr/local/etc/squid/squid.conf + + + 15 + 0 + * + * + * + root + /usr/local/pkg/swapstate_check.php + + + + + + + + + ICMP + icmp + ICMP + + + + TCP + tcp + Generic TCP + + + + HTTP + http + Generic HTTP + + / + + 200 + + + + HTTPS + https + Generic HTTPS + + / + + 200 + + + + SMTP + send + Generic SMTP + + + 220 * + + + + + system_information:col1:open:0,interfaces:col2:open:0 + 10 + + + + + + + + + + lan + all + 1 + 4 + 10 + 10 + auto + 512 + 200 + 86400 + 0 + 900 + 10000 + disabled + ZGlyZWN0Cgpsb2NhbC16b25lOiAiYXBpLnF1YXkub2NwNC5leGFtcGxlLmNvbSIgcmVkaXJlY3QKbG9jYWwtZGF0YTogImFwaS5xdWF5Lm9jcDQuZXhhbXBsZS5jb20gODY0MDAgSU4gQSAxOTIuMTY4Ljk0LjQyIgpsb2NhbC16b25lOiAiYXBwcy5xdWF5Lm9jcDQuZXhhbXBsZS5jb20iIHJlZGlyZWN0CmxvY2FsLWRhdGE6ICJhcHBzLnF1YXkub2NwNC5leGFtcGxlLmNvbSA4NjQwMCBJTiBBIDE5Mi4xNjguOTQuNDMiCgpzZXJ2ZXI6CmFjY2Vzcy1jb250cm9sLXZpZXc6IDE5Mi4xNjguMTk5LjAvMjEgQWxsb3dfVkxBTjE5OQoKdmlldzoKbmFtZTogIkFsbG93X1ZMQU4xOTkiCnZpZXctZmlyc3Q6IHllcwpsb2NhbC1kYXRhOiAicGZzZW5zZS5leGFtcGxlLmNvbSBBIDE5Mi4xNjguMTk5LjciCgo= + + api + one.ocp4.example.com + 192.168.94.40 + + + + + apps + two.ocp4.example.com + 192.168.94.45 + + + + + containers + example.com + 192.168.99.33 + + + + pictures + example.com + + + + recipes + example.com + + + + + all + + transparent + + + + 5e6e610114156 + + facebook.com + 127.0.0.1 + + + + + + + + + + + aggregated change + + + + 5c00e5f9029df + webConfigurator default (5c00e5f9029df) + server + xxx + xxx + + + + wan + 192.168.1.220 + GW_WAN + 1 + inet + + Interface wan Gateway + + + lan + 192.168.1.220 + GW_LAN + 1 + inet + + Interface lan Gateway + + GW_WAN + + + + nmap + NMap is a utility for network exploration or security auditing.<br/> + It supports ping scanning (determine which hosts are up), many port scanning techniques (determine what services the hosts are offering), version detection (determine what application/service is running on a port), and TCP/IP fingerprinting (remote host OS or device identification). + It also offers flexible target and port specification, decoy/stealth scanning, SunRPC scanning, and more. + 1.4.4_1 + https://doc.pfsense.org/index.php/Nmap_package + nmap.xml + /usr/local/pkg/nmap.inc + + + iftop + https://forum.pfsense.org/ + Realtime interface monitor (console/shell only). + http://www.ex-parrot.com/~pdw/iftop/ + 0.17_2 + iftop.xml + + + Open-VM-Tools + VMware Tools is a suite of utilities that enhances the performance of the virtual machine's guest operating system and improves management of the virtual machine. + http://open-vm-tools.sourceforge.net/ + 10.1.0,1 + https://doc.pfsense.org/index.php/Open_VM_Tools_package + open-vm-tools.xml + /usr/local/pkg/open-vm-tools.inc + + + squid3 + squid + High performance web proxy cache (3.4 branch). It combines Squid as a proxy server with its capabilities of acting as a HTTP / HTTPS reverse proxy.<br /> + It includes an Exchange-Web-Access (OWA) Assistant, SSL filtering and antivirus integration via C-ICAP. + https://forum.pfsense.org/index.php?board=60.0 + http://www.squid-cache.org/ + 0.4.44_7 + squid.xml + squid_generate_rules + + + General + /pkg_edit.php?xml=squid.xml&id=0 + + + + Remote Cache + /pkg.php?xml=squid_upstream.xml + + + Local Cache + /pkg_edit.php?xml=squid_cache.xml&id=0 + + + Antivirus + /pkg_edit.php?xml=squid_antivirus.xml&id=0 + + + ACLs + /pkg_edit.php?xml=squid_nac.xml&id=0 + + + Traffic Mgmt + /pkg_edit.php?xml=squid_traffic.xml&id=0 + + + Authentication + /pkg_edit.php?xml=squid_auth.xml&id=0 + + + Users + /pkg.php?xml=squid_users.xml + + + Real Time + /squid_monitor.php + + + Sync + /pkg_edit.php?xml=squid_sync.xml + + + /usr/local/pkg/squid.inc + + + NMap +
Diagnostics
+ nmap.xml +
+ + Squid Proxy Server + Modify the proxy server settings +
Services
+ /pkg_edit.php?xml=squid.xml&id=0 +
+ + Squid Reverse Proxy + Modify the reverse proxy server settings +
Services
+ /pkg_edit.php?xml=squid_reverse_general.xml&id=0 +
+ + vmware-guestd + vmware-guestd.sh + mwexec("/usr/local/etc/rc.d/vmware-guestd status") == 0; + VMware Guest Daemon + + + vmware-kmod + vmware-kmod.sh + mwexec("/usr/local/etc/rc.d/vmware-kmod status") == 0; + VMware Kernel Modules + + + squid + squid.sh + squid + Squid Proxy Server Service + + + clamd + clamd.sh + clamd + ClamAV Antivirus + + + c-icap + c-icap.sh + c-icap + ICAP Inteface for Squid and ClamAV integration + + + + heap LFUDA + 90 + 95 + + + + 100 + ufs + 16 + /var/squid/cache + 0 + 4 + 64 + 256 + heap GDSF + + + + + + + + none + + + + + on + on + lan + 3128 + + on + + + + + lan + + + + + splicewhitelist + lan + + modern + 2048 + none + + + + + /var/squid/logs + + + localhost + admin@localhost + en + on + + strip + + + + + + + + + + + + + Lg== + + + + + + + +
+ + + + + ipalias + lan + 5c0a4b6139b05 + + single + 24 + 10.255.2.254 + + + ipalias + lan + 5c0a4bd391375 + + single + 24 + 10.255.3.254 + + + + + pfSense + acme.com + + + + + opt1 opt2 opt3 + + IFGROUP1 + + + + + vmx0 + 100 + + + vmx0.100 + + + vmx1 + 100 + + + vmx1.100 + + + vmx1 + 1100 + + + vmx1.1100 + + + vmx2 + 1100 + + + vmx2.1100 + + +
From 23173cd0bb90c755313eba00aa8d37cc366196b0 Mon Sep 17 00:00:00 2001 From: Orion Poplawski Date: Mon, 18 Aug 2025 22:13:10 -0600 Subject: [PATCH 2/3] Fix index and conditional --- plugins/modules/pfsense_dns_resolver.py | 40 ++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/plugins/modules/pfsense_dns_resolver.py b/plugins/modules/pfsense_dns_resolver.py index b744ee77..5e4301d3 100644 --- a/plugins/modules/pfsense_dns_resolver.py +++ b/plugins/modules/pfsense_dns_resolver.py @@ -455,31 +455,30 @@ def _params_to_obj(self): new_custom_options = [line.strip() for line in params["custom_options"].strip().split("\n")] merged_custom_options = existing_custom_options.copy() for option in new_custom_options: - if "view:" or "server:" in option: + if "view:" in option or "server:" in option: merged_custom_options.append(option) elif option not in existing_custom_options: merged_custom_options.append(option) else: - pass + pass custom_opts_base64 = base64.b64encode(bytes("\n".join(merged_custom_options), "utf-8")).decode() else: - # If no new custom options are provided, retain the existing ones - custom_opts_base64 = custom_options_elt.text if custom_options_elt is not None else "" + # If no new custom options are provided, retain the existing ones + custom_opts_base64 = custom_options_elt.text if custom_options_elt is not None else "" if params.get("preserve"): - for host_elt in self.root_elt.findall("hosts"): - host_entry = {} - for child in host_elt: - if child.tag == "aliases" and child.text is not None: - # Handle aliases as a string if it's not an XML element - host_entry["aliases"] = child.text - else: - host_entry[child.tag] = child.text - existing_hosts.append(host_entry) - existing_hosts.extend(params.get("hosts")) - # exit() + for host_elt in self.root_elt.findall("hosts"): + host_entry = {} + for child in host_elt: + if child.tag == "aliases" and child.text is not None: + # Handle aliases as a string if it's not an XML element + host_entry["aliases"] = child.text + else: + host_entry[child.tag] = child.text + existing_hosts.append(host_entry) + existing_hosts.extend(params.get("hosts")) # Preserve existing domain overrides existing_overrides = [] @@ -534,11 +533,11 @@ def _params_to_obj(self): self._get_ansible_param_bool(domainoverride, "forward_tls_upstream", value="", params=domainoverride) obj["custom_options"] = base64.b64encode(bytes(params['custom_options'], 'utf-8')).decode() if params.get("preserve"): - obj["hosts"] = existing_hosts - if existing_overrides: - obj["domainoverrides"] = existing_overrides - if existing_custom_options: - obj["custom_options"] = custom_opts_base64 + obj["hosts"] = existing_hosts + if existing_overrides: + obj["domainoverrides"] = existing_overrides + if existing_custom_options: + obj["custom_options"] = custom_opts_base64 # Append new hosts if provided if params.get("hosts"): @@ -684,6 +683,7 @@ def _log_fields(self, before=None): # todo: hosts and domainoverrides is not logged return values + def main(): module = AnsibleModule( argument_spec=DNS_RESOLVER_ARGUMENT_SPEC, From 7875e7a8546ace8511b9c1599ac6d8099d73d654 Mon Sep 17 00:00:00 2001 From: Orion Poplawski Date: Mon, 18 Aug 2025 22:17:11 -0600 Subject: [PATCH 3/3] indent --- plugins/modules/pfsense_dns_resolver.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/modules/pfsense_dns_resolver.py b/plugins/modules/pfsense_dns_resolver.py index 5e4301d3..e5c7e814 100644 --- a/plugins/modules/pfsense_dns_resolver.py +++ b/plugins/modules/pfsense_dns_resolver.py @@ -535,9 +535,9 @@ def _params_to_obj(self): if params.get("preserve"): obj["hosts"] = existing_hosts if existing_overrides: - obj["domainoverrides"] = existing_overrides + obj["domainoverrides"] = existing_overrides if existing_custom_options: - obj["custom_options"] = custom_opts_base64 + obj["custom_options"] = custom_opts_base64 # Append new hosts if provided if params.get("hosts"): @@ -581,12 +581,12 @@ def _params_to_obj(self): return obj def _find_host_index(self, obj, new_host): - for index, nested_dict in enumerate(obj["hosts"]): - existing_host = f"{nested_dict.get('host')}.{nested_dict.get('domain')}" - new_host_fqdn = f"{new_host.get('host')}.{new_host.get('domain')}" - if existing_host == new_host_fqdn: - return index - return None + for index, nested_dict in enumerate(obj["hosts"]): + existing_host = f"{nested_dict.get('host')}.{nested_dict.get('domain')}" + new_host_fqdn = f"{new_host.get('host')}.{new_host.get('domain')}" + if existing_host == new_host_fqdn: + return index + return None def _validate_params(self): """ do some extra checks on input parameters """