Skip to content

Commit a80db48

Browse files
committedFeb 8, 2024
More work on S3 support
1 parent 21792a7 commit a80db48

14 files changed

+69
-91
lines changed
 

‎backups-lib.pl

+5-9
Original file line numberDiff line numberDiff line change
@@ -6625,9 +6625,11 @@ sub rename_backup_owner
66256625
sub list_all_s3_accounts
66266626
{
66276627
local @rv;
6628-
if (&can_use_cloud("s3") && $config{'s3_akey'} && $config{'s3_skey'}) {
6629-
push(@rv, [ $config{'s3_akey'}, $config{'s3_skey'},
6630-
$config{'s3_endpoint'} ]);
6628+
if (&can_cloud_providers()) {
6629+
foreach my $s3 (&list_s3_accounts()) {
6630+
push(@rv, [ $s3->{'access'}, $s3->{'secret'},
6631+
$s3->{'endpoint'} ]);
6632+
}
66316633
}
66326634
foreach my $sched (grep { &can_backup_sched($_) } &list_scheduled_backups()) {
66336635
local @dests = &get_scheduled_backup_dests($sched);
@@ -6639,12 +6641,6 @@ sub list_all_s3_accounts
66396641
}
66406642
}
66416643
}
6642-
if (&can_cloud_providers()) {
6643-
foreach my $s3 (&list_s3_accounts()) {
6644-
push(@rv, [ $s3->{'access'}, $s3->{'secret'},
6645-
$s3->{'endpoint'} ]);
6646-
}
6647-
}
66486644
local %done;
66496645
return grep { !$done{$_->[0]}++ } @rv;
66506646
}

‎cloud-lib.pl

