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