Skip to content

Commit f9fa36c

Browse files
committed
refactor: allow passing in multiple connections
1 parent d974ad8 commit f9fa36c

File tree

1 file changed

+61
-45
lines changed

1 file changed

+61
-45
lines changed

main.go

+61-45
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77
"github.com/minio/minio-go/v7"
88
"github.com/minio/minio-go/v7/pkg/credentials"
99
"log"
10+
"net/url"
1011
"os"
1112
"strconv"
13+
"strings"
1214
"time"
1315
)
1416

@@ -17,26 +19,55 @@ func main() {
1719
log.Printf("WARNING: Error loading .env file: %s\n", err)
1820
}
1921

20-
postgresHost := flag.String("postgres-host", lookupEnvOrString("POSTGRES_HOST", "localhost"), "connectionOptions host")
21-
postgresPort := flag.Int("postgres-port", lookupEnvOrInt("POSTGRES_PORT", 5432), "connectionOptions port")
22-
postgresUser := flag.String("postgres-user", lookupEnvOrString("POSTGRES_USER", "postgres"), "connectionOptions user")
23-
postgresPassword := flag.String("postgres-password", lookupEnvOrString("POSTGRES_PASSWORD", "postgres"), "connectionOptions password")
24-
postgresDB := flag.String("postgres-db", lookupEnvOrString("POSTGRES_DB", "postgres"), "connectionOptions database")
22+
rawUrls := flag.String("urls", lookupEnvOrString("URLS", ""), "comma separated list of urls to backup, these must be in the format postgres://<user>:<password>@<host>[:<port>]/<dbname>")
2523

2624
s3Endpoint := flag.String("s3-endpoint", lookupEnvOrString("S3_ENDPOINT", ""), "S3 endpoint")
2725
s3Bucket := flag.String("s3-bucket", lookupEnvOrString("S3_BUCKET", "postgres-backups"), "S3 bucket")
2826
s3AccessKey := flag.String("s3-access-key", lookupEnvOrString("S3_ACCESS_KEY", "minio"), "S3 access key")
2927
s3SecretKey := flag.String("s3-secret-key", lookupEnvOrString("S3_SECRET_KEY", "minioadmin"), "S3 secret key")
3028

31-
every := flag.Duration("every", lookupEnvOrDuration("EVERY", 24*time.Hour), "How often to run the backup")
29+
interval := flag.Duration("interval", lookupEnvOrDuration("INTERVAL", 24*time.Hour), "How often to run the backup")
3230

3331
flag.Parse()
3432

35-
must("postgres-host", postgresHost)
33+
must("urls", rawUrls)
3634
must("s3-endpoint", s3Endpoint)
3735
must("s3-access-key", s3AccessKey)
3836
must("s3-secret-key", s3SecretKey)
3937

38+
urls := make([]connectionOptions, len(strings.Split(*rawUrls, ",")))
39+
for i, rawUrl := range strings.Split(*rawUrls, ",") {
40+
parsedUrl, err := url.Parse(rawUrl)
41+
if err != nil {
42+
log.Fatalf("Failed to parse url %s: %s", rawUrl, err)
43+
}
44+
45+
port := 5432
46+
rawPort := parsedUrl.Port()
47+
if rawPort != "" {
48+
port, err = strconv.Atoi(rawPort)
49+
if err != nil {
50+
log.Fatalf("Failed to parse port %s: %s", parsedUrl.Port(), err)
51+
}
52+
}
53+
54+
password, exist := parsedUrl.User.Password()
55+
if !exist {
56+
log.Fatalf("Failed to parse password %s: %s", parsedUrl.User, err)
57+
}
58+
59+
urls[i] = connectionOptions{
60+
Host: parsedUrl.Hostname(),
61+
Port: port,
62+
Database: strings.TrimPrefix(parsedUrl.Path, "/"),
63+
Username: parsedUrl.User.Username(),
64+
Password: password,
65+
}
66+
}
67+
if len(urls) == 0 {
68+
log.Fatalf("No URLs specified")
69+
}
70+
4071
s3, err := minio.New(*s3Endpoint, &minio.Options{
4172
Creds: credentials.NewStaticV4(*s3AccessKey, *s3SecretKey, ""),
4273
Secure: true,
@@ -46,36 +77,34 @@ func main() {
4677
}
4778

4879
for {
49-
log.Printf("Sleeping for %s", *every)
50-
time.Sleep(*every)
51-
52-
file := newFileName(*postgresDB)
53-
err = RunDump(&connectionOptions{
54-
Host: *postgresHost,
55-
Port: *postgresPort,
56-
Database: *postgresDB,
57-
Username: *postgresUser,
58-
Password: *postgresPassword,
59-
}, file)
60-
if err != nil {
61-
log.Printf("WARNING: Failed to dump database: %s", err)
62-
continue
63-
}
80+
for _, u := range urls {
81+
log.Printf("Backing up %s", u.Database)
6482

65-
log.Printf("Uploading %s to %s", file, *s3Bucket)
83+
file := newFileName(u.Database)
6684

67-
if _, err := s3.FPutObject(context.Background(), *s3Bucket, file, file, minio.PutObjectOptions{}); err != nil {
68-
log.Printf("WARNING: Failed to upload %s to %s: %s", file, *s3Bucket, err)
69-
continue
70-
}
85+
if err = RunDump(&u, file); err != nil {
86+
log.Printf("WARNING: Failed to dump database: %s", err)
87+
continue
88+
}
7189

72-
log.Printf("Removing %s", file)
73-
if err := os.Remove(file); err != nil {
74-
log.Printf("WARNING: Failed to remove %s: %s", file, err)
75-
continue
90+
log.Printf("Uploading %s to %s", file, *s3Bucket)
91+
92+
if _, err := s3.FPutObject(context.Background(), *s3Bucket, file, file, minio.PutObjectOptions{}); err != nil {
93+
log.Printf("WARNING: Failed to upload %s to %s: %s", file, *s3Bucket, err)
94+
continue
95+
}
96+
97+
log.Printf("Removing %s", file)
98+
if err := os.Remove(file); err != nil {
99+
log.Printf("WARNING: Failed to remove %s: %s", file, err)
100+
continue
101+
}
102+
103+
log.Printf("Done")
76104
}
77105

78-
log.Printf("Done")
106+
log.Printf("Sleeping for %s", *interval)
107+
time.Sleep(*interval)
79108
}
80109
}
81110

@@ -87,19 +116,6 @@ func lookupEnvOrString(key string, defaultVal string) string {
87116
return defaultVal
88117
}
89118

90-
func lookupEnvOrInt(key string, defaultVal int) int {
91-
if val, ok := os.LookupEnv(key); ok {
92-
parsed, err := strconv.Atoi(val)
93-
if err != nil {
94-
log.Fatal(err)
95-
}
96-
97-
return parsed
98-
}
99-
100-
return defaultVal
101-
}
102-
103119
func lookupEnvOrDuration(key string, defaultVal time.Duration) time.Duration {
104120
if val, ok := os.LookupEnv(key); ok {
105121
parsed, err := time.ParseDuration(val)

0 commit comments

Comments
 (0)