Example #1
0
def change_instance_state(module, gce, instance_names, number, zone, state):
    """Changes the state of a list of instances. For example,
    change from started to stopped, or started to absent.

    module: Ansible module object
    gce: authenticated GCE connection object
    instance_names: a list of instance names to terminate
    zone: GCEZone object where the instances reside prior to termination
    state: 'state' parameter passed into module as argument

    Returns a dictionary of instance names that were changed.

    """
    changed = False
    nodes = []
    state_instance_names = []

    if isinstance(instance_names, str) and number:
        node_names = ['%s-%03d' % (instance_names, i) for i in range(number)]
    elif isinstance(instance_names, str) and not number:
        node_names = [instance_names]
    else:
        node_names = instance_names

    for name in node_names:
        inst = None
        try:
            inst = gce.ex_get_node(name, zone)
        except ResourceNotFoundError:
            state_instance_names.append(name)
        except Exception as e:
            module.fail_json(msg=unexpected_error_msg(e), changed=False)
        else:
            nodes.append(inst)
            state_instance_names.append(name)

    if state in ['absent', 'deleted'] and number:
        changed_nodes = gce.ex_destroy_multiple_nodes(nodes) or [False]
        changed = reduce(lambda x, y: x or y, changed_nodes)
    else:
        for node in nodes:
            if state in ['absent', 'deleted']:
                gce.destroy_node(node)
                changed = True
            elif state == 'started' and node.state == libcloud.compute.types.NodeState.STOPPED:
                gce.ex_start_node(node)
                changed = True
            elif state in [
                    'stopped', 'terminated'
            ] and node.state == libcloud.compute.types.NodeState.RUNNING:
                gce.ex_stop_node(node)
                changed = True

    return (changed, state_instance_names)
Example #2
0
def change_instance_state(module, gce, instance_names, number, zone, state):
    """Changes the state of a list of instances. For example,
    change from started to stopped, or started to absent.

    module: Ansible module object
    gce: authenticated GCE connection object
    instance_names: a list of instance names to terminate
    zone: GCEZone object where the instances reside prior to termination
    state: 'state' parameter passed into module as argument

    Returns a dictionary of instance names that were changed.

    """
    changed = False
    nodes = []
    state_instance_names = []

    if isinstance(instance_names, str) and number:
        node_names = ['%s-%03d' % (instance_names, i) for i in range(number)]
    elif isinstance(instance_names, str) and not number:
        node_names = [instance_names]
    else:
        node_names = instance_names

    for name in node_names:
        inst = None
        try:
            inst = gce.ex_get_node(name, zone)
        except ResourceNotFoundError:
            state_instance_names.append(name)
        except Exception as e:
            module.fail_json(msg=unexpected_error_msg(e), changed=False)
        else:
            nodes.append(inst)
            state_instance_names.append(name)

    if state in ['absent', 'deleted'] and number:
        changed_nodes = gce.ex_destroy_multiple_nodes(nodes) or [False]
        changed = reduce(lambda x, y: x or y, changed_nodes)
    else:
        for node in nodes:
            if state in ['absent', 'deleted']:
                gce.destroy_node(node)
                changed = True
            elif state == 'started' and \
                      node.state == libcloud.compute.types.NodeState.STOPPED:
                gce.ex_start_node(node)
                changed = True
            elif state in ['stopped', 'terminated'] and \
                      node.state == libcloud.compute.types.NodeState.RUNNING:
                gce.ex_stop_node(node)
                changed = True

    return (changed, state_instance_names)
