def main():
    argument_spec = ec2_argument_spec()

    argument_spec.update(dict(
        caller_reference=dict(),
        distribution_id=dict(),
        alias=dict(),
        target_paths=dict(required=True, type='list')
    ))

    module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=False, mutually_exclusive=[['distribution_id', 'alias']])

    validation_mgr = CloudFrontInvalidationValidationManager(module)
    service_mgr = CloudFrontInvalidationServiceManager(module)

    caller_reference = module.params.get('caller_reference')
    distribution_id = module.params.get('distribution_id')
    alias = module.params.get('alias')
    target_paths = module.params.get('target_paths')

    result = {}

    distribution_id = validation_mgr.validate_distribution_id(distribution_id, alias)
    valid_target_paths = validation_mgr.validate_invalidation_batch(target_paths, caller_reference)
    valid_pascal_target_paths = snake_dict_to_camel_dict(valid_target_paths, True)
    result, changed = service_mgr.create_invalidation(distribution_id, valid_pascal_target_paths)

    module.exit_json(changed=changed, **camel_dict_to_snake_dict(result))
Ejemplo n.º 2
0
def create_or_update_bucket_cors(connection, module):

    name = module.params.get("name")
    rules = module.params.get("rules", [])
    changed = False

    try:
        current_camel_rules = connection.get_bucket_cors(
            Bucket=name)['CORSRules']
    except ClientError:
        current_camel_rules = []

    new_camel_rules = snake_dict_to_camel_dict(rules, capitalize_first=True)
    # compare_policies() takes two dicts and makes them hashable for comparison
    if compare_policies(new_camel_rules, current_camel_rules):
        changed = True

    if changed:
        try:
            cors = connection.put_bucket_cors(
                Bucket=name, CORSConfiguration={'CORSRules': new_camel_rules})
        except ClientError as e:
            module.fail_json(
                msg="Unable to update CORS for bucket {0}: {1}".format(
                    name, to_native(e)),
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response))
        except BotoCoreError as e:
            module.fail_json(msg=to_native(e),
                             exception=traceback.format_exc())

    module.exit_json(changed=changed, name=name, rules=rules)
Ejemplo n.º 3
0
def main():
    argument_spec = ec2_argument_spec()

    argument_spec.update(
        dict(caller_reference=dict(),
             distribution_id=dict(),
             alias=dict(),
             target_paths=dict(required=True, type='list')))

    module = AnsibleAWSModule(argument_spec=argument_spec,
                              supports_check_mode=False,
                              mutually_exclusive=[['distribution_id',
                                                   'alias']])

    validation_mgr = CloudFrontInvalidationValidationManager(module)
    service_mgr = CloudFrontInvalidationServiceManager(module)

    caller_reference = module.params.get('caller_reference')
    distribution_id = module.params.get('distribution_id')
    alias = module.params.get('alias')
    target_paths = module.params.get('target_paths')

    result = {}

    distribution_id = validation_mgr.validate_distribution_id(
        distribution_id, alias)
    valid_target_paths = validation_mgr.validate_invalidation_batch(
        target_paths, caller_reference)
    valid_pascal_target_paths = snake_dict_to_camel_dict(
        valid_target_paths, True)
    result, changed = service_mgr.create_invalidation(
        distribution_id, valid_pascal_target_paths)

    module.exit_json(changed=changed, **camel_dict_to_snake_dict(result))
Ejemplo n.º 4
0
def create_or_update_bucket_cors(connection, module):

    name = module.params.get("name")
    rules = module.params.get("rules", [])
    changed = False

    try:
        current_camel_rules = connection.get_bucket_cors(Bucket=name)['CORSRules']
    except ClientError:
        current_camel_rules = []

    new_camel_rules = snake_dict_to_camel_dict(rules, capitalize_first=True)
    # compare_policies() takes two dicts and makes them hashable for comparison
    if compare_policies(new_camel_rules, current_camel_rules):
        changed = True

    if changed:
        try:
            cors = connection.put_bucket_cors(Bucket=name, CORSConfiguration={'CORSRules': new_camel_rules})
        except ClientError as e:
            module.fail_json(
                msg="Unable to update CORS for bucket {0}: {1}".format(name, to_native(e)),
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response)
            )
        except BotoCoreError as e:
            module.fail_json(
                msg=to_native(e),
                exception=traceback.format_exc()
            )

    module.exit_json(changed=changed, name=name, rules=rules)
def build_actions(actions):
    action_items = []

    for action in actions:
        action_item = snake_dict_to_camel_dict(action)
        action_items.append(action_item)

    return action_items
Ejemplo n.º 6
0
def build_actions(actions):
    action_items = []

    for action in actions:
        action_item = snake_dict_to_camel_dict(action)
        action_items.append(action_item)

    return action_items
Ejemplo n.º 7
0
def update_sqs_queue(module, client, queue_url):
    check_mode = module.check_mode
    changed = False
    existing_attributes = client.get_queue_attributes(
        QueueUrl=queue_url, AttributeNames=['All'],
        aws_retry=True)['Attributes']
    new_attributes = snake_dict_to_camel_dict(module.params,
                                              capitalize_first=True)
    attributes_to_set = dict()

    # Boto3 SQS deals with policies as strings, we want to deal with them as
    # dicts
    if module.params.get('policy') is not None:
        policy = module.params.get('policy')
        current_value = existing_attributes.get('Policy', '{}')
        current_policy = json.loads(current_value)
        if compare_policies(current_policy, policy):
            attributes_to_set['Policy'] = json.dumps(policy)
            changed = True
    if module.params.get('redrive_policy') is not None:
        policy = module.params.get('redrive_policy')
        current_value = existing_attributes.get('RedrivePolicy', '{}')
        current_policy = json.loads(current_value)
        if compare_policies(current_policy, policy):
            attributes_to_set['RedrivePolicy'] = json.dumps(policy)
            changed = True

    for attribute, value in existing_attributes.items():
        # We handle these as a special case because they're IAM policies
        if attribute in ['Policy', 'RedrivePolicy']:
            continue

        if attribute not in new_attributes.keys():
            continue

        if new_attributes.get(attribute) is None:
            continue

        new_value = new_attributes[attribute]

        if isinstance(new_value, bool):
            new_value = str(new_value).lower()
            existing_value = str(existing_value).lower()

        if new_value == value:
            continue

        # Boto3 expects strings
        attributes_to_set[attribute] = str(new_value)
        changed = True

    if changed and not check_mode:
        client.set_queue_attributes(QueueUrl=queue_url,
                                    Attributes=attributes_to_set,
                                    aws_retry=True)

    return changed, existing_attributes.get('queue_arn'),
