Example #1
0
def core(module):
    snapshot_type = module.params['snapshot_type']

    rest = DigitalOceanHelper(module)

    base_url = 'snapshots?'
    snapshot = []

    if snapshot_type == 'by_id':
        base_url += "/{0}".format(module.params.get('snapshot_id'))
        response = rest.get(base_url)
        status_code = response.status_code

        if status_code != 200:
            module.fail_json(msg="Failed to fetch snapshot information due to error : %s" % response.json['message'])

        snapshot.extend(response.json["snapshot"])
    else:
        if snapshot_type == 'droplet':
            base_url += "resource_type=droplet&"
        elif snapshot_type == 'volume':
            base_url += "resource_type=volume&"

        snapshot = rest.get_paginated_data(base_url=base_url, data_key_name='snapshots')
    module.exit_json(changed=False, data=snapshot)
Example #2
0
def core(module):
    domain_name = module.params.get('domain_name', None)
    rest = DigitalOceanHelper(module)
    domain_results = []

    if domain_name is not None:
        response = rest.get("domains/%s" % domain_name)
        status_code = response.status_code

        if status_code != 200:
            module.fail_json(msg="Failed to retrieve domain for DigitalOcean")

        resp_json = response.json
        domains = [resp_json['domain']]
    else:
        domains = rest.get_paginated_data(base_url="domains?", data_key_name='domains')

    for temp_domain in domains:
        temp_domain_dict = {
            "name": temp_domain['name'],
            "ttl": temp_domain['ttl'],
            "zone_file": temp_domain['zone_file'],
            "domain_records": list(),
        }

        base_url = "domains/%s/records?" % temp_domain['name']

        temp_domain_dict["domain_records"] = rest.get_paginated_data(base_url=base_url, data_key_name='domain_records')
        domain_results.append(temp_domain_dict)

    module.exit_json(changed=False, data=domain_results)
 def __init__(self, module):
     self.rest = DigitalOceanHelper(module)
     self.module = module
     self.wait = self.module.params.pop('wait', True)
     self.wait_timeout = self.module.params.pop('wait_timeout', 120)
     self.unique_name = self.module.params.pop('unique_name', False)
     # pop the oauth token so we don't include it in the POST data
     self.module.params.pop('oauth_token')
Example #4
0
def core(module):
    rest = DigitalOceanHelper(module)

    response = rest.get("account")
    if response.status_code != 200:
        module.fail_json(msg="Failed to fetch 'account' information due to error : %s" % response.json['message'])

    module.exit_json(changed=False, data=response.json["account"])
Example #5
0
def core(module):
    state = module.params['state']
    name = module.params['name']

    rest = DigitalOceanHelper(module)

    results = dict(changed=False)

    response = rest.get('certificates')
    status_code = response.status_code
    resp_json = response.json

    if status_code != 200:
        module.fail_json(msg="Failed to retrieve certificates for DigitalOcean")

    if state == 'present':
        for cert in resp_json['certificates']:
            if cert['name'] == name:
                module.fail_json(msg="Certificate name %s already exists" % name)

        # Certificate does not exist, let us create it
        cert_data = dict(name=name,
                         private_key=module.params['private_key'],
                         leaf_certificate=module.params['leaf_certificate'])

        if module.params['certificate_chain'] is not None:
            cert_data.update(certificate_chain=module.params['certificate_chain'])

        response = rest.post("certificates", data=cert_data)
        status_code = response.status_code
        if status_code == 500:
            module.fail_json(msg="Failed to upload certificates as the certificates are malformed.")

        resp_json = response.json
        if status_code == 201:
            results.update(changed=True, response=resp_json)
        elif status_code == 422:
            results.update(changed=False, response=resp_json)

    elif state == 'absent':
        cert_id_del = None
        for cert in resp_json['certificates']:
            if cert['name'] == name:
                cert_id_del = cert['id']

        if cert_id_del is not None:
            url = "certificates/{0}".format(cert_id_del)
            response = rest.delete(url)
            if response.status_code == 204:
                results.update(changed=True)
            else:
                results.update(changed=False)
        else:
            module.fail_json(msg="Failed to find certificate %s" % name)

    module.exit_json(**results)
