Beispiel #1
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            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+) required for this module')

    gce = gce_connect(module)

    changed = False
    gce_regions = []

    try:
        regions = gce.ex_list_regions()
        for r in regions:
            gce_region = {}
            gce_region['name'] = r.name
            gce_region['status'] = r.status
            gce_region['zones'] = []
            for z in r.zones:
                gce_zone = {}
                gce_zone['name'] = z.name
                gce_zone['status'] = z.status
                gce_region['zones'].append(gce_zone)
            gce_regions.append(gce_region)
        json_output = { 'regions': gce_regions }
        module.exit_json(changed=False, results=json_output)
    except ResourceNotFoundError:
        pass
Beispiel #2
0
def main():
    module = AnsibleModule(argument_spec=dict(
        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+) required for this module')

    gce = gce_connect(module)

    changed = False
    gce_regions = []

    try:
        regions = gce.ex_list_regions()
        for r in regions:
            gce_region = {}
            gce_region['name'] = r.name
            gce_region['status'] = r.status
            gce_region['zones'] = []
            for z in r.zones:
                gce_zone = {}
                gce_zone['name'] = z.name
                gce_zone['status'] = z.status
                gce_region['zones'].append(gce_zone)
            gce_regions.append(gce_region)
        json_output = {'regions': gce_regions}
        module.exit_json(changed=False, results=json_output)
    except ResourceNotFoundError:
        pass
def main():
    module = AnsibleModule(
        argument_spec=dict(
            state=dict(choices=['present', 'absent'], default='present'),
            name=dict(require=True, aliases=['base_name']),
            size=dict(default='f1-micro'),
            source=dict(),
            image=dict(),
            image_family=dict(default='debian-8'),
            disk_type=dict(choices=['pd-standard', 'pd-ssd'], default='pd-standard', type='str'),
            disk_auto_delete=dict(type='bool', default=True),
            network=dict(default='default'),
            subnetwork=dict(),
            can_ip_forward=dict(type='bool', default=False),
            external_ip=dict(default='ephemeral'),
            service_account_email=dict(),
            service_account_permissions=dict(type='list'),
            automatic_restart=dict(type='bool', default=None),
            preemptible=dict(type='bool', default=None),
            tags=dict(type='list'),
            metadata=dict(),
            description=dict(),
            disks=dict(type='list'),
            nic_gce_struct=dict(type='list'),
            project_id=dict(),
            pem_file=dict(type='path'),
            credentials_file=dict(type='path'),
            subnetwork_region=dict(),
            disks_gce_struct=dict(type='list')
        ),
        mutually_exclusive=[['source', 'image']],
        required_one_of=[['image', 'image_family']],
        supports_check_mode=True
    )

    if not HAS_PYTHON26:
        module.fail_json(
            msg="GCE module requires python's 'ast' module, python v2.6+")
    if not HAS_LIBCLOUD:
        module.fail_json(
            msg='libcloud with GCE support (0.17.0+) required for this module')

    try:
        gce = gce_connect(module)
    except GoogleBaseError as e:
        module.fail_json(msg='GCE Connexion failed %s' % to_native(e), exception=traceback.format_exc())

    if module.check_mode:
        (changed, output) = check_if_system_state_would_be_changed(module, gce)
        module.exit_json(
            changed=changed,
            msg=output
        )
    else:
        module_controller(module, gce)
def main():
    module = AnsibleModule(
        argument_spec=dict(
            state=dict(choices=['present', 'absent'], default='present'),
            name=dict(require=True, aliases=['base_name']),
            size=dict(default='f1-micro'),
            source=dict(),
            image=dict(),
            image_family=dict(default='debian-8'),
            disk_type=dict(choices=['pd-standard', 'pd-ssd'], default='pd-standard', type='str'),
            disk_auto_delete=dict(type='bool', default=True),
            network=dict(default='default'),
            subnetwork=dict(),
            can_ip_forward=dict(type='bool', default=False),
            external_ip=dict(default='ephemeral'),
            service_account_email=dict(),
            service_account_permissions=dict(type='list'),
            automatic_restart=dict(type='bool', default=None),
            preemptible=dict(type='bool', default=None),
            tags=dict(type='list'),
            metadata=dict(),
            description=dict(),
            disks=dict(type='list'),
            nic_gce_struct=dict(type='list'),
            project_id=dict(),
            pem_file=dict(type='path'),
            credentials_file=dict(type='path'),
            subnetwork_region=dict(),
            disks_gce_struct=dict(type='list')
        ),
        mutually_exclusive=[['source', 'image']],
        required_one_of=[['image', 'image_family']],
        supports_check_mode=True
    )

    if not HAS_PYTHON26:
        module.fail_json(
            msg="GCE module requires python's 'ast' module, python v2.6+")
    if not HAS_LIBCLOUD:
        module.fail_json(
            msg='libcloud with GCE support (0.17.0+) required for this module')

    try:
        gce = gce_connect(module)
    except GoogleBaseError as e:
        module.fail_json(msg='GCE Connexion failed %s' % to_native(e), exception=traceback.format_exc())

    if module.check_mode:
        (changed, output) = check_if_system_state_would_be_changed(module, gce)
        module.exit_json(
            changed=changed,
            msg=output
        )
    else:
        module_controller(module, gce)
Beispiel #5
0
def main():
    module = AnsibleModule(argument_spec=dict(
        instance_name=dict(required=True),
        tags=dict(type='list'),
        state=dict(default='present', choices=['present', 'absent']),
        zone=dict(default='us-central1-a'),
        service_account_email=dict(),
        pem_file=dict(type='path'),
        project_id=dict(),
    ))

    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud with GCE support is required.')

    instance_name = module.params.get('instance_name')
    state = module.params.get('state')
    tags = module.params.get('tags')
    zone = module.params.get('zone')
    changed = False

    if not zone:
        module.fail_json(msg='Must specify "zone"', changed=False)

    if not tags:
        module.fail_json(msg='Must specify "tags"', changed=False)

    gce = gce_connect(module)

    # add tags to instance.
    if state == 'present':
        changed, tags_changed = add_tags(gce, module, instance_name, tags)

    # remove tags from instance
    if state == 'absent':
        changed, tags_changed = remove_tags(gce, module, instance_name, tags)

    module.exit_json(changed=changed,
                     instance_name=instance_name,
                     tags=tags_changed,
                     zone=zone)
Beispiel #6
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            instance_name=dict(required=True),
            tags=dict(type='list'),
            state=dict(default='present', choices=['present', 'absent']),
            zone=dict(default='us-central1-a'),
            service_account_email=dict(),
            pem_file=dict(type='path'),
            project_id=dict(),
        )
    )

    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud with GCE support is required.')

    instance_name = module.params.get('instance_name')
    state = module.params.get('state')
    tags = module.params.get('tags')
    zone = module.params.get('zone')
    changed = False

    if not zone:
        module.fail_json(msg='Must specify "zone"', changed=False)

    if not tags:
        module.fail_json(msg='Must specify "tags"', changed=False)

    gce = gce_connect(module)

    # add tags to instance.
    if state == 'present':
        changed, tags_changed = add_tags(gce, module, instance_name, tags)

    # remove tags from instance
    if state == 'absent':
        changed, tags_changed = remove_tags(gce, module, instance_name, tags)

    module.exit_json(changed=changed, instance_name=instance_name, tags=tags_changed, zone=zone)