Ejemplo n.º 8
0
def set_api_params(module, module_params):
    """
    Sets module parameters to those expected by the boto3 API.
    :param module:
    :param module_params:
    :return:
    """
    api_params = dict((k, v) for k, v in dict(module.params).items() if k in module_params and v is not None)
    return snake_dict_to_camel_dict(api_params)
Ejemplo n.º 9
0
def set_api_params(module, module_params):
    """
    Sets module parameters to those expected by the boto3 API.
    :param module:
    :param module_params:
    :return:
    """
    api_params = dict((k, v) for k, v in dict(module.params).items()
                      if k in module_params and v is not None)
    return snake_dict_to_camel_dict(api_params)
Ejemplo n.º 10
0
def create_route_spec(connection, module, vpc_id):
    routes = module.params.get('routes')

    for route_spec in routes:
        rename_key(route_spec, 'dest', 'destination_cidr_block')

        if route_spec.get('gateway_id') and route_spec['gateway_id'].lower() == 'igw':
            igw = find_igw(connection, module, vpc_id)
            route_spec['gateway_id'] = igw
        if route_spec.get('gateway_id') and route_spec['gateway_id'].startswith('nat-'):
            rename_key(route_spec, 'gateway_id', 'nat_gateway_id')

    return snake_dict_to_camel_dict(routes, capitalize_first=True)
Ejemplo n.º 11
0
def create_or_update_project(client, params, module):
    resp = {}
    name = params['name']
    # clean up params
    formatted_params = snake_dict_to_camel_dict(
        dict((k, v) for k, v in params.items() if v is not None))
    permitted_create_params = get_boto3_client_method_parameters(
        client, 'create_project')
    permitted_update_params = get_boto3_client_method_parameters(
        client, 'update_project')

    formatted_create_params = dict((k, v) for k, v in formatted_params.items()
                                   if k in permitted_create_params)
    formatted_update_params = dict((k, v) for k, v in formatted_params.items()
                                   if k in permitted_update_params)

    # Check if project with that name already exists and if so update existing:
    found = describe_project(client=client, name=name, module=module)
    changed = False

    if 'name' in found:
        found_project = found
        resp = update_project(client=client,
                              params=formatted_update_params,
                              module=module)
        updated_project = resp['project']

        # Prep both dicts for sensible change comparison:
        found_project.pop('lastModified')
        updated_project.pop('lastModified')
        if 'tags' not in updated_project:
            updated_project['tags'] = []

        if updated_project != found_project:
            changed = True
        return resp, changed
    # Or create new project:
    try:
        resp = client.create_project(**formatted_create_params)
        changed = True
        return resp, changed
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Unable to create CodeBuild project")
Ejemplo n.º 12
0
def delete_cluster(module, redshift):
    """
    Delete a cluster.

    module: Ansible module object
    redshift: authenticated redshift connection object
    """

    identifier = module.params.get('identifier')
    wait = module.params.get('wait')
    wait_timeout = module.params.get('wait_timeout')

    params = {}
    for p in ('skip_final_cluster_snapshot',
              'final_cluster_snapshot_identifier'):
        if p in module.params:
            # https://github.com/boto/boto3/issues/400
            if module.params.get(p) is not None:
                params[p] = module.params.get(p)

    try:
        _delete_cluster(redshift,
                        ClusterIdentifier=identifier,
                        **snake_dict_to_camel_dict(params,
                                                   capitalize_first=True))
    except is_boto3_error_code('ClusterNotFound'):
        return (False, {})
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, msg="Failed to delete cluster")

    if wait:
        attempts = wait_timeout // 60
        waiter = redshift.get_waiter('cluster_deleted')
        try:
            waiter.wait(ClusterIdentifier=identifier,
                        WaiterConfig=dict(MaxAttempts=attempts))
        except (botocore.exceptions.ClientError,
                botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(e, msg="Timeout deleting the cluster")

    return (True, {})
Ejemplo n.º 13
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(state=dict(required=True,
                        choices=['present', 'absent', 'deleting']),
             name=dict(required=True, type='str'),
             cluster=dict(required=False, type='str'),
             task_definition=dict(required=False, type='str'),
             load_balancers=dict(required=False, default=[], type='list'),
             desired_count=dict(required=False, type='int'),
             client_token=dict(required=False, default='', type='str'),
             role=dict(required=False, default='', type='str'),
             delay=dict(required=False, type='int', default=10),
             repeat=dict(required=False, type='int', default=10),
             deployment_configuration=dict(required=False,
                                           default={},
                                           type='dict'),
             placement_constraints=dict(required=False,
                                        default=[],
                                        type='list'),
             placement_strategy=dict(required=False, default=[], type='list'),
             network_configuration=dict(required=False, type='dict'),
             launch_type=dict(required=False, choices=['EC2', 'FARGATE'])))

    module = AnsibleAWSModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[('state', 'present', ['task_definition',
                                           'desired_count']),
                     ('launch_type', 'FARGATE', ['network_configuration'])],
        required_together=[['load_balancers', 'role']])

    service_mgr = EcsServiceManager(module)
    if module.params['network_configuration']:
        if not service_mgr.ecs_api_handles_network_configuration():
            module.fail_json(
                msg=
                'botocore needs to be version 1.7.44 or higher to use network configuration'
            )
        network_configuration = service_mgr.format_network_configuration(
            module.params['network_configuration'])
    else:
        network_configuration = None

    deployment_configuration = map_complex_type(
        module.params['deployment_configuration'],
        DEPLOYMENT_CONFIGURATION_TYPE_MAP)

    deploymentConfiguration = snake_dict_to_camel_dict(
        deployment_configuration)

    try:
        existing = service_mgr.describe_service(module.params['cluster'],
                                                module.params['name'])
    except Exception as e:
        module.fail_json(msg="Exception describing service '" +
                         module.params['name'] + "' in cluster '" +
                         module.params['cluster'] + "': " + str(e))

    results = dict(changed=False)

    if module.params['launch_type']:
        if not module.botocore_at_least('1.8.4'):
            module.fail_json(
                msg=
                'botocore needs to be version 1.8.4 or higher to use launch_type'
            )

    if module.params['state'] == 'present':

        matching = False
        update = False

        if existing and 'status' in existing and existing['status'] == "ACTIVE":
            if service_mgr.is_matching_service(module.params, existing):
                matching = True
                results['service'] = existing
            else:
                update = True

        if not matching:
            if not module.check_mode:

                role = module.params['role']
                clientToken = module.params['client_token']
                loadBalancers = module.params['load_balancers']

                if update:
                    if (existing['loadBalancers'] or []) != loadBalancers:
                        module.fail_json(
                            msg=
                            "It is not possible to update the load balancers of an existing service"
                        )
                    # update required
                    response = service_mgr.update_service(
                        module.params['name'], module.params['cluster'],
                        module.params['task_definition'],
                        module.params['desired_count'],
                        deploymentConfiguration, network_configuration)
                else:
                    for loadBalancer in loadBalancers:
                        if 'containerPort' in loadBalancer:
                            loadBalancer['containerPort'] = int(
                                loadBalancer['containerPort'])
                    # doesn't exist. create it.
                    try:
                        response = service_mgr.create_service(
                            module.params['name'], module.params['cluster'],
                            module.params['task_definition'], loadBalancers,
                            module.params['desired_count'], clientToken, role,
                            deploymentConfiguration,
                            module.params['placement_constraints'],
                            module.params['placement_strategy'],
                            network_configuration,
                            module.params['launch_type'])
                    except botocore.exceptions.ClientError as e:
                        module.fail_json_aws(e, msg="Couldn't create service")

                results['service'] = response

            results['changed'] = True

    elif module.params['state'] == 'absent':
        if not existing:
            pass
        else:
            # it exists, so we should delete it and mark changed.
            # return info about the cluster deleted
            del existing['deployments']
            del existing['events']
            results['ansible_facts'] = existing
            if 'status' in existing and existing['status'] == "INACTIVE":
                results['changed'] = False
            else:
                if not module.check_mode:
                    try:
                        service_mgr.delete_service(module.params['name'],
                                                   module.params['cluster'])
                    except botocore.exceptions.ClientError as e:
                        module.fail_json_aws(e, msg="Couldn't delete service")
                results['changed'] = True

    elif module.params['state'] == 'deleting':
        if not existing:
            module.fail_json(msg="Service '" + module.params['name'] +
                             " not found.")
            return
        # it exists, so we should delete it and mark changed.
        # return info about the cluster deleted
        delay = module.params['delay']
        repeat = module.params['repeat']
        time.sleep(delay)
        for i in range(repeat):
            existing = service_mgr.describe_service(module.params['cluster'],
                                                    module.params['name'])
            status = existing['status']
            if status == "INACTIVE":
                results['changed'] = True
                break
            time.sleep(delay)
        if i is repeat - 1:
            module.fail_json(msg="Service still not deleted after " +
                             str(repeat) + " tries of " + str(delay) +
                             " seconds each.")
            return

    module.exit_json(**results)
