storj.io/uplink@v1.13.0/private/bucket/buckets.go (about)

     1  // Copyright (C) 2022 Storj Labs, Inc.
     2  // See LICENSE for copying information.
     3  
     4  package bucket
     5  
     6  import (
     7  	"context"
     8  	_ "unsafe" // for go:linkname
     9  
    10  	"github.com/spacemonkeygo/monkit/v3"
    11  	"github.com/zeebo/errs"
    12  
    13  	"storj.io/uplink"
    14  	"storj.io/uplink/private/metaclient"
    15  )
    16  
    17  var mon = monkit.Package()
    18  
    19  // Bucket contains information about the bucket.
    20  type Bucket metaclient.Bucket
    21  
    22  // ListBucketsOptions defines bucket listing options.
    23  type ListBucketsOptions struct {
    24  	// Cursor sets the starting position of the iterator. The first item listed will be the one after the cursor.
    25  	Cursor string
    26  }
    27  
    28  // ListBucketsWithAttribution returns an iterator over the buckets.
    29  func ListBucketsWithAttribution(ctx context.Context, project *uplink.Project, options *ListBucketsOptions) *Iterator {
    30  	defer mon.Task()(&ctx)(nil)
    31  
    32  	if options == nil {
    33  		options = &ListBucketsOptions{}
    34  	}
    35  
    36  	buckets := Iterator{
    37  		iterator: metaclient.IterateBuckets(ctx, metaclient.IterateBucketsOptions{
    38  			Cursor: options.Cursor,
    39  			DialClientFunc: func() (*metaclient.Client, error) {
    40  				return dialMetainfoClient(ctx, project)
    41  			},
    42  		}),
    43  	}
    44  
    45  	return &buckets
    46  }
    47  
    48  // Iterator is an iterator over a collection of buckets.
    49  type Iterator struct {
    50  	iterator *metaclient.BucketIterator
    51  }
    52  
    53  // Next prepares next Bucket for reading.
    54  // It returns false if the end of the iteration is reached and there are no more buckets, or if there is an error.
    55  func (buckets *Iterator) Next() bool {
    56  	return buckets.iterator.Next()
    57  }
    58  
    59  // Err returns error, if one happened during iteration.
    60  func (buckets *Iterator) Err() error {
    61  	return convertKnownErrors(buckets.iterator.Err(), "", "")
    62  }
    63  
    64  // Item returns the current bucket in the iterator.
    65  func (buckets *Iterator) Item() *Bucket {
    66  	item := buckets.iterator.Item()
    67  	if item == nil {
    68  		return nil
    69  	}
    70  	return &Bucket{
    71  		Name:        item.Name,
    72  		Created:     item.Created,
    73  		Attribution: item.Attribution,
    74  	}
    75  }
    76  
    77  // GetBucketLocation returns bucket location.
    78  func GetBucketLocation(ctx context.Context, project *uplink.Project, bucketName string) (_ string, err error) {
    79  	defer mon.Task()(&ctx)(&err)
    80  
    81  	if bucketName == "" {
    82  		return "", convertKnownErrors(metaclient.ErrNoBucket.New(""), bucketName, "")
    83  	}
    84  
    85  	metainfoClient, err := dialMetainfoClient(ctx, project)
    86  	if err != nil {
    87  		return "", convertKnownErrors(err, bucketName, "")
    88  	}
    89  	defer func() { err = errs.Combine(err, metainfoClient.Close()) }()
    90  
    91  	response, err := metainfoClient.GetBucketLocation(ctx, metaclient.GetBucketLocationParams{
    92  		Name: []byte(bucketName),
    93  	})
    94  	return string(response.Location), convertKnownErrors(err, bucketName, "")
    95  }
    96  
    97  // GetBucketVersioning returns bucket versioning state.
    98  func GetBucketVersioning(ctx context.Context, project *uplink.Project, bucketName string) (_ int32, err error) {
    99  	defer mon.Task()(&ctx)(&err)
   100  
   101  	if bucketName == "" {
   102  		return 0, convertKnownErrors(metaclient.ErrNoBucket.New(""), bucketName, "")
   103  	}
   104  
   105  	metainfoClient, err := dialMetainfoClient(ctx, project)
   106  	if err != nil {
   107  		return 0, convertKnownErrors(err, bucketName, "")
   108  	}
   109  	defer func() { err = errs.Combine(err, metainfoClient.Close()) }()
   110  
   111  	response, err := metainfoClient.GetBucketVersioning(ctx, metaclient.GetBucketVersioningParams{
   112  		Name: []byte(bucketName),
   113  	})
   114  	return response.Versioning, convertKnownErrors(err, bucketName, "")
   115  }
   116  
   117  // SetBucketVersioning sets the versioning state for a bucket. True will attempt to enable versioning,
   118  // false will attempt to disable it.
   119  func SetBucketVersioning(ctx context.Context, project *uplink.Project, bucketName string, versioning bool) (err error) {
   120  	defer mon.Task()(&ctx)(&err)
   121  
   122  	if bucketName == "" {
   123  		return convertKnownErrors(metaclient.ErrNoBucket.New(""), bucketName, "")
   124  	}
   125  
   126  	metainfoClient, err := dialMetainfoClient(ctx, project)
   127  	if err != nil {
   128  		return convertKnownErrors(err, bucketName, "")
   129  	}
   130  	defer func() { err = errs.Combine(err, metainfoClient.Close()) }()
   131  
   132  	err = metainfoClient.SetBucketVersioning(ctx, metaclient.SetBucketVersioningParams{
   133  		Name:       []byte(bucketName),
   134  		Versioning: versioning,
   135  	})
   136  	return convertKnownErrors(err, bucketName, "")
   137  }
   138  
   139  //go:linkname convertKnownErrors storj.io/uplink.convertKnownErrors
   140  func convertKnownErrors(err error, bucket, key string) error
   141  
   142  //go:linkname dialMetainfoClient storj.io/uplink.dialMetainfoClient
   143  func dialMetainfoClient(ctx context.Context, project *uplink.Project) (_ *metaclient.Client, err error)