Skip to content

Commit bb8c144

Browse files
authored
feat(simplestorage)!: achieve feature parity with TypeScript SDK (#26)
* feat(simplestorage)!: achieve feature parity with TypeScript SDK Add missing object operations and extended options to match @tigrisdata/storage, plus a few correctness fixes on top. Object operations: - Head: metadata-only retrieval with a presigned URL - GetPresignedUrl: GET/PUT URL generation with expiry + content type - Put options: WithAccessType, WithRandomSuffix, WithAllowOverwrite, WithContentDisposition, WithMultipartUpload, WithUploadProgress - Get options: WithResponseContentType, WithResponseContentDisposition, WithResponseCacheControl, WithQuerySnapshotVersion - List options: WithDelimiter, WithPrefix, WithPaginationToken; now returns *ListResult with CommonPrefixes and HasMore Bucket options: - WithBucketAccess, WithDefaultTier, WithConsistentRead, WithForkSourceSnapshot Correctness: - WithAllowOverwrite(false) now uses Tigris' If-Match: "" header (WithCreateObjectIfNotExists) for a server-side atomic check instead of a racy Head-then-Put. - storage.Client.CreateBucketSnapshot returns a new CreateBucketSnapshotOutput exposing SnapshotVersion from the X-Tigris-Snapshot-Version response header, so callers no longer need to list snapshots to learn the version. - simplestorage.ListBucketSnapshots now uses the dedicated storage.Client.ListBucketSnapshots wrapper and leaves SnapshotInfo.Name empty since the listing API does not return the user-provided description. BREAKING CHANGE: storage.Client.CreateBucketSnapshot now returns *CreateBucketSnapshotOutput instead of *s3.CreateBucketOutput. The new type embeds *s3.CreateBucketOutput so existing field access still works; callers that bound the return value to *s3.CreateBucketOutput must re-type their variables. BREAKING CHANGE: simplestorage.Client.List now returns *ListResult instead of []Object to carry CommonPrefixes, PaginationToken, and HasMore. Assisted-by: Claude Opus 4.7 via Claude Code Signed-off-by: Xe Iaso <xe@tigrisdata.com> * fix(simplestorage): default bucket Access to private BucketOptions.defaults() left Access as the empty zero value, which made bucketACL emit no canned ACL header. The WithBucketAccess docstring already documented private as the default, so align the implementation with the contract: seed Access in defaults() and have bucketACL fall through to BucketCannedACLPrivate so unset values still land on the wire as private. Add a regression test that asserts the default. Signed-off-by: Xe Iaso <xe@tigrisdata.com> Assisted-by: Claude Opus 4.7 via Claude Code Signed-off-by: Xe Iaso <xe@tigrisdata.com> * fix(simplestorage): handle rand.Read error in generateRandomSuffix Two issues: - rand.Read could return an error that the previous code silently dropped, leaving the suffix all-zeros if entropy failed. - length/2 truncated for odd lengths, producing a hex string shorter than the requested length before slicing. Return (string, error), use (length+1)/2 bytes so the hex output is always at least length characters before truncation, and propagate the error from Put with bucket/key context. Signed-off-by: Xe Iaso <xe@tigrisdata.com> Assisted-by: Claude Opus 4.7 via Claude Code Signed-off-by: Xe Iaso <xe@tigrisdata.com> --------- Signed-off-by: Xe Iaso <xe@tigrisdata.com>
1 parent 53063c8 commit bb8c144

12 files changed

Lines changed: 906 additions & 123 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ output, err := client.CreateSnapshotEnabledBucket(ctx, &s3.CreateBucketInput{
8484
output, err := client.CreateBucketSnapshot(ctx, "Initial backup", &s3.CreateBucketInput{
8585
Bucket: aws.String("my-bucket"),
8686
})
87+
// output.SnapshotVersion holds the version returned by Tigris.
8788
```
8889

8990
#### Fork a Bucket

bundle.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ var bundleHTTPClient = &http.Client{
3939
Transport: &http.Transport{
4040
Proxy: http.ProxyFromEnvironment,
4141
DialContext: (&net.Dialer{Timeout: 30 * time.Second}).DialContext,
42-
TLSHandshakeTimeout: 10 * time.Second,
42+
TLSHandshakeTimeout: 10 * time.Second,
4343
ResponseHeaderTimeout: 60 * time.Second,
4444
},
4545
}

client.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ type Client struct {
1616
*s3.Client
1717
}
1818

19+
// S3 returns the underlying S3 client.
20+
func (c *Client) S3() *s3.Client {
21+
return c.Client
22+
}
23+
1924
// CreateBucketFork creates a fork of the source bucket named target.
2025
//
2126
// If you want to specify an exact snapshot version to fork from, use tigrisheaders.WithSnapshotVersion.
@@ -27,11 +32,32 @@ func (c *Client) CreateBucketFork(ctx context.Context, source, target string, op
2732
}, opts...)
2833
}
2934

35+
// CreateBucketSnapshotOutput is the response from CreateBucketSnapshot.
36+
// It wraps the underlying s3.CreateBucketOutput and surfaces the snapshot
37+
// version that Tigris returns in the X-Tigris-Snapshot-Version response header.
38+
type CreateBucketSnapshotOutput struct {
39+
*s3.CreateBucketOutput
40+
41+
// SnapshotVersion is the version identifier of the snapshot just created.
42+
// Empty if the server did not return a version header.
43+
SnapshotVersion string
44+
}
45+
3046
// CreateBucketSnapshot creates a snapshot with the given description for a bucket.
31-
func (c *Client) CreateBucketSnapshot(ctx context.Context, description string, in *s3.CreateBucketInput, opts ...func(*s3.Options)) (*s3.CreateBucketOutput, error) {
47+
// The returned output carries the snapshot version in SnapshotVersion.
48+
func (c *Client) CreateBucketSnapshot(ctx context.Context, description string, in *s3.CreateBucketInput, opts ...func(*s3.Options)) (*CreateBucketSnapshotOutput, error) {
3249
opts = append(opts, tigrisheaders.WithTakeSnapshot(description))
3350

34-
return c.Client.CreateBucket(ctx, in, opts...)
51+
resp, err := c.Client.CreateBucket(ctx, in, opts...)
52+
if err != nil {
53+
return nil, err
54+
}
55+
56+
out := &CreateBucketSnapshotOutput{CreateBucketOutput: resp}
57+
if rawResp, ok := middleware.GetRawResponse(resp.ResultMetadata).(*http.Response); ok {
58+
out.SnapshotVersion = rawResp.Header.Get("X-Tigris-Snapshot-Version")
59+
}
60+
return out, nil
3561
}
3662

3763
// CreateSnapshotEnabledBucket creates a new bucket with the ability to take snapshots and fork the contents of it.

go.mod

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,30 @@ module github.com/tigrisdata/storage-go
33
go 1.25.5
44

55
require (
6-
github.com/aws/aws-sdk-go-v2 v1.41.0
7-
github.com/aws/aws-sdk-go-v2/config v1.32.6
8-
github.com/aws/aws-sdk-go-v2/credentials v1.19.6
9-
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0
10-
github.com/aws/smithy-go v1.24.0
6+
github.com/aws/aws-sdk-go-v2 v1.41.6
7+
github.com/aws/aws-sdk-go-v2/config v1.32.16
8+
github.com/aws/aws-sdk-go-v2/credentials v1.19.15
9+
github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.1.17
10+
github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1
11+
github.com/aws/smithy-go v1.25.0
1112
github.com/joho/godotenv v1.5.1
1213
)
1314

1415
require (
1516
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
16-
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
17-
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 // indirect
18-
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect
19-
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect
20-
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
21-
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 // indirect
22-
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
23-
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 // indirect
24-
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect
25-
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 // indirect
26-
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 // indirect
27-
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 // indirect
28-
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 // indirect
29-
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 // indirect
17+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9 // indirect
18+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 // indirect
19+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 // indirect
20+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 // indirect
21+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 // indirect
22+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 // indirect
23+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14 // indirect
24+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 // indirect
25+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22 // indirect
26+
github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 // indirect
27+
github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 // indirect
28+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 // indirect
29+
github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 // indirect
3030
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect
3131
golang.org/x/mod v0.32.0 // indirect
3232
golang.org/x/sync v0.19.0 // indirect

go.sum

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,43 @@
11
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
22
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
3-
github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4=
4-
github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
5-
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
6-
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=
7-
github.com/aws/aws-sdk-go-v2/config v1.32.6 h1:hFLBGUKjmLAekvi1evLi5hVvFQtSo3GYwi+Bx4lpJf8=
8-
github.com/aws/aws-sdk-go-v2/config v1.32.6/go.mod h1:lcUL/gcd8WyjCrMnxez5OXkO3/rwcNmvfno62tnXNcI=
9-
github.com/aws/aws-sdk-go-v2/credentials v1.19.6 h1:F9vWao2TwjV2MyiyVS+duza0NIRtAslgLUM0vTA1ZaE=
10-
github.com/aws/aws-sdk-go-v2/credentials v1.19.6/go.mod h1:SgHzKjEVsdQr6Opor0ihgWtkWdfRAIwxYzSJ8O85VHY=
11-
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 h1:80+uETIWS1BqjnN9uJ0dBUaETh+P1XwFy5vwHwK5r9k=
12-
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16/go.mod h1:wOOsYuxYuB/7FlnVtzeBYRcjSRtQpAW0hCP7tIULMwo=
13-
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc=
14-
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA=
15-
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U=
16-
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc=
17-
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
18-
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
19-
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 h1:CjMzUs78RDDv4ROu3JnJn/Ig1r6ZD7/T2DXLLRpejic=
20-
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16/go.mod h1:uVW4OLBqbJXSHJYA9svT9BluSvvwbzLQ2Crf6UPzR3c=
21-
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
22-
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
23-
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 h1:DIBqIrJ7hv+e4CmIk2z3pyKT+3B6qVMgRsawHiR3qso=
24-
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7/go.mod h1:vLm00xmBke75UmpNvOcZQ/Q30ZFjbczeLFqGx5urmGo=
25-
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI=
26-
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM=
27-
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 h1:NSbvS17MlI2lurYgXnCOLvCFX38sBW4eiVER7+kkgsU=
28-
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16/go.mod h1:SwT8Tmqd4sA6G1qaGdzWCJN99bUmPGHfRwwq3G5Qb+A=
29-
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0 h1:MIWra+MSq53CFaXXAywB2qg9YvVZifkk6vEGl/1Qor0=
30-
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0/go.mod h1:79S2BdqCJpScXZA2y+cpZuocWsjGjJINyXnOsf5DTz8=
31-
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 h1:HpI7aMmJ+mm1wkSHIA2t5EaFFv5EFYXePW30p1EIrbQ=
32-
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4/go.mod h1:C5RdGMYGlfM0gYq/tifqgn4EbyX99V15P2V3R+VHbQU=
33-
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 h1:aM/Q24rIlS3bRAhTyFurowU8A0SMyGDtEOY/l/s/1Uw=
34-
github.com/aws/aws-sdk-go-v2/service/sso v1.30.8/go.mod h1:+fWt2UHSb4kS7Pu8y+BMBvJF0EWx+4H0hzNwtDNRTrg=
35-
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 h1:AHDr0DaHIAo8c9t1emrzAlVDFp+iMMKnPdYy6XO4MCE=
36-
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12/go.mod h1:GQ73XawFFiWxyWXMHWfhiomvP3tXtdNar/fi8z18sx0=
37-
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70=
38-
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk=
39-
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
40-
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
3+
github.com/aws/aws-sdk-go-v2 v1.41.6 h1:1AX0AthnBQzMx1vbmir3Y4WsnJgiydmnJjiLu+LvXOg=
4+
github.com/aws/aws-sdk-go-v2 v1.41.6/go.mod h1:dy0UzBIfwSeot4grGvY1AqFWN5zgziMmWGzysDnHFcQ=
5+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9 h1:adBsCIIpLbLmYnkQU+nAChU5yhVTvu5PerROm+/Kq2A=
6+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9/go.mod h1:uOYhgfgThm/ZyAuJGNQ5YgNyOlYfqnGpTHXvk3cpykg=
7+
github.com/aws/aws-sdk-go-v2/config v1.32.16 h1:Q0iQ7quUgJP0F/SCRTieScnaMdXr9h/2+wze1u3cNeM=
8+
github.com/aws/aws-sdk-go-v2/config v1.32.16/go.mod h1:duCCnJEFqpt2RC6no1iK6q+8HpwOAkiUua0pY507dQc=
9+
github.com/aws/aws-sdk-go-v2/credentials v1.19.15 h1:fyvgWTszojq8hEnMi8PPBTvZdTtEVmAVyo+NFLHBhH4=
10+
github.com/aws/aws-sdk-go-v2/credentials v1.19.15/go.mod h1:gJiYyMOjNg8OEdRWOf3CrFQxM2a98qmrtjx1zuiQfB8=
11+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 h1:IOGsJ1xVWhsi+ZO7/NW8OuZZBtMJLZbk4P5HDjJO0jQ=
12+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22/go.mod h1:b+hYdbU+jGKfXE8kKM6g1+h+L/Go3vMvzlxBsiuGsxg=
13+
github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.1.17 h1:95y7/EqethAhFwMKJ9cDutzBhsS1h8uBwkJ5rp8pNTU=
14+
github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.1.17/go.mod h1:77baheqr62SkTw77HWH8qpdWTd2gXKN0xg0qLvDSkpk=
15+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 h1:GmLa5Kw1ESqtFpXsx5MmC84QWa/ZrLZvlJGa2y+4kcQ=
16+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22/go.mod h1:6sW9iWm9DK9YRpRGga/qzrzNLgKpT2cIxb7Vo2eNOp0=
17+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 h1:dY4kWZiSaXIzxnKlj17nHnBcXXBfac6UlsAx2qL6XrU=
18+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22/go.mod h1:KIpEUx0JuRZLO7U6cbV204cWAEco2iC3l061IxlwLtI=
19+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 h1:FPXsW9+gMuIeKmz7j6ENWcWtBGTe1kH8r9thNt5Uxx4=
20+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23/go.mod h1:7J8iGMdRKk6lw2C+cMIphgAnT8uTwBwNOsGkyOCm80U=
21+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 h1:HtOTYcbVcGABLOVuPYaIihj6IlkqubBwFj10K5fxRek=
22+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8/go.mod h1:VsK9abqQeGlzPgUr+isNWzPlK2vKe9INMLWnY65f5Xs=
23+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14 h1:xnvDEnw+pnj5mctWiYuFbigrEzSm35x7k4KS/ZkCANg=
24+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14/go.mod h1:yS5rNogD8e0Wu9+l3MUwr6eENBzEeGejvINpN5PAYfY=
25+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 h1:PUmZeJU6Y1Lbvt9WFuJ0ugUK2xn6hIWUBBbKuOWF30s=
26+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22/go.mod h1:nO6egFBoAaoXze24a2C0NjQCvdpk8OueRoYimvEB9jo=
27+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22 h1:SE+aQ4DEqG53RRCAIHlCf//B2ycxGH7jFkpnAh/kKPM=
28+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22/go.mod h1:ES3ynECd7fYeJIL6+oax+uIEljmfps0S70BaQzbMd/o=
29+
github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1 h1:kU/eBN5+MWNo/LcbNa4hWDdN76hdcd7hocU5kvu7IsU=
30+
github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1/go.mod h1:Fw9aqhJicIVee1VytBBjH+l+5ov6/PhbtIK/u3rt/ls=
31+
github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 h1:a1Fq/KXn75wSzoJaPQTgZO0wHGqE9mjFnylnqEPTchA=
32+
github.com/aws/aws-sdk-go-v2/service/signin v1.0.10/go.mod h1:p6+MXNxW7IA6dMgHfTAzljuwSKD0NCm/4lbS4t6+7vI=
33+
github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 h1:x6bKbmDhsgSZwv6q19wY/u3rLk/3FGjJWyqKcIRufpE=
34+
github.com/aws/aws-sdk-go-v2/service/sso v1.30.16/go.mod h1:CudnEVKRtLn0+3uMV0yEXZ+YZOKnAtUJ5DmDhilVnIw=
35+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 h1:oK/njaL8GtyEihkWMD4k3VgHCT64RQKkZwh0DG5j8ak=
36+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20/go.mod h1:JHs8/y1f3zY7U5WcuzoJ/yAYGYtNIVPKLIbp61euvmg=
37+
github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 h1:ks8KBcZPh3PYISr5dAiXCM5/Thcuxk8l+PG4+A0exds=
38+
github.com/aws/aws-sdk-go-v2/service/sts v1.42.0/go.mod h1:pFw33T0WLvXU3rw1WBkpMlkgIn54eCB5FYLhjDc9Foo=
39+
github.com/aws/smithy-go v1.25.0 h1:Sz/XJ64rwuiKtB6j98nDIPyYrV1nVNJ4YU74gttcl5U=
40+
github.com/aws/smithy-go v1.25.0/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
4141
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
4242
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
4343
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=

simplestorage/bucket_options.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package simplestorage
22

33
import (
44
"github.com/aws/aws-sdk-go-v2/service/s3"
5+
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
56
"github.com/tigrisdata/storage-go/tigrisheaders"
67
)
78

@@ -16,12 +17,24 @@ type BucketOptions struct {
1617
// SnapshotVersion specifies a snapshot version to target (for forking from specific snapshot).
1718
SnapshotVersion string
1819

20+
// SourceBucketSnapshot specifies the snapshot version to fork from.
21+
SourceBucketSnapshot string
22+
1923
// Region sets static replication region for the bucket.
2024
// This field is stored for visibility but the actual behavior is configured
2125
// via S3Options (see WithBucketRegion). Keeping the field enables debugging
2226
// and potential future use in bucket info responses.
2327
Region string
2428

29+
// DefaultTier sets the storage class tier for the bucket.
30+
DefaultTier string
31+
32+
// Consistency sets the consistency level for the bucket ("strict" or "default").
33+
Consistency string
34+
35+
// Access sets the bucket-level access type (public or private).
36+
Access AccessType
37+
2538
// MaxKeys sets the maximum number of results to return in ListBuckets.
2639
MaxKeys *int32
2740

@@ -36,6 +49,7 @@ type BucketOptions struct {
3649
func (BucketOptions) defaults() BucketOptions {
3750
return BucketOptions{
3851
EnableSnapshot: false,
52+
Access: AccessPrivate,
3953
MaxKeys: nil,
4054
ContinuationToken: nil,
4155
S3Options: []func(*s3.Options){},
@@ -84,3 +98,50 @@ func WithListToken(token string) BucketOption {
8498
o.ContinuationToken = &token
8599
}
86100
}
101+
102+
// WithDefaultTier sets the storage class tier for the bucket.
103+
// Valid values: "STANDARD", "STANDARD_IA", "GLACIER", "GLACIER_IR"
104+
func WithDefaultTier(tier string) BucketOption {
105+
return func(o *BucketOptions) {
106+
o.DefaultTier = tier
107+
o.S3Options = append(o.S3Options, tigrisheaders.WithStorageClass(tier))
108+
}
109+
}
110+
111+
// WithConsistentRead enables consistent read mode for the bucket.
112+
func WithConsistentRead() BucketOption {
113+
return func(o *BucketOptions) {
114+
o.Consistency = "strict"
115+
o.S3Options = append(o.S3Options, tigrisheaders.WithConsistentRead())
116+
}
117+
}
118+
119+
// WithForkSourceSnapshot specifies the snapshot version when forking from a bucket.
120+
// Use this with CreateBucket when forking from a specific snapshot version.
121+
func WithForkSourceSnapshot(snapshot string) BucketOption {
122+
return func(o *BucketOptions) {
123+
o.SourceBucketSnapshot = snapshot
124+
o.S3Options = append(o.S3Options, tigrisheaders.WithForkSourceBucketSnapshot(snapshot))
125+
}
126+
}
127+
128+
// WithBucketAccess sets the bucket-level canned ACL (public or private).
129+
// Use AccessPublic to allow anonymous reads via public-read, or AccessPrivate
130+
// (the default) to require authenticated access.
131+
func WithBucketAccess(access AccessType) BucketOption {
132+
return func(o *BucketOptions) {
133+
o.Access = access
134+
}
135+
}
136+
137+
// bucketACL maps an AccessType to an S3 canned ACL for bucket operations.
138+
// Defaults to private for unset values so callers don't accidentally inherit
139+
// a permissive account-wide default.
140+
func bucketACL(a AccessType) s3types.BucketCannedACL {
141+
switch a {
142+
case AccessPublic:
143+
return s3types.BucketCannedACLPublicRead
144+
default:
145+
return s3types.BucketCannedACLPrivate
146+
}
147+
}

0 commit comments

Comments
 (0)