1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
5 #include "rgw_bucket.h"
6 #include "rgw_rest_bucket.h"
8 #include "include/str_list.h"
10 #include "services/svc_sys_obj.h"
11 #include "services/svc_zone.h"
13 #define dout_subsys ceph_subsys_rgw
16 class RGWOp_Bucket_Info
: public RGWRESTOp
{
19 RGWOp_Bucket_Info() {}
21 int check_caps(const RGWUserCaps
& caps
) override
{
22 return caps
.check_cap("buckets", RGW_CAP_READ
);
25 void execute() override
;
27 const char* name() const override
{ return "get_bucket_info"; }
30 void RGWOp_Bucket_Info::execute()
32 RGWBucketAdminOpState op_state
;
40 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
41 rgw_user
uid(uid_str
);
43 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
);
44 RESTArgs::get_bool(s
, "stats", false, &fetch_stats
);
46 op_state
.set_user_id(uid
);
47 op_state
.set_bucket_name(bucket
);
48 op_state
.set_fetch_stats(fetch_stats
);
50 http_ret
= RGWBucketAdminOp::info(store
, op_state
, flusher
);
53 class RGWOp_Get_Policy
: public RGWRESTOp
{
58 int check_caps(const RGWUserCaps
& caps
) override
{
59 return caps
.check_cap("buckets", RGW_CAP_READ
);
62 void execute() override
;
64 const char* name() const override
{ return "get_policy"; }
67 void RGWOp_Get_Policy::execute()
69 RGWBucketAdminOpState op_state
;
74 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
);
75 RESTArgs::get_string(s
, "object", object
, &object
);
77 op_state
.set_bucket_name(bucket
);
78 op_state
.set_object(object
);
80 http_ret
= RGWBucketAdminOp::get_policy(store
, op_state
, flusher
);
83 class RGWOp_Check_Bucket_Index
: public RGWRESTOp
{
86 RGWOp_Check_Bucket_Index() {}
88 int check_caps(const RGWUserCaps
& caps
) override
{
89 return caps
.check_cap("buckets", RGW_CAP_WRITE
);
92 void execute() override
;
94 const char* name() const override
{ return "check_bucket_index"; }
97 void RGWOp_Check_Bucket_Index::execute()
104 RGWBucketAdminOpState op_state
;
106 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
);
107 RESTArgs::get_bool(s
, "fix", false, &fix_index
);
108 RESTArgs::get_bool(s
, "check-objects", false, &check_objects
);
110 op_state
.set_bucket_name(bucket
);
111 op_state
.set_fix_index(fix_index
);
112 op_state
.set_check_objects(check_objects
);
114 http_ret
= RGWBucketAdminOp::check_index(store
, op_state
, flusher
, s
->yield
);
117 class RGWOp_Bucket_Link
: public RGWRESTOp
{
120 RGWOp_Bucket_Link() {}
122 int check_caps(const RGWUserCaps
& caps
) override
{
123 return caps
.check_cap("buckets", RGW_CAP_WRITE
);
126 void execute() override
;
128 const char* name() const override
{ return "link_bucket"; }
131 void RGWOp_Bucket_Link::execute()
135 std::string bucket_id
;
136 std::string new_bucket_name
;
138 RGWBucketAdminOpState op_state
;
140 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
141 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
);
142 RESTArgs::get_string(s
, "bucket-id", bucket_id
, &bucket_id
);
143 RESTArgs::get_string(s
, "new-bucket-name", new_bucket_name
, &new_bucket_name
);
145 rgw_user
uid(uid_str
);
146 op_state
.set_user_id(uid
);
147 op_state
.set_bucket_name(bucket
);
148 op_state
.set_bucket_id(bucket_id
);
149 op_state
.set_new_bucket_name(new_bucket_name
);
151 if (!store
->svc()->zone
->is_meta_master()) {
153 op_ret
= forward_request_to_master(s
, nullptr, store
, data
, nullptr);
155 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
159 http_ret
= RGWBucketAdminOp::link(store
, op_state
);
162 class RGWOp_Bucket_Unlink
: public RGWRESTOp
{
165 RGWOp_Bucket_Unlink() {}
167 int check_caps(const RGWUserCaps
& caps
) override
{
168 return caps
.check_cap("buckets", RGW_CAP_WRITE
);
171 void execute() override
;
173 const char* name() const override
{ return "unlink_bucket"; }
176 void RGWOp_Bucket_Unlink::execute()
181 RGWBucketAdminOpState op_state
;
183 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
184 rgw_user
uid(uid_str
);
186 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
);
188 op_state
.set_user_id(uid
);
189 op_state
.set_bucket_name(bucket
);
191 if (!store
->svc()->zone
->is_meta_master()) {
193 op_ret
= forward_request_to_master(s
, nullptr, store
, data
, nullptr);
195 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
199 http_ret
= RGWBucketAdminOp::unlink(store
, op_state
);
202 class RGWOp_Bucket_Remove
: public RGWRESTOp
{
205 RGWOp_Bucket_Remove() {}
207 int check_caps(const RGWUserCaps
& caps
) override
{
208 return caps
.check_cap("buckets", RGW_CAP_WRITE
);
211 void execute() override
;
213 const char* name() const override
{ return "remove_bucket"; }
216 void RGWOp_Bucket_Remove::execute()
219 bool delete_children
;
221 RGWBucketAdminOpState op_state
;
223 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
);
224 RESTArgs::get_bool(s
, "purge-objects", false, &delete_children
);
226 op_state
.set_bucket_name(bucket
);
227 op_state
.set_delete_children(delete_children
);
229 if (!store
->svc()->zone
->is_meta_master()) {
231 op_ret
= forward_request_to_master(s
, nullptr, store
, data
, nullptr);
233 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
237 http_ret
= RGWBucketAdminOp::remove_bucket(store
, op_state
, s
->yield
);
240 class RGWOp_Set_Bucket_Quota
: public RGWRESTOp
{
243 RGWOp_Set_Bucket_Quota() {}
245 int check_caps(const RGWUserCaps
& caps
) override
{
246 return caps
.check_cap("buckets", RGW_CAP_WRITE
);
249 void execute() override
;
251 const char* name() const override
{ return "set_bucket_quota"; }
254 #define QUOTA_INPUT_MAX_LEN 1024
256 void RGWOp_Set_Bucket_Quota::execute()
258 bool uid_arg_existed
= false;
260 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
, &uid_arg_existed
);
261 if (! uid_arg_existed
) {
265 rgw_user
uid(uid_str
);
266 bool bucket_arg_existed
= false;
268 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
, &bucket_arg_existed
);
269 if (! bucket_arg_existed
) {
274 bool use_http_params
;
276 if (s
->content_length
> 0) {
277 use_http_params
= false;
279 const char *encoding
= s
->info
.env
->get("HTTP_TRANSFER_ENCODING");
280 use_http_params
= (!encoding
|| strcmp(encoding
, "chunked") != 0);
283 if (!use_http_params
) {
285 http_ret
= rgw_rest_get_json_input(store
->ctx(), s
, quota
, QUOTA_INPUT_MAX_LEN
, &empty
);
289 /* was probably chunked input, but no content provided, configure via http params */
290 use_http_params
= true;
293 if (use_http_params
) {
294 RGWBucketInfo bucket_info
;
295 map
<string
, bufferlist
> attrs
;
296 http_ret
= store
->getRados()->get_bucket_info(store
->svc(), uid
.tenant
, bucket
, bucket_info
, NULL
, s
->yield
, &attrs
);
300 RGWQuotaInfo
*old_quota
= &bucket_info
.quota
;
301 int64_t old_max_size_kb
= rgw_rounded_kb(old_quota
->max_size
);
303 RESTArgs::get_int64(s
, "max-objects", old_quota
->max_objects
, "a
.max_objects
);
304 RESTArgs::get_int64(s
, "max-size-kb", old_max_size_kb
, &max_size_kb
);
305 quota
.max_size
= max_size_kb
* 1024;
306 RESTArgs::get_bool(s
, "enabled", old_quota
->enabled
, "a
.enabled
);
309 RGWBucketAdminOpState op_state
;
310 op_state
.set_user_id(uid
);
311 op_state
.set_bucket_name(bucket
);
312 op_state
.set_quota(quota
);
314 http_ret
= RGWBucketAdminOp::set_quota(store
, op_state
);
317 class RGWOp_Sync_Bucket
: public RGWRESTOp
{
320 RGWOp_Sync_Bucket() {}
322 int check_caps(const RGWUserCaps
& caps
) override
{
323 return caps
.check_cap("buckets", RGW_CAP_WRITE
);
326 void execute() override
;
328 const char* name() const override
{ return "sync_bucket"; }
331 void RGWOp_Sync_Bucket::execute()
337 RGWBucketAdminOpState op_state
;
338 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
);
339 RESTArgs::get_string(s
, "tenant", tenant
, &tenant
);
340 RESTArgs::get_bool(s
, "sync", true, &sync_bucket
);
342 op_state
.set_bucket_name(bucket
);
343 op_state
.set_tenant(tenant
);
344 op_state
.set_sync_bucket(sync_bucket
);
346 http_ret
= RGWBucketAdminOp::sync_bucket(store
, op_state
);
349 class RGWOp_Object_Remove
: public RGWRESTOp
{
352 RGWOp_Object_Remove() {}
354 int check_caps(const RGWUserCaps
& caps
) override
{
355 return caps
.check_cap("buckets", RGW_CAP_WRITE
);
358 void execute() override
;
360 const char* name() const override
{ return "remove_object"; }
363 void RGWOp_Object_Remove::execute()
368 RGWBucketAdminOpState op_state
;
370 RESTArgs::get_string(s
, "bucket", bucket
, &bucket
);
371 RESTArgs::get_string(s
, "object", object
, &object
);
373 op_state
.set_bucket_name(bucket
);
374 op_state
.set_object(object
);
376 http_ret
= RGWBucketAdminOp::remove_object(store
, op_state
);
380 RGWOp
*RGWHandler_Bucket::op_get()
383 if (s
->info
.args
.sub_resource_exists("policy"))
384 return new RGWOp_Get_Policy
;
386 if (s
->info
.args
.sub_resource_exists("index"))
387 return new RGWOp_Check_Bucket_Index
;
389 return new RGWOp_Bucket_Info
;
392 RGWOp
*RGWHandler_Bucket::op_put()
394 if (s
->info
.args
.sub_resource_exists("quota"))
395 return new RGWOp_Set_Bucket_Quota
;
397 if (s
->info
.args
.sub_resource_exists("sync"))
398 return new RGWOp_Sync_Bucket
;
400 return new RGWOp_Bucket_Link
;
403 RGWOp
*RGWHandler_Bucket::op_post()
405 return new RGWOp_Bucket_Unlink
;
408 RGWOp
*RGWHandler_Bucket::op_delete()
410 if (s
->info
.args
.sub_resource_exists("object"))
411 return new RGWOp_Object_Remove
;
413 return new RGWOp_Bucket_Remove
;