2022-03-14 05:53:03 +00:00
|
|
|
#!/home/frappe/frappe-bench/env/bin/python
|
2022-04-03 10:27:22 +00:00
|
|
|
from __future__ import annotations
|
2022-03-14 05:53:03 +00:00
|
|
|
|
|
|
|
import argparse
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
from pathlib import Path
|
|
|
|
from typing import TYPE_CHECKING, Any, List, cast
|
|
|
|
|
|
|
|
import boto3
|
|
|
|
import frappe
|
|
|
|
from frappe.utils.backups import BackupGenerator
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
from mypy_boto3_s3.service_resource import _Bucket
|
|
|
|
|
|
|
|
|
|
|
|
class Arguments(argparse.Namespace):
|
|
|
|
site: str
|
|
|
|
bucket: str
|
|
|
|
region_name: str
|
|
|
|
endpoint_url: str
|
|
|
|
aws_access_key_id: str
|
|
|
|
aws_secret_access_key: str
|
2022-04-19 23:39:56 +00:00
|
|
|
bucket_directory: str
|
2022-03-14 05:53:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _get_files_from_previous_backup(site_name: str) -> list[Path]:
|
|
|
|
frappe.connect(site_name)
|
|
|
|
|
|
|
|
conf = cast(Any, frappe.conf)
|
|
|
|
backup_generator = BackupGenerator(
|
|
|
|
db_name=conf.db_name,
|
|
|
|
user=conf.db_name,
|
|
|
|
password=conf.db_password,
|
|
|
|
db_host=frappe.db.host,
|
|
|
|
db_port=frappe.db.port,
|
|
|
|
db_type=conf.db_type,
|
|
|
|
)
|
|
|
|
recent_backup_files = backup_generator.get_recent_backup(24)
|
|
|
|
|
|
|
|
frappe.destroy()
|
|
|
|
return [Path(f) for f in recent_backup_files if f]
|
|
|
|
|
|
|
|
|
|
|
|
def get_files_from_previous_backup(site_name: str) -> list[Path]:
|
|
|
|
files = _get_files_from_previous_backup(site_name)
|
|
|
|
if not files:
|
|
|
|
print("No backup found that was taken <24 hours ago.")
|
|
|
|
return files
|
|
|
|
|
|
|
|
|
2022-04-03 10:27:22 +00:00
|
|
|
def get_bucket(args: Arguments) -> _Bucket:
|
2022-03-14 05:53:03 +00:00
|
|
|
return boto3.resource(
|
|
|
|
service_name="s3",
|
|
|
|
endpoint_url=args.endpoint_url,
|
|
|
|
region_name=args.region_name,
|
|
|
|
aws_access_key_id=args.aws_access_key_id,
|
|
|
|
aws_secret_access_key=args.aws_secret_access_key,
|
|
|
|
).Bucket(args.bucket)
|
|
|
|
|
|
|
|
|
2022-04-19 23:39:56 +00:00
|
|
|
def upload_file(
|
|
|
|
path: Path, site_name: str, bucket: _Bucket, bucket_directory: str = None
|
|
|
|
) -> None:
|
2022-03-14 05:53:03 +00:00
|
|
|
filename = str(path.absolute())
|
|
|
|
key = str(Path(site_name) / path.name)
|
2022-04-19 23:39:56 +00:00
|
|
|
if bucket_directory:
|
|
|
|
key = bucket_directory + "/" + key
|
2022-03-14 05:53:03 +00:00
|
|
|
print(f"Uploading {key}")
|
|
|
|
bucket.upload_file(Filename=filename, Key=key)
|
|
|
|
os.remove(path)
|
|
|
|
|
|
|
|
|
|
|
|
def push_backup(args: Arguments) -> None:
|
|
|
|
"""Get latest backup files using Frappe utils, push them to S3 and remove local copy"""
|
|
|
|
|
|
|
|
files = get_files_from_previous_backup(args.site)
|
|
|
|
bucket = get_bucket(args)
|
|
|
|
|
|
|
|
for path in files:
|
2022-04-19 23:39:56 +00:00
|
|
|
upload_file(
|
|
|
|
path=path,
|
|
|
|
site_name=args.site,
|
|
|
|
bucket=bucket,
|
|
|
|
bucket_directory=args.bucket_directory,
|
|
|
|
)
|
2022-03-14 05:53:03 +00:00
|
|
|
|
|
|
|
print("Done!")
|
|
|
|
|
|
|
|
|
2022-04-03 10:27:22 +00:00
|
|
|
def parse_args(args: list[str]) -> Arguments:
|
2022-03-14 05:53:03 +00:00
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument("--site", required=True)
|
|
|
|
parser.add_argument("--bucket", required=True)
|
|
|
|
parser.add_argument("--region-name", required=True)
|
|
|
|
parser.add_argument("--endpoint-url", required=True)
|
|
|
|
# Looking for default AWS credentials variables
|
|
|
|
parser.add_argument(
|
|
|
|
"--aws-access-key-id", required=True, default=os.getenv("AWS_ACCESS_KEY_ID")
|
|
|
|
)
|
|
|
|
parser.add_argument(
|
|
|
|
"--aws-secret-access-key",
|
|
|
|
required=True,
|
|
|
|
default=os.getenv("AWS_SECRET_ACCESS_KEY"),
|
|
|
|
)
|
2022-04-19 23:39:56 +00:00
|
|
|
parser.add_argument("--bucket-directory")
|
2022-03-14 05:53:03 +00:00
|
|
|
return parser.parse_args(args, namespace=Arguments())
|
|
|
|
|
|
|
|
|
2022-04-03 10:27:22 +00:00
|
|
|
def main(args: list[str]) -> int:
|
2022-03-14 05:53:03 +00:00
|
|
|
push_backup(parse_args(args))
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
raise SystemExit(main(sys.argv[1:]))
|