Exemple #1
0
def test_object_get(mocker):
    test_data = '01234'
    with TemporaryDirectory() as tmp_dir:
        with utils.temp_file(tmp_dir) as input_file:
            with open(input_file, 'w') as writer:
                writer.write(test_data)
            with open(input_file, 'rb') as reader:

                class MockRawRequest():
                    def __init__(self):
                        self.raw = reader

                class MockOCI():
                    def __init__(self, *args, **kwargs):
                        pass

                    def get_object(self, *args, **kwargs):
                        return MockResponse(200, MockRawRequest())

                mocker.patch('backup_tool.oci_client.from_file',
                             return_value='')
                mocker.patch('backup_tool.oci_client.ObjectStorageClient',
                             return_value=MockOCI)
                mocker.patch('backup_tool.oci_client.to_dict',
                             side_effect=to_dict_mock)
                client = OCIObjectStorageClient(FAKE_CONFIG, FAKE_SECTION)
                # Make sure to pass page limit of 1
                with utils.temp_file(tmp_dir) as temp_file:
                    objects = client.object_get(FAKE_NAMESPACE, FAKE_BUCKET,
                                                'some-object-name', temp_file)
                    md5 = utils.md5(temp_file)
                    assert md5 == 'QQDE1E2pF3JH5EpfwVRneA=='
Exemple #2
0
def test_object_put_invalid_status(mocker):
    class MockOCI():
        def __init__(self, *args, **kwargs):
            pass

    class MockUploadManager():
        def __init__(self, *args, **kwargs):
            pass

        def upload_file(self, *args, **kwargs):
            return MockResponse(400, f'This aint Valyrian steel')

    mocker.patch('backup_tool.oci_client.from_file', return_value='')
    mocker.patch('backup_tool.oci_client.ObjectStorageClient',
                 return_value=MockOCI)
    mocker.patch('backup_tool.oci_client.UploadManager',
                 return_value=MockUploadManager)
    mocker.patch('backup_tool.oci_client.to_dict', side_effect=to_dict_mock)
    client = OCIObjectStorageClient(FAKE_CONFIG, FAKE_SECTION)
    fake_data = utils.random_string()
    with TemporaryDirectory() as tmp_dir:
        with utils.temp_file(tmp_dir) as temp_file:
            with open(temp_file, 'w+') as writer:
                writer.write(fake_data)
            with pytest.raises(ObjectStorageException) as error:
                client.object_put(FAKE_NAMESPACE, FAKE_BUCKET,
                                  'some-object-name', temp_file)
            assert str(
                error.value) == 'Error uploading object, Reponse code 400'
Exemple #3
0
def test_object_put(mocker):
    class MockOCI():
        def __init__(self, *args, **kwargs):
            pass

    class MockUploadManager():
        def __init__(self, *args, **kwargs):
            pass

        def upload_file(self, *args, **kwargs):
            return MockResponse(200, None)

    mocker.patch('backup_tool.oci_client.from_file', return_value='')
    mocker.patch('backup_tool.oci_client.ObjectStorageClient',
                 return_value=MockOCI)
    mocker.patch('backup_tool.oci_client.UploadManager',
                 return_value=MockUploadManager)
    mocker.patch('backup_tool.oci_client.to_dict', side_effect=to_dict_mock)
    client = OCIObjectStorageClient(FAKE_CONFIG, FAKE_SECTION)
    fake_data = utils.random_string()
    with TemporaryDirectory() as tmp_dir:
        with utils.temp_file(tmp_dir) as temp_file:
            with open(temp_file, 'w+') as writer:
                writer.write(fake_data)
                client.object_put(FAKE_NAMESPACE, FAKE_BUCKET,
                                  'some-object-name', temp_file)
Exemple #4
0
def test_object_get_restore_invalid_status(mocker):
    class MockOCI():
        def __init__(self, *args, **kwargs):
            pass

        def get_object(self, *args, **kwargs):
            raise ServiceError(400, 400, {}, "'code': 'NotRestored'")

        def restore_objects(self, *args, **kwargs):
            return MockResponse(400, None)

    mocker.patch('backup_tool.oci_client.from_file', return_value='')
    mocker.patch('backup_tool.oci_client.ObjectStorageClient',
                 return_value=MockOCI)
    mocker.patch('backup_tool.oci_client.to_dict', side_effect=to_dict_mock)
    client = OCIObjectStorageClient(FAKE_CONFIG, FAKE_SECTION)
    # Make sure to pass page limit of 1
    with TemporaryDirectory() as tmp_dir:
        with utils.temp_file(tmp_dir) as temp_file:
            with pytest.raises(ObjectStorageException) as error:
                client.object_get(FAKE_NAMESPACE,
                                  FAKE_BUCKET,
                                  'some-object-name',
                                  temp_file,
                                  set_restore=True)
        assert str(error.value) == 'Error restoring object, Response code 400'