Ejemplo n.º 14
0
def create_launch_config(connection, module):
    name = module.params.get('name')
    vpc_id = module.params.get('vpc_id')
    try:
        region, ec2_url, aws_connect_kwargs = get_aws_connection_info(
            module, boto3=True)
        ec2_connection = boto3_conn(module, 'client', 'ec2', region, ec2_url,
                                    **aws_connect_kwargs)
        security_groups = get_ec2_security_group_ids_from_names(
            module.params.get('security_groups'),
            ec2_connection,
            vpc_id=vpc_id,
            boto3=True)
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Failed to get Security Group IDs",
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))
    except ValueError as e:
        module.fail_json(msg="Failed to get Security Group IDs",
                         exception=traceback.format_exc())
    user_data = module.params.get('user_data')
    user_data_path = module.params.get('user_data_path')
    volumes = module.params['volumes']
    instance_monitoring = module.params.get('instance_monitoring')
    assign_public_ip = module.params.get('assign_public_ip')
    instance_profile_name = module.params.get('instance_profile_name')
    ebs_optimized = module.params.get('ebs_optimized')
    classic_link_vpc_id = module.params.get('classic_link_vpc_id')
    classic_link_vpc_security_groups = module.params.get(
        'classic_link_vpc_security_groups')

    block_device_mapping = []

    convert_list = [
        'image_id', 'instance_type', 'instance_type', 'instance_id',
        'placement_tenancy', 'key_name', 'kernel_id', 'ramdisk_id',
        'spot_price'
    ]

    launch_config = (snake_dict_to_camel_dict(
        dict((k.capitalize(), str(v)) for k, v in module.params.items()
             if v is not None and k in convert_list)))

    if user_data_path:
        try:
            with open(user_data_path, 'r') as user_data_file:
                user_data = user_data_file.read()
        except IOError as e:
            module.fail_json(msg="Failed to open file for reading",
                             exception=traceback.format_exc())

    if volumes:
        for volume in volumes:
            if 'device_name' not in volume:
                module.fail_json(msg='Device name must be set for volume')
            # Minimum volume size is 1GiB. We'll use volume size explicitly set to 0 to be a signal not to create this volume
            if 'volume_size' not in volume or int(volume['volume_size']) > 0:
                block_device_mapping.append(
                    create_block_device_meta(module, volume))

    try:
        launch_configs = connection.describe_launch_configurations(
            LaunchConfigurationNames=[name]).get('LaunchConfigurations')
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Failed to describe launch configuration by name",
                         exception=traceback.format_exc(),
                         **camel_dict_to_snake_dict(e.response))

    changed = False
    result = {}

    launch_config['LaunchConfigurationName'] = name

    if security_groups is not None:
        launch_config['SecurityGroups'] = security_groups

    if classic_link_vpc_id is not None:
        launch_config['ClassicLinkVPCId'] = classic_link_vpc_id

    if instance_monitoring is not None:
        launch_config['InstanceMonitoring'] = {'Enabled': instance_monitoring}

    if classic_link_vpc_security_groups is not None:
        launch_config[
            'ClassicLinkVPCSecurityGroups'] = classic_link_vpc_security_groups

    if block_device_mapping:
        launch_config['BlockDeviceMappings'] = block_device_mapping

    if instance_profile_name is not None:
        launch_config['IamInstanceProfile'] = instance_profile_name

    if assign_public_ip is not None:
        launch_config['AssociatePublicIpAddress'] = assign_public_ip

    if user_data is not None:
        launch_config['UserData'] = user_data

    if ebs_optimized is not None:
        launch_config['EbsOptimized'] = ebs_optimized

    if len(launch_configs) == 0:
        try:
            connection.create_launch_configuration(**launch_config)
            launch_configs = connection.describe_launch_configurations(
                LaunchConfigurationNames=[name]).get('LaunchConfigurations')
            changed = True
            if launch_configs:
                launch_config = launch_configs[0]
        except botocore.exceptions.ClientError as e:
            module.fail_json(msg="Failed to create launch configuration",
                             exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))

    result = (dict((k, v) for k, v in launch_config.items() if k not in [
        'Connection', 'CreatedTime', 'InstanceMonitoring',
        'BlockDeviceMappings'
    ]))

    result['CreatedTime'] = to_text(launch_config.get('CreatedTime'))

    try:
        result['InstanceMonitoring'] = module.boolean(
            launch_config.get('InstanceMonitoring').get('Enabled'))
    except AttributeError:
        result['InstanceMonitoring'] = False

    result['BlockDeviceMappings'] = []

    for block_device_mapping in launch_config.get('BlockDeviceMappings', []):
        result['BlockDeviceMappings'].append(
            dict(device_name=block_device_mapping.get('DeviceName'),
                 virtual_name=block_device_mapping.get('VirtualName')))
        if block_device_mapping.get('Ebs') is not None:
            result['BlockDeviceMappings'][-1]['ebs'] = dict(
                snapshot_id=block_device_mapping.get('Ebs').get('SnapshotId'),
                volume_size=block_device_mapping.get('Ebs').get('VolumeSize'))

    if user_data_path:
        result[
            'UserData'] = "hidden"  # Otherwise, we dump binary to the user's terminal

    return_object = {
        'Name': result.get('LaunchConfigurationName'),
        'CreatedTime': result.get('CreatedTime'),
        'ImageId': result.get('ImageId'),
        'Arn': result.get('LaunchConfigurationARN'),
        'SecurityGroups': result.get('SecurityGroups'),
        'InstanceType': result.get('InstanceType'),
        'Result': result
    }

    module.exit_json(changed=changed,
                     **camel_dict_to_snake_dict(return_object))
