Beispiel #1
0
def lambda_replication(event, context):
    """Perform replication in a single region when called by AWS Lambda."""

    # baseline logging for lambda
    logging.basicConfig(level=logging.INFO)
    LOG.setLevel(logging.INFO)
    logging.getLogger('botocore').setLevel(logging.WARNING)
    logging.getLogger('boto3').setLevel(logging.WARNING)

    if not (event and event.get('Records')):
        LOG.warn('lambda_replication must be invoked from an SNS topic')
        return

    records = event.get('Records')
    for record in records:
        sns = record.get('Sns')
        if not sns:
            LOG.warn('lambda_replication missing an SNS section: %s', str(event))
            continue

        message = sns.get('Message')
        if not message:
            LOG.warn('lambda_replication missing a message section: %s', str(event))
            continue

        message_json = json.loads(message)

        if 'region' not in message_json:
            LOG.warn('lambda_replication missing specific keys: %s', str(event))
            continue

        # call the snapshot cleanup method
        replication.perform_replication(context, message_json['region'])

    LOG.info('Function lambda_replication completed')
Beispiel #2
0
def test_perform_replication(mocker):
    """Test for method of the same name."""

    # some default settings for this test
    region_a = 'us-west-1'
    region_b = 'us-east-1'
    ctx = utils.MockContext()

    # setup some dummy configuration for snapshots
    mocks.create_dynamodb('us-east-1')
    snapshot_settings = {'snapshot': {'minimum': 5, 'frequency': '2 hours', 'retention': '5 days'},
                         'match': {'tag:backup': 'yes'}}
    dynamo.store_configuration('us-east-1', 'some_unique_id', AWS_MOCK_ACCOUNT, snapshot_settings)

    # clients
    client_a = boto3.client('ec2', region_name=region_a)
    client_b = boto3.client('ec2', region_name=region_b)

    # create a volume in region_a
    volume = client_a.create_volume(Size=100, AvailabilityZone=region_a + "a")
    snapshot_description = "Something from EBS Snapper"
    snapshot = client_a.create_snapshot(
        VolumeId=volume['VolumeId'],
        Description=snapshot_description
    )
    client_a.create_tags(
        Resources=[snapshot['SnapshotId']],
        Tags=[{'Key': 'replication_dst_region', 'Value': region_b}]
    )

    # trigger replication, assert that we copied a snapshot to region_b
    mocker.patch('ebs_snapper.utils.copy_snapshot_and_tag')
    replication.perform_replication(ctx, region_a)
    utils.copy_snapshot_and_tag.assert_any_call(  # pylint: disable=E1103
        ctx,
        region_a,
        region_b,
        snapshot['SnapshotId'],
        snapshot_description)

    # now create that snapshot manually
    replica_volume = client_b.create_volume(Size=100, AvailabilityZone=region_b + "a")
    replica_snapshot_description = "Something from EBS Snapper, copied to region b"
    replica_snapshot = client_b.create_snapshot(
        VolumeId=replica_volume['VolumeId'],
        Description=replica_snapshot_description
    )
    client_b.create_tags(
        Resources=[replica_snapshot['SnapshotId']],
        Tags=[
            {'Key': 'replication_src_region', 'Value': region_a},
            {'Key': 'replication_snapshot_id', 'Value': snapshot['SnapshotId']}
        ]
    )

    # trigger replication a second time, and confirm still one copy (not 2)
    utils.copy_snapshot_and_tag.reset_mock()
    replication.perform_replication(ctx, region_a)
    utils.copy_snapshot_and_tag.assert_not_called()  # pylint: disable=E1103

    # now delete the original and trigger replication, confirm replica deleted
    utils.delete_snapshot(snapshot['SnapshotId'], region_a)
    mocker.patch('ebs_snapper.utils.delete_snapshot')
    replication.perform_replication(ctx, region_b)
    utils.delete_snapshot.assert_any_call(  # pylint: disable=E1103
        replica_snapshot['SnapshotId'],
        region_b
    )