Example #6
0
def core(module):
    rest = DigitalOceanHelper(module)

    response = rest.get("account/keys")
    status_code = response.status_code
    json = response.json
    if status_code == 200:
        module.exit_json(changed=False, data=json['ssh_keys'])
    else:
        module.fail_json(msg='Error fetching SSH Key information [{0}: {1}]'.format(
            status_code, response.json['message']))
def core(module):
    rest = DigitalOceanHelper(module)

    response = rest.get("account/keys")
    status_code = response.status_code
    json = response.json
    if status_code == 200:
        module.exit_json(changed=False, ansible_facts=json)
    else:
        module.fail_json(msg='Error fetching facts [{0}: {1}]'.format(
            status_code, response.json['message']))
def core(module):
    region_name = module.params.get('region_name', None)

    rest = DigitalOceanHelper(module)

    base_url = 'volumes?'
    if region_name is not None:
        base_url += "region=%s&" % region_name

    volumes = rest.get_paginated_data(base_url=base_url,
                                      data_key_name='volumes')

    module.exit_json(changed=False, data=volumes)
def core(module):
    image_type = module.params['image_type']

    rest = DigitalOceanHelper(module)

    base_url = 'images?'
    if image_type == 'distribution':
        base_url += "type=distribution&"
    elif image_type == 'application':
        base_url += "type=application&"
    elif image_type == 'private':
        base_url += "private=true&"

    images = rest.get_paginated_data(base_url=base_url, data_key_name='images')

    module.exit_json(changed=False, data=images)
Example #10
0
def main():
    module = AnsibleModule(
        argument_spec=DigitalOceanHelper.digital_ocean_argument_spec(),
        supports_check_mode=True,
    )

    core(module)
Example #11
0
def main():
    argument_spec = DigitalOceanHelper.digital_ocean_argument_spec()
    module = AnsibleModule(argument_spec=argument_spec)
    if module._name == 'digital_ocean_account_facts':
        module.deprecate("The 'digital_ocean_account_facts' module has been renamed to 'digital_ocean_account_info'", version='2.13')
    try:
        core(module)
    except Exception as e:
        module.fail_json(msg=to_native(e), exception=format_exc())
Example #12
0
def core(module):
    tag_name = module.params.get('tag_name', None)
    rest = DigitalOceanHelper(module)

    base_url = 'tags?'
    if tag_name is not None:
        response = rest.get("%s/%s" % (base_url, tag_name))
        status_code = response.status_code

        if status_code != 200:
            module.fail_json(msg="Failed to retrieve tags for DigitalOcean")

        resp_json = response.json
        tag = resp_json['tag']
    else:
        tag = rest.get_paginated_data(base_url=base_url, data_key_name='tags')

    module.exit_json(changed=False, data=tag)
Example #13
0
def core(module):
    firewall_name = module.params.get('name', None)
    rest = DigitalOceanHelper(module)
    base_url = 'firewalls?'

    response = rest.get("%s" % base_url)
    status_code = response.status_code
    if status_code != 200:
        module.fail_json(msg="Failed to retrieve firewalls from Digital Ocean")
    firewalls = rest.get_paginated_data(base_url=base_url,
                                        data_key_name='firewalls')

    if firewall_name is not None:
        rule = {}
        for firewall in firewalls:
            if firewall['name'] == firewall_name:
                rule.update(firewall)
        module.exit_json(changed=False, data=rule)
    else:
        module.exit_json(changed=False, data=firewalls)
Example #14
0
def core(module):
    certificate_id = module.params.get('certificate_id', None)
    rest = DigitalOceanHelper(module)

    base_url = 'certificates?'
    if certificate_id is not None:
        response = rest.get("%s/%s" % (base_url, certificate_id))
        status_code = response.status_code

        if status_code != 200:
            module.fail_json(
                msg="Failed to retrieve certificates for DigitalOcean")

        resp_json = response.json
        certificate = resp_json['certificate']
    else:
        certificate = rest.get_paginated_data(base_url=base_url,
                                              data_key_name='certificates')

    module.exit_json(changed=False, data=certificate)
