selfprivacy-rest-api/selfprivacy_api/resources/services/restic.py

242 lines
6.9 KiB
Python

#!/usr/bin/env python3
"""Backups management module"""
from flask_restful import Resource, reqparse
from selfprivacy_api.resources.services import api
from selfprivacy_api.utils import WriteUserData
from selfprivacy_api.restic_controller import tasks as restic_tasks
from selfprivacy_api.restic_controller import ResticController, ResticStates
class ListAllBackups(Resource):
"""List all restic backups"""
def get(self):
"""
Get all restic backups
---
tags:
- Backups
security:
- bearerAuth: []
responses:
200:
description: A list of snapshots
400:
description: Bad request
401:
description: Unauthorized
"""
restic = ResticController()
return restic.snapshot_list
class AsyncCreateBackup(Resource):
"""Create a new restic backup"""
def put(self):
"""
Initiate a new restic backup
---
tags:
- Backups
security:
- bearerAuth: []
responses:
200:
description: Backup creation has started
400:
description: Bad request
401:
description: Unauthorized
409:
description: Backup already in progress
"""
restic = ResticController()
if restic.state is ResticStates.NO_KEY:
return {"error": "No key provided"}, 400
if restic.state is ResticStates.INITIALIZING:
return {"error": "Backup is initializing"}, 400
if restic.state is ResticStates.BACKING_UP:
return {"error": "Backup is already running"}, 409
restic_tasks.start_backup()
return {
"status": 0,
"message": "Backup creation has started",
}
class CheckBackupStatus(Resource):
"""Check current backup status"""
def get(self):
"""
Get backup status
---
tags:
- Backups
security:
- bearerAuth: []
responses:
200:
description: Backup status
400:
description: Bad request
401:
description: Unauthorized
"""
restic = ResticController()
return {
"status": restic.state.name,
"progress": restic.progress,
"error_message": restic.error_message,
}
class ForceReloadSnapshots(Resource):
"""Force reload snapshots"""
def get(self):
"""
Force reload snapshots
---
tags:
- Backups
security:
- bearerAuth: []
responses:
200:
description: Snapshots reloaded
400:
description: Bad request
401:
description: Unauthorized
"""
restic_tasks.load_snapshots()
return {
"status": 0,
"message": "Snapshots reload started",
}
class AsyncRestoreBackup(Resource):
"""Trigger backup restoration process"""
def put(self):
"""
Start backup restoration
---
tags:
- Backups
security:
- bearerAuth: []
parameters:
- in: body
required: true
name: backup
description: Backup to restore
schema:
type: object
required:
- backupId
properties:
backupId:
type: string
responses:
200:
description: Backup restoration process started
400:
description: Bad request
401:
description: Unauthorized
"""
parser = reqparse.RequestParser()
parser.add_argument("backupId", type=str, required=True)
args = parser.parse_args()
restic = ResticController()
if restic.state is ResticStates.NO_KEY:
return {"error": "No key provided"}, 400
if restic.state is ResticStates.NOT_INITIALIZED:
return {"error": "Repository is not initialized"}, 400
if restic.state is ResticStates.BACKING_UP:
return {"error": "Backup is already running"}, 409
if restic.state is ResticStates.INITIALIZING:
return {"error": "Repository is initializing"}, 400
if restic.state is ResticStates.RESTORING:
return {"error": "Restore is already running"}, 409
for backup in restic.snapshot_list:
if backup["short_id"] == args["backupId"]:
restic_tasks.restore_from_backup(args["backupId"])
return {
"status": 0,
"message": "Backup restoration procedure started",
}
return {"error": "Backup not found"}, 404
class BackblazeConfig(Resource):
"""Backblaze config"""
def put(self):
"""
Set the new key for backblaze
---
tags:
- Backups
security:
- bearerAuth: []
parameters:
- in: body
required: true
name: backblazeSettings
description: New Backblaze settings
schema:
type: object
required:
- accountId
- accountKey
- bucket
properties:
accountId:
type: string
accountKey:
type: string
bucket:
type: string
responses:
200:
description: New Backblaze settings
400:
description: Bad request
401:
description: Unauthorized
"""
parser = reqparse.RequestParser()
parser.add_argument("accountId", type=str, required=True)
parser.add_argument("accountKey", type=str, required=True)
parser.add_argument("bucket", type=str, required=True)
args = parser.parse_args()
with WriteUserData() as data:
if "backblaze" not in data:
data["backblaze"] = {}
data["backblaze"]["accountId"] = args["accountId"]
data["backblaze"]["accountKey"] = args["accountKey"]
data["backblaze"]["bucket"] = args["bucket"]
restic_tasks.update_keys_from_userdata()
return "New Backblaze settings saved"
api.add_resource(ListAllBackups, "/restic/backup/list")
api.add_resource(AsyncCreateBackup, "/restic/backup/create")
api.add_resource(CheckBackupStatus, "/restic/backup/status")
api.add_resource(AsyncRestoreBackup, "/restic/backup/restore")
api.add_resource(BackblazeConfig, "/restic/backblaze/config")
api.add_resource(ForceReloadSnapshots, "/restic/backup/reload")