From 4ef5a9547ef91240e7855e7ae292b72c951024d0 Mon Sep 17 00:00:00 2001 From: Kharitonov Maksim Andreevich Date: Wed, 27 Jul 2022 13:56:09 +0300 Subject: [PATCH] rgw/admin: List user's bucket support --- rgw/admin/user_bucket.go | 69 +++++++++++++++++++++++++++++++++++ rgw/admin/user_bucket_test.go | 66 +++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 rgw/admin/user_bucket.go create mode 100644 rgw/admin/user_bucket_test.go diff --git a/rgw/admin/user_bucket.go b/rgw/admin/user_bucket.go new file mode 100644 index 0000000..db24fc3 --- /dev/null +++ b/rgw/admin/user_bucket.go @@ -0,0 +1,69 @@ +//go:build ceph_preview +// +build ceph_preview + +package admin + +import ( + "context" + "encoding/json" + "fmt" + "net/http" +) + +// BucketListingSpec describes a request +type BucketListingSpec struct { + UID string `url:"uid"` + GenerateStat *bool `url:"stats"` +} + +// ListUsersBuckets will return the list of all users buckets without stat +func (api *API) ListUsersBuckets(ctx context.Context, uid string) ([]string, error) { + if uid == "" { + return nil, errMissingUserID + } + + generateStat := false + listingSpec := BucketListingSpec{ + UID: uid, + GenerateStat: &generateStat, + } + + body, err := api.call(ctx, http.MethodGet, "/bucket", valueToURLParams(listingSpec, []string{"uid", "stats"})) + if err != nil { + return nil, err + } + + var s []string + err = json.Unmarshal(body, &s) + if err != nil { + return nil, fmt.Errorf("%s. %s. %w", unmarshalError, string(body), err) + } + + return s, nil +} + +// ListUsersBucketsWithStat will return the list of all users buckets with stat +func (api *API) ListUsersBucketsWithStat(ctx context.Context, uid string) ([]Bucket, error) { + if uid == "" { + return nil, errMissingUserID + } + + generateStat := true + listingSpec := BucketListingSpec{ + UID: uid, + GenerateStat: &generateStat, + } + + body, err := api.call(ctx, http.MethodGet, "/bucket", valueToURLParams(listingSpec, []string{"uid", "stats"})) + if err != nil { + return nil, err + } + + ref := []Bucket{} + err = json.Unmarshal(body, &ref) + if err != nil { + return nil, fmt.Errorf("%s. %s. %w", unmarshalError, string(body), err) + } + + return ref, nil +} diff --git a/rgw/admin/user_bucket_test.go b/rgw/admin/user_bucket_test.go new file mode 100644 index 0000000..ffae0bb --- /dev/null +++ b/rgw/admin/user_bucket_test.go @@ -0,0 +1,66 @@ +//go:build ceph_preview +// +build ceph_preview + +package admin + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func (suite *RadosGWTestSuite) TestUserBucket() { + suite.SetupConnection() + co, err := New(suite.endpoint, suite.accessKey, suite.secretKey, newDebugHTTPClient(http.DefaultClient)) + assert.NoError(suite.T(), err) + + s3, err := newS3Agent(suite.accessKey, suite.secretKey, suite.endpoint, true) + assert.NoError(suite.T(), err) + + err = s3.createBucket(suite.bucketTestName) + assert.NoError(suite.T(), err) + + suite.T().Run("list empty user's buckets", func(t *testing.T) { + _, err := co.ListUsersBuckets(context.Background(), "") + assert.Error(suite.T(), err) + assert.True(suite.T(), errors.Is(err, errMissingUserID), err) + }) + + suite.T().Run("list user's buckets", func(t *testing.T) { + buckets, err := co.ListUsersBuckets(context.Background(), "admin") + assert.NoError(suite.T(), err) + assert.Equal(suite.T(), 1, len(buckets)) + }) + + suite.T().Run("list unknown user's buckets", func(t *testing.T) { + buckets, err := co.ListUsersBuckets(context.Background(), "foo") + assert.NoError(suite.T(), err) + assert.Equal(suite.T(), 0, len(buckets)) + }) + + suite.T().Run("list empty user's buckets with stat", func(t *testing.T) { + _, err := co.ListUsersBucketsWithStat(context.Background(), "") + assert.Error(suite.T(), err) + assert.True(suite.T(), errors.Is(err, errMissingUserID), err) + }) + + suite.T().Run("list user's buckets with stat", func(t *testing.T) { + buckets, err := co.ListUsersBucketsWithStat(context.Background(), "admin") + assert.NoError(suite.T(), err) + assert.Equal(suite.T(), 1, len(buckets)) + b := buckets[0] + assert.NotNil(suite.T(), b) + assert.Equal(suite.T(), suite.bucketTestName, b.Bucket) + assert.Equal(suite.T(), "admin", b.Owner) + assert.NotNil(suite.T(), b.BucketQuota.MaxSize) + }) + + suite.T().Run("list unknown user's buckets with stat", func(t *testing.T) { + buckets, err := co.ListUsersBucketsWithStat(context.Background(), "foo") + assert.NoError(suite.T(), err) + assert.Equal(suite.T(), 0, len(buckets)) + }) +}