Ejemplo n.º 1
0
def await_resource(conn, resource, status, module):
    start_time = time.time()
    wait_timeout = module.params.get('wait_timeout') + start_time
    check_interval = 5
    while wait_timeout > time.time() and resource.status != status:
        time.sleep(check_interval)
        if wait_timeout <= time.time():
            module.fail_json(msg="Timeout waiting for RDS resource %s" %
                             resource.name)
        if module.params.get('command') == 'snapshot':
            # Temporary until all the rds2 commands have their responses parsed
            if resource.name is None:
                module.fail_json(
                    msg="There was a problem waiting for RDS snapshot %s" %
                    resource.snapshot)
            # Back off if we're getting throttled, since we're just waiting anyway
            resource = AWSRetry.backoff(tries=5, delay=20, backoff=1.5)(
                conn.get_db_snapshot)(resource.name)
        else:
            # Temporary until all the rds2 commands have their responses parsed
            if resource.name is None:
                module.fail_json(
                    msg="There was a problem waiting for RDS instance %s" %
                    resource.instance)
            # Back off if we're getting throttled, since we're just waiting anyway
            resource = AWSRetry.backoff(tries=5, delay=20, backoff=1.5)(
                conn.get_db_instance)(resource.name)
            if resource is None:
                break
        # Some RDS resources take much longer than others to be ready. Check
        # less aggressively for slow ones to avoid throttling.
        if time.time() > start_time + 90:
            check_interval = 20
    return resource
Ejemplo n.º 2
0
def get_vpc(module, connection, vpc_id):
    # wait for vpc to be available
    try:
        connection.get_waiter('vpc_available').wait(VpcIds=[vpc_id])
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(
            e,
            msg="Unable to wait for VPC {0} to be available.".format(vpc_id))

    try:
        vpc_obj = AWSRetry.backoff(
            delay=3,
            tries=8,
            catch_extra_error_codes=['InvalidVpcID.NotFound'],
        )(connection.describe_vpcs)(VpcIds=[vpc_id])['Vpcs'][0]
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to describe VPCs")
    try:
        vpc_obj['ClassicLinkEnabled'] = get_classic_link_with_backoff(
            connection, vpc_id)
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to describe VPCs")

    return vpc_obj
Ejemplo n.º 3
0
def update_vpc_tags(connection, module, vpc_id, tags, name):

    if tags is None:
        tags = dict()

    tags.update({'Name': name})
    try:
        current_tags = dict((t['Key'], t['Value']) for t in connection.describe_tags(Filters=[{'Name': 'resource-id', 'Values': [vpc_id]}])['Tags'])
        if tags != current_tags:
            if not module.check_mode:
                tags = ansible_dict_to_boto3_tag_list(tags)
                vpc_obj = AWSRetry.backoff(
                    delay=1, tries=5,
                    catch_extra_error_codes=['InvalidVpcID.NotFound'],
                )(connection.create_tags)(Resources=[vpc_id], Tags=tags)

                # Wait for tags to be updated
                expected_tags = boto3_tag_list_to_ansible_dict(tags)
                filters = [{'Name': 'tag:{0}'.format(key), 'Values': [value]} for key, value in expected_tags.items()]
                connection.get_waiter('vpc_available').wait(VpcIds=[vpc_id], Filters=filters)

            return True
        else:
            return False
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to update tags")
Ejemplo n.º 4
0
def update_vpc_tags(connection, module, vpc_id, tags, name):

    if tags is None:
        tags = dict()

    tags.update({'Name': name})
    try:
        current_tags = dict(
            (t['Key'], t['Value'])
            for t in connection.describe_tags(Filters=[{
                'Name': 'resource-id',
                'Values': [vpc_id]
            }])['Tags'])
        if tags != current_tags:
            if not module.check_mode:
                tags = ansible_dict_to_boto3_tag_list(tags)
                vpc_obj = AWSRetry.backoff(
                    delay=1,
                    tries=5,
                    catch_extra_error_codes=['InvalidVpcID.NotFound'],
                )(connection.create_tags)(Resources=[vpc_id], Tags=tags)
            return True
        else:
            return False
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to update tags")
Ejemplo n.º 5
0
 def run_func(*args, **kwargs):
     try:
         result = AWSRetry.backoff(tries=8,
                                   delay=5,
                                   catch_extra_error_codes=[
                                       'DirectConnectClientException'
                                   ])(f)(*args, **kwargs)
     except (ClientError, BotoCoreError) as e:
         raise DirectConnectError(failure_msg, traceback.format_exc(),
                                  e)
     return result