Beispiel #7
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            family=dict(),
            description=dict(),
            source=dict(),
            state=dict(default='present', choices=['present', 'absent']),
            zone=dict(default='us-central1-a'),
            service_account_email=dict(),
            pem_file=dict(type='path'),
            project_id=dict(),
            timeout=dict(type='int', default=180)
        )
    )

    if not has_libcloud:
        module.fail_json(msg='libcloud with GCE support is required.')

    gce = gce_connect(module)

    name = module.params.get('name')
    state = module.params.get('state')
    family = module.params.get('family')
    changed = False

    if family is not None and hasattr(libcloud, '__version__') and libcloud.__version__ <= '0.20.1':
        module.fail_json(msg="Apache Libcloud 1.0.0+ is required to use 'family' option",
                         changed=False)

    # user wants to create an image.
    if state == 'present':
        changed = create_image(gce, name, module)

    # user wants to delete the image.
    if state == 'absent':
        changed = delete_image(gce, name, module)

    module.exit_json(changed=changed, name=name)
Beispiel #8
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            family=dict(),
            description=dict(),
            source=dict(),
            state=dict(default='present', choices=['present', 'absent']),
            zone=dict(default='us-central1-a'),
            service_account_email=dict(),
            pem_file=dict(type='path'),
            project_id=dict(),
            timeout=dict(type='int', default=180)
        )
    )

    if not has_libcloud:
        module.fail_json(msg='libcloud with GCE support is required.')

    gce = gce_connect(module)

    name = module.params.get('name')
    state = module.params.get('state')
    family = module.params.get('family')
    changed = False

    if family is not None and hasattr(libcloud, '__version__') and libcloud.__version__ <= '0.20.1':
        module.fail_json(msg="Apache Libcloud 1.0.0+ is required to use 'family' option",
                         changed=False)

    # user wants to create an image.
    if state == 'present':
        changed = create_image(gce, name, module)

    # user wants to delete the image.
    if state == 'absent':
        changed = delete_image(gce, name, module)

    module.exit_json(changed=changed, name=name)