Ejemplo n.º 15
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        state=dict(required=True, choices=['present', 'absent', 'deleting']),
        name=dict(required=True, type='str'),
        cluster=dict(required=False, type='str'),
        task_definition=dict(required=False, type='str'),
        load_balancers=dict(required=False, default=[], type='list'),
        desired_count=dict(required=False, type='int'),
        client_token=dict(required=False, default='', type='str'),
        role=dict(required=False, default='', type='str'),
        delay=dict(required=False, type='int', default=10),
        repeat=dict(required=False, type='int', default=10),
        deployment_configuration=dict(required=False, default={}, type='dict'),
        placement_constraints=dict(required=False, default=[], type='list'),
        placement_strategy=dict(required=False, default=[], type='list')
    ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True,
                           required_if=[
                               ('state', 'present', ['task_definition', 'desired_count'])
                           ],
                           required_together=[['load_balancers', 'role']]
                           )

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

    if not HAS_BOTO3:
        module.fail_json(msg='boto3 is required.')

    service_mgr = EcsServiceManager(module)

    deployment_configuration = map_complex_type(module.params['deployment_configuration'],
                                                DEPLOYMENT_CONFIGURATION_TYPE_MAP)

    deploymentConfiguration = snake_dict_to_camel_dict(deployment_configuration)

    try:
        existing = service_mgr.describe_service(module.params['cluster'], module.params['name'])
    except Exception as e:
        module.fail_json(msg="Exception describing service '" + module.params['name'] + "' in cluster '" + module.params['cluster'] + "': " + str(e))

    results = dict(changed=False)
    if module.params['state'] == 'present':

        matching = False
        update = False
        if existing and 'status' in existing and existing['status']=="ACTIVE":
            if service_mgr.is_matching_service(module.params, existing):
                matching = True
                results['service'] = service_mgr.jsonize(existing)
            else:
                update = True

        if not matching:
            if not module.check_mode:
                loadBalancers = module.params['load_balancers']
                for loadBalancer in loadBalancers:
                    if 'containerPort' in loadBalancer:
                        loadBalancer['containerPort'] = int(loadBalancer['containerPort'])

                role = module.params['role']
                clientToken = module.params['client_token']

                if update:
                    # update required
                    response = service_mgr.update_service(module.params['name'],
                        module.params['cluster'],
                        module.params['task_definition'],
                        loadBalancers,
                        module.params['desired_count'],
                        clientToken,
                        role,
                        deploymentConfiguration)
                else:
                    # doesn't exist. create it.
                    response = service_mgr.create_service(module.params['name'],
                        module.params['cluster'],
                        module.params['task_definition'],
                        loadBalancers,
                        module.params['desired_count'],
                        clientToken,
                        role,
                        deploymentConfiguration,
                        module.params['placement_constraints'],
                        module.params['placement_strategy'])

                results['service'] = response

            results['changed'] = True

    elif module.params['state'] == 'absent':
        if not existing:
            pass
        else:
            # it exists, so we should delete it and mark changed.
            # return info about the cluster deleted
            del existing['deployments']
            del existing['events']
            results['ansible_facts'] = existing
            if 'status' in existing and existing['status']=="INACTIVE":
                results['changed'] = False
            else:
                if not module.check_mode:
                    try:
                        service_mgr.delete_service(
                            module.params['name'],
                            module.params['cluster']
                        )
                    except botocore.exceptions.ClientError as e:
                        module.fail_json(msg=e.message)
                results['changed'] = True

    elif module.params['state'] == 'deleting':
        if not existing:
            module.fail_json(msg="Service '" + module.params['name'] + " not found.")
            return
        # it exists, so we should delete it and mark changed.
        # return info about the cluster deleted
        delay = module.params['delay']
        repeat = module.params['repeat']
        time.sleep(delay)
        for i in range(repeat):
            existing = service_mgr.describe_service(module.params['cluster'], module.params['name'])
            status = existing['status']
            if status == "INACTIVE":
                results['changed'] = True
                break
            time.sleep(delay)
        if i is repeat - 1:
            module.fail_json(msg="Service still not deleted after " + str(repeat) + " tries of " + str(delay) + " seconds each.")
            return

    module.exit_json(**results)
