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
|
||||
|
||||
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
|
||||
======
|
||||
|
||||
@@ -18,6 +41,12 @@ 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
|
||||
|
||||
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
|
||||
======
|
||||
|
||||
|
||||
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"
|
||||
name: "nsupdate_zone"
|
||||
version: 1.3.3
|
||||
version: 1.3.4
|
||||
readme: README.md
|
||||
authors:
|
||||
- Dan Kercher
|
||||
|
||||
@@ -388,6 +388,12 @@ class DNSZoneManager:
|
||||
self.current_zone = None
|
||||
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
|
||||
|
||||
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]:
|
||||
"""Resolve DNS server FQDN to IP addresses."""
|
||||
@@ -506,7 +512,7 @@ class DNSZoneManager:
|
||||
record_name = record_config['record']
|
||||
record_type = record_config['type'].upper()
|
||||
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')
|
||||
|
||||
# Normalize record name
|
||||
@@ -880,7 +886,7 @@ class DNSZoneManager:
|
||||
for record in sorted(changes['deletes'], key=lambda r: (r['name'].to_text(), r['type'])):
|
||||
record_name = record['name'].to_text().rstrip('.')
|
||||
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'])
|
||||
for value in values:
|
||||
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'])):
|
||||
record_name = record['name'].to_text().rstrip('.')
|
||||
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'])
|
||||
for value in values:
|
||||
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'])):
|
||||
record_name = record['name'].to_text().rstrip('.')
|
||||
record_type = record['type']
|
||||
old_ttl = record.get('old_ttl', self.soa_minimum_ttl)
|
||||
new_ttl = record.get('new_ttl', self.soa_minimum_ttl)
|
||||
old_ttl = record.get(\'old_ttl\', self._get_default_ttl())
|
||||
new_ttl = record.get(\'new_ttl\', self._get_default_ttl())
|
||||
old_values = sorted(str(v) for v in record['old_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