1
0
mirror of https://github.com/ceph/ceph synced 2024-12-25 04:43:17 +00:00

rgw: Admin API Support for bucket quota change

Allow admin to change the quota of a individual bucket through Admin API

Fixes: http://tracker.ceph.com/issues/21811
Signed-off-by: Jeegn Chen <jeegnchen@gmail.com>
This commit is contained in:
Jeegn Chen 2017-10-16 17:46:39 +08:00
parent 6b72f45613
commit b2893d1710
3 changed files with 89 additions and 0 deletions

View File

@ -917,6 +917,27 @@ int RGWBucket::unlink(RGWBucketAdminOpState& op_state, std::string *err_msg)
return r;
}
int RGWBucket::set_quota(RGWBucketAdminOpState& op_state, std::string *err_msg)
{
rgw_bucket bucket = op_state.get_bucket();
RGWBucketInfo bucket_info;
map<string, bufferlist> attrs;
RGWObjectCtx obj_ctx(store);
int r = store->get_bucket_info(obj_ctx, bucket.tenant, bucket.name, bucket_info, NULL, &attrs);
if (r < 0) {
set_err_msg(err_msg, "could not get bucket info for bucket=" + bucket.name + ": " + cpp_strerror(-r));
return r;
}
bucket_info.quota = op_state.quota;
r = store->put_bucket_instance_info(bucket_info, false, real_time(), &attrs);
if (r < 0) {
set_err_msg(err_msg, "ERROR: failed writing bucket instance info: " + cpp_strerror(-r));
return r;
}
return r;
}
int RGWBucket::remove(RGWBucketAdminOpState& op_state, bool bypass_gc,
bool keep_index_consistent, std::string *err_msg)
{
@ -1619,6 +1640,15 @@ int RGWBucketAdminOp::info(RGWRados *store, RGWBucketAdminOpState& op_state,
return 0;
}
int RGWBucketAdminOp::set_quota(RGWRados *store, RGWBucketAdminOpState& op_state)
{
RGWBucket bucket;
int ret = bucket.init(store, op_state);
if (ret < 0)
return ret;
return bucket.set_quota(op_state);
}
void rgw_data_change::dump(Formatter *f) const
{

View File

@ -213,6 +213,8 @@ struct RGWBucketAdminOpState {
rgw_bucket bucket;
RGWQuotaInfo quota;
void set_fetch_stats(bool value) { stat_buckets = value; }
void set_check_objects(bool value) { check_objects = value; }
void set_fix_index(bool value) { fix_index = value; }
@ -231,6 +233,10 @@ struct RGWBucketAdminOpState {
void set_object(std::string& object_str) {
object_name = object_str;
}
void set_quota(RGWQuotaInfo& value) {
quota = value;
}
rgw_user& get_user_id() { return uid; }
std::string& get_user_display_name() { return display_name; }
@ -300,6 +306,7 @@ public:
int remove(RGWBucketAdminOpState& op_state, bool bypass_gc = false, bool keep_index_consistent = true, std::string *err_msg = NULL);
int link(RGWBucketAdminOpState& op_state, std::string *err_msg = NULL);
int unlink(RGWBucketAdminOpState& op_state, std::string *err_msg = NULL);
int set_quota(RGWBucketAdminOpState& op_state, std::string *err_msg = NULL);
int remove_object(RGWBucketAdminOpState& op_state, std::string *err_msg = NULL);
int policy_bl_to_stream(bufferlist& bl, ostream& o);
@ -331,6 +338,7 @@ public:
const std::list<std::string>& user_ids,
RGWFormatterFlusher& flusher,
bool warnings_only = false);
static int set_quota(RGWRados *store, RGWBucketAdminOpState& op_state);
};

View File

@ -206,6 +206,55 @@ void RGWOp_Bucket_Remove::execute()
http_ret = RGWBucketAdminOp::remove_bucket(store, op_state);
}
class RGWOp_Set_Bucket_Quota : public RGWRESTOp {
public:
RGWOp_Set_Bucket_Quota() {}
int check_caps(RGWUserCaps& caps) {
return caps.check_cap("buckets", RGW_CAP_WRITE);
}
void execute();
virtual const string name() { return "set_bucket_quota"; }
};
#define QUOTA_INPUT_MAX_LEN 1024
void RGWOp_Set_Bucket_Quota::execute()
{
bool uid_arg_existed = false;
std::string uid_str;
RESTArgs::get_string(s, "uid", uid_str, &uid_str, &uid_arg_existed);
if (! uid_arg_existed) {
http_ret = -EINVAL;
return;
}
rgw_user uid(uid_str);
bool bucket_arg_existed = false;
std::string bucket;
RESTArgs::get_string(s, "bucket", bucket, &bucket, &bucket_arg_existed);
if (! bucket_arg_existed) {
http_ret = -EINVAL;
return;
}
RGWQuotaInfo quota;
bool empty;
http_ret = rgw_rest_get_json_input(store->ctx(), s, quota, QUOTA_INPUT_MAX_LEN, &empty);
if (http_ret < 0) {
ldout(store->ctx(), 20) << "failed to retrieve input" << dendl;
return;
}
RGWBucketAdminOpState op_state;
op_state.set_user_id(uid);
op_state.set_bucket_name(bucket);
op_state.set_quota(quota);
http_ret = RGWBucketAdminOp::set_quota(store, op_state);
}
class RGWOp_Object_Remove: public RGWRESTOp {
public:
@ -250,6 +299,8 @@ RGWOp *RGWHandler_Bucket::op_get()
RGWOp *RGWHandler_Bucket::op_put()
{
if (s->info.args.sub_resource_exists("quota"))
return new RGWOp_Set_Bucket_Quota;
return new RGWOp_Bucket_Link;
}