def main():
    module = AnsibleModule(
        argument_spec=DigitalOceanHelper.digital_ocean_argument_spec(),
        supports_check_mode=False,
    )

    module.deprecate(
        "The 'digital_ocean_sshkey_facts' module has been deprecated, use the new 'digital_ocean_sshkey_info' module",
        version='2.13')

    core(module)
def main():
    argument_spec = DigitalOceanHelper.digital_ocean_argument_spec()
    argument_spec.update(region_name=dict(type='str', required=False), )
    module = AnsibleModule(argument_spec=argument_spec)
    if module._name == 'digital_ocean_volume_facts':
        module.deprecate(
            "The 'digital_ocean_volume_facts' module has been renamed to 'digital_ocean_volume_info'",
            version='2.13')

    try:
        core(module)
    except Exception as e:
        module.fail_json(msg=to_native(e), exception=format_exc())
def core(module):
    rest = DigitalOceanHelper(module)

    page = 1
    has_next = True
    floating_ips = []
    status_code = None
    while has_next or status_code != 200:
        response = rest.get("floating_ips?page={0}&per_page=20".format(page))
        status_code = response.status_code
        # stop if any error during pagination
        if status_code != 200:
            break
        page += 1
        floating_ips.extend(response.json["floating_ips"])
        has_next = "pages" in response.json["links"] and "next" in response.json["links"]["pages"]

    if status_code == 200:
        module.exit_json(changed=False, floating_ips=floating_ips)
    else:
        module.fail_json(msg="Error fetching information [{0}: {1}]".format(
            status_code, response.json["message"]))
Example #18
0
def main():
    argument_spec = DigitalOceanHelper.digital_ocean_argument_spec()
    argument_spec.update(
        name=dict(type='str', required=True),
        resource_id=dict(aliases=['droplet_id'], type='str'),
        resource_type=dict(choices=['droplet'], default='droplet'),
        state=dict(choices=['present', 'absent'], default='present'),
    )

    module = AnsibleModule(argument_spec=argument_spec)

    try:
        core(module)
    except Exception as e:
        module.fail_json(msg=to_native(e), exception=format_exc())
def main():
    argument_spec = DigitalOceanHelper.digital_ocean_argument_spec()
    argument_spec.update(image_type=dict(
        type='str',
        required=False,
        choices=['all', 'application', 'distribution', 'private'],
        default='all'))

    module = AnsibleModule(argument_spec=argument_spec)
    if module._name == 'digital_ocean_image_facts':
        module.deprecate(
            "The 'digital_ocean_image_facts' module has been renamed to 'digital_ocean_image_info'",
            version='2.13')

    try:
        core(module)
    except Exception as e:
        module.fail_json(msg=to_native(e), exception=format_exc())
Example #20
0
def main():
    argument_spec = DigitalOceanHelper.digital_ocean_argument_spec()
    argument_spec.update(
        state=dict(choices=['present', 'absent'], default='present'),
        name=dict(type='str'),
        id=dict(aliases=['droplet_id'], type='int'),
        ip=dict(type='str')
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        required_one_of=(
            ['id', 'name'],
        ),
    )

    try:
        core(module)
    except Exception as e:
        module.fail_json(msg=to_native(e), exception=traceback.format_exc())
Example #21
0
def main():
    argument_spec = DigitalOceanHelper.digital_ocean_argument_spec()
    argument_spec.update(
        name=dict(type='str'),
        leaf_certificate=dict(type='str'),
        private_key=dict(type='str', no_log=True),
        state=dict(choices=['present', 'absent'], default='present'),
        certificate_chain=dict(type='str')
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        required_if=[('state', 'present', ['name', 'leaf_certificate', 'private_key']),
                     ('state', 'absent', ['name'])
                     ],
    )

    try:
        core(module)
    except Exception as e:
        module.fail_json(msg=to_native(e))