Beispiel #9
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            template=dict(),
            recreate_instances=dict(type='bool', default=False),
            # Do not set a default size here.  For Create and some update
            # operations, it is required and should be explicitly set.
            # Below, we set it to the existing value if it has not been set.
            size=dict(type='int'),
            state=dict(choices=['absent', 'present'], default='present'),
            zone=dict(required=True),
            autoscaling=dict(type='dict', default=None),
            named_ports=dict(type='list', default=None),
            service_account_email=dict(),
            service_account_permissions=dict(type='list'),
            pem_file=dict(type='path'),
            credentials_file=dict(type='path'),
            project_id=dict(),
        ), )

    if not HAS_PYTHON26:
        module.fail_json(
            msg="GCE module requires python's 'ast' module, python v2.6+")
    if not HAS_LIBCLOUD:
        module.fail_json(
            msg=
            'libcloud with GCE Managed Instance Group support (1.2+) required for this module.'
        )

    gce = gce_connect(module)
    if not hasattr(gce, 'ex_create_instancegroupmanager'):
        module.fail_json(
            msg=
            'libcloud with GCE Managed Instance Group support (1.2+) required for this module.',
            changed=False)

    params = {}
    params['state'] = module.params.get('state')
    params['zone'] = module.params.get('zone')
    params['name'] = module.params.get('name')
    params['size'] = module.params.get('size')
    params['template'] = module.params.get('template')
    params['recreate_instances'] = module.params.get('recreate_instances')
    params['autoscaling'] = module.params.get('autoscaling', None)
    params['named_ports'] = module.params.get('named_ports', None)

    (valid_autoscaling, as_msg) = _validate_autoscaling_params(params)
    if not valid_autoscaling:
        module.fail_json(msg=as_msg, changed=False)

    if params['named_ports'] is not None and not hasattr(
            gce, 'ex_instancegroup_set_named_ports'):
        module.fail_json(
            msg=
            "Apache Libcloud 1.3.0+ is required to use 'named_ports' option",
            changed=False)

    (valid_named_ports, np_msg) = _validate_named_port_params(params)
    if not valid_named_ports:
        module.fail_json(msg=np_msg, changed=False)

    changed = False
    json_output = {'state': params['state'], 'zone': params['zone']}
    mig = get_mig(gce, params['name'], params['zone'])

    if not mig:
        if params['state'] == 'absent':
            # Doesn't exist in GCE, and state==absent.
            changed = False
            module.fail_json(
                msg="Cannot delete unknown managed instance group: %s" %
                (params['name']))
        else:
            # Create MIG
            req_create_fields = [
                {'name': 'template', 'required': True, 'type': str},
                {'name': 'size', 'required': True, 'type': int}
            ] # yapf: disable

            (valid_create_fields,
             valid_create_msg) = _check_params(params, req_create_fields)
            if not valid_create_fields:
                module.fail_json(msg=valid_create_msg, changed=False)

            (changed,
             json_output['created_instances']) = create_mig(gce, params)
            if params['autoscaling'] and params['autoscaling'][
                    'enabled'] is True:
                # Fetch newly-created MIG and create Autoscaler for it.
                mig = get_mig(gce, params['name'], params['zone'])
                if not mig:
                    module.fail_json(
                        msg='Unable to fetch created MIG %s to create \
                        autoscaler in zone: %s' %
                        (params['name'], params['zone']),
                        changed=False)

                if not create_autoscaler(gce, mig, params['autoscaling']):
                    module.fail_json(
                        msg='Unable to fetch MIG %s to create autoscaler \
                        in zone: %s' % (params['name'], params['zone']),
                        changed=False)

                json_output['created_autoscaler'] = True
            # Add named ports if available
            if params['named_ports']:
                mig = get_mig(gce, params['name'], params['zone'])
                if not mig:
                    module.fail_json(
                        msg='Unable to fetch created MIG %s to create \
                        autoscaler in zone: %s' %
                        (params['name'], params['zone']),
                        changed=False)
                json_output['set_named_ports'] = update_named_ports(
                    mig, params['named_ports'])
                if json_output['set_named_ports']:
                    json_output['named_ports'] = params['named_ports']

    elif params['state'] == 'absent':
        # Delete MIG

        # First, check and remove the autoscaler, if present.
        # Note: multiple autoscalers can be associated to a single MIG.  We
        # only handle the one that is named, but we might want to think about this.
        if params['autoscaling']:
            autoscaler = get_autoscaler(gce, params['autoscaling']['name'],
                                        params['zone'])
            if not autoscaler:
                module.fail_json(msg='Unable to fetch autoscaler %s to delete \
                in zone: %s' % (params['autoscaling']['name'], params['zone']),
                                 changed=False)

            changed = delete_autoscaler(autoscaler)
            json_output['deleted_autoscaler'] = changed

        # Now, delete the MIG.
        (changed, json_output['deleted_instances']) = delete_mig(mig)

    else:
        # Update MIG

        # If we're going to update a MIG, we need a size and template values.
        # If not specified, we use the values from the existing MIG.
        if not params['size']:
            params['size'] = mig.size

        if not params['template']:
            params['template'] = mig.template.name

        if params['template'] != mig.template.name:
            # Update Instance Template.
            new_template = gce.ex_get_instancetemplate(params['template'])
            mig.set_instancetemplate(new_template)
            json_output['updated_instancetemplate'] = True
            changed = True
        if params['recreate_instances'] is True:
            # Recreate Instances.
            (changed, json_output['recreated_instances']
             ) = recreate_instances_in_mig(mig)

        if params['size'] != mig.size:
            # Resize MIG.
            keystr = 'created' if params['size'] > mig.size else 'deleted'
            (changed, json_output['resize_%s_instances' %
                                  (keystr)]) = resize_mig(mig, params['size'])

        # Update Autoscaler
        if params['autoscaling']:
            autoscaler = get_autoscaler(gce, params['autoscaling']['name'],
                                        params['zone'])
            if not autoscaler:
                # Try to create autoscaler.
                # Note: this isn't perfect, if the autoscaler name has changed
                # we wouldn't know that here.
                if not create_autoscaler(gce, mig, params['autoscaling']):
                    module.fail_json(
                        msg='Unable to create autoscaler %s for existing MIG %s\
                        in zone: %s' % (params['autoscaling']['name'],
                                        params['name'], params['zone']),
                        changed=False)
                json_output['created_autoscaler'] = True
                changed = True
            else:
                if params['autoscaling']['enabled'] is False:
                    # Delete autoscaler
                    changed = delete_autoscaler(autoscaler)
                    json_output['delete_autoscaler'] = changed
                else:
                    # Update policy, etc.
                    changed = update_autoscaler(gce, autoscaler,
                                                params['autoscaling'])
                    json_output['updated_autoscaler'] = changed
        named_ports = params['named_ports'] or []
        json_output['updated_named_ports'] = update_named_ports(
            mig, named_ports)
        if json_output['updated_named_ports']:
            json_output['named_ports'] = named_ports

    json_output['changed'] = changed
    json_output.update(params)
    module.exit_json(**json_output)
