Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions gcs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The GCS client requires a JSON configuration file.
"json_key": "<string> (required if credentials_source = 'static')",
"storage_class": "<string> (optional - default: 'STANDARD', check for more options=https://docs.cloud.google.com/storage/docs/storage-classes)",
"encryption_key": "<string> (optional)",
"uniform_bucket_level_access": "<boolean> (optional)"
}
```

Expand All @@ -26,6 +27,12 @@ The GCS client requires a JSON configuration file.
* **"none":** specifies that credentials are explicitly empty and that the client should be restricted to a read-only scope.
* **"static:"** specifies that a service account file included in json_key should be used for authentication.

### Bucket Creation
The `ensure-storage-exists` command creates a bucket if it does not already exist. The `uniform_bucket_level_access` configuration option controls the access control model:
* **`true`**: Creates a bucket with uniform bucket-level access (IAM-only, ACLs disabled)
* **`false` or omitted (default)**: Creates a bucket with fine-grained access control (ACLs enabled)


### Authentication Methods (`credentials_source`)
* `static`: A [service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) key will be provided via the `json_key` field.
* `none`: No credentials are provided. The client is reading from a public bucket.
Expand Down
4 changes: 4 additions & 0 deletions gcs/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,10 @@ func (client *GCSBlobstore) EnsureStorageExists() error {
battr.StorageClass = client.config.StorageClass
}

if client.config.UniformBucketLevelAccess {
battr.UniformBucketLevelAccess = storage.UniformBucketLevelAccess{Enabled: true}
}

projectID, err := extractProjectID(ctx, client.config)
if err != nil {
return fmt.Errorf("extracting project ID: %w", err)
Expand Down
5 changes: 5 additions & 0 deletions gcs/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ type GCSCli struct {
// StorageClass is the type of storage used for objects added to the bucket
// https://cloud.google.com/storage/docs/storage-classes
StorageClass string `json:"storage_class"`
// UniformBucketLevelAccess enables uniform bucket-level access control.
// When true, disables ACLs and uses only IAM for permissions.
// When false (default), buckets use fine-grained ACL-based access control.
// https://cloud.google.com/storage/docs/uniform-bucket-level-access
UniformBucketLevelAccess bool `json:"uniform_bucket_level_access"`
// EncryptionKey is a Customer-Supplied encryption key used to
// encrypt objects added to the bucket.
// If left empty, no explicit encryption key will be used;
Expand Down
23 changes: 23 additions & 0 deletions gcs/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,27 @@ var _ = Describe("BlobstoreClient configuration", func() {
})
})

Describe("when uniform_bucket_level_access is set to true", func() {
dummyJSONBytes := []byte(`{"bucket_name": "some-bucket", "uniform_bucket_level_access":true}`)
dummyJSONReader := bytes.NewReader(dummyJSONBytes)

It("it has value true", func() {
c, err := NewFromReader(dummyJSONReader)
Expect(err).To(BeNil())
Expect(c.UniformBucketLevelAccess).To(BeTrue())

})
})

Describe("when uniform_bucket_level_access is not set", func() {
dummyJSONBytes := []byte(`{"bucket_name": "some-bucket"}`)
dummyJSONReader := bytes.NewReader(dummyJSONBytes)

It("it has value false", func() {
c, err := NewFromReader(dummyJSONReader)
Expect(err).To(BeNil())
Expect(c.UniformBucketLevelAccess).To(BeFalse())
})
})

})
Loading