def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        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'),
             secondary_private_ip_address_count=dict(default=None, type='int'),
             attached=dict(default=None, type='bool')))

    module = AnsibleModule(argument_spec=argument_spec,
                           mutually_exclusive=[[
                               'secondary_private_ip_addresses',
                               'secondary_private_ip_address_count'
                           ]],
                           required_if=([('state', 'absent', ['eni_id']),
                                         ('attached', True, ['instance_id'])]))

    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(msg=str(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)
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)
Esempio n. 3
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            filters = dict(default=None, type='dict')
        )
    )

    module = AnsibleModule(argument_spec=argument_spec)

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

    if HAS_BOTO3:
        region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True)

        if region:
            connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params)
        else:
            module.fail_json(msg="region must be specified")

        list_ec2_eni_boto3(connection, module)
    else:
        region, ec2_url, aws_connect_params = get_aws_connection_info(module)

        if region:
            try:
                connection = connect_to_aws(boto.ec2, 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_eni(connection, module)
Esempio n. 4
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            role_arn = dict(required=True, default=None),
            role_session_name = dict(required=True, default=None),
            duration_seconds = dict(required=False, default=None, type='int'),
            external_id = dict(required=False, default=None),
            policy = dict(required=False, default=None),
            mfa_serial_number = dict(required=False, default=None),
            mfa_token = dict(required=False, default=None)
        )
    )

    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)

    if region:
        try:
            connection = connect_to_aws(boto.sts, 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")

    try:
        assume_role_policy(connection, module)
    except BotoServerError as e:
        module.fail_json(msg=e)
Esempio n. 5
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(required=True, 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'),
    ))

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

    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 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))

    state = module.params.get('state')
    if state == 'present':
        create_or_update_dynamo_table(connection, module)
    elif state == 'absent':
        delete_dynamo_table(connection, module)
Esempio n. 6
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            filters = dict(default=None, type='dict')
        )
    )

    module = AnsibleModule(argument_spec=argument_spec)

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

    if HAS_BOTO3:
        region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True)

        if region:
            connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params)
        else:
            module.fail_json(msg="region must be specified")

        list_ec2_snapshots_boto3(connection, module)
    else:
        region, ec2_url, aws_connect_params = get_aws_connection_info(module)

        if region:
            try:
                connection = connect_to_aws(boto.ec2, 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_eni(connection, module)
Esempio n. 7
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(required=True, 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'),
    ))

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

    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 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))

    state = module.params.get('state')
    if state == 'present':
        create_or_update_dynamo_table(connection, module)
    elif state == 'absent':
        delete_dynamo_table(connection, module)
Esempio n. 8
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 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)
        except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
            module.fail_json(msg=str(e))
    else:
        module.fail_json(msg="region must be specified")

    list_ec2_instances(connection, module)
Esempio n. 9
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
Esempio n. 10
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]
Esempio n. 11
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 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)
        except (boto.exception.NoAuthHandlerFound, AnsibleAWSError) as e:
            module.fail_json(msg=str(e))
    else:
        module.fail_json(msg="region must be specified")

    list_ec2_instances(connection, module)
Esempio n. 12
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)
Esempio n. 13
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)
Esempio n. 14
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
Esempio n. 15
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]
Esempio n. 16
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(role_arn=dict(required=True, default=None),
             role_session_name=dict(required=True, default=None),
             duration_seconds=dict(required=False, default=None, type='int'),
             external_id=dict(required=False, default=None),
             policy=dict(required=False, default=None),
             mfa_serial_number=dict(required=False, default=None),
             mfa_token=dict(required=False, default=None)))

    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)

    if region:
        try:
            connection = connect_to_aws(boto.sts, 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")

    try:
        assume_role_policy(connection, module)
    except BotoServerError as e:
        module.fail_json(msg=e)
Esempio n. 17
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            name=dict(required=True, type='str'),
            metric=dict(type='str'),
            namespace=dict(type='str'),
            statistic=dict(type='str',
                           choices=[
                               'SampleCount', 'Average', 'Sum', 'Minimum',
                               'Maximum'
                           ]),
            comparison=dict(type='str', choices=['<=', '<', '>', '>=']),
            threshold=dict(type='float'),
            period=dict(type='int'),
            unit=dict(type='str',
                      choices=[
                          'Seconds', 'Microseconds', 'Milliseconds', 'Bytes',
                          'Kilobytes', 'Megabytes', 'Gigabytes', 'Terabytes',
                          'Bits', 'Kilobits', 'Megabits', 'Gigabits',
                          'Terabits', 'Percent', 'Count', 'Bytes/Second',
                          'Kilobytes/Second', 'Megabytes/Second',
                          'Gigabytes/Second', 'Terabytes/Second',
                          'Bits/Second', 'Kilobits/Second', 'Megabits/Second',
                          'Gigabits/Second', 'Terabits/Second', 'Count/Second',
                          'None'
                      ]),
            evaluation_periods=dict(type='int'),
            description=dict(type='str'),
            dimensions=dict(type='dict', default={}),
            alarm_actions=dict(type='list'),
            insufficient_data_actions=dict(type='list'),
            ok_actions=dict(type='list'),
            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')

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

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)

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

    if state == 'present':
        create_metric_alarm(connection, module)
    elif state == 'absent':
        delete_metric_alarm(connection, module)
Esempio n. 18
0
    def __init__(self, module, region=None, **aws_connect_params):
        self.module = module
        self.region = region
        self.aws_connect_params = aws_connect_params
        self.changed = False

        try:
            self.conn = connect_to_aws(boto.cloudtrail, self.region, **self.aws_connect_params)
        except boto.exception.NoAuthHandlerFound as e:
            self.module.fail_json(msg=str(e))
Esempio n. 19
0
    def __init__(self, module, region=None, **aws_connect_params):
        self.module = module
        self.region = region
        self.aws_connect_params = aws_connect_params
        self.changed = False

        try:
            self.conn = connect_to_aws(boto.cloudtrail, self.region, **self.aws_connect_params)
        except boto.exception.NoAuthHandlerFound as e:
            self.module.fail_json(msg=str(e))
Esempio n. 20
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(lookup=dict(default='tag', required=False, choices=['tag', 'id']),
             propagating_vgw_ids=dict(default=None,
                                      required=False,
                                      type='list'),
             purge_routes=dict(default=True, type='bool'),
             purge_subnets=dict(default=True, type='bool'),
             route_table_id=dict(default=None, required=False),
             routes=dict(default=[], required=False, type='list'),
             state=dict(default='present', choices=['present', 'absent']),
             subnets=dict(default=None, required=False, type='list'),
             tags=dict(default=None,
                       required=False,
                       type='dict',
                       aliases=['resource_tags']),
             vpc_id=dict(default=None, required=True)))

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

    if not HAS_BOTO:
        module.fail_json(msg='boto is 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")

    lookup = module.params.get('lookup')
    route_table_id = module.params.get('route_table_id')
    state = module.params.get('state', 'present')

    if lookup == 'id' and route_table_id is None:
        module.fail_json(
            msg="You must specify route_table_id if lookup is set to id")

    try:
        if state == 'present':
            result = ensure_route_table_present(connection, module)
        elif state == 'absent':
            result = ensure_route_table_absent(connection, module)
    except AnsibleRouteTableException as e:
        if e.error_traceback:
            module.fail_json(msg=e.message, exception=e.error_traceback)
        module.fail_json(msg=e.message)

    module.exit_json(**result)
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            cidr_block=dict(),
            instance_tenancy=dict(choices=['default', 'dedicated'],
                                  default='default'),
            wait=dict(type='bool', default=False),
            wait_timeout=dict(default=300),
            dns_support=dict(type='bool', default=True),
            dns_hostnames=dict(type='bool', default=True),
            subnets=dict(type='list'),
            vpc_id=dict(),
            internet_gateway=dict(type='bool', default=False),
            resource_tags=dict(type='dict', required=True),
            route_tables=dict(type='list'),
            state=dict(choices=['present', 'absent'], default='present'),
        ))

    module = AnsibleModule(argument_spec=argument_spec, )

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

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

    region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module)

    # If we have a region specified, connect to its endpoint.
    if region:
        try:
            vpc_conn = connect_to_aws(boto.vpc, region, **aws_connect_kwargs)
        except boto.exception.NoAuthHandlerFound as e:
            module.fail_json(msg=str(e))
    else:
        module.fail_json(msg="region must be specified")

    igw_id = None
    if module.params.get('state') == 'absent':
        vpc_id = module.params.get('vpc_id')
        cidr = module.params.get('cidr_block')
        (changed, vpc_dict,
         new_vpc_id) = terminate_vpc(module, vpc_conn, vpc_id, cidr)
        subnets_changed = None
    elif module.params.get('state') == 'present':
        # Changed is always set to true when provisioning a new VPC
        (vpc_dict, new_vpc_id, subnets_changed, igw_id,
         changed) = create_vpc(module, vpc_conn)

    module.exit_json(changed=changed,
                     vpc_id=new_vpc_id,
                     vpc=vpc_dict,
                     igw_id=igw_id,
                     subnets=subnets_changed)
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(vpc_id=dict(required=True),
             state=dict(default='present', choices=['present', 'absent']),
             tags=dict(default=dict(),
                       required=False,
                       type='dict',
                       aliases=['resource_tags'])))

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

    if not HAS_BOTO:
        module.fail_json(msg='boto is 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")

    vpc_id = module.params.get('vpc_id')
    state = module.params.get('state', 'present')
    tags = module.params.get('tags')

    nonstring_tags = [
        k for k, v in tags.items() if not isinstance(v, string_types)
    ]
    if nonstring_tags:
        module.fail_json(msg='One or more tags contain non-string values: {0}'.
                         format(nonstring_tags))

    try:
        if state == 'present':
            result = ensure_igw_present(connection,
                                        vpc_id,
                                        tags,
                                        check_mode=module.check_mode)
        elif state == 'absent':
            result = ensure_igw_absent(connection,
                                       vpc_id,
                                       check_mode=module.check_mode)
    except AnsibleIGWException as e:
        module.fail_json(msg=str(e))

    module.exit_json(changed=result['changed'], **result.get('gateway', {}))
Esempio n. 23
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(required=True, 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(e))
    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)
    elif state == 'absent':
        delete_dynamo_table(connection, module)
