]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: new utility crs
authorYehuda Sadeh <yehuda@redhat.com>
Fri, 29 Jun 2018 00:23:11 +0000 (17:23 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Tue, 11 Dec 2018 08:10:42 +0000 (00:10 -0800)
 - get user info
 - create bucket

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/rgw_cr_tools.cc
src/rgw/rgw_cr_tools.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h

index ee9b9e1376473ff8ce4a1beac6f5ed6e00a14f07..6176cc4df55f6f8f26825f8b54d50abc7d59ecb8 100644 (file)
@@ -1,5 +1,11 @@
 #include "rgw_cr_tools.h"
+#include "rgw_bucket.h"
 #include "rgw_user.h"
+#include "rgw_op.h"
+#include "rgw_acl_s3.h"
+
+#define dout_context g_ceph_context
+#define dout_subsys ceph_subsys_rgw
 
 template<>
 int RGWUserCreateCR::Request::_send_request()
@@ -77,3 +83,137 @@ int RGWUserCreateCR::Request::_send_request()
   return RGWUserAdminOp_User::create(store, op_state, flusher);
 }
 
+template<>
+int RGWGetUserInfoCR::Request::_send_request()
+{
+  rgw_user user(params.tenant, params.uid);
+  return rgw_get_user_info_by_uid(store, user, result->user_info);
+}
+
+template<>
+int RGWBucketCreateLocalCR::Request::_send_request()
+{
+  CephContext *cct = store->ctx();
+
+  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;
+
+  const auto& zonegroup = store->get_zonegroup();
+
+  if (!placement_rule.empty() &&
+      !zonegroup.placement_targets.count(placement_rule)) {
+    ldout(cct, 0) << "placement target (" << placement_rule << ")"
+      << " doesn't exist in the placement targets of zonegroup"
+      << " (" << store->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 */
+  RGWObjectCtx obj_ctx(store);
+  RGWBucketInfo bucket_info;
+  map<string, bufferlist> bucket_attrs;
+
+  int ret = store->get_bucket_info(obj_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 = store->get_zonegroup().get_id();
+
+  if (bucket_exists) {
+    string selected_placement_rule;
+    rgw_bucket bucket;
+    bucket.tenant = user.tenant;
+    bucket.name = bucket_name;
+    ret = store->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;
+}
index 9cd0b01cf76ffaae79a22299988f1068c8733f83..8ac6626362804976f982b717ad016df1c4ce7fa4 100644 (file)
@@ -25,5 +25,25 @@ struct rgw_user_create_params {
 using RGWUserCreateCR = RGWSimpleWriteOnlyAsyncCR<rgw_user_create_params>;
 
 
+struct rgw_get_user_info_params {
+  std::string uid;
+  std::string tenant;
+};
+
+struct rgw_get_user_info_result {
+  RGWUserInfo user_info;
+};
+
+using RGWGetUserInfoCR = RGWSimpleAsyncCR<rgw_get_user_info_params, rgw_get_user_info_result>;
+
+struct rgw_bucket_create_local_params {
+  shared_ptr<RGWUserInfo> user_info;
+  std::string bucket_name;
+  std::string placement_rule;
+};
+
+using RGWBucketCreateLocalCR = RGWSimpleWriteOnlyAsyncCR<rgw_bucket_create_local_params>;
+
+
 
 #endif
index 2f8044981fbae97ef76f307851a47e5296215873..f17be228b803683436c7167d45d0a4ce1cf3f023 100644 (file)
@@ -267,11 +267,11 @@ static int get_obj_policy_from_attr(CephContext *cct,
  * object: name of the object to get the ACL for.
  * Returns: 0 on success, -ERR# otherwise.
  */
-static int get_bucket_policy_from_attr(CephContext *cct,
-                                      RGWRados *store,
-                                      RGWBucketInfo& bucket_info,
-                                      map<string, bufferlist>& bucket_attrs,
-                                      RGWAccessControlPolicy *policy)
+int rgw_op_get_bucket_policy_from_attr(CephContext *cct,
+                                       RGWRados *store,
+                                       RGWBucketInfo& bucket_info,
+                                       map<string, bufferlist>& bucket_attrs,
+                                       RGWAccessControlPolicy *policy)
 {
   return get_bucket_instance_policy_from_attr(cct, store, bucket_info, bucket_attrs, policy);
 }
@@ -350,7 +350,7 @@ static int read_bucket_policy(RGWRados *store,
     return 0;
   }
 
-  int ret = get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, policy);
+  int ret = rgw_op_get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, policy);
   if (ret == -ENOENT) {
       ret = -ERR_NO_SUCH_BUCKET;
   }
@@ -395,7 +395,7 @@ static int read_obj_policy(RGWRados *store,
     /* object does not exist checking the bucket's ACL to make sure
        that we send a proper error code */
     RGWAccessControlPolicy bucket_policy(s->cct);
-    ret = get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, &bucket_policy);
+    ret = rgw_op_get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, &bucket_policy);
     if (ret < 0) {
       return ret;
     }
@@ -2831,8 +2831,8 @@ void RGWCreateBucket::execute()
   s->bucket_owner.set_id(s->user->user_id);
   s->bucket_owner.set_name(s->user->display_name);
   if (s->bucket_exists) {
-    int r = get_bucket_policy_from_attr(s->cct, store, s->bucket_info,
-                                        s->bucket_attrs, &old_policy);
+    int r = rgw_op_get_bucket_policy_from_attr(s->cct, store, s->bucket_info,
+                                               s->bucket_attrs, &old_policy);
     if (r >= 0)  {
       if (old_policy.get_owner().get_id().compare(s->user->user_id) != 0) {
         op_ret = -EEXIST;
@@ -6362,8 +6362,8 @@ int RGWBulkUploadOp::handle_dir(const boost::string_ref path)
 
   if (bucket_exists) {
     RGWAccessControlPolicy old_policy(s->cct);
-    int r = get_bucket_policy_from_attr(s->cct, store, binfo,
-                                        battrs, &old_policy);
+    int r = rgw_op_get_bucket_policy_from_attr(s->cct, store, binfo,
+                                               battrs, &old_policy);
     if (r >= 0)  {
       if (old_policy.get_owner().get_id().compare(s->user->user_id) != 0) {
         op_ret = -EEXIST;
index e7f4225de1324e973949e18af37519e3d04a6175..dec114b90de4299efc282ea75617d652ac11fd97 100644 (file)
@@ -65,6 +65,11 @@ class StrategyRegistry;
 }
 }
 
+int rgw_op_get_bucket_policy_from_attr(CephContext *cct,
+                                       RGWRados *store,
+                                       RGWBucketInfo& bucket_info,
+                                       map<string, bufferlist>& bucket_attrs,
+                                       RGWAccessControlPolicy *policy);
 
 class RGWHandler {
 protected: