1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
4 #include "common/ceph_json.h"
8 #include "rgw_rest_user.h"
9 #include "rgw_sal_rados.h"
11 #include "include/str_list.h"
12 #include "include/ceph_assert.h"
14 #include "services/svc_zone.h"
15 #include "services/svc_sys_obj.h"
18 #define dout_subsys ceph_subsys_rgw
20 class RGWOp_User_List
: public RGWRESTOp
{
25 int check_caps(const RGWUserCaps
& caps
) override
{
26 return caps
.check_cap("users", RGW_CAP_READ
);
29 void execute(optional_yield y
) override
;
31 const char* name() const override
{ return "list_user"; }
34 void RGWOp_User_List::execute(optional_yield y
)
36 RGWUserAdminOpState op_state
;
40 RESTArgs::get_uint32(s
, "max-entries", 1000, &max_entries
);
41 RESTArgs::get_string(s
, "marker", marker
, &marker
);
43 op_state
.max_entries
= max_entries
;
44 op_state
.marker
= marker
;
45 op_ret
= RGWUserAdminOp_User::list(store
, op_state
, flusher
);
48 class RGWOp_User_Info
: public RGWRESTOp
{
53 int check_caps(const RGWUserCaps
& caps
) override
{
54 return caps
.check_cap("users", RGW_CAP_READ
);
57 void execute(optional_yield y
) override
;
59 const char* name() const override
{ return "get_user_info"; }
62 void RGWOp_User_Info::execute(optional_yield y
)
64 RGWUserAdminOpState op_state
;
66 std::string uid_str
, access_key_str
;
70 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
71 RESTArgs::get_string(s
, "access-key", access_key_str
, &access_key_str
);
73 // if uid was not supplied in rest argument, error out now, otherwise we'll
74 // end up initializing anonymous user, for which keys.init will eventually
76 if (uid_str
.empty() && access_key_str
.empty()){
81 rgw_user
uid(uid_str
);
83 RESTArgs::get_bool(s
, "stats", false, &fetch_stats
);
85 RESTArgs::get_bool(s
, "sync", false, &sync_stats
);
87 op_state
.set_user_id(uid
);
88 op_state
.set_access_key(access_key_str
);
89 op_state
.set_fetch_stats(fetch_stats
);
90 op_state
.set_sync_stats(sync_stats
);
92 op_ret
= RGWUserAdminOp_User::info(store
, op_state
, flusher
, y
);
95 class RGWOp_User_Create
: public RGWRESTOp
{
98 RGWOp_User_Create() {}
100 int check_caps(const RGWUserCaps
& caps
) override
{
101 return caps
.check_cap("users", RGW_CAP_WRITE
);
104 void execute(optional_yield y
) override
;
106 const char* name() const override
{ return "create_user"; }
109 void RGWOp_User_Create::execute(optional_yield y
)
112 std::string display_name
;
114 std::string access_key
;
115 std::string secret_key
;
116 std::string key_type_str
;
118 std::string tenant_name
;
119 std::string op_mask_str
;
120 std::string default_placement_str
;
121 std::string placement_tags_str
;
129 const int32_t default_max_buckets
=
130 s
->cct
->_conf
.get_val
<int64_t>("rgw_user_max_buckets");
132 RGWUserAdminOpState op_state
;
134 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
135 rgw_user
uid(uid_str
);
137 RESTArgs::get_string(s
, "display-name", display_name
, &display_name
);
138 RESTArgs::get_string(s
, "email", email
, &email
);
139 RESTArgs::get_string(s
, "access-key", access_key
, &access_key
);
140 RESTArgs::get_string(s
, "secret-key", secret_key
, &secret_key
);
141 RESTArgs::get_string(s
, "key-type", key_type_str
, &key_type_str
);
142 RESTArgs::get_string(s
, "user-caps", caps
, &caps
);
143 RESTArgs::get_string(s
, "tenant", tenant_name
, &tenant_name
);
144 RESTArgs::get_bool(s
, "generate-key", true, &gen_key
);
145 RESTArgs::get_bool(s
, "suspended", false, &suspended
);
146 RESTArgs::get_int32(s
, "max-buckets", default_max_buckets
, &max_buckets
);
147 RESTArgs::get_bool(s
, "system", false, &system
);
148 RESTArgs::get_bool(s
, "exclusive", false, &exclusive
);
149 RESTArgs::get_string(s
, "op-mask", op_mask_str
, &op_mask_str
);
150 RESTArgs::get_string(s
, "default-placement", default_placement_str
, &default_placement_str
);
151 RESTArgs::get_string(s
, "placement-tags", placement_tags_str
, &placement_tags_str
);
153 if (!s
->user
->get_info().system
&& system
) {
154 ldout(s
->cct
, 0) << "cannot set system flag by non-system user" << dendl
;
159 if (!tenant_name
.empty()) {
160 uid
.tenant
= tenant_name
;
163 // TODO: validate required args are passed in. (for eg. uid and display_name here)
164 op_state
.set_user_id(uid
);
165 op_state
.set_display_name(display_name
);
166 op_state
.set_user_email(email
);
167 op_state
.set_caps(caps
);
168 op_state
.set_access_key(access_key
);
169 op_state
.set_secret_key(secret_key
);
171 if (!op_mask_str
.empty()) {
173 int ret
= rgw_parse_op_type_list(op_mask_str
, &op_mask
);
175 ldout(s
->cct
, 0) << "failed to parse op_mask: " << ret
<< dendl
;
179 op_state
.set_op_mask(op_mask
);
182 if (!key_type_str
.empty()) {
183 int32_t key_type
= KEY_TYPE_UNDEFINED
;
184 if (key_type_str
.compare("swift") == 0)
185 key_type
= KEY_TYPE_SWIFT
;
186 else if (key_type_str
.compare("s3") == 0)
187 key_type
= KEY_TYPE_S3
;
189 op_state
.set_key_type(key_type
);
192 if (max_buckets
!= default_max_buckets
) {
193 if (max_buckets
< 0) {
196 op_state
.set_max_buckets(max_buckets
);
198 if (s
->info
.args
.exists("suspended"))
199 op_state
.set_suspension(suspended
);
201 if (s
->info
.args
.exists("system"))
202 op_state
.set_system(system
);
204 if (s
->info
.args
.exists("exclusive"))
205 op_state
.set_exclusive(exclusive
);
208 op_state
.set_generate_key();
210 if (!default_placement_str
.empty()) {
211 rgw_placement_rule target_rule
;
212 target_rule
.from_str(default_placement_str
);
213 if (!store
->svc()->zone
->get_zone_params().valid_placement(target_rule
)) {
214 ldout(s
->cct
, 0) << "NOTICE: invalid dest placement: " << target_rule
.to_str() << dendl
;
218 op_state
.set_default_placement(target_rule
);
221 if (!placement_tags_str
.empty()) {
222 list
<string
> placement_tags_list
;
223 get_str_list(placement_tags_str
, ",", placement_tags_list
);
224 op_state
.set_placement_tags(placement_tags_list
);
228 op_ret
= store
->forward_request_to_master(s
->user
.get(), nullptr, data
, nullptr, s
->info
, y
);
230 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
233 op_ret
= RGWUserAdminOp_User::create(store
, op_state
, flusher
, y
);
236 class RGWOp_User_Modify
: public RGWRESTOp
{
239 RGWOp_User_Modify() {}
241 int check_caps(const RGWUserCaps
& caps
) override
{
242 return caps
.check_cap("users", RGW_CAP_WRITE
);
245 void execute(optional_yield y
) override
;
247 const char* name() const override
{ return "modify_user"; }
250 void RGWOp_User_Modify::execute(optional_yield y
)
253 std::string display_name
;
255 std::string access_key
;
256 std::string secret_key
;
257 std::string key_type_str
;
259 std::string op_mask_str
;
260 std::string default_placement_str
;
261 std::string placement_tags_str
;
270 RGWUserAdminOpState op_state
;
272 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
273 rgw_user
uid(uid_str
);
275 RESTArgs::get_string(s
, "display-name", display_name
, &display_name
);
276 RESTArgs::get_string(s
, "email", email
, &email
, &email_set
);
277 RESTArgs::get_string(s
, "access-key", access_key
, &access_key
);
278 RESTArgs::get_string(s
, "secret-key", secret_key
, &secret_key
);
279 RESTArgs::get_string(s
, "user-caps", caps
, &caps
);
280 RESTArgs::get_bool(s
, "generate-key", false, &gen_key
);
281 RESTArgs::get_bool(s
, "suspended", false, &suspended
);
282 RESTArgs::get_int32(s
, "max-buckets", RGW_DEFAULT_MAX_BUCKETS
, &max_buckets
, "a_set
);
283 RESTArgs::get_string(s
, "key-type", key_type_str
, &key_type_str
);
285 RESTArgs::get_bool(s
, "system", false, &system
);
286 RESTArgs::get_string(s
, "op-mask", op_mask_str
, &op_mask_str
);
287 RESTArgs::get_string(s
, "default-placement", default_placement_str
, &default_placement_str
);
288 RESTArgs::get_string(s
, "placement-tags", placement_tags_str
, &placement_tags_str
);
290 if (!s
->user
->get_info().system
&& system
) {
291 ldout(s
->cct
, 0) << "cannot set system flag by non-system user" << dendl
;
296 op_state
.set_user_id(uid
);
297 op_state
.set_display_name(display_name
);
300 op_state
.set_user_email(email
);
302 op_state
.set_caps(caps
);
303 op_state
.set_access_key(access_key
);
304 op_state
.set_secret_key(secret_key
);
307 if (max_buckets
< 0 ) {
310 op_state
.set_max_buckets(max_buckets
);
313 op_state
.set_generate_key();
315 if (!key_type_str
.empty()) {
316 int32_t key_type
= KEY_TYPE_UNDEFINED
;
317 if (key_type_str
.compare("swift") == 0)
318 key_type
= KEY_TYPE_SWIFT
;
319 else if (key_type_str
.compare("s3") == 0)
320 key_type
= KEY_TYPE_S3
;
322 op_state
.set_key_type(key_type
);
325 if (!op_mask_str
.empty()) {
327 if (rgw_parse_op_type_list(op_mask_str
, &op_mask
) < 0) {
328 ldout(s
->cct
, 0) << "failed to parse op_mask" << dendl
;
332 op_state
.set_op_mask(op_mask
);
335 if (s
->info
.args
.exists("suspended"))
336 op_state
.set_suspension(suspended
);
338 if (s
->info
.args
.exists("system"))
339 op_state
.set_system(system
);
341 if (!op_mask_str
.empty()) {
343 int ret
= rgw_parse_op_type_list(op_mask_str
, &op_mask
);
345 ldout(s
->cct
, 0) << "failed to parse op_mask: " << ret
<< dendl
;
349 op_state
.set_op_mask(op_mask
);
352 if (!default_placement_str
.empty()) {
353 rgw_placement_rule target_rule
;
354 target_rule
.from_str(default_placement_str
);
355 if (!store
->svc()->zone
->get_zone_params().valid_placement(target_rule
)) {
356 ldout(s
->cct
, 0) << "NOTICE: invalid dest placement: " << target_rule
.to_str() << dendl
;
360 op_state
.set_default_placement(target_rule
);
363 if (!placement_tags_str
.empty()) {
364 list
<string
> placement_tags_list
;
365 get_str_list(placement_tags_str
, ",", placement_tags_list
);
366 op_state
.set_placement_tags(placement_tags_list
);
370 op_ret
= store
->forward_request_to_master(s
->user
.get(), nullptr, data
, nullptr, s
->info
, y
);
372 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
375 op_ret
= RGWUserAdminOp_User::modify(store
, op_state
, flusher
, y
);
378 class RGWOp_User_Remove
: public RGWRESTOp
{
381 RGWOp_User_Remove() {}
383 int check_caps(const RGWUserCaps
& caps
) override
{
384 return caps
.check_cap("users", RGW_CAP_WRITE
);
387 void execute(optional_yield y
) override
;
389 const char* name() const override
{ return "remove_user"; }
392 void RGWOp_User_Remove::execute(optional_yield y
)
397 RGWUserAdminOpState op_state
;
399 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
400 rgw_user
uid(uid_str
);
402 RESTArgs::get_bool(s
, "purge-data", false, &purge_data
);
404 // FIXME: no double checking
406 op_state
.set_user_id(uid
);
408 op_state
.set_purge_data(purge_data
);
411 op_ret
= store
->forward_request_to_master(s
->user
.get(), nullptr, data
, nullptr, s
->info
, y
);
413 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
416 op_ret
= RGWUserAdminOp_User::remove(store
, op_state
, flusher
, s
->yield
);
419 class RGWOp_Subuser_Create
: public RGWRESTOp
{
422 RGWOp_Subuser_Create() {}
424 int check_caps(const RGWUserCaps
& caps
) override
{
425 return caps
.check_cap("users", RGW_CAP_WRITE
);
428 void execute(optional_yield y
) override
;
430 const char* name() const override
{ return "create_subuser"; }
433 void RGWOp_Subuser_Create::execute(optional_yield y
)
437 std::string secret_key
;
438 std::string access_key
;
439 std::string perm_str
;
440 std::string key_type_str
;
442 bool gen_subuser
= false; // FIXME placeholder
446 uint32_t perm_mask
= 0;
447 int32_t key_type
= KEY_TYPE_SWIFT
;
449 RGWUserAdminOpState op_state
;
451 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
452 rgw_user
uid(uid_str
);
454 RESTArgs::get_string(s
, "subuser", subuser
, &subuser
);
455 RESTArgs::get_string(s
, "access-key", access_key
, &access_key
);
456 RESTArgs::get_string(s
, "secret-key", secret_key
, &secret_key
);
457 RESTArgs::get_string(s
, "access", perm_str
, &perm_str
);
458 RESTArgs::get_string(s
, "key-type", key_type_str
, &key_type_str
);
459 //RESTArgs::get_bool(s, "generate-subuser", false, &gen_subuser);
460 RESTArgs::get_bool(s
, "generate-secret", false, &gen_secret
);
461 RESTArgs::get_bool(s
, "gen-access-key", false, &gen_access
);
463 perm_mask
= rgw_str_to_perm(perm_str
.c_str());
464 op_state
.set_perm(perm_mask
);
466 op_state
.set_user_id(uid
);
467 op_state
.set_subuser(subuser
);
468 op_state
.set_access_key(access_key
);
469 op_state
.set_secret_key(secret_key
);
470 op_state
.set_generate_subuser(gen_subuser
);
473 op_state
.set_gen_access();
476 op_state
.set_gen_secret();
478 if (!key_type_str
.empty()) {
479 if (key_type_str
.compare("swift") == 0)
480 key_type
= KEY_TYPE_SWIFT
;
481 else if (key_type_str
.compare("s3") == 0)
482 key_type
= KEY_TYPE_S3
;
484 op_state
.set_key_type(key_type
);
487 op_ret
= store
->forward_request_to_master(s
->user
.get(), nullptr, data
, nullptr, s
->info
, y
);
489 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
492 op_ret
= RGWUserAdminOp_Subuser::create(store
, op_state
, flusher
, y
);
495 class RGWOp_Subuser_Modify
: public RGWRESTOp
{
498 RGWOp_Subuser_Modify() {}
500 int check_caps(const RGWUserCaps
& caps
) override
{
501 return caps
.check_cap("users", RGW_CAP_WRITE
);
504 void execute(optional_yield y
) override
;
506 const char* name() const override
{ return "modify_subuser"; }
509 void RGWOp_Subuser_Modify::execute(optional_yield y
)
513 std::string secret_key
;
514 std::string key_type_str
;
515 std::string perm_str
;
517 RGWUserAdminOpState op_state
;
520 int32_t key_type
= KEY_TYPE_SWIFT
;
524 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
525 rgw_user
uid(uid_str
);
527 RESTArgs::get_string(s
, "subuser", subuser
, &subuser
);
528 RESTArgs::get_string(s
, "secret-key", secret_key
, &secret_key
);
529 RESTArgs::get_string(s
, "access", perm_str
, &perm_str
);
530 RESTArgs::get_string(s
, "key-type", key_type_str
, &key_type_str
);
531 RESTArgs::get_bool(s
, "generate-secret", false, &gen_secret
);
533 perm_mask
= rgw_str_to_perm(perm_str
.c_str());
534 op_state
.set_perm(perm_mask
);
536 op_state
.set_user_id(uid
);
537 op_state
.set_subuser(subuser
);
539 if (!secret_key
.empty())
540 op_state
.set_secret_key(secret_key
);
543 op_state
.set_gen_secret();
545 if (!key_type_str
.empty()) {
546 if (key_type_str
.compare("swift") == 0)
547 key_type
= KEY_TYPE_SWIFT
;
548 else if (key_type_str
.compare("s3") == 0)
549 key_type
= KEY_TYPE_S3
;
551 op_state
.set_key_type(key_type
);
554 op_ret
= store
->forward_request_to_master(s
->user
.get(), nullptr, data
, nullptr, s
->info
, y
);
556 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
559 op_ret
= RGWUserAdminOp_Subuser::modify(store
, op_state
, flusher
, y
);
562 class RGWOp_Subuser_Remove
: public RGWRESTOp
{
565 RGWOp_Subuser_Remove() {}
567 int check_caps(const RGWUserCaps
& caps
) override
{
568 return caps
.check_cap("users", RGW_CAP_WRITE
);
571 void execute(optional_yield y
) override
;
573 const char* name() const override
{ return "remove_subuser"; }
576 void RGWOp_Subuser_Remove::execute(optional_yield y
)
582 RGWUserAdminOpState op_state
;
584 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
585 rgw_user
uid(uid_str
);
587 RESTArgs::get_string(s
, "subuser", subuser
, &subuser
);
588 RESTArgs::get_bool(s
, "purge-keys", true, &purge_keys
);
590 op_state
.set_user_id(uid
);
591 op_state
.set_subuser(subuser
);
594 op_state
.set_purge_keys();
597 op_ret
= store
->forward_request_to_master(s
->user
.get(), nullptr, data
, nullptr, s
->info
, y
);
599 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
602 op_ret
= RGWUserAdminOp_Subuser::remove(store
, op_state
, flusher
, y
);
605 class RGWOp_Key_Create
: public RGWRESTOp
{
608 RGWOp_Key_Create() {}
610 int check_caps(const RGWUserCaps
& caps
) override
{
611 return caps
.check_cap("users", RGW_CAP_WRITE
);
614 void execute(optional_yield y
) override
;
616 const char* name() const override
{ return "create_access_key"; }
619 void RGWOp_Key_Create::execute(optional_yield y
)
623 std::string access_key
;
624 std::string secret_key
;
625 std::string key_type_str
;
629 RGWUserAdminOpState op_state
;
631 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
632 rgw_user
uid(uid_str
);
634 RESTArgs::get_string(s
, "subuser", subuser
, &subuser
);
635 RESTArgs::get_string(s
, "access-key", access_key
, &access_key
);
636 RESTArgs::get_string(s
, "secret-key", secret_key
, &secret_key
);
637 RESTArgs::get_string(s
, "key-type", key_type_str
, &key_type_str
);
638 RESTArgs::get_bool(s
, "generate-key", true, &gen_key
);
640 op_state
.set_user_id(uid
);
641 op_state
.set_subuser(subuser
);
642 op_state
.set_access_key(access_key
);
643 op_state
.set_secret_key(secret_key
);
646 op_state
.set_generate_key();
648 if (!key_type_str
.empty()) {
649 int32_t key_type
= KEY_TYPE_UNDEFINED
;
650 if (key_type_str
.compare("swift") == 0)
651 key_type
= KEY_TYPE_SWIFT
;
652 else if (key_type_str
.compare("s3") == 0)
653 key_type
= KEY_TYPE_S3
;
655 op_state
.set_key_type(key_type
);
658 op_ret
= RGWUserAdminOp_Key::create(store
, op_state
, flusher
, y
);
661 class RGWOp_Key_Remove
: public RGWRESTOp
{
664 RGWOp_Key_Remove() {}
666 int check_caps(const RGWUserCaps
& caps
) override
{
667 return caps
.check_cap("users", RGW_CAP_WRITE
);
670 void execute(optional_yield y
) override
;
672 const char* name() const override
{ return "remove_access_key"; }
675 void RGWOp_Key_Remove::execute(optional_yield y
)
679 std::string access_key
;
680 std::string key_type_str
;
682 RGWUserAdminOpState op_state
;
684 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
685 rgw_user
uid(uid_str
);
687 RESTArgs::get_string(s
, "subuser", subuser
, &subuser
);
688 RESTArgs::get_string(s
, "access-key", access_key
, &access_key
);
689 RESTArgs::get_string(s
, "key-type", key_type_str
, &key_type_str
);
691 op_state
.set_user_id(uid
);
692 op_state
.set_subuser(subuser
);
693 op_state
.set_access_key(access_key
);
695 if (!key_type_str
.empty()) {
696 int32_t key_type
= KEY_TYPE_UNDEFINED
;
697 if (key_type_str
.compare("swift") == 0)
698 key_type
= KEY_TYPE_SWIFT
;
699 else if (key_type_str
.compare("s3") == 0)
700 key_type
= KEY_TYPE_S3
;
702 op_state
.set_key_type(key_type
);
705 op_ret
= RGWUserAdminOp_Key::remove(store
, op_state
, flusher
, y
);
708 class RGWOp_Caps_Add
: public RGWRESTOp
{
713 int check_caps(const RGWUserCaps
& caps
) override
{
714 return caps
.check_cap("users", RGW_CAP_WRITE
);
717 void execute(optional_yield y
) override
;
719 const char* name() const override
{ return "add_user_caps"; }
722 void RGWOp_Caps_Add::execute(optional_yield y
)
727 RGWUserAdminOpState op_state
;
729 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
730 rgw_user
uid(uid_str
);
732 RESTArgs::get_string(s
, "user-caps", caps
, &caps
);
734 op_state
.set_user_id(uid
);
735 op_state
.set_caps(caps
);
738 op_ret
= store
->forward_request_to_master(s
->user
.get(), nullptr, data
, nullptr, s
->info
, y
);
740 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
743 op_ret
= RGWUserAdminOp_Caps::add(store
, op_state
, flusher
, y
);
746 class RGWOp_Caps_Remove
: public RGWRESTOp
{
749 RGWOp_Caps_Remove() {}
751 int check_caps(const RGWUserCaps
& caps
) override
{
752 return caps
.check_cap("users", RGW_CAP_WRITE
);
755 void execute(optional_yield y
) override
;
757 const char* name() const override
{ return "remove_user_caps"; }
760 void RGWOp_Caps_Remove::execute(optional_yield y
)
765 RGWUserAdminOpState op_state
;
767 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
768 rgw_user
uid(uid_str
);
770 RESTArgs::get_string(s
, "user-caps", caps
, &caps
);
772 op_state
.set_user_id(uid
);
773 op_state
.set_caps(caps
);
776 op_ret
= store
->forward_request_to_master(s
->user
.get(), nullptr, data
, nullptr, s
->info
, y
);
778 ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
781 op_ret
= RGWUserAdminOp_Caps::remove(store
, op_state
, flusher
, y
);
785 RGWQuotaInfo bucket_quota
;
786 RGWQuotaInfo user_quota
;
790 explicit UserQuotas(RGWUserInfo
& info
) : bucket_quota(info
.bucket_quota
),
791 user_quota(info
.user_quota
) {}
793 void dump(Formatter
*f
) const {
794 encode_json("bucket_quota", bucket_quota
, f
);
795 encode_json("user_quota", user_quota
, f
);
797 void decode_json(JSONObj
*obj
) {
798 JSONDecoder::decode_json("bucket_quota", bucket_quota
, obj
);
799 JSONDecoder::decode_json("user_quota", user_quota
, obj
);
803 class RGWOp_Quota_Info
: public RGWRESTOp
{
806 RGWOp_Quota_Info() {}
808 int check_caps(const RGWUserCaps
& caps
) override
{
809 return caps
.check_cap("users", RGW_CAP_READ
);
812 void execute(optional_yield y
) override
;
814 const char* name() const override
{ return "get_quota_info"; }
818 void RGWOp_Quota_Info::execute(optional_yield y
)
820 RGWUserAdminOpState op_state
;
823 std::string quota_type
;
825 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
826 RESTArgs::get_string(s
, "quota-type", quota_type
, "a_type
);
828 if (uid_str
.empty()) {
833 rgw_user
uid(uid_str
);
835 bool show_all
= quota_type
.empty();
836 bool show_bucket
= show_all
|| (quota_type
== "bucket");
837 bool show_user
= show_all
|| (quota_type
== "user");
839 if (!(show_all
|| show_bucket
|| show_user
)) {
844 op_state
.set_user_id(uid
);
847 op_ret
= user
.init(store
, op_state
, y
);
851 if (!op_state
.has_existing_user()) {
852 op_ret
= -ERR_NO_SUCH_USER
;
858 op_ret
= user
.info(info
, &err_msg
);
864 UserQuotas
quotas(info
);
865 encode_json("quota", quotas
, s
->formatter
);
866 } else if (show_user
) {
867 encode_json("user_quota", info
.user_quota
, s
->formatter
);
869 encode_json("bucket_quota", info
.bucket_quota
, s
->formatter
);
875 class RGWOp_Quota_Set
: public RGWRESTOp
{
880 int check_caps(const RGWUserCaps
& caps
) override
{
881 return caps
.check_cap("users", RGW_CAP_WRITE
);
884 void execute(optional_yield y
) override
;
886 const char* name() const override
{ return "set_quota_info"; }
892 * two different ways to set the quota info: as json struct in the message body or via http params.
896 * PUT /admin/user?uid=<uid>["a-type=<type>]
898 * whereas quota-type is optional and is either user, or bucket
900 * if quota-type is not specified then we expect to get a structure that contains both quotas,
901 * otherwise we'll only get the relevant configuration.
903 * E.g., if quota type not specified:
906 * "max_size_kb" : 4096,
907 * "max_objects" : -1,
911 * "max_size_kb" : 1024,
912 * "max_objects" : -1,
918 * or if quota type is specified:
920 * "max_size_kb" : 4096,
921 * "max_objects" : -1,
925 * Another option is not to pass any body and set the following http params:
929 * max-objects=<max objects>
930 * enabled[={true,false}]
932 * all params are optionals and default to the current settings. With this type of configuration the
933 * quota-type param is mandatory.
937 void RGWOp_Quota_Set::execute(optional_yield y
)
939 RGWUserAdminOpState op_state
;
942 std::string quota_type
;
944 RESTArgs::get_string(s
, "uid", uid_str
, &uid_str
);
945 RESTArgs::get_string(s
, "quota-type", quota_type
, "a_type
);
947 if (uid_str
.empty()) {
952 rgw_user
uid(uid_str
);
954 bool set_all
= quota_type
.empty();
955 bool set_bucket
= set_all
|| (quota_type
== "bucket");
956 bool set_user
= set_all
|| (quota_type
== "user");
958 if (!(set_all
|| set_bucket
|| set_user
)) {
959 ldout(store
->ctx(), 20) << "invalid quota type" << dendl
;
964 bool use_http_params
;
966 if (s
->content_length
> 0) {
967 use_http_params
= false;
969 const char *encoding
= s
->info
.env
->get("HTTP_TRANSFER_ENCODING");
970 use_http_params
= (!encoding
|| strcmp(encoding
, "chunked") != 0);
973 if (use_http_params
&& set_all
) {
974 ldout(store
->ctx(), 20) << "quota type was not specified, can't set all quotas via http headers" << dendl
;
979 op_state
.set_user_id(uid
);
982 op_ret
= user
.init(store
, op_state
, y
);
984 ldout(store
->ctx(), 20) << "failed initializing user info: " << op_ret
<< dendl
;
988 if (!op_state
.has_existing_user()) {
989 op_ret
= -ERR_NO_SUCH_USER
;
993 #define QUOTA_INPUT_MAX_LEN 1024
997 if ((op_ret
= rgw_rest_get_json_input(store
->ctx(), s
, quotas
, QUOTA_INPUT_MAX_LEN
, NULL
)) < 0) {
998 ldout(store
->ctx(), 20) << "failed to retrieve input" << dendl
;
1002 op_state
.set_user_quota(quotas
.user_quota
);
1003 op_state
.set_bucket_quota(quotas
.bucket_quota
);
1007 if (!use_http_params
) {
1009 op_ret
= rgw_rest_get_json_input(store
->ctx(), s
, quota
, QUOTA_INPUT_MAX_LEN
, &empty
);
1011 ldout(store
->ctx(), 20) << "failed to retrieve input" << dendl
;
1015 /* was probably chunked input, but no content provided, configure via http params */
1016 use_http_params
= true;
1020 if (use_http_params
) {
1023 op_ret
= user
.info(info
, &err_msg
);
1025 ldout(store
->ctx(), 20) << "failed to get user info: " << op_ret
<< dendl
;
1028 RGWQuotaInfo
*old_quota
;
1030 old_quota
= &info
.user_quota
;
1032 old_quota
= &info
.bucket_quota
;
1035 RESTArgs::get_int64(s
, "max-objects", old_quota
->max_objects
, "a
.max_objects
);
1036 RESTArgs::get_int64(s
, "max-size", old_quota
->max_size
, "a
.max_size
);
1037 int64_t max_size_kb
;
1038 bool has_max_size_kb
= false;
1039 RESTArgs::get_int64(s
, "max-size-kb", 0, &max_size_kb
, &has_max_size_kb
);
1040 if (has_max_size_kb
) {
1041 quota
.max_size
= max_size_kb
* 1024;
1043 RESTArgs::get_bool(s
, "enabled", old_quota
->enabled
, "a
.enabled
);
1047 op_state
.set_user_quota(quota
);
1049 op_state
.set_bucket_quota(quota
);
1054 op_ret
= user
.modify(op_state
, y
, &err
);
1056 ldout(store
->ctx(), 20) << "failed updating user info: " << op_ret
<< ": " << err
<< dendl
;
1061 RGWOp
*RGWHandler_User::op_get()
1063 if (s
->info
.args
.sub_resource_exists("quota"))
1064 return new RGWOp_Quota_Info
;
1066 if (s
->info
.args
.sub_resource_exists("list"))
1067 return new RGWOp_User_List
;
1069 return new RGWOp_User_Info
;
1072 RGWOp
*RGWHandler_User::op_put()
1074 if (s
->info
.args
.sub_resource_exists("subuser"))
1075 return new RGWOp_Subuser_Create
;
1077 if (s
->info
.args
.sub_resource_exists("key"))
1078 return new RGWOp_Key_Create
;
1080 if (s
->info
.args
.sub_resource_exists("caps"))
1081 return new RGWOp_Caps_Add
;
1083 if (s
->info
.args
.sub_resource_exists("quota"))
1084 return new RGWOp_Quota_Set
;
1086 return new RGWOp_User_Create
;
1089 RGWOp
*RGWHandler_User::op_post()
1091 if (s
->info
.args
.sub_resource_exists("subuser"))
1092 return new RGWOp_Subuser_Modify
;
1094 return new RGWOp_User_Modify
;
1097 RGWOp
*RGWHandler_User::op_delete()
1099 if (s
->info
.args
.sub_resource_exists("subuser"))
1100 return new RGWOp_Subuser_Remove
;
1102 if (s
->info
.args
.sub_resource_exists("key"))
1103 return new RGWOp_Key_Remove
;
1105 if (s
->info
.args
.sub_resource_exists("caps"))
1106 return new RGWOp_Caps_Remove
;
1108 return new RGWOp_User_Remove
;