#!/usr/bin/python # -*- coding: UTF-8 -*- # Copyright (c) 2016, Adfinis SyGroup AG # Tobias Rueetschi # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . # from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.univention_umc import ( umc_module_for_add, umc_module_for_edit, ldap_search, base_dn, ) DOCUMENTATION = ''' --- module: udm_dns_zone version_added: "2.2" author: "Tobias Rueetschi (@2-B)" short_description: Manage dns zones on a univention corporate server description: - "This module allows to manage dns zones on a univention corporate server (UCS). It uses the python API of the UCS to create a new object or edit it." requirements: - Python >= 2.6 options: state: required: false default: "present" choices: [ present, absent ] description: - Whether the dns zone is present or not. type: required: true choices: [ forward_zone, reverse_zone ] description: - Define if the zone is a forward or reverse DNS zone. zone: required: true description: - DNS zone name, e.g. C(example.com). nameserver: required: false description: - List of appropriate name servers. Required if C(state=present). interfaces: required: false description: - List of interface IP addresses, on which the server should response this zone. Required if C(state=present). refresh: required: false default: 3600 description: - Interval before the zone should be refreshed. retry: required: false default: 1800 description: - Interval that should elapse before a failed refresh should be retried. expire: required: false default: 604800 description: - Specifies the upper limit on the time interval that can elapse before the zone is no longer authoritative. ttl: required: false default: 600 description: - Minimum TTL field that should be exported with any RR from this zone. contact: required: false default: '' description: - Contact person in the SOA record. mx: required: false default: [] description: - List of MX servers. (Must declared as A or AAAA records). ''' EXAMPLES = ''' # Create a DNS zone on a UCS - udm_dns_zone: zone=example.com type=forward_zone nameserver=['ucs.example.com'] interfaces=['192.0.2.1'] ''' RETURN = '''# ''' def convert_time(time): """Convert a time in seconds into the biggest unit""" units = [ (24 * 60 * 60 , 'days'), (60 * 60 , 'hours'), (60 , 'minutes'), (1 , 'seconds'), ] if time == 0: return ('0', 'seconds') for unit in units: if time >= unit[0]: return ('{}'.format(time // unit[0]), unit[1]) def main(): module = AnsibleModule( argument_spec = dict( type = dict(required=True, type='str'), zone = dict(required=True, aliases=['name'], type='str'), nameserver = dict(default=[], type='list'), interfaces = dict(default=[], type='list'), refresh = dict(default=3600, type='int'), retry = dict(default=1800, type='int'), expire = dict(default=604800, type='int'), ttl = dict(default=600, type='int'), contact = dict(default='', type='str'), mx = dict(default=[], type='list'), state = dict(default='present', choices=['present', 'absent'], type='str') ), supports_check_mode=True, required_if = ([ ('state', 'present', ['nameserver', 'interfaces']) ]) ) type = module.params['type'] zone = module.params['zone'] nameserver = module.params['nameserver'] interfaces = module.params['interfaces'] refresh = module.params['refresh'] retry = module.params['retry'] expire = module.params['expire'] ttl = module.params['ttl'] contact = module.params['contact'] mx = module.params['mx'] state = module.params['state'] changed = False obj = list(ldap_search( '(&(objectClass=dNSZone)(zoneName={}))'.format(zone), attr=['dNSZone'] )) exists = bool(len(obj)) container = 'cn=dns,{}'.format(base_dn()) dn = 'zoneName={},{}'.format(zone, container) if contact == '': contact = 'root@{}.'.format(zone) if state == 'present': try: if not exists: obj = umc_module_for_add('dns/{}'.format(type), container) else: obj = umc_module_for_edit('dns/{}'.format(type), dn) obj['zone'] = zone obj['nameserver'] = nameserver obj['a'] = interfaces obj['refresh'] = convert_time(refresh) obj['retry'] = convert_time(retry) obj['expire'] = convert_time(expire) obj['ttl'] = convert_time(ttl) obj['contact'] = contact obj['mx'] = mx diff = obj.diff() if exists: for k in obj.keys(): if obj.hasChanged(k): changed = True else: changed = True if not module.check_mode: if not exists: obj.create() elif changed: obj.modify() except Exception as e: module.fail_json( msg='Creating/editing dns zone {} failed: {}'.format(zone, e) ) if state == 'absent' and exists: try: obj = umc_module_for_edit('dns/{}'.format(type), dn) if not module.check_mode: obj.remove() changed = True except Exception as e: module.fail_json( msg='Removing dns zone {} failed: {}'.format(zone, e) ) module.exit_json( changed=changed, diff=diff, zone=zone ) if __name__ == '__main__': main()