]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rest_bucket.cc
import ceph 15.2.10
[ceph.git] / ceph / src / rgw / rgw_rest_bucket.cc
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
7c673cae
FG
3
4#include "rgw_op.h"
5#include "rgw_bucket.h"
6#include "rgw_rest_bucket.h"
7
8#include "include/str_list.h"
9
11fdf7f2 10#include "services/svc_sys_obj.h"
9f95a23c 11#include "services/svc_zone.h"
11fdf7f2 12
7c673cae
FG
13#define dout_subsys ceph_subsys_rgw
14
9f95a23c 15
7c673cae
FG
16class RGWOp_Bucket_Info : public RGWRESTOp {
17
18public:
19 RGWOp_Bucket_Info() {}
20
9f95a23c 21 int check_caps(const RGWUserCaps& caps) override {
7c673cae
FG
22 return caps.check_cap("buckets", RGW_CAP_READ);
23 }
24
25 void execute() override;
26
11fdf7f2 27 const char* name() const override { return "get_bucket_info"; }
7c673cae
FG
28};
29
30void RGWOp_Bucket_Info::execute()
31{
32 RGWBucketAdminOpState op_state;
33
34 bool fetch_stats;
35
36 std::string bucket;
37
38 string uid_str;
39
40 RESTArgs::get_string(s, "uid", uid_str, &uid_str);
41 rgw_user uid(uid_str);
42
43 RESTArgs::get_string(s, "bucket", bucket, &bucket);
44 RESTArgs::get_bool(s, "stats", false, &fetch_stats);
45
46 op_state.set_user_id(uid);
47 op_state.set_bucket_name(bucket);
48 op_state.set_fetch_stats(fetch_stats);
49
50 http_ret = RGWBucketAdminOp::info(store, op_state, flusher);
51}
52
53class RGWOp_Get_Policy : public RGWRESTOp {
54
55public:
56 RGWOp_Get_Policy() {}
57
9f95a23c 58 int check_caps(const RGWUserCaps& caps) override {
7c673cae
FG
59 return caps.check_cap("buckets", RGW_CAP_READ);
60 }
61
62 void execute() override;
63
11fdf7f2 64 const char* name() const override { return "get_policy"; }
7c673cae
FG
65};
66
67void RGWOp_Get_Policy::execute()
68{
69 RGWBucketAdminOpState op_state;
70
71 std::string bucket;
72 std::string object;
73
74 RESTArgs::get_string(s, "bucket", bucket, &bucket);
75 RESTArgs::get_string(s, "object", object, &object);
76
77 op_state.set_bucket_name(bucket);
78 op_state.set_object(object);
79
80 http_ret = RGWBucketAdminOp::get_policy(store, op_state, flusher);
81}
82
83class RGWOp_Check_Bucket_Index : public RGWRESTOp {
84
85public:
86 RGWOp_Check_Bucket_Index() {}
87
9f95a23c 88 int check_caps(const RGWUserCaps& caps) override {
7c673cae
FG
89 return caps.check_cap("buckets", RGW_CAP_WRITE);
90 }
91
92 void execute() override;
93
11fdf7f2 94 const char* name() const override { return "check_bucket_index"; }
7c673cae
FG
95};
96
97void RGWOp_Check_Bucket_Index::execute()
98{
99 std::string bucket;
100
101 bool fix_index;
102 bool check_objects;
103
104 RGWBucketAdminOpState op_state;
105
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);
109
110 op_state.set_bucket_name(bucket);
111 op_state.set_fix_index(fix_index);
112 op_state.set_check_objects(check_objects);
113
9f95a23c 114 http_ret = RGWBucketAdminOp::check_index(store, op_state, flusher, s->yield);
7c673cae
FG
115}
116
117class RGWOp_Bucket_Link : public RGWRESTOp {
118
119public:
120 RGWOp_Bucket_Link() {}
121
9f95a23c 122 int check_caps(const RGWUserCaps& caps) override {
7c673cae
FG
123 return caps.check_cap("buckets", RGW_CAP_WRITE);
124 }
125
126 void execute() override;
127
11fdf7f2 128 const char* name() const override { return "link_bucket"; }
7c673cae
FG
129};
130
131void RGWOp_Bucket_Link::execute()
132{
133 std::string uid_str;
134 std::string bucket;
135 std::string bucket_id;
9f95a23c 136 std::string new_bucket_name;
7c673cae
FG
137
138 RGWBucketAdminOpState op_state;
139
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);
9f95a23c 143 RESTArgs::get_string(s, "new-bucket-name", new_bucket_name, &new_bucket_name);
7c673cae
FG
144
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);
9f95a23c 149 op_state.set_new_bucket_name(new_bucket_name);
7c673cae 150
9f95a23c
TL
151 if (!store->svc()->zone->is_meta_master()) {
152 bufferlist data;
153 op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
154 if (op_ret < 0) {
155 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
156 return;
157 }
158 }
7c673cae
FG
159 http_ret = RGWBucketAdminOp::link(store, op_state);
160}
161
162class RGWOp_Bucket_Unlink : public RGWRESTOp {
163
164public:
165 RGWOp_Bucket_Unlink() {}
166
9f95a23c 167 int check_caps(const RGWUserCaps& caps) override {
7c673cae
FG
168 return caps.check_cap("buckets", RGW_CAP_WRITE);
169 }
170
171 void execute() override;
172
11fdf7f2 173 const char* name() const override { return "unlink_bucket"; }
7c673cae
FG
174};
175
176void RGWOp_Bucket_Unlink::execute()
177{
178 std::string uid_str;
179 std::string bucket;
180
181 RGWBucketAdminOpState op_state;
182
183 RESTArgs::get_string(s, "uid", uid_str, &uid_str);
184 rgw_user uid(uid_str);
185
186 RESTArgs::get_string(s, "bucket", bucket, &bucket);
187
188 op_state.set_user_id(uid);
189 op_state.set_bucket_name(bucket);
190
9f95a23c
TL
191 if (!store->svc()->zone->is_meta_master()) {
192 bufferlist data;
193 op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
194 if (op_ret < 0) {
195 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
196 return;
197 }
198 }
7c673cae
FG
199 http_ret = RGWBucketAdminOp::unlink(store, op_state);
200}
201
202class RGWOp_Bucket_Remove : public RGWRESTOp {
203
204public:
205 RGWOp_Bucket_Remove() {}
206
9f95a23c 207 int check_caps(const RGWUserCaps& caps) override {
7c673cae
FG
208 return caps.check_cap("buckets", RGW_CAP_WRITE);
209 }
210
211 void execute() override;
212
11fdf7f2 213 const char* name() const override { return "remove_bucket"; }
7c673cae
FG
214};
215
216void RGWOp_Bucket_Remove::execute()
217{
218 std::string bucket;
219 bool delete_children;
220
221 RGWBucketAdminOpState op_state;
222
223 RESTArgs::get_string(s, "bucket", bucket, &bucket);
224 RESTArgs::get_bool(s, "purge-objects", false, &delete_children);
225
226 op_state.set_bucket_name(bucket);
227 op_state.set_delete_children(delete_children);
228
9f95a23c
TL
229 if (!store->svc()->zone->is_meta_master()) {
230 bufferlist data;
231 op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
232 if (op_ret < 0) {
233 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
234 return;
235 }
236 }
237 http_ret = RGWBucketAdminOp::remove_bucket(store, op_state, s->yield);
7c673cae
FG
238}
239
94b18763
FG
240class RGWOp_Set_Bucket_Quota : public RGWRESTOp {
241
242public:
243 RGWOp_Set_Bucket_Quota() {}
244
9f95a23c 245 int check_caps(const RGWUserCaps& caps) override {
94b18763
FG
246 return caps.check_cap("buckets", RGW_CAP_WRITE);
247 }
248
11fdf7f2 249 void execute() override;
94b18763 250
11fdf7f2 251 const char* name() const override { return "set_bucket_quota"; }
94b18763
FG
252};
253
254#define QUOTA_INPUT_MAX_LEN 1024
255
256void RGWOp_Set_Bucket_Quota::execute()
257{
258 bool uid_arg_existed = false;
259 std::string uid_str;
260 RESTArgs::get_string(s, "uid", uid_str, &uid_str, &uid_arg_existed);
261 if (! uid_arg_existed) {
262 http_ret = -EINVAL;
263 return;
264 }
265 rgw_user uid(uid_str);
266 bool bucket_arg_existed = false;
267 std::string bucket;
268 RESTArgs::get_string(s, "bucket", bucket, &bucket, &bucket_arg_existed);
269 if (! bucket_arg_existed) {
270 http_ret = -EINVAL;
271 return;
272 }
273
274 bool use_http_params;
275
276 if (s->content_length > 0) {
277 use_http_params = false;
278 } else {
279 const char *encoding = s->info.env->get("HTTP_TRANSFER_ENCODING");
280 use_http_params = (!encoding || strcmp(encoding, "chunked") != 0);
281 }
282 RGWQuotaInfo quota;
283 if (!use_http_params) {
284 bool empty;
285 http_ret = rgw_rest_get_json_input(store->ctx(), s, quota, QUOTA_INPUT_MAX_LEN, &empty);
286 if (http_ret < 0) {
287 if (!empty)
288 return;
289 /* was probably chunked input, but no content provided, configure via http params */
290 use_http_params = true;
291 }
292 }
293 if (use_http_params) {
294 RGWBucketInfo bucket_info;
295 map<string, bufferlist> attrs;
9f95a23c 296 http_ret = store->getRados()->get_bucket_info(store->svc(), uid.tenant, bucket, bucket_info, NULL, s->yield, &attrs);
94b18763
FG
297 if (http_ret < 0) {
298 return;
299 }
300 RGWQuotaInfo *old_quota = &bucket_info.quota;
301 int64_t old_max_size_kb = rgw_rounded_kb(old_quota->max_size);
302 int64_t max_size_kb;
303 RESTArgs::get_int64(s, "max-objects", old_quota->max_objects, &quota.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, &quota.enabled);
307 }
308
309 RGWBucketAdminOpState op_state;
310 op_state.set_user_id(uid);
311 op_state.set_bucket_name(bucket);
312 op_state.set_quota(quota);
313
314 http_ret = RGWBucketAdminOp::set_quota(store, op_state);
315}
316
9f95a23c
TL
317class RGWOp_Sync_Bucket : public RGWRESTOp {
318
319public:
320 RGWOp_Sync_Bucket() {}
321
322 int check_caps(const RGWUserCaps& caps) override {
323 return caps.check_cap("buckets", RGW_CAP_WRITE);
324 }
325
326 void execute() override;
327
328 const char* name() const override { return "sync_bucket"; }
329};
330
331void RGWOp_Sync_Bucket::execute()
332{
333 std::string bucket;
334 std::string tenant;
335 bool sync_bucket;
336
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);
341
342 op_state.set_bucket_name(bucket);
343 op_state.set_tenant(tenant);
344 op_state.set_sync_bucket(sync_bucket);
345
346 http_ret = RGWBucketAdminOp::sync_bucket(store, op_state);
347}
348
7c673cae
FG
349class RGWOp_Object_Remove: public RGWRESTOp {
350
351public:
352 RGWOp_Object_Remove() {}
353
9f95a23c 354 int check_caps(const RGWUserCaps& caps) override {
7c673cae
FG
355 return caps.check_cap("buckets", RGW_CAP_WRITE);
356 }
357
358 void execute() override;
359
11fdf7f2 360 const char* name() const override { return "remove_object"; }
7c673cae
FG
361};
362
363void RGWOp_Object_Remove::execute()
364{
365 std::string bucket;
366 std::string object;
367
368 RGWBucketAdminOpState op_state;
369
370 RESTArgs::get_string(s, "bucket", bucket, &bucket);
371 RESTArgs::get_string(s, "object", object, &object);
372
373 op_state.set_bucket_name(bucket);
374 op_state.set_object(object);
375
376 http_ret = RGWBucketAdminOp::remove_object(store, op_state);
377}
378
9f95a23c 379
7c673cae
FG
380RGWOp *RGWHandler_Bucket::op_get()
381{
382
383 if (s->info.args.sub_resource_exists("policy"))
384 return new RGWOp_Get_Policy;
385
386 if (s->info.args.sub_resource_exists("index"))
387 return new RGWOp_Check_Bucket_Index;
388
389 return new RGWOp_Bucket_Info;
390}
391
392RGWOp *RGWHandler_Bucket::op_put()
393{
94b18763
FG
394 if (s->info.args.sub_resource_exists("quota"))
395 return new RGWOp_Set_Bucket_Quota;
9f95a23c
TL
396
397 if (s->info.args.sub_resource_exists("sync"))
398 return new RGWOp_Sync_Bucket;
399
7c673cae
FG
400 return new RGWOp_Bucket_Link;
401}
402
403RGWOp *RGWHandler_Bucket::op_post()
404{
405 return new RGWOp_Bucket_Unlink;
406}
407
408RGWOp *RGWHandler_Bucket::op_delete()
409{
410 if (s->info.args.sub_resource_exists("object"))
411 return new RGWOp_Object_Remove;
412
413 return new RGWOp_Bucket_Remove;
414}
415