Skip to content

Commit ce6264c

Browse files
stratus-ssopoplawski
authored andcommitted
[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
1 parent 9ab04ad commit ce6264c

File tree

2 files changed

+1945
-6
lines changed

2 files changed

+1945
-6
lines changed

plugins/modules/pfsense_dns_resolver.py

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,11 @@
267267
default: 1
268268
choices: [ 0, 1, 2, 3, 4, 5 ]
269269
type: int
270+
preserve:
271+
description: Preserve the current DNS entries instead of overriding them.
272+
required: false
273+
default: false
274+
type: bool
270275
"""
271276

272277
EXAMPLES = """
@@ -371,7 +376,8 @@
371376
infra_host_ttl=dict(default=900, type='int', choices=[60, 120, 300, 600, 900]),
372377
infra_cache_numhosts=dict(default=10000, type='int', choices=[1000, 5000, 10000, 20000, 50000, 100000, 200000]),
373378
unwanted_reply_threshold=dict(default="disabled", type='str', choices=["disabled", "5000000", "10000000", "20000000", "40000000", "50000000"]),
374-
log_verbosity=dict(default=1, type='int', choices=[0, 1, 2, 3, 4, 5])
379+
log_verbosity=dict(default=1, type='int', choices=[0, 1, 2, 3, 4, 5]),
380+
preserve=dict(default=False, type='bool'),
375381
# TODO: Disable Auto-added Access Control
376382
# TODO: Disable Auto-added Host Entries
377383
# TODO: Experimental Bit 0x20 Support
@@ -415,13 +421,68 @@ def _params_to_obj(self):
415421
params = self.params
416422

417423
obj = dict()
424+
# Initialize with existing configuration_merg
425+
if self.root_elt is not None:
426+
# Preserve existing hosts
427+
existing_hosts = []
428+
# Preserve existing custom options
429+
existing_custom_options = []
430+
custom_options_elt = self.root_elt.find("custom_options")
431+
432+
if custom_options_elt is not None and custom_options_elt.text:
433+
# Decode the base64-encoded custom options
434+
decoded_custom_options = base64.b64decode(custom_options_elt.text).decode('utf-8')
435+
# Split into lines for comparison
436+
existing_custom_options = [line.strip() for line in decoded_custom_options.strip().split("\n")]
437+
438+
if params.get("custom_options"):
439+
new_custom_options = [line.strip() for line in params["custom_options"].strip().split("\n")]
440+
merged_custom_options = existing_custom_options.copy()
441+
for option in new_custom_options:
442+
if "view:" or "server:" in option:
443+
merged_custom_options.append(option)
444+
elif option not in existing_custom_options:
445+
merged_custom_options.append(option)
446+
else:
447+
pass
448+
449+
custom_opts_base64 = base64.b64encode(bytes("\n".join(merged_custom_options), "utf-8")).decode()
450+
451+
else:
452+
# If no new custom options are provided, retain the existing ones
453+
custom_opts_base64 = custom_options_elt.text if custom_options_elt is not None else ""
454+
455+
if params.get("preserve"):
456+
for host_elt in self.root_elt.findall("hosts"):
457+
host_entry = {}
458+
for child in host_elt:
459+
if child.tag == "aliases" and child.text is not None:
460+
# Handle aliases as a string if it's not an XML element
461+
host_entry["aliases"] = child.text
462+
else:
463+
host_entry[child.tag] = child.text
464+
existing_hosts.append(host_entry)
465+
existing_hosts.extend(params.get("hosts"))
466+
# exit()
467+
468+
# Preserve existing domain overrides
469+
existing_overrides = []
470+
for override_elt in self.root_elt.findall("domainoverrides"):
471+
override_entry = {}
472+
for child in override_elt:
473+
override_entry[child.tag] = child.text
474+
existing_overrides.append(override_entry)
475+
476+
if existing_hosts:
477+
obj["hosts"] = existing_hosts
478+
if existing_overrides:
479+
obj["domainoverrides"] = existing_overrides
418480

419481
if params["state"] == "present":
420482

421483
obj["enable"] = ""
422484
obj["active_interface"] = ",".join(self.get_interface_by_display_name(x) for x in params["active_interface"])
423485
obj["outgoing_interface"] = ",".join(self.get_interface_by_display_name(x) for x in params["outgoing_interface"])
424-
obj["custom_options"] = base64.b64encode(bytes(params['custom_options'], 'utf-8')).decode()
425486
self._get_ansible_param_bool(obj, "hideidentity", value="")
426487
self._get_ansible_param_bool(obj, "hideversion", value="")
427488
self._get_ansible_param_bool(obj, "dnssecstripped", value="")
@@ -451,8 +512,39 @@ def _params_to_obj(self):
451512
self._get_ansible_param(obj, "infra_cache_numhosts")
452513
self._get_ansible_param(obj, "unwanted_reply_threshold")
453514
self._get_ansible_param(obj, "log_verbosity")
454-
self._get_ansible_param(obj, "hosts")
455515
self._get_ansible_param(obj, "domainoverrides")
516+
obj["custom_options"] = base64.b64encode(bytes(params['custom_options'], 'utf-8')).decode()
517+
if params.get("preserve"):
518+
obj["hosts"] = existing_hosts
519+
if existing_overrides:
520+
obj["domainoverrides"] = existing_overrides
521+
if existing_custom_options:
522+
obj["custom_options"] = custom_opts_base64
523+
524+
# Append new hosts if provided
525+
if params.get("hosts"):
526+
if "hosts" not in obj:
527+
obj["hosts"] = []
528+
529+
# Process new hosts
530+
for new_host in params["hosts"]:
531+
# Format aliases for the new host
532+
if new_host.get("aliases"):
533+
new_host["aliases"] = {"item": new_host["aliases"]}
534+
else:
535+
new_host["aliases"] = "\n\t\t\t"
536+
537+
existing_host_index = self._find_host_index(obj, new_host)
538+
539+
if existing_host_index is not None:
540+
obj["hosts"][existing_host_index] = new_host
541+
else:
542+
obj["hosts"].append(new_host)
543+
# Append new domain overrides if provided
544+
if params.get("domainoverrides"):
545+
if "domainoverrides" not in obj:
546+
obj["domainoverrides"] = []
547+
obj["domainoverrides"].extend(params["domainoverrides"])
456548

457549
if obj["active_interface"] != "all":
458550
obj["active_interface"] += ",lo0"
@@ -465,11 +557,17 @@ def _params_to_obj(self):
465557
"item": tmp_aliases
466558
}
467559
else:
468-
# Default is an empty element
469560
host["aliases"] = ""
470-
471561
return obj
472562

563+
def _find_host_index(self, obj, new_host):
564+
for index, nested_dict in enumerate(obj["hosts"]):
565+
existing_host = f"{nested_dict.get('host')}.{nested_dict.get('domain')}"
566+
new_host_fqdn = f"{new_host.get('host')}.{new_host.get('domain')}"
567+
if existing_host == new_host_fqdn:
568+
return index
569+
return None
570+
473571
def _validate_params(self):
474572
""" do some extra checks on input parameters """
475573
params = self.params
@@ -567,7 +665,6 @@ def _log_fields(self, before=None):
567665
# todo: hosts and domainoverrides is not logged
568666
return values
569667

570-
571668
def main():
572669
module = AnsibleModule(
573670
argument_spec=DNS_RESOLVER_ARGUMENT_SPEC,

0 commit comments

Comments
 (0)