]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: support setting the account quota of Swift API through POST.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Tue, 10 May 2016 11:31:48 +0000 (13:31 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Mon, 30 May 2016 09:42:56 +0000 (11:42 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_op.cc
src/rgw/rgw_op.h

index 7e44d3ae8231ec25e3e78c6ce777da47c74c7d21..6b2bbba5044487f97941b64afcc2a25dc955af0b 100644 (file)
@@ -1914,8 +1914,11 @@ static void populate_with_generic_attrs(const req_state * const s,
 
 static int filter_out_quota_info(std::map<std::string, bufferlist>& add_attrs,
                                  const std::set<std::string>& rmattr_names,
-                                 RGWQuotaInfo& quota)
+                                 RGWQuotaInfo& quota,
+                                 bool * quota_extracted = nullptr)
 {
+  bool extracted = false;
+
   /* Put new limit on max objects. */
   auto iter = add_attrs.find(RGW_ATTR_QUOTA_NOBJS);
   std::string err;
@@ -1926,6 +1929,7 @@ static int filter_out_quota_info(std::map<std::string, bufferlist>& add_attrs,
       return -EINVAL;
     }
     add_attrs.erase(iter);
+    extracted = true;
   }
 
   /* Put new limit on bucket (container) size. */
@@ -1937,23 +1941,31 @@ static int filter_out_quota_info(std::map<std::string, bufferlist>& add_attrs,
       return -EINVAL;
     }
     add_attrs.erase(iter);
+    extracted = true;
   }
 
   for (const auto& name : rmattr_names) {
     /* Remove limit on max objects. */
     if (name.compare(RGW_ATTR_QUOTA_NOBJS) == 0) {
       quota.max_objects = -1;
+      extracted = true;
     }
 
     /* Remove limit on max bucket size. */
     if (name.compare(RGW_ATTR_QUOTA_MSIZE) == 0) {
       quota.max_size = -1;
+      extracted = true;
     }
   }
 
   /* Swift requries checking on raw usage instead of the 4 KiB rounded one. */
   quota.check_on_raw = true;
   quota.enabled = quota.max_size > 0 || quota.max_objects > 0;
+
+  if (quota_extracted) {
+    *quota_extracted = extracted;
+  }
+
   return 0;
 }
 
@@ -2856,6 +2868,13 @@ int RGWPutMetadataAccount::init_processing()
    * evaluate whether we need FULL_CONTROL or not. */
   filter_out_temp_url(attrs, rmattr_names, temp_url_keys);
 
+  /* The same with quota except a client needs to be reseller admin. */
+  op_ret = filter_out_quota_info(attrs, rmattr_names, new_quota,
+                                 &new_quota_extracted);
+  if (op_ret < 0) {
+    return op_ret;
+  }
+
   return 0;
 }
 
@@ -2874,6 +2893,13 @@ int RGWPutMetadataAccount::verify_permission()
     return -EPERM;
   }
 
+  /* We are failing this intensionally to allow system user/reseller admin
+   * override in rgw_process.cc. This is the way to specify a given RGWOp
+   * expect extra privileges.  */
+  if (new_quota_extracted) {
+    return -EPERM;
+  }
+
   return 0;
 }
 
@@ -2894,6 +2920,11 @@ void RGWPutMetadataAccount::execute()
     }
   }
 
+  /* Handle the quota extracted at the verify_permission step. */
+  if (new_quota_extracted) {
+    new_uinfo.user_quota = std::move(new_quota);
+  }
+
   /* We are passing here the current (old) user info to allow the function
    * optimize-out some operations. */
   op_ret = rgw_store_user_info(store, new_uinfo, s->user,
index abed5a556de64ff5fc38ce063bb81abf43100c66..7bc6f84a21482a1dfeed19eb038662d9cc50971a 100644 (file)
@@ -748,13 +748,17 @@ protected:
   std::set<std::string> rmattr_names;
   std::map<std::string, bufferlist> attrs, orig_attrs;
   std::map<int, std::string> temp_url_keys;
+  RGWQuotaInfo new_quota;
+  bool new_quota_extracted;
 
   RGWObjVersionTracker acct_op_tracker;
 
   RGWAccessControlPolicy policy;
 
 public:
-  RGWPutMetadataAccount() {}
+  RGWPutMetadataAccount()
+    : new_quota_extracted(false) {
+  }
 
   virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
     RGWOp::init(store, s, h);