Skip to content

Commit a204f98

Browse files
authored
Merge pull request ceph#60829 from cbodley/wip-69042
radosgw-admin: bucket link/unlink support accounts Reviewed-by: Adam Emerson <[email protected]>
2 parents 5695c38 + 0e73c9d commit a204f98

File tree

4 files changed

+80
-9
lines changed

4 files changed

+80
-9
lines changed

qa/tasks/radosgw_admin.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import time
1717
import datetime
1818
import sys
19+
import errno
1920

2021
from io import StringIO
2122
from queue import Queue
@@ -725,6 +726,40 @@ def task(ctx, config):
725726
(err, out) = rgwadmin(ctx, client, ['user', 'rm', '--tenant', tenant_name, '--uid', 'tenanteduser'],
726727
check_status=True)
727728

729+
account_id = 'RGW12312312312312312'
730+
account_name = 'testacct'
731+
rgwadmin(ctx, client, [
732+
'account', 'create',
733+
'--account-id', account_id,
734+
'--account-name', account_name,
735+
], check_status=True)
736+
rgwadmin(ctx, client, [
737+
'user', 'create',
738+
'--account-id', account_id,
739+
'--uid', 'testacctuser',
740+
'--display-name', 'accountuser',
741+
'--gen-access-key',
742+
'--gen-secret',
743+
], check_status=True)
744+
745+
# TESTCASE 'bucket link', 'bucket', 'account user', 'fails'
746+
(err, out) = rgwadmin(ctx, client, ['bucket', 'link', '--bucket', bucket_name, '--uid', 'testacctuser'])
747+
assert err == errno.EINVAL
748+
749+
rgwadmin(ctx, client, ['user', 'rm', '--uid', 'testacctuser'], check_status=True)
750+
751+
# TESTCASE 'bucket link', 'bucket', 'account', 'succeeds'
752+
rgwadmin(ctx, client,
753+
['bucket', 'link', '--bucket', bucket_name, '--account-id', account_id],
754+
check_status=True)
755+
756+
# relink the bucket to the first user and delete the account
757+
rgwadmin(ctx, client,
758+
['bucket', 'link', '--bucket', bucket_name, '--uid', user1],
759+
check_status=True)
760+
rgwadmin(ctx, client, ['account', 'rm', '--account-id', account_id],
761+
check_status=True)
762+
728763
# TESTCASE 'object-rm', 'object', 'rm', 'remove object', 'succeeds, object is removed'
729764

730765
# upload an object