Example #3
0
def main():
    module = AnsibleModule(
        argument_spec = dict(
            allowed = dict(),
            ipv4_range = dict(),
            fwname = dict(),
            name = dict(),
            src_range = dict(default=[], type='list'),
            src_tags = dict(default=[], type='list'),
            target_tags = dict(default=[], type='list'),
            state = dict(default='present'),
            service_account_email = dict(),
            pem_file = dict(type='path'),
            credentials_file = dict(type='path'),
            project_id = dict(),
            mode = dict(default='legacy', choices=['legacy', 'auto', 'custom']),
            subnet_name = dict(),
            subnet_region = dict(),
            subnet_desc = dict(),
        )
    )

    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud with GCE support (0.17.0+) required for this module')

    gce = gce_connect(module)

    allowed = module.params.get('allowed')
    ipv4_range = module.params.get('ipv4_range')
    fwname = module.params.get('fwname')
    name = module.params.get('name')
    src_range = module.params.get('src_range')
    src_tags = module.params.get('src_tags')
    target_tags = module.params.get('target_tags')
    state = module.params.get('state')
    mode = module.params.get('mode')
    subnet_name = module.params.get('subnet_name')
    subnet_region = module.params.get('subnet_region')
    subnet_desc = module.params.get('subnet_desc')

    changed = False
    json_output = {'state': state}

    if state in ['active', 'present']:
        network = None
        subnet = None
        try:
            network = gce.ex_get_network(name)
            json_output['name'] = name
            if mode == 'legacy':
                json_output['ipv4_range'] = network.cidr
            if network and mode == 'custom' and subnet_name:
                if not hasattr(gce, 'ex_get_subnetwork'):
                    module.fail_json(msg="Update libcloud to a more recent version (>1.0) that supports network 'mode' parameter", changed=False)

                subnet = gce.ex_get_subnetwork(subnet_name, region=subnet_region)
                json_output['subnet_name'] = subnet_name
                json_output['ipv4_range'] = subnet.cidr
        except ResourceNotFoundError:
            pass
        except Exception as e:
            module.fail_json(msg=unexpected_error_msg(e), changed=False)

        # user wants to create a new network that doesn't yet exist
        if name and not network:
            if not ipv4_range and mode != 'auto':
                module.fail_json(msg="Network '" + name + "' is not found. To create network in legacy or custom mode, 'ipv4_range' parameter is required",
                    changed=False)
            args = [ipv4_range if mode =='legacy' else None]
            kwargs = {}
            if mode != 'legacy':
                kwargs['mode'] = mode

            try:
                network = gce.ex_create_network(name, *args, **kwargs)
                json_output['name'] = name
                json_output['ipv4_range'] = ipv4_range
                changed = True
            except TypeError:
                module.fail_json(msg="Update libcloud to a more recent version (>1.0) that supports network 'mode' parameter", changed=False)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

        if (subnet_name or ipv4_range) and not subnet and mode == 'custom':
            if not hasattr(gce, 'ex_create_subnetwork'):
                module.fail_json(msg='Update libcloud to a more recent version (>1.0) that supports subnetwork creation', changed=changed)
            if not subnet_name or not ipv4_range or not subnet_region:
                module.fail_json(msg="subnet_name, ipv4_range, and subnet_region required for custom mode", changed=changed)

            try:
                subnet = gce.ex_create_subnetwork(subnet_name, cidr=ipv4_range, network=name, region=subnet_region, description=subnet_desc)
                json_output['subnet_name'] = subnet_name
                json_output['ipv4_range'] = ipv4_range
                changed = True
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=changed)

        if fwname:
            # user creating a firewall rule
            if not allowed and not src_range and not src_tags:
                if changed and network:
                    module.fail_json(
                        msg="Network created, but missing required " + \
                        "firewall rule parameter(s)", changed=True)
                module.fail_json(
                    msg="Missing required firewall rule parameter(s)",
                    changed=False)

            allowed_list = format_allowed(allowed)

            # Fetch existing rule and if it exists, compare attributes
            # update if attributes changed.  Create if doesn't exist.
            try:
                fw_changed = False
                fw = gce.ex_get_firewall(fwname)

                # If old and new attributes are different, we update the firewall rule.
                # This implicitly lets us clear out attributes as well.
                # allowed_list is required and must not be None for firewall rules.
                if allowed_list and (sorted_allowed_list(allowed_list) != sorted_allowed_list(fw.allowed)):
                    fw.allowed = allowed_list
                    fw_changed = True

                # source_ranges might not be set in the project; cast it to an empty list
                fw.source_ranges = fw.source_ranges or []

                # If these attributes are lists, we sort them first, then compare.
                # Otherwise, we update if they differ.
                if fw.source_ranges != src_range:
                    if isinstance(src_range, list):
                        if sorted(fw.source_ranges) != sorted(src_range):
                            fw.source_ranges = src_range
                            fw_changed = True
                    else:
                        fw.source_ranges = src_range
                        fw_changed = True

                # source_tags might not be set in the project; cast it to an empty list
                fw.source_tags = fw.source_tags or []

                if fw.source_tags != src_tags:
                    if isinstance(src_tags, list):
                        if sorted(fw.source_tags) != sorted(src_tags):
                            fw.source_tags = src_tags
                            fw_changed = True
                    else:
                        fw.source_tags = src_tags
                        fw_changed = True

                # target_tags might not be set in the project; cast it to an empty list
                fw.target_tags = fw.target_tags or []

                if fw.target_tags != target_tags:
                    if isinstance(target_tags, list):
                        if sorted(fw.target_tags) != sorted(target_tags):
                            fw.target_tags = target_tags
                            fw_changed = True
                    else:
                        fw.target_tags = target_tags
                        fw_changed = True

                if fw_changed is True:
                    try:
                        gce.ex_update_firewall(fw)
                        changed = True
                    except Exception as e:
                        module.fail_json(msg=unexpected_error_msg(e), changed=False)

            # Firewall rule not found so we try to create it.
            except ResourceNotFoundError:
                try:
                    gce.ex_create_firewall(fwname, allowed_list, network=name,
                        source_ranges=src_range, source_tags=src_tags, target_tags=target_tags)
                    changed = True

                except Exception as e:
                    module.fail_json(msg=unexpected_error_msg(e), changed=False)

            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

            json_output['fwname'] = fwname
            json_output['allowed'] = allowed
            json_output['src_range'] = src_range
            json_output['src_tags'] = src_tags
            json_output['target_tags'] = target_tags

    if state in ['absent', 'deleted']:
        if fwname:
            json_output['fwname'] = fwname
            fw = None
            try:
                fw = gce.ex_get_firewall(fwname)
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if fw:
                gce.ex_destroy_firewall(fw)
                changed = True
        elif subnet_name:
            if not hasattr(gce, 'ex_get_subnetwork') or not hasattr(gce, 'ex_destroy_subnetwork'):
                module.fail_json(msg='Update libcloud to a more recent version (>1.0) that supports subnetwork creation', changed=changed)
            json_output['name'] = subnet_name
            subnet = None
            try:
                subnet = gce.ex_get_subnetwork(subnet_name, region=subnet_region)
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if subnet:
                gce.ex_destroy_subnetwork(subnet)
                changed = True
        elif name:
            json_output['name'] = name
            network = None
            try:
                network = gce.ex_get_network(name)

            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if network:
                try:
                    gce.ex_destroy_network(network)
                except Exception as e:
                    module.fail_json(msg=unexpected_error_msg(e), changed=False)
                changed = True

    json_output['changed'] = changed
    module.exit_json(**json_output)
