Commit 2efc0cc7 authored by Stan Hu's avatar Stan Hu

Backup: Disable setting of ACL for Google uploads

Google Cloud Storage supports two types of access controls:

1. Uniform bucket level access
1. Fine-grained bucket level access

When Google uniform bucket uniform bucket access is enabled, uploading a
backup via object storage results in the error:

```
Google::Apis::ClientError (invalid: Cannot use ACL API to set object
policy when object policies are disabled.)
```

This happened because previously the backup manager passed in `public:
false`, which would cause fog-google to attempt to set the ACL of the
object to `privateProject`. This must be omitted when uniform
bucket-only policy is used. This is also the default level when
fine-grained bucket level access is used, so specifying the ACL doesn't
add anything.

This mirrors what we did with
https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/26781.

Closes https://gitlab.com/gitlab-org/gitlab/issues/35662
parent eb10fa5c
---
title: 'Backup: Disable setting of ACL for Google uploads'
merge_request: 20407
author:
type: fixed
...@@ -47,11 +47,7 @@ module Backup ...@@ -47,11 +47,7 @@ module Backup
directory = connect_to_remote_directory(connection_settings) directory = connect_to_remote_directory(connection_settings)
if directory.files.create(key: remote_target, body: File.open(tar_file), public: false, if directory.files.create(create_attributes)
multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
encryption: Gitlab.config.backup.upload.encryption,
encryption_key: Gitlab.config.backup.upload.encryption_key,
storage_class: Gitlab.config.backup.upload.storage_class)
progress.puts "done".color(:green) progress.puts "done".color(:green)
else else
puts "uploading backup to #{remote_directory} failed".color(:red) puts "uploading backup to #{remote_directory} failed".color(:red)
...@@ -252,5 +248,27 @@ module Backup ...@@ -252,5 +248,27 @@ module Backup
skipped: ENV["SKIP"] skipped: ENV["SKIP"]
} }
end end
def create_attributes
attrs = {
key: remote_target,
body: File.open(tar_file),
multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
encryption: Gitlab.config.backup.upload.encryption,
encryption_key: Gitlab.config.backup.upload.encryption_key,
storage_class: Gitlab.config.backup.upload.storage_class
}
# Google bucket-only policies prevent setting an ACL. In any case, by default,
# all objects are set to the default ACL, which is project-private:
# https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls
attrs[:public] = false unless google_provider?
attrs
end
def google_provider?
Gitlab.config.backup.upload.connection&.provider&.downcase == 'google'
end
end end
end end
...@@ -326,7 +326,7 @@ describe Backup::Manager do ...@@ -326,7 +326,7 @@ describe Backup::Manager do
context 'target path' do context 'target path' do
it 'uses the tar filename by default' do it 'uses the tar filename by default' do
expect_any_instance_of(Fog::Collection).to receive(:create) expect_any_instance_of(Fog::Collection).to receive(:create)
.with(hash_including(key: backup_filename)) .with(hash_including(key: backup_filename, public: false))
.and_return(true) .and_return(true)
Dir.chdir(Gitlab.config.backup.path) do Dir.chdir(Gitlab.config.backup.path) do
...@@ -338,7 +338,39 @@ describe Backup::Manager do ...@@ -338,7 +338,39 @@ describe Backup::Manager do
stub_env('DIRECTORY', 'daily') stub_env('DIRECTORY', 'daily')
expect_any_instance_of(Fog::Collection).to receive(:create) expect_any_instance_of(Fog::Collection).to receive(:create)
.with(hash_including(key: "daily/#{backup_filename}")) .with(hash_including(key: "daily/#{backup_filename}", public: false))
.and_return(true)
Dir.chdir(Gitlab.config.backup.path) do
subject.upload
end
end
end
context 'with Google provider' do
before do
stub_backup_setting(
upload: {
connection: {
provider: 'Google',
google_storage_access_key_id: 'test-access-id',
google_storage_secret_access_key: 'secret'
},
remote_directory: 'directory',
multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
encryption: nil,
encryption_key: nil,
storage_class: nil
}
)
connection = ::Fog::Storage.new(Gitlab.config.backup.upload.connection.symbolize_keys)
connection.directories.create(key: Gitlab.config.backup.upload.remote_directory)
end
it 'does not attempt to set ACL' do
expect_any_instance_of(Fog::Collection).to receive(:create)
.with(hash_excluding(public: false))
.and_return(true) .and_return(true)
Dir.chdir(Gitlab.config.backup.path) do Dir.chdir(Gitlab.config.backup.path) do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment