object_storage_buckets.go raw
1 package linodego
2
3 import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "time"
8
9 "github.com/google/go-querystring/query"
10 "github.com/linode/linodego/internal/parseabletime"
11 )
12
13 // ObjectStorageBucket represents a ObjectStorage object
14 type ObjectStorageBucket struct {
15 Label string `json:"label"`
16
17 // Deprecated: The 'Cluster' field has been deprecated in favor of the 'Region' field.
18 // For example, a Cluster value of `us-mia-1` will translate to a Region value of `us-mia`.
19 //
20 // This is necessary because there are now multiple Object Storage clusters to a region.
21 //
22 // NOTE: The 'Cluster' field will always return a value similar to `<REGION>-1` (e.g., `us-mia-1`)
23 // for backward compatibility purposes.
24 Cluster string `json:"cluster"`
25 Region string `json:"region"`
26
27 S3Endpoint string `json:"s3_endpoint"`
28 EndpointType ObjectStorageEndpointType `json:"endpoint_type"`
29 Created *time.Time `json:"-"`
30 Hostname string `json:"hostname"`
31 Objects int `json:"objects"`
32 Size int `json:"size"`
33 }
34
35 // ObjectStorageBucketAccess holds Object Storage access info
36 type ObjectStorageBucketAccess struct {
37 ACL ObjectStorageACL `json:"acl"`
38 CorsEnabled bool `json:"cors_enabled"`
39 }
40
41 type ObjectStorageBucketAccessV2 struct {
42 ACL ObjectStorageACL `json:"acl"`
43 ACLXML string `json:"acl_xml"`
44 CorsEnabled *bool `json:"cors_enabled"`
45 CorsXML *string `json:"cors_xml"`
46 }
47
48 // ObjectStorageBucketContent holds the content of an ObjectStorageBucket
49 type ObjectStorageBucketContent struct {
50 Data []ObjectStorageBucketContentData `json:"data"`
51 IsTruncated bool `json:"is_truncated"`
52 NextMarker *string `json:"next_marker"`
53 }
54
55 // ObjectStorageBucketContentData holds the data of the content of an ObjectStorageBucket
56 type ObjectStorageBucketContentData struct {
57 Etag string `json:"etag"`
58 LastModified *time.Time `json:"last_modified"`
59 Name string `json:"name"`
60 Owner string `json:"owner"`
61 Size int `json:"size"`
62 }
63
64 // UnmarshalJSON implements the json.Unmarshaler interface
65 func (i *ObjectStorageBucket) UnmarshalJSON(b []byte) error {
66 type Mask ObjectStorageBucket
67
68 p := struct {
69 *Mask
70
71 Created *parseabletime.ParseableTime `json:"created"`
72 }{
73 Mask: (*Mask)(i),
74 }
75
76 if err := json.Unmarshal(b, &p); err != nil {
77 return err
78 }
79
80 i.Created = (*time.Time)(p.Created)
81
82 return nil
83 }
84
85 // ObjectStorageBucketCreateOptions fields are those accepted by CreateObjectStorageBucket
86 type ObjectStorageBucketCreateOptions struct {
87 // Deprecated: The 'Cluster' field has been deprecated.
88 //
89 // Going forward, the 'Region' field will be the supported way to designate where an
90 // Object Storage Bucket should be created. For example, a 'Cluster' value of `us-mia-1`
91 // will translate to a Region value of `us-mia`.
92 Cluster string `json:"cluster,omitempty"`
93 Region string `json:"region,omitempty"`
94
95 Label string `json:"label"`
96 S3Endpoint string `json:"s3_endpoint,omitempty"`
97 EndpointType ObjectStorageEndpointType `json:"endpoint_type,omitempty"`
98
99 ACL ObjectStorageACL `json:"acl,omitempty"`
100 CorsEnabled *bool `json:"cors_enabled,omitempty"`
101 }
102
103 // ObjectStorageBucketUpdateAccessOptions fields are those accepted by UpdateObjectStorageBucketAccess
104 type ObjectStorageBucketUpdateAccessOptions struct {
105 ACL ObjectStorageACL `json:"acl,omitempty"`
106 CorsEnabled *bool `json:"cors_enabled,omitempty"`
107 }
108
109 // ObjectStorageBucketListContentsParams fields are the query parameters for ListObjectStorageBucketContents
110 type ObjectStorageBucketListContentsParams struct {
111 Marker *string
112 Delimiter *string
113 Prefix *string
114 PageSize *int
115 }
116
117 // ObjectStorageACL options start with ACL and include all known ACL types
118 type ObjectStorageACL string
119
120 // ObjectStorageACL options represent the access control level of a bucket.
121 const (
122 ACLPrivate ObjectStorageACL = "private"
123 ACLPublicRead ObjectStorageACL = "public-read"
124 ACLAuthenticatedRead ObjectStorageACL = "authenticated-read"
125 ACLPublicReadWrite ObjectStorageACL = "public-read-write"
126 )
127
128 // ListObjectStorageBuckets lists ObjectStorageBuckets
129 func (c *Client) ListObjectStorageBuckets(ctx context.Context, opts *ListOptions) ([]ObjectStorageBucket, error) {
130 return getPaginatedResults[ObjectStorageBucket](ctx, c, "object-storage/buckets", opts)
131 }
132
133 // ListObjectStorageBucketsInCluster lists all ObjectStorageBuckets of a cluster
134 func (c *Client) ListObjectStorageBucketsInCluster(ctx context.Context, opts *ListOptions, clusterOrRegionID string) ([]ObjectStorageBucket, error) {
135 return getPaginatedResults[ObjectStorageBucket](ctx, c, formatAPIPath("object-storage/buckets/%s", clusterOrRegionID), opts)
136 }
137
138 // GetObjectStorageBucket gets the ObjectStorageBucket with the provided label
139 func (c *Client) GetObjectStorageBucket(ctx context.Context, clusterOrRegionID, label string) (*ObjectStorageBucket, error) {
140 e := formatAPIPath("object-storage/buckets/%s/%s", clusterOrRegionID, label)
141 return doGETRequest[ObjectStorageBucket](ctx, c, e)
142 }
143
144 // CreateObjectStorageBucket creates an ObjectStorageBucket
145 func (c *Client) CreateObjectStorageBucket(ctx context.Context, opts ObjectStorageBucketCreateOptions) (*ObjectStorageBucket, error) {
146 return doPOSTRequest[ObjectStorageBucket](ctx, c, "object-storage/buckets", opts)
147 }
148
149 // GetObjectStorageBucketAccess gets the current access config for a bucket
150 //
151 // Deprecated: use GetObjectStorageBucketAccessV2 for new implementations
152 func (c *Client) GetObjectStorageBucketAccess(ctx context.Context, clusterOrRegionID, label string) (*ObjectStorageBucketAccess, error) {
153 e := formatAPIPath("object-storage/buckets/%s/%s/access", clusterOrRegionID, label)
154 return doGETRequest[ObjectStorageBucketAccess](ctx, c, e)
155 }
156
157 // UpdateObjectStorageBucketAccess updates the access configuration for an ObjectStorageBucket
158 func (c *Client) UpdateObjectStorageBucketAccess(ctx context.Context, clusterOrRegionID, label string, opts ObjectStorageBucketUpdateAccessOptions) error {
159 e := formatAPIPath("object-storage/buckets/%s/%s/access", clusterOrRegionID, label)
160 return doPOSTRequestNoResponseBody(ctx, c, e, opts)
161 }
162
163 // GetObjectStorageBucketAccessV2 gets the current access config for a bucket
164 func (c *Client) GetObjectStorageBucketAccessV2(ctx context.Context, clusterOrRegionID, label string) (*ObjectStorageBucketAccessV2, error) {
165 e := formatAPIPath("object-storage/buckets/%s/%s/access", clusterOrRegionID, label)
166 return doGETRequest[ObjectStorageBucketAccessV2](ctx, c, e)
167 }
168
169 // DeleteObjectStorageBucket deletes the ObjectStorageBucket with the specified label
170 func (c *Client) DeleteObjectStorageBucket(ctx context.Context, clusterOrRegionID, label string) error {
171 e := formatAPIPath("object-storage/buckets/%s/%s", clusterOrRegionID, label)
172 return doDELETERequest(ctx, c, e)
173 }
174
175 // ListObjectStorageBucketContents lists the contents of the specified ObjectStorageBucket
176 func (c *Client) ListObjectStorageBucketContents(
177 ctx context.Context,
178 clusterOrRegionID, label string,
179 params *ObjectStorageBucketListContentsParams,
180 ) (*ObjectStorageBucketContent, error) {
181 basePath := formatAPIPath("object-storage/buckets/%s/%s/object-list", clusterOrRegionID, label)
182
183 queryString := ""
184
185 if params != nil {
186 values, err := query.Values(params)
187 if err != nil {
188 return nil, fmt.Errorf("failed to encode query params: %w", err)
189 }
190
191 queryString = "?" + values.Encode()
192 }
193
194 e := basePath + queryString
195
196 return doGETRequest[ObjectStorageBucketContent](ctx, c, e)
197 }
198