#!/usr/bin/python # 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 . # This is a DOCUMENTATION stub specific to this module, it extends # a documentation fragment located in ansible.utils.module_docs_fragments DOCUMENTATION = ''' --- module: rax_dns_record short_description: Manage DNS records on Rackspace Cloud DNS description: - Manage DNS records on Rackspace Cloud DNS version_added: 1.5 options: comment: description: - Brief description of the domain. Maximum length of 160 characters data: description: - IP address for A/AAAA record, FQDN for CNAME/MX/NS, or text data for SRV/TXT required: True domain: description: - Domain name to create the record in required: True name: description: - FQDN record name to create required: True priority: description: - Required for MX and SRV records, but forbidden for other record types. If specified, must be an integer from 0 to 65535. state: description: - Indicate desired state of the resource choices: - present - absent default: present ttl: description: - Time to live of domain in seconds default: 3600 type: description: - DNS record type choices: - A - AAAA - CNAME - MX - NS - SRV - TXT default: A author: Matt Martz extends_documentation_fragment: rackspace ''' EXAMPLES = ''' - name: Create record hosts: all gather_facts: False tasks: - name: Record create request local_action: module: rax_dns_record credentials: ~/.raxpub domain: example.org name: www.example.org data: 127.0.0.1 type: A register: rax_dns_record ''' from types import NoneType try: import pyrax HAS_PYRAX = True except ImportError: HAS_PYRAX = False NON_CALLABLES = (basestring, bool, dict, int, list, NoneType) def to_dict(obj): instance = {} for key in dir(obj): value = getattr(obj, key) if (isinstance(value, NON_CALLABLES) and not key.startswith('_')): instance[key] = value return instance def rax_dns_record(module, comment, data, domain, name, priority, record_type, state, ttl): changed = False dns = pyrax.cloud_dns if not dns: module.fail_json(msg='Failed to instantiate client. This ' 'typically indicates an invalid region or an ' 'incorrectly capitalized region name.') if state == 'present': if not priority and record_type in ['MX', 'SRV']: module.fail_json(msg='A "priority" attribute is required for ' 'creating a MX or SRV record') try: domain = dns.find(name=domain) except Exception, e: module.fail_json(msg='%s' % e.message) try: record = domain.find_record(record_type, name=name) except pyrax.exceptions.DomainRecordNotUnique, e: module.fail_json(msg='%s' % e.message) except pyrax.exceptions.DomainRecordNotFound, e: try: record_data = { 'type': record_type, 'name': name, 'data': data, 'ttl': ttl } if comment: record_data.update(dict(comment=comment)) if priority: record_data.update(dict(priority=priority)) record = domain.add_records([record_data])[0] changed = True except Exception, e: module.fail_json(msg='%s' % e.message) update = {} if comment != getattr(record, 'comment', None): update['comment'] = comment if ttl != getattr(record, 'ttl', None): update['ttl'] = ttl if priority != getattr(record, 'priority', None): update['priority'] = priority if data != getattr(record, 'data', None): update['data'] = data if update: try: record.update(**update) changed = True record.get() except Exception, e: module.fail_json(msg='%s' % e.message) elif state == 'absent': try: domain = dns.find(name=domain) except Exception, e: module.fail_json(msg='%s' % e.message) try: record = domain.find_record(record_type, name=name, data=data) except pyrax.exceptions.DomainRecordNotFound, e: record = {} pass except pyrax.exceptions.DomainRecordNotUnique, e: module.fail_json(msg='%s' % e.message) if record: try: record.delete() changed = True except Exception, e: module.fail_json(msg='%s' % e.message) module.exit_json(changed=changed, record=to_dict(record)) def main(): argument_spec = rax_argument_spec() argument_spec.update( dict( comment=dict(), data=dict(required=True), domain=dict(required=True), name=dict(required=True), priority=dict(type='int'), state=dict(default='present', choices=['present', 'absent']), ttl=dict(type='int', default=3600), type=dict(default='A', choices=['A', 'AAAA', 'CNAME', 'MX', 'NS', 'SRV', 'TXT']) ) ) module = AnsibleModule( argument_spec=argument_spec, required_together=rax_required_together(), ) if not HAS_PYRAX: module.fail_json(msg='pyrax is required for this module') comment = module.params.get('comment') data = module.params.get('data') domain = module.params.get('domain') name = module.params.get('name') priority = module.params.get('priority') state = module.params.get('state') ttl = module.params.get('ttl') record_type = module.params.get('type') setup_rax_module(module, pyrax) rax_dns_record(module, comment, data, domain, name, priority, record_type, state, ttl) # import module snippets from ansible.module_utils.basic import * from ansible.module_utils.rax import * ### invoke the module main()