Example #22
0
def main():
    argument_spec = DigitalOceanHelper.digital_ocean_argument_spec()
    argument_spec.update(state=dict(choices=['present', 'absent'],
                                    required=True),
                         command=dict(choices=['create', 'attach'],
                                      required=True),
                         block_size=dict(type='int', required=False),
                         volume_name=dict(type='str', required=True),
                         description=dict(type='str'),
                         region=dict(type='str', required=False),
                         snapshot_id=dict(type='str', required=False),
                         droplet_id=dict(type='int'))

    module = AnsibleModule(argument_spec=argument_spec)

    try:
        handle_request(module)
    except DOBlockStorageException as e:
        module.fail_json(msg=e.message, exception=traceback.format_exc())
    except KeyError as e:
        module.fail_json(msg='Unable to load %s' % e.message,
                         exception=traceback.format_exc())
Example #23
0
def main():
    argument_spec = DigitalOceanHelper.digital_ocean_argument_spec()
    argument_spec.update(
        snapshot_type=dict(type='str',
                           required=False,
                           choices=['all', 'droplet', 'volume', 'by_id'],
                           default='all'),
        snapshot_id=dict(type='str',
                         required=False),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        required_if=[
            ['snapshot_type', 'by_id', ['snapshot_id']],
        ],
    )
    if module._name == 'digital_ocean_snapshot_facts':
        module.deprecate("The 'digital_ocean_snapshot_facts' module has been renamed to 'digital_ocean_snapshot_info'", version='2.13')

    try:
        core(module)
    except Exception as e:
        module.fail_json(msg=to_native(e), exception=format_exc())
Example #24
0
def core(module):
    state = module.params['state']
    name = module.params['name']
    resource_id = module.params['resource_id']
    resource_type = module.params['resource_type']

    rest = DigitalOceanHelper(module)

    if state == 'present':
        response = rest.get('tags/{0}'.format(name))
        status_code = response.status_code
        resp_json = response.json
        changed = False
        if status_code == 200 and resp_json['tag']['name'] == name:
            changed = False
        else:
            # Ensure Tag exists
            response = rest.post("tags", data={'name': name})
            status_code = response.status_code
            resp_json = response.json
            if status_code == 201:
                changed = True
            elif status_code == 422:
                changed = False
            else:
                module.exit_json(changed=False, data=resp_json)

        if resource_id is None:
            # No resource defined, we're done.
            module.exit_json(changed=changed, data=resp_json)
        else:
            # Check if resource is already tagged or not
            found = False
            url = "{0}?tag_name={1}".format(resource_type, name)
            if resource_type == 'droplet':
                url = "droplets?tag_name={0}".format(name)
            response = rest.get(url)
            status_code = response.status_code
            resp_json = response.json
            if status_code == 200:
                for resource in resp_json['droplets']:
                    if not found and resource['id'] == int(resource_id):
                        found = True
                        break
                if not found:
                    # If resource is not tagged, tag a resource
                    url = "tags/{0}/resources".format(name)
                    payload = {
                        'resources': [{
                            'resource_id': resource_id,
                            'resource_type': resource_type}]}
                    response = rest.post(url, data=payload)
                    if response.status_code == 204:
                        module.exit_json(changed=True)
                    else:
                        module.fail_json(msg="error tagging resource '{0}': {1}".format(resource_id, response.json["message"]))
                else:
                    # Already tagged resource
                    module.exit_json(changed=False)
            else:
                # Unable to find resource specified by user
                module.fail_json(msg=resp_json['message'])

    elif state == 'absent':
        if resource_id:
            url = "tags/{0}/resources".format(name)
            payload = {
                'resources': [{
                    'resource_id': resource_id,
                    'resource_type': resource_type}]}
            response = rest.delete(url, data=payload)
        else:
            url = "tags/{0}".format(name)
            response = rest.delete(url)
        if response.status_code == 204:
            module.exit_json(changed=True)
        else:
            module.exit_json(changed=False, data=response.json)
