def command_encrypt_ami(values, log): session_id = util.make_nonce() encryptor_ami = ( values.encryptor_ami or encrypt_ami.get_encryptor_ami(values.region) ) default_tags = encrypt_ami.get_default_tags(session_id, encryptor_ami) aws_svc = aws_service.AWSService( session_id, default_tags=default_tags) _connect_and_validate(aws_svc, values, encryptor_ami) log.info('Starting encryptor session %s', aws_svc.session_id) encrypted_image_id = encrypt_ami.encrypt( aws_svc=aws_svc, enc_svc_cls=encryptor_service.EncryptorService, image_id=values.ami, encryptor_ami=encryptor_ami, encrypted_ami_name=values.encrypted_ami_name, subnet_id=values.subnet_id, security_group_ids=values.security_group_ids, brkt_env=values.brkt_env ) # Print the AMI ID to stdout, in case the caller wants to process # the output. Log messages go to stderr. print(encrypted_image_id) return 0
def command_update_encrypted_ami(values, log): nonce = util.make_nonce() default_tags = encrypt_ami.get_default_tags(nonce, '') aws_svc = aws_service.AWSService( nonce, default_tags=default_tags) encryptor_ami = ( values.encryptor_ami or encrypt_ami.get_encryptor_ami(values.region) ) _connect_and_validate(aws_svc, values, encryptor_ami) encrypted_ami = values.ami if values.validate: guest_ami_error = aws_svc.validate_guest_encrypted_ami(encrypted_ami) if guest_ami_error: raise ValidationError( 'Encrypted AMI verification failed: %s' % guest_ami_error) else: log.info('skipping AMI verification') guest_image = aws_svc.get_image(encrypted_ami) mv_image = aws_svc.get_image(encryptor_ami) if (guest_image.virtualization_type != mv_image.virtualization_type): log.error("Encryptor virtualization_type mismatch") return 1 encrypted_ami_name = values.encrypted_ami_name if not encrypted_ami_name: # Replace nonce in AMI name name = guest_image.name m = re.match('(.+) \(encrypted (\S+)\)', name) if m: encrypted_ami_name = m.group(1) + ' (encrypted %s)' % (nonce,) else: encrypted_ami_name = name + ' (encrypted %s)' % (nonce,) filters = {'name': encrypted_ami_name} if aws_svc.get_images(filters=filters): raise ValidationError( 'There is already an image named %s' % encrypted_ami_name ) # Initial validation done log.info('Updating %s with new metavisor %s', encrypted_ami, encryptor_ami) updated_ami_id = update_ami( aws_svc, encrypted_ami, encryptor_ami, encrypted_ami_name, subnet_id=values.subnet_id, security_group_ids=values.security_group_ids) print(updated_ami_id) return 0
def main(): parser = argparse.ArgumentParser() parser.add_argument( '-v', '--verbose', dest='verbose', action='store_true', help='Print status information to the console' ) parser.add_argument( '--version', action='version', version='brkt-cli version %s' % VERSION ) subparsers = parser.add_subparsers() encrypt_ami_parser = subparsers.add_parser('encrypt-ami') encrypt_ami_args.setup_encrypt_ami_args(encrypt_ami_parser) argv = sys.argv[1:] values = parser.parse_args(argv) region = values.region # Initialize logging. Log messages are written to stderr and are # prefixed with a compact timestamp, so that the user knows how long # each operation took. if values.verbose: log_level = logging.DEBUG else: # Boto logs auth errors and 401s at ERROR level by default. boto.log.setLevel(logging.FATAL) log_level = logging.INFO # Set the log level of our modules explicitly. We can't set the # default log level to INFO because we would see INFO messages from # boto and other 3rd party libraries in the command output. logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%H:%M:%S') global log log = logging.getLogger(__name__) log.setLevel(log_level) aws_service.log.setLevel(log_level) encryptor_service.log.setLevel(log_level) if values.encrypted_ami_name: try: aws_service.validate_image_name(values.encrypted_ami_name) except aws_service.ImageNameError as e: print(e.message, file=sys.stderr) return 1 # Validate the region. regions = [str(r.name) for r in boto.vpc.regions()] if region not in regions: print( 'Invalid region %s. Must be one of %s.' % (region, str(regions)), file=sys.stderr ) return 1 encryptor_ami = values.encryptor_ami if not encryptor_ami: try: encryptor_ami = encrypt_ami.get_encryptor_ami(region) except: log.exception('Failed to get encryptor AMI.') return 1 session_id = util.make_nonce() default_tags = encrypt_ami.get_default_tags(session_id, encryptor_ami) try: # Connect to AWS. aws_svc = aws_service.AWSService( session_id, encryptor_ami, default_tags=default_tags) aws_svc.connect(region, key_name=values.key_name) except NoAuthHandlerFound: msg = ( 'Unable to connect to AWS. Are your AWS_ACCESS_KEY_ID and ' 'AWS_SECRET_ACCESS_KEY environment variables set?' ) if values.verbose: log.exception(msg) else: log.error(msg) return 1 try: if values.key_name: # Validate the key pair name. aws_svc.get_key_pair(values.key_name) if not values.no_validate_ami: error = aws_svc.validate_guest_ami(values.ami) if error: print(error, file=sys.stderr) return 1 error = aws_svc.validate_encryptor_ami(encryptor_ami) if error: print(error, file=sys.stderr) return 1 log.info('Starting encryptor session %s', aws_svc.session_id) encrypted_image_id = encrypt_ami.encrypt( aws_svc=aws_svc, enc_svc_cls=encryptor_service.EncryptorService, image_id=values.ami, encryptor_ami=encryptor_ami, encrypted_ami_name=values.encrypted_ami_name ) # Print the AMI ID to stdout, in case the caller wants to process # the output. Log messages go to stderr. print(encrypted_image_id) return 0 except EC2ResponseError as e: if e.error_code == 'AuthFailure': msg = 'Check your AWS login credentials and permissions' if values.verbose: log.exception(msg) else: log.error(msg + ': ' + e.error_message) elif e.error_code == 'InvalidKeyPair.NotFound': if values.verbose: log.exception(e.error_message) else: log.error(e.error_message) elif e.error_code == 'UnauthorizedOperation': if values.verbose: log.exception(e.error_message) else: log.error(e.error_message) log.error( 'Unauthorized operation. Check the IAM policy for your ' 'AWS account.' ) else: raise except util.BracketError as e: if values.verbose: log.exception(e.message) else: log.error(e.message) except KeyboardInterrupt: if values.verbose: log.exception('Interrupted by user') else: log.error('Interrupted by user') return 1
def command_encrypt_ami(values, log): region = values.region # Initialize logging. Log messages are written to stderr and are # prefixed with a compact timestamp, so that the user knows how long # each operation took. if values.verbose: log_level = logging.DEBUG else: # Boto logs auth errors and 401s at ERROR level by default. boto.log.setLevel(logging.FATAL) log_level = logging.INFO if values.encrypted_ami_name: try: aws_service.validate_image_name(values.encrypted_ami_name) except aws_service.ImageNameError as e: print(e.message, file=sys.stderr) return 1 # Validate the region. regions = [str(r.name) for r in boto.vpc.regions()] if region not in regions: print( 'Invalid region %s. Must be one of %s.' % (region, str(regions)), file=sys.stderr ) return 1 encryptor_ami = values.encryptor_ami if not encryptor_ami: try: encryptor_ami = encrypt_ami.get_encryptor_ami(region) except: log.exception('Failed to get encryptor AMI.') return 1 session_id = util.make_nonce() default_tags = encrypt_ami.get_default_tags(session_id, encryptor_ami) try: # Connect to AWS. aws_svc = aws_service.AWSService( session_id, default_tags=default_tags) aws_svc.connect(region, key_name=values.key_name) except NoAuthHandlerFound: msg = ( 'Unable to connect to AWS. Are your AWS_ACCESS_KEY_ID and ' 'AWS_SECRET_ACCESS_KEY environment variables set?' ) if values.verbose: log.exception(msg) else: log.error(msg) return 1 try: if values.key_name: # Validate the key pair name. aws_svc.get_key_pair(values.key_name) if not values.no_validate_ami: error = aws_svc.validate_guest_ami(values.ami) if error: print(error, file=sys.stderr) return 1 error = aws_svc.validate_encryptor_ami(encryptor_ami) if error: print(error, file=sys.stderr) return 1 log.info('Starting encryptor session %s', aws_svc.session_id) encrypted_image_id = encrypt_ami.encrypt( aws_svc=aws_svc, enc_svc_cls=encryptor_service.EncryptorService, image_id=values.ami, encryptor_ami=encryptor_ami, encrypted_ami_name=values.encrypted_ami_name ) # Print the AMI ID to stdout, in case the caller wants to process # the output. Log messages go to stderr. print(encrypted_image_id) return 0 except EC2ResponseError as e: if e.error_code == 'AuthFailure': msg = 'Check your AWS login credentials and permissions' if values.verbose: log.exception(msg) else: log.error(msg + ': ' + e.error_message) elif e.error_code == 'InvalidKeyPair.NotFound': if values.verbose: log.exception(e.error_message) else: log.error(e.error_message) elif e.error_code == 'UnauthorizedOperation': if values.verbose: log.exception(e.error_message) else: log.error(e.error_message) log.error( 'Unauthorized operation. Check the IAM policy for your ' 'AWS account.' ) else: raise except util.BracketError as e: if values.verbose: log.exception(e.message) else: log.error(e.message) except KeyboardInterrupt: if values.verbose: log.exception('Interrupted by user') else: log.error('Interrupted by user') return 1