]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Zipper - More getRados removal
authorDaniel Gryniewicz <dang@redhat.com>
Fri, 7 Aug 2020 15:17:01 +0000 (11:17 -0400)
committerDaniel Gryniewicz <dang@redhat.com>
Tue, 8 Sep 2020 15:51:28 +0000 (11:51 -0400)
- zonegroup
- obj policy

Signed-off-by: Daniel Gryniewicz <dang@redhat.com>
src/rgw/rgw_op.cc
src/rgw/rgw_sal.h
src/rgw/rgw_sal_rados.cc
src/rgw/rgw_sal_rados.h

index 8116cdc41c8991231fc93a8251a5de6077743705..b2f738d09edbf646f3b51561460051dce831bfd3 100644 (file)
@@ -235,22 +235,21 @@ int rgw_op_get_bucket_policy_from_attr(CephContext *cct,
 }
 
 static int get_obj_policy_from_attr(CephContext *cct,
-                                   rgw::sal::RGWRadosStore *store,
+                                   rgw::sal::RGWStore *store,
                                    RGWObjectCtx& obj_ctx,
                                    RGWBucketInfo& bucket_info,
                                    map<string, bufferlist>& bucket_attrs,
                                    RGWAccessControlPolicy *policy,
                                     string *storage_class,
-                                   rgw_obj& obj,
+                                   rgw::sal::RGWObject* obj,
                                     optional_yield y)
 {
   bufferlist bl;
   int ret = 0;
 
-  RGWRados::Object op_target(store->getRados(), bucket_info, obj_ctx, obj);
-  RGWRados::Object::Read rop(&op_target);
+  std::unique_ptr<rgw::sal::RGWObject::ReadOp> rop = obj->get_read_op(&obj_ctx);
 
-  ret = rop.get_attr(RGW_ATTR_ACL, bl, y);
+  ret = rop->get_attr(RGW_ATTR_ACL, bl, y);
   if (ret >= 0) {
     ret = decode_policy(cct, bl, policy);
     if (ret < 0)
@@ -258,17 +257,17 @@ static int get_obj_policy_from_attr(CephContext *cct,
   } else if (ret == -ENODATA) {
     /* object exists, but policy is broken */
     ldout(cct, 0) << "WARNING: couldn't find acl header for object, generating default" << dendl;
-    rgw::sal::RGWRadosUser user(store, bucket_info.owner);
-    ret = user.load_by_id(y);
+    std::unique_ptr<rgw::sal::RGWUser> user = store->get_user(bucket_info.owner);
+    ret = user->load_by_id(y);
     if (ret < 0)
       return ret;
 
-    policy->create_default(bucket_info.owner, user.get_display_name());
+    policy->create_default(bucket_info.owner, user->get_display_name());
   }
 
   if (storage_class) {
     bufferlist scbl;
-    int r = rop.get_attr(RGW_ATTR_STORAGE_CLASS, scbl, y);
+    int r = rop->get_attr(RGW_ATTR_STORAGE_CLASS, scbl, y);
     if (r >= 0) {
       *storage_class = scbl.to_str();
     } else {
@@ -281,7 +280,6 @@ static int get_obj_policy_from_attr(CephContext *cct,
 
 
 static boost::optional<Policy> get_iam_policy_from_attr(CephContext* cct,
-                                                       rgw::sal::RGWRadosStore* store,
                                                        map<string, bufferlist>& attrs,
                                                        const string& tenant) {
   auto i = attrs.find(RGW_ATTR_IAM_POLICY);
@@ -472,19 +470,20 @@ static int read_bucket_policy(rgw::sal::RGWStore *store,
   return ret;
 }
 
-static int read_obj_policy(rgw::sal::RGWRadosStore *store,
+static int read_obj_policy(rgw::sal::RGWStore *store,
                            struct req_state *s,
                            RGWBucketInfo& bucket_info,
                            map<string, bufferlist>& bucket_attrs,
                            RGWAccessControlPolicy* acl,
                            string *storage_class,
-                           boost::optional<Policy>& policy,
-                           rgw_bucket& bucket,
-                           rgw_obj_key& object,
+                          boost::optional<Policy>& policy,
+                           rgw::sal::RGWBucket* bucket,
+                           rgw::sal::RGWObject* object,
                            bool copy_src=false)
 {
   string upload_id;
   upload_id = s->info.args.get("uploadId");
+  std::unique_ptr<rgw::sal::RGWObject> mpobj;
   rgw_obj obj;
 
   if (!s->system_request && bucket_info.flags & BUCKET_SUSPENDED) {
@@ -497,18 +496,17 @@ static int read_obj_policy(rgw::sal::RGWRadosStore *store,
   // 'copy_src' is used to make this function backward compatible.
   if (!upload_id.empty() && !copy_src) {
     /* multipart upload */
-    RGWMPObj mp(object.name, upload_id);
+    RGWMPObj mp(object->get_name(), upload_id);
     string oid = mp.get_meta();
-    obj.init_ns(bucket, oid, mp_ns);
-    obj.set_in_extra_data(true);
-  } else {
-    obj = rgw_obj(bucket, object);
+    mpobj = bucket->get_object(rgw_obj_key(oid, string(), mp_ns));
+    mpobj->set_in_extra_data(true);
+    object = mpobj.get();
   }
-  policy = get_iam_policy_from_attr(s->cct, store, bucket_attrs, bucket.tenant);
+  policy = get_iam_policy_from_attr(s->cct, bucket_attrs, bucket->get_tenant());
 
   RGWObjectCtx *obj_ctx = static_cast<RGWObjectCtx *>(s->obj_ctx);
   int ret = get_obj_policy_from_attr(s->cct, store, *obj_ctx,
-                                     bucket_info, bucket_attrs, acl, storage_class, obj, s->yield);
+                                     bucket_info, bucket_attrs, acl, storage_class, object, s->yield);
   if (ret == -ENOENT) {
     /* object does not exist checking the bucket's ACL to make sure
        that we send a proper error code */
@@ -521,7 +519,7 @@ static int read_obj_policy(rgw::sal::RGWRadosStore *store,
     if (bucket_owner.compare(s->user->get_id()) != 0 &&
         ! s->auth.identity->is_admin_of(bucket_owner)) {
       if (policy) {
-        auto r =  policy->eval(s->env, *s->auth.identity, rgw::IAM::s3ListBucket, ARN(bucket));
+        auto r =  policy->eval(s->env, *s->auth.identity, rgw::IAM::s3ListBucket, ARN(bucket->get_key()));
         if (r == Effect::Allow)
           return -ENOENT;
         if (r == Effect::Deny)
@@ -575,16 +573,15 @@ int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state*
 
   /* check if copy source is within the current domain */
   if (!s->src_bucket_name.empty()) {
-    RGWBucketInfo source_info;
-
-    if (s->bucket_instance_id.empty()) {
-      ret = store->getRados()->get_bucket_info(store->svc(), s->src_tenant_name, s->src_bucket_name, source_info, NULL, s->yield);
-    } else {
-      ret = store->getRados()->get_bucket_instance_info(obj_ctx, s->bucket_instance_id, source_info, NULL, NULL, s->yield);
+    std::unique_ptr<rgw::sal::RGWBucket> src_bucket;
+    ret = store->get_bucket(nullptr, s->src_tenant_name, s->src_bucket_name, &src_bucket);
+    if (ret == 0) {
+      ret = src_bucket->load_by_name(s->src_tenant_name, s->src_bucket_name,
+                                    s->bucket_instance_id, &obj_ctx, s->yield);
     }
     if (ret == 0) {
-      string& zonegroup = source_info.zonegroup;
-      s->local_source = store->svc()->zone->get_zonegroup().equals(zonegroup);
+      string& zonegroup = src_bucket->get_info().zonegroup;
+      s->local_source = store->get_zonegroup().equals(zonegroup);
     }
   }
 
@@ -625,7 +622,7 @@ int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state*
     s->bucket_owner = s->bucket_acl->get_owner();
 
     RGWZoneGroup zonegroup;
-    int r = store->svc()->zone->get_zonegroup(s->bucket->get_info().zonegroup, zonegroup);
+    int r = store->get_zonegroup(s->bucket->get_info().zonegroup, zonegroup);
     if (!r) {
       if (!zonegroup.endpoints.empty()) {
        s->zonegroup_endpoint = zonegroup.endpoints.front();
@@ -642,14 +639,14 @@ int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state*
       ret = r;
     }
 
-    if (!store->svc()->zone->get_zonegroup().equals(s->bucket->get_info().zonegroup)) {
+    if (!store->get_zonegroup().equals(s->bucket->get_info().zonegroup)) {
       ldpp_dout(s, 0) << "NOTICE: request for data in a different zonegroup ("
           << s->bucket->get_info().zonegroup << " != "
-          << store->svc()->zone->get_zonegroup().get_id() << ")" << dendl;
+          << store->get_zonegroup().get_id() << ")" << dendl;
       /* we now need to make sure that the operation actually requires copy source, that is
        * it's a copy operation
        */
-      if (store->svc()->zone->get_zonegroup().is_master_zonegroup() && s->system_request) {
+      if (store->get_zonegroup().is_master_zonegroup() && s->system_request) {
         /*If this is the master, don't redirect*/
       } else if (s->op_type == RGW_OP_GET_BUCKET_LOCATION ) {
         /* If op is get bucket location, don't redirect */
@@ -718,8 +715,7 @@ int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state*
   }
 
   try {
-    s->iam_policy = get_iam_policy_from_attr(s->cct, store, s->bucket_attrs,
-                                            s->bucket_tenant);
+    s->iam_policy = get_iam_policy_from_attr(s->cct, s->bucket_attrs, s->bucket_tenant);
   } catch (const std::exception& e) {
     // Really this is a can't happen condition. We parse the policy
     // when it's given to us, so perhaps we should abort or otherwise
@@ -760,8 +756,8 @@ int rgw_build_object_policies(rgw::sal::RGWRadosStore *store, struct req_state *
       s->object->set_prefetch_data(s->obj_ctx);
     }
     ret = read_obj_policy(store, s, s->bucket->get_info(), s->bucket_attrs,
-                         s->object_acl.get(), nullptr, s->iam_policy, s->bucket->get_key(),
-                          s->object->get_key());
+                         s->object_acl.get(), nullptr, s->iam_policy, s->bucket.get(),
+                          s->object.get());
   }
 
   return ret;
@@ -1860,8 +1856,7 @@ int RGWGetObj::handle_user_manifest(const char *prefix)
       ldpp_dout(this, 0) << "failed to read bucket policy" << dendl;
       return r;
     }
-    _bucket_policy = get_iam_policy_from_attr(s->cct, store, bucket_attrs,
-                                             s->user->get_tenant());
+    _bucket_policy = get_iam_policy_from_attr(s->cct, bucket_attrs, s->user->get_tenant());
     bucket_policy = &_bucket_policy;
     pbucket = ubucket.get();
   } else {
@@ -1994,7 +1989,7 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl)
           return r;
        }
        auto _bucket_policy = get_iam_policy_from_attr(
-         s->cct, store, tmp_bucket->get_attrs().attrs, tmp_bucket->get_tenant());
+         s->cct, tmp_bucket->get_attrs().attrs, tmp_bucket->get_tenant());
         bucket_policy = _bucket_policy.get_ptr();
        buckets[bucket_name].swap(tmp_bucket);
         policies[bucket_name] = make_pair(bucket_acl, _bucket_policy);
@@ -2372,7 +2367,7 @@ void RGWListBuckets::execute()
     /* We need to have stats for all our policies - even if a given policy
      * isn't actually used in a given account. In such situation its usage
      * stats would be simply full of zeros. */
-    for (const auto& policy : store->svc()->zone->get_zonegroup().placement_targets) {
+    for (const auto& policy : store->get_zonegroup().placement_targets) {
       policies_stats.emplace(policy.second.name,
                              decltype(policies_stats)::mapped_type());
     }
@@ -2515,7 +2510,7 @@ void RGWStatAccount::execute()
       /* We need to have stats for all our policies - even if a given policy
        * isn't actually used in a given account. In such situation its usage
        * stats would be simply full of zeros. */
-      for (const auto& policy : store->svc()->zone->get_zonegroup().placement_targets) {
+      for (const auto& policy : store->get_zonegroup().placement_targets) {
         policies_stats.emplace(policy.second.name,
                                decltype(policies_stats)::mapped_type());
       }
@@ -3107,22 +3102,22 @@ void RGWCreateBucket::execute()
       return;
   }
 
-  if (!relaxed_region_enforcement && !store->svc()->zone->get_zonegroup().is_master_zonegroup() && !location_constraint.empty() &&
-      store->svc()->zone->get_zonegroup().api_name != location_constraint) {
+  if (!relaxed_region_enforcement && !store->get_zonegroup().is_master_zonegroup() && !location_constraint.empty() &&
+      store->get_zonegroup().api_name != location_constraint) {
     ldpp_dout(this, 0) << "location constraint (" << location_constraint << ")"
-                     << " doesn't match zonegroup" << " (" << store->svc()->zone->get_zonegroup().api_name << ")"
+                     << " doesn't match zonegroup" << " (" << store->get_zonegroup().api_name << ")"
                      << dendl;
     op_ret = -ERR_INVALID_LOCATION_CONSTRAINT;
     s->err.message = "The specified location-constraint is not valid";
     return;
   }
 
-  const auto& zonegroup = store->svc()->zone->get_zonegroup();
+  const auto& zonegroup = store->get_zonegroup();
   if (!placement_rule.name.empty() &&
       !zonegroup.placement_targets.count(placement_rule.name)) {
     ldpp_dout(this, 0) << "placement target (" << placement_rule.name << ")"
                      << " doesn't exist in the placement targets of zonegroup"
-                     << " (" << store->svc()->zone->get_zonegroup().api_name << ")" << dendl;
+                     << " (" << store->get_zonegroup().api_name << ")" << dendl;
     op_ret = -ERR_INVALID_LOCATION_CONSTRAINT;
     s->err.message = "The specified placement target does not exist";
     return;
@@ -3148,10 +3143,10 @@ void RGWCreateBucket::execute()
   if (s->system_request) {
     zonegroup_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "zonegroup");
     if (zonegroup_id.empty()) {
-      zonegroup_id = store->svc()->zone->get_zonegroup().get_id();
+      zonegroup_id = store->get_zonegroup().get_id();
     }
   } else {
-    zonegroup_id = store->svc()->zone->get_zonegroup().get_id();
+    zonegroup_id = store->get_zonegroup().get_id();
   }
 
   /* Encode special metadata first as we're using std::map::emplace under
@@ -3504,7 +3499,7 @@ int RGWPutObj::verify_permission()
 
     /* check source object permissions */
     if (read_obj_policy(store, s, copy_source_bucket_info, cs_attrs, &cs_acl, nullptr,
-                       policy, cs_bucket->get_key(), cs_object->get_key(), true) < 0) {
+                       policy, cs_bucket.get(), cs_object.get(), true) < 0) {
       return -EACCES;
     }
 
@@ -5003,7 +4998,7 @@ int RGWCopyObj::verify_permission()
 
     /* check source object permissions */
     op_ret = read_obj_policy(store, s, src_bucket->get_info(), src_bucket->get_attrs().attrs, &src_acl, &src_placement.storage_class,
-                            src_policy, src_bucket->get_key(), src_object->get_key());
+                            src_policy, src_bucket.get(), src_object.get());
     if (op_ret < 0) {
       return op_ret;
     }
@@ -5075,7 +5070,7 @@ int RGWCopyObj::verify_permission()
   if (op_ret < 0) {
     return op_ret;
   }
-  auto dest_iam_policy = get_iam_policy_from_attr(s->cct, store, dest_bucket->get_attrs().attrs, dest_bucket->get_tenant());
+  auto dest_iam_policy = get_iam_policy_from_attr(s->cct, dest_bucket->get_attrs().attrs, dest_bucket->get_tenant());
   /* admin request overrides permission checks */
   if (! s->auth.identity->is_admin_of(dest_policy.get_owner().get_id())){
     if (dest_iam_policy != boost::none) {
@@ -6634,7 +6629,7 @@ bool RGWBulkDelete::Deleter::verify_permission(RGWBucketInfo& binfo,
     return false;
   }
 
-  auto policy = get_iam_policy_from_attr(s->cct, store, battrs, binfo.bucket.tenant);
+  auto policy = get_iam_policy_from_attr(s->cct, battrs, binfo.bucket.tenant);
 
   bucket_owner = bacl.get_owner();
 
@@ -6934,7 +6929,7 @@ int RGWBulkUploadOp::handle_dir(const std::string_view path)
   forward_req_info(s->cct, info, bucket_name);
 
   op_ret = store->create_bucket(*s->user, new_bucket,
-                                store->svc()->zone->get_zonegroup().get_id(),
+                                store->get_zonegroup().get_id(),
                                 placement_rule, swift_ver_location,
                                 pquota_info, attrs,
                                 out_info, ep_objv,
@@ -6995,7 +6990,7 @@ bool RGWBulkUploadOp::handle_file_verify_permission(RGWBucketInfo& binfo,
     return false;
   }
 
-  auto policy = get_iam_policy_from_attr(s->cct, store, battrs, binfo.bucket.tenant);
+  auto policy = get_iam_policy_from_attr(s->cct, battrs, binfo.bucket.tenant);
 
   bucket_owner = bacl.get_owner();
   if (policy || ! s->iam_user_policies.empty()) {
index 6f7ebe0105286e97b62bae93486888f57cccc9ef..e09ddb62fee144d3597c9b62c78565d81c8f1604 100644 (file)
@@ -97,6 +97,8 @@ class RGWStore : public DoutPrefixProvider {
                                  bufferlist& in_data, JSONParser *jp, req_info& info) = 0;
     virtual int defer_gc(RGWObjectCtx *rctx, RGWBucket* bucket, RGWObject* obj,
                         optional_yield y) = 0;
+    virtual const RGWZoneGroup& get_zonegroup() = 0;
+    virtual int get_zonegroup(const string& id, RGWZoneGroup& zonegroup) = 0;
 
     virtual void finalize(void)=0;
 
@@ -299,7 +301,8 @@ class RGWObject {
     uint64_t obj_size;
     RGWAttrs attrs;
     ceph::real_time mtime;
-    bool delete_marker;
+    bool delete_marker{false};
+    bool in_extra_data{false};
 
   public:
 
@@ -328,6 +331,7 @@ class RGWObject {
       virtual int read(int64_t ofs, int64_t end, bufferlist& bl, optional_yield y) = 0;
       virtual int iterate(int64_t ofs, int64_t end, RGWGetDataCB *cb, optional_yield y) = 0;
       virtual int get_manifest(RGWObjManifest **pmanifest, optional_yield y) = 0;
+      virtual int get_attr(const char *name, bufferlist& dest, optional_yield y) = 0;
     };
 
     RGWObject()
@@ -336,24 +340,21 @@ class RGWObject {
       index_hash_source(),
       obj_size(),
       attrs(),
-      mtime(),
-      delete_marker(false) {}
+      mtime() {}
     RGWObject(const rgw_obj_key& _k)
       : key(_k),
       bucket(),
       index_hash_source(),
       obj_size(),
       attrs(),
-      mtime(),
-      delete_marker(false) {}
+      mtime() {}
     RGWObject(const rgw_obj_key& _k, RGWBucket* _b)
       : key(_k),
       bucket(_b),
       index_hash_source(),
       obj_size(),
       attrs(),
-      mtime(),
-      delete_marker(false) {}
+      mtime() {}
     RGWObject(RGWObject& _o) = default;
 
     virtual ~RGWObject() = default;
@@ -404,6 +405,8 @@ class RGWObject {
     void set_hash_source(std::string s) { index_hash_source = s; }
     std::string get_oid(void) const { return key.get_oid(); }
     bool get_delete_marker(void) { return delete_marker; }
+    bool get_in_extra_data(void) { return in_extra_data; }
+    void set_in_extra_data(bool i) { in_extra_data = i; }
     int range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end);
 
     /* OPs */
@@ -421,7 +424,11 @@ class RGWObject {
     void set_obj_size(uint64_t s) { obj_size = s; }
     virtual void set_name(const std::string& n) { key = n; }
     virtual void set_key(const rgw_obj_key& k) { key = k; }
-    virtual rgw_obj get_obj(void) const { return rgw_obj(bucket->get_key(), key); }
+    virtual rgw_obj get_obj(void) const {
+      rgw_obj obj(bucket->get_key(), key);
+      obj.set_in_extra_data(in_extra_data);
+      return obj;
+    }
     virtual void gen_rand_obj_instance_name() = 0;
 
     /* dang - This is temporary, until the API is completed */
index 06028c303b03e4e204dc5091327434a567de93f2..601f03f699e681fed1d532dd2c71275867e5c75a 100644 (file)
@@ -589,6 +589,11 @@ int RGWRadosObject::RadosReadOp::get_manifest(RGWObjManifest **pmanifest,
   return op_target.get_manifest(pmanifest, y);
 }
 
+int RGWRadosObject::RadosReadOp::get_attr(const char *name, bufferlist& dest, optional_yield y)
+{
+  return parent_op.get_attr(name, dest, y);
+}
+
 int RGWRadosObject::delete_object(RGWObjectCtx* obj_ctx, ACLOwner obj_owner, ACLOwner bucket_owner, ceph::real_time unmod_since, bool high_precision_time, uint64_t epoch, string& version_id, optional_yield y)
 {
   int ret = 0;
@@ -799,6 +804,16 @@ int RGWRadosStore::defer_gc(RGWObjectCtx *rctx, RGWBucket* bucket, RGWObject* ob
   return rados->defer_gc(rctx, bucket->get_info(), obj->get_obj(), y);
 }
 
+const RGWZoneGroup& RGWRadosStore::get_zonegroup()
+{
+  return rados->svc.zone->get_zonegroup();
+}
+
+int RGWRadosStore::get_zonegroup(const string& id, RGWZoneGroup& zonegroup)
+{
+  return rados->svc.zone->get_zonegroup(id, zonegroup);
+}
+
 int RGWRadosStore::create_bucket(RGWUser& u, const rgw_bucket& b,
                                 const string& zonegroup_id,
                                 rgw_placement_rule& placement_rule,
index 82eb1c1def0b70ceabef1b6185b04dd4b3229377..c43d4b7b56029552eef12b4e044095fb376a28e6 100644 (file)
@@ -63,6 +63,7 @@ class RGWRadosObject : public RGWObject {
       virtual int read(int64_t ofs, int64_t end, bufferlist& bl, optional_yield y) override;
       virtual int iterate(int64_t ofs, int64_t end, RGWGetDataCB *cb, optional_yield y) override;
       virtual int get_manifest(RGWObjManifest **pmanifest, optional_yield y) override;
+      virtual int get_attr(const char *name, bufferlist& dest, optional_yield y) override;
     };
 
     RGWRadosObject() = default;
@@ -249,6 +250,8 @@ class RGWRadosStore : public RGWStore {
                                  bufferlist& in_data, JSONParser *jp, req_info& info) override;
     virtual int defer_gc(RGWObjectCtx *rctx, RGWBucket* bucket, RGWObject* obj,
                         optional_yield y) override;
+    virtual const RGWZoneGroup& get_zonegroup() override;
+    virtual int get_zonegroup(const string& id, RGWZoneGroup& zonegroup) override;
 
     void setRados(RGWRados * st) { rados = st; }
     RGWRados *getRados(void) { return rados; }