summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_cr_tools.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/rgw/rgw_cr_tools.cc
parentInitial commit. (diff)
downloadceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz
ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/rgw/rgw_cr_tools.cc')
-rw-r--r--src/rgw/rgw_cr_tools.cc275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/rgw/rgw_cr_tools.cc b/src/rgw/rgw_cr_tools.cc
new file mode 100644
index 00000000..85654cb7
--- /dev/null
+++ b/src/rgw/rgw_cr_tools.cc
@@ -0,0 +1,275 @@
+#include "common/errno.h"
+
+#include "rgw_cr_tools.h"
+#include "rgw_bucket.h"
+#include "rgw_user.h"
+#include "rgw_op.h"
+#include "rgw_acl_s3.h"
+#include "rgw_zone.h"
+
+#define dout_context g_ceph_context
+#define dout_subsys ceph_subsys_rgw
+
+template<>
+int RGWUserCreateCR::Request::_send_request()
+{
+ CephContext *cct = store->ctx();
+
+ const int32_t default_max_buckets =
+ cct->_conf.get_val<int64_t>("rgw_user_max_buckets");
+
+ RGWUserAdminOpState op_state;
+
+ auto& user = params.user;
+
+ op_state.set_user_id(user);
+ op_state.set_display_name(params.display_name);
+ op_state.set_user_email(params.email);
+ op_state.set_caps(params.caps);
+ op_state.set_access_key(params.access_key);
+ op_state.set_secret_key(params.secret_key);
+
+ if (!params.key_type.empty()) {
+ int32_t key_type = KEY_TYPE_S3;
+ if (params.key_type == "swift") {
+ key_type = KEY_TYPE_SWIFT;
+ }
+
+ op_state.set_key_type(key_type);
+ }
+
+ op_state.set_max_buckets(params.max_buckets.value_or(default_max_buckets));
+ op_state.set_suspension(params.suspended);
+ op_state.set_system(params.system);
+ op_state.set_exclusive(params.exclusive);
+
+ if (params.generate_key) {
+ op_state.set_generate_key();
+ }
+
+
+ if (params.apply_quota) {
+ RGWQuotaInfo bucket_quota;
+ RGWQuotaInfo user_quota;
+
+ if (cct->_conf->rgw_bucket_default_quota_max_objects >= 0) {
+ bucket_quota.max_objects = cct->_conf->rgw_bucket_default_quota_max_objects;
+ bucket_quota.enabled = true;
+ }
+
+ if (cct->_conf->rgw_bucket_default_quota_max_size >= 0) {
+ bucket_quota.max_size = cct->_conf->rgw_bucket_default_quota_max_size;
+ bucket_quota.enabled = true;
+ }
+
+ if (cct->_conf->rgw_user_default_quota_max_objects >= 0) {
+ user_quota.max_objects = cct->_conf->rgw_user_default_quota_max_objects;
+ user_quota.enabled = true;
+ }
+
+ if (cct->_conf->rgw_user_default_quota_max_size >= 0) {
+ user_quota.max_size = cct->_conf->rgw_user_default_quota_max_size;
+ user_quota.enabled = true;
+ }
+
+ if (bucket_quota.enabled) {
+ op_state.set_bucket_quota(bucket_quota);
+ }
+
+ if (user_quota.enabled) {
+ op_state.set_user_quota(user_quota);
+ }
+ }
+
+ RGWNullFlusher flusher;
+ return RGWUserAdminOp_User::create(store, op_state, flusher);
+}
+
+template<>
+int RGWGetUserInfoCR::Request::_send_request()
+{
+ return rgw_get_user_info_by_uid(store, params.user, *result);
+}
+
+template<>
+int RGWGetBucketInfoCR::Request::_send_request()
+{
+ RGWSysObjectCtx obj_ctx(store->svc.sysobj->init_obj_ctx());
+ return store->get_bucket_info(obj_ctx, params.tenant, params.bucket_name,
+ result->bucket_info, &result->mtime, &result->attrs);
+}
+
+template<>
+int RGWBucketCreateLocalCR::Request::_send_request()
+{
+ CephContext *cct = store->ctx();
+ auto& zone_svc = store->svc.zone;
+ auto& sysobj_svc = store->svc.sysobj;
+
+ const auto& user_info = params.user_info.get();
+ const auto& user = user_info->user_id;
+ const auto& bucket_name = params.bucket_name;
+ auto& placement_rule = params.placement_rule;
+
+ if (!placement_rule.empty() &&
+ !zone_svc->get_zone_params().valid_placement(placement_rule)) {
+ ldout(cct, 0) << "placement target (" << placement_rule << ")"
+ << " doesn't exist in the placement targets of zonegroup"
+ << " (" << zone_svc->get_zonegroup().api_name << ")" << dendl;
+ return -ERR_INVALID_LOCATION_CONSTRAINT;
+ }
+
+ /* we need to make sure we read bucket info, it's not read before for this
+ * specific request */
+ RGWSysObjectCtx sysobj_ctx(sysobj_svc->init_obj_ctx());
+ RGWBucketInfo bucket_info;
+ map<string, bufferlist> bucket_attrs;
+
+ int ret = store->get_bucket_info(sysobj_ctx, user.tenant, bucket_name,
+ bucket_info, nullptr, &bucket_attrs);
+ if (ret < 0 && ret != -ENOENT)
+ return ret;
+ bool bucket_exists = (ret != -ENOENT);
+
+ RGWAccessControlPolicy old_policy(cct);
+ ACLOwner bucket_owner;
+ bucket_owner.set_id(user);
+ bucket_owner.set_name(user_info->display_name);
+ if (bucket_exists) {
+ ret = rgw_op_get_bucket_policy_from_attr(cct, store, bucket_info,
+ bucket_attrs, &old_policy);
+ if (ret >= 0) {
+ if (old_policy.get_owner().get_id().compare(user) != 0) {
+ return -EEXIST;
+ }
+ }
+ }
+
+ RGWBucketInfo master_info;
+ rgw_bucket *pmaster_bucket = nullptr;
+ uint32_t *pmaster_num_shards = nullptr;
+ real_time creation_time;
+
+ string zonegroup_id = zone_svc->get_zonegroup().get_id();
+
+ if (bucket_exists) {
+ rgw_placement_rule selected_placement_rule;
+ rgw_bucket bucket;
+ bucket.tenant = user.tenant;
+ bucket.name = bucket_name;
+ ret = zone_svc->select_bucket_placement(*user_info, zonegroup_id,
+ placement_rule,
+ &selected_placement_rule, nullptr);
+ if (selected_placement_rule != bucket_info.placement_rule) {
+ ldout(cct, 0) << "bucket already exists on a different placement rule: "
+ << " selected_rule= " << selected_placement_rule
+ << " existing_rule= " << bucket_info.placement_rule << dendl;
+ return -EEXIST;
+ }
+ }
+
+ /* Encode special metadata first as we're using std::map::emplace under
+ * the hood. This method will add the new items only if the map doesn't
+ * contain such keys yet. */
+ RGWAccessControlPolicy_S3 policy(cct);
+ policy.create_canned(bucket_owner, bucket_owner, string()); /* default private policy */
+ bufferlist aclbl;
+ policy.encode(aclbl);
+ map<string, buffer::list> attrs;
+ attrs.emplace(std::move(RGW_ATTR_ACL), std::move(aclbl));
+
+ RGWQuotaInfo quota_info;
+ const RGWQuotaInfo * pquota_info = nullptr;
+
+ rgw_bucket bucket;
+ bucket.tenant = user.tenant;
+ bucket.name = bucket_name;
+
+ RGWBucketInfo info;
+ obj_version ep_objv;
+
+ ret = store->create_bucket(*user_info, bucket, zonegroup_id,
+ placement_rule, bucket_info.swift_ver_location,
+ pquota_info, attrs,
+ info, nullptr, &ep_objv, creation_time,
+ pmaster_bucket, pmaster_num_shards, true);
+
+
+ if (ret && ret != -EEXIST)
+ return ret;
+
+ bool existed = (ret == -EEXIST);
+
+ if (existed) {
+ if (info.owner != user) {
+ ldout(cct, 20) << "NOTICE: bucket already exists under a different user (bucket=" << bucket << " user=" << user << " bucket_owner=" << info.owner << dendl;
+ return -EEXIST;
+ }
+ bucket = info.bucket;
+ }
+
+ ret = rgw_link_bucket(store, user, bucket,
+ info.creation_time, false);
+ if (ret && !existed && ret != -EEXIST) {
+ /* if it exists (or previously existed), don't remove it! */
+ int r = rgw_unlink_bucket(store, user, bucket.tenant, bucket.name);
+ if (r < 0) {
+ ldout(cct, 0) << "WARNING: failed to unlink bucket: ret=" << r << dendl;
+ }
+ } else if (ret == -EEXIST || (ret == 0 && existed)) {
+ ret = -ERR_BUCKET_EXISTS;
+ }
+
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: bucket creation (bucket=" << bucket << ") return ret=" << ret << dendl;
+ }
+
+ return ret;
+}
+
+template<>
+int RGWObjectSimplePutCR::Request::_send_request()
+{
+ RGWDataAccess::ObjectRef obj;
+
+ CephContext *cct = store->ctx();
+
+ int ret = params.bucket->get_object(params.key, &obj);
+ if (ret < 0) {
+ lderr(cct) << "ERROR: failed to get object: " << cpp_strerror(-ret) << dendl;
+ return -ret;
+ }
+
+ if (params.user_data) {
+ obj->set_user_data(*params.user_data);
+ }
+
+ ret = obj->put(params.data, params.attrs);
+ if (ret < 0) {
+ lderr(cct) << "ERROR: put object returned error: " << cpp_strerror(-ret) << dendl;
+ }
+
+ return 0;
+}
+
+template<>
+int RGWBucketLifecycleConfigCR::Request::_send_request()
+{
+ CephContext *cct = store->ctx();
+
+ RGWLC *lc = store->get_lc();
+ if (!lc) {
+ lderr(cct) << "ERROR: lifecycle object is not initialized!" << dendl;
+ return -EIO;
+ }
+
+ int ret = lc->set_bucket_config(params.bucket_info,
+ params.bucket_attrs,
+ &params.config);
+ if (ret < 0) {
+ lderr(cct) << "ERROR: failed to set lifecycle on bucke: " << cpp_strerror(-ret) << dendl;
+ return -ret;
+ }
+
+ return 0;
+}