示例#1
0
文件: test.py 项目: jimvoll/brkt-cli
 def test_name_validation(self):
     name = 'Test123 ()[]./-\'@_'
     self.assertEquals(name, aws_service.validate_image_name(name))
     with self.assertRaises(aws_service.ImageNameError):
         aws_service.validate_image_name(None)
     with self.assertRaises(aws_service.ImageNameError):
         aws_service.validate_image_name('ab')
     with self.assertRaises(aws_service.ImageNameError):
         aws_service.validate_image_name('a' * 129)
     for c in '?!#$%^&*~`{}\|"<>':
         with self.assertRaises(aws_service.ImageNameError):
             aws_service.validate_image_name('test' + c)
示例#2
0
文件: test.py 项目: dancudds/brkt-cli
 def test_name_validation(self):
     name = "Test123 ()[]./-'@_"
     self.assertEquals(name, aws_service.validate_image_name(name))
     with self.assertRaises(aws_service.ImageNameError):
         aws_service.validate_image_name(None)
     with self.assertRaises(aws_service.ImageNameError):
         aws_service.validate_image_name("ab")
     with self.assertRaises(aws_service.ImageNameError):
         aws_service.validate_image_name("a" * 129)
     for c in '?!#$%^&*~`{}\|"<>':
         with self.assertRaises(aws_service.ImageNameError):
             aws_service.validate_image_name("test" + c)
示例#3
0
def _connect_and_validate(aws_svc, values, encryptor_ami_id):
    """ Connect to the AWS service and validate command-line options

    :param aws_svc: the BaseAWSService implementation
    :param values: object that was generated by argparse
    """
    if values.encrypted_ami_name:
        try:
            aws_service.validate_image_name(values.encrypted_ami_name)
        except aws_service.ImageNameError as e:
            raise ValidationError(e.message)

    regions = [str(r.name) for r in aws_svc.get_regions()]
    if values.region not in regions:
        raise ValidationError(
            'Invalid region %s.  Must be one of %s.' %
            (values.region, str(regions)))

    aws_svc.connect(values.region, key_name=values.key_name)

    try:
        if values.key_name:
            aws_svc.get_key_pair(values.key_name)

        if values.validate:
            _validate_subnet_and_security_groups(
                aws_svc, values.subnet_id, values.security_group_ids)

            error_msg = aws_svc.validate_guest_ami(values.ami)
            if error_msg:
                raise ValidationError(error_msg)

            error_msg = aws_svc.validate_encryptor_ami(encryptor_ami_id)
            if error_msg:
                raise ValidationError(error_msg)
        else:
            log.debug('Skipping validation')

        if values.encrypted_ami_name:
            filters = {'name': values.encrypted_ami_name}
            if aws_svc.get_images(filters=filters):
                raise ValidationError(
                        'There is already an image named %s' %
                        values.encrypted_ami_name
                )
    except EC2ResponseError as e:
        raise ValidationError(e.message)
示例#4
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
示例#5
0
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
示例#6
0
def command_update_encrypted_ami(values, log):
    encrypted_ami_name = None
    if values.encrypted_ami_name:
        try:
            aws_service.validate_image_name(values.encrypted_ami_name)
            encrypted_ami_name = values.encrypted_ami_name
        except aws_service.ImageNameError as e:
            print(e.message, file=sys.stderr)
            return 1
    region = values.region
    nonce = util.make_nonce()
    default_tags = encrypt_ami.get_default_tags(nonce, '')
    aws_svc = aws_service.AWSService(
        nonce, default_tags=default_tags)
    if not aws_svc.validate_region(region):
        print ('Invalid region %s' % region,
               file=sys.stderr)
        return 1
    aws_svc.connect(region)
    encrypted_ami = values.ami
    if not values.no_validate_ami:
        guest_ami_error = aws_svc.validate_guest_encrypted_ami(encrypted_ami)
        if guest_ami_error:
            print ('Encrypted AMI verification failed: %s' % guest_ami_error,
                   file=sys.stderr)
            return 1
    else:
        log.info('skipping AMI verification')
    updater_ami = values.updater_ami
    updater_ami_error = aws_svc.validate_encryptor_ami(values.updater_ami)
    if updater_ami_error:
        log.error('Update failed: %s', updater_ami_error)
        return 1
    # Initial validation done
    log.info('Updating %s', encrypted_ami)
    # snapshot the guest's volume
    guest_snapshot, volume_info, error = \
        update_encrypted_ami.retrieve_guest_volume_snapshot(
            aws_svc,
            encrypted_ami)
    if not guest_snapshot:
        log.error('failed to launch instance %s: %s' % (encrypted_ami, error))
        return 1
    log.info('Launching metavisor update encryptor instance')
    updater_ami_block_devices = \
        update_encrypted_ami.snapshot_updater_ami_block_devices(
            aws_svc,
            encrypted_ami,
            updater_ami,
            guest_snapshot.id,
            volume_info['size'])
    ami = encrypt_ami.register_new_ami(
        aws_svc,
        updater_ami_block_devices[encrypt_ami.NAME_METAVISOR_GRUB_SNAPSHOT],
        updater_ami_block_devices[encrypt_ami.NAME_METAVISOR_ROOT_SNAPSHOT],
        updater_ami_block_devices[encrypt_ami.NAME_METAVISOR_LOG_SNAPSHOT],
        guest_snapshot,
        volume_info['type'],
        volume_info['iops'],
        encrypted_ami,
        encrypted_ami_name=encrypted_ami_name)
    log.info('Done.')
    print(ami)
    return 0