class DODroplet(object):
    def __init__(self, module):
        self.rest = DigitalOceanHelper(module)
        self.module = module
        self.wait = self.module.params.pop('wait', True)
        self.wait_timeout = self.module.params.pop('wait_timeout', 120)
        self.unique_name = self.module.params.pop('unique_name', False)
        # pop the oauth token so we don't include it in the POST data
        self.module.params.pop('oauth_token')

    def get_by_id(self, droplet_id):
        if not droplet_id:
            return None
        response = self.rest.get('droplets/{0}'.format(droplet_id))
        json_data = response.json
        if response.status_code == 200:
            return json_data
        return None

    def get_by_name(self, droplet_name):
        if not droplet_name:
            return None
        page = 1
        while page is not None:
            response = self.rest.get('droplets?page={0}'.format(page))
            json_data = response.json
            if response.status_code == 200:
                for droplet in json_data['droplets']:
                    if droplet['name'] == droplet_name:
                        return {'droplet': droplet}
                if 'links' in json_data and 'pages' in json_data[
                        'links'] and 'next' in json_data['links']['pages']:
                    page += 1
                else:
                    page = None
        return None

    def get_addresses(self, data):
        """
         Expose IP addresses as their own property allowing users extend to additional tasks
        """
        _data = data
        for k, v in data.items():
            setattr(self, k, v)
        networks = _data['droplet']['networks']
        for network in networks.get('v4', []):
            if network['type'] == 'public':
                _data['ip_address'] = network['ip_address']
            else:
                _data['private_ipv4_address'] = network['ip_address']
        for network in networks.get('v6', []):
            if network['type'] == 'public':
                _data['ipv6_address'] = network['ip_address']
            else:
                _data['private_ipv6_address'] = network['ip_address']
        return _data

    def get_droplet(self):
        json_data = self.get_by_id(self.module.params['id'])
        if not json_data and self.unique_name:
            json_data = self.get_by_name(self.module.params['name'])
        return json_data

    def create(self):
        json_data = self.get_droplet()
        droplet_data = None
        if json_data:
            droplet_data = self.get_addresses(json_data)
            self.module.exit_json(changed=False, data=droplet_data)
        if self.module.check_mode:
            self.module.exit_json(changed=True)
        request_params = dict(self.module.params)
        del request_params['id']
        response = self.rest.post('droplets', data=request_params)
        json_data = response.json
        if response.status_code >= 400:
            self.module.fail_json(changed=False, msg=json_data['message'])
        if self.wait:
            json_data = self.ensure_power_on(json_data['droplet']['id'])
            droplet_data = self.get_addresses(json_data)
        self.module.exit_json(changed=True, data=droplet_data)

    def delete(self):
        json_data = self.get_droplet()
        if json_data:
            if self.module.check_mode:
                self.module.exit_json(changed=True)
            response = self.rest.delete('droplets/{0}'.format(
                json_data['droplet']['id']))
            json_data = response.json
            if response.status_code == 204:
                self.module.exit_json(changed=True, msg='Droplet deleted')
            self.module.fail_json(changed=False,
                                  msg='Failed to delete droplet')
        else:
            self.module.exit_json(changed=False, msg='Droplet not found')

    def ensure_power_on(self, droplet_id):
        end_time = time.time() + self.wait_timeout
        while time.time() < end_time:
            response = self.rest.get('droplets/{0}'.format(droplet_id))
            json_data = response.json
            if json_data['droplet']['status'] == 'active':
                return json_data
            time.sleep(min(2, end_time - time.time()))
        self.module.fail_json(msg='Wait for droplet powering on timeout')
Example #26
0
 def __init__(self, module):
     self.module = module
     self.rest = DigitalOceanHelper(module)
