Exemple #1
0
 def _get_instance(self):
     """Returns a boto.ec2.InstanceObject for self.instance_id"""
     try:
         ec2 = connect_to_aws(boto.ec2, self.region, **self.aws_connect_params)
     except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
         self.module.fail_json(msg=str(e))
     return ec2.get_only_instances(instance_ids=[self.instance_id])[0]
Exemple #2
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            filters=dict(default=None, type='dict')
        )
    )

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)
    if module._name == 'ec2_vpc_route_table_facts':
        module.deprecate("The 'ec2_vpc_route_table_facts' module has been renamed to 'ec2_vpc_route_table_info'", version='2.13')

    if not HAS_BOTO:
        module.fail_json(msg='boto required for this module')

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)

    if region:
        try:
            connection = connect_to_aws(boto.vpc, region, **aws_connect_params)
        except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
            module.fail_json(msg=str(e))
    else:
        module.fail_json(msg="region must be specified")

    list_ec2_vpc_route_tables(connection, module)
def main():
    module = AnsibleAWSModule(
        argument_spec={},
        supports_check_mode=True,
        check_boto3=False,
    )

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)
    if not region:
        module.fail_json(msg="Fail JSON: No Region")

    try:
        client = connect_to_aws(boto.ec2, region, **aws_connect_params)
    except boto.exception.NoAuthHandlerFound as e:
        module.fail_json_aws(e, msg='No Authentication Handler Found')
    except AnsibleAWSError as e:
        module.fail_json_aws(e, msg='Fail JSON AWS')

    filters = {'name': 'amzn2-ami-hvm-2.0.202006*-x86_64-gp2'}

    try:
        images = client.get_all_images(image_ids=[],
                                       filters=filters,
                                       owners=['amazon'],
                                       executable_by=[])
    except (boto.exception.BotoServerError, AnsibleAWSError) as e:
        module.fail_json_aws(e, msg='Fail JSON AWS')

    images_out = []
    for image in images:
        images_out.append(image.id)

    # Return something, just because we can.
    module.exit_json(changed=False, images=images_out)
Exemple #4
0
    def _get_auto_scaling_group_lbs(self):
        """Returns a list of ELBs associated with self.instance_id
           indirectly through its auto scaling group membership"""

        try:
            asg = connect_to_aws(boto.ec2.autoscale, self.region, **self.aws_connect_params)
        except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
            self.module.fail_json(msg=str(e))

        asg_instances = asg.get_all_autoscaling_instances([self.instance_id])
        if len(asg_instances) > 1:
            self.module.fail_json(msg="Illegal state, expected one auto scaling group instance.")

        if not asg_instances:
            asg_elbs = []
        else:
            asg_name = asg_instances[0].group_name

            asgs = asg.get_all_groups([asg_name])
            if len(asg_instances) != 1:
                self.module.fail_json(msg="Illegal state, expected one auto scaling group.")

            asg_elbs = asgs[0].load_balancers

        return asg_elbs
Exemple #5
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            name=dict(required=True, type='str'),
            adjustment_type=dict(type='str', choices=['ChangeInCapacity', 'ExactCapacity', 'PercentChangeInCapacity']),
            asg_name=dict(required=True, type='str'),
            scaling_adjustment=dict(type='int'),
            min_adjustment_step=dict(type='int'),
            cooldown=dict(type='int'),
            state=dict(default='present', choices=['present', 'absent']),
        )
    )

    module = AnsibleModule(argument_spec=argument_spec)

    if not HAS_BOTO:
        module.fail_json(msg='boto required for this module')

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)

    state = module.params.get('state')

    try:
        connection = connect_to_aws(boto.ec2.autoscale, region, **aws_connect_params)
    except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
        module.fail_json(msg=str(e))

    if state == 'present':
        create_scaling_policy(connection, module)
    elif state == 'absent':
        delete_scaling_policy(connection, module)