Beispiel #10
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)
Beispiel #11
0
def main():
    module = AnsibleModule(argument_spec=dict(
        backends=dict(type='list', required=True),
        backend_service_name=dict(required=True),
        healthchecks=dict(type='list', required=True),
        service_account_email=dict(),
        service_account_permissions=dict(type='list'),
        enable_cdn=dict(type='bool'),
        port_name=dict(type='str'),
        protocol=dict(type='str', default='TCP',
                      choices=['HTTP', 'HTTPS', 'SSL', 'TCP']),
        timeout=dict(type='int'),
        state=dict(choices=['absent', 'present'], default='present'),
        pem_file=dict(),
        credentials_file=dict(),
        project_id=dict(), ), )

    if not HAS_PYTHON26:
        module.fail_json(
            msg="GCE module requires python's 'ast' module, python v2.6+")
    if not HAS_LIBCLOUD:
        module.fail_json(
            msg='libcloud with GCE Backend Service support (1.3+) required for this module.')

    gce = gce_connect(module)
    if not hasattr(gce, 'ex_create_instancegroupmanager'):
        module.fail_json(
            msg='libcloud with GCE Backend Service support (1.3+) required for this module.',
            changed=False)

    params = {}
    params['state'] = module.params.get('state')
    params['backend_service_name'] = module.params.get('backend_service_name')
    params['backends'] = module.params.get('backends')
    params['healthchecks'] = module.params.get('healthchecks')
    params['enable_cdn'] = module.params.get('enable_cdn', None)
    params['port_name'] = module.params.get('port_name', None)
    params['protocol'] = module.params.get('protocol', None)
    params['timeout'] = module.params.get('timeout', None)

    try:
        _validate_params(params)
    except Exception as e:
        module.fail_json(msg=e.message, changed=False)

    changed = False
    json_output = {'state': params['state']}
    bes = get_backend_service(gce, params['backend_service_name'])

    if not bes:
        if params['state'] == 'absent':
            # Doesn't exist and state==absent.
            changed = False
            module.fail_json(
                msg="Cannot delete unknown backend service: %s" %
                (params['backend_service_name']))
        else:
            # Create
            (changed, json_output['backend_service_created']) = create_backend_service(gce,
                                                                                       params)
    elif params['state'] == 'absent':
        # Delete
        (changed, json_output['backend_service_deleted']) = delete_backend_service(bes)
    else:
        # TODO(supertom): Add update support when it is available in libcloud.
        changed = False

    json_output['changed'] = changed
    json_output.update(params)
    module.exit_json(**json_output)
Beispiel #12
0
def main():
    module = AnsibleModule(argument_spec=dict(
        instance_name=dict(required=True),
        snapshot_name=dict(required=True),
        state=dict(choices=['present', 'absent'], default='present'),
        disks=dict(default=None, type='list'),
        service_account_email=dict(type='str'),
        credentials_file=dict(type='path'),
        project_id=dict(type='str')))

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

    gce = gce_connect(module)

    instance_name = module.params.get('instance_name')
    snapshot_name = module.params.get('snapshot_name')
    disks = module.params.get('disks')
    state = module.params.get('state')

    json_output = dict(changed=False,
                       snapshots_created=[],
                       snapshots_deleted=[],
                       snapshots_existing=[],
                       snapshots_absent=[])

    snapshot = None

    instance = gce.ex_get_node(instance_name, 'all')
    instance_disks = instance.extra['disks']

    for instance_disk in instance_disks:
        disk_snapshot_name = snapshot_name
        device_name = instance_disk['deviceName']
        if disks is None or device_name in disks:
            volume_obj = gce.ex_get_volume(device_name)

            # If we have more than one disk to snapshot, prepend the disk name
            if len(instance_disks) > 1:
                disk_snapshot_name = device_name + "-" + disk_snapshot_name

            snapshot = find_snapshot(volume_obj, disk_snapshot_name)

            if snapshot and state == 'present':
                json_output['snapshots_existing'].append(disk_snapshot_name)

            elif snapshot and state == 'absent':
                snapshot.destroy()
                json_output['changed'] = True
                json_output['snapshots_deleted'].append(disk_snapshot_name)

            elif not snapshot and state == 'present':
                volume_obj.snapshot(disk_snapshot_name)
                json_output['changed'] = True
                json_output['snapshots_created'].append(disk_snapshot_name)

            elif not snapshot and state == 'absent':
                json_output['snapshots_absent'].append(disk_snapshot_name)

    module.exit_json(**json_output)