Example #4
0
def main():
    module = AnsibleModule(argument_spec=dict(
        allowed=dict(),
        ipv4_range=dict(),
        fwname=dict(),
        name=dict(),
        src_range=dict(default=[], type='list'),
        src_tags=dict(default=[], type='list'),
        target_tags=dict(default=[], type='list'),
        state=dict(default='present'),
        service_account_email=dict(),
        pem_file=dict(type='path'),
        credentials_file=dict(type='path'),
        project_id=dict(),
        mode=dict(default='legacy', choices=['legacy', 'auto', 'custom']),
        subnet_name=dict(),
        subnet_region=dict(),
        subnet_desc=dict(),
    ))

    if not HAS_LIBCLOUD:
        module.fail_json(
            msg='libcloud with GCE support (0.17.0+) required for this module')

    gce = gce_connect(module)

    allowed = module.params.get('allowed')
    ipv4_range = module.params.get('ipv4_range')
    fwname = module.params.get('fwname')
    name = module.params.get('name')
    src_range = module.params.get('src_range')
    src_tags = module.params.get('src_tags')
    target_tags = module.params.get('target_tags')
    state = module.params.get('state')
    mode = module.params.get('mode')
    subnet_name = module.params.get('subnet_name')
    subnet_region = module.params.get('subnet_region')
    subnet_desc = module.params.get('subnet_desc')

    changed = False
    json_output = {'state': state}

    if state in ['active', 'present']:
        network = None
        subnet = None
        try:
            network = gce.ex_get_network(name)
            json_output['name'] = name
            if mode == 'legacy':
                json_output['ipv4_range'] = network.cidr
            if network and mode == 'custom' and subnet_name:
                if not hasattr(gce, 'ex_get_subnetwork'):
                    module.fail_json(
                        msg=
                        "Update libcloud to a more recent version (>1.0) that supports network 'mode' parameter",
                        changed=False)

                subnet = gce.ex_get_subnetwork(subnet_name,
                                               region=subnet_region)
                json_output['subnet_name'] = subnet_name
                json_output['ipv4_range'] = subnet.cidr
        except ResourceNotFoundError:
            pass
        except Exception as e:
            module.fail_json(msg=unexpected_error_msg(e), changed=False)

        # user wants to create a new network that doesn't yet exist
        if name and not network:
            if not ipv4_range and mode != 'auto':
                module.fail_json(
                    msg="Network '" + name +
                    "' is not found. To create network in legacy or custom mode, 'ipv4_range' parameter is required",
                    changed=False)
            args = [ipv4_range if mode == 'legacy' else None]
            kwargs = {}
            if mode != 'legacy':
                kwargs['mode'] = mode

            try:
                network = gce.ex_create_network(name, *args, **kwargs)
                json_output['name'] = name
                json_output['ipv4_range'] = ipv4_range
                changed = True
            except TypeError:
                module.fail_json(
                    msg=
                    "Update libcloud to a more recent version (>1.0) that supports network 'mode' parameter",
                    changed=False)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

        if (subnet_name or ipv4_range) and not subnet and mode == 'custom':
            if not hasattr(gce, 'ex_create_subnetwork'):
                module.fail_json(
                    msg=
                    'Update libcloud to a more recent version (>1.0) that supports subnetwork creation',
                    changed=changed)
            if not subnet_name or not ipv4_range or not subnet_region:
                module.fail_json(
                    msg=
                    "subnet_name, ipv4_range, and subnet_region required for custom mode",
                    changed=changed)

            try:
                subnet = gce.ex_create_subnetwork(subnet_name,
                                                  cidr=ipv4_range,
                                                  network=name,
                                                  region=subnet_region,
                                                  description=subnet_desc)
                json_output['subnet_name'] = subnet_name
                json_output['ipv4_range'] = ipv4_range
                changed = True
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=changed)

        if fwname:
            # user creating a firewall rule
            if not allowed and not src_range and not src_tags:
                if changed and network:
                    module.fail_json(
                        msg="Network created, but missing required " +
                        "firewall rule parameter(s)",
                        changed=True)
                module.fail_json(
                    msg="Missing required firewall rule parameter(s)",
                    changed=False)

            allowed_list = format_allowed(allowed)

            # Fetch existing rule and if it exists, compare attributes
            # update if attributes changed.  Create if doesn't exist.
            try:
                fw_changed = False
                fw = gce.ex_get_firewall(fwname)

                # If old and new attributes are different, we update the firewall rule.
                # This implicitly lets us clear out attributes as well.
                # allowed_list is required and must not be None for firewall rules.
                if allowed_list and (sorted_allowed_list(allowed_list) !=
                                     sorted_allowed_list(fw.allowed)):
                    fw.allowed = allowed_list
                    fw_changed = True

                # source_ranges might not be set in the project; cast it to an empty list
                fw.source_ranges = fw.source_ranges or []

                # If these attributes are lists, we sort them first, then compare.
                # Otherwise, we update if they differ.
                if fw.source_ranges != src_range:
                    if isinstance(src_range, list):
                        if sorted(fw.source_ranges) != sorted(src_range):
                            fw.source_ranges = src_range
                            fw_changed = True
                    else:
                        fw.source_ranges = src_range
                        fw_changed = True

                # source_tags might not be set in the project; cast it to an empty list
                fw.source_tags = fw.source_tags or []

                if fw.source_tags != src_tags:
                    if isinstance(src_tags, list):
                        if sorted(fw.source_tags) != sorted(src_tags):
                            fw.source_tags = src_tags
                            fw_changed = True
                    else:
                        fw.source_tags = src_tags
                        fw_changed = True

                # target_tags might not be set in the project; cast it to an empty list
                fw.target_tags = fw.target_tags or []

                if fw.target_tags != target_tags:
                    if isinstance(target_tags, list):
                        if sorted(fw.target_tags) != sorted(target_tags):
                            fw.target_tags = target_tags
                            fw_changed = True
                    else:
                        fw.target_tags = target_tags
                        fw_changed = True

                if fw_changed is True:
                    try:
                        gce.ex_update_firewall(fw)
                        changed = True
                    except Exception as e:
                        module.fail_json(msg=unexpected_error_msg(e),
                                         changed=False)

            # Firewall rule not found so we try to create it.
            except ResourceNotFoundError:
                try:
                    gce.ex_create_firewall(fwname,
                                           allowed_list,
                                           network=name,
                                           source_ranges=src_range,
                                           source_tags=src_tags,
                                           target_tags=target_tags)
                    changed = True

                except Exception as e:
                    module.fail_json(msg=unexpected_error_msg(e),
                                     changed=False)

            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

            json_output['fwname'] = fwname
            json_output['allowed'] = allowed
            json_output['src_range'] = src_range
            json_output['src_tags'] = src_tags
            json_output['target_tags'] = target_tags

    if state in ['absent', 'deleted']:
        if fwname:
            json_output['fwname'] = fwname
            fw = None
            try:
                fw = gce.ex_get_firewall(fwname)
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if fw:
                gce.ex_destroy_firewall(fw)
                changed = True
        elif subnet_name:
            if not hasattr(gce, 'ex_get_subnetwork') or not hasattr(
                    gce, 'ex_destroy_subnetwork'):
                module.fail_json(
                    msg=
                    'Update libcloud to a more recent version (>1.0) that supports subnetwork creation',
                    changed=changed)
            json_output['name'] = subnet_name
            subnet = None
            try:
                subnet = gce.ex_get_subnetwork(subnet_name,
                                               region=subnet_region)
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if subnet:
                gce.ex_destroy_subnetwork(subnet)
                changed = True
        elif name:
            json_output['name'] = name
            network = None
            try:
                network = gce.ex_get_network(name)

            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if network:
                try:
                    gce.ex_destroy_network(network)
                except Exception as e:
                    module.fail_json(msg=unexpected_error_msg(e),
                                     changed=False)
                changed = True

    json_output['changed'] = changed
    module.exit_json(**json_output)