Exemple #6
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        state=dict(default='present', choices=['present', 'absent']),
        name=dict(required=True, type='str'),
        hash_key_name=dict(type='str'),
        hash_key_type=dict(default='STRING', type='str', choices=['STRING', 'NUMBER', 'BINARY']),
        range_key_name=dict(type='str'),
        range_key_type=dict(default='STRING', type='str', choices=['STRING', 'NUMBER', 'BINARY']),
        read_capacity=dict(default=1, type='int'),
        write_capacity=dict(default=1, type='int'),
        indexes=dict(default=[], type='list'),
        tags=dict(type='dict'),
        wait_for_active_timeout=dict(default=60, type='int'),
    ))

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True)

    if not HAS_BOTO:
        module.fail_json(msg='boto required for this module')

    if not HAS_BOTO3 and module.params.get('tags'):
        module.fail_json(msg='boto3 required when using tags for this module')

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)
    if not region:
        module.fail_json(msg='region must be specified')

    try:
        connection = connect_to_aws(boto.dynamodb2, region, **aws_connect_params)
    except (NoAuthHandlerFound, AnsibleAWSError) as e:
        module.fail_json(msg=str(e))

    if module.params.get('tags'):
        try:
            region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
            boto3_dynamodb = boto3_conn(module, conn_type='client', resource='dynamodb', region=region, endpoint=ec2_url, **aws_connect_kwargs)
            if not hasattr(boto3_dynamodb, 'tag_resource'):
                module.fail_json(msg='boto3 connection does not have tag_resource(), likely due to using an old version')
            boto3_sts = boto3_conn(module, conn_type='client', resource='sts', region=region, endpoint=ec2_url, **aws_connect_kwargs)
        except botocore.exceptions.NoCredentialsError as e:
            module.fail_json(msg='cannot connect to AWS', exception=traceback.format_exc())
    else:
        boto3_dynamodb = None
        boto3_sts = None

    state = module.params.get('state')
    if state == 'present':
        create_or_update_dynamo_table(connection, module, boto3_dynamodb, boto3_sts, region)
    elif state == 'absent':
        delete_dynamo_table(connection, module)
    def _get_instance_lbs(self, ec2_elbs=None):
        """Returns a list of ELBs attached to self.instance_id
        ec2_elbs: an optional list of elb names that will be used
                  for elb lookup instead of returning what elbs
                  are attached to self.instance_id"""

        if not ec2_elbs:
            ec2_elbs = self._get_auto_scaling_group_lbs()

        try:
            elb = connect_to_aws(boto.ec2.elb, self.region,
                                 **self.aws_connect_params)
        except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
            self.module.fail_json(msg=str(e))

        elbs = []
        marker = None
        while True:
            try:
                newelbs = elb.get_all_load_balancers(marker=marker)
                marker = newelbs.next_marker
                elbs.extend(newelbs)
                if not marker:
                    break
            except TypeError:
                # Older version of boto do not allow for params
                elbs = elb.get_all_load_balancers()
                break

        if ec2_elbs:
            lbs = sorted(lb for lb in elbs if lb.name in ec2_elbs)
        else:
            lbs = []
            for lb in elbs:
                for info in lb.instances:
                    if self.instance_id == info.id:
                        lbs.append(lb)
        return lbs
Exemple #8
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        state=dict(required=True, choices=['present', 'absent']),
        name=dict(required=True),
        description=dict(required=False),
        subnets=dict(required=False, type='list'),
    )
    )
    module = AnsibleModule(argument_spec=argument_spec)

    if not HAS_BOTO:
        module.fail_json(msg='boto required for this module')

    state = module.params.get('state')
    group_name = module.params.get('name').lower()
    group_description = module.params.get('description')
    group_subnets = module.params.get('subnets') or {}

    if state == 'present':
        for required in ['description', 'subnets']:
            if not module.params.get(required):
                module.fail_json(msg=str("Parameter %s required for state='present'" % required))
    else:
        for not_allowed in ['description', 'subnets']:
            if module.params.get(not_allowed):
                module.fail_json(msg=str("Parameter %s not allowed for state='absent'" % not_allowed))

    # Retrieve any AWS settings from the environment.
    region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module)

    if not region:
        module.fail_json(msg=str("Either region or AWS_REGION or EC2_REGION environment variable or boto config aws_region or ec2_region must be set."))

    try:
        conn = connect_to_aws(boto.rds, region, **aws_connect_kwargs)
    except BotoServerError as e:
        module.fail_json(msg=e.error_message)

    try:
        exists = False
        result = create_result(False)

        try:
            matching_groups = conn.get_all_db_subnet_groups(group_name, max_records=100)
            exists = len(matching_groups) > 0
        except BotoServerError as e:
            if e.error_code != 'DBSubnetGroupNotFoundFault':
                module.fail_json(msg=e.error_message)

        if state == 'absent':
            if exists:
                conn.delete_db_subnet_group(group_name)
                result = create_result(True)
        else:
            if not exists:
                new_group = conn.create_db_subnet_group(group_name, desc=group_description, subnet_ids=group_subnets)
                result = create_result(True, new_group)
            else:
                # Sort the subnet groups before we compare them
                matching_groups[0].subnet_ids.sort()
                group_subnets.sort()
                if (matching_groups[0].name != group_name or
                        matching_groups[0].description != group_description or
                        matching_groups[0].subnet_ids != group_subnets):
                    changed_group = conn.modify_db_subnet_group(group_name, description=group_description, subnet_ids=group_subnets)
                    result = create_result(True, changed_group)
                else:
                    result = create_result(False, matching_groups[0])
    except BotoServerError as e:
        module.fail_json(msg=e.error_message)

    module.exit_json(**result)
