Skip to content

Commit

Permalink
task #38 - generic unboundplus cfg with sections and uuid-subsections
Browse files Browse the repository at this point in the history
  • Loading branch information
zerwes committed Sep 11, 2024
1 parent 0f75966 commit 809e415
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 233 deletions.
232 changes: 23 additions & 209 deletions tasks/unbound.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,36 @@
# 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
ansible.builtin.fail:
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
Expand All @@ -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

...
43 changes: 19 additions & 24 deletions tasks/unboundplus.yml
Original file line number Diff line number Diff line change
@@ -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()

...
14 changes: 14 additions & 0 deletions tasks/unboundplusuuid.yml
Original file line number Diff line number Diff line change
@@ -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 }}"


...

0 comments on commit 809e415

Please sign in to comment.