Source code for ferrosoft.ops.backup

import argparse
import datetime
import os
import tempfile

import orjson
from cattrs import structure

from ferrosoft.ops import commands
from ferrosoft.ops.models import Tenant, JournalEntry, Journal


[docs] def backup_database( args: argparse.Namespace, backup_date: datetime.datetime, master_database: str = None, tenant: Tenant = None, ) -> JournalEntry: db_name = master_database if tenant is None else tenant.db_name tenant_args = ( [] if tenant is None else [ "--host", tenant.db_hostname, "--port=%s" % tenant.db_port, "--username", tenant.db_username, ] ) dump_env = None if tenant is None else {"PGPASSWORD": tenant.db_password} dump_filename = "%s-%s.pgdump.%s" % ( db_name, backup_date.isoformat(), args.compress, ) dump_absname = os.path.join(args.directory, dump_filename) pg_dump = [ args.pgdump, "-w", *args.dump.split(" "), *tenant_args, "-Z", args.compress, "-f", dump_absname, db_name, ] commands.run(pg_dump, env=dump_env) if not os.path.isfile(dump_absname): raise RuntimeError("pg_dump did not create backup file: %s" % dump_absname) if args.destination == "s3": commands.run( [ args.aws, "s3", "cp", dump_absname, "s3://%s" % args.bucket, ] ) elif args.destination == "sftp": cmd = "put %s %s/%s" % (dump_absname, args.bucket, dump_filename) commands.run( [ args.sftp, "-o", "PasswordAuthentication=no", "-P", str(args.sftp_port), args.sftp_host, ], input=cmd.encode(), ) else: raise RuntimeError("Unknown destination type: %s" % args.destination) os.unlink(dump_absname) return JournalEntry( filename=dump_filename, db_name=db_name, pg_dump_args=" ".join(pg_dump), tenant=tenant, )
[docs] def save_journal(journal: Journal, args: argparse.Namespace): # noinspection PyUnresolvedReferences journal_str = orjson.dumps(structure(journal)) dest_file_name = "%s/journal-%s.json" % ( args.bucket, journal.backup_date.isoformat(), ) if args.destination == "s3": commands.run( [ args.aws, "s3", "cp", "-", "s3://%s" % dest_file_name, ], input=journal_str.encode(), ) elif args.destination == "sftp": with tempfile.NamedTemporaryFile(mode="w+b") as journal_file: journal_file.write(journal_str.encode()) journal_file.flush() cmd = "put %s %s" % (journal_file.name, dest_file_name) commands.run( [ args.sftp, "-o", "PasswordAuthentication=no", "-P", str(args.sftp_port), args.sftp_host, ], input=cmd.encode(), ) else: raise RuntimeError("Unknown destination type: %s" % args.destination)