Exemple #9
0
 def _get_elb_connection(self):
     return connect_to_aws(boto.ec2.elb, self.region, **self.aws_connect_params)
Exemple #10
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(iam_type=dict(required=True, choices=['user', 'group', 'role']),
             groups=dict(type='list', default=None, required=False),
             state=dict(required=True, choices=['present', 'absent',
                                                'update']),
             password=dict(default=None, required=False, no_log=True),
             update_password=dict(default='always',
                                  required=False,
                                  choices=['always', 'on_create']),
             access_key_state=dict(default=None,
                                   required=False,
                                   choices=[
                                       'active', 'inactive', 'create',
                                       'remove', 'Active', 'Inactive',
                                       'Create', 'Remove'
                                   ]),
             access_key_ids=dict(type='list', default=None, required=False),
             key_count=dict(type='int', default=1, required=False),
             name=dict(required=True),
             trust_policy_filepath=dict(default=None, required=False),
             trust_policy=dict(type='dict', default=None, required=False),
             new_name=dict(default=None, required=False),
             path=dict(default='/', required=False),
             new_path=dict(default=None, required=False)))

    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive=[['trust_policy', 'trust_policy_filepath']],
    )

    if not HAS_BOTO:
        module.fail_json(msg='This module requires boto, please install it')

    state = module.params.get('state').lower()
    iam_type = module.params.get('iam_type').lower()
    groups = module.params.get('groups')
    name = module.params.get('name')
    new_name = module.params.get('new_name')
    password = module.params.get('password')
    update_pw = module.params.get('update_password')
    path = module.params.get('path')
    new_path = module.params.get('new_path')
    key_count = module.params.get('key_count')
    key_state = module.params.get('access_key_state')
    trust_policy = module.params.get('trust_policy')
    trust_policy_filepath = module.params.get('trust_policy_filepath')
    key_ids = module.params.get('access_key_ids')

    if key_state:
        key_state = key_state.lower()
        if any([n in key_state
                for n in ['active', 'inactive']]) and not key_ids:
            module.fail_json(
                changed=False,
                msg="At least one access key has to be defined in order"
                " to use 'active' or 'inactive'")

    if iam_type == 'user' and module.params.get('password') is not None:
        pwd = module.params.get('password')
    elif iam_type != 'user' and module.params.get('password') is not None:
        module.fail_json(msg="a password is being specified when the iam_type "
                         "is not user. Check parameters")
    else:
        pwd = None

    if iam_type != 'user' and (
            module.params.get('access_key_state') is not None
            or module.params.get('access_key_id') is not None):
        module.fail_json(msg="the IAM type must be user, when IAM access keys "
                         "are being modified. Check parameters")

    if iam_type == 'role' and state == 'update':
        module.fail_json(changed=False,
                         msg="iam_type: role, cannot currently be updated, "
                         "please specify present or absent")

    # check if trust_policy is present -- it can be inline JSON or a file path to a JSON file
    if trust_policy_filepath:
        try:
            with open(trust_policy_filepath, 'r') as json_data:
                trust_policy_doc = json.dumps(json.load(json_data))
        except Exception as e:
            module.fail_json(msg=str(e) + ': ' + trust_policy_filepath)
    elif trust_policy:
        try:
            trust_policy_doc = json.dumps(trust_policy)
        except Exception as e:
            module.fail_json(msg=str(e) + ': ' + trust_policy)
    else:
        trust_policy_doc = None

    region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module)

    try:
        if region:
            iam = connect_to_aws(boto.iam, region, **aws_connect_kwargs)
        else:
            iam = boto.iam.connection.IAMConnection(**aws_connect_kwargs)
    except boto.exception.NoAuthHandlerFound as e:
        module.fail_json(msg=str(e))

    result = {}
    changed = False

    try:
        orig_group_list = list_all_groups(iam)

        orig_user_list = list_all_users(iam)

        orig_role_list = list_all_roles(iam)

        orig_prof_list = list_all_instance_profiles(iam)
    except boto.exception.BotoServerError as err:
        module.fail_json(msg=err.message)

    if iam_type == 'user':
        been_updated = False
        user_groups = None
        user_exists = any([n in [name, new_name] for n in orig_user_list])
        if user_exists:
            current_path = iam.get_user(name).get_user_result.user['path']
            if not new_path and current_path != path:
                new_path = path
                path = current_path

        if state == 'present' and not user_exists and not new_name:
            (meta, changed) = create_user(module, iam, name, password, path,
                                          key_state, key_count)
            keys = iam.get_all_access_keys(name).list_access_keys_result.\
                access_key_metadata
            if groups:
                (user_groups,
                 changed) = set_users_groups(module, iam, name, groups,
                                             been_updated, new_name)
            module.exit_json(user_meta=meta,
                             groups=user_groups,
                             keys=keys,
                             changed=changed)

        elif state in ['present', 'update'] and user_exists:
            if update_pw == 'on_create':
                password = None
            if name not in orig_user_list and new_name in orig_user_list:
                been_updated = True
            name_change, key_list, user_changed, new_key = update_user(
                module, iam, name, new_name, new_path, key_state, key_count,
                key_ids, password, been_updated)
            if new_key:
                user_meta = {'access_keys': list(new_key)}
                user_meta['access_keys'].extend(
                    [{
                        'access_key_id': key,
                        'status': value
                    } for key, value in key_list.items()
                     if key not in [it['access_key_id'] for it in new_key]])
            else:
                user_meta = {
                    'access_keys': [{
                        'access_key_id': key,
                        'status': value
                    } for key, value in key_list.items()]
                }

            if name_change and new_name:
                orig_name = name
                name = new_name
            if isinstance(groups, list):
                user_groups, groups_changed = set_users_groups(
                    module, iam, name, groups, been_updated, new_name)
                if groups_changed == user_changed:
                    changed = groups_changed
                else:
                    changed = True
            else:
                changed = user_changed
            if new_name and new_path:
                module.exit_json(changed=changed,
                                 groups=user_groups,
                                 old_user_name=orig_name,
                                 new_user_name=new_name,
                                 old_path=path,
                                 new_path=new_path,
                                 keys=key_list,
                                 created_keys=new_key,
                                 user_meta=user_meta)
            elif new_name and not new_path and not been_updated:
                module.exit_json(changed=changed,
                                 groups=user_groups,
                                 old_user_name=orig_name,
                                 new_user_name=new_name,
                                 keys=key_list,
                                 created_keys=new_key,
                                 user_meta=user_meta)
            elif new_name and not new_path and been_updated:
                module.exit_json(changed=changed,
                                 groups=user_groups,
                                 user_name=new_name,
                                 keys=key_list,
                                 key_state=key_state,
                                 created_keys=new_key,
                                 user_meta=user_meta)
            elif not new_name and new_path:
                module.exit_json(changed=changed,
                                 groups=user_groups,
                                 user_name=name,
                                 old_path=path,
                                 new_path=new_path,
                                 keys=key_list,
                                 created_keys=new_key,
                                 user_meta=user_meta)
            else:
                module.exit_json(changed=changed,
                                 groups=user_groups,
                                 user_name=name,
                                 keys=key_list,
                                 created_keys=new_key,
                                 user_meta=user_meta)

        elif state == 'update' and not user_exists:
            module.fail_json(
                msg="The user %s does not exist. No update made." % name)

        elif state == 'absent':
            if user_exists:
                try:
                    set_users_groups(module, iam, name, '')
                    name, changed = delete_user(module, iam, name)
                    module.exit_json(deleted_user=name, changed=changed)

                except Exception as ex:
                    module.fail_json(changed=changed, msg=str(ex))
            else:
                module.exit_json(
                    changed=False,
                    msg="User %s is already absent from your AWS IAM users" %
                    name)

    elif iam_type == 'group':
        group_exists = name in orig_group_list

        if state == 'present' and not group_exists:
            new_group, changed = create_group(module=module,
                                              iam=iam,
                                              name=name,
                                              path=path)
            module.exit_json(changed=changed, group_name=new_group)
        elif state in ['present', 'update'] and group_exists:
            changed, updated_name, updated_path, cur_path = update_group(
                module=module,
                iam=iam,
                name=name,
                new_name=new_name,
                new_path=new_path)

            if new_path and new_name:
                module.exit_json(changed=changed,
                                 old_group_name=name,
                                 new_group_name=updated_name,
                                 old_path=cur_path,
                                 new_group_path=updated_path)

            if new_path and not new_name:
                module.exit_json(changed=changed,
                                 group_name=name,
                                 old_path=cur_path,
                                 new_group_path=updated_path)

            if not new_path and new_name:
                module.exit_json(changed=changed,
                                 old_group_name=name,
                                 new_group_name=updated_name,
                                 group_path=cur_path)

            if not new_path and not new_name:
                module.exit_json(changed=changed,
                                 group_name=name,
                                 group_path=cur_path)

        elif state == 'update' and not group_exists:
            module.fail_json(
                changed=changed,
                msg="Update Failed. Group %s doesn't seem to exist!" % name)

        elif state == 'absent':
            if name in orig_group_list:
                removed_group, changed = delete_group(module=module,
                                                      iam=iam,
                                                      name=name)
                module.exit_json(changed=changed, delete_group=removed_group)
            else:
                module.exit_json(changed=changed, msg="Group already absent")

    elif iam_type == 'role':
        role_list = []
        if state == 'present':
            changed, role_list, role_result, instance_profile_result = create_role(
                module, iam, name, path, orig_role_list, orig_prof_list,
                trust_policy_doc)
        elif state == 'absent':
            changed, role_list, role_result, instance_profile_result = delete_role(
                module, iam, name, orig_role_list, orig_prof_list)
        elif state == 'update':
            module.fail_json(
                changed=False,
                msg='Role update not currently supported by boto.')
        module.exit_json(changed=changed,
                         roles=role_list,
                         role_result=role_result,
                         instance_profile_result=instance_profile_result)