Esempio n. 24
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(e))
    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)
Esempio n. 25
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(az=dict(default=None, required=False),
             cidr=dict(default=None, required=True),
             state=dict(default='present', choices=['present', 'absent']),
             tags=dict(default=None,
                       required=False,
                       type='dict',
                       aliases=['resource_tags']),
             vpc_id=dict(default=None, required=True)))

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

    if not HAS_BOTO:
        module.fail_json(msg='boto is 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")

    vpc_id = module.params.get('vpc_id')
    tags = module.params.get('tags')
    cidr = module.params.get('cidr')
    az = module.params.get('az')
    state = module.params.get('state')

    try:
        if state == 'present':
            result = ensure_subnet_present(connection,
                                           vpc_id,
                                           cidr,
                                           az,
                                           tags,
                                           check_mode=module.check_mode)
        elif state == 'absent':
            result = ensure_subnet_absent(connection,
                                          vpc_id,
                                          cidr,
                                          check_mode=module.check_mode)
    except AnsibleVPCSubnetException as e:
        module.fail_json(msg=str(e))

    module.exit_json(**result)
Esempio n. 26
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            lookup=dict(default='tag', required=False, choices=['tag', 'id']),
            propagating_vgw_ids=dict(default=None, required=False, type='list'),
            purge_routes=dict(default=True, type='bool'),
            purge_subnets=dict(default=True, type='bool'),
            route_table_id=dict(default=None, required=False),
            routes=dict(default=[], required=False, type='list'),
            state=dict(default='present', choices=['present', 'absent']),
            subnets=dict(default=None, required=False, type='list'),
            tags=dict(default=None, required=False, type='dict', aliases=['resource_tags']),
            vpc_id=dict(default=None, required=True)
        )
    )

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

    if not HAS_BOTO:
        module.fail_json(msg='boto is 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")

    lookup = module.params.get('lookup')
    route_table_id = module.params.get('route_table_id')
    state = module.params.get('state', 'present')

    if lookup == 'id' and route_table_id is None:
        module.fail_json(msg="You must specify route_table_id if lookup is set to id")

    try:
        if state == 'present':
            result = ensure_route_table_present(connection, module)
        elif state == 'absent':
            result = ensure_route_table_absent(connection, module)
    except AnsibleRouteTableException as e:
        if e.error_traceback:
            module.fail_json(msg=e.message, exception=e.error_traceback)
        module.fail_json(msg=e.message)

    module.exit_json(**result)
Esempio n. 27
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            name=dict(required=True, type='str'),
            image_id=dict(type='str'),
            key_name=dict(type='str'),
            security_groups=dict(type='list'),
            user_data=dict(type='str'),
            user_data_path=dict(type='path'),
            kernel_id=dict(type='str'),
            volumes=dict(type='list'),
            instance_type=dict(type='str'),
            state=dict(default='present', choices=['present', 'absent']),
            spot_price=dict(type='float'),
            ramdisk_id=dict(type='str'),
            instance_profile_name=dict(type='str'),
            ebs_optimized=dict(default=False, type='bool'),
            associate_public_ip_address=dict(type='bool'),
            instance_monitoring=dict(default=False, type='bool'),
            assign_public_ip=dict(type='bool'),
            classic_link_vpc_security_groups=dict(type='list'),
            classic_link_vpc_id=dict(type='str'),
            vpc_id=dict(type='str')
        )
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive = [['user_data', 'user_data_path']]
    )

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

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)

    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))

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

    if state == 'present':
        create_launch_config(connection, module)
    elif state == 'absent':
        delete_launch_config(connection, module)
