rax_dns 5.18 KB
Newer Older
Matt Martz committed
1
#!/usr/bin/python
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 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 <http://www.gnu.org/licenses/>.

17 18
# This is a DOCUMENTATION stub specific to this module, it extends
# a documentation fragment located in ansible.utils.module_docs_fragments
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
DOCUMENTATION = '''
---
module: rax_dns
short_description: Manage domains on Rackspace Cloud DNS
description:
     - Manage domains on Rackspace Cloud DNS
version_added: 1.5
options:
  comment:
    description:
      - Brief description of the domain. Maximum length of 160 characters
  email:
    desctiption:
      - Email address of the domain administrator
  name:
    description:
      - Domain name to create
36 37 38
  state:
    description:
      - Indicate desired state of the resource
39 40 41
    choices:
      - present
      - absent
42
    default: present
43 44 45 46
  ttl:
    description:
      - Time to live of domain in seconds
    default: 3600
47 48 49 50
notes:
  - "It is recommended that plays utilizing this module be run with C(serial: 1)
    to avoid exceeding the API request limit imposed by the Rackspace CloudDNS
    API"
51
author: Matt Martz
52
extends_documentation_fragment: rackspace
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
'''

EXAMPLES = '''
- name: Create domain
  hosts: all
  gather_facts: False
  tasks:
    - name: Domain create request
      local_action:
        module: rax_dns
        credentials: ~/.raxpub
        name: example.org
        email: admin@example.org
      register: rax_dns
'''

from types import NoneType

try:
    import pyrax
Matt Martz committed
73
    HAS_PYRAX = True
74
except ImportError:
Matt Martz committed
75
    HAS_PYRAX = False
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

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(module, comment, email, name, state, ttl):
    changed = False

    dns = pyrax.cloud_dns
Matt Martz committed
93 94 95 96
    if not dns:
        module.fail_json(msg='Failed to instantiate client. This '
                             'typically indicates an invalid region or an '
                             'incorrectly capitalized region name.')
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166

    if state == 'present':
        if not email:
            module.fail_json(msg='An "email" attribute is required for '
                                 'creating a domain')

        try:
            domain = dns.find(name=name)
        except pyrax.exceptions.NoUniqueMatch, e:
            module.fail_json(msg='%s' % e.message)
        except pyrax.exceptions.NotFound:
            try:
                domain = dns.create(name=name, emailAddress=email, ttl=ttl,
                                    comment=comment)
                changed = True
            except Exception, e:
                module.fail_json(msg='%s' % e.message)

        update = {}
        if comment != getattr(domain, 'comment', None):
            update['comment'] = comment
        if ttl != getattr(domain, 'ttl', None):
            update['ttl'] = ttl
        if email != getattr(domain, 'emailAddress', None):
            update['emailAddress'] = email

        if update:
            try:
                domain.update(**update)
                changed = True
                domain.get()
            except Exception, e:
                module.fail_json('%s' % e.message)

    elif state == 'absent':
        try:
            domain = dns.find(name=name)
        except pyrax.exceptions.NotFound:
            domain = {}
            pass
        except Exception, e:
            module.fail_json(msg='%s' % e.message)

        if domain:
            try:
                domain.delete()
                changed = True
            except Exception, e:
                module.fail_json(msg='%s' % e.message)

    module.exit_json(changed=changed, domain=to_dict(domain))


def main():
    argument_spec = rax_argument_spec()
    argument_spec.update(
        dict(
            comment=dict(),
            email=dict(),
            name=dict(),
            state=dict(default='present', choices=['present', 'absent']),
            ttl=dict(type='int', default=3600),
        )
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        required_together=rax_required_together(),
    )

Matt Martz committed
167 168 169
    if not HAS_PYRAX:
        module.fail_json(msg='pyrax is required for this module')

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    comment = module.params.get('comment')
    email = module.params.get('email')
    name = module.params.get('name')
    state = module.params.get('state')
    ttl = module.params.get('ttl')

    setup_rax_module(module, pyrax)

    rax_dns(module, comment, email, name, state, ttl)


# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.rax import *

### invoke the module
main()