Repository: ceph/go-ceph
Pull request #1046 (2024-11-26 09:35:26)

rgw/admin: support new-bucket-name for LinkBucket
<!--
Thank you for opening a pull request. Please provide:

- A clear summary of your changes

- Descriptive and succinct commit messages with the format:
  """
  [topic]: [short description]

  [Longer description]

  Signed-off-by: [Your Name] <[your email]>
  """

  Topic will generally be the go ceph package dir you are working in.

- Ensure checklist items listed below are accounted for
-->

Adding the `new-bucket-name` parameter to `BucketLinkInput` which allows renaming a specific bucket.

## Checklist
- [x] Added tests for features and functional changes
- [x] Public functions and types are documented
- [x] Standard formatting is applied to Go code
- [ ] Is this a new API? Added a new file that begins with `//go:build ceph_preview`
- [x] Ran `make api-update` to record new APIs

New or infrequent contributors may want to review the go-ceph [Developer's Guide](https://github.com/ceph/go-ceph/blob/master/docs/development.md) including the section on how we track [API Status](https://github.com/ceph/go-ceph/blob/master/docs/development.md#api-status) and the [API Stability Plan](https://github.com/ceph/go-ceph/blob/master/docs/api-stability.md).

The go-ceph project uses mergify. View the [mergify command guide](https://docs.mergify.com/commands/#commands) for information on how to interact with mergify. Add a comment with `@Mergifyio` `rebase` to rebase your PR when github indicates that the PR is out of date with the base branch.


anoopcs9: > Generally LGTM, but I certainly find the rgw stuff my weakest go-ceph area.

Adding our usual _goto_ as an additional reviewer 😄 

> @anoopcs9 do you want to try and take #1051 first and then retest this one with a "fixed" CI first?

Sure.

anoopcs9: @Mergifyio rebase
mergify[bot]: > rebase

#### ✅ Branch has been successfully rebased



<!---
DO NOT EDIT
-*- Mergify Payload -*-
{"command": "rebase", "conclusion": "success", "action_is_running": true}
-*- Mergify Payload End -*-
-->
mergify[bot]: This pull request has been removed from the queue for the following reason: <code>pull request branch update failed</code>.

The pull request can't be updated

You should look at the reason for the failure and decide if the pull request needs to be fixed or if you want to requeue it.

If you want to requeue this pull request, you need to post a comment with the text: `@mergifyio requeue`

sj14: Is there anything I can help with to get this merged?
anoopcs9: @Mergifyio rebase
mergify[bot]: > rebase

#### ✅ Branch has been successfully rebased



<!---
DO NOT EDIT
-*- Mergify Payload -*-
{"command": "rebase", "conclusion": "success", "action_is_running": true}
-*- Mergify Payload End -*-
-->

Patch:
diff --git a/rgw/admin/link.go b/rgw/admin/link.go
index 7237831..407b4eb 100644
--- a/rgw/admin/link.go
+++ b/rgw/admin/link.go
@@ -7,9 +7,10 @@ import (
 
 // BucketLinkInput the bucket link/unlink input parameters
 type BucketLinkInput struct {
-	Bucket   string `url:"bucket" json:"bucket"`
-	BucketID string `url:"bucket-id" json:"bucket_id"`
-	UID      string `url:"uid" json:"uid"`
+	Bucket        string `url:"bucket" json:"bucket"`
+	BucketID      string `url:"bucket-id" json:"bucket_id"`
+	UID           string `url:"uid" json:"uid"`
+	NewBucketName string `url:"new-bucket-name" json:"new_bucket_name"` // Link operation only; optional; use to rename a bucket. While the tenant-id can be specified, this is not necessary in normal operation.
 }
 
 // UnlinkBucket unlink a bucket from a specified user
@@ -34,7 +35,6 @@ func (api *API) LinkBucket(ctx context.Context, link BucketLinkInput) error {
 	if link.Bucket == "" {
 		return errMissingBucket
 	}
-	//  valid parameters not supported by go-ceph: new-bucket-name
-	_, err := api.call(ctx, http.MethodPut, "/bucket", valueToURLParams(link, []string{"uid", "bucket-id", "bucket"}))
+	_, err := api.call(ctx, http.MethodPut, "/bucket", valueToURLParams(link, []string{"uid", "bucket-id", "bucket", "new-bucket-name"}))
 	return err
 }


Test patch:
diff --git a/rgw/admin/link_test.go b/rgw/admin/link_test.go
index 506ac81..eb10e92 100644
--- a/rgw/admin/link_test.go
+++ b/rgw/admin/link_test.go
@@ -76,4 +76,57 @@ func (suite *RadosGWTestSuite) TestLink() {
 		err := co.RemoveUser(context.Background(), User{ID: "test-user2"})
 		assert.NoError(suite.T(), err)
 	})
+
+}
+
+func (suite *RadosGWTestSuite) TestLinkRename() {
+	suite.SetupConnection()
+	co, err := New(suite.endpoint, suite.accessKey, suite.secretKey, newDebugHTTPClient(http.DefaultClient))
+	assert.NoError(suite.T(), err)
+
+	const (
+		userName          = "test-user-bucket-rename"
+		initialBucketName = "initial-name"
+		renamedBucketName = "renamed-name"
+	)
+
+	suite.T().Run("create test user for bucket rename", func(_ *testing.T) {
+		user, err := co.CreateUser(context.Background(), User{ID: userName, DisplayName: userName, Email: "test-user-bucket-rename@example.com"})
+		assert.NoError(suite.T(), err)
+		assert.Equal(suite.T(), userName, user.ID)
+		assert.Zero(suite.T(), len(user.Caps))
+	})
+
+	suite.T().Run("create test bucket for rename", func(t *testing.T) {
+		s3, err := newS3Agent(suite.accessKey, suite.secretKey, suite.endpoint, true)
+		assert.NoError(t, err)
+
+		err = s3.createBucket(initialBucketName)
+		assert.NoError(t, err)
+	})
+
+	suite.T().Run("rename bucket", func(t *testing.T) {
+		err = co.LinkBucket(context.Background(), BucketLinkInput{
+			UID:           userName,
+			Bucket:        initialBucketName,
+			NewBucketName: renamedBucketName,
+		})
+		assert.NoError(suite.T(), err)
+
+		_, err = co.GetBucketInfo(context.Background(), Bucket{Bucket: initialBucketName})
+		assert.ErrorIs(t, err, ErrNoSuchBucket)
+
+		_, err = co.GetBucketInfo(context.Background(), Bucket{Bucket: renamedBucketName})
+		assert.NoError(t, err)
+	})
+
+	suite.T().Run("remove bucket", func(_ *testing.T) {
+		err := co.RemoveBucket(context.Background(), Bucket{Bucket: renamedBucketName})
+		assert.NoError(suite.T(), err)
+	})
+
+	suite.T().Run("delete test user for bucket rename", func(_ *testing.T) {
+		err := co.RemoveUser(context.Background(), User{ID: userName})
+		assert.NoError(suite.T(), err)
+	})
 }