33
33
from flask .blueprints import Blueprint
34
34
from flask .cli import with_appcontext
35
35
from flask .config import Config
36
+
36
37
from lifemonitor .utils import FtpUtils , encrypt_folder
37
38
38
39
from .db import backup , backup_options
51
52
encryption_key_file_option = click .option ("-kf" , "--encryption-key-file" ,
52
53
type = click .File ("rb" ), default = None ,
53
54
help = "File containing the encryption key" )
55
+ encryption_asymmetric_option = click .option ("-a" , "--encryption-asymmetric" , is_flag = True , default = False ,
56
+ show_default = True ,
57
+ help = "Use asymmetric encryption" )
54
58
55
59
56
60
class RequiredIf (GroupedOption ):
@@ -120,17 +124,29 @@ def bck(ctx):
120
124
@backup_options
121
125
@synch_otptions
122
126
@with_appcontext
123
- def db_cmd (file , directory , encryption_key , encryption_key_file , verbose , * args , ** kwargs ):
127
+ def db_cmd (file , directory ,
128
+ encryption_key , encryption_key_file , encryption_asymmetric ,
129
+ verbose , * args , ** kwargs ):
124
130
"""
125
131
Make a backup of the database
126
132
"""
127
- result = backup_db (directory , file , encryption_key , encryption_key_file , verbose , * args , ** kwargs )
133
+ result = backup_db (directory , file ,
134
+ encryption_key = encryption_key ,
135
+ encryption_key_file = encryption_key_file ,
136
+ encryption_asymmetric = encryption_asymmetric ,
137
+ verbose = verbose , * args , ** kwargs )
128
138
sys .exit (result )
129
139
130
140
131
- def backup_db (directory , file = None , encryption_key = None , encryption_key_file = None , verbose = False , * args , ** kwargs ):
141
+ def backup_db (directory , file = None ,
142
+ encryption_key = None , encryption_key_file = None , encryption_asymmetric = False ,
143
+ verbose = False , * args , ** kwargs ):
132
144
logger .debug (sys .argv )
133
- result = backup (directory , file , encryption_key , encryption_key_file , verbose )
145
+ logger .debug ("Backup DB: %r - %r - %r - %r - %r - %r - %r" ,)
146
+ logger .warning (f"Encryption asymmetric: { encryption_asymmetric } " )
147
+ result = backup (directory , file ,
148
+ encryption_key = encryption_key , encryption_key_file = encryption_key_file ,
149
+ encryption_asymmetric = encryption_asymmetric , verbose = verbose )
134
150
if result .returncode == 0 :
135
151
synch = kwargs .pop ('synch' , False )
136
152
if synch :
@@ -143,20 +159,25 @@ def backup_db(directory, file=None, encryption_key=None, encryption_key_file=Non
143
159
help = "Local path to store RO-Crates" )
144
160
@encryption_key_option
145
161
@encryption_key_file_option
162
+ @encryption_asymmetric_option
146
163
@synch_otptions
147
164
@with_appcontext
148
- def crates_cmd (directory , encryption_key , encryption_key_file , * args , ** kwargs ):
165
+ def crates_cmd (directory ,
166
+ encryption_key , encryption_key_file , encryption_asymmetric ,
167
+ * args , ** kwargs ):
149
168
"""
150
169
Make a backup of the registered workflow RO-Crates
151
170
"""
152
171
result = backup_crates (current_app .config , directory ,
153
- encryption_key , encryption_key_file ,
172
+ encryption_key = encryption_key , encryption_key_file = encryption_key_file ,
173
+ encryption_asymmetric = encryption_asymmetric ,
154
174
* args , ** kwargs )
155
175
sys .exit (result .returncode )
156
176
157
177
158
178
def backup_crates (config , directory ,
159
179
encryption_key : bytes = None , encryption_key_file : BinaryIO = None ,
180
+ encryption_asymmetric : bool = False ,
160
181
* args , ** kwargs ) -> subprocess .CompletedProcess :
161
182
assert config .get ("DATA_WORKFLOWS" , None ), "DATA_WORKFLOWS not configured"
162
183
# get the path of the RO-Crates
@@ -169,19 +190,23 @@ def backup_crates(config, directory,
169
190
if encryption_key or encryption_key_file :
170
191
if not encryption_key :
171
192
encryption_key = encryption_key_file .read ()
172
- result = encrypt_folder (rocrate_source_path , directory , encryption_key )
173
- result = subprocess .CompletedProcess (returncode = 0 if result else 1 , args = ())
193
+ result = encrypt_folder (rocrate_source_path , directory , encryption_key ,
194
+ encryption_asymmetric = encryption_asymmetric )
195
+ result = subprocess .CompletedProcess (returncode = 0 if result else 1 , args = ())
174
196
else :
175
197
result = subprocess .run (f'rsync -avh --delete { rocrate_source_path } / { directory } ' ,
176
198
shell = True , capture_output = True )
177
- if result :
199
+ if result . returncode == 0 :
178
200
print ("Created backup of workflow RO-Crates @ '%s'" % directory )
179
201
synch = kwargs .pop ('synch' , False )
180
202
if synch :
181
203
logger .debug ("Remaining args: %r" , kwargs )
182
204
return __remote_synch__ (source = directory , ** kwargs )
183
205
else :
184
- print ("Unable to backup workflow RO-Crates\n %s" , result .stderr .decode ())
206
+ try :
207
+ print ("Unable to backup workflow RO-Crates\n %s" , result .stderr .decode ())
208
+ except Exception :
209
+ print ("Unable to backup workflow RO-Crates\n " )
185
210
return result
186
211
187
212
@@ -192,20 +217,36 @@ def auto(config: Config):
192
217
click .echo ("No BACKUP_LOCAL_PATH found in your settings" )
193
218
sys .exit (0 )
194
219
195
- # search for an encryption key
196
- encryption_key = config .get ("BACKUP_ENCRYPTION_KEY" , None )
220
+ # search for an encryption key file
221
+ encryption_key = None
222
+ encryption_key_file = config .get ("BACKUP_ENCRYPTION_KEY_PATH" , None )
223
+ if not encryption_key_file :
224
+ click .echo ("WARNING: No BACKUP_ENCRYPTION_KEY_PATH found in your settings" )
225
+ logger .warning ("No BACKUP_ENCRYPTION_KEY_PATH found in your settings" )
226
+ else :
227
+ # read the encryption key from the file if the key is not provided
228
+ if isinstance (encryption_key_file , str ):
229
+ with open (encryption_key_file , "rb" ) as encryption_key_file :
230
+ encryption_key = encryption_key_file .read ()
231
+ elif isinstance (encryption_key_file , BinaryIO ):
232
+ encryption_key = encryption_key_file .read ()
233
+ else :
234
+ raise ValueError ("Invalid encryption key file" )
197
235
198
236
# set paths
199
237
base_path = base_path .removesuffix ('/' ) # remove trailing '/'
200
238
db_backups = f"{ base_path } /db"
201
239
rc_backups = f"{ base_path } /crates"
202
240
logger .debug ("Backup paths: %r - %r - %r" , base_path , db_backups , rc_backups )
203
241
# backup database
204
- result = backup (db_backups , encryption_key = encryption_key )
242
+ result = backup (db_backups ,
243
+ encryption_key = encryption_key ,
244
+ encryption_asymmetric = True )
205
245
if result .returncode != 0 :
206
246
sys .exit (result .returncode )
207
247
# backup crates
208
- result = backup_crates (config , rc_backups , encryption_key = encryption_key )
248
+ result = backup_crates (config , rc_backups ,
249
+ encryption_key = encryption_key , encryption_asymmetric = True )
209
250
if result .returncode != 0 :
210
251
sys .exit (result .returncode )
211
252
# clean up old files
0 commit comments