Ejemplo n.º 16
0
def main():
    argument_spec = dict(state=dict(required=True,
                                    choices=['present', 'absent', 'deleting']),
                         name=dict(required=True, type='str'),
                         cluster=dict(required=False, type='str'),
                         task_definition=dict(required=False, type='str'),
                         load_balancers=dict(required=False,
                                             default=[],
                                             type='list'),
                         desired_count=dict(required=False, type='int'),
                         client_token=dict(required=False,
                                           default='',
                                           type='str'),
                         role=dict(required=False, default='', type='str'),
                         delay=dict(required=False, type='int', default=10),
                         repeat=dict(required=False, type='int', default=10),
                         force_new_deployment=dict(required=False,
                                                   default=False,
                                                   type='bool'),
                         deployment_configuration=dict(required=False,
                                                       default={},
                                                       type='dict'),
                         placement_constraints=dict(required=False,
                                                    default=[],
                                                    type='list'),
                         placement_strategy=dict(required=False,
                                                 default=[],
                                                 type='list'),
                         health_check_grace_period_seconds=dict(required=False,
                                                                type='int'),
                         network_configuration=dict(
                             required=False,
                             type='dict',
                             options=dict(subnets=dict(type='list'),
                                          security_groups=dict(type='list'),
                                          assign_public_ip=dict(type='bool'))),
                         launch_type=dict(required=False,
                                          choices=['EC2', 'FARGATE']),
                         service_registries=dict(required=False,
                                                 type='list',
                                                 default=[]),
                         scheduling_strategy=dict(
                             required=False, choices=['DAEMON', 'REPLICA']))

    module = AnsibleAWSModule(argument_spec=argument_spec,
                              supports_check_mode=True,
                              required_if=[('state', 'present',
                                            ['task_definition']),
                                           ('launch_type', 'FARGATE',
                                            ['network_configuration'])],
                              required_together=[['load_balancers', 'role']])

    if module.params['state'] == 'present' and module.params[
            'scheduling_strategy'] == 'REPLICA':
        if module.params['desired_count'] is None:
            module.fail_json(
                msg=
                'state is present, scheduling_strategy is REPLICA; missing desired_count'
            )

    service_mgr = EcsServiceManager(module)
    if module.params['network_configuration']:
        if not service_mgr.ecs_api_handles_network_configuration():
            module.fail_json(
                msg=
                'botocore needs to be version 1.7.44 or higher to use network configuration'
            )
        network_configuration = service_mgr.format_network_configuration(
            module.params['network_configuration'])
    else:
        network_configuration = None

    deployment_configuration = map_complex_type(
        module.params['deployment_configuration'],
        DEPLOYMENT_CONFIGURATION_TYPE_MAP)

    deploymentConfiguration = snake_dict_to_camel_dict(
        deployment_configuration)
    serviceRegistries = list(
        map(snake_dict_to_camel_dict, module.params['service_registries']))

    try:
        existing = service_mgr.describe_service(module.params['cluster'],
                                                module.params['name'])
    except Exception as e:
        module.fail_json(msg="Exception describing service '" +
                         module.params['name'] + "' in cluster '" +
                         module.params['cluster'] + "': " + str(e))

    results = dict(changed=False)

    if module.params['launch_type']:
        if not module.botocore_at_least('1.8.4'):
            module.fail_json(
                msg=
                'botocore needs to be version 1.8.4 or higher to use launch_type'
            )
    if module.params['force_new_deployment']:
        if not module.botocore_at_least('1.8.4'):
            module.fail_json(
                msg=
                'botocore needs to be version 1.8.4 or higher to use force_new_deployment'
            )
    if module.params['health_check_grace_period_seconds']:
        if not module.botocore_at_least('1.8.20'):
            module.fail_json(
                msg=
                'botocore needs to be version 1.8.20 or higher to use health_check_grace_period_seconds'
            )

    if module.params['state'] == 'present':

        matching = False
        update = False

        if existing and 'status' in existing and existing['status'] == "ACTIVE":
            if module.params['force_new_deployment']:
                update = True
            elif service_mgr.is_matching_service(module.params, existing):
                matching = True
                results['service'] = existing
            else:
                update = True

        if not matching:
            if not module.check_mode:

                role = module.params['role']
                clientToken = module.params['client_token']

                loadBalancers = []
                for loadBalancer in module.params['load_balancers']:
                    if 'containerPort' in loadBalancer:
                        loadBalancer['containerPort'] = int(
                            loadBalancer['containerPort'])
                    loadBalancers.append(loadBalancer)

                for loadBalancer in loadBalancers:
                    if 'containerPort' in loadBalancer:
                        loadBalancer['containerPort'] = int(
                            loadBalancer['containerPort'])

                if update:
                    # check various parameters and boto versions and give a helpful error in boto is not new enough for feature

                    if module.params['scheduling_strategy']:
                        if not module.botocore_at_least('1.10.37'):
                            module.fail_json(
                                msg=
                                'botocore needs to be version 1.10.37 or higher to use scheduling_strategy'
                            )
                        elif (existing['schedulingStrategy']
                              ) != module.params['scheduling_strategy']:
                            module.fail_json(
                                msg=
                                "It is not possible to update the scheduling strategy of an existing service"
                            )

                    if module.params['service_registries']:
                        if not module.botocore_at_least('1.9.15'):
                            module.fail_json(
                                msg=
                                'botocore needs to be version 1.9.15 or higher to use service_registries'
                            )
                        elif (existing['serviceRegistries']
                              or []) != serviceRegistries:
                            module.fail_json(
                                msg=
                                "It is not possible to update the service registries of an existing service"
                            )

                    if (existing['loadBalancers'] or []) != loadBalancers:
                        module.fail_json(
                            msg=
                            "It is not possible to update the load balancers of an existing service"
                        )

                    # update required
                    response = service_mgr.update_service(
                        module.params['name'], module.params['cluster'],
                        module.params['task_definition'],
                        module.params['desired_count'],
                        deploymentConfiguration, network_configuration,
                        module.params['health_check_grace_period_seconds'],
                        module.params['force_new_deployment'])

                else:
                    try:
                        response = service_mgr.create_service(
                            module.params['name'], module.params['cluster'],
                            module.params['task_definition'], loadBalancers,
                            module.params['desired_count'], clientToken, role,
                            deploymentConfiguration,
                            module.params['placement_constraints'],
                            module.params['placement_strategy'],
                            module.params['health_check_grace_period_seconds'],
                            network_configuration, serviceRegistries,
                            module.params['launch_type'],
                            module.params['scheduling_strategy'])
                    except botocore.exceptions.ClientError as e:
                        module.fail_json_aws(e, msg="Couldn't create service")

                results['service'] = response

            results['changed'] = True

    elif module.params['state'] == 'absent':
        if not existing:
            pass
        else:
            # it exists, so we should delete it and mark changed.
            # return info about the cluster deleted
            del existing['deployments']
            del existing['events']
            results['ansible_facts'] = existing
            if 'status' in existing and existing['status'] == "INACTIVE":
                results['changed'] = False
            else:
                if not module.check_mode:
                    try:
                        service_mgr.delete_service(module.params['name'],
                                                   module.params['cluster'])
                    except botocore.exceptions.ClientError as e:
                        module.fail_json_aws(e, msg="Couldn't delete service")
                results['changed'] = True

    elif module.params['state'] == 'deleting':
        if not existing:
            module.fail_json(msg="Service '" + module.params['name'] +
                             " not found.")
            return
        # it exists, so we should delete it and mark changed.
        # return info about the cluster deleted
        delay = module.params['delay']
        repeat = module.params['repeat']
        time.sleep(delay)
        for i in range(repeat):
            existing = service_mgr.describe_service(module.params['cluster'],
                                                    module.params['name'])
            status = existing['status']
            if status == "INACTIVE":
                results['changed'] = True
                break
            time.sleep(delay)
        if i is repeat - 1:
            module.fail_json(msg="Service still not deleted after " +
                             str(repeat) + " tries of " + str(delay) +
                             " seconds each.")
            return

    module.exit_json(**results)