Beispiel #13
0
def main():
    module = AnsibleModule(argument_spec=dict(
        name=dict(required=True),
        template=dict(),
        recreate_instances=dict(type='bool', default=False),
        # Do not set a default size here.  For Create and some update
        # operations, it is required and should be explicitly set.
        # Below, we set it to the existing value if it has not been set.
        size=dict(type='int'),
        state=dict(choices=['absent', 'present'], default='present'),
        zone=dict(required=True),
        autoscaling=dict(type='dict', default=None),
        named_ports=dict(type='list', default=None),
        service_account_email=dict(),
        service_account_permissions=dict(type='list'),
        pem_file=dict(type='path'),
        credentials_file=dict(type='path'),
        project_id=dict(), ), )

    if not HAS_PYTHON26:
        module.fail_json(
            msg="GCE module requires python's 'ast' module, python v2.6+")
    if not HAS_LIBCLOUD:
        module.fail_json(
            msg='libcloud with GCE Managed Instance Group support (1.2+) required for this module.')

    gce = gce_connect(module)
    if not hasattr(gce, 'ex_create_instancegroupmanager'):
        module.fail_json(
            msg='libcloud with GCE Managed Instance Group support (1.2+) required for this module.',
            changed=False)

    params = {}
    params['state'] = module.params.get('state')
    params['zone'] = module.params.get('zone')
    params['name'] = module.params.get('name')
    params['size'] = module.params.get('size')
    params['template'] = module.params.get('template')
    params['recreate_instances'] = module.params.get('recreate_instances')
    params['autoscaling'] = module.params.get('autoscaling', None)
    params['named_ports'] = module.params.get('named_ports', None)

    (valid_autoscaling, as_msg) = _validate_autoscaling_params(params)
    if not valid_autoscaling:
        module.fail_json(msg=as_msg, changed=False)

    if params['named_ports'] is not None and not hasattr(
            gce, 'ex_instancegroup_set_named_ports'):
        module.fail_json(
            msg="Apache Libcloud 1.3.0+ is required to use 'named_ports' option",
            changed=False)

    (valid_named_ports, np_msg) = _validate_named_port_params(params)
    if not valid_named_ports:
        module.fail_json(msg=np_msg, changed=False)

    changed = False
    json_output = {'state': params['state'], 'zone': params['zone']}
    mig = get_mig(gce, params['name'], params['zone'])

    if not mig:
        if params['state'] == 'absent':
            # Doesn't exist in GCE, and state==absent.
            changed = False
            module.fail_json(
                msg="Cannot delete unknown managed instance group: %s" %
                (params['name']))
        else:
            # Create MIG
            req_create_fields = [
                {'name': 'template', 'required': True, 'type': str},
                {'name': 'size', 'required': True, 'type': int}
            ]  # yapf: disable

            (valid_create_fields, valid_create_msg) = _check_params(
                params, req_create_fields)
            if not valid_create_fields:
                module.fail_json(msg=valid_create_msg, changed=False)

            (changed, json_output['created_instances']) = create_mig(gce,
                                                                     params)
            if params['autoscaling'] and params['autoscaling'][
                    'enabled'] is True:
                # Fetch newly-created MIG and create Autoscaler for it.
                mig = get_mig(gce, params['name'], params['zone'])
                if not mig:
                    module.fail_json(
                        msg='Unable to fetch created MIG %s to create \
                        autoscaler in zone: %s' % (
                            params['name'], params['zone']), changed=False)

                if not create_autoscaler(gce, mig, params['autoscaling']):
                    module.fail_json(
                        msg='Unable to fetch MIG %s to create autoscaler \
                        in zone: %s' % (params['name'], params['zone']),
                        changed=False)

                json_output['created_autoscaler'] = True
            # Add named ports if available
            if params['named_ports']:
                mig = get_mig(gce, params['name'], params['zone'])
                if not mig:
                    module.fail_json(
                        msg='Unable to fetch created MIG %s to create \
                        autoscaler in zone: %s' % (
                            params['name'], params['zone']), changed=False)
                json_output['set_named_ports'] = update_named_ports(
                    mig, params['named_ports'])
                if json_output['set_named_ports']:
                    json_output['named_ports'] = params['named_ports']

    elif params['state'] == 'absent':
        # Delete MIG

        # First, check and remove the autoscaler, if present.
        # Note: multiple autoscalers can be associated to a single MIG.  We
        # only handle the one that is named, but we might want to think about this.
        if params['autoscaling']:
            autoscaler = get_autoscaler(gce, params['autoscaling']['name'],
                                        params['zone'])
            if not autoscaler:
                module.fail_json(msg='Unable to fetch autoscaler %s to delete \
                in zone: %s' % (params['autoscaling']['name'], params['zone']),
                    changed=False)

            changed = delete_autoscaler(autoscaler)
            json_output['deleted_autoscaler'] = changed

        # Now, delete the MIG.
        (changed, json_output['deleted_instances']) = delete_mig(mig)

    else:
        # Update MIG

        # If we're going to update a MIG, we need a size and template values.
        # If not specified, we use the values from the existing MIG.
        if not params['size']:
            params['size'] = mig.size

        if not params['template']:
            params['template'] = mig.template.name

        if params['template'] != mig.template.name:
            # Update Instance Template.
            new_template = gce.ex_get_instancetemplate(params['template'])
            mig.set_instancetemplate(new_template)
            json_output['updated_instancetemplate'] = True
            changed = True
        if params['recreate_instances'] is True:
            # Recreate Instances.
            (changed, json_output['recreated_instances']
             ) = recreate_instances_in_mig(mig)

        if params['size'] != mig.size:
            # Resize MIG.
            keystr = 'created' if params['size'] > mig.size else 'deleted'
            (changed, json_output['resize_%s_instances' %
                                  (keystr)]) = resize_mig(mig, params['size'])

        # Update Autoscaler
        if params['autoscaling']:
            autoscaler = get_autoscaler(gce, params['autoscaling']['name'],
                                        params['zone'])
            if not autoscaler:
                # Try to create autoscaler.
                # Note: this isn't perfect, if the autoscaler name has changed
                # we wouldn't know that here.
                if not create_autoscaler(gce, mig, params['autoscaling']):
                    module.fail_json(
                        msg='Unable to create autoscaler %s for existing MIG %s\
                        in zone: %s' % (params['autoscaling']['name'],
                                        params['name'], params['zone']),
                        changed=False)
                json_output['created_autoscaler'] = True
                changed = True
            else:
                if params['autoscaling']['enabled'] is False:
                    # Delete autoscaler
                    changed = delete_autoscaler(autoscaler)
                    json_output['delete_autoscaler'] = changed
                else:
                    # Update policy, etc.
                    changed = update_autoscaler(gce, autoscaler,
                                                params['autoscaling'])
                    json_output['updated_autoscaler'] = changed
        named_ports = params['named_ports'] or []
        json_output['updated_named_ports'] = update_named_ports(mig,
                                                                named_ports)
        if json_output['updated_named_ports']:
            json_output['named_ports'] = named_ports

    json_output['changed'] = changed
    json_output.update(params)
    module.exit_json(**json_output)