Esempio n. 28
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            name=dict(required=True, type='str'),
            metric=dict(type='str'),
            namespace=dict(type='str'),
            statistic=dict(type='str', choices=['SampleCount', 'Average', 'Sum', 'Minimum', 'Maximum']),
            comparison=dict(type='str', choices=['<=', '<', '>', '>=']),
            threshold=dict(type='float'),
            period=dict(type='int'),
            unit=dict(type='str', choices=['Seconds', 'Microseconds', 'Milliseconds', 'Bytes', 'Kilobytes', 'Megabytes', 'Gigabytes', 'Terabytes',
                                           'Bits', 'Kilobits', 'Megabits', 'Gigabits', 'Terabits', 'Percent', 'Count', 'Bytes/Second', 'Kilobytes/Second',
                                           'Megabytes/Second', 'Gigabytes/Second', 'Terabytes/Second', 'Bits/Second', 'Kilobits/Second', 'Megabits/Second',
                                           'Gigabits/Second', 'Terabits/Second', 'Count/Second', 'None']),
            evaluation_periods=dict(type='int'),
            description=dict(type='str'),
            dimensions=dict(type='dict', default={}),
            alarm_actions=dict(type='list'),
            insufficient_data_actions=dict(type='list'),
            ok_actions=dict(type='list'),
            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')

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

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)

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

    if state == 'present':
        create_metric_alarm(connection, module)
    elif state == 'absent':
        delete_metric_alarm(connection, module)
Esempio n. 29
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            vpc_id=dict(required=True),
            state=dict(default='present', choices=['present', 'absent']),
            tags=dict(default=dict(), required=False, type='dict', aliases=['resource_tags'])
        )
    )

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

    if not HAS_BOTO:
        module.fail_json(msg='boto is 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")

    vpc_id = module.params.get('vpc_id')
    state = module.params.get('state', 'present')
    tags = module.params.get('tags')

    nonstring_tags = [k for k, v in tags.items() if not isinstance(v, string_types)]
    if nonstring_tags:
        module.fail_json(msg='One or more tags contain non-string values: {0}'.format(nonstring_tags))

    try:
        if state == 'present':
            result = ensure_igw_present(connection, vpc_id, tags, check_mode=module.check_mode)
        elif state == 'absent':
            result = ensure_igw_absent(connection, vpc_id, check_mode=module.check_mode)
    except AnsibleIGWException as e:
        module.fail_json(msg=str(e))

    module.exit_json(changed=result['changed'], **result.get('gateway', {}))
Esempio n. 30
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            az = dict(default=None, required=False),
            cidr = dict(default=None, required=True),
            state = dict(default='present', choices=['present', 'absent']),
            tags = dict(default=None, required=False, type='dict', aliases=['resource_tags']),
            vpc_id = dict(default=None, required=True)
        )
    )

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

    if not HAS_BOTO:
        module.fail_json(msg='boto is 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")

    vpc_id = module.params.get('vpc_id')
    tags = module.params.get('tags')
    cidr = module.params.get('cidr')
    az = module.params.get('az')
    state = module.params.get('state')

    try:
        if state == 'present':
            result = ensure_subnet_present(connection, vpc_id, cidr, az, tags,
                                           check_mode=module.check_mode)
        elif state == 'absent':
            result = ensure_subnet_absent(connection, vpc_id, cidr,
                                          check_mode=module.check_mode)
    except AnsibleVPCSubnetException as e:
        module.fail_json(msg=str(e))

    module.exit_json(**result)
Esempio n. 31
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(filters=dict(default=None, type='dict')))

    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)

    if region:
        try:
            connection = connect_to_aws(boto.ec2, region, **aws_connect_params)
        except (boto.exception.NoAuthHandlerFound, Exception) as e:
            module.fail_json(msg=to_native(e),
                             exception=traceback.format_exc())
    else:
        module.fail_json(msg="region must be specified")

    list_ec2_volumes(connection, module)
Esempio n. 32
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(vpc_id=dict(required=True),
             state=dict(default='present', choices=['present', 'absent'])))

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

    if not HAS_BOTO:
        module.fail_json(msg='boto is 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")

    vpc_id = module.params.get('vpc_id')
    state = module.params.get('state', 'present')

    try:
        if state == 'present':
            result = ensure_igw_present(connection,
                                        vpc_id,
                                        check_mode=module.check_mode)
        elif state == 'absent':
            result = ensure_igw_absent(connection,
                                       vpc_id,
                                       check_mode=module.check_mode)
    except AnsibleIGWException as e:
        module.fail_json(msg=str(e))

    module.exit_json(**result)
Esempio n. 33
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            vpc_id = dict(required=True),
            state = dict(default='present', choices=['present', 'absent'])
        )
    )

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

    if not HAS_BOTO:
        module.fail_json(msg='boto is 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")

    vpc_id = module.params.get('vpc_id')
    state = module.params.get('state', 'present')

    try:
        if state == 'present':
            result = ensure_igw_present(connection, vpc_id, check_mode=module.check_mode)
        elif state == 'absent':
            result = ensure_igw_absent(connection, vpc_id, check_mode=module.check_mode)
    except AnsibleIGWException as e:
        module.fail_json(msg=str(e))

    module.exit_json(**result)
Esempio n. 34
0
    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
Esempio n. 35
0
    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
Esempio n. 36
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'),
        default_visibility_timeout=dict(type='int'),
        message_retention_period=dict(type='int'),
        maximum_message_size=dict(type='int'),
        delivery_delay=dict(type='int'),
        receive_message_wait_time=dict(type='int'),
        policy=dict(type='dict', required=False),
        redrive_policy=dict(type='dict', required=False),
    ))

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

    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 not region:
        module.fail_json(msg='region must be specified')

    try:
        connection = connect_to_aws(boto.sqs, region, **aws_connect_params)

    except (NoAuthHandlerFound, AnsibleAWSError) as e:
        module.fail_json(msg=str(e))

    state = module.params.get('state')
    if state == 'present':
        create_or_update_sqs_queue(connection, module)
    elif state == 'absent':
        delete_sqs_queue(connection, module)
Esempio n. 37
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            filters = dict(default=None, type='dict')
        )
    )

    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)

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

    list_ec2_vpcs(connection, module)
Esempio n. 38
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'),
        default_visibility_timeout=dict(type='int'),
        message_retention_period=dict(type='int'),
        maximum_message_size=dict(type='int'),
        delivery_delay=dict(type='int'),
        receive_message_wait_time=dict(type='int'),
        policy=dict(type='dict', required=False),
        redrive_policy=dict(type='dict', required=False),
    ))

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

    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 not region:
        module.fail_json(msg='region must be specified')

    try:
        connection = connect_to_aws(boto.sqs, region, **aws_connect_params)

    except (NoAuthHandlerFound, AnsibleAWSError) as e:
        module.fail_json(msg=str(e))

    state = module.params.get('state')
    if state == 'present':
        create_or_update_sqs_queue(connection, module)
    elif state == 'absent':
        delete_sqs_queue(connection, module)
Esempio n. 39
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            msg=dict(type='str', required=True, aliases=['default']),
            subject=dict(type='str', default=None),
            topic=dict(type='str', required=True),
            email=dict(type='str', default=None),
            sqs=dict(type='str', default=None),
            sms=dict(type='str', default=None),
            http=dict(type='str', default=None),
            https=dict(type='str', default=None),
        ))

    module = AnsibleModule(argument_spec=argument_spec)

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

    msg = module.params['msg']
    subject = module.params['subject']
    topic = module.params['topic']
    email = module.params['email']
    sqs = module.params['sqs']
    sms = module.params['sms']
    http = module.params['http']
    https = module.params['https']

    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.sns, region, **aws_connect_params)
    except boto.exception.NoAuthHandlerFound:
        e = get_exception()
        module.fail_json(msg=str(e))

    # .publish() takes full ARN topic id, but I'm lazy and type shortnames
    # so do a lookup (topics cannot contain ':', so thats the decider)
    if ':' in topic:
        arn_topic = topic
    else:
        arn_topic = arn_topic_lookup(connection, topic)

    if not arn_topic:
        module.fail_json(msg='Could not find topic: {}'.format(topic))

    dict_msg = {'default': msg}
    if email:
        dict_msg.update(email=email)
    if sqs:
        dict_msg.update(sqs=sqs)
    if sms:
        dict_msg.update(sms=sms)
    if http:
        dict_msg.update(http=http)
    if https:
        dict_msg.update(https=https)

    json_msg = json.dumps(dict_msg)
    try:
        connection.publish(topic=arn_topic,
                           subject=subject,
                           message_structure='json',
                           message=json_msg)
    except boto.exception.BotoServerError:
        e = get_exception()
        module.fail_json(msg=str(e))

    module.exit_json(msg="OK")
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 not specified and unable to determine region from EC2_REGION."
        ))

    # 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)