Ejemplo n.º 17
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(dict(
        state=dict(required=True, choices=['present', 'absent', 'deleting']),
        name=dict(required=True, type='str'),
        cluster=dict(required=False, type='str'),
        task_definition=dict(required=False, type='str'),
        load_balancers=dict(required=False, default=[], type='list'),
        desired_count=dict(required=False, type='int'),
        client_token=dict(required=False, default='', type='str'),
        role=dict(required=False, default='', type='str'),
        delay=dict(required=False, type='int', default=10),
        repeat=dict(required=False, type='int', default=10),
        deployment_configuration=dict(required=False, default={}, type='dict'),
        placement_constraints=dict(required=False, default=[], type='list'),
        placement_strategy=dict(required=False, default=[], type='list')
    ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True,
                           required_if=[
                               ('state', 'present', ['task_definition', 'desired_count'])
                           ],
                           required_together=[['load_balancers', 'role']]
                           )

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

    if not HAS_BOTO3:
        module.fail_json(msg='boto3 is required.')

    service_mgr = EcsServiceManager(module)

    deployment_configuration = map_complex_type(module.params['deployment_configuration'],
                                                DEPLOYMENT_CONFIGURATION_TYPE_MAP)

    deploymentConfiguration = snake_dict_to_camel_dict(deployment_configuration)

    try:
        existing = service_mgr.describe_service(module.params['cluster'], module.params['name'])
    except Exception as e:
        module.fail_json(msg="Exception describing service '" + module.params['name'] + "' in cluster '" + module.params['cluster'] + "': " + str(e))

    results = dict(changed=False)
    if module.params['state'] == 'present':

        matching = False
        update = False
        if existing and 'status' in existing and existing['status']=="ACTIVE":
            if service_mgr.is_matching_service(module.params, existing):
                matching = True
                results['service'] = service_mgr.jsonize(existing)
            else:
                update = True

        if not matching:
            if not module.check_mode:
                loadBalancers = module.params['load_balancers']
                for loadBalancer in loadBalancers:
                    if 'containerPort' in loadBalancer:
                        loadBalancer['containerPort'] = int(loadBalancer['containerPort'])

                role = module.params['role']
                clientToken = module.params['client_token']

                if update:
                    # update required
                    response = service_mgr.update_service(module.params['name'],
                        module.params['cluster'],
                        module.params['task_definition'],
                        loadBalancers,
                        module.params['desired_count'],
                        clientToken,
                        role,
                        deploymentConfiguration)
                else:
                    # doesn't exist. create it.
                    response = service_mgr.create_service(module.params['name'],
                        module.params['cluster'],
                        module.params['task_definition'],
                        loadBalancers,
                        module.params['desired_count'],
                        clientToken,
                        role,
                        deploymentConfiguration,
                        module.params['placement_constraints'],
                        module.params['placement_strategy'])

                results['service'] = response

            results['changed'] = True

    elif module.params['state'] == 'absent':
        if not existing:
            pass
        else:
            # it exists, so we should delete it and mark changed.
            # return info about the cluster deleted
            del existing['deployments']
            del existing['events']
            results['ansible_facts'] = existing
            if 'status' in existing and existing['status']=="INACTIVE":
                results['changed'] = False
            else:
                if not module.check_mode:
                    try:
                        service_mgr.delete_service(
                            module.params['name'],
                            module.params['cluster']
                        )
                    except botocore.exceptions.ClientError as e:
                        module.fail_json(msg=e.message)
                results['changed'] = True

    elif module.params['state'] == 'deleting':
        if not existing:
            module.fail_json(msg="Service '" + module.params['name'] + " not found.")
            return
        # it exists, so we should delete it and mark changed.
        # return info about the cluster deleted
        delay = module.params['delay']
        repeat = module.params['repeat']
        time.sleep(delay)
        for i in range(repeat):
            existing = service_mgr.describe_service(module.params['cluster'], module.params['name'])
            status = existing['status']
            if status == "INACTIVE":
                results['changed'] = True
                break
            time.sleep(delay)
        if i is repeat - 1:
            module.fail_json(msg="Service still not deleted after " + str(repeat) + " tries of " + str(delay) + " seconds each.")
            return

    module.exit_json(**results)
Ejemplo n.º 18
0
def create_cluster(module, redshift):
    """
    Create a new cluster

    module: AnsibleModule object
    redshift: authenticated redshift connection object

    Returns:
    """

    identifier = module.params.get('identifier')
    node_type = module.params.get('node_type')
    username = module.params.get('username')
    password = module.params.get('password')
    d_b_name = module.params.get('db_name')
    wait = module.params.get('wait')
    wait_timeout = module.params.get('wait_timeout')

    changed = True
    # Package up the optional parameters
    params = {}
    for p in ('cluster_type', 'cluster_security_groups',
              'vpc_security_group_ids', 'cluster_subnet_group_name',
              'availability_zone', 'preferred_maintenance_window',
              'cluster_parameter_group_name',
              'automated_snapshot_retention_period', 'port', 'cluster_version',
              'allow_version_upgrade', 'number_of_nodes',
              'publicly_accessible', 'encrypted', 'elastic_ip',
              'enhanced_vpc_routing'):
        # https://github.com/boto/boto3/issues/400
        if module.params.get(p) is not None:
            params[p] = module.params.get(p)

    if d_b_name:
        params['d_b_name'] = d_b_name

    try:
        redshift.describe_clusters(ClusterIdentifier=identifier)['Clusters'][0]
        changed = False
    except is_boto3_error_code('ClusterNotFound'):
        try:
            redshift.create_cluster(ClusterIdentifier=identifier,
                                    NodeType=node_type,
                                    MasterUsername=username,
                                    MasterUserPassword=password,
                                    **snake_dict_to_camel_dict(
                                        params, capitalize_first=True))
        except (botocore.exceptions.BotoCoreError,
                botocore.exceptions.ClientError) as e:
            module.fail_json_aws(e, msg="Failed to create cluster")
    except (botocore.exceptions.BotoCoreError,
            botocore.exceptions.ClientError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e, msg="Failed to describe cluster")
    if wait:
        attempts = wait_timeout // 60
        waiter = redshift.get_waiter('cluster_available')
        try:
            waiter.wait(ClusterIdentifier=identifier,
                        WaiterConfig=dict(MaxAttempts=attempts))
        except (botocore.exceptions.ClientError,
                botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(
                e, msg="Timeout waiting for the cluster creation")
    try:
        resource = redshift.describe_clusters(
            ClusterIdentifier=identifier)['Clusters'][0]
    except (botocore.exceptions.BotoCoreError,
            botocore.exceptions.ClientError) as e:
        module.fail_json_aws(e, msg="Failed to describe cluster")

    return (changed, _collect_facts(resource))
Ejemplo n.º 19
0
def create_launch_config(connection, module):
    name = module.params.get('name')
    vpc_id = module.params.get('vpc_id')
    try:
        region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
        ec2_connection = boto3_conn(module, 'client', 'ec2', region, ec2_url, **aws_connect_kwargs)
        security_groups = get_ec2_security_group_ids_from_names(module.params.get('security_groups'), ec2_connection, vpc_id=vpc_id, boto3=True)
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Failed to get Security Group IDs", exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response))
    except ValueError as e:
        module.fail_json(msg="Failed to get Security Group IDs", exception=traceback.format_exc())
    user_data = module.params.get('user_data')
    user_data_path = module.params.get('user_data_path')
    volumes = module.params['volumes']
    instance_monitoring = module.params.get('instance_monitoring')
    assign_public_ip = module.params.get('assign_public_ip')
    instance_profile_name = module.params.get('instance_profile_name')
    ebs_optimized = module.params.get('ebs_optimized')
    classic_link_vpc_id = module.params.get('classic_link_vpc_id')
    classic_link_vpc_security_groups = module.params.get('classic_link_vpc_security_groups')

    block_device_mapping = {}

    convert_list = ['image_id', 'instance_type', 'instance_type', 'instance_id', 'placement_tenancy', 'key_name', 'kernel_id', 'ramdisk_id', 'spot_price']

    launch_config = (snake_dict_to_camel_dict(dict((k.capitalize(), str(v)) for k, v in module.params.items() if v is not None and k in convert_list)))

    if user_data_path:
        try:
            with open(user_data_path, 'r') as user_data_file:
                user_data = user_data_file.read()
        except IOError as e:
            module.fail_json(msg="Failed to open file for reading", exception=traceback.format_exc())

    if volumes:
        for volume in volumes:
            if 'device_name' not in volume:
                module.fail_json(msg='Device name must be set for volume')
            # Minimum volume size is 1GB. We'll use volume size explicitly set to 0 to be a signal not to create this volume
            if 'volume_size' not in volume or int(volume['volume_size']) > 0:
                block_device_mapping.update(create_block_device_meta(module, volume))

    try:
        launch_configs = connection.describe_launch_configurations(LaunchConfigurationNames=[name]).get('LaunchConfigurations')
    except botocore.exceptions.ClientError as e:
        module.fail_json(msg="Failed to describe launch configuration by name", exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response))

    changed = False
    result = {}

    launch_config['LaunchConfigurationName'] = name

    if security_groups is not None:
        launch_config['SecurityGroups'] = security_groups

    if classic_link_vpc_id is not None:
        launch_config['ClassicLinkVPCId'] = classic_link_vpc_id

    if instance_monitoring:
        launch_config['InstanceMonitoring'] = {'Enabled': instance_monitoring}

    if classic_link_vpc_security_groups is not None:
        launch_config['ClassicLinkVPCSecurityGroups'] = classic_link_vpc_security_groups

    if block_device_mapping:
        launch_config['BlockDeviceMappings'] = [block_device_mapping]

    if instance_profile_name is not None:
        launch_config['IamInstanceProfile'] = instance_profile_name

    if assign_public_ip is not None:
        launch_config['AssociatePublicIpAddress'] = assign_public_ip

    if user_data is not None:
        launch_config['UserData'] = user_data

    if ebs_optimized is not None:
        launch_config['EbsOptimized'] = ebs_optimized

    if len(launch_configs) == 0:
        try:
            connection.create_launch_configuration(**launch_config)
            launch_configs = connection.describe_launch_configurations(LaunchConfigurationNames=[name]).get('LaunchConfigurations')
            changed = True
            if launch_configs:
                launch_config = launch_configs[0]
        except botocore.exceptions.ClientError as e:
            module.fail_json(msg="Failed to create launch configuration", exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response))

    result = (dict((k, v) for k, v in launch_config.items()
              if k not in ['Connection', 'CreatedTime', 'InstanceMonitoring', 'BlockDeviceMappings']))

    result['CreatedTime'] = to_text(launch_config.get('CreatedTime'))

    try:
        result['InstanceMonitoring'] = module.boolean(launch_config.get('InstanceMonitoring').get('Enabled'))
    except AttributeError:
        result['InstanceMonitoring'] = False

    result['BlockDeviceMappings'] = []

    for block_device_mapping in launch_config.get('BlockDeviceMappings', []):
        result['BlockDeviceMappings'].append(dict(device_name=block_device_mapping.get('DeviceName'), virtual_name=block_device_mapping.get('VirtualName')))
        if block_device_mapping.get('Ebs') is not None:
            result['BlockDeviceMappings'][-1]['ebs'] = dict(
                snapshot_id=block_device_mapping.get('Ebs').get('SnapshotId'), volume_size=block_device_mapping.get('Ebs').get('VolumeSize'))

    if user_data_path:
        result['UserData'] = "hidden"  # Otherwise, we dump binary to the user's terminal

    return_object = {
        'Name': result.get('LaunchConfigurationName'),
        'CreatedTime': result.get('CreatedTime'),
        'ImageId': result.get('ImageId'),
        'Arn': result.get('LaunchConfigurationARN'),
        'SecurityGroups': result.get('SecurityGroups'),
        'InstanceType': result.get('InstanceType'),
        'Result': result
    }

    module.exit_json(changed=changed, **camel_dict_to_snake_dict(return_object))