Beispiel #14
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            image=dict(default='debian-8'),
            image_family=dict(),
            external_projects=dict(type='list'),
            instance_names=dict(),
            machine_type=dict(default='n1-standard-1'),
            metadata=dict(),
            name=dict(aliases=['base_name']),
            num_instances=dict(type='int'),
            network=dict(default='default'),
            subnetwork=dict(),
            persistent_boot_disk=dict(type='bool', default=False),
            disks=dict(type='list'),
            state=dict(choices=['active', 'present', 'absent', 'deleted',
                                'started', 'stopped', 'terminated'],
                       default='present'),
            tags=dict(type='list'),
            zone=dict(default='us-central1-a'),
            service_account_email=dict(),
            service_account_permissions=dict(type='list'),
            pem_file=dict(type='path'),
            credentials_file=dict(type='path'),
            project_id=dict(),
            ip_forward=dict(type='bool', default=False),
            external_ip=dict(default='ephemeral'),
            disk_auto_delete=dict(type='bool', default=True),
            disk_size=dict(type='int', default=10),
            preemptible=dict(type='bool', default=None),
        ),
        mutually_exclusive=[('instance_names', 'name')]
    )

    if not HAS_PYTHON26:
        module.fail_json(msg="GCE module requires python's 'ast' module, python v2.6+")
    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud with GCE support (0.17.0+) required for this module')

    gce = gce_connect(module)

    image = module.params.get('image')
    image_family = module.params.get('image_family')
    external_projects = module.params.get('external_projects')
    instance_names = module.params.get('instance_names')
    name = module.params.get('name')
    number = module.params.get('num_instances')
    subnetwork = module.params.get('subnetwork')
    state = module.params.get('state')
    zone = module.params.get('zone')
    preemptible = module.params.get('preemptible')
    changed = False

    inames = None
    if isinstance(instance_names, list):
        inames = instance_names
    elif isinstance(instance_names, str):
        inames = instance_names.split(',')
    if name:
        inames = name
    if not inames:
        module.fail_json(msg='Must specify a "name" or "instance_names"',
                         changed=False)
    if not zone:
        module.fail_json(msg='Must specify a "zone"', changed=False)

    lc_zone = get_valid_location(module, gce, zone)
    if preemptible is not None and hasattr(libcloud, '__version__') and libcloud.__version__ < '0.20':
        module.fail_json(msg="Apache Libcloud 0.20.0+ is required to use 'preemptible' option",
                         changed=False)

    if subnetwork is not None and not hasattr(gce, 'ex_get_subnetwork'):
        module.fail_json(msg="Apache Libcloud 1.0.0+ is required to use 'subnetwork' option",
                         changed=False)

    json_output = {'zone': zone}
    if state in ['absent', 'deleted', 'started', 'stopped', 'terminated']:
        json_output['state'] = state
        (changed, state_instance_names) = change_instance_state(
            module, gce, inames, number, lc_zone, state)

        # based on what user specified, return the same variable, although
        # value could be different if an instance could not be destroyed
        if instance_names or name and number:
            json_output['instance_names'] = state_instance_names
        elif name:
            json_output['name'] = name

    elif state in ['active', 'present']:
        json_output['state'] = 'present'
        (changed, instance_data, instance_name_list) = create_instances(
            module, gce, inames, number, lc_zone)
        json_output['instance_data'] = instance_data
        if instance_names:
            json_output['instance_names'] = instance_name_list
        elif name:
            json_output['name'] = name

    json_output['changed'] = changed
    module.exit_json(**json_output)
Beispiel #15
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            instance_name=dict(required=False),
            instance_pattern=dict(required=False),
            tags=dict(type='list', required=True),
            state=dict(default='present', choices=['present', 'absent']),
            zone=dict(default='us-central1-a'),
            service_account_email=dict(),
            pem_file=dict(type='path'),
            project_id=dict(),
        ),
        mutually_exclusive=[
            [ 'instance_name', 'instance_pattern' ]
        ],
        required_one_of=[
            [ 'instance_name', 'instance_pattern' ]
        ]
    )

    instance_name = module.params.get('instance_name')
    instance_pattern = module.params.get('instance_pattern')
    state = module.params.get('state')
    tags = module.params.get('tags')
    zone = module.params.get('zone')
    changed = False

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

    gce = gce_connect(module)

    # Create list of nodes to operate on
    matching_nodes = []
    try:
        if instance_pattern:
            instances = gce.list_nodes(ex_zone=zone)
            # no instances in zone
            if not instances:
                module.exit_json(changed=False, tags=tags, zone=zone, instances_updated=[])
            try:
                # Python regex fully supported: https://docs.python.org/2/library/re.html
                p = re.compile(instance_pattern)
                matching_nodes = [i for i in instances if p.search(i.name) is not None]
            except re.error as e:
                module.fail_json(msg='Regex error for pattern %s: %s' % (instance_pattern, e), changed=False)
        else:
            matching_nodes = [gce.ex_get_node(instance_name, zone=zone)]
    except ResourceNotFoundError:
        module.fail_json(msg='Instance %s not found in zone %s' % (instance_name, zone), changed=False)
    except GoogleBaseError as e:
        module.fail_json(msg=str(e), changed=False, exception=traceback.format_exc())

    # Tag nodes
    instance_pattern_matches = []
    tags_changed = []
    for node in matching_nodes:
        changed, tags_changed = modify_tags(gce, module, node, tags, state)
        if changed:
            instance_pattern_matches.append({'instance_name': node.name, 'tags_changed': tags_changed})
    if instance_pattern:
        module.exit_json(changed=changed, instance_pattern=instance_pattern, tags=tags_changed, zone=zone, instances_updated=instance_pattern_matches)
    else:
        module.exit_json(changed=changed, instance_name=instance_name, tags=tags_changed, zone=zone)
