Beispiel #1
0
def _s3_decrypt_image(context, encrypted_filename, encrypted_key, encrypted_iv,
                      decrypted_filename):
    encrypted_key = binascii.a2b_hex(encrypted_key)
    encrypted_iv = binascii.a2b_hex(encrypted_iv)
    cert_client = clients.nova_cert(context)
    try:
        key = cert_client.decrypt_text(base64.b64encode(encrypted_key))
    except Exception as exc:
        msg = _('Failed to decrypt private key: %s') % exc
        raise exception.EC2Exception(msg)
    try:
        iv = cert_client.decrypt_text(base64.b64encode(encrypted_iv))
    except Exception as exc:
        msg = _('Failed to decrypt initialization vector: %s') % exc
        raise exception.EC2Exception(msg)

    try:
        processutils.execute('openssl', 'enc', '-d', '-aes-128-cbc', '-in',
                             '%s' % (encrypted_filename, ), '-K',
                             '%s' % (key, ), '-iv', '%s' % (iv, ), '-out',
                             '%s' % (decrypted_filename, ))
    except processutils.ProcessExecutionError as exc:
        raise exception.EC2Exception(
            _('Failed to decrypt image file '
              '%(image_file)s: %(err)s') % {
                  'image_file': encrypted_filename,
                  'err': exc.stdout
              })
Beispiel #2
0
def _decrypt_text(text):
    private_key_file = CONF.x509_root_private_key
    if not private_key_file:
        msg = _("Path to ca private key isn't configured")
        raise exception.EC2Exception(msg)
    with open(private_key_file, 'rb') as f:
        data = f.read()
    priv_key = serialization.load_pem_private_key(data, None,
                                                  backends.default_backend())
    return priv_key.decrypt(text, padding.PKCS1v15())
Beispiel #3
0
def db_sync(version=None):
    if version is not None:
        try:
            version = int(version)
        except ValueError:
            raise exception.EC2Exception(_("version should be an integer"))

    current_version = db_version()
    repository = _find_migrate_repo()
    if version is None or version > current_version:
        return versioning_api.upgrade(get_engine(), repository, version)
    else:
        return versioning_api.downgrade(get_engine(), repository, version)
Beispiel #4
0
def db_version():
    repository = _find_migrate_repo()
    try:
        return versioning_api.db_version(get_engine(), repository)
    except versioning_exceptions.DatabaseNotControlledError:
        meta = sqlalchemy.MetaData()
        engine = get_engine()
        meta.reflect(bind=engine)
        tables = meta.tables
        if len(tables) == 0:
            db_version_control(INIT_VERSION)
            return versioning_api.db_version(get_engine(), repository)
        else:
            # Some pre-Essex DB's may not be version controlled.
            # Require them to upgrade using Essex first.
            raise exception.EC2Exception(
                _("Upgrade DB using Essex release first."))
Beispiel #5
0
    def test_execute_error(self):
        @tools.screen_all_logs
        def do_check(ex, status, code, message):
            self.controller.reset_mock()
            self.controller.fake_action.side_effect = ex

            res = self.request.send(self.application)

            self.assertEqual(status, res.status_code)
            self.assertEqual('text/xml', res.content_type)
            expected_xml = fakes.XML_ERROR_TEMPLATE % {
                'code': code,
                'message': message,
                'request_id': self.fake_context.request_id
            }
            self.assertThat(res.body.decode("utf-8"),
                            matchers.XMLMatches(expected_xml))
            self.controller.fake_action.assert_called_once_with(
                self.fake_context, param='fake_param')

        do_check(exception.EC2Exception('fake_msg'), 400, 'EC2Exception',
                 'fake_msg')
        do_check(KeyError('fake_msg'), 500, 'KeyError',
                 'Unknown error occurred.')
        do_check(exception.InvalidVpcIDNotFound('fake_msg'), 400,
                 'InvalidVpcID.NotFound', 'fake_msg')
        do_check(nova_exception.BadRequest(400, message='fake_msg'), 400,
                 'BadRequest', 'fake_msg')
        do_check(glance_exception.HTTPBadRequest(), 400, 'HTTPBadRequest',
                 'HTTP HTTPBadRequest')
        do_check(cinder_exception.BadRequest(400, message='fake_msg'), 400,
                 'BadRequest', 'fake_msg')
        do_check(neutron_exception.BadRequest(message='fake_msg'), 400,
                 'BadRequest', 'fake_msg')
        do_check(keystone_exception.BadRequest(message='fake_msg'), 400,
                 'BadRequest', 'fake_msg (HTTP 400)')
        do_check(
            botocore_exceptions.ClientError(
                {
                    'Error': {
                        'Code': '',
                        'Message': ''
                    },
                    'Code': 'FakeCode',
                    'Message': 'fake_msg'
                }, 'register_image'), 400, 'FakeCode', 'fake_msg')