Exemple #11
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(state=dict(required=True, choices=['present', 'absent']),
             name=dict(required=True),
             cert=dict(),
             key=dict(no_log=True),
             cert_chain=dict(),
             new_name=dict(),
             path=dict(default='/'),
             new_path=dict(),
             dup_ok=dict(type='bool')))

    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive=[
            ['new_path', 'key'],
            ['new_path', 'cert'],
            ['new_path', 'cert_chain'],
            ['new_name', 'key'],
            ['new_name', 'cert'],
            ['new_name', 'cert_chain'],
        ],
    )

    if not HAS_BOTO:
        module.fail_json(msg="Boto is required for this module")

    region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module)

    try:
        if region:
            iam = connect_to_aws(boto.iam, region, **aws_connect_kwargs)
        else:
            iam = boto.iam.connection.IAMConnection(**aws_connect_kwargs)
    except boto.exception.NoAuthHandlerFound as e:
        module.fail_json(msg=str(e))

    state = module.params.get('state')
    name = module.params.get('name')
    path = module.params.get('path')
    new_name = module.params.get('new_name')
    new_path = module.params.get('new_path')
    dup_ok = module.params.get('dup_ok')
    if state == 'present' and not new_name and not new_path:
        cert, key, cert_chain = load_data(
            cert=module.params.get('cert'),
            key=module.params.get('key'),
            cert_chain=module.params.get('cert_chain'))
    else:
        cert = key = cert_chain = None

    orig_cert_names = [
        ctb['server_certificate_name'] for ctb in iam.get_all_server_certs().
        list_server_certificates_result.server_certificate_metadata_list
    ]
    orig_cert_bodies = [
        iam.get_server_certificate(
            thing).get_server_certificate_result.certificate_body
        for thing in orig_cert_names
    ]
    if new_name == name:
        new_name = None
    if new_path == path:
        new_path = None

    changed = False
    try:
        cert_action(module, iam, name, path, new_name, new_path, state, cert,
                    key, cert_chain, orig_cert_names, orig_cert_bodies, dup_ok)
    except boto.exception.BotoServerError as err:
        module.fail_json(changed=changed, msg=str(err), debug=[cert, key])
Exemple #12
0
def main():
    argument_spec = dict(
        instance=dict(),
        id=dict(),
        name=dict(),
        volume_size=dict(type='int'),
        volume_type=dict(choices=['standard', 'gp2', 'io1', 'st1', 'sc1'],
                         default='standard'),
        iops=dict(type='int'),
        encrypted=dict(type='bool', default=False),
        kms_key_id=dict(),
        device_name=dict(),
        delete_on_termination=dict(type='bool', default=False),
        zone=dict(aliases=['availability_zone', 'aws_zone', 'ec2_zone']),
        snapshot=dict(),
        state=dict(choices=['absent', 'present', 'list'], default='present'),
        tags=dict(type='dict', default={}))
    module = AnsibleAWSModule(argument_spec=argument_spec, check_boto3=False)

    if not HAS_BOTO:
        module.fail_json(msg='boto required for this module')

    id = module.params.get('id')
    name = module.params.get('name')
    instance = module.params.get('instance')
    volume_size = module.params.get('volume_size')
    encrypted = module.params.get('encrypted')
    kms_key_id = module.params.get('kms_key_id')
    device_name = module.params.get('device_name')
    zone = module.params.get('zone')
    snapshot = module.params.get('snapshot')
    state = module.params.get('state')
    tags = module.params.get('tags')

    # Ensure we have the zone or can get the zone
    if instance is None and zone is None and state == 'present':
        module.fail_json(msg="You must specify either instance or zone")

    # Set volume detach flag
    if instance == 'None' or instance == '':
        instance = None
        detach_vol_flag = True
    else:
        detach_vol_flag = False

    # Set changed flag
    changed = False

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)

    if region:
        try:
            ec2 = connect_to_aws(boto.ec2, region, **aws_connect_params)
        except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
            module.fail_json_aws(e)
    else:
        module.fail_json(msg="region must be specified")

    if state == 'list':
        returned_volumes = []
        vols = get_volumes(module, ec2)

        for v in vols:
            attachment = v.attach_data

            returned_volumes.append(get_volume_info(v, state))

        module.exit_json(changed=False, volumes=returned_volumes)

    if encrypted and not boto_supports_volume_encryption():
        module.fail_json(
            msg="You must use boto >= v2.29.0 to use encrypted volumes")

    if kms_key_id is not None and not boto_supports_kms_key_id():
        module.fail_json(msg="You must use boto >= v2.39.0 to use kms_key_id")

    # Here we need to get the zone info for the instance. This covers situation where
    # instance is specified but zone isn't.
    # Useful for playbooks chaining instance launch with volume create + attach and where the
    # zone doesn't matter to the user.
    inst = None
    if instance:
        try:
            reservation = ec2.get_all_instances(instance_ids=instance)
        except BotoServerError as e:
            module.fail_json_aws(e)
        inst = reservation[0].instances[0]
        zone = inst.placement

        # Check if there is a volume already mounted there.
        if device_name:
            if device_name in inst.block_device_mapping:
                module.exit_json(
                    msg="Volume mapping for %s already exists on instance %s" %
                    (device_name, instance),
                    volume_id=inst.block_device_mapping[device_name].volume_id,
                    device=device_name,
                    changed=False)

    # Delaying the checks until after the instance check allows us to get volume ids for existing volumes
    # without needing to pass an unused volume_size
    if not volume_size and not (id or name or snapshot):
        module.fail_json(
            msg=
            "You must specify volume_size or identify an existing volume by id, name, or snapshot"
        )

    if volume_size and id:
        module.fail_json(msg="Cannot specify volume_size together with id")

    if state == 'present':
        volume, changed = create_volume(module, ec2, zone)
        if detach_vol_flag:
            volume, changed = detach_volume(module, ec2, volume)
        elif inst is not None:
            volume, changed = attach_volume(module, ec2, volume, inst)

        # Add device, volume_id and volume_type parameters separately to maintain backward compatibility
        volume_info = get_volume_info(volume, state)

        # deleteOnTermination is not correctly reflected on attachment
        if module.params.get('delete_on_termination'):
            for attempt in range(0, 8):
                if volume_info['attachment_set'].get(
                        'deleteOnTermination') == 'true':
                    break
                time.sleep(5)
                volume = ec2.get_all_volumes(volume_ids=volume.id)[0]
                volume_info = get_volume_info(volume, state)
        module.exit_json(changed=changed,
                         volume=volume_info,
                         device=volume_info['attachment_set']['device'],
                         volume_id=volume_info['id'],
                         volume_type=volume_info['type'])
    elif state == 'absent':
        delete_volume(module, ec2)
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            state=dict(required=True, choices=['present', 'absent']),
            group_name=dict(required=True, aliases=['name']),
            group_description=dict(required=False, aliases=['description']),
            group_subnets=dict(required=False,
                               aliases=['subnets'],
                               type='list'),
        ))
    module = AnsibleModule(argument_spec=argument_spec)

    if not HAS_BOTO:
        module.fail_json(msg='boto v2.9.0+ required for this module')

    state = module.params.get('state')
    group_name = module.params.get('group_name')
    group_description = module.params.get('group_description')
    group_subnets = module.params.get('group_subnets')

    if state == 'present':
        for required in ('group_name', 'group_description', 'group_subnets'):
            if not module.params.get(required):
                module.fail_json(
                    msg=str("parameter %s required for state='present'" %
                            required))
    else:
        for not_allowed in ('group_description', 'group_subnets'):
            if module.params.get(not_allowed):
                module.fail_json(
                    msg=str("parameter %s not allowed for state='absent'" %
                            not_allowed))

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)
    if not region:
        module.fail_json(msg=str(
            "Region must be specified as a parameter, in EC2_REGION or AWS_REGION environment variables or in boto configuration file"
        ))

    # Connect to the Redshift endpoint.
    try:
        conn = connect_to_aws(boto.redshift, region, **aws_connect_params)
    except boto.exception.JSONResponseError as e:
        module.fail_json(msg=str(e))

    try:
        changed = False
        exists = False
        group = None

        try:
            matching_groups = conn.describe_cluster_subnet_groups(
                group_name, max_records=100)
            exists = len(matching_groups) > 0
        except boto.exception.JSONResponseError as e:
            if e.body['Error']['Code'] != 'ClusterSubnetGroupNotFoundFault':
                # if e.code != 'ClusterSubnetGroupNotFoundFault':
                module.fail_json(msg=str(e))

        if state == 'absent':
            if exists:
                conn.delete_cluster_subnet_group(group_name)
                changed = True

        else:
            if not exists:
                new_group = conn.create_cluster_subnet_group(
                    group_name, group_description, group_subnets)
                group = {
                    'name':
                    new_group['CreateClusterSubnetGroupResponse']
                    ['CreateClusterSubnetGroupResult']['ClusterSubnetGroup']
                    ['ClusterSubnetGroupName'],
                    'vpc_id':
                    new_group['CreateClusterSubnetGroupResponse']
                    ['CreateClusterSubnetGroupResult']['ClusterSubnetGroup']
                    ['VpcId'],
                }
            else:
                changed_group = conn.modify_cluster_subnet_group(
                    group_name, group_subnets, description=group_description)
                group = {
                    'name':
                    changed_group['ModifyClusterSubnetGroupResponse']
                    ['ModifyClusterSubnetGroupResult']['ClusterSubnetGroup']
                    ['ClusterSubnetGroupName'],
                    'vpc_id':
                    changed_group['ModifyClusterSubnetGroupResponse']
                    ['ModifyClusterSubnetGroupResult']['ClusterSubnetGroup']
                    ['VpcId'],
                }

            changed = True

    except boto.exception.JSONResponseError as e:
        module.fail_json(msg=str(e))

    module.exit_json(changed=changed, group=group)
Exemple #14
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        dhcp_options_id=dict(type='str', default=None),
        domain_name=dict(type='str', default=None),
        dns_servers=dict(type='list', default=None),
        ntp_servers=dict(type='list', default=None),
        netbios_name_servers=dict(type='list', default=None),
        netbios_node_type=dict(type='int', default=None),
        vpc_id=dict(type='str', default=None),
        delete_old=dict(type='bool', default=True),
        inherit_existing=dict(type='bool', default=False),
        tags=dict(type='dict', default=None, aliases=['resource_tags']),
        state=dict(type='str', default='present', choices=['present', 'absent'])
    )
    )

    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)

    params = module.params
    found = False
    changed = False
    new_options = collections.defaultdict(lambda: None)

    if not HAS_BOTO:
        module.fail_json(msg='boto is required for this module')

    region, ec2_url, boto_params = get_aws_connection_info(module)
    connection = connect_to_aws(boto.vpc, region, **boto_params)

    existing_options = None

    # First check if we were given a dhcp_options_id
    if not params['dhcp_options_id']:
        # No, so create new_options from the parameters
        if params['dns_servers'] is not None:
            new_options['domain-name-servers'] = params['dns_servers']
        if params['netbios_name_servers'] is not None:
            new_options['netbios-name-servers'] = params['netbios_name_servers']
        if params['ntp_servers'] is not None:
            new_options['ntp-servers'] = params['ntp_servers']
        if params['domain_name'] is not None:
            # needs to be a list for comparison with boto objects later
            new_options['domain-name'] = [params['domain_name']]
        if params['netbios_node_type'] is not None:
            # needs to be a list for comparison with boto objects later
            new_options['netbios-node-type'] = [str(params['netbios_node_type'])]
        # If we were given a vpc_id then we need to look at the options on that
        if params['vpc_id']:
            existing_options = fetch_dhcp_options_for_vpc(connection, params['vpc_id'])
            # if we've been asked to inherit existing options, do that now
            if params['inherit_existing']:
                if existing_options:
                    for option in ['domain-name-servers', 'netbios-name-servers', 'ntp-servers', 'domain-name', 'netbios-node-type']:
                        if existing_options.options.get(option) and new_options[option] != [] and (not new_options[option] or [''] == new_options[option]):
                            new_options[option] = existing_options.options.get(option)

            # Do the vpc's dhcp options already match what we're asked for? if so we are done
            if existing_options and new_options == existing_options.options:
                module.exit_json(changed=changed, new_options=new_options, dhcp_options_id=existing_options.id)

        # If no vpc_id was given, or the options don't match then look for an existing set using tags
        found, dhcp_option = match_dhcp_options(connection, params['tags'], new_options)

    # Now let's cover the case where there are existing options that we were told about by id
    # If a dhcp_options_id was supplied we don't look at options inside, just set tags (if given)
    else:
        supplied_options = connection.get_all_dhcp_options(filters={'dhcp-options-id': params['dhcp_options_id']})
        if len(supplied_options) != 1:
            if params['state'] != 'absent':
                module.fail_json(msg=" a dhcp_options_id was supplied, but does not exist")
        else:
            found = True
            dhcp_option = supplied_options[0]
            if params['state'] != 'absent' and params['tags']:
                ensure_tags(module, connection, dhcp_option.id, params['tags'], False, module.check_mode)

    # Now we have the dhcp options set, let's do the necessary

    # if we found options we were asked to remove then try to do so
    if params['state'] == 'absent':
        if not module.check_mode:
            if found:
                changed = remove_dhcp_options_by_id(connection, dhcp_option.id)
        module.exit_json(changed=changed, new_options={})

    # otherwise if we haven't found the required options we have something to do
    elif not module.check_mode and not found:

        # create some dhcp options if we weren't able to use existing ones
        if not found:
            # Convert netbios-node-type and domain-name back to strings
            if new_options['netbios-node-type']:
                new_options['netbios-node-type'] = new_options['netbios-node-type'][0]
            if new_options['domain-name']:
                new_options['domain-name'] = new_options['domain-name'][0]

            # create the new dhcp options set requested
            dhcp_option = connection.create_dhcp_options(
                new_options['domain-name'],
                new_options['domain-name-servers'],
                new_options['ntp-servers'],
                new_options['netbios-name-servers'],
                new_options['netbios-node-type'])

            # wait for dhcp option to be accessible
            found_dhcp_opt = False
            start_time = time()
            try:
                found_dhcp_opt = retry_not_found(connection.get_all_dhcp_options, dhcp_options_ids=[dhcp_option.id])
            except EC2ResponseError as e:
                module.fail_json(msg="Failed to describe DHCP options", exception=traceback.format_exc)
            if not found_dhcp_opt:
                module.fail_json(msg="Failed to wait for {0} to be available.".format(dhcp_option.id))

            changed = True
            if params['tags']:
                ensure_tags(module, connection, dhcp_option.id, params['tags'], False, module.check_mode)

    # If we were given a vpc_id, then attach the options we now have to that before we finish
    if params['vpc_id'] and not module.check_mode:
        changed = True
        connection.associate_dhcp_options(dhcp_option.id, params['vpc_id'])
        # and remove old ones if that was requested
        if params['delete_old'] and existing_options:
            remove_dhcp_options_by_id(connection, existing_options.id)

    module.exit_json(changed=changed, new_options=new_options, dhcp_options_id=dhcp_option.id)
