76 lines
2.5 KiB
Go
76 lines
2.5 KiB
Go
package backup
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/config"
|
|
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/crypto/composite"
|
|
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/crypto/keymanager"
|
|
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/crypto/mlkem768"
|
|
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/crypto/x25519"
|
|
adapterpgdump "git.tswf.io/infra/go-synapse-backupper/pkg/adapters/pgdump"
|
|
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/pipeline"
|
|
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/retention"
|
|
"git.tswf.io/infra/go-synapse-backupper/pkg/adapters/storage/local"
|
|
domaincrypto "git.tswf.io/infra/go-synapse-backupper/pkg/domain/crypto"
|
|
domainpgdump "git.tswf.io/infra/go-synapse-backupper/pkg/domain/pgdump"
|
|
)
|
|
|
|
func RunOnce(ctx context.Context, cfg *config.Config) error {
|
|
registry := domaincrypto.NewRegistry()
|
|
if err := registry.Register(0x0006, func() domaincrypto.KEM { return mlkem768.New() }); err != nil {
|
|
return fmt.Errorf("register mlkem768: %w", err)
|
|
}
|
|
if err := registry.Register(0x0007, func() domaincrypto.KEM { return x25519.New() }); err != nil {
|
|
return fmt.Errorf("register x25519: %w", err)
|
|
}
|
|
|
|
keyMgr := keymanager.NewKeyManager(registry)
|
|
|
|
pqPub, err := keyMgr.LoadPub(cfg.PQPublicKeyPath, cfg.PQScheme)
|
|
if err != nil {
|
|
return fmt.Errorf("load pq public key: %w", err)
|
|
}
|
|
|
|
classicalPub, err := keyMgr.LoadPub(cfg.ClassicalPublicKeyPath, cfg.ClassicalScheme)
|
|
if err != nil {
|
|
return fmt.Errorf("load classical public key: %w", err)
|
|
}
|
|
|
|
recipients := []domaincrypto.RecipientPub{pqPub, classicalPub}
|
|
|
|
encryptor := composite.NewEncryptor(registry)
|
|
dumper := adapterpgdump.New()
|
|
sink := local.NewLocalSink(cfg.Backup.Dir)
|
|
|
|
runner := pipeline.NewRunner(
|
|
pipeline.WithDumper(dumper),
|
|
pipeline.WithEncryptor(encryptor),
|
|
)
|
|
|
|
now := time.Now()
|
|
timestamp := now.UTC().Format("20060102-150405")
|
|
pgDumpOpts := domainpgdump.Options{
|
|
Host: cfg.PG.Host,
|
|
Port: cfg.PG.Port,
|
|
Database: cfg.PG.Database,
|
|
User: cfg.PG.User,
|
|
Password: cfg.PG.Password,
|
|
ExcludeTables: cfg.PG.ExcludeTables,
|
|
Key: fmt.Sprintf("synapse-%s.dump.pqenc", timestamp),
|
|
}
|
|
|
|
if err := runner.Run(ctx, pgDumpOpts, recipients, sink, rand.Reader); err != nil {
|
|
return fmt.Errorf("backup pipeline failed: %w", err)
|
|
}
|
|
|
|
if _, err := retention.PruneByAge(ctx, cfg.Backup.Dir, cfg.Backup.RetentionDays, now); err != nil {
|
|
return fmt.Errorf("retention pruning failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|