Beispiel #16
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)
Beispiel #17
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)
Beispiel #18
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)
def main():
    module = AnsibleModule(
        argument_spec=dict(
            instance_name=dict(required=False),
            instance_pattern=dict(required=False),
            tags=dict(type='list', required=True),
            state=dict(default='present', choices=['present', 'absent']),
            zone=dict(default='us-central1-a'),
            service_account_email=dict(),
            pem_file=dict(type='path'),
            project_id=dict(),
        ),
        mutually_exclusive=[['instance_name', 'instance_pattern']],
        required_one_of=[['instance_name', 'instance_pattern']])

    instance_name = module.params.get('instance_name')
    instance_pattern = module.params.get('instance_pattern')
    state = module.params.get('state')
    tags = module.params.get('tags')
    zone = module.params.get('zone')
    changed = False

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

    gce = gce_connect(module)

    # Create list of nodes to operate on
    matching_nodes = []
    try:
        if instance_pattern:
            instances = gce.list_nodes(ex_zone=zone)
            # no instances in zone
            if not instances:
                module.exit_json(changed=False,
                                 tags=tags,
                                 zone=zone,
                                 instances_updated=[])
            try:
                # Python regex fully supported: https://docs.python.org/2/library/re.html
                p = re.compile(instance_pattern)
                matching_nodes = [
                    i for i in instances if p.search(i.name) is not None
                ]
            except re.error as e:
                module.fail_json(msg='Regex error for pattern %s: %s' %
                                 (instance_pattern, e),
                                 changed=False)
        else:
            matching_nodes = [gce.ex_get_node(instance_name, zone=zone)]
    except ResourceNotFoundError:
        module.fail_json(msg='Instance %s not found in zone %s' %
                         (instance_name, zone),
                         changed=False)
    except GoogleBaseError as e:
        module.fail_json(msg=str(e),
                         changed=False,
                         exception=traceback.format_exc())

    # Tag nodes
    instance_pattern_matches = []
    tags_changed = []
    for node in matching_nodes:
        changed, tags_changed = modify_tags(gce, module, node, tags, state)
        if changed:
            instance_pattern_matches.append({
                'instance_name': node.name,
                'tags_changed': tags_changed
            })
    if instance_pattern:
        module.exit_json(changed=changed,
                         instance_pattern=instance_pattern,
                         tags=tags_changed,
                         zone=zone,
                         instances_updated=instance_pattern_matches)
    else:
        module.exit_json(changed=changed,
                         instance_name=instance_name,
                         tags=tags_changed,
                         zone=zone)
Beispiel #20
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            instance_name=dict(required=True),
            snapshot_name=dict(required=True),
            state=dict(choices=['present', 'absent'], default='present'),
            disks=dict(default=None, type='list'),
            service_account_email=dict(type='str'),
            credentials_file=dict(type='path'),
            project_id=dict(type='str')
        )
    )

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

    gce = gce_connect(module)

    instance_name = module.params.get('instance_name')
    snapshot_name = module.params.get('snapshot_name')
    disks = module.params.get('disks')
    state = module.params.get('state')

    json_output = dict(
        changed=False,
        snapshots_created=[],
        snapshots_deleted=[],
        snapshots_existing=[],
        snapshots_absent=[]
    )

    snapshot = None

    instance = gce.ex_get_node(instance_name, 'all')
    instance_disks = instance.extra['disks']

    for instance_disk in instance_disks:
        disk_snapshot_name = snapshot_name
        device_name = instance_disk['deviceName']
        if disks is None or device_name in disks:
            volume_obj = gce.ex_get_volume(device_name)

            # If we have more than one disk to snapshot, prepend the disk name
            if len(instance_disks) > 1:
                disk_snapshot_name = device_name + "-" + disk_snapshot_name

            snapshot = find_snapshot(volume_obj, disk_snapshot_name)

            if snapshot and state == 'present':
                json_output['snapshots_existing'].append(disk_snapshot_name)

            elif snapshot and state == 'absent':
                snapshot.destroy()
                json_output['changed'] = True
                json_output['snapshots_deleted'].append(disk_snapshot_name)

            elif not snapshot and state == 'present':
                volume_obj.snapshot(disk_snapshot_name)
                json_output['changed'] = True
                json_output['snapshots_created'].append(disk_snapshot_name)

            elif not snapshot and state == 'absent':
                json_output['snapshots_absent'].append(disk_snapshot_name)

    module.exit_json(**json_output)
