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