]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: bucket link: Add ability to name bucket w/ different tenant.
authorMarcus Watts <mwatts@redhat.com>
Tue, 21 Aug 2018 22:09:33 +0000 (18:09 -0400)
committerShilpa Jagannath <smanjara@redhat.com>
Tue, 30 Jul 2019 08:30:45 +0000 (14:00 +0530)
This is not a complete fix; but it makes it possible for the
bucket link command to correctly find and attempt to link a bucket
to a user with a different tenant.  The reason this is not a complete
fix is that with just this change, the resulting bucket is "broken";
a duplicate endpoint but 0 length contents is created, and
the info entry is not correctly moved.

Fixes: http://tracker.ceph.com/issues/35885
Signed-off-by: Marcus Watts <mwatts@redhat.com>
src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h
src/rgw/rgw_rest_bucket.cc

index c6db07186ffc45432e4d1481e68b4b8d1ddd9b8b..2f18b5d5a62f279b620867923a66324ed07c205e 100644 (file)
@@ -781,15 +781,20 @@ static void set_err_msg(std::string *sink, std::string msg)
     *sink = msg;
 }
 
-int RGWBucket::init(RGWRados *storage, RGWBucketAdminOpState& op_state)
+int RGWBucket::init(RGWRados *storage, RGWBucketAdminOpState& op_state,
+       std::string *err_msg)
 {
-  if (!storage)
+  std::string bucket_tenant;
+  if (!storage) {
+    set_err_msg(err_msg, "no storage!");
     return -EINVAL;
+  }
 
   store = storage;
 
   rgw_user user_id = op_state.get_user_id();
   tenant = user_id.tenant;
+  bucket_tenant = tenant;
   bucket_name = op_state.get_bucket_name();
   RGWUserBuckets user_buckets;
   auto obj_ctx = store->svc.sysobj->init_obj_ctx();
@@ -797,9 +802,18 @@ int RGWBucket::init(RGWRados *storage, RGWBucketAdminOpState& op_state)
   if (bucket_name.empty() && user_id.empty())
     return -EINVAL;
 
+  // split possible tenant/name
+  auto pos = bucket_name.find('/');
+  if (pos != boost::string_ref::npos) {
+    bucket_tenant = bucket_name.substr(0, pos);
+    bucket_name = bucket_name.substr(pos + 1);
+  }
+
   if (!bucket_name.empty()) {
     int r = store->get_bucket_info(obj_ctx, tenant, bucket_name, bucket_info, NULL, null_yield);
+
     if (r < 0) {
+      set_err_msg(err_msg, "failed to fetch bucket info for bucket=" + bucket_name);
       ldout(store->ctx(), 0) << "could not get bucket info for bucket=" << bucket_name << dendl;
       return r;
     }
@@ -809,8 +823,10 @@ int RGWBucket::init(RGWRados *storage, RGWBucketAdminOpState& op_state)
 
   if (!user_id.empty()) {
     int r = rgw_get_user_info_by_uid(store, user_id, user_info);
-    if (r < 0)
+    if (r < 0) {
+      set_err_msg(err_msg, "failed to fetch user info");
       return r;
+    }
 
     op_state.display_name = user_info.display_name;
   }
@@ -827,13 +843,19 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg)
   }
 
   string bucket_id = op_state.get_bucket_id();
+#if 0
   if (bucket_id.empty()) {
     set_err_msg(err_msg, "empty bucket instance id");
     return -EINVAL;
   }
+#endif
 
   std::string display_name = op_state.get_user_display_name();
   rgw_bucket bucket = op_state.get_bucket();
+  if (!bucket_id.empty() && bucket_id != bucket.bucket_id) {
+    set_err_msg(err_msg, "specified bucket id does not match");
+    return -EINVAL;
+  }
 
   const rgw_pool& root_pool = store->svc.zone->get_zone_params().domain_root;
   std::string bucket_entry;
@@ -847,6 +869,7 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg)
   auto obj_ctx = store->svc.sysobj->init_obj_ctx();
   int r = store->get_bucket_instance_info(obj_ctx, bucket, bucket_info, NULL, &attrs, null_yield);
   if (r < 0) {
+    set_err_msg(err_msg, "failed to refetch bucket info");
     return r;
   }
 
@@ -892,6 +915,7 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg)
               .set_objv_tracker(&objv_tracker)
               .write_attr(RGW_ATTR_ACL, aclbl, null_yield);
     if (r < 0) {
+      set_err_msg(err_msg, "failed to set new acl");
       return r;
     }
 
@@ -907,12 +931,14 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg)
                    .set_objv_tracker(&objv_tracker)
                    .write_attr(RGW_ATTR_ACL, aclbl, null_yield);
     if (r < 0) {
+      set_err_msg(err_msg, "failed to set bucket policy");
       return r;
     }
 
     r = rgw_link_bucket(store, user_info.user_id, bucket_info.bucket,
                         ceph::real_time());
     if (r < 0) {
+      set_err_msg(err_msg, "failed to relink bucket");
       return r;
     }
   }
@@ -1351,7 +1377,7 @@ int RGWBucketAdminOp::link(RGWRados *store, RGWBucketAdminOpState& op_state, str
 {
   RGWBucket bucket;
 
-  int ret = bucket.init(store, op_state);
+  int ret = bucket.init(store, op_state, err);
   if (ret < 0)
     return ret;
 
index 3892a76e70ff3a22fa1edd8a063dd0943bf4020e..086a4b6ebbdec30e9692c69d7cbe62d21b8d1e1d 100644 (file)
@@ -316,7 +316,8 @@ class RGWBucket
 
 public:
   RGWBucket() : store(NULL), handle(NULL), failure(false) {}
-  int init(RGWRados *storage, RGWBucketAdminOpState& op_state);
+  int init(RGWRados *storage, RGWBucketAdminOpState& op_state,
+              std::string *err_msg = NULL);
 
   int check_bad_index_multipart(RGWBucketAdminOpState& op_state,
               RGWFormatterFlusher& flusher, std::string *err_msg = NULL);
index b8a2c75502db43bb6d59a180d4378da999b83e58..165f70126d7643d171d5425faf0004ab7ba04219 100644 (file)
@@ -131,17 +131,20 @@ void RGWOp_Bucket_Link::execute()
   std::string uid_str;
   std::string bucket;
   std::string bucket_id;
+  std::string new_bucket_name;
 
   RGWBucketAdminOpState op_state;
 
   RESTArgs::get_string(s, "uid", uid_str, &uid_str);
   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);
 
   rgw_user uid(uid_str);
   op_state.set_user_id(uid);
   op_state.set_bucket_name(bucket);
   op_state.set_bucket_id(bucket_id);
+  op_state.set_new_bucket_name(new_bucket_name);
 
   http_ret = RGWBucketAdminOp::link(store, op_state);
 }