Esempio n. 41
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        iam_type=dict(
            default=None, required=True, choices=['user', 'group', 'role']),
        state=dict(
            default=None, required=True, choices=['present', 'absent']),
        iam_name=dict(default=None, required=False),
        policy_name=dict(default=None, required=True),
        policy_document=dict(default=None, required=False),
        policy_json=dict(type='json', default=None, required=False),
        skip_duplicates=dict(type='bool', default=True, required=False)
    ))

    module = AnsibleModule(
        argument_spec=argument_spec,
    )

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

    state = module.params.get('state').lower()
    iam_type = module.params.get('iam_type').lower()
    state = module.params.get('state')
    name = module.params.get('iam_name')
    policy_name = module.params.get('policy_name')
    skip = module.params.get('skip_duplicates')

    if module.params.get('policy_document') is not None and module.params.get('policy_json') is not None:
        module.fail_json(msg='Only one of "policy_document" or "policy_json" may be set')

    if module.params.get('policy_document') is not None:
        with open(module.params.get('policy_document'), 'r') as json_data:
            pdoc = json.dumps(json.load(json_data))
            json_data.close()
    elif module.params.get('policy_json') is not None:
        pdoc = module.params.get('policy_json')
        # if its a string, assume it is already JSON
        if not isinstance(pdoc, string_types):
            try:
                pdoc = json.dumps(pdoc)
            except Exception as e:
                module.fail_json(msg='Failed to convert the policy into valid JSON: %s' % str(e))
    else:
        pdoc=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))

    changed = False

    if iam_type == 'user':
        changed, user_name, current_policies = user_action(module, iam, name,
                                                           policy_name, skip, pdoc,
                                                           state)
        module.exit_json(changed=changed, user_name=name, policies=current_policies)
    elif iam_type == 'role':
        changed, role_name, current_policies = role_action(module, iam, name,
                                                           policy_name, skip, pdoc,
                                                           state)
        module.exit_json(changed=changed, role_name=name, policies=current_policies)
    elif iam_type == 'group':
        changed, group_name, current_policies, msg = group_action(module, iam, name,
                                                           policy_name, skip, pdoc,
                                                           state)
        module.exit_json(changed=changed, group_name=name, policies=current_policies, msg=msg)
Esempio n. 42
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        instance=dict(),
        id=dict(),
        name=dict(),
        volume_size=dict(),
        volume_type=dict(choices=['standard', 'gp2', 'io1', 'st1', 'sc1'], default='standard'),
        iops=dict(),
        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 = AnsibleModule(argument_spec=argument_spec)

    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(msg=str(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(msg=e.message)
        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)
Esempio n. 43
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'])
            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)
Esempio n. 44
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 ['name', '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:
        changed = False
        exists = 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)
                changed = True
        else:
            if not exists:
                new_group = conn.create_db_subnet_group(group_name, desc=group_description, subnet_ids=group_subnets)
                changed = True
            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)
                    changed = True
    except BotoServerError as e:
        module.fail_json(msg = e.error_message)

    module.exit_json(changed=changed)
Esempio n. 45
0
 def _get_boto_connection(self):
     try:
         return connect_to_aws(boto.sns, self.region,
                               **self.aws_connect_params)
     except BotoServerError as err:
         self.module.fail_json(msg=err.message)
 def _get_elb_connection(self):
     return connect_to_aws(boto.ec2.elb, self.region, **self.aws_connect_params)
Esempio n. 47
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(instance=dict(),
             id=dict(),
             name=dict(),
             volume_size=dict(),
             volume_type=dict(choices=['standard', 'gp2', 'io1', 'st1', 'sc1'],
                              default='standard'),
             iops=dict(),
             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 = AnsibleModule(argument_spec=argument_spec)

    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(msg=str(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(msg=e.message)
        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)
Esempio n. 48
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        state=dict(required=True, choices=['present', 'absent']),
        name=dict(),
        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])
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)
Esempio n. 50
0
 def _get_elb_connection(self):
     return connect_to_aws(boto.ec2.elb, self.region, **self.aws_connect_params)
