Update CHANGELOG for v1.3.4 release; add new features and bug fixes
Some checks failed
Test Collection / Sanity Tests (Ansible devel) (push) Failing after 12s
Test Collection / Sanity Tests (Ansible stable-2.15) (push) Failing after 28s
Test Collection / Sanity Tests (Ansible stable-2.16) (push) Failing after 27s
Test Collection / Sanity Tests (Ansible stable-2.17) (push) Failing after 28s
Test Collection / Python Syntax Check (push) Failing after 6s
Test Collection / Build Collection (push) Failing after 10s
Test Collection / YAML and Ansible Lint (push) Successful in 10s
Test Collection / Documentation Check (push) Successful in 7s
Test Collection / Unit Tests (push) Successful in 8s
Some checks failed
Test Collection / Sanity Tests (Ansible devel) (push) Failing after 12s
Test Collection / Sanity Tests (Ansible stable-2.15) (push) Failing after 28s
Test Collection / Sanity Tests (Ansible stable-2.16) (push) Failing after 27s
Test Collection / Sanity Tests (Ansible stable-2.17) (push) Failing after 28s
Test Collection / Python Syntax Check (push) Failing after 6s
Test Collection / Build Collection (push) Failing after 10s
Test Collection / YAML and Ansible Lint (push) Successful in 10s
Test Collection / Documentation Check (push) Successful in 7s
Test Collection / Unit Tests (push) Successful in 8s
Add example playbooks for filtering and updating DNS zones Enhance nsupdate_zone module with default_ttl handling and improved diff output
This commit is contained in:
@@ -4,6 +4,29 @@ Valid.Nsupdate_zone Collection Release Notes
|
|||||||
|
|
||||||
.. contents:: Topics
|
.. contents:: Topics
|
||||||
|
|
||||||
|
v1.3.4
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Enhancements to record handling, diff output, and defaults.
|
||||||
|
|
||||||
|
New Features
|
||||||
|
------------
|
||||||
|
|
||||||
|
- Add default_ttl parameter to apply a consistent TTL when records omit ttl
|
||||||
|
- Extend ignore_dnssec_records to ignore CDNSKEY, CDS, and TYPE65534
|
||||||
|
- Improve diff output to zone file format with +/- markers and per-record lines
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Allow extra keys in zones and records by filtering input before processing
|
||||||
|
- Fix diff output newline rendering by returning lists of lines
|
||||||
|
- Use correct Ansible diff flag via module._diff
|
||||||
|
- Improve error reporting with better messages and verbose traceback output
|
||||||
|
|
||||||
v1.3.3
|
v1.3.3
|
||||||
======
|
======
|
||||||
|
|
||||||
@@ -18,6 +41,12 @@ New Features
|
|||||||
- Add ignore_ns_records flag (default: true) to automatically ignore NS records
|
- Add ignore_ns_records flag (default: true) to automatically ignore NS records
|
||||||
- Add support for extra keys in zones and records parameters via options_ignore_list
|
- Add support for extra keys in zones and records parameters via options_ignore_list
|
||||||
|
|
||||||
|
New Features
|
||||||
|
------------
|
||||||
|
|
||||||
|
- Add ignore_ns_records flag (default: true) to automatically ignore NS records
|
||||||
|
- Add support for extra keys in zones and records parameters via options_ignore_list
|
||||||
|
|
||||||
v1.3.2
|
v1.3.2
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|||||||
76
examples/filter_and_update_zones.yml
Normal file
76
examples/filter_and_update_zones.yml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
# Simpler approach: Just extract the fields you need inline
|
||||||
|
# This is cleaner and easier to understand/maintain
|
||||||
|
|
||||||
|
- name: Clean zones and update DNS
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
zones_with_extras:
|
||||||
|
- name: example.com
|
||||||
|
type: internal
|
||||||
|
comment: "Main domain"
|
||||||
|
dns_server: ns1.example.com
|
||||||
|
records:
|
||||||
|
- record: 'example.com.'
|
||||||
|
type: A
|
||||||
|
value: 192.168.1.1
|
||||||
|
ttl: 3600
|
||||||
|
comment: "Zone apex"
|
||||||
|
|
||||||
|
- record: www
|
||||||
|
type: A
|
||||||
|
value: 192.168.1.10
|
||||||
|
comment: "Web server"
|
||||||
|
ttl: 300
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Extract cleaned zones with only valid keys
|
||||||
|
set_fact:
|
||||||
|
cleaned_zones: |
|
||||||
|
{% set zones = [] %}
|
||||||
|
{% for zone in zones_with_extras %}
|
||||||
|
{% set cleaned_zone = {
|
||||||
|
'name': zone.name,
|
||||||
|
'records': []
|
||||||
|
} %}
|
||||||
|
{% if zone.get('dns_server') %}
|
||||||
|
{% set _ = cleaned_zone.update({'dns_server': zone.dns_server}) %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for record in zone.records %}
|
||||||
|
{% set cleaned_record = {
|
||||||
|
'record': record.record,
|
||||||
|
'type': record.type,
|
||||||
|
'value': record.value
|
||||||
|
} %}
|
||||||
|
{% if record.get('ttl') %}
|
||||||
|
{% set _ = cleaned_record.update({'ttl': record.ttl}) %}
|
||||||
|
{% endif %}
|
||||||
|
{% if record.get('state') %}
|
||||||
|
{% set _ = cleaned_record.update({'state': record.state}) %}
|
||||||
|
{% endif %}
|
||||||
|
{% set _ = cleaned_zone.records.append(cleaned_record) %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% set _ = zones.append(cleaned_zone) %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ zones }}
|
||||||
|
|
||||||
|
- name: Display cleaned zones
|
||||||
|
debug:
|
||||||
|
var: cleaned_zones
|
||||||
|
|
||||||
|
- name: Update DNS zones (no validation errors expected)
|
||||||
|
valid.nsupdate_zone.nsupdate_zone:
|
||||||
|
key_name: "nsupdate"
|
||||||
|
key_secret: "{{ vault_dns_key }}"
|
||||||
|
zones: "{{ cleaned_zones }}"
|
||||||
|
register: dns_result
|
||||||
|
# Uncomment when testing:
|
||||||
|
# check_mode: yes
|
||||||
|
|
||||||
|
- name: Show results
|
||||||
|
debug:
|
||||||
|
var: dns_result.results
|
||||||
110
examples/filter_zones.yml
Normal file
110
examples/filter_zones.yml
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
---
|
||||||
|
# Example playbook to filter zones variable to only include valid keys
|
||||||
|
# This is useful if you have extra metadata/comments in your zones definition
|
||||||
|
# and want to clean it before passing to nsupdate_zone module
|
||||||
|
|
||||||
|
- name: Filter and rebuild zones list with valid keys only
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# Example zones with extra keys (comment, type, custom_field, etc.)
|
||||||
|
zones_with_extras:
|
||||||
|
- name: example.com
|
||||||
|
type: internal # <- extra key
|
||||||
|
comment: "Main domain" # <- extra key
|
||||||
|
custom_field: foo # <- extra key
|
||||||
|
dns_server: ns1.example.com
|
||||||
|
records:
|
||||||
|
- record: 'example.com.'
|
||||||
|
type: A
|
||||||
|
value: 192.168.1.1
|
||||||
|
ttl: 3600
|
||||||
|
comment: "Zone apex" # <- extra key
|
||||||
|
|
||||||
|
- record: www
|
||||||
|
type: A
|
||||||
|
value: 192.168.1.10
|
||||||
|
comment: "Web server" # <- extra key
|
||||||
|
ttl: 300
|
||||||
|
|
||||||
|
- name: example.org
|
||||||
|
type: external # <- extra key
|
||||||
|
dns_server: ns2.example.org
|
||||||
|
records:
|
||||||
|
- record: 'example.org.'
|
||||||
|
type: A
|
||||||
|
value: 192.168.2.1
|
||||||
|
ttl: 3600
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Display original zones (with extra keys)
|
||||||
|
debug:
|
||||||
|
var: zones_with_extras
|
||||||
|
|
||||||
|
- name: Filter zones to valid keys only
|
||||||
|
set_fact:
|
||||||
|
cleaned_zones: "{{ zones_with_extras | map('dict2items') | map('selectattr', 'key', 'in', zone_valid_keys) | map('list') | map('items2dict') | list }}"
|
||||||
|
vars:
|
||||||
|
zone_valid_keys:
|
||||||
|
- name
|
||||||
|
- dns_server
|
||||||
|
- records
|
||||||
|
|
||||||
|
- name: Filter records within each zone to valid keys only
|
||||||
|
set_fact:
|
||||||
|
cleaned_zones: |
|
||||||
|
[
|
||||||
|
{%- for zone in cleaned_zones -%}
|
||||||
|
{
|
||||||
|
"name": {{ zone.name | to_json }},
|
||||||
|
{%- if zone.get('dns_server') %}
|
||||||
|
"dns_server": {{ zone.dns_server | to_json }},
|
||||||
|
{%- endif %}
|
||||||
|
"records": [
|
||||||
|
{%- for record in zone.records -%}
|
||||||
|
{
|
||||||
|
"record": {{ record.record | to_json }},
|
||||||
|
"type": {{ record.type | to_json }},
|
||||||
|
"value": {{ record.value | to_json }}
|
||||||
|
{%- if record.get('ttl') %},
|
||||||
|
"ttl": {{ record.ttl | to_json }}
|
||||||
|
{%- endif %}
|
||||||
|
{%- if record.get('state') %},
|
||||||
|
"state": {{ record.state | to_json }}
|
||||||
|
{%- endif %}
|
||||||
|
}{{ "," if not loop.last }}
|
||||||
|
{%- endfor %}
|
||||||
|
]
|
||||||
|
}{{ "," if not loop.last }}
|
||||||
|
{%- endfor %}
|
||||||
|
]
|
||||||
|
|
||||||
|
- name: Parse cleaned zones JSON
|
||||||
|
set_fact:
|
||||||
|
cleaned_zones: "{{ cleaned_zones | from_json }}"
|
||||||
|
|
||||||
|
- name: Display cleaned zones (only valid keys)
|
||||||
|
debug:
|
||||||
|
var: cleaned_zones
|
||||||
|
|
||||||
|
- name: Show the difference
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
Original zone 0 keys: {{ zones_with_extras[0].keys() | list }}
|
||||||
|
Cleaned zone 0 keys: {{ cleaned_zones[0].keys() | list }}
|
||||||
|
|
||||||
|
Original record 0 keys: {{ zones_with_extras[0].records[0].keys() | list }}
|
||||||
|
Cleaned record 0 keys: {{ cleaned_zones[0].records[0].keys() | list }}
|
||||||
|
|
||||||
|
- name: Now you can use cleaned_zones with nsupdate_zone module
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
The 'cleaned_zones' variable now contains only valid keys and can be passed
|
||||||
|
directly to the nsupdate_zone module without parameter validation errors:
|
||||||
|
|
||||||
|
- name: Update DNS zones
|
||||||
|
valid.nsupdate_zone.nsupdate_zone:
|
||||||
|
key_name: "nsupdate"
|
||||||
|
key_secret: "your-key"
|
||||||
|
zones: "{{ cleaned_zones }}"
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace: "valid"
|
namespace: "valid"
|
||||||
name: "nsupdate_zone"
|
name: "nsupdate_zone"
|
||||||
version: 1.3.3
|
version: 1.3.4
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- Dan Kercher
|
- Dan Kercher
|
||||||
|
|||||||
@@ -388,6 +388,12 @@ class DNSZoneManager:
|
|||||||
self.current_zone = None
|
self.current_zone = None
|
||||||
self.soa_minimum_ttl = 3600 # Default, will be updated from SOA
|
self.soa_minimum_ttl = 3600 # Default, will be updated from SOA
|
||||||
self.default_ttl = module.params.get('default_ttl') # User-specified default, or None to use SOA minimum
|
self.default_ttl = module.params.get('default_ttl') # User-specified default, or None to use SOA minimum
|
||||||
|
|
||||||
|
def _get_default_ttl(self) -> int:
|
||||||
|
"""Get the effective default TTL, preferring user-specified over SOA minimum."""
|
||||||
|
if self.default_ttl is not None:
|
||||||
|
return self.default_ttl
|
||||||
|
return self.soa_minimum_ttl
|
||||||
|
|
||||||
def _resolve_server(self) -> list[str]:
|
def _resolve_server(self) -> list[str]:
|
||||||
"""Resolve DNS server FQDN to IP addresses."""
|
"""Resolve DNS server FQDN to IP addresses."""
|
||||||
@@ -506,7 +512,7 @@ class DNSZoneManager:
|
|||||||
record_name = record_config['record']
|
record_name = record_config['record']
|
||||||
record_type = record_config['type'].upper()
|
record_type = record_config['type'].upper()
|
||||||
record_values = record_config['value']
|
record_values = record_config['value']
|
||||||
record_ttl = record_config.get('ttl', self.soa_minimum_ttl)
|
record_ttl = record_config.get('ttl', self._get_default_ttl())
|
||||||
record_state = record_config.get('state', 'present')
|
record_state = record_config.get('state', 'present')
|
||||||
|
|
||||||
# Normalize record name
|
# Normalize record name
|
||||||
@@ -880,7 +886,7 @@ class DNSZoneManager:
|
|||||||
for record in sorted(changes['deletes'], key=lambda r: (r['name'].to_text(), r['type'])):
|
for record in sorted(changes['deletes'], key=lambda r: (r['name'].to_text(), r['type'])):
|
||||||
record_name = record['name'].to_text().rstrip('.')
|
record_name = record['name'].to_text().rstrip('.')
|
||||||
record_type = record['type']
|
record_type = record['type']
|
||||||
ttl = record.get('ttl', self.soa_minimum_ttl)
|
ttl = record.get(\'ttl\', self._get_default_ttl())
|
||||||
values = sorted(str(v) for v in record['values'])
|
values = sorted(str(v) for v in record['values'])
|
||||||
for value in values:
|
for value in values:
|
||||||
before_lines.append(f"-{record_name:<34} {ttl:<10} {record_type:<10} {value}")
|
before_lines.append(f"-{record_name:<34} {ttl:<10} {record_type:<10} {value}")
|
||||||
@@ -889,7 +895,7 @@ class DNSZoneManager:
|
|||||||
for record in sorted(changes['adds'], key=lambda r: (r['name'].to_text(), r['type'])):
|
for record in sorted(changes['adds'], key=lambda r: (r['name'].to_text(), r['type'])):
|
||||||
record_name = record['name'].to_text().rstrip('.')
|
record_name = record['name'].to_text().rstrip('.')
|
||||||
record_type = record['type']
|
record_type = record['type']
|
||||||
ttl = record.get('ttl', self.soa_minimum_ttl)
|
ttl = record.get(\'ttl\', self._get_default_ttl())
|
||||||
values = sorted(str(v) for v in record['values'])
|
values = sorted(str(v) for v in record['values'])
|
||||||
for value in values:
|
for value in values:
|
||||||
after_lines.append(f"+{record_name:<34} {ttl:<10} {record_type:<10} {value}")
|
after_lines.append(f"+{record_name:<34} {ttl:<10} {record_type:<10} {value}")
|
||||||
@@ -898,8 +904,8 @@ class DNSZoneManager:
|
|||||||
for record in sorted(changes['updates'], key=lambda r: (r['name'].to_text(), r['type'])):
|
for record in sorted(changes['updates'], key=lambda r: (r['name'].to_text(), r['type'])):
|
||||||
record_name = record['name'].to_text().rstrip('.')
|
record_name = record['name'].to_text().rstrip('.')
|
||||||
record_type = record['type']
|
record_type = record['type']
|
||||||
old_ttl = record.get('old_ttl', self.soa_minimum_ttl)
|
old_ttl = record.get(\'old_ttl\', self._get_default_ttl())
|
||||||
new_ttl = record.get('new_ttl', self.soa_minimum_ttl)
|
new_ttl = record.get(\'new_ttl\', self._get_default_ttl())
|
||||||
old_values = sorted(str(v) for v in record['old_values'])
|
old_values = sorted(str(v) for v in record['old_values'])
|
||||||
new_values = sorted(str(v) for v in record['new_values'])
|
new_values = sorted(str(v) for v in record['new_values'])
|
||||||
|
|
||||||
|
|||||||
BIN
valid-nsupdate_zone-1.3.2.tar.gz
Normal file
BIN
valid-nsupdate_zone-1.3.2.tar.gz
Normal file
Binary file not shown.
BIN
valid-nsupdate_zone-1.3.3.tar.gz
Normal file
BIN
valid-nsupdate_zone-1.3.3.tar.gz
Normal file
Binary file not shown.
Reference in New Issue
Block a user