Ejemplo n.º 20
0
def main():
    argument_spec = ec2_argument_spec()
    scan_args = dict(table_name=dict(required=True, type='str'),
                     index_name=dict(type='str'),
                     limit=dict(type='int'),
                     projection_expression=dict(type='list'),
                     filter_expression=dict(type='list'))
    argument_spec.update(scan_args)
    argument_spec.update(dict(simplify=dict(type='bool')))

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

    if not HAS_BOTO3:
        module.fail_json(msg='boto3 required for this module')

    region, ec2_url, aws_connect_params = get_aws_connection_info(module,
                                                                  boto3=True)

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

    try:
        args = {}
        for k, v in list(module.params.items()):
            if v and k in scan_args.keys():
                args[k] = v
        args = snake_dict_to_camel_dict(args, True)
        helper = DynamoDbConditionsHelper(module)

        if 'filter_expression' in module.params and type(
                module.params['filter_expression']) is list:
            expression = helper.build_filter_expression()
            args['FilterExpression'] = expression.condition_expression
            args[
                'ExpressionAttributeNames'] = expression.attribute_name_placeholders
            args[
                'ExpressionAttributeValues'] = expression.attribute_value_placeholders

        if 'ProjectionExpression' in args and type(
                args['ProjectionExpression']) is list:
            args['ProjectionExpression'] = ", ".join(
                args['ProjectionExpression'])

        result = connection.scan(**args)['Items']
        if 'simplify' in module.params.keys() and module.params['simplify']:
            result = helper.simplify(result)
    except ClientError as e:
        module.fail_json(msg=e.message, exception=traceback.format_exc())
    except ParamValidationError as e:
        msg = e.message + "\nexpression = " + str(expression)
        module.fail_json(msg=msg, exception=traceback.format_exc())

    module.exit_json(Items=result)
