import time
import datetime
import sys
+import errno
from io import StringIO
from queue import Queue
(err, out) = rgwadmin(ctx, client, ['user', 'rm', '--tenant', tenant_name, '--uid', 'tenanteduser'],
check_status=True)
+ account_id = 'RGW12312312312312312'
+ account_name = 'testacct'
+ rgwadmin(ctx, client, [
+ 'account', 'create',
+ '--account-id', account_id,
+ '--account-name', account_name,
+ ], check_status=True)
+ rgwadmin(ctx, client, [
+ 'user', 'create',
+ '--account-id', account_id,
+ '--uid', 'testacctuser',
+ '--display-name', 'accountuser',
+ '--gen-access-key',
+ '--gen-secret',
+ ], check_status=True)
+
+ # TESTCASE 'bucket link', 'bucket', 'account user', 'fails'
+ (err, out) = rgwadmin(ctx, client, ['bucket', 'link', '--bucket', bucket_name, '--uid', 'testacctuser'])
+ assert err == errno.EINVAL
+
+ rgwadmin(ctx, client, ['user', 'rm', '--uid', 'testacctuser'], check_status=True)
+
+ # TESTCASE 'bucket link', 'bucket', 'account', 'succeeds'
+ rgwadmin(ctx, client,
+ ['bucket', 'link', '--bucket', bucket_name, '--account-id', account_id],
+ check_status=True)
+
+ # relink the bucket to the first user and delete the account
+ rgwadmin(ctx, client,
+ ['bucket', 'link', '--bucket', bucket_name, '--uid', user1],
+ check_status=True)
+ rgwadmin(ctx, client, ['account', 'rm', '--account-id', account_id],
+ check_status=True)
+
# TESTCASE 'object-rm', 'object', 'rm', 'remove object', 'succeeds, object is removed'
# upload an object
int RGWBucketAdminOp::unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, string *err)
{
+ rgw_owner owner;
+ if (op_state.is_account_op()) {
+ owner = op_state.get_account_id();
+ } else if (op_state.is_user_op()) {
+ owner = op_state.get_user_id();
+ } else {
+ set_err_msg(err, "requires user or account id");
+ return -EINVAL;
+ }
+
auto radosdriver = dynamic_cast<rgw::sal::RadosStore*>(driver);
if (!radosdriver) {
set_err_msg(err, "rados store only");
return ret;
auto* rados = radosdriver->getRados()->get_rados_handle();
- return radosdriver->ctl()->bucket->unlink_bucket(*rados, op_state.get_user_id(), op_state.get_bucket()->get_info().bucket, y, dpp, true);
+ return radosdriver->ctl()->bucket->unlink_bucket(*rados, owner, op_state.get_bucket()->get_info().bucket, y, dpp, true);
}
int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, string *err)
{
- if (!op_state.is_user_op()) {
- set_err_msg(err, "empty user id");
+ rgw_owner new_owner;
+ if (op_state.is_account_op()) {
+ new_owner = op_state.get_account_id();
+ } else if (op_state.is_user_op()) {
+ new_owner = op_state.get_user_id();
+ } else {
+ set_err_msg(err, "requires user or account id");
return -EINVAL;
}
auto radosdriver = dynamic_cast<rgw::sal::RadosStore*>(driver);
if (ret < 0)
return ret;
+ std::string display_name;
+ if (op_state.is_account_op()) {
+ RGWAccountInfo info;
+ rgw::sal::Attrs attrs;
+ RGWObjVersionTracker objv;
+ ret = driver->load_account_by_id(dpp, y, op_state.get_account_id(),
+ info, attrs, objv);
+ if (ret < 0) {
+ set_err_msg(err, "failed to load account");
+ return ret;
+ }
+ display_name = std::move(info.name);
+ } else if (!bucket.get_user()->get_info().account_id.empty()) {
+ set_err_msg(err, "account users cannot own buckets. use --account-id instead");
+ return -EINVAL;
+ } else {
+ display_name = bucket.get_user()->get_display_name();
+ }
+
string bucket_id = op_state.get_bucket_id();
- std::string display_name = op_state.get_user_display_name();
std::unique_ptr<rgw::sal::Bucket> loc_bucket;
std::unique_ptr<rgw::sal::Bucket> old_bucket;
old_bucket = loc_bucket->clone();
- loc_bucket->get_key().tenant = op_state.get_user_id().tenant;
+ loc_bucket->get_key().tenant = op_state.get_tenant();
if (!op_state.new_bucket_name.empty()) {
auto pos = op_state.new_bucket_name.find('/');
}
RGWAccessControlPolicy policy_instance;
- policy_instance.create_default(op_state.get_user_id(), display_name);
+ policy_instance.create_default(new_owner, display_name);
owner = policy_instance.get_owner();
aclbl.clear();
policy_instance.encode(aclbl);
bool exclusive = false;
- loc_bucket->get_info().owner = op_state.get_user_id();
+ loc_bucket->get_info().owner = new_owner;
if (*loc_bucket != *old_bucket) {
loc_bucket->get_info().bucket = loc_bucket->get_key();
loc_bucket->get_info().objv_tracker.version_for_read()->ver = 0;
/* link to user */
RGWBucketEntryPoint ep;
ep.bucket = loc_bucket->get_info().bucket;
- ep.owner = op_state.get_user_id();
+ ep.owner = new_owner;
ep.creation_time = loc_bucket->get_info().creation_time;
ep.linked = true;
rgw::sal::Attrs ep_attrs;
rgw_ep_info ep_data{ep, ep_attrs};
- 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);
+ 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);
if (r < 0) {
set_err_msg(err, "failed to relink bucket");
return r;
RGWBucketAdminOpState op_state;
RESTArgs::get_string(s, "uid", uid_str, &uid_str);
+ RESTArgs::get_string(s, "account-id", op_state.account_id, &op_state.account_id);
RESTArgs::get_string(s, "bucket", bucket, &bucket);
RESTArgs::get_string(s, "bucket-id", bucket_id, &bucket_id);
RESTArgs::get_string(s, "new-bucket-name", new_bucket_name, &new_bucket_name);
RESTArgs::get_string(s, "uid", uid_str, &uid_str);
rgw_user uid(uid_str);
+ RESTArgs::get_string(s, "account-id", op_state.account_id, &op_state.account_id);
RESTArgs::get_string(s, "bucket", bucket, &bucket);
op_state.set_user_id(uid);