Exemple #5
0
def test_setup_logger():
    '''
    Test basic logging to file
    '''
    with TemporaryDirectory() as tmp_dir:
        with utils.temp_file(tmp_dir) as temp:
            log = utils.setup_logger('test', 10, logging_file=temp)
        log.debug(f'Running log test with log file {temp}')
Exemple #6
0
def test_md5():
    '''
    Run md5 and make sure it matches expected
    '''
    # Hardcoded, this is what the base64 hash of foo is
    value = '07BzhNET7exJ6qYjitX/AA=='
    with TemporaryDirectory() as tmp_dir:
        with utils.temp_file(tmp_dir) as temp:
            with open(temp, 'w') as writer:
                writer.write('foo\n')
            md5_value = utils.md5(temp)
        assert md5_value == value, 'MD5 value not equal to expected'
Exemple #7
0
 def _file_backup_encrypt(self, local_file_path, local_file_md5):
     with utils.temp_file(self.work_directory, delete=False) as encrypted_file:
         self.logger.debug(f'Creating encrypted file "{str(encrypted_file)}" from file "{str(local_file_path)}"')
         check_local_file_md5, encrypted_file_md5 = crypto.encrypt_file(str(local_file_path), str(encrypted_file), self.crypto_key)
         if check_local_file_md5 != local_file_md5:
             self.logger.error(f'Unable to verify md5 during crypto phase for file "{str(local_file_path)}"')
             raise BackupToolClientException(f'Unable to verify md5 during crypto phase for file "{str(local_file_path)}"')
         self.logger.debug(f'Created encrypted file "{str(encrypted_file)}" with md5 "{encrypted_file_md5}" '
                         f' from original file "{str(local_file_path)}" with md5 "{local_file_md5}"')
         return {
             'local_file': str(local_file_path),
             'local_file_md5': local_file_md5,
             'encrypted_file': str(encrypted_file),
             'encrypted_file_md5': encrypted_file_md5,
         }
Exemple #8
0
    def file_restore(self, local_file_id, overwrite=False, set_restore=False): #pylint: disable=too-many-return-statements
        '''
        Restore file from object storage

        local_file_id   :   ID of local file database entry to restore locally
        overwrite       :   Overwrite local file if md5 does not match
        set_restore     :   If object is archived, attempt to restore
        '''
        self.logger.info(f'Restoring local file: {local_file_id}')

        local_file = self.db_session.query(BackupEntryLocalFile).get(local_file_id)
        if not local_file:
            self.logger.error(f'Unable to find local file: {local_file_id}')
            return False

        if not local_file.backup_entry_id:
            self.logger.error(f'No backup entry for local file: {local_file_id}')
            return False

        backup_entry = self.db_session.query(BackupEntry).get(local_file.backup_entry_id)

        if not backup_entry:
            self.logger.error(f'Expecting backup entry {local_file.backup_entry_id} does not exist')

        local_file_path = Path(local_file.local_file_path)
        if self.relative_path:
            local_file_path = self.relative_path / local_file_path

        if local_file_path.is_file():
            self.logger.debug(f'Checking local file "{str(local_file_path)}" md5')
            local_file_md5 = utils.md5(str(local_file_path))
            self.logger.debug(f'Local file "{str(local_file_path)}" has md5 sum {local_file_md5}')
            if backup_entry.original_md5_checksum == local_file_md5:
                if not overwrite:
                    self.logger.info(f'Local file "{str(local_file_path)}" has expected md5 {local_file_md5}')
                    return True

        # Write file to temp dir
        with utils.temp_file(self.work_directory) as encrypted_file:
            self.logger.info(f'Downloading object {backup_entry.uploaded_file_path} to temp file "{str(encrypted_file)}"')
            self.os_client.object_get(self.oci_namespace, self.oci_bucket,
                                      backup_entry.uploaded_file_path, str(encrypted_file), set_restore=set_restore)
            self.logger.info(f'Downloaded of object {backup_entry.uploaded_file_path} complete, written to temp file "{str(encrypted_file)}"')

            # Ensure dir of new decrypted file is created
            if not local_file_path.parent.exists():
                local_file_path.mkdir(parents=True)
            self.logger.debug(f'Decrypting temp file "{str(encrypted_file)}" to file "{str(local_file_path)}"')
            encrypted_file_md5, local_file_md5 = crypto.decrypt_file(str(encrypted_file),
                                                                     str(local_file_path),
                                                                     self.crypto_key)
            self.logger.debug(f'Decrypted file "{str(encrypted_file)}" with md5 "{encrypted_file_md5}" to '
                              f'file "{str(local_file_path)}" with md5 "{local_file_md5}"')
            if backup_entry.uploaded_md5_checksum != encrypted_file_md5:
                self.logger.error(f'Downloaded file "{str(encrypted_file)}" has unexpected md5 {encrypted_file_md5}, '
                                  f'expected {backup_entry.uploaded_md5_checksum}')
                return False

            if local_file_md5 != backup_entry.original_md5_checksum:
                self.logger.error(f'MD5 {local_file_md5} of decrypted file "{str(local_file_path)}" does not match expected {backup_entry.original_md5_checksum}')
                return False
        return True