1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

udm_dns_record: Fix handling of PTR records (#3244) (#3256)

* udm_dns_record: Fix handling of PTR records (#3244)

Before, it was not possible to manage PTR records in Univention DNS,
due to broken zone lookups and improper used parameters of the object.
This patch fixes the PTR handling, allowing both v4 and v6 entries.

* udm_dns_record: [doc] add changelog fragment

* udm_dns_record: [fix] validation errors

* udm_dns_record: import ipaddress module conditionally (#3244)

* udm_dns_record: fix sanity check error, improve doc (#3244)

* udm_dns_record: Improve changes to meet community standards (#3244)
This commit is contained in:
Sebastian Damm 2021-08-30 06:53:30 +02:00 committed by GitHub
parent 1ce79db763
commit d9dcdcbbe4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 5 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- udm_dns_record - fixed managing of PTR records, which can never have worked before (https://github.com/ansible-collections/community.general/pull/3256).

View file

@ -21,6 +21,7 @@ description:
requirements: requirements:
- Python >= 2.6 - Python >= 2.6
- Univention - Univention
- ipaddress (for I(type=ptr_record))
options: options:
state: state:
type: str type: str
@ -34,11 +35,13 @@ options:
description: description:
- "Name of the record, this is also the DNS record. E.g. www for - "Name of the record, this is also the DNS record. E.g. www for
www.example.com." www.example.com."
- For PTR records this has to be the IP address.
zone: zone:
type: str type: str
required: true required: true
description: description:
- Corresponding DNS zone for this record, e.g. example.com. - Corresponding DNS zone for this record, e.g. example.com.
- For PTR records this has to be the full reverse zone (for example C(1.1.192.in-addr.arpa)).
type: type:
type: str type: str
required: true required: true
@ -66,12 +69,29 @@ EXAMPLES = '''
a: a:
- 192.0.2.1 - 192.0.2.1
- 2001:0db8::42 - 2001:0db8::42
- name: Create a DNS v4 PTR record on a UCS
community.general.udm_dns_record:
name: 192.0.2.1
zone: 2.0.192.in-addr.arpa
type: ptr_record
data:
ptr_record: "www.example.com."
- name: Create a DNS v6 PTR record on a UCS
community.general.udm_dns_record:
name: 2001:db8:0:0:0:ff00:42:8329
zone: 2.4.0.0.0.0.f.f.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa
type: ptr_record
data:
ptr_record: "www.example.com."
''' '''
RETURN = '''#''' RETURN = '''#'''
HAVE_UNIVENTION = False HAVE_UNIVENTION = False
HAVE_IPADDRESS = False
try: try:
from univention.admin.handlers.dns import ( from univention.admin.handlers.dns import (
forward_zone, forward_zone,
@ -82,6 +102,7 @@ except ImportError:
pass pass
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import missing_required_lib
from ansible_collections.community.general.plugins.module_utils.univention_umc import ( from ansible_collections.community.general.plugins.module_utils.univention_umc import (
umc_module_for_add, umc_module_for_add,
umc_module_for_edit, umc_module_for_edit,
@ -90,6 +111,11 @@ from ansible_collections.community.general.plugins.module_utils.univention_umc i
config, config,
uldap, uldap,
) )
try:
import ipaddress
HAVE_IPADDRESS = True
except ImportError:
pass
def main(): def main():
@ -124,14 +150,30 @@ def main():
changed = False changed = False
diff = None diff = None
workname = name
if type == 'ptr_record':
if not HAVE_IPADDRESS:
module.fail_json(msg=missing_required_lib('ipaddress'))
try:
if 'arpa' not in zone:
raise Exception("Zone must be reversed zone for ptr_record. (e.g. 1.1.192.in-addr.arpa)")
ipaddr_rev = ipaddress.ip_address(name).reverse_pointer
subnet_offset = ipaddr_rev.find(zone)
if subnet_offset == -1:
raise Exception("reversed IP address {0} is not part of zone.".format(ipaddr_rev))
workname = ipaddr_rev[0:subnet_offset - 1]
except Exception as e:
module.fail_json(
msg='handling PTR record for {0} in zone {1} failed: {2}'.format(name, zone, e)
)
obj = list(ldap_search( obj = list(ldap_search(
'(&(objectClass=dNSZone)(zoneName={0})(relativeDomainName={1}))'.format(zone, name), '(&(objectClass=dNSZone)(zoneName={0})(relativeDomainName={1}))'.format(zone, workname),
attr=['dNSZone'] attr=['dNSZone']
)) ))
exists = bool(len(obj)) exists = bool(len(obj))
container = 'zoneName={0},cn=dns,{1}'.format(zone, base_dn()) container = 'zoneName={0},cn=dns,{1}'.format(zone, base_dn())
dn = 'relativeDomainName={0},{1}'.format(name, container) dn = 'relativeDomainName={0},{1}'.format(workname, container)
if state == 'present': if state == 'present':
try: try:
@ -144,13 +186,21 @@ def main():
) or reverse_zone.lookup( ) or reverse_zone.lookup(
config(), config(),
uldap(), uldap(),
'(zone={0})'.format(zone), '(zoneName={0})'.format(zone),
scope='domain', scope='domain',
) )
if len(so) == 0:
raise Exception("Did not find zone '{0}' in Univention".format(zone))
obj = umc_module_for_add('dns/{0}'.format(type), container, superordinate=so[0]) obj = umc_module_for_add('dns/{0}'.format(type), container, superordinate=so[0])
else: else:
obj = umc_module_for_edit('dns/{0}'.format(type), dn) obj = umc_module_for_edit('dns/{0}'.format(type), dn)
obj['name'] = name
if type == 'ptr_record':
obj['ip'] = name
obj['address'] = workname
else:
obj['name'] = name
for k, v in data.items(): for k, v in data.items():
obj[k] = v obj[k] = v
diff = obj.diff() diff = obj.diff()