Exemple #15
0
def main():
    argument_spec = dict(eni_id=dict(default=None, type='str'),
                         instance_id=dict(default=None, type='str'),
                         private_ip_address=dict(type='str'),
                         subnet_id=dict(type='str'),
                         description=dict(type='str'),
                         security_groups=dict(default=[], type='list'),
                         device_index=dict(default=0, type='int'),
                         state=dict(default='present',
                                    choices=['present', 'absent']),
                         force_detach=dict(default='no', type='bool'),
                         source_dest_check=dict(default=None, type='bool'),
                         delete_on_termination=dict(default=None, type='bool'),
                         secondary_private_ip_addresses=dict(default=None,
                                                             type='list'),
                         purge_secondary_private_ip_addresses=dict(
                             default=False, type='bool'),
                         secondary_private_ip_address_count=dict(default=None,
                                                                 type='int'),
                         allow_reassignment=dict(default=False, type='bool'),
                         attached=dict(default=None, type='bool'))

    module = AnsibleAWSModule(argument_spec=argument_spec,
                              check_boto3=False,
                              mutually_exclusive=[[
                                  'secondary_private_ip_addresses',
                                  'secondary_private_ip_address_count'
                              ]],
                              required_if=([
                                  ('state', 'absent', ['eni_id']),
                                  ('attached', True, ['instance_id']),
                                  ('purge_secondary_private_ip_addresses',
                                   True, ['secondary_private_ip_addresses'])
                              ]))

    if not HAS_BOTO:
        module.fail_json(msg='boto required for this module')

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)

    if region:
        try:
            connection = connect_to_aws(boto.ec2, region, **aws_connect_params)
            vpc_connection = connect_to_aws(boto.vpc, region,
                                            **aws_connect_params)
        except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
            module.fail_json_aws(e)
    else:
        module.fail_json(msg="region must be specified")

    state = module.params.get("state")

    if state == 'present':
        eni = uniquely_find_eni(connection, module)
        if eni is None:
            subnet_id = module.params.get("subnet_id")
            if subnet_id is None:
                module.fail_json(
                    msg="subnet_id is required when creating a new ENI")

            vpc_id = _get_vpc_id(vpc_connection, module, subnet_id)
            create_eni(connection, vpc_id, module)
        else:
            vpc_id = eni.vpc_id
            modify_eni(connection, vpc_id, module, eni)

    elif state == 'absent':
        delete_eni(connection, module)