Example #5
0
def main():
    module = AnsibleModule(argument_spec=dict(
        delete_on_termination=dict(type='bool'),
        detach_only=dict(type='bool'),
        instance_name=dict(),
        mode=dict(default='READ_ONLY', choices=['READ_WRITE', 'READ_ONLY']),
        name=dict(required=True),
        size_gb=dict(default=10),
        disk_type=dict(default='pd-standard'),
        image=dict(),
        image_family=dict(),
        external_projects=dict(type='list'),
        snapshot=dict(),
        state=dict(default='present'),
        zone=dict(default='us-central1-b'),
        service_account_email=dict(),
        pem_file=dict(type='path'),
        credentials_file=dict(type='path'),
        project_id=dict(),
    ))
    if not HAS_LIBCLOUD:
        module.fail_json(
            msg=
            'libcloud with GCE support (0.17.0+) is required for this module')

    gce = gce_connect(module)

    delete_on_termination = module.params.get('delete_on_termination')
    detach_only = module.params.get('detach_only')
    instance_name = module.params.get('instance_name')
    mode = module.params.get('mode')
    name = module.params.get('name')
    size_gb = module.params.get('size_gb')
    disk_type = module.params.get('disk_type')
    image = module.params.get('image')
    image_family = module.params.get('image_family')
    external_projects = module.params.get('external_projects')
    snapshot = module.params.get('snapshot')
    state = module.params.get('state')
    zone = module.params.get('zone')

    if delete_on_termination and not instance_name:
        module.fail_json(
            msg=
            'Must specify an instance name when requesting delete on termination',
            changed=False)

    if detach_only and not instance_name:
        module.fail_json(
            msg='Must specify an instance name when detaching a disk',
            changed=False)

    disk = inst = None
    changed = is_attached = False

    json_output = {
        'name': name,
        'zone': zone,
        'state': state,
        'disk_type': disk_type
    }
    if detach_only:
        json_output['detach_only'] = True
        json_output['detached_from_instance'] = instance_name

    if instance_name:
        # user wants to attach/detach from an existing instance
        try:
            inst = gce.ex_get_node(instance_name, zone)
            # is the disk attached?
            for d in inst.extra['disks']:
                if d['deviceName'] == name:
                    is_attached = True
                    json_output['attached_mode'] = d['mode']
                    json_output['attached_to_instance'] = inst.name
        except:
            pass

    # find disk if it already exists
    try:
        disk = gce.ex_get_volume(name)
        json_output['size_gb'] = int(disk.size)
    except ResourceNotFoundError:
        pass
    except Exception as e:
        module.fail_json(msg=unexpected_error_msg(e), changed=False)

    # user wants a disk to exist.  If "instance_name" is supplied the user
    # also wants it attached
    if state in ['active', 'present']:

        if not size_gb:
            module.fail_json(msg="Must supply a size_gb", changed=False)
        try:
            size_gb = int(round(float(size_gb)))
            if size_gb < 1:
                raise Exception
        except:
            module.fail_json(msg="Must supply a size_gb larger than 1 GB",
                             changed=False)

        if instance_name and inst is None:
            module.fail_json(msg='Instance %s does not exist in zone %s' %
                             (instance_name, zone),
                             changed=False)

        if not disk:
            if image is not None and snapshot is not None:
                module.fail_json(
                    msg='Cannot give both image (%s) and snapshot (%s)' %
                    (image, snapshot),
                    changed=False)
            lc_image = None
            lc_snapshot = None
            if image_family is not None:
                lc_image = gce.ex_get_image_from_family(
                    image_family, ex_project_list=external_projects)
            elif image is not None:
                lc_image = gce.ex_get_image(image,
                                            ex_project_list=external_projects)
            elif snapshot is not None:
                lc_snapshot = gce.ex_get_snapshot(snapshot)
            try:
                disk = gce.create_volume(size_gb,
                                         name,
                                         location=zone,
                                         image=lc_image,
                                         snapshot=lc_snapshot,
                                         ex_disk_type=disk_type)
            except ResourceExistsError:
                pass
            except QuotaExceededError:
                module.fail_json(msg='Requested disk size exceeds quota',
                                 changed=False)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            json_output['size_gb'] = size_gb
            if image is not None:
                json_output['image'] = image
            if snapshot is not None:
                json_output['snapshot'] = snapshot
            changed = True
        if inst and not is_attached:
            try:
                gce.attach_volume(inst,
                                  disk,
                                  device=name,
                                  ex_mode=mode,
                                  ex_auto_delete=delete_on_termination)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            json_output['attached_to_instance'] = inst.name
            json_output['attached_mode'] = mode
            if delete_on_termination:
                json_output['delete_on_termination'] = True
            changed = True

    # user wants to delete a disk (or perhaps just detach it).
    if state in ['absent', 'deleted'] and disk:

        if inst and is_attached:
            try:
                gce.detach_volume(disk, ex_node=inst)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            changed = True
        if not detach_only:
            try:
                gce.destroy_volume(disk)
            except ResourceInUseError as e:
                module.fail_json(msg=str(e.value), changed=False)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            changed = True

    json_output['changed'] = changed
    module.exit_json(**json_output)
