From: Seena Fallah Date: Wed, 8 Jan 2025 22:27:31 +0000 (+0100) Subject: rgw: call RGWBucketAdminOp::remove_bucket by RGWOp_Bucket_Remove X-Git-Tag: v19.2.3~139^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e2a2aba08832709ae82f247c631b3af0b917c012;p=ceph.git rgw: call RGWBucketAdminOp::remove_bucket by RGWOp_Bucket_Remove To align same functionality for bucket deletion from both API and rgw-admin, use the same function from RGWBucketAdminOp. Signed-off-by: Seena Fallah (cherry picked from commit 9ae2d8c4e95807179fc17f84be6754d2b19fe639) --- diff --git a/doc/radosgw/adminops.rst b/doc/radosgw/adminops.rst index 643190123d3..4b6ba3ec34d 100644 --- a/doc/radosgw/adminops.rst +++ b/doc/radosgw/adminops.rst @@ -1484,6 +1484,13 @@ Request Parameters :Example: ``foo_bucket`` :Required: Yes +``tenant`` + +:Description: The tenant under which the bucket is to be removed. +:Type: String +:Example: ``tenant1`` +:Required: No + ``purge-objects`` :Description: Remove a buckets objects before deletion. @@ -1491,6 +1498,13 @@ Request Parameters :Example: True [False] :Required: No +``bypass-gc`` + +:Description: Bypass garbage collection. +:Type: Boolean +:Example: True [False] +:Required: No + Response Entities ~~~~~~~~~~~~~~~~~ diff --git a/src/rgw/driver/rados/rgw_bucket.cc b/src/rgw/driver/rados/rgw_bucket.cc index a884cefe442..ab78f76c24d 100644 --- a/src/rgw/driver/rados/rgw_bucket.cc +++ b/src/rgw/driver/rados/rgw_bucket.cc @@ -1280,7 +1280,7 @@ int RGWBucketAdminOp::check_index(rgw::sal::Driver* driver, RGWBucketAdminOpStat int RGWBucketAdminOp::remove_bucket(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, optional_yield y, const DoutPrefixProvider *dpp, - bool bypass_gc, bool keep_index_consistent) + bool bypass_gc, bool keep_index_consistent, bool forwarded_request) { std::unique_ptr bucket; @@ -1290,6 +1290,14 @@ int RGWBucketAdminOp::remove_bucket(rgw::sal::Driver* driver, RGWBucketAdminOpSt if (ret < 0) return ret; + // check if the bucket is owned by my zonegroup, if not, refuse to remove it + if (!forwarded_request && bucket->get_info().zonegroup != driver->get_zone()->get_zonegroup().get_id()) { + ldpp_dout(dpp, 0) << "ERROR: The bucket's zonegroup does not match. " + << "Removal is not allowed. Please execute this operation " + << "on the bucket's zonegroup: " << bucket->get_info().zonegroup << dendl; + return -ERR_PERMANENT_REDIRECT; + } + if (bypass_gc) ret = bucket->remove_bypass_gc(op_state.get_max_aio(), keep_index_consistent, y, dpp); else diff --git a/src/rgw/driver/rados/rgw_bucket.h b/src/rgw/driver/rados/rgw_bucket.h index edbb5856aea..95eb8404c4b 100644 --- a/src/rgw/driver/rados/rgw_bucket.h +++ b/src/rgw/driver/rados/rgw_bucket.h @@ -398,7 +398,7 @@ public: RGWFormatterFlusher& flusher, const DoutPrefixProvider *dpp); static int remove_bucket(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, optional_yield y, - const DoutPrefixProvider *dpp, bool bypass_gc = false, bool keep_index_consistent = true); + const DoutPrefixProvider *dpp, bool bypass_gc = false, bool keep_index_consistent = true, bool forwarded_request = false); static int remove_object(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y); static int info(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, RGWFormatterFlusher& flusher, optional_yield y, const DoutPrefixProvider *dpp); static int limit_check(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, diff --git a/src/rgw/driver/rados/rgw_rest_bucket.cc b/src/rgw/driver/rados/rgw_rest_bucket.cc index 0c3f7029604..bdbafe2d1eb 100644 --- a/src/rgw/driver/rados/rgw_rest_bucket.cc +++ b/src/rgw/driver/rados/rgw_rest_bucket.cc @@ -216,36 +216,24 @@ public: void RGWOp_Bucket_Remove::execute(optional_yield y) { - std::string bucket_name; - bool delete_children; - std::unique_ptr bucket; + std::string bucket_name, tenant; + bool delete_children, bypass_gc; RESTArgs::get_string(s, "bucket", bucket_name, &bucket_name); + RESTArgs::get_string(s, "tenant", tenant, &tenant); RESTArgs::get_bool(s, "purge-objects", false, &delete_children); + RESTArgs::get_bool(s, "bypass-gc", false, &bypass_gc); - op_ret = rgw_forward_request_to_master(this, *s->penv.site, s->user->get_id(), - nullptr, nullptr, s->info, y); - if (op_ret < 0) { - ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl; - if (op_ret == -ENOENT) { - /* adjust error, we want to return with NoSuchBucket and not - * NoSuchKey */ - op_ret = -ERR_NO_SUCH_BUCKET; - } - return; - } + RGWBucketAdminOpState op_state; + op_state.set_bucket_name(bucket_name); + op_state.set_tenant(tenant); + op_state.set_delete_children(delete_children); - op_ret = driver->load_bucket(s, rgw_bucket("", bucket_name), - &bucket, y); - if (op_ret < 0) { - ldpp_dout(this, 0) << "get_bucket returned ret=" << op_ret << dendl; - if (op_ret == -ENOENT) { - op_ret = -ERR_NO_SUCH_BUCKET; - } - return; - } + // Check if the request is being forwarded by looking for the "rgwx-zonegroup" argument + // As this is an admin endpoint, checking by system_request is not sufficient + const bool is_forwarded = s->info.args.exists(RGW_SYS_PARAM_PREFIX "zonegroup"); - op_ret = bucket->remove(s, delete_children, s->yield); + op_ret = RGWBucketAdminOp::remove_bucket(driver, *s->penv.site, op_state, y, s, bypass_gc, true, is_forwarded); } class RGWOp_Set_Bucket_Quota : public RGWRESTOp { diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index da4f5b5a609..5c2f9f43d9d 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -8755,14 +8755,14 @@ next: if (opt_cmd == OPT::BUCKET_RM) { if (!inconsistent_index) { - RGWBucketAdminOp::remove_bucket(driver, bucket_op, null_yield, dpp(), bypass_gc, true); + RGWBucketAdminOp::remove_bucket(driver, bucket_op, null_yield, dpp(), bypass_gc, true, false); } else { if (!yes_i_really_mean_it) { cerr << "using --inconsistent_index can corrupt the bucket index " << std::endl << "do you really mean it? (requires --yes-i-really-mean-it)" << std::endl; return 1; } - RGWBucketAdminOp::remove_bucket(driver, bucket_op, null_yield, dpp(), bypass_gc, false); + RGWBucketAdminOp::remove_bucket(driver, bucket_op, null_yield, dpp(), bypass_gc, false, false); } }