def connection_exists(client,
                      connection_id=None,
                      connection_name=None,
                      verify=True):
    params = {}
    if connection_id:
        params['connectionId'] = connection_id
    try:
        response = AWSRetry.backoff(**retry_params)(
            client.describe_connections)(**params)
    except (BotoCoreError, ClientError) as e:
        if connection_id:
            msg = "Failed to describe DirectConnect ID {0}".format(
                connection_id)
        else:
            msg = "Failed to describe DirectConnect connections"
        raise DirectConnectError(msg=msg,
                                 last_traceback=traceback.format_exc(),
                                 exception=e)

    match = []
    connection = []

    # look for matching connections

    if len(response.get('connections', [])) == 1 and connection_id:
        if response['connections'][0]['connectionState'] != 'deleted':
            match.append(response['connections'][0]['connectionId'])
            connection.extend(response['connections'])

    for conn in response.get('connections', []):
        if connection_name == conn[
                'connectionName'] and conn['connectionState'] != 'deleted':
            match.append(conn['connectionId'])
            connection.append(conn)

    # verifying if the connections exists; if true, return connection identifier, otherwise return False
    if verify and len(match) == 1:
        return match[0]
    elif verify:
        return False
    # not verifying if the connection exists; just return current connection info
    elif len(connection) == 1:
        return {'connection': connection[0]}
    return {'connection': {}}
def create_connection(client, location, bandwidth, name, lag_id):
    if not name:
        raise DirectConnectError(msg="Failed to create a Direct Connect connection: name required.")
    params = {
        'location': location,
        'bandwidth': bandwidth,
        'connectionName': name,
    }
    if lag_id:
        params['lagId'] = lag_id

    try:
        connection = AWSRetry.backoff(**retry_params)(client.create_connection)(**params)
    except (BotoCoreError, ClientError) as e:
        raise DirectConnectError(msg="Failed to create DirectConnect connection {0}".format(name),
                                 last_traceback=traceback.format_exc(),
                                 exception=e)
    return connection['connectionId']
Ejemplo n.º 8
0
def create_connection(client, location, bandwidth, name, lag_id):
    if not name:
        raise DirectConnectError(msg="Failed to create a Direct Connect connection: name required.")
    params = {
        'location': location,
        'bandwidth': bandwidth,
        'connectionName': name,
    }
    if lag_id:
        params['lagId'] = lag_id

    try:
        connection = AWSRetry.backoff(**retry_params)(client.create_connection)(**params)
    except (BotoCoreError, ClientError) as e:
        raise DirectConnectError(msg="Failed to create DirectConnect connection {0}".format(name),
                                 last_traceback=traceback.format_exc(),
                                 exception=e)
    return connection['connectionId']
Ejemplo n.º 9
0
def get_vpc(module, connection, vpc_id):
    # wait for vpc to be available
    try:
        connection.get_waiter('vpc_available').wait(VpcIds=[vpc_id])
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Unable to wait for VPC {0} to be available.".format(vpc_id))

    try:
        vpc_obj = AWSRetry.backoff(
            delay=3, tries=8,
            catch_extra_error_codes=['InvalidVpcID.NotFound'],
        )(connection.describe_vpcs)(VpcIds=[vpc_id])['Vpcs'][0]
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to describe VPCs")
    try:
        vpc_obj['ClassicLinkEnabled'] = get_classic_link_with_backoff(connection, vpc_id)
    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to describe VPCs")

    return vpc_obj
    def list_elbs(self):
        elb_array, token = [], None
        get_elb_with_backoff = AWSRetry.backoff(tries=5, delay=5, backoff=2.0)(self.connection.get_all_load_balancers)
        while True:
            all_elbs = get_elb_with_backoff(marker=token)
            token = all_elbs.next_marker

            if all_elbs:
                if self.names:
                    for existing_lb in all_elbs:
                        if existing_lb.name in self.names:
                            elb_array.append(existing_lb)
                else:
                    elb_array.extend(all_elbs)
            else:
                break

            if token is None:
                break

        return list(map(self._get_elb_info, elb_array))
Ejemplo n.º 11
0
    def list_elbs(self):
        elb_array, token = [], None
        get_elb_with_backoff = AWSRetry.backoff(tries=5, delay=5, backoff=2.0)(self.connection.get_all_load_balancers)
        while True:
            all_elbs = get_elb_with_backoff(marker=token)
            token = all_elbs.next_marker

            if all_elbs:
                if self.names:
                    for existing_lb in all_elbs:
                        if existing_lb.name in self.names:
                            elb_array.append(existing_lb)
                else:
                    elb_array.extend(all_elbs)
            else:
                break

            if token is None:
                break

        return list(map(self._get_elb_info, elb_array))