Example #6
0
def main():
    module = AnsibleModule(
        argument_spec = dict(
            httphealthcheck_name = dict(),
            httphealthcheck_port = dict(default=80),
            httphealthcheck_path = dict(default='/'),
            httphealthcheck_interval = dict(default=5),
            httphealthcheck_timeout = dict(default=5),
            httphealthcheck_unhealthy_count = dict(default=2),
            httphealthcheck_healthy_count = dict(default=2),
            httphealthcheck_host = dict(),
            name = dict(),
            protocol = dict(default='tcp'),
            region = dict(),
            external_ip = dict(),
            port_range = dict(),
            members = dict(type='list'),
            state = dict(default='present'),
            service_account_email = dict(),
            pem_file = dict(type='path'),
            credentials_file = dict(type='path'),
            project_id = dict(),
        )
    )

    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud with GCE support (0.13.3+) required for this module.')

    gce = gce_connect(module)

    httphealthcheck_name = module.params.get('httphealthcheck_name')
    httphealthcheck_port = module.params.get('httphealthcheck_port')
    httphealthcheck_path = module.params.get('httphealthcheck_path')
    httphealthcheck_interval = module.params.get('httphealthcheck_interval')
    httphealthcheck_timeout = module.params.get('httphealthcheck_timeout')
    httphealthcheck_unhealthy_count = \
            module.params.get('httphealthcheck_unhealthy_count')
    httphealthcheck_healthy_count = \
            module.params.get('httphealthcheck_healthy_count')
    httphealthcheck_host = module.params.get('httphealthcheck_host')
    name = module.params.get('name')
    protocol = module.params.get('protocol')
    region = module.params.get('region')
    external_ip = module.params.get('external_ip')
    port_range = module.params.get('port_range')
    members = module.params.get('members')
    state = module.params.get('state')

    try:
        gcelb = get_driver_lb(Provider_lb.GCE)(gce_driver=gce)
        gcelb.connection.user_agent_append("%s/%s" % (
            USER_AGENT_PRODUCT, USER_AGENT_VERSION))
    except Exception as e:
        module.fail_json(msg=unexpected_error_msg(e), changed=False)

    changed = False
    json_output = {'name': name, 'state': state}

    if not name and not httphealthcheck_name:
        module.fail_json(msg='Nothing to do, please specify a "name" ' + \
                'or "httphealthcheck_name" parameter', changed=False)

    if state in ['active', 'present']:
        # first, create the httphealthcheck if requested
        hc = None
        if httphealthcheck_name:
            json_output['httphealthcheck_name'] = httphealthcheck_name
            try:
                hc = gcelb.ex_create_healthcheck(httphealthcheck_name,
                    host=httphealthcheck_host, path=httphealthcheck_path,
                    port=httphealthcheck_port,
                    interval=httphealthcheck_interval,
                    timeout=httphealthcheck_timeout,
                    unhealthy_threshold=httphealthcheck_unhealthy_count,
                    healthy_threshold=httphealthcheck_healthy_count)
                changed = True
            except ResourceExistsError:
                hc = gce.ex_get_healthcheck(httphealthcheck_name)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

            if hc is not None:
                json_output['httphealthcheck_host'] = hc.extra['host']
                json_output['httphealthcheck_path'] = hc.path
                json_output['httphealthcheck_port'] = hc.port
                json_output['httphealthcheck_interval'] = hc.interval
                json_output['httphealthcheck_timeout'] = hc.timeout
                json_output['httphealthcheck_unhealthy_count'] = \
                        hc.unhealthy_threshold
                json_output['httphealthcheck_healthy_count'] = \
                        hc.healthy_threshold

        # create the forwarding rule (and target pool under the hood)
        lb = None
        if name:
            if not region:
                module.fail_json(msg='Missing required region name',
                        changed=False)
            nodes = []
            output_nodes = []
            json_output['name'] = name
            # members is a python list of 'zone/inst' strings
            if members:
                for node in members:
                    try:
                        zone, node_name = node.split('/')
                        nodes.append(gce.ex_get_node(node_name, zone))
                        output_nodes.append(node)
                    except:
                        # skip nodes that are badly formatted or don't exist
                        pass
            try:
                if hc is not None:
                    lb = gcelb.create_balancer(name, port_range, protocol,
                        None, nodes, ex_region=region, ex_healthchecks=[hc],
                        ex_address=external_ip)
                else:
                    lb = gcelb.create_balancer(name, port_range, protocol,
                        None, nodes, ex_region=region, ex_address=external_ip)
                changed = True
            except ResourceExistsError:
                lb = gcelb.get_balancer(name)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

            if lb is not None:
                json_output['members'] = output_nodes
                json_output['protocol'] = protocol
                json_output['region'] = region
                json_output['external_ip'] = lb.ip
                json_output['port_range'] = lb.port
                hc_names = []
                if 'healthchecks' in lb.extra:
                    for hc in lb.extra['healthchecks']:
                        hc_names.append(hc.name)
                json_output['httphealthchecks'] = hc_names

    if state in ['absent', 'deleted']:
        # first, delete the load balancer (forwarding rule and target pool)
        # if specified.
        if name:
            json_output['name'] = name
            try:
                lb = gcelb.get_balancer(name)
                gcelb.destroy_balancer(lb)
                changed = True
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

        # destroy the health check if specified
        if httphealthcheck_name:
            json_output['httphealthcheck_name'] = httphealthcheck_name
            try:
                hc = gce.ex_get_healthcheck(httphealthcheck_name)
                gce.ex_destroy_healthcheck(hc)
                changed = True
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)


    json_output['changed'] = changed
    module.exit_json(**json_output)
