@@ -9,40 +9,44 @@ import (
9
9
"strconv"
10
10
"strings"
11
11
12
+ "filippo.io/age"
12
13
"github.com/theandrew168/pg2s3"
13
14
"golang.org/x/term"
14
15
)
15
16
16
- // TODO: move env var names to package constants?
17
-
18
17
func main () {
19
18
log .SetFlags (0 )
20
19
20
+ usage := "usage: pg2s3 backup|restore|prune"
21
+ if len (os .Args ) < 2 {
22
+ log .Fatalln (usage )
23
+ }
24
+
21
25
client , err := pg2s3 .New (
22
- requireEnv ("PG2S3_PG_CONNECTION_URI" ),
23
- requireEnv ("PG2S3_S3_ENDPOINT" ),
24
- requireEnv ("PG2S3_S3_ACCESS_KEY_ID" ),
25
- requireEnv ("PG2S3_S3_SECRET_ACCESS_KEY" ),
26
- requireEnv ("PG2S3_S3_BUCKET_NAME" ))
26
+ requireEnv (pg2s3 . EnvPGConnectionURI ),
27
+ requireEnv (pg2s3 . EnvS3Endpoint ),
28
+ requireEnv (pg2s3 . EnvS3AccessKeyID ),
29
+ requireEnv (pg2s3 . EnvS3SecretAccessKey ),
30
+ requireEnv (pg2s3 . EnvS3BucketName ))
27
31
if err != nil {
28
32
log .Fatalln (err )
29
33
}
30
34
31
- prefix := requireEnv ("PG2S3_BACKUP_PREFIX" )
32
- retention , err := strconv .Atoi (requireEnv ("PG2S3_BACKUP_RETENTION" ))
35
+ prefix := requireEnv (pg2s3 . EnvBackupPrefix )
36
+ retention , err := strconv .Atoi (requireEnv (pg2s3 . EnvBackupRetention ))
33
37
if err != nil {
34
38
log .Fatalln (err )
35
39
}
36
40
37
- usage := "usage: pg2s3 backup|restore|prune"
38
- if len (os .Args ) < 2 {
39
- log .Fatalln (usage )
41
+ // validate public key (if provided)
42
+ publicKey := os .Getenv (pg2s3 .EnvAgePublicKey )
43
+ if publicKey != "" {
44
+ _ , err = age .ParseX25519Recipient (publicKey )
45
+ if err != nil {
46
+ log .Fatalln (err )
47
+ }
40
48
}
41
49
42
- // TODO: verify connection to PG
43
- // TODO: verify connection to S3
44
- // TODO: verify age public key (if provided)
45
-
46
50
cmd := os .Args [1 ]
47
51
switch cmd {
48
52
case "backup" :
@@ -91,39 +95,32 @@ func confirm(message string) bool {
91
95
}
92
96
93
97
func backup (client * pg2s3.Client , prefix string ) error {
94
- publicKey := os .Getenv ("PG2S3_AGE_PUBLIC_KEY" )
98
+ publicKey := os .Getenv (pg2s3 . EnvAgePublicKey )
95
99
96
100
// generate name for backup
97
101
name , err := pg2s3 .GenerateBackupName (prefix )
98
102
if err != nil {
99
103
return err
100
104
}
101
105
102
- // generate path for backup
103
- path := pg2s3 .GenerateBackupPath (name )
104
-
105
106
// create backup
106
- err = client .CreateBackup (path )
107
+ backup , err : = client .CreateBackup ()
107
108
if err != nil {
108
109
return err
109
110
}
110
- defer os .Remove (path )
111
111
112
112
// encrypt backup (if applicable)
113
113
if publicKey != "" {
114
- agePath := path + ".age"
115
- err := client .EncryptBackup (agePath , path , publicKey )
114
+ backup , err = client .EncryptBackup (backup , publicKey )
116
115
if err != nil {
117
116
return err
118
117
}
119
118
120
119
name = name + ".age"
121
- path = agePath
122
120
}
123
- defer os .Remove (path )
124
121
125
122
// upload backup
126
- err = client .UploadBackup (name , path )
123
+ err = client .UploadBackup (name , backup )
127
124
if err != nil {
128
125
return err
129
126
}
@@ -133,7 +130,7 @@ func backup(client *pg2s3.Client, prefix string) error {
133
130
}
134
131
135
132
func restore (client * pg2s3.Client ) error {
136
- publicKey := os .Getenv ("PG2S3_AGE_PUBLIC_KEY" )
133
+ publicKey := os .Getenv (pg2s3 . EnvAgePublicKey )
137
134
138
135
// list all backups
139
136
backups , err := client .ListBackups ()
@@ -148,34 +145,28 @@ func restore(client *pg2s3.Client) error {
148
145
// determine latest backup
149
146
latest := backups [0 ]
150
147
151
- // generate path for backup
152
- path := pg2s3 .GenerateBackupPath (latest )
153
-
154
148
// download backup
155
- err = client .DownloadBackup (path , latest )
149
+ backup , err : = client .DownloadBackup (latest )
156
150
if err != nil {
157
151
return err
158
152
}
159
- defer os .Remove (path )
160
153
161
154
// decrypt backup (if applicable)
162
155
if publicKey != "" {
163
- fmt .Println ("enter age private key:" )
156
+ fmt .Print ("enter private key: " )
164
157
input , err := term .ReadPassword (int (os .Stdin .Fd ()))
165
158
if err != nil {
166
159
return err
167
160
}
168
161
162
+ fmt .Println ()
169
163
privateKey := string (input )
170
164
171
- agePath := path
172
- path = strings .TrimSuffix (path , ".age" )
173
- err = client .DecryptBackup (path , agePath , privateKey )
165
+ backup , err = client .DecryptBackup (backup , privateKey )
174
166
if err != nil {
175
167
return err
176
168
}
177
169
}
178
- defer os .Remove (path )
179
170
180
171
// confirm restore before applying
181
172
message := fmt .Sprintf ("restore %s" , latest )
@@ -184,7 +175,7 @@ func restore(client *pg2s3.Client) error {
184
175
}
185
176
186
177
// restore backup
187
- err = client .RestoreBackup (path )
178
+ err = client .RestoreBackup (backup )
188
179
if err != nil {
189
180
return err
190
181
}
0 commit comments