src/rgw/driver/rados/rgw_bucket.cc

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,16 @@ int RGWBucketAdminOp::dump_s3_policy(rgw::sal::Driver* driver, RGWBucketAdminOpS
11401140

11411141
int RGWBucketAdminOp::unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, string *err)
11421142
{
1143+
rgw_owner owner;
1144+
if (op_state.is_account_op()) {
1145+
owner = op_state.get_account_id();
1146+
} else if (op_state.is_user_op()) {
1147+
owner = op_state.get_user_id();
1148+
} else {
1149+
set_err_msg(err, "requires user or account id");
1150+
return -EINVAL;
1151+
}
1152+
11431153
auto radosdriver = dynamic_cast<rgw::sal::RadosStore*>(driver);
11441154
if (!radosdriver) {
11451155
set_err_msg(err, "rados store only");
@@ -1152,13 +1162,18 @@ int RGWBucketAdminOp::unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op
11521162
return ret;
11531163

11541164
auto* rados = radosdriver->getRados()->get_rados_handle();
1155-
return radosdriver->ctl()->bucket->unlink_bucket(*rados, op_state.get_user_id(), op_state.get_bucket()->get_info().bucket, y, dpp, true);
1165+
return radosdriver->ctl()->bucket->unlink_bucket(*rados, owner, op_state.get_bucket()->get_info().bucket, y, dpp, true);
11561166
}
11571167

11581168
int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, string *err)
11591169
{
1160-
if (!op_state.is_user_op()) {
1161-
set_err_msg(err, "empty user id");
1170+
rgw_owner new_owner;
1171+
if (op_state.is_account_op()) {
1172+
new_owner = op_state.get_account_id();
1173+
} else if (op_state.is_user_op()) {
1174+
new_owner = op_state.get_user_id();
1175+
} else {
1176+
set_err_msg(err, "requires user or account id");
11621177
return -EINVAL;
11631178
}
11641179
auto radosdriver = dynamic_cast<rgw::sal::RadosStore*>(driver);
@@ -1172,8 +1187,26 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s
11721187
if (ret < 0)
11731188
return ret;
11741189

1190+
std::string display_name;
1191+
if (op_state.is_account_op()) {
1192+
RGWAccountInfo info;
1193+
rgw::sal::Attrs attrs;
1194+
RGWObjVersionTracker objv;
1195+
ret = driver->load_account_by_id(dpp, y, op_state.get_account_id(),
1196+
info, attrs, objv);
1197+
if (ret < 0) {
1198+
set_err_msg(err, "failed to load account");
1199+
return ret;
1200+
}
1201+
display_name = std::move(info.name);
1202+
} else if (!bucket.get_user()->get_info().account_id.empty()) {
1203+
set_err_msg(err, "account users cannot own buckets. use --account-id instead");
1204+
return -EINVAL;
1205+
} else {
1206+
display_name = bucket.get_user()->get_display_name();
1207+
}
1208+
11751209
string bucket_id = op_state.get_bucket_id();
1176-
std::string display_name = op_state.get_user_display_name();
11771210
std::unique_ptr<rgw::sal::Bucket> loc_bucket;
11781211
std::unique_ptr<rgw::sal::Bucket> old_bucket;
11791212

@@ -1187,7 +1220,7 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s
11871220

11881221
old_bucket = loc_bucket->clone();
11891222

1190-
loc_bucket->get_key().tenant = op_state.get_user_id().tenant;
1223+
loc_bucket->get_key().tenant = op_state.get_tenant();
11911224

11921225
if (!op_state.new_bucket_name.empty()) {
11931226
auto pos = op_state.new_bucket_name.find('/');
@@ -1236,14 +1269,14 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s
12361269
}
12371270

12381271
RGWAccessControlPolicy policy_instance;
1239-
policy_instance.create_default(op_state.get_user_id(), display_name);
1272+
policy_instance.create_default(new_owner, display_name);
12401273
owner = policy_instance.get_owner();
12411274

12421275
aclbl.clear();
12431276
policy_instance.encode(aclbl);
12441277

12451278
bool exclusive = false;
1246-
loc_bucket->get_info().owner = op_state.get_user_id();
1279+
loc_bucket->get_info().owner = new_owner;
12471280
if (*loc_bucket != *old_bucket) {
12481281
loc_bucket->get_info().bucket = loc_bucket->get_key();
12491282
loc_bucket->get_info().objv_tracker.version_for_read()->ver = 0;
@@ -1259,13 +1292,13 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s
12591292
/* link to user */
12601293
RGWBucketEntryPoint ep;
12611294
ep.bucket = loc_bucket->get_info().bucket;
1262-
ep.owner = op_state.get_user_id();
1295+
ep.owner = new_owner;
12631296
ep.creation_time = loc_bucket->get_info().creation_time;
12641297
ep.linked = true;
12651298
rgw::sal::Attrs ep_attrs;
12661299
rgw_ep_info ep_data{ep, ep_attrs};
12671300

1268-
r = radosdriver->ctl()->bucket->link_bucket(*rados, op_state.get_user_id(), loc_bucket->get_info().bucket, loc_bucket->get_info().creation_time, y, dpp, true, &ep_data);
1301+
r = radosdriver->ctl()->bucket->link_bucket(*rados, new_owner, loc_bucket->get_info().bucket, loc_bucket->get_info().creation_time, y, dpp, true, &ep_data);
12691302
if (r < 0) {
12701303
set_err_msg(err, "failed to relink bucket");
12711304
return r;

src/rgw/driver/rados/rgw_bucket.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ class RGWBucket {
361361
void clear_failure() { failure = false; }
362362

363363
const RGWBucketInfo& get_bucket_info() const { return bucket->get_info(); }
364+
rgw::sal::User* get_user() { return user.get(); }
364365
};
365366

366367
class RGWBucketAdminOp {

src/rgw/driver/rados/rgw_rest_bucket.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ void RGWOp_Bucket_Link::execute(optional_yield y)
141141
RGWBucketAdminOpState op_state;
142142

143143
RESTArgs::get_string(s, "uid", uid_str, &uid_str);
144+
RESTArgs::get_string(s, "account-id", op_state.account_id, &op_state.account_id);
144145
RESTArgs::get_string(s, "bucket", bucket, &bucket);
145146
RESTArgs::get_string(s, "bucket-id", bucket_id, &bucket_id);
146147
RESTArgs::get_string(s, "new-bucket-name", new_bucket_name, &new_bucket_name);
@@ -184,6 +185,7 @@ void RGWOp_Bucket_Unlink::execute(optional_yield y)
184185
RESTArgs::get_string(s, "uid", uid_str, &uid_str);
185186
rgw_user uid(uid_str);
186187

188+
RESTArgs::get_string(s, "account-id", op_state.account_id, &op_state.account_id);
187189
RESTArgs::get_string(s, "bucket", bucket, &bucket);
188190

189191
op_state.set_user_id(uid);

0 commit comments

Comments
 (0)