Example #7
0
def main():
    module = AnsibleModule(
        argument_spec = dict(
            delete_on_termination = dict(type='bool'),
            detach_only = dict(type='bool'),
            instance_name = dict(),
            mode = dict(default='READ_ONLY', choices=['READ_WRITE', 'READ_ONLY']),
            name = dict(required=True),
            size_gb = dict(default=10),
            disk_type = dict(default='pd-standard'),
            image = dict(),
            image_family = dict(),
            external_projects = dict(type='list'),
            snapshot = dict(),
            state = dict(default='present'),
            zone = dict(default='us-central1-b'),
            service_account_email = dict(),
            pem_file = dict(type='path'),
            credentials_file = dict(type='path'),
            project_id = dict(),
        )
    )
    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud with GCE support (0.17.0+) is required for this module')

    gce = gce_connect(module)

    delete_on_termination = module.params.get('delete_on_termination')
    detach_only = module.params.get('detach_only')
    instance_name = module.params.get('instance_name')
    mode = module.params.get('mode')
    name = module.params.get('name')
    size_gb = module.params.get('size_gb')
    disk_type = module.params.get('disk_type')
    image = module.params.get('image')
    image_family = module.params.get('image_family')
    external_projects = module.params.get('external_projects')
    snapshot = module.params.get('snapshot')
    state = module.params.get('state')
    zone = module.params.get('zone')

    if delete_on_termination and not instance_name:
        module.fail_json(
            msg='Must specify an instance name when requesting delete on termination',
            changed=False)

    if detach_only and not instance_name:
        module.fail_json(
            msg='Must specify an instance name when detaching a disk',
            changed=False)

    disk = inst = None
    changed = is_attached = False

    json_output = { 'name': name, 'zone': zone, 'state': state, 'disk_type': disk_type  }
    if detach_only:
        json_output['detach_only'] = True
        json_output['detached_from_instance'] = instance_name

    if instance_name:
        # user wants to attach/detach from an existing instance
        try:
            inst = gce.ex_get_node(instance_name, zone)
            # is the disk attached?
            for d in inst.extra['disks']:
                if d['deviceName'] == name:
                    is_attached = True
                    json_output['attached_mode'] = d['mode']
                    json_output['attached_to_instance'] = inst.name
        except:
            pass

    # find disk if it already exists
    try:
        disk = gce.ex_get_volume(name)
        json_output['size_gb'] = int(disk.size)
    except ResourceNotFoundError:
        pass
    except Exception as e:
        module.fail_json(msg=unexpected_error_msg(e), changed=False)

    # user wants a disk to exist.  If "instance_name" is supplied the user
    # also wants it attached
    if state in ['active', 'present']:

        if not size_gb:
            module.fail_json(msg="Must supply a size_gb", changed=False)
        try:
            size_gb = int(round(float(size_gb)))
            if size_gb < 1:
                raise Exception
        except:
            module.fail_json(msg="Must supply a size_gb larger than 1 GB",
                    changed=False)

        if instance_name and inst is None:
            module.fail_json(msg='Instance %s does not exist in zone %s' % (
                instance_name, zone), changed=False)

        if not disk:
            if image is not None and snapshot is not None:
                module.fail_json(
                    msg='Cannot give both image (%s) and snapshot (%s)' % (
                        image, snapshot), changed=False)
            lc_image = None
            lc_snapshot = None
            if image_family is not None:
                lc_image = gce.ex_get_image_from_family(image_family, ex_project_list=external_projects)
            elif image is not None:
                lc_image = gce.ex_get_image(image, ex_project_list=external_projects)
            elif snapshot is not None:
                lc_snapshot = gce.ex_get_snapshot(snapshot)
            try:
                disk = gce.create_volume(
                    size_gb, name, location=zone, image=lc_image,
                    snapshot=lc_snapshot, ex_disk_type=disk_type)
            except ResourceExistsError:
                pass
            except QuotaExceededError:
                module.fail_json(msg='Requested disk size exceeds quota',
                        changed=False)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            json_output['size_gb'] = size_gb
            if image is not None:
                json_output['image'] = image
            if snapshot is not None:
                json_output['snapshot'] = snapshot
            changed = True
        if inst and not is_attached:
            try:
                gce.attach_volume(inst, disk, device=name, ex_mode=mode,
                                  ex_auto_delete=delete_on_termination)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            json_output['attached_to_instance'] = inst.name
            json_output['attached_mode'] = mode
            if delete_on_termination:
                json_output['delete_on_termination'] = True
            changed = True

    # user wants to delete a disk (or perhaps just detach it).
    if state in ['absent', 'deleted'] and disk:

        if inst and is_attached:
            try:
                gce.detach_volume(disk, ex_node=inst)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            changed = True
        if not detach_only:
            try:
                gce.destroy_volume(disk)
            except ResourceInUseError as e:
                module.fail_json(msg=str(e.value), changed=False)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            changed = True

    json_output['changed'] = changed
    module.exit_json(**json_output)
