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/errno.h"
6 #include "rgw_cr_tools.h"
7 #include "rgw_bucket.h"
10 #include "rgw_acl_s3.h"
13 #include "services/svc_zone.h"
15 #define dout_context g_ceph_context
16 #define dout_subsys ceph_subsys_rgw
21 int RGWUserCreateCR::Request::_send_request(const DoutPrefixProvider
*dpp
)
23 CephContext
*cct
= store
->ctx();
25 const int32_t default_max_buckets
=
26 cct
->_conf
.get_val
<int64_t>("rgw_user_max_buckets");
28 RGWUserAdminOpState
op_state(store
);
30 auto& user
= params
.user
;
32 op_state
.set_user_id(user
);
33 op_state
.set_display_name(params
.display_name
);
34 op_state
.set_user_email(params
.email
);
35 op_state
.set_caps(params
.caps
);
36 op_state
.set_access_key(params
.access_key
);
37 op_state
.set_secret_key(params
.secret_key
);
39 if (!params
.key_type
.empty()) {
40 int32_t key_type
= KEY_TYPE_S3
;
41 if (params
.key_type
== "swift") {
42 key_type
= KEY_TYPE_SWIFT
;
45 op_state
.set_key_type(key_type
);
48 op_state
.set_max_buckets(params
.max_buckets
.value_or(default_max_buckets
));
49 op_state
.set_suspension(params
.suspended
);
50 op_state
.set_system(params
.system
);
51 op_state
.set_exclusive(params
.exclusive
);
53 if (params
.generate_key
) {
54 op_state
.set_generate_key();
58 if (params
.apply_quota
) {
59 RGWQuotaInfo bucket_quota
;
60 RGWQuotaInfo user_quota
;
62 if (cct
->_conf
->rgw_bucket_default_quota_max_objects
>= 0) {
63 bucket_quota
.max_objects
= cct
->_conf
->rgw_bucket_default_quota_max_objects
;
64 bucket_quota
.enabled
= true;
67 if (cct
->_conf
->rgw_bucket_default_quota_max_size
>= 0) {
68 bucket_quota
.max_size
= cct
->_conf
->rgw_bucket_default_quota_max_size
;
69 bucket_quota
.enabled
= true;
72 if (cct
->_conf
->rgw_user_default_quota_max_objects
>= 0) {
73 user_quota
.max_objects
= cct
->_conf
->rgw_user_default_quota_max_objects
;
74 user_quota
.enabled
= true;
77 if (cct
->_conf
->rgw_user_default_quota_max_size
>= 0) {
78 user_quota
.max_size
= cct
->_conf
->rgw_user_default_quota_max_size
;
79 user_quota
.enabled
= true;
82 if (bucket_quota
.enabled
) {
83 op_state
.set_bucket_quota(bucket_quota
);
86 if (user_quota
.enabled
) {
87 op_state
.set_user_quota(user_quota
);
91 RGWNullFlusher flusher
;
92 return RGWUserAdminOp_User::create(dpp
, store
, op_state
, flusher
, null_yield
);
96 int RGWGetUserInfoCR::Request::_send_request(const DoutPrefixProvider
*dpp
)
98 return store
->ctl()->user
->get_info_by_uid(dpp
, params
.user
, result
.get(), null_yield
);
102 int RGWGetBucketInfoCR::Request::_send_request(const DoutPrefixProvider
*dpp
)
104 return store
->get_bucket(dpp
, nullptr, params
.tenant
, params
.bucket_name
, &result
->bucket
, null_yield
);
108 int RGWBucketCreateLocalCR::Request::_send_request(const DoutPrefixProvider
*dpp
)
110 CephContext
*cct
= store
->ctx();
111 auto& zone_svc
= store
->svc()->zone
;
113 const auto& user_info
= params
.user_info
.get();
114 const auto& user
= user_info
->user_id
;
115 const auto& bucket_name
= params
.bucket_name
;
116 auto& placement_rule
= params
.placement_rule
;
118 if (!placement_rule
.empty() &&
119 !zone_svc
->get_zone_params().valid_placement(placement_rule
)) {
120 ldpp_dout(dpp
, 0) << "placement target (" << placement_rule
<< ")"
121 << " doesn't exist in the placement targets of zonegroup"
122 << " (" << zone_svc
->get_zonegroup().api_name
<< ")" << dendl
;
123 return -ERR_INVALID_LOCATION_CONSTRAINT
;
126 /* we need to make sure we read bucket info, it's not read before for this
127 * specific request */
128 RGWBucketInfo bucket_info
;
129 map
<string
, bufferlist
> bucket_attrs
;
131 int ret
= store
->getRados()->get_bucket_info(store
->svc(), user
.tenant
, bucket_name
,
132 bucket_info
, nullptr, null_yield
, dpp
, &bucket_attrs
);
133 if (ret
< 0 && ret
!= -ENOENT
)
135 bool bucket_exists
= (ret
!= -ENOENT
);
137 RGWAccessControlPolicy
old_policy(cct
);
138 ACLOwner bucket_owner
;
139 bucket_owner
.set_id(user
);
140 bucket_owner
.set_name(user_info
->display_name
);
142 ret
= rgw_op_get_bucket_policy_from_attr(dpp
, cct
, store
, bucket_info
,
143 bucket_attrs
, &old_policy
, null_yield
);
145 if (old_policy
.get_owner().get_id().compare(user
) != 0) {
151 RGWBucketInfo master_info
;
152 rgw_bucket
*pmaster_bucket
= nullptr;
153 uint32_t *pmaster_num_shards
= nullptr;
154 real_time creation_time
;
156 string zonegroup_id
= zone_svc
->get_zonegroup().get_id();
159 rgw_placement_rule selected_placement_rule
;
161 bucket
.tenant
= user
.tenant
;
162 bucket
.name
= bucket_name
;
163 ret
= zone_svc
->select_bucket_placement(dpp
, *user_info
, zonegroup_id
,
165 &selected_placement_rule
, nullptr, null_yield
);
166 if (selected_placement_rule
!= bucket_info
.placement_rule
) {
167 ldpp_dout(dpp
, 0) << "bucket already exists on a different placement rule: "
168 << " selected_rule= " << selected_placement_rule
169 << " existing_rule= " << bucket_info
.placement_rule
<< dendl
;
174 /* Encode special metadata first as we're using std::map::emplace under
175 * the hood. This method will add the new items only if the map doesn't
176 * contain such keys yet. */
177 RGWAccessControlPolicy_S3
policy(cct
);
178 policy
.create_canned(bucket_owner
, bucket_owner
, string()); /* default private policy */
180 policy
.encode(aclbl
);
181 map
<string
, buffer::list
> attrs
;
182 attrs
.emplace(std::move(RGW_ATTR_ACL
), std::move(aclbl
));
184 RGWQuotaInfo quota_info
;
185 const RGWQuotaInfo
* pquota_info
= nullptr;
188 bucket
.tenant
= user
.tenant
;
189 bucket
.name
= bucket_name
;
194 ret
= store
->getRados()->create_bucket(*user_info
, bucket
, zonegroup_id
,
195 placement_rule
, bucket_info
.swift_ver_location
,
197 info
, nullptr, &ep_objv
, creation_time
,
198 pmaster_bucket
, pmaster_num_shards
, null_yield
, dpp
, true);
201 if (ret
&& ret
!= -EEXIST
)
204 bool existed
= (ret
== -EEXIST
);
207 if (info
.owner
!= user
) {
208 ldpp_dout(dpp
, 20) << "NOTICE: bucket already exists under a different user (bucket=" << bucket
<< " user=" << user
<< " bucket_owner=" << info
.owner
<< dendl
;
211 bucket
= info
.bucket
;
214 ret
= store
->ctl()->bucket
->link_bucket(user
, bucket
, info
.creation_time
, null_yield
, dpp
, false);
215 if (ret
&& !existed
&& ret
!= -EEXIST
) {
216 /* if it exists (or previously existed), don't remove it! */
217 int r
= store
->ctl()->bucket
->unlink_bucket(user
, bucket
, null_yield
, dpp
);
219 ldpp_dout(dpp
, 0) << "WARNING: failed to unlink bucket: ret=" << r
<< dendl
;
221 } else if (ret
== -EEXIST
|| (ret
== 0 && existed
)) {
222 ret
= -ERR_BUCKET_EXISTS
;
226 ldpp_dout(dpp
, 0) << "ERROR: bucket creation (bucket=" << bucket
<< ") return ret=" << ret
<< dendl
;
233 int RGWObjectSimplePutCR::Request::_send_request(const DoutPrefixProvider
*dpp
)
235 RGWDataAccess::ObjectRef obj
;
237 CephContext
*cct
= store
->ctx();
239 int ret
= params
.bucket
->get_object(params
.key
, &obj
);
241 lderr(cct
) << "ERROR: failed to get object: " << cpp_strerror(-ret
) << dendl
;
245 if (params
.user_data
) {
246 obj
->set_user_data(*params
.user_data
);
249 ret
= obj
->put(params
.data
, params
.attrs
, dpp
, null_yield
);
251 ldpp_dout(dpp
, -1) << "ERROR: put object returned error: " << cpp_strerror(-ret
) << dendl
;
258 int RGWBucketLifecycleConfigCR::Request::_send_request(const DoutPrefixProvider
*dpp
)
260 CephContext
*cct
= store
->ctx();
262 RGWLC
*lc
= store
->getRados()->get_lc();
264 lderr(cct
) << "ERROR: lifecycle object is not initialized!" << dendl
;
268 int ret
= lc
->set_bucket_config(params
.bucket
,
272 lderr(cct
) << "ERROR: failed to set lifecycle on bucke: " << cpp_strerror(-ret
) << dendl
;
280 int RGWBucketGetSyncPolicyHandlerCR::Request::_send_request(const DoutPrefixProvider
*dpp
)
282 int r
= store
->ctl()->bucket
->get_sync_policy_handler(params
.zone
,
284 &result
->policy_handler
,
288 ldpp_dout(dpp
, -1) << "ERROR: " << __func__
<< "(): get_sync_policy_handler() returned " << r
<< dendl
;