Esempio n. 51
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        command=dict(choices=['create', 'facts', 'delete', 'modify'], required=True),
        identifier=dict(required=True),
        node_type=dict(choices=['ds1.xlarge', 'ds1.8xlarge', 'ds2.xlarge', 'ds2.8xlarge', 'dc1.large',
                                'dc2.large', 'dc1.8xlarge', 'dw1.xlarge', 'dw1.8xlarge', 'dw2.large',
                                'dw2.8xlarge'], required=False),
        username=dict(required=False),
        password=dict(no_log=True, required=False),
        db_name=dict(require=False),
        cluster_type=dict(choices=['multi-node', 'single-node', ], default='single-node'),
        cluster_security_groups=dict(aliases=['security_groups'], type='list'),
        vpc_security_group_ids=dict(aliases=['vpc_security_groups'], type='list'),
        skip_final_cluster_snapshot=dict(aliases=['skip_final_snapshot'], type='bool', default=False),
        final_cluster_snapshot_identifier=dict(aliases=['final_snapshot_id'], required=False),
        cluster_subnet_group_name=dict(aliases=['subnet']),
        availability_zone=dict(aliases=['aws_zone', 'zone']),
        preferred_maintenance_window=dict(aliases=['maintance_window', 'maint_window']),
        cluster_parameter_group_name=dict(aliases=['param_group_name']),
        automated_snapshot_retention_period=dict(aliases=['retention_period']),
        port=dict(type='int'),
        cluster_version=dict(aliases=['version'], choices=['1.0']),
        allow_version_upgrade=dict(aliases=['version_upgrade'], type='bool', default=True),
        number_of_nodes=dict(type='int'),
        publicly_accessible=dict(type='bool', default=False),
        encrypted=dict(type='bool', default=False),
        elastic_ip=dict(required=False),
        new_cluster_identifier=dict(aliases=['new_identifier']),
        enhanced_vpc_routing=dict(type='bool', default=False),
        wait=dict(type='bool', default=False),
        wait_timeout=dict(type='int', default=300),
    ))

    required_if = [
        ('command', 'delete', ['skip_final_cluster_snapshot']),
        ('skip_final_cluster_snapshot', False, ['final_cluster_snapshot_identifier'])
    ]

    module = AnsibleModule(
        argument_spec=argument_spec,
        required_if=required_if
    )

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

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

    region, ec2_url, aws_connect_params = get_aws_connection_info(module)
    if not region:
        module.fail_json(msg=str("region not specified and unable to determine region from EC2_REGION."))

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

    changed = True
    if command == 'create':
        (changed, cluster) = create_cluster(module, conn)

    elif command == 'facts':
        (changed, cluster) = describe_cluster(module, conn)

    elif command == 'delete':
        (changed, cluster) = delete_cluster(module, conn)

    elif command == 'modify':
        (changed, cluster) = modify_cluster(module, conn)

    module.exit_json(changed=changed, cluster=cluster)
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 not specified and unable to determine region from EC2_REGION."))

    # 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)
Esempio n. 53
0
 def _get_boto_connection(self):
     try:
         return connect_to_aws(boto.sns, self.region,
             **self.aws_connect_params)
     except BotoServerError as err:
         self.module.fail_json(msg=err.message)
Esempio n. 54
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        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'),
            secondary_private_ip_address_count=dict(default=None, type='int'),
            attached=dict(default=None, type='bool')
        )
    )

    module = AnsibleModule(argument_spec=argument_spec,
                           mutually_exclusive=[
                               ['secondary_private_ip_addresses', 'secondary_private_ip_address_count']
                           ],
                           required_if=([
                               ('state', 'absent', ['eni_id']),
                               ('attached', True, ['instance_id'])
                           ])
                           )

    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(msg=str(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)
Esempio n. 55
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            msg=dict(type='str', required=True, aliases=['default']),
            subject=dict(type='str', default=None),
            topic=dict(type='str', required=True),
            email=dict(type='str', default=None),
            sqs=dict(type='str', default=None),
            sms=dict(type='str', default=None),
            http=dict(type='str', default=None),
            https=dict(type='str', default=None),
        )
    )

    module = AnsibleModule(argument_spec=argument_spec)

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

    msg = module.params['msg']
    subject = module.params['subject']
    topic = module.params['topic']
    email = module.params['email']
    sqs = module.params['sqs']
    sms = module.params['sms']
    http = module.params['http']
    https = module.params['https']

    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.sns, region, **aws_connect_params)
    except boto.exception.NoAuthHandlerFound:
        e = get_exception()
        module.fail_json(msg=str(e))

    # .publish() takes full ARN topic id, but I'm lazy and type shortnames
    # so do a lookup (topics cannot contain ':', so thats the decider)
    if ':' in topic:
        arn_topic = topic
    else:
        arn_topic = arn_topic_lookup(connection, topic)

    if not arn_topic:
        module.fail_json(msg='Could not find topic: {}'.format(topic))

    dict_msg = {'default': msg}
    if email:
        dict_msg.update(email=email)
    if sqs:
        dict_msg.update(sqs=sqs)
    if sms:
        dict_msg.update(sms=sms)
    if http:
        dict_msg.update(http=http)
    if https:
        dict_msg.update(https=https)

    json_msg = json.dumps(dict_msg)
    try:
        connection.publish(topic=arn_topic, subject=subject,
                           message_structure='json', message=json_msg)
    except boto.exception.BotoServerError:
        e = get_exception()
        module.fail_json(msg=str(e))

    module.exit_json(msg="OK")
