"""Lambda function module.""" from urllib import parse from constants import common import common_config import s3 # noqa import sentry # noqa def process_dynamodb_event(event): """Process a single DynamoDB event and extract bucket name and key. Args: event (dict): A single DynamoDB event Returns: tuple: (bucket_name, key) which are extracted from the event """ data = event['dynamodb']['OldImage'] bucket_name = data['bucket_name']['S'] key = data['file_key']['S'] key = parse.unquote_plus(key) return bucket_name, key def process_dynamodb_events(records): """Process a list of DynamoDB events and extract remove records. Args: records (list): list of events Returns: list: list of keys to delete """ keys = [] for dynamodb_event in records: if dynamodb_event.get('eventName') != 'REMOVE': # ignore everything but REMOVE events continue bucket_name, key = process_dynamodb_event(dynamodb_event) unexpected_bucket = bucket_name != common_config.S3_BUCKET_NAME unexpected_dir = not key.startswith( common_config.S3_BUCKET_FOLDER) if unexpected_bucket or unexpected_dir: if unexpected_bucket: msg = 'Got unexpected bucket, expected: {}, got: {}'.format( common_config.S3_BUCKET_NAME, bucket_name) else: msg = 'Got unexpected folder, expected: {}; got: {}'.format( common_config.S3_BUCKET_FOLDER, key) common_config.logger.info(msg) continue keys.append(key) return keys @sentry.sentry_capture_exception def handler(event, context): """Process DynamoDB events from statement attachments error table.""" if common_config.IGNORE_ALL_EVENTS is not None: common_config.logger.warning(common.IGNORE_MESSAGE) return records = event.get('Records') if records is None: return keys = process_dynamodb_events(records) if not keys: return common_config.logger.info('Deleting keys: {}'.format(keys)) response = s3.delete_objects( bucket=common_config.S3_BUCKET_NAME, keys=keys, quiet=True) if response['ResponseMetadata']['HTTPStatusCode'] != 200: common_config.logger.error('Bad response: {}'.format(response))