Skip to content

Commit

Permalink
project: MultiCluster Object Storage (#522)
Browse files Browse the repository at this point in the history
* Add MultiCluster API changes support for key and bucket structs (#516)

* Deprecate OBJ Clusters List and View Functions (#517)

* Mark ListObjectStorageClusters and GetObjectStorageCluster as deprecated

* format code

* Update deprecated warning wording

Co-authored-by: Lena Garber <[email protected]>

* Update deprecated warning wording

Co-authored-by: Lena Garber <[email protected]>

---------

Co-authored-by: Lena Garber <[email protected]>

* Deprecated OBJ Cluster Fields (#524)

* Fix typo

---------

Co-authored-by: Lena Garber <[email protected]>
  • Loading branch information
zliang-akamai and lgarber-akamai authored Jul 9, 2024
1 parent 2a5ae92 commit 4243c0e
Show file tree
Hide file tree
Showing 10 changed files with 918 additions and 54 deletions.
2 changes: 1 addition & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func TestDebugLogSanitization(t *testing.T) {
Label string `json:"label"`
}

var testResp = instanceResponse{
testResp := instanceResponse{
ID: 100,
Region: "test-central",
Label: "this-is-a-test-linode",
Expand Down
18 changes: 9 additions & 9 deletions object_storage_bucket_certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ type ObjectStorageBucketCertUploadOptions struct {
}

// UploadObjectStorageBucketCert uploads a TLS/SSL Cert to be used with an Object Storage Bucket.
func (c *Client) UploadObjectStorageBucketCert(ctx context.Context, clusterID, bucket string, opts ObjectStorageBucketCertUploadOptions) (*ObjectStorageBucketCert, error) {
func (c *Client) UploadObjectStorageBucketCert(ctx context.Context, clusterOrRegionID, bucket string, opts ObjectStorageBucketCertUploadOptions) (*ObjectStorageBucketCert, error) {
body, err := json.Marshal(opts)
if err != nil {
return nil, err
}

clusterID = url.PathEscape(clusterID)
clusterOrRegionID = url.PathEscape(clusterOrRegionID)
bucket = url.PathEscape(bucket)
e := fmt.Sprintf("object-storage/buckets/%s/%s/ssl", clusterID, bucket)
e := fmt.Sprintf("object-storage/buckets/%s/%s/ssl", clusterOrRegionID, bucket)
req := c.R(ctx).SetResult(&ObjectStorageBucketCert{}).SetBody(string(body))
r, err := coupleAPIErrors(req.Post(e))
if err != nil {
Expand All @@ -35,10 +35,10 @@ func (c *Client) UploadObjectStorageBucketCert(ctx context.Context, clusterID, b
}

// GetObjectStorageBucketCert gets an ObjectStorageBucketCert
func (c *Client) GetObjectStorageBucketCert(ctx context.Context, clusterID, bucket string) (*ObjectStorageBucketCert, error) {
clusterID = url.PathEscape(clusterID)
func (c *Client) GetObjectStorageBucketCert(ctx context.Context, clusterOrRegionID, bucket string) (*ObjectStorageBucketCert, error) {
clusterOrRegionID = url.PathEscape(clusterOrRegionID)
bucket = url.PathEscape(bucket)
e := fmt.Sprintf("object-storage/buckets/%s/%s/ssl", clusterID, bucket)
e := fmt.Sprintf("object-storage/buckets/%s/%s/ssl", clusterOrRegionID, bucket)
req := c.R(ctx).SetResult(&ObjectStorageBucketCert{})
r, err := coupleAPIErrors(req.Get(e))
if err != nil {
Expand All @@ -48,10 +48,10 @@ func (c *Client) GetObjectStorageBucketCert(ctx context.Context, clusterID, buck
}

// DeleteObjectStorageBucketCert deletes an ObjectStorageBucketCert
func (c *Client) DeleteObjectStorageBucketCert(ctx context.Context, clusterID, bucket string) error {
clusterID = url.PathEscape(clusterID)
func (c *Client) DeleteObjectStorageBucketCert(ctx context.Context, clusterOrRegionID, bucket string) error {
clusterOrRegionID = url.PathEscape(clusterOrRegionID)
bucket = url.PathEscape(bucket)
e := fmt.Sprintf("object-storage/buckets/%s/%s/ssl", clusterID, bucket)
e := fmt.Sprintf("object-storage/buckets/%s/%s/ssl", clusterOrRegionID, bucket)
_, err := coupleAPIErrors(c.R(ctx).Delete(e))
return err
}
48 changes: 32 additions & 16 deletions object_storage_buckets.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,17 @@ import (

// ObjectStorageBucket represents a ObjectStorage object
type ObjectStorageBucket struct {
Label string `json:"label"`
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"`

Created *time.Time `json:"-"`
Hostname string `json:"hostname"`
Expand Down Expand Up @@ -50,8 +59,15 @@ func (i *ObjectStorageBucket) UnmarshalJSON(b []byte) error {

// ObjectStorageBucketCreateOptions fields are those accepted by CreateObjectStorageBucket
type ObjectStorageBucketCreateOptions struct {
Cluster string `json:"cluster"`
Label string `json:"label"`
// 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"`

ACL ObjectStorageACL `json:"acl,omitempty"`
CorsEnabled *bool `json:"cors_enabled,omitempty"`
Expand Down Expand Up @@ -110,20 +126,20 @@ func (c *Client) ListObjectStorageBuckets(ctx context.Context, opts *ListOptions
}

// ListObjectStorageBucketsInCluster lists all ObjectStorageBuckets of a cluster
func (c *Client) ListObjectStorageBucketsInCluster(ctx context.Context, opts *ListOptions, clusterID string) ([]ObjectStorageBucket, error) {
func (c *Client) ListObjectStorageBucketsInCluster(ctx context.Context, opts *ListOptions, clusterOrRegionID string) ([]ObjectStorageBucket, error) {
response := ObjectStorageBucketsPagedResponse{}
err := c.listHelper(ctx, &response, opts, clusterID)
err := c.listHelper(ctx, &response, opts, clusterOrRegionID)
if err != nil {
return nil, err
}
return response.Data, nil
}

// GetObjectStorageBucket gets the ObjectStorageBucket with the provided label
func (c *Client) GetObjectStorageBucket(ctx context.Context, clusterID, label string) (*ObjectStorageBucket, error) {
func (c *Client) GetObjectStorageBucket(ctx context.Context, clusterOrRegionID, label string) (*ObjectStorageBucket, error) {
label = url.PathEscape(label)
clusterID = url.PathEscape(clusterID)
e := fmt.Sprintf("object-storage/buckets/%s/%s", clusterID, label)
clusterOrRegionID = url.PathEscape(clusterOrRegionID)
e := fmt.Sprintf("object-storage/buckets/%s/%s", clusterOrRegionID, label)
req := c.R(ctx).SetResult(&ObjectStorageBucket{})
r, err := coupleAPIErrors(req.Get(e))
if err != nil {
Expand All @@ -149,10 +165,10 @@ func (c *Client) CreateObjectStorageBucket(ctx context.Context, opts ObjectStora
}

// GetObjectStorageBucketAccess gets the current access config for a bucket
func (c *Client) GetObjectStorageBucketAccess(ctx context.Context, clusterID, label string) (*ObjectStorageBucketAccess, error) {
func (c *Client) GetObjectStorageBucketAccess(ctx context.Context, clusterOrRegionID, label string) (*ObjectStorageBucketAccess, error) {
label = url.PathEscape(label)
clusterID = url.PathEscape(clusterID)
e := fmt.Sprintf("object-storage/buckets/%s/%s/access", clusterID, label)
clusterOrRegionID = url.PathEscape(clusterOrRegionID)
e := fmt.Sprintf("object-storage/buckets/%s/%s/access", clusterOrRegionID, label)
req := c.R(ctx).SetResult(&ObjectStorageBucketAccess{})
r, err := coupleAPIErrors(req.Get(e))
if err != nil {
Expand All @@ -163,15 +179,15 @@ func (c *Client) GetObjectStorageBucketAccess(ctx context.Context, clusterID, la
}

// UpdateObjectStorageBucketAccess updates the access configuration for an ObjectStorageBucket
func (c *Client) UpdateObjectStorageBucketAccess(ctx context.Context, clusterID, label string, opts ObjectStorageBucketUpdateAccessOptions) error {
func (c *Client) UpdateObjectStorageBucketAccess(ctx context.Context, clusterOrRegionID, label string, opts ObjectStorageBucketUpdateAccessOptions) error {
body, err := json.Marshal(opts)
if err != nil {
return err
}

label = url.PathEscape(label)
clusterID = url.PathEscape(clusterID)
e := fmt.Sprintf("object-storage/buckets/%s/%s/access", clusterID, label)
clusterOrRegionID = url.PathEscape(clusterOrRegionID)
e := fmt.Sprintf("object-storage/buckets/%s/%s/access", clusterOrRegionID, label)
_, err = coupleAPIErrors(c.R(ctx).SetBody(string(body)).Post(e))
if err != nil {
return err
Expand All @@ -181,9 +197,9 @@ func (c *Client) UpdateObjectStorageBucketAccess(ctx context.Context, clusterID,
}

// DeleteObjectStorageBucket deletes the ObjectStorageBucket with the specified label
func (c *Client) DeleteObjectStorageBucket(ctx context.Context, clusterID, label string) error {
func (c *Client) DeleteObjectStorageBucket(ctx context.Context, clusterOrRegionID, label string) error {
label = url.PathEscape(label)
e := fmt.Sprintf("object-storage/buckets/%s/%s", clusterID, label)
e := fmt.Sprintf("object-storage/buckets/%s/%s", clusterOrRegionID, label)
_, err := coupleAPIErrors(c.R(ctx).Delete(e))
return err
}
2 changes: 2 additions & 0 deletions object_storage_clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func (resp *ObjectStorageClustersPagedResponse) castResult(r *resty.Request, e s
return castedRes.Pages, castedRes.Results, nil
}

// Deprecated: ListObjectStorageClusters uses a deprecated API endpoint.
// ListObjectStorageClusters lists ObjectStorageClusters
func (c *Client) ListObjectStorageClusters(ctx context.Context, opts *ListOptions) ([]ObjectStorageCluster, error) {
response := ObjectStorageClustersPagedResponse{}
Expand All @@ -48,6 +49,7 @@ func (c *Client) ListObjectStorageClusters(ctx context.Context, opts *ListOption
return response.Data, nil
}

// Deprecated: GetObjectStorageCluster uses a deprecated API endpoint.
// GetObjectStorageCluster gets the template with the provided ID
func (c *Client) GetObjectStorageCluster(ctx context.Context, clusterID string) (*ObjectStorageCluster, error) {
clusterID = url.PathEscape(clusterID)
Expand Down
19 changes: 16 additions & 3 deletions object_storage_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import (
"github.com/go-resty/resty/v2"
)

type ObjectStorageKeyRegion struct {
ID string `json:"id"`
S3Endpoint string `json:"s3_endpoint"`
}

// ObjectStorageKey represents a linode object storage key object
type ObjectStorageKey struct {
ID int `json:"id"`
Expand All @@ -16,24 +21,32 @@ type ObjectStorageKey struct {
SecretKey string `json:"secret_key"`
Limited bool `json:"limited"`
BucketAccess *[]ObjectStorageKeyBucketAccess `json:"bucket_access"`
Regions []ObjectStorageKeyRegion `json:"regions"`
}

// ObjectStorageKeyBucketAccess represents a linode limited object storage key's bucket access
type ObjectStorageKeyBucketAccess struct {
Cluster string `json:"cluster"`
// Deprecated: Cluster field has been deprecated.
// Please consider switching to use the 'Region' field.
// If your Cluster is `us-mia-1`, then the region would be `us-mia`.
Cluster string `json:"cluster,omitempty"`
Region string `json:"region,omitempty"`

BucketName string `json:"bucket_name"`
Permissions string `json:"permissions"`
}

// ObjectStorageKeyCreateOptions fields are those accepted by CreateObjectStorageKey
type ObjectStorageKeyCreateOptions struct {
Label string `json:"label"`
BucketAccess *[]ObjectStorageKeyBucketAccess `json:"bucket_access"`
BucketAccess *[]ObjectStorageKeyBucketAccess `json:"bucket_access,omitempty"`
Regions []string `json:"regions,omitempty"`
}

// ObjectStorageKeyUpdateOptions fields are those accepted by UpdateObjectStorageKey
type ObjectStorageKeyUpdateOptions struct {
Label string `json:"label"`
Label string `json:"label,omitempty"`
Regions []string `json:"regions,omitempty"`
}

// ObjectStorageKeysPagedResponse represents a linode API response for listing
Expand Down
Loading

0 comments on commit 4243c0e

Please sign in to comment.