Beispiel #6
0
    def delayed_create(context, image, name, os_instance):
        try:
            os_instance.stop()

            # wait instance for really stopped
            start_time = time.time()
            while os_instance.status != 'SHUTOFF':
                time.sleep(1)
                os_instance.get()
                # NOTE(yamahata): timeout and error. 1 hour for now for safety.
                #                 Is it too short/long?
                #                 Or is there any better way?
                timeout = 1 * 60 * 60
                if time.time() > start_time + timeout:
                    err = (_("Couldn't stop instance within %d sec") % timeout)
                    raise exception.EC2Exception(message=err)

            # NOTE(ft): create an image with ec2_id metadata to let other code
            # link os and db objects in race conditions
            os_image_id = os_instance.create_image(
                name, metadata={'ec2_id': image['id']})
            image['os_id'] = os_image_id
            db_api.update_item(context, image)
        except Exception:
            LOG.exception(_LE('Failed to complete image %s creation'),
                          image.id)
            try:
                image['state'] = 'failed'
                db_api.update_item(context, image)
            except Exception:
                LOG.warning(_LW("Couldn't set 'failed' state for db image %s"),
                            image.id,
                            exc_info=True)

        try:
            os_instance.start()
        except Exception:
            LOG.warning(_LW('Failed to start instance %(i_id)s after '
                            'completed creation of image %(image_id)s'), {
                                'i_id': instance['id'],
                                'image_id': image['id']
                            },
                        exc_info=True)
Beispiel #7
0
    def __get_backend(self):
        if not self.__backend:
            if self.__config_group is None:
                backend_name = CONF[self.__pivot]
            else:
                backend_name = CONF[self.__config_group][self.__pivot]
            if backend_name not in self.__backends:
                msg = _('Invalid backend: %s') % backend_name
                raise exception.EC2Exception(msg)

            backend = self.__backends[backend_name]
            if isinstance(backend, tuple):
                name = backend[0]
                fromlist = backend[1]
            else:
                name = backend
                fromlist = backend

            self.__backend = __import__(name, None, None, fromlist)
        return self.__backend
Beispiel #8
0
def create_image(context,
                 instance_id,
                 name=None,
                 description=None,
                 no_reboot=False,
                 block_device_mapping=None):
    instance = ec2utils.get_db_item(context, instance_id)

    if not instance_api._is_ebs_instance(context, instance['os_id']):
        msg = _('Instance does not have a volume attached at root (null).')
        raise exception.InvalidParameterValue(value=instance_id,
                                              parameter='InstanceId',
                                              reason=msg)

    nova = clients.nova(context)
    os_instance = nova.servers.get(instance['os_id'])
    restart_instance = False
    if not no_reboot and os_instance.status != 'SHUTOFF':
        if os_instance.status != 'ACTIVE':
            # TODO(ft): Change the error code and message with the real AWS
            # ones
            msg = _('Instance must be run or stopped')
            raise exception.IncorrectState(reason=msg)

        restart_instance = True
        os_instance.stop()

        # wait instance for really stopped
        start_time = time.time()
        while os_instance.status != 'SHUTOFF':
            time.sleep(1)
            os_instance.get()
            # NOTE(yamahata): timeout and error. 1 hour for now for safety.
            #                 Is it too short/long?
            #                 Or is there any better way?
            timeout = 1 * 60 * 60
            if time.time() > start_time + timeout:
                err = _("Couldn't stop instance within %d sec") % timeout
                raise exception.EC2Exception(message=err)

    # meaningful image name
    name_map = dict(instance=instance['os_id'], now=timeutils.isotime())
    name = name or _('image of %(instance)s at %(now)s') % name_map

    glance = clients.glance(context)
    with common.OnCrashCleaner() as cleaner:
        os_image_id = os_instance.create_image(name)
        cleaner.addCleanup(glance.images.delete, os_image_id)
        # TODO(andrey-mp): snapshot and volume also must be deleted in case
        # of error
        os_image = glance.images.get(os_image_id)
        image = db_api.add_item(context, _get_os_image_kind(os_image), {
            'os_id': os_image_id,
            'is_public': False,
            'description': description
        })

    if restart_instance:
        os_instance.start()

    return {'imageId': image['id']}