Example #8
0
def main():
    module = AnsibleModule(argument_spec=dict(
        httphealthcheck_name=dict(),
        httphealthcheck_port=dict(default=80),
        httphealthcheck_path=dict(default='/'),
        httphealthcheck_interval=dict(default=5),
        httphealthcheck_timeout=dict(default=5),
        httphealthcheck_unhealthy_count=dict(default=2),
        httphealthcheck_healthy_count=dict(default=2),
        httphealthcheck_host=dict(),
        name=dict(),
        protocol=dict(default='tcp'),
        region=dict(),
        external_ip=dict(),
        port_range=dict(),
        members=dict(type='list'),
        state=dict(default='present'),
        service_account_email=dict(),
        pem_file=dict(type='path'),
        credentials_file=dict(type='path'),
        project_id=dict(),
    ))

    if not HAS_LIBCLOUD:
        module.fail_json(
            msg='libcloud with GCE support (0.13.3+) required for this module.'
        )

    gce = gce_connect(module)

    httphealthcheck_name = module.params.get('httphealthcheck_name')
    httphealthcheck_port = module.params.get('httphealthcheck_port')
    httphealthcheck_path = module.params.get('httphealthcheck_path')
    httphealthcheck_interval = module.params.get('httphealthcheck_interval')
    httphealthcheck_timeout = module.params.get('httphealthcheck_timeout')
    httphealthcheck_unhealthy_count = module.params.get(
        'httphealthcheck_unhealthy_count')
    httphealthcheck_healthy_count = module.params.get(
        'httphealthcheck_healthy_count')
    httphealthcheck_host = module.params.get('httphealthcheck_host')
    name = module.params.get('name')
    protocol = module.params.get('protocol')
    region = module.params.get('region')
    external_ip = module.params.get('external_ip')
    port_range = module.params.get('port_range')
    members = module.params.get('members')
    state = module.params.get('state')

    try:
        gcelb = get_driver_lb(Provider_lb.GCE)(gce_driver=gce)
        gcelb.connection.user_agent_append(
            "%s/%s" % (USER_AGENT_PRODUCT, USER_AGENT_VERSION))
    except Exception as e:
        module.fail_json(msg=unexpected_error_msg(e), changed=False)

    changed = False
    json_output = {'name': name, 'state': state}

    if not name and not httphealthcheck_name:
        module.fail_json(msg='Nothing to do, please specify a "name" ' +
                         'or "httphealthcheck_name" parameter',
                         changed=False)

    if state in ['active', 'present']:
        # first, create the httphealthcheck if requested
        hc = None
        if httphealthcheck_name:
            json_output['httphealthcheck_name'] = httphealthcheck_name
            try:
                hc = gcelb.ex_create_healthcheck(
                    httphealthcheck_name,
                    host=httphealthcheck_host,
                    path=httphealthcheck_path,
                    port=httphealthcheck_port,
                    interval=httphealthcheck_interval,
                    timeout=httphealthcheck_timeout,
                    unhealthy_threshold=httphealthcheck_unhealthy_count,
                    healthy_threshold=httphealthcheck_healthy_count)
                changed = True
            except ResourceExistsError:
                hc = gce.ex_get_healthcheck(httphealthcheck_name)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

            if hc is not None:
                json_output['httphealthcheck_host'] = hc.extra['host']
                json_output['httphealthcheck_path'] = hc.path
                json_output['httphealthcheck_port'] = hc.port
                json_output['httphealthcheck_interval'] = hc.interval
                json_output['httphealthcheck_timeout'] = hc.timeout
                json_output[
                    'httphealthcheck_unhealthy_count'] = hc.unhealthy_threshold
                json_output[
                    'httphealthcheck_healthy_count'] = hc.healthy_threshold

        # create the forwarding rule (and target pool under the hood)
        lb = None
        if name:
            if not region:
                module.fail_json(msg='Missing required region name',
                                 changed=False)
            nodes = []
            output_nodes = []
            json_output['name'] = name
            # members is a python list of 'zone/inst' strings
            if members:
                for node in members:
                    try:
                        zone, node_name = node.split('/')
                        nodes.append(gce.ex_get_node(node_name, zone))
                        output_nodes.append(node)
                    except:
                        # skip nodes that are badly formatted or don't exist
                        pass
            try:
                if hc is not None:
                    lb = gcelb.create_balancer(name,
                                               port_range,
                                               protocol,
                                               None,
                                               nodes,
                                               ex_region=region,
                                               ex_healthchecks=[hc],
                                               ex_address=external_ip)
                else:
                    lb = gcelb.create_balancer(name,
                                               port_range,
                                               protocol,
                                               None,
                                               nodes,
                                               ex_region=region,
                                               ex_address=external_ip)
                changed = True
            except ResourceExistsError:
                lb = gcelb.get_balancer(name)
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

            if lb is not None:
                json_output['members'] = output_nodes
                json_output['protocol'] = protocol
                json_output['region'] = region
                json_output['external_ip'] = lb.ip
                json_output['port_range'] = lb.port
                hc_names = []
                if 'healthchecks' in lb.extra:
                    for hc in lb.extra['healthchecks']:
                        hc_names.append(hc.name)
                json_output['httphealthchecks'] = hc_names

    if state in ['absent', 'deleted']:
        # first, delete the load balancer (forwarding rule and target pool)
        # if specified.
        if name:
            json_output['name'] = name
            try:
                lb = gcelb.get_balancer(name)
                gcelb.destroy_balancer(lb)
                changed = True
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

        # destroy the health check if specified
        if httphealthcheck_name:
            json_output['httphealthcheck_name'] = httphealthcheck_name
            try:
                hc = gce.ex_get_healthcheck(httphealthcheck_name)
                gce.ex_destroy_healthcheck(hc)
                changed = True
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

    json_output['changed'] = changed
    module.exit_json(**json_output)