From 809e41540304a14e7f867782b7772978467dd888 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes <zerwes@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:26:18 +0200 Subject: [PATCH] task #38 - generic unboundplus cfg with sections and uuid-subsections --- tasks/unbound.yml | 232 ++++---------------------------------- tasks/unboundplus.yml | 43 ++++--- tasks/unboundplusuuid.yml | 14 +++ 3 files changed, 56 insertions(+), 233 deletions(-) create mode 100644 tasks/unboundplusuuid.yml diff --git a/tasks/unbound.yml b/tasks/unbound.yml index fc96f5b..b7a8de0 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -12,24 +12,20 @@ # active_interface: lan,wan # default: empty => all # outgoing_interface: # local_zone_type: transparent +# hosts: +# 04ac0d40-ecd0-4a1c-8603-91ce9aed08ad: # uuid +# enabled: 1 +# hostname: "*" +# domain: test.de +# rr: A +# mxprio: +# mx: +# server: 10.11.12.13 +# description: test de +# aliases: # ... -# domainoverrides: # list of domainoverrides dicts -# - domain: example.xor -# ip: 127.0..1.1 -# descr: xtra domain # descr is optional, but in order to work as expected -# # please do yourself a favor and be consistent and use -# # either in all entries or none of them -# ... -# acls: # list of acl dicts -# - aclname: dnsaclx # !!! please use uniq names !!! -# aclaction: allow -# description: dns acl for xtra -# rows: -# - acl_network: 172.0.0.0 -# mask: 24 -# description: this network # same restrictions as for domainoverrides descr -# # entries apply here -# ... +# +# see tests/unbound*.yml for more examples - name: fail if we have a deprecated config delegate_to: localhost @@ -37,16 +33,15 @@ msg: "found deprectated 'opn_unbound' setting! please use 'opn_unboundplus'!" when: opn_unbound is defined -- name: unbound general settings - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/OPNsense/unboundplus/general/{{ item.key }} - value: "{{ item.value }}" - pretty_print: true - register: _unbound_general_settings - with_dict: - - "{{ opn_unboundplus.general | default({}) }}" +- name: unboundplus + ansible.builtin.include_tasks: unboundplus.yml + vars: + unboundplussection: "{{ _opnunbndsettings.key }}" + unboundplussectionsettings: "{{ _opnunbndsettings.value }}" + when: opn_unboundplus is defined + with_dict: "{{ opn_unboundplus }}" + loop_control: + loop_var: _opnunbndsettings # this is just a hackish fix for the strange empty tag handling in community.general.xml # https://github.com/ansible-collections/community.general/issues/8361 @@ -60,187 +55,6 @@ with_items: - present - absent - when: _unbound_general_settings is changed - -# unbound/domainoverrides - -- name: count unbound/domainoverrides - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides/domain - count: true - register: configured_unbound_domainoverrides_count - -- name: debug configured_unbound_domainoverrides_count - ansible.builtin.debug: - var: configured_unbound_domainoverrides_count - verbosity: 1 - -- name: get unbound/domainoverrides/domain entries - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides/domain - content: "text" - register: configured_unbound_domainoverrides_domain - when: configured_unbound_domainoverrides_count.count > 0 - -- name: debug configured_unbound_domainoverrides_domain - ansible.builtin.debug: - var: configured_unbound_domainoverrides_domain - verbosity: 1 - -- name: get unbound/domainoverrides/ip entries - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides/ip - content: "text" - register: configured_unbound_domainoverrides_ip - when: configured_unbound_domainoverrides_count.count > 0 - -- name: denug configured_unbound_domainoverrides_ip - ansible.builtin.debug: - var: configured_unbound_domainoverrides_ip - verbosity: 1 - -# descr is optional -# FIXME: here the detection is not working in all cases -# i.e. if you do not use descr in the first element of the -# domainoverrides list -- name: get unbound/domainoverrides/descr entries - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides/descr - content: "text" - ignore_errors: true - register: configured_unbound_domainoverrides_descr - when: configured_unbound_domainoverrides_count.count > 0 - -- name: debug configured_unbound_domainoverrides_descr - ansible.builtin.debug: - var: configured_unbound_domainoverrides_descr|default([]) - verbosity: 1 - -- name: init configured_unbound_domainoverrides - ansible.builtin.set_fact: - configured_unbound_domainoverrides: [] - -- name: populate configured_unbound_domainoverrides - ansible.builtin.set_fact: - configured_unbound_domainoverrides: "[ - {% for domaindict in configured_unbound_domainoverrides_domain.matches %} - { - 'domain':'{{ domaindict.domain }}', - 'ip':'{{ configured_unbound_domainoverrides_ip.matches[loop.index0].ip }}' - {% if configured_unbound_domainoverrides_descr.matches[loop.index0].descr is defined - and configured_unbound_domainoverrides_descr.matches[loop.index0].descr %} - ,'descr':'{{ configured_unbound_domainoverrides_descr.matches[loop.index0].descr }}' - {% endif %} - }, - {% endfor %} - ]" - when: configured_unbound_domainoverrides_count.count > 0 - -- name: debug configured_unbound_domainoverrides - ansible.builtin.debug: - var: configured_unbound_domainoverrides - verbosity: 1 -- name: debug opn_unbound.domainoverrides - ansible.builtin.debug: - var: opn_unbound.domainoverrides|default([]) - verbosity: 1 - -- name: compare configured and defined unbound domainoverrides - ansible.builtin.set_fact: - unbound_domainoverrides_delta: "{{ configured_unbound_domainoverrides | symmetric_difference(opn_unbound.domainoverrides | default([])) }}" -- name: debug delta between configured and defined unbound domainoverrides - ansible.builtin.debug: - var: unbound_domainoverrides_delta - verbosity: 1 -- name: check if a update of unbound domainoverrides is required - ansible.builtin.set_fact: - unbound_domainoverrides_update: true - when: unbound_domainoverrides_delta | length > 0 - -# opnsense uses one or more domainoverrides entries for one forward-zone -# in unbound multiple entries for the same zone are merged into one forward-zone -# with multiple forward-addr entries -# so here we just have one chance: remove all domainoverrides and recreate them in a bulk -- name: unbound domainoverrides - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides - state: absent - pretty_print: true - when: unbound_domainoverrides_update | default(False) - -- name: unbound domainoverrides # noqa jinja[spacing] - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound - add_children: "[ - {% for domainoverrides in opn_unbound.domainoverrides -%} - '<domainoverrides> - {% for k, v in domainoverrides.items() | list -%} - <{{ k }}>{{ v }}</{{ k }}> - {%- endfor %} - </domainoverrides>', - {%- endfor %} - ]" - input_type: xml - pretty_print: true - when: - - opn_unbound.domainoverrides is defined - - unbound_domainoverrides_update | default(False) - -# END unbound/domainoverrides - -# unbound/acls -# assumes uniq names and doesn't clean up undefined ACLs -# in order to remove stuff from the xml, use opn_unset - -- name: unbound acls aclaction - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ item.aclname }}']/aclaction" - value: "{{ item.aclaction }}" - pretty_print: true - with_items: - - "{{ opn_unbound.acls | default([]) }}" - -- name: unbound acls description - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ item.aclname }}']/description" - value: "{{ item.description }}" - pretty_print: true - with_items: - - "{{ opn_unbound.acls | default([]) }}" - when: item.description is defined - -# Invalid variable name in 'register' specified: 'configured_unbound_acls_rows_count['{{ item.0.aclname }}']' -# FIXME use block with_items and nested loop in block - -- name: unbound acls rows - ansible.builtin.include_tasks: unboundaclsrows.yml - vars: - aclname: "{{ item.aclname }}" - rows: "{{ item.rows }}" - when: item.rows is defined - with_items: - - "{{ opn_unbound.acls | default([]) }}" - -# END unbound/acls - -- name: unboundplus - ansible.builtin.include_tasks: unboundplus.yml - when: opn_unboundplus is defined + when: _unbound_settings is changed or _unbound_settings_uuid is changed ... diff --git a/tasks/unboundplus.yml b/tasks/unboundplus.yml index 5447077..de5f856 100644 --- a/tasks/unboundplus.yml +++ b/tasks/unboundplus.yml @@ -1,36 +1,31 @@ # vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 smartindent nu ft=yaml --- -# example definition: -# -# opn_unboundplus: -# dnsbl: -# enabled: 1 -# type: "aa,ag,bla0,bla" -# whitelists: "*.example.com,*.another.xyz" -# dots: DNSoverTLS is NOT YET IMPLEMENTED! -# miscellaneous: -# privatedomain: "..." -# insecuredomain: "..." +# handle different unboundlus sections -- name: unboundplus dnsbl +- name: unboundplus settings {{ unboundplussection }} delegate_to: localhost community.general.xml: path: "{{ local_config_path }}" - xpath: "/opnsense/OPNsense/unboundplus/dnsbl/{{ item.key }}" + xpath: "/opnsense/OPNsense/unboundplus/{{ unboundplussection }}/{{ item.key }}" value: "{{ item.value }}" pretty_print: true - with_dict: "{{ opn_unboundplus.dnsbl }}" - when: opn_unboundplus.dnsbl is defined + register: _unbound_settings + with_dict: "{{ unboundplussectionsettings }}" + when: + - unboundplussectionsettings is defined + - unboundplussection not in opn_unboundplus_uuid_sections.keys() -- name: unboundplus miscellaneous - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/OPNsense/unboundplus/miscellaneous/{{ item.key }}" - value: "{{ item.value }}" - pretty_print: true - with_dict: "{{ opn_unboundplus.miscellaneous }}" - when: opn_unboundplus.miscellaneous is defined +- name: unboundplus uuid settings for {{ unboundplussection }} + ansible.builtin.include_tasks: unboundplusuuid.yml + vars: + _uuid: "{{ _opnunbndsettingsuuid.key }}" + _uuidvalues: "{{ _opnunbndsettingsuuid.value }}" + with_dict: "{{ unboundplussectionsettings }}" + loop_control: + loop_var: _opnunbndsettingsuuid + when: + - unboundplussectionsettings is defined + - unboundplussection in opn_unboundplus_uuid_sections.keys() ... diff --git a/tasks/unboundplusuuid.yml b/tasks/unboundplusuuid.yml new file mode 100644 index 0000000..8fab5bc --- /dev/null +++ b/tasks/unboundplusuuid.yml @@ -0,0 +1,14 @@ +--- + +- name: unboundplus settings {{ unboundplussection }} + delegate_to: localhost + community.general.xml: + path: "{{ local_config_path }}" + xpath: "/opnsense/OPNsense/unboundplus/{{ unboundplussection }}/{{ opn_unboundplus_uuid_sections[unboundplussection] }}[@uuid='{{ _uuid }}']/{{ item.key }}" + value: "{{ item.value }}" + pretty_print: true + register: _unbound_settings_uuid + with_dict: "{{ _uuidvalues }}" + + +...