+13-53
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,45 @@ sub list_cloud_providers
66
{
77
my @rv = ( { 'name' => 's3',
88
'prefix' => [ 's3', 's3rrs' ],
9+
'clear' => 0,
910
'url' => 'https://aws.amazon.com/s3/',
1011
'desc' => $text{'cloud_s3desc'},
1112
'longdesc' => \&cloud_s3_longdesc },
1213
{ 'name' => 'rs',
1314
'prefix' => [ 'rs' ],
15+
'clear' => 0,
1416
'url' => 'https://www.rackspace.com/openstack/public/files',
1517
'desc' => $text{'cloud_rsdesc'},
1618
'longdesc' => $text{'cloud_rs_longdesc'} } );
1719
if ($virtualmin_pro) {
1820
my $ourl = &get_miniserv_base_url()."/$module_name/oauth.cgi";
1921
push(@rv, { 'name' => 'google',
2022
'prefix' => [ 'gcs' ],
23+
'clear' => 1,
2124
'url' => 'https://cloud.google.com/storage',
2225
'desc' => $text{'cloud_googledesc'},
2326
'longdesc' => \&cloud_google_longdesc });
2427
push(@rv, { 'name' => 'dropbox',
2528
'prefix' => [ 'dropbox' ],
29+
'clear' => 1,
2630
'url' => 'https://www.dropbox.com/',
2731
'desc' => $text{'cloud_dropboxdesc'},
2832
'longdesc' => $text{'cloud_dropbox_longdesc'} });
2933
push(@rv, { 'name' => 'bb',
3034
'prefix' => [ 'bb' ],
35+
'clear' => 1,
3136
'url' => 'https://www.backblaze.com/',
3237
'desc' => $text{'cloud_bbdesc'},
3338
'longdesc' => $text{'cloud_bb_longdesc'} });
3439
push(@rv, { 'name' => 'azure',
3540
'prefix' => [ 'azure' ],
41+
'clear' => 1,
3642
'url' => 'https://azure.microsoft.com/',
3743
'desc' => $text{'cloud_azdesc'},
3844
'longdesc' => $text{'cloud_az_longdesc'} });
3945
push(@rv, { 'name' => 'drive',
4046
'prefix' => [ 'drive' ],
47+
'clear' => 1,
4148
'url' => 'https://drive.google.com/',
4249
'desc' => $text{'cloud_drivedesc'},
4350
'longdesc' => \&cloud_drive_longdesc });
@@ -68,10 +75,11 @@ sub backup_uses_cloud
6875

6976
sub cloud_s3_get_state
7077
{
71-
if ($config{'s3_akey'}) {
78+
my @s3s = &list_s3_accounts();
79+
if (@s3s) {
7280
return { 'ok' => 1,
7381
'desc' => &text('cloud_s3account',
74-
"<tt>$config{'s3_akey'}</tt>"),
82+
"<tt>$s3s[0]->{'access'}</tt>"),
7583
};
7684
}
7785
elsif (&can_use_aws_s3_creds()) {
@@ -86,36 +94,19 @@ sub cloud_s3_get_state
8694

8795
sub cloud_s3_longdesc
8896
{
89-
if (!$config{'s3_akey'} && &can_use_aws_s3_creds()) {
97+
my @s3s = &list_s3_accounts();
98+
if (!@s3s && &can_use_aws_s3_creds()) {
9099
return $text{'cloud_s3_creds'};
91100
}
92101
else {
93-
return $text{'cloud_s3_longdesc'};
102+
return &text('cloud_s3_longdesc2', 'list_s3s.cgi');
94103
}
95104
}
96105

97106
sub cloud_s3_show_inputs
98107
{
99108
my $rv;
100109

101-
# Default login
102-
if ($config{'s3_akey'} || !&can_use_aws_s3_creds()) {
103-
# Prompt for login
104-
$rv .= &ui_table_row($text{'cloud_s3_akey'},
105-
&ui_radio("s3_akey_def", $config{'s3_akey'} ? 0 : 1,
106-
[ [ 1, $text{'cloud_noneset'} ],
107-
[ 0, $text{'cloud_below'} ] ])."<br>\n".
108-
&ui_grid_table([ "<b>$text{'cloud_s3_access'}</b>",
109-
&ui_textbox("s3_akey", $config{'s3_akey'}, 50),
110-
"<b>$text{'cloud_s3_secret'}</b>",
111-
&ui_textbox("s3_skey", $config{'s3_skey'}, 50) ], 2));
112-
}
113-
114-
# S3 endpoint hostname, for non-amazon implementations
115-
$rv .= &ui_table_row($text{'cloud_s3_endpoint'},
116-
&ui_opt_textbox("s3_endpoint", $config{'s3_endpoint'}, 40,
117-
$text{'cloud_s3_amazon'}));
118-
119110
# Upload chunk size
120111
$rv .= &ui_table_row($text{'cloud_s3_chunk'},
121112
&ui_opt_textbox("s3_chunk", $config{'s3_chunk'}, 6,
@@ -147,33 +138,6 @@ sub cloud_s3_parse_inputs
147138
{
148139
my ($in) = @_;
149140

150-
# Parse default login
151-
if ($config{'s3_akey'} || !&can_use_aws_s3_creds()) {
152-
if ($in->{'s3_akey_def'}) {
153-
delete($config{'s3_akey'});
154-
delete($config{'s3_skey'});
155-
}
156-
else {
157-
$in->{'s3_akey'} =~ /^\S+$/ || &error($text{'backup_eakey'});
158-
$in->{'s3_skey'} =~ /^\S+$/ || &error($text{'backup_eskey'});
159-
$config{'s3_akey'} = $in->{'s3_akey'};
160-
$config{'s3_skey'} = $in->{'s3_skey'};
161-
}
162-
}
163-
164-
# Parse endpoint hostname
165-
if ($in->{'s3_endpoint_def'}) {
166-
delete($config{'s3_endpoint'});
167-
}
168-
else {
169-
my ($host, $port) = split(/:/, $in->{'s3_endpoint'});
170-
&to_ipaddress($host) ||
171-
&error($text{'cloud_es3_endpoint'});
172-
!$port || $port =~ /^\d+$/ ||
173-
&error($text{'cloud_es3_endport'});
174-
$config{'s3_endpoint'} = $in->{'s3_endpoint'};
175-
}
176-
177141
# Parse chunk size
178142
if ($in->{'s3_chunk_def'}) {
179143
delete($config{'s3_chunk'});
@@ -207,11 +171,7 @@ sub cloud_s3_parse_inputs
207171
sub cloud_s3_clear
208172
{
209173
# Clear Virtualmin's credentials
210-
my $akey = $config{'s3_akey'};
211174
&lock_file($module_config_file);
212-
delete($config{'s3_akey'});
213-
delete($config{'s3_skey'});
214-
delete($config{'s3_location'});
215175
&save_module_config();
216176
&unlock_file($module_config_file);
217177

‎create-s3-bucket.pl

+1-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ package virtual_server;
5151
&usage("Unknown parameter $a");
5252
}
5353
}
54-
$akey ||= $config{'s3_akey'};
55-
$skey ||= $config{'s3_skey'};
54+
($akey, $skey) = &lookup_s3_credentials($akey, $skey);
5655
if (!&can_use_aws_s3_creds()) {
5756
$akey || &usage("Missing --access-key parameter");
5857
$skey || &usage("Missing --secret-key parameter");

‎delete-s3-bucket.pl

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ package virtual_server;
5353
&usage("Unknown parameter $a");
5454
}
5555
}
56-
$akey ||= $config{'s3_akey'};
57-
$skey ||= $config{'s3_skey'};
56+
($akey, $skey) = &lookup_s3_credentials($akey, $skey);
5857
if (!&can_use_aws_s3_creds()) {
5958
$akey || &usage("Missing --access-key parameter");
6059
$skey || &usage("Missing --secret-key parameter");

‎delete-s3-file.pl

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ package virtual_server;
5353
&usage("Unknown parameter $a");
5454
}
5555
}
56-
$akey ||= $config{'s3_akey'};
57-
$skey ||= $config{'s3_skey'};
56+
($akey, $skey) = &lookup_s3_credentials($akey, $skey);
5857
if (!&can_use_aws_s3_creds()) {
5958
$akey || &usage("Missing --access-key parameter");
6059
$skey || &usage("Missing --secret-key parameter");

‎download-s3-file.pl

+1-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ package virtual_server;
5555
&usage("Unknown parameter $a");
5656
}
5757
}
58-
$akey ||= $config{'s3_akey'};
59-
$skey ||= $config{'s3_skey'};
58+
($akey, $skey) = &lookup_s3_credentials($akey, $skey);
6059
if (!&can_use_aws_s3_creds()) {
6160
$akey || &usage("Missing --access-key parameter");
6261
$skey || &usage("Missing --secret-key parameter");

‎edit_cloud.cgi

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ print &ui_table_row($text{'cloud_users'}, $utable);
8383

8484
print &ui_table_end();
8585
print &ui_form_end([ [ undef, $text{'save'} ],
86-
$state->{'ok'} ? ( [ 'clear', $text{'cloud_clear'} ] )
87-
: ( ) ]);
86+
$state->{'ok'} && $prov->{'clear'} ?
87+
( [ 'clear', $text{'cloud_clear'} ] ) : ( ) ]);
8888

8989
&ui_print_footer("list_clouds.cgi", $text{'clouds_return'});

‎lang/en

+11-11
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,9 @@ index_backuplog=Backup Logs
244244
index_backuplogdesc=Show logs of all backups that you have permissions to create, made via the Virtualmin UI, command line or on schedule.
245245
index_bkeys=Backup Encryption Keys
246246
index_bkeysdesc=List GPG keys used for signing and encrypting Virtualmin backups.
247-
index_buckets=Amazon S3 Buckets
247+
index_buckets=S3 Buckets
248248
index_bucketsdesc=Show S3 buckets used for backups, and allow migration to Glacier to be configured.
249-
index_s3s=Amazon S3 Accounts
249+
index_s3s=S3 Accounts
250250
index_s3sdesc=Show accounts at Amazon S3 and compatible providers, for use by Virtualmin backups.
251251
index_clouds=Cloud Storage Providers
252252
index_cloudsdesc=Configure authentication to cloud storage providers like S3, rackspace, Google and Dropbox.
@@ -2451,7 +2451,7 @@ backup_mode0=Local file or directory
24512451
backup_mode0a=File under <tt>virtualmin-backup/</tt>
24522452
backup_mode1=FTP server
24532453
backup_mode2=SSH server
2454-
backup_mode3=Amazon S3 bucket
2454+
backup_mode3=S3 bucket
24552455
backup_mode44=Download via link
24562456
backup_mode5=Upload to server
24572457
backup_mode6=Rackspace Cloud Files
@@ -2512,8 +2512,8 @@ backup_niceftp=$1 on FTP server $2
25122512
backup_nicescp=$1 on SSH server $2
25132513
backup_nicewebmin=$1 on Webmin server $2
25142514
backup_nicefile=local file $1
2515-
backup_nices3=Amazon S3 bucket $1
2516-
backup_nices3p=$2 in Amazon S3 bucket $1
2515+
backup_nices3=S3 bucket $1
2516+
backup_nices3p=$2 in S3 bucket $1
25172517
backup_nicers=Rackspace container $1
25182518
backup_nicersp=$2 in Rackspace container $1
25192519
backup_nicego=Google folder $1
@@ -2875,7 +2875,7 @@ restore_disabledomain=Re-disabling virtual server $1 ..
28752875
restore_fordomain=Restoring backup for virtual server $1 ..
28762876
restore_download=Downloading archive from FTP server ..
28772877
restore_downloadssh=Downloading archive from SSH server ..
2878-
restore_downloads3=Downloading archive from Amazon S3 server ..
2878+
restore_downloads3=Downloading archive from S3 server ..
28792879
restore_downloadrs=Downloading archive from Rackspace Cloud Files ..
28802880
restore_downloadgc=Downloading archive from Google Cloud Storage ..
28812881
restore_downloaddb=Downloading archive from Dropbox ..
@@ -7271,7 +7271,7 @@ fixmodphp_ecannot=You are not allowed to fix PHP permissions
72717271
fixmodphp_doing=Updating all virtual servers to prevent use of mod_php when disabled ..
72727272
fixmodphp_done=.. fixed $1 domains
72737273

7274-
buckets_title=Amazon S3 Buckets
7274+
buckets_title=S3 Buckets
72757275
buckets_ecannot=You are not allowed to manage S3 buckets
72767276
buckets_eaccounts=No scheduled backups to S3 have been created yet, and no default S3 keys have been set.
72777277
buckets_none=No S3 buckets associated with any of your S3 accounts were found.
@@ -7288,7 +7288,7 @@ bucket_title2=Edit S3 Bucket
72887288
bucket_eagone=Account does not exist!
72897289
bucket_elist=Failed to list buckets : $1
72907290
bucket_egone=Bucket no longer exists!
7291-
bucket_header=Amazon S3 bucket details
7291+
bucket_header=S3 bucket details
72927292
bucket_account=S3 account key
72937293
bucket_name=Bucket name
72947294
bucket_owner=Owned by
@@ -7519,7 +7519,7 @@ cloud_google_project=Project ID
75197519
cloud_google_location=Location for new buckets
75207520
cloud_google_oauth=OAuth2 code from Google
75217521
cloud_google_token=OAuth2 token from Google
7522-
cloud_s3_longdesc=The credentials to enter on this page can be found on the Security Credentials page of your account on the <a href=https://console.aws.amazon.com/ target=_blank>AWS Console</a>.
7522+
cloud_s3_longdesc2=The credentials for Amazon S3 or other compatible providers can be entered on the <a href='$1'>S3 Accounts</a> page.
75237523
cloud_google_longdesc=The settings on this page are supplied by Google when you grant API access to your project on the <a href=https://console.cloud.google.com/apis/credentials target=_blank>Google Cloud Console</a> page, under <b>APIs & Services ⇾ Credentials</b> page. You must create an <b>OAuth 2.0 Client ID</b> credential, with the <b>Authorized redirect URI</b> set to <tt>$1</tt> value. Once created, the <b>client ID</b> and <b>client secret</b> can be entered here.
75247524
cloud_dropbox_longdesc=Before you can backup to Dropbox, you must first <a href=https://www.dropbox.com/register target=_blank>create an account</a> on their website if you don't already have one.
75257525
cloud_bb_longdesc=Before you can backup to Backblaze, you must first <a href=https://backblaze.com/ target=_blank>create an account</a>, and then enable <b>B2 Cloud Storage</b> on the <b>My Settings</b> page. Then you need to generate an Application key with all capabilities on the <b>App Keys</b> page.
@@ -7942,7 +7942,7 @@ global_dismiss=Dismiss
79427942
ports_fpm=PHP FPM server
79437943
ports_script=Installed $1 script
79447944

7945-
s3s_title=Amazon S3 Accounts
7945+
s3s_title=S3 Accounts
79467946
s3s_longdesc=The S3 accounts on this page can be used by Virtualmin scheduled backups. Accounts can either be at Amazon AWS, or at other cloud storage providers that offer an S3-compatible HTTP API.
79477947
s3s_none=No accounts have been registered yet.
79487948
s3s_add=Add a new S3 account.
@@ -7957,7 +7957,7 @@ s3s_return=S3 accounts
79577957

79587958
s3_title1=Add S3 Account
79597959
s3_title2=Edit S3 Account
7960-
s3_longdesc=XXX
7960+
s3_longdesc=The credentials to enter on this page can be found on the Security Credentials page of your account on the <a href=https://console.aws.amazon.com/ target=_blank>AWS Console</a> if you are using AWS. Other S3 compatible providers will also supply an access key and secret key for your account that you can enter here, along with the provider's endpoint URL.
79617961
s3_header=S3 account details
79627962
s3_desc=Account description
79637963
s3_access=S3 access key

‎list-s3-accounts.pl

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ package virtual_server;
5252
# Full details
5353
my @scheds = &list_scheduled_backups();
5454
foreach $s (@s3s) {
55-
print $s->{'access'},"\n";
55+
print $s->{'id'},"\n";
56+
print " Access key: $s->{'access'}\n";
5657
print " Secret key: $s->{'secret'}\n";
5758
if ($s->{'desc'}) {
5859
print " Description: $s->{'desc'}\n";

‎list-s3-buckets.pl

+1-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ package virtual_server;
5858
&usage("Unknown parameter $a");
5959
}
6060
}
61-
$akey ||= $config{'s3_akey'};
62-
$skey ||= $config{'s3_skey'};
61+
($akey, $skey) = &lookup_s3_credentials($akey, $skey);
6362
if (!&can_use_aws_s3_creds()) {
6463
$akey || &usage("Missing --access-key parameter");
6564
$skey || &usage("Missing --secret-key parameter");

‎list-s3-files.pl

+1-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ package virtual_server;
5858
&usage("Unknown parameter $a");
5959
}
6060
}
61-
$akey ||= $config{'s3_akey'};
62-
$skey ||= $config{'s3_skey'};
61+
($akey, $skey) = &lookup_s3_credentials($akey, $skey);
6362
if (!&can_use_aws_s3_creds()) {
6463
$akey || &usage("Missing --access-key parameter");
6564
$skey || &usage("Missing --secret-key parameter");

‎postinstall.pl

+3
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,9 @@ sub module_install
524524
}
525525
}
526526

527+
# Create S3 account entries from scheduled backups
528+
&create_s3_accounts_from_backups();
529+
527530
# Run any needed actions, like server restarts
528531
&run_post_actions_silently();
529532

‎s3-lib.pl

+26-1
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ sub list_s3_accounts
12441244
'default' => 1, });
12451245
}
12461246
if (opendir(DIR, $s3_accounts_dir)) {
1247-
foreach my $f (readdir(DIR)) {
1247+
foreach my $f (sort { $a cmp $b } readdir(DIR)) {
12481248
next if ($f eq "." || $f eq "..");
12491249
my %account;
12501250
&read_file("$s3_accounts_dir/$f", \%account);
@@ -1268,6 +1268,30 @@ sub get_s3_account
12681268
return $rv;
12691269
}
12701270

1271+
# get_default_s3_account()
1272+
# Returns the first or default S3 account
1273+
sub get_default_s3_account
1274+
{
1275+
my @s3s = &list_s3_accounts();
1276+
return undef if (!@s3s);
1277+
my ($s3) = grep { $_->{'default'} } @s3s;
1278+
$s3 ||= $s3s[0];
1279+
return $s3;
1280+
}
1281+
1282+
# lookup_s3_credentials([access-key], [secret-key])
1283+
# Returns either the default access and secret key, or the secret key from
1284+
# the account matching the access key
1285+
sub lookup_s3_credentials
1286+
{
1287+
my ($akey, $skey) = @_;
1288+
if ($akey && $skey) {
1289+
return ($akey, $skey);
1290+
}
1291+
my $s3 = $akey ? &get_s3_account($akey) : &get_default_s3_account();
1292+
return $s3 ? ( $s3->{'access'}, $s3->{'secret'} ) : ( );
1293+
}
1294+
12711295
# save_s3_account(&account)
12721296
# Create or update an S3 account
12731297
sub save_s3_account
@@ -1344,6 +1368,7 @@ sub create_s3_accounts_from_backups
13441368
'secret' => $skey,
13451369
'desc' => "S3 account from backup ".
13461370
$sched->{'desc'},
1371+
'endpoint' => $config{'s3_endpoint'},
13471372
};
13481373
&save_s3_account($s3);
13491374
push(@s3s, $s3);

‎upload-s3-file.pl

+1-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ package virtual_server;
7878
&usage("Unknown parameter $a");
7979
}
8080
}
81-
$akey ||= $config{'s3_akey'};
82-
$skey ||= $config{'s3_skey'};
81+
($akey, $skey) = &lookup_s3_credentials($akey, $skey);
8382
if (!&can_use_aws_s3_creds()) {
8483
$akey || &usage("Missing --access-key parameter");
8584
$skey || &usage("Missing --secret-key parameter");

0 commit comments

Comments
 (0)
Please sign in to comment.