Esempio n. 56
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            msg=dict(type='str', required=True, aliases=['default']),
            subject=dict(type='str', default=None),
            topic=dict(type='str', required=True),
            email=dict(type='str', default=None),
            sqs=dict(type='str', default=None),
            sms=dict(type='str', default=None),
            http=dict(type='str', default=None),
            https=dict(type='str', default=None),
            message_attributes=dict(type='dict', default=None),
            message_structure=dict(type='str', choices=['json', 'string'], default='json'),
        )
    )

    module = AnsibleModule(argument_spec=argument_spec)

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

    msg = module.params['msg']
    subject = module.params['subject']
    topic = module.params['topic']
    email = module.params['email']
    sqs = module.params['sqs']
    sms = module.params['sms']
    http = module.params['http']
    https = module.params['https']
    message_attributes = module.params['message_attributes']
    message_structure = module.params['message_structure']

    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.sns, region, **aws_connect_params)
    except boto.exception.NoAuthHandlerFound as e:
        module.fail_json(msg=to_native(e), exception=traceback.format_exc())

    if not message_structure == 'string' and message_attributes:
        module.fail_json(msg="when specifying message_attributes, the message_structure must be set to 'string'; otherwise the attributes will not be sent.")
    elif message_structure == 'string' and (email or sqs or sms or http or https):
        module.fail_json(msg="do not specify non-default message formats when using the 'string' message_structure. they can only be used with "
                             "the 'json' message_structure.")

    # .publish() takes full ARN topic id, but I'm lazy and type shortnames
    # so do a lookup (topics cannot contain ':', so that's the decider)
    if ':' in topic:
        arn_topic = topic
    else:
        arn_topic = arn_topic_lookup(connection, topic)

    if not arn_topic:
        module.fail_json(msg='Could not find topic: {}'.format(topic))

    dict_msg = {'default': msg}
    if email:
        dict_msg.update(email=email)
    if sqs:
        dict_msg.update(sqs=sqs)
    if sms:
        dict_msg.update(sms=sms)
    if http:
        dict_msg.update(http=http)
    if https:
        dict_msg.update(https=https)

    if not message_structure == 'json':
        json_msg = msg
    else:
        json_msg = json.dumps(dict_msg)

    try:
        connection.publish(topic=arn_topic, subject=subject,
                           message_structure=message_structure, message=json_msg,
                           message_attributes=message_attributes)
    except boto.exception.BotoServerError as e:
        module.fail_json(msg=to_native(e), exception=traceback.format_exc())

    module.exit_json(msg="OK")
Esempio n. 57
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(state=dict(required=True, choices=['present', 'absent']),
             name=dict(),
             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])
Esempio n. 58
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 ['name', '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)
Esempio n. 59
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        iam_type=dict(
            default=None, required=True, choices=['user', 'group', 'role']),
        state=dict(
            default=None, required=True, choices=['present', 'absent']),
        iam_name=dict(default=None, required=False),
        policy_name=dict(default=None, required=True),
        policy_document=dict(default=None, required=False),
        policy_json=dict(type='json', default=None, required=False),
        skip_duplicates=dict(type='bool', default=True, required=False)
    ))

    module = AnsibleModule(
        argument_spec=argument_spec,
    )

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

    state = module.params.get('state').lower()
    iam_type = module.params.get('iam_type').lower()
    state = module.params.get('state')
    name = module.params.get('iam_name')
    policy_name = module.params.get('policy_name')
    skip = module.params.get('skip_duplicates')

    if module.params.get('policy_document') is not None and module.params.get('policy_json') is not None:
        module.fail_json(msg='Only one of "policy_document" or "policy_json" may be set')

    if module.params.get('policy_document') is not None:
        with open(module.params.get('policy_document'), 'r') as json_data:
            pdoc = json.dumps(json.load(json_data))
            json_data.close()
    elif module.params.get('policy_json') is not None:
        pdoc = module.params.get('policy_json')
        # if its a string, assume it is already JSON
        if not isinstance(pdoc, string_types):
            try:
                pdoc = json.dumps(pdoc)
            except Exception as e:
                module.fail_json(msg='Failed to convert the policy into valid JSON: %s' % str(e))
    else:
        pdoc = 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))

    changed = False

    if iam_type == 'user':
        changed, user_name, current_policies = user_action(module, iam, name,
                                                           policy_name, skip, pdoc,
                                                           state)
        module.exit_json(changed=changed, user_name=name, policies=current_policies)
    elif iam_type == 'role':
        changed, role_name, current_policies = role_action(module, iam, name,
                                                           policy_name, skip, pdoc,
                                                           state)
        module.exit_json(changed=changed, role_name=name, policies=current_policies)
    elif iam_type == 'group':
        changed, group_name, current_policies, msg = group_action(module, iam, name,
                                                                  policy_name, skip, pdoc,
                                                                  state)
        module.exit_json(changed=changed, group_name=name, policies=current_policies, msg=msg)
Esempio n. 60
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        iam_type=dict(
            default=None, required=True, choices=['user', 'group', 'role']),
        groups=dict(type='list', default=None, required=False),
        state=dict(
            default=None, 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(default=None, required=False),
        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)