Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Commit

Permalink
Insert new entries before deleting old ones.
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon-TheUser committed May 9, 2022
1 parent cf55ef8 commit ceb8131
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion plugins/modules/net_tools/nsupdate.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,31 @@ def create_record(self):

def modify_record(self):
update = dns.update.Update(self.zone, keyring=self.keyring, keyalgorithm=self.algorithm)
update.delete(self.module.params['record'], self.module.params['type'])

if self.module.params['type'].upper() == 'NS':
# When modifying a NS record, track records that are no longer required and only remove them
# after adding the new entries.
# Bind9 silently refuses to delete all the NS entries for a zone:
# 09-May-2022 18:00:50.352 client @0x7fe7dd1f9568 192.168.1.3#45458/key rndc_ddns_ansible: updating zone 'lab/IN': attempt to delete all SOA or NS records ignored
# https://gitlab.isc.org/isc-projects/bind9/-/blob/v9_18/lib/ns/update.c#L3304
query = dns.message.make_query(self.module.params['record'], self.module.params['type'])
if self.keyring:
query.use_tsig(keyring=self.keyring, algorithm=self.algorithm)

try:
if self.module.params['protocol'] == 'tcp':
lookup = dns.query.tcp(query, self.module.params['server'], timeout=10, port=self.module.params['port'])
else:
lookup = dns.query.udp(query, self.module.params['server'], timeout=10, port=self.module.params['port'])
except (dns.tsig.PeerBadKey, dns.tsig.PeerBadSignature) as e:
self.module.fail_json(msg='TSIG update error (%s): %s' % (e.__class__.__name__, to_native(e)))
except (socket_error, dns.exception.Timeout) as e:
self.module.fail_json(msg='DNS server error: (%s): %s' % (e.__class__.__name__, to_native(e)))

entries_to_remove = [ n.to_text() for n in lookup.answer[0].items if n.to_text() not in self.value]
else:
update.delete(self.module.params['record'], self.module.params['type'])

for entry in self.value:
try:
update.add(self.module.params['record'],
Expand All @@ -349,6 +373,11 @@ def modify_record(self):
self.module.fail_json(msg='value needed when state=present')
except dns.exception.SyntaxError:
self.module.fail_json(msg='Invalid/malformed value')

if self.module.params['type'].upper() == 'NS':
for entry in entries_to_remove:
update.delete(self.module.params['record'], self.module.params['type'], entry)

response = self.__do_update(update)

return dns.message.Message.rcode(response)
Expand Down

0 comments on commit ceb8131

Please sign in to comment.