Beispiel #21
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            image=dict(default='debian-8'),
            image_family=dict(),
            external_projects=dict(type='list'),
            instance_names=dict(),
            machine_type=dict(default='n1-standard-1'),
            metadata=dict(),
            name=dict(aliases=['base_name']),
            num_instances=dict(type='int'),
            network=dict(default='default'),
            subnetwork=dict(),
            persistent_boot_disk=dict(type='bool', default=False),
            disks=dict(type='list'),
            state=dict(choices=['active', 'present', 'absent', 'deleted',
                                'started', 'stopped', 'terminated'],
                       default='present'),
            tags=dict(type='list'),
            zone=dict(default='us-central1-a'),
            service_account_email=dict(),
            service_account_permissions=dict(type='list'),
            pem_file=dict(type='path'),
            credentials_file=dict(type='path'),
            project_id=dict(),
            ip_forward=dict(type='bool', default=False),
            external_ip=dict(default='ephemeral'),
            disk_auto_delete=dict(type='bool', default=True),
            disk_size=dict(type='int', default=10),
            preemptible=dict(type='bool', default=None),
        ),
        mutually_exclusive=[('instance_names', 'name')]
    )

    if not HAS_PYTHON26:
        module.fail_json(msg="GCE module requires python's 'ast' module, python v2.6+")
    if not HAS_LIBCLOUD:
        module.fail_json(msg='libcloud with GCE support (0.17.0+) required for this module')

    gce = gce_connect(module)

    image = module.params.get('image')
    image_family = module.params.get('image_family')
    external_projects = module.params.get('external_projects')
    instance_names = module.params.get('instance_names')
    name = module.params.get('name')
    number = module.params.get('num_instances')
    subnetwork = module.params.get('subnetwork')
    state = module.params.get('state')
    zone = module.params.get('zone')
    preemptible = module.params.get('preemptible')
    changed = False

    inames = None
    if isinstance(instance_names, list):
        inames = instance_names
    elif isinstance(instance_names, str):
        inames = instance_names.split(',')
    if name:
        inames = name
    if not inames:
        module.fail_json(msg='Must specify a "name" or "instance_names"',
                         changed=False)
    if not zone:
        module.fail_json(msg='Must specify a "zone"', changed=False)

    lc_zone = get_valid_location(module, gce, zone)
    if preemptible is not None and hasattr(libcloud, '__version__') and libcloud.__version__ < '0.20':
        module.fail_json(msg="Apache Libcloud 0.20.0+ is required to use 'preemptible' option",
                         changed=False)

    if subnetwork is not None and not hasattr(gce, 'ex_get_subnetwork'):
        module.fail_json(msg="Apache Libcloud 1.0.0+ is required to use 'subnetwork' option",
                         changed=False)

    json_output = {'zone': zone}
    if state in ['absent', 'deleted', 'started', 'stopped', 'terminated']:
        json_output['state'] = state
        (changed, state_instance_names) = change_instance_state(
            module, gce, inames, number, lc_zone, state)

        # based on what user specified, return the same variable, although
        # value could be different if an instance could not be destroyed
        if instance_names or name and number:
            json_output['instance_names'] = state_instance_names
        elif name:
            json_output['name'] = name

    elif state in ['active', 'present']:
        json_output['state'] = 'present'
        (changed, instance_data, instance_name_list) = create_instances(
            module, gce, inames, number, lc_zone)
        json_output['instance_data'] = instance_data
        if instance_names:
            json_output['instance_names'] = instance_name_list
        elif name:
            json_output['name'] = name

    json_output['changed'] = changed
    module.exit_json(**json_output)
Beispiel #22
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)
Beispiel #23
0
def main():
    module = AnsibleModule(argument_spec=dict(
        backends=dict(type='list', required=True),
        backend_service_name=dict(required=True),
        healthchecks=dict(type='list', required=True),
        service_account_email=dict(),
        service_account_permissions=dict(type='list'),
        enable_cdn=dict(type='bool'),
        port_name=dict(type='str'),
        protocol=dict(type='str',
                      default='TCP',
                      choices=['HTTP', 'HTTPS', 'SSL', 'TCP']),
        timeout=dict(type='int'),
        state=dict(choices=['absent', 'present'], default='present'),
        pem_file=dict(),
        credentials_file=dict(),
        project_id=dict(),
    ), )

    if not HAS_PYTHON26:
        module.fail_json(
            msg="GCE module requires python's 'ast' module, python v2.6+")
    if not HAS_LIBCLOUD:
        module.fail_json(
            msg=
            'libcloud with GCE Backend Service support (1.3+) required for this module.'
        )

    gce = gce_connect(module)
    if not hasattr(gce, 'ex_create_instancegroupmanager'):
        module.fail_json(
            msg=
            'libcloud with GCE Backend Service support (1.3+) required for this module.',
            changed=False)

    params = {}
    params['state'] = module.params.get('state')
    params['backend_service_name'] = module.params.get('backend_service_name')
    params['backends'] = module.params.get('backends')
    params['healthchecks'] = module.params.get('healthchecks')
    params['enable_cdn'] = module.params.get('enable_cdn', None)
    params['port_name'] = module.params.get('port_name', None)
    params['protocol'] = module.params.get('protocol', None)
    params['timeout'] = module.params.get('timeout', None)

    try:
        _validate_params(params)
    except Exception as e:
        module.fail_json(msg=e.message, changed=False)

    changed = False
    json_output = {'state': params['state']}
    bes = get_backend_service(gce, params['backend_service_name'])

    if not bes:
        if params['state'] == 'absent':
            # Doesn't exist and state==absent.
            changed = False
            module.fail_json(msg="Cannot delete unknown backend service: %s" %
                             (params['backend_service_name']))
        else:
            # Create
            (changed,
             json_output['backend_service_created']) = create_backend_service(
                 gce, params)
    elif params['state'] == 'absent':
        # Delete
        (changed,
         json_output['backend_service_deleted']) = delete_backend_service(bes)
    else:
        # TODO(supertom): Add update support when it is available in libcloud.
        changed = False

    json_output['changed'] = changed
    json_output.update(params)
    module.exit_json(**json_output)
Beispiel #24
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)