Example #27
0
class DOBlockStorage(object):
    def __init__(self, module):
        self.module = module
        self.rest = DigitalOceanHelper(module)

    def get_key_or_fail(self, k):
        v = self.module.params[k]
        if v is None:
            self.module.fail_json(msg='Unable to load %s' % k)
        return v

    def poll_action_for_complete_status(self, action_id):
        url = 'actions/{0}'.format(action_id)
        end_time = time.time() + self.module.params['timeout']
        while time.time() < end_time:
            time.sleep(2)
            response = self.rest.get(url)
            status = response.status_code
            json = response.json
            if status == 200:
                if json['action']['status'] == 'completed':
                    return True
                elif json['action']['status'] == 'errored':
                    raise DOBlockStorageException(json['message'])
        raise DOBlockStorageException('Unable to reach api.digitalocean.com')

    def get_attached_droplet_ID(self, volume_name, region):
        url = 'volumes?name={0}&region={1}'.format(volume_name, region)
        response = self.rest.get(url)
        status = response.status_code
        json = response.json
        if status == 200:
            volumes = json['volumes']
            if len(volumes) > 0:
                droplet_ids = volumes[0]['droplet_ids']
                if len(droplet_ids) > 0:
                    return droplet_ids[0]
            return None
        else:
            raise DOBlockStorageException(json['message'])

    def attach_detach_block_storage(self, method, volume_name, region,
                                    droplet_id):
        data = {
            'type': method,
            'volume_name': volume_name,
            'region': region,
            'droplet_id': droplet_id
        }
        response = self.rest.post('volumes/actions', data=data)
        status = response.status_code
        json = response.json
        if status == 202:
            return self.poll_action_for_complete_status(json['action']['id'])
        elif status == 200:
            return True
        elif status == 422:
            return False
        else:
            raise DOBlockStorageException(json['message'])

    def create_block_storage(self):
        volume_name = self.get_key_or_fail('volume_name')
        snapshot_id = self.module.params['snapshot_id']
        if snapshot_id:
            self.module.params['block_size'] = None
            self.module.params['region'] = None
            block_size = None
            region = None
        else:
            block_size = self.get_key_or_fail('block_size')
            region = self.get_key_or_fail('region')
        description = self.module.params['description']
        data = {
            'size_gigabytes': block_size,
            'name': volume_name,
            'description': description,
            'region': region,
            'snapshot_id': snapshot_id,
        }
        response = self.rest.post("volumes", data=data)
        status = response.status_code
        json = response.json
        if status == 201:
            self.module.exit_json(changed=True, id=json['volume']['id'])
        elif status == 409 and json['id'] == 'conflict':
            self.module.exit_json(changed=False)
        else:
            raise DOBlockStorageException(json['message'])

    def delete_block_storage(self):
        volume_name = self.get_key_or_fail('volume_name')
        region = self.get_key_or_fail('region')
        url = 'volumes?name={0}&region={1}'.format(volume_name, region)
        attached_droplet_id = self.get_attached_droplet_ID(volume_name, region)
        if attached_droplet_id is not None:
            self.attach_detach_block_storage('detach', volume_name, region,
                                             attached_droplet_id)
        response = self.rest.delete(url)
        status = response.status_code
        json = response.json
        if status == 204:
            self.module.exit_json(changed=True)
        elif status == 404:
            self.module.exit_json(changed=False)
        else:
            raise DOBlockStorageException(json['message'])

    def attach_block_storage(self):
        volume_name = self.get_key_or_fail('volume_name')
        region = self.get_key_or_fail('region')
        droplet_id = self.get_key_or_fail('droplet_id')
        attached_droplet_id = self.get_attached_droplet_ID(volume_name, region)
        if attached_droplet_id is not None:
            if attached_droplet_id == droplet_id:
                self.module.exit_json(changed=False)
            else:
                self.attach_detach_block_storage('detach', volume_name, region,
                                                 attached_droplet_id)
        changed_status = self.attach_detach_block_storage(
            'attach', volume_name, region, droplet_id)
        self.module.exit_json(changed=changed_status)

    def detach_block_storage(self):
        volume_name = self.get_key_or_fail('volume_name')
        region = self.get_key_or_fail('region')
        droplet_id = self.get_key_or_fail('droplet_id')
        changed_status = self.attach_detach_block_storage(
            'detach', volume_name, region, droplet_id)
        self.module.exit_json(changed=changed_status)