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