feature(backups): provider storage and retrieval

pull/35/head
Houkime 2023-03-13 19:03:41 +00:00 committed by Inex Code
parent 48dc63a590
commit 02deae217d
3 changed files with 67 additions and 6 deletions

View File

@ -1,17 +1,25 @@
from typing import List
from selfprivacy_api.models.backup.snapshot import Snapshot
from selfprivacy_api.models.backup.provider import BackupProviderModel
from selfprivacy_api.utils.singleton_metaclass import SingletonMetaclass
from selfprivacy_api.utils import ReadUserData
from selfprivacy_api.utils.redis_pool import RedisPool
from selfprivacy_api.utils.redis_model_storage import store_model_as_hash, hash_as_model
from selfprivacy_api.services import get_service_by_id
from selfprivacy_api.services.service import Service
from selfprivacy_api.backup.providers.provider import AbstractBackupProvider
from selfprivacy_api.backup.providers import get_provider
from selfprivacy_api.backup.providers import get_provider, get_kind
from selfprivacy_api.graphql.queries.providers import BackupProvider
REDIS_PROVIDER_KEY = "backups:provider"
redis = RedisPool().get_connection()
# Singleton has a property of being persistent between tests.
# I don't know what to do with this yet
@ -37,6 +45,29 @@ class Backups:
provider_class = get_provider(BackupProvider[kind])
return provider_class(login=login, key=key)
@staticmethod
def store_provider_redis(provider: AbstractBackupProvider):
store_model_as_hash(
redis,
REDIS_PROVIDER_KEY,
BackupProviderModel(
kind=get_kind(provider), login=provider.login, key=provider.key
),
)
@staticmethod
def load_provider_redis() -> AbstractBackupProvider:
provider_model = hash_as_model(redis, REDIS_PROVIDER_KEY, BackupProviderModel)
if provider_model is None:
return None
return Backups.construct_provider(
provider_model.kind, provider_model.login, provider_model.key
)
@staticmethod
def reset():
redis.delete(REDIS_PROVIDER_KEY)
def lookup_provider(self) -> AbstractBackupProvider:
redis_provider = Backups.load_provider_redis()
if redis_provider is not None:
@ -48,10 +79,6 @@ class Backups:
return Backups.construct_provider("MEMORY", login="", key="")
@staticmethod
def load_provider_redis() -> AbstractBackupProvider:
pass
@staticmethod
def load_provider_json() -> AbstractBackupProvider:
with ReadUserData() as user_data:

View File

@ -14,3 +14,9 @@ PROVIDER_MAPPING = {
def get_provider(provider_type: BackupProvider) -> AbstractBackupProvider:
return PROVIDER_MAPPING[provider_type]
def get_kind(provider: AbstractBackupProvider) -> str:
for key, value in PROVIDER_MAPPING.items():
if isinstance(provider, value):
return key.value

View File

@ -23,7 +23,16 @@ REPO_NAME = "test_backup"
@pytest.fixture(scope="function")
def backups(tmpdir):
test_repo_path = path.join(tmpdir, "totallyunrelated")
return Backups(test_repo_path)
backups = Backups(test_repo_path)
backups.reset()
return backups
@pytest.fixture()
def backups_backblaze(generic_userdata):
backups = Backups()
backups.reset()
return backups
@pytest.fixture()
@ -75,6 +84,7 @@ def file_backup(tmpdir) -> AbstractBackupProvider:
def test_config_load(generic_userdata):
backups = Backups()
backups.reset()
provider = backups.provider
assert provider is not None
@ -145,3 +155,21 @@ def test_sizing(backups, dummy_service):
size = backups.service_snapshot_size(dummy_service, snap.id)
assert size is not None
assert size > 0
def test_redis_storage(backups_backblaze):
backups = Backups()
backups.reset()
provider = backups.provider
assert provider is not None
assert isinstance(provider, Backblaze)
assert provider.login == "ID"
assert provider.key == "KEY"
backups.store_provider_redis(provider)
restored_provider = backups.load_provider_redis()
assert isinstance(restored_provider, Backblaze)
assert restored_provider.login == "ID"
assert restored_provider.key == "KEY"