Ejemplo n.º 21
0
def modify_cluster(module, redshift):
    """
    Modify an existing cluster.

    module: Ansible module object
    redshift: authenticated redshift connection object
    """

    identifier = module.params.get('identifier')
    wait = module.params.get('wait')
    wait_timeout = module.params.get('wait_timeout')

    # Package up the optional parameters
    params = {}
    for p in ('cluster_type', 'cluster_security_groups',
              'vpc_security_group_ids', 'cluster_subnet_group_name',
              'availability_zone', 'preferred_maintenance_window',
              'cluster_parameter_group_name',
              'automated_snapshot_retention_period', 'port', 'cluster_version',
              'allow_version_upgrade', 'number_of_nodes',
              'new_cluster_identifier'):
        # https://github.com/boto/boto3/issues/400
        if module.params.get(p) is not None:
            params[p] = module.params.get(p)

    # enhanced_vpc_routing parameter change needs an exclusive request
    if module.params.get('enhanced_vpc_routing') is not None:
        try:
            redshift.modify_cluster(
                ClusterIdentifier=identifier,
                EnhancedVpcRouting=module.params.get('enhanced_vpc_routing'))
        except (botocore.exceptions.BotoCoreError,
                botocore.exceptions.ClientError) as e:
            module.fail_json_aws(e,
                                 msg="Couldn't modify redshift cluster %s " %
                                 identifier)
    if wait:
        attempts = wait_timeout // 60
        waiter = redshift.get_waiter('cluster_available')
        try:
            waiter.wait(ClusterIdentifier=identifier,
                        WaiterConfig=dict(MaxAttempts=attempts))
        except (botocore.exceptions.ClientError,
                botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(
                e,
                msg=
                "Timeout waiting for cluster enhanced vpc routing modification"
            )

    # change the rest
    try:
        redshift.modify_cluster(ClusterIdentifier=identifier,
                                **snake_dict_to_camel_dict(
                                    params, capitalize_first=True))
    except (botocore.exceptions.BotoCoreError,
            botocore.exceptions.ClientError) as e:
        module.fail_json_aws(e,
                             msg="Couldn't modify redshift cluster %s " %
                             identifier)

    if module.params.get('new_cluster_identifier'):
        identifier = module.params.get('new_cluster_identifier')

    if wait:
        attempts = wait_timeout // 60
        waiter2 = redshift.get_waiter('cluster_available')
        try:
            waiter2.wait(ClusterIdentifier=identifier,
                         WaiterConfig=dict(MaxAttempts=attempts))
        except (botocore.exceptions.ClientError,
                botocore.exceptions.BotoCoreError) as e:
            module.fail_json_aws(
                e, msg="Timeout waiting for cluster modification")
    try:
        resource = redshift.describe_clusters(
            ClusterIdentifier=identifier)['Clusters'][0]
    except (botocore.exceptions.BotoCoreError,
            botocore.exceptions.ClientError) as e:
        module.fail_json(e,
                         msg="Couldn't modify redshift cluster %s " %
                         identifier)

    return (True, _collect_facts(resource))
Ejemplo n.º 22
0
 def as_dict(self):
     result = self.__dict__
     result.pop("tags")
     return snake_dict_to_camel_dict(result)