# ============================================================================== # == Purpose: Enable Server Access Logging on specific S3 Legacy Buckets. # == Assumption: 1. Destination S3 Bucket has ACL log-delivery-write set. # == 2. S3 target bucket on the choosen destination has to exist. # == # == INSTRUCTIONS: 1. This script must be ran from the same location where target # == buckets exists. (It's not possible to enable logging accross regions.) # == # == Release Date: 11.27.2019 # == Version: 2.6 # == Testing Env: DataArt AWS account. # == # == Change 11.27.2019: add boto3.session, removed sys library as we've changed logic, # == changed variable names for suitable descriptions, print lines, # == add destination bucket using get_caller_identity method and # == update file name from S3.py to S3_Enable_Logging.py. # == # == Change 12.02.2019: add check for logging enabled, add ClientError msg, modify # == output messages, adding profile, region, bucket file and # == parsing region variable into destination_bucket variable, # == replacing "put" method for "put_bucket_logging" method, # == remove resource as it was not being used # == # == Change 12.04.2019: removed nested try\except blocks for a cleaner code, added # == hability to request for an input file, chenged integers for # == booleans values, added in what region the bucket is located # == # == Change 12.05.2019: replacing "is_enabled" var since it's not required # == # == Change 12.09.2019: replacing sys.argv for argparse and compacting arguments, added # == if name == main, removed unused variables, fixing account # == id error, transform account_id = args.profile to: # == account_id = profile.client('sts').get_caller_identity().get('Account') # == Change 12.10.2019 removing unnecesary variable var_none since default buckets do not # == need region name in its location, adding LocationConstraint to result. # == # == Change 12.11.2019 added check to see if target bucket is on bucket's files # == added logging # == # == Author: DataArt. # ============================================================================== import argparse import boto3 from botocore.exceptions import ClientError import logging # ============================================================================== # Define login argument's function def parse_arguments(): parser = argparse.ArgumentParser() parser.add_argument('--input_file', help='Input File', required=True) return parser.parse_args() # ============================================================================== if __name__ == "__main__": logger = logging.getLogger('') logger.setLevel(logging.DEBUG) # declaring argument's variable with compacted parsed user arguments args = parse_arguments() # ============================================================================== # Seting up boto3 s3_client = boto3.client('s3') # Seting up variable to get the proper account id to be parsed account_id = boto3.client('sts').get_caller_identity().get('Account') # ============================================================================== # Open S3_Legacy_Buckets file where a list of buckets has been defined and loop through it with open(args.input_file,'r') as input_file: for line in input_file: # Removing carrier return bucket_name = line.rstrip('\n') try: # Checking on what region the bucket is located result = s3_client.get_bucket_location(Bucket=bucket_name) # This has to be done because for buckets created in the US Standard region, # us-east-1, the value of LocationConstraint will be null # ref: http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region if result['LocationConstraint'] == None: destination_bucket = f"security-{account_id}-logs" else: # declare variable to hold target bucket name destination_bucket = f"security-{account_id}-eu-west-1-logs" # If target bucket has been entered in bucket file do not process it if bucket_name != destination_bucket: # adding target bucket prefix if 'dev-delphi' in bucket_name: s3_prefix = f"s3/dev-delphi/{bucket_name.replace('dev-delphi-', '')}/" elif 'dev-apollo' in bucket_name: s3_prefix = f"s3/dev-apollo/{bucket_name.replace('dev-apollo-', '')}/" elif 'uat-apollo' in bucket_name: s3_prefix = f"s3/uat-apollo/{bucket_name.replace('uat-apollo-', '')}/" else: s3_prefix = f"s3/{bucket_name}/" # checking for the existence of the bucket s3_client.head_bucket(Bucket=bucket_name) # checking if logging is enabled check_if_enabled = s3_client.get_bucket_logging( Bucket=bucket_name ) if 'LoggingEnabled' in check_if_enabled: print('\n' + '-> bucket name ' + bucket_name + \ ' does exist and logging is enabled') else: print('\n' + '-> bucket name ' + bucket_name + \ ' does exist but logging is not enabled. ENABLING...') # using put method from the bucket logging resource to indicate # required attributes to be set response = s3_client.put_bucket_logging( Bucket=bucket_name, BucketLoggingStatus={ 'LoggingEnabled': { 'TargetBucket': destination_bucket, 'TargetPrefix': s3_prefix } }, ) # Exception except ClientError as e: if e.response['Error']['Message']: print(e.response['Error']['Message']) else: pass # ==============================================================================