def connection_exists(client, connection_id=None, connection_name=None, verify=True):
    params = {}
    if connection_id:
        params['connectionId'] = connection_id
    try:
        response = AWSRetry.backoff(**retry_params)(client.describe_connections)(**params)
    except (BotoCoreError, ClientError) as e:
        if connection_id:
            msg = "Failed to describe DirectConnect ID {0}".format(connection_id)
        else:
            msg = "Failed to describe DirectConnect connections"
        raise DirectConnectError(msg=msg,
                                 last_traceback=traceback.format_exc(),
                                 exception=e)

    match = []
    connection = []

    # look for matching connections

    if len(response.get('connections', [])) == 1 and connection_id:
        if response['connections'][0]['connectionState'] != 'deleted':
            match.append(response['connections'][0]['connectionId'])
            connection.extend(response['connections'])

    for conn in response.get('connections', []):
        if connection_name == conn['connectionName'] and conn['connectionState'] != 'deleted':
            match.append(conn['connectionId'])
            connection.append(conn)

    # verifying if the connections exists; if true, return connection identifier, otherwise return False
    if verify and len(match) == 1:
        return match[0]
    elif verify:
        return False
    # not verifying if the connection exists; just return current connection info
    elif len(connection) == 1:
        return {'connection': connection[0]}
    return {'connection': {}}
Ejemplo n.º 13
0
def update_vpc_tags(connection, module, vpc_id, tags, name):
    if tags is None:
        tags = dict()

    tags.update({'Name': name})
    tags = dict((k, to_native(v)) for k, v in tags.items())
    try:
        current_tags = dict(
            (t['Key'], t['Value'])
            for t in connection.describe_tags(Filters=[{
                'Name': 'resource-id',
                'Values': [vpc_id]
            }])['Tags'])
        tags_to_update, dummy = compare_aws_tags(current_tags, tags, False)
        if tags_to_update:
            if not module.check_mode:
                tags = ansible_dict_to_boto3_tag_list(tags_to_update)
                vpc_obj = AWSRetry.backoff(
                    delay=1,
                    tries=5,
                    catch_extra_error_codes=['InvalidVpcID.NotFound'],
                )(connection.create_tags)(Resources=[vpc_id], Tags=tags)

                # Wait for tags to be updated
                expected_tags = boto3_tag_list_to_ansible_dict(tags)
                filters = [{
                    'Name': 'tag:{0}'.format(key),
                    'Values': [value]
                } for key, value in expected_tags.items()]
                connection.get_waiter('vpc_available').wait(VpcIds=[vpc_id],
                                                            Filters=filters)

            return True
        else:
            return False
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to update tags")
Ejemplo n.º 14
0
def get_vpc(module, connection, vpc_id):
    try:
        vpc_obj = AWSRetry.backoff(
            delay=1,
            tries=5,
            catch_extra_error_codes=['InvalidVpcID.NotFound'],
        )(connection.describe_vpcs)(VpcIds=[vpc_id])['Vpcs'][0]
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:
        module.fail_json_aws(e, msg="Failed to describe VPCs")
    try:
        classic_link = connection.describe_vpc_classic_link(
            VpcIds=[vpc_id])['Vpcs'][0].get('ClassicLinkEnabled')
        vpc_obj['ClassicLinkEnabled'] = classic_link
    except botocore.exceptions.ClientError as e:
        if e.response["Error"][
                "Message"] == "The functionality you requested is not available in this region.":
            vpc_obj['ClassicLinkEnabled'] = False
        else:
            module.fail_json_aws(e, msg="Failed to describe VPCs")
    except botocore.exceptions.BotoCoreError as e:
        module.fail_json_aws(e, msg="Failed to describe VPCs")

    return vpc_obj
Ejemplo n.º 15
0
RETURN = '''#'''

try:
    import botocore
    from botocore.exceptions import BotoCoreError, ClientError
except ImportError:
    pass  # handled by AnsibleAWSModule

from ansible.module_utils.aws.core import AnsibleAWSModule, is_boto3_error_code
from ansible.module_utils.ec2 import boto3_conn, get_aws_connection_info, AWSRetry
from ansible.module_utils.ec2 import camel_dict_to_snake_dict, boto3_tag_list_to_ansible_dict

# this waits for an IAM role to become fully available, at the cost of
# taking a long time to fail when the IAM role/policy really is invalid
retry_unavailable_iam_on_put_delivery = AWSRetry.backoff(
    catch_extra_error_codes=['InsufficientDeliveryPolicyException'], )


def resource_exists(client, module, params):
    try:
        channel = client.describe_delivery_channels(
            DeliveryChannelNames=[params['name']],
            aws_retry=True,
        )
        return channel['DeliveryChannels'][0]
    except is_boto3_error_code('NoSuchDeliveryChannelException'):
        return
    except (botocore.exceptions.ClientError,
            botocore.exceptions.BotoCoreError) as e:  # pylint: disable=duplicate-except
        module.fail_json_aws(e)
 def run_func(*args, **kwargs):
     try:
         result = AWSRetry.backoff(tries=8, delay=5, catch_extra_error_codes=['DirectConnectClientException'])(f)(*args, **kwargs)
     except (ClientError, BotoCoreError) as e:
         raise DirectConnectError(failure_msg, traceback.format_exc(), e)
     return result