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
19 int RGWUserCreateCR::Request::_send_request()
21 CephContext
*cct
= store
->ctx();
23 int32_t default_max_buckets
= cct
->_conf
->rgw_user_max_buckets
;
25 RGWUserAdminOpState op_state
;
27 auto& user
= params
.user
;
29 op_state
.set_user_id(user
);
30 op_state
.set_display_name(params
.display_name
);
31 op_state
.set_user_email(params
.email
);
32 op_state
.set_caps(params
.caps
);
33 op_state
.set_access_key(params
.access_key
);
34 op_state
.set_secret_key(params
.secret_key
);
36 if (!params
.key_type
.empty()) {
37 int32_t key_type
= KEY_TYPE_S3
;
38 if (params
.key_type
== "swift") {
39 key_type
= KEY_TYPE_SWIFT
;
42 op_state
.set_key_type(key_type
);
45 op_state
.set_max_buckets(params
.max_buckets
.value_or(default_max_buckets
));
46 op_state
.set_suspension(params
.suspended
);
47 op_state
.set_system(params
.system
);
48 op_state
.set_exclusive(params
.exclusive
);
50 if (params
.generate_key
) {
51 op_state
.set_generate_key();
55 if (params
.apply_quota
) {
56 RGWQuotaInfo bucket_quota
;
57 RGWQuotaInfo user_quota
;
59 if (cct
->_conf
->rgw_bucket_default_quota_max_objects
>= 0) {
60 bucket_quota
.max_objects
= cct
->_conf
->rgw_bucket_default_quota_max_objects
;
61 bucket_quota
.enabled
= true;
64 if (cct
->_conf
->rgw_bucket_default_quota_max_size
>= 0) {
65 bucket_quota
.max_size
= cct
->_conf
->rgw_bucket_default_quota_max_size
;
66 bucket_quota
.enabled
= true;
69 if (cct
->_conf
->rgw_user_default_quota_max_objects
>= 0) {
70 user_quota
.max_objects
= cct
->_conf
->rgw_user_default_quota_max_objects
;
71 user_quota
.enabled
= true;
74 if (cct
->_conf
->rgw_user_default_quota_max_size
>= 0) {
75 user_quota
.max_size
= cct
->_conf
->rgw_user_default_quota_max_size
;
76 user_quota
.enabled
= true;
79 if (bucket_quota
.enabled
) {
80 op_state
.set_bucket_quota(bucket_quota
);
83 if (user_quota
.enabled
) {
84 op_state
.set_user_quota(user_quota
);
88 RGWNullFlusher flusher
;
89 return RGWUserAdminOp_User::create(store
, op_state
, flusher
);
93 int RGWGetUserInfoCR::Request::_send_request()
95 return store
->ctl()->user
->get_info_by_uid(params
.user
, result
.get(), null_yield
);
99 int RGWGetBucketInfoCR::Request::_send_request()
101 return store
->getRados()->get_bucket_info(store
->svc(), params
.tenant
, params
.bucket_name
,
102 result
->bucket_info
, &result
->mtime
, null_yield
, &result
->attrs
);
106 int RGWBucketCreateLocalCR::Request::_send_request()
108 CephContext
*cct
= store
->ctx();
109 auto& zone_svc
= store
->svc()->zone
;
111 const auto& user_info
= params
.user_info
.get();
112 const auto& user
= user_info
->user_id
;
113 const auto& bucket_name
= params
.bucket_name
;
114 auto& placement_rule
= params
.placement_rule
;
116 if (!placement_rule
.empty() &&
117 !zone_svc
->get_zone_params().valid_placement(placement_rule
)) {
118 ldout(cct
, 0) << "placement target (" << placement_rule
<< ")"
119 << " doesn't exist in the placement targets of zonegroup"
120 << " (" << zone_svc
->get_zonegroup().api_name
<< ")" << dendl
;
121 return -ERR_INVALID_LOCATION_CONSTRAINT
;
124 /* we need to make sure we read bucket info, it's not read before for this
125 * specific request */
126 RGWBucketInfo bucket_info
;
127 map
<string
, bufferlist
> bucket_attrs
;
129 int ret
= store
->getRados()->get_bucket_info(store
->svc(), user
.tenant
, bucket_name
,
130 bucket_info
, nullptr, null_yield
, &bucket_attrs
);
131 if (ret
< 0 && ret
!= -ENOENT
)
133 bool bucket_exists
= (ret
!= -ENOENT
);
135 RGWAccessControlPolicy
old_policy(cct
);
136 ACLOwner bucket_owner
;
137 bucket_owner
.set_id(user
);
138 bucket_owner
.set_name(user_info
->display_name
);
140 ret
= rgw_op_get_bucket_policy_from_attr(cct
, store
, bucket_info
,
141 bucket_attrs
, &old_policy
);
143 if (old_policy
.get_owner().get_id().compare(user
) != 0) {
149 RGWBucketInfo master_info
;
150 rgw_bucket
*pmaster_bucket
= nullptr;
151 uint32_t *pmaster_num_shards
= nullptr;
152 real_time creation_time
;
154 string zonegroup_id
= zone_svc
->get_zonegroup().get_id();
157 rgw_placement_rule selected_placement_rule
;
159 bucket
.tenant
= user
.tenant
;
160 bucket
.name
= bucket_name
;
161 ret
= zone_svc
->select_bucket_placement(*user_info
, zonegroup_id
,
163 &selected_placement_rule
, nullptr);
164 if (selected_placement_rule
!= bucket_info
.placement_rule
) {
165 ldout(cct
, 0) << "bucket already exists on a different placement rule: "
166 << " selected_rule= " << selected_placement_rule
167 << " existing_rule= " << bucket_info
.placement_rule
<< dendl
;
172 /* Encode special metadata first as we're using std::map::emplace under
173 * the hood. This method will add the new items only if the map doesn't
174 * contain such keys yet. */
175 RGWAccessControlPolicy_S3
policy(cct
);
176 policy
.create_canned(bucket_owner
, bucket_owner
, string()); /* default private policy */
178 policy
.encode(aclbl
);
179 map
<string
, buffer::list
> attrs
;
180 attrs
.emplace(std::move(RGW_ATTR_ACL
), std::move(aclbl
));
182 RGWQuotaInfo quota_info
;
183 const RGWQuotaInfo
* pquota_info
= nullptr;
186 bucket
.tenant
= user
.tenant
;
187 bucket
.name
= bucket_name
;
192 ret
= store
->getRados()->create_bucket(*user_info
, bucket
, zonegroup_id
,
193 placement_rule
, bucket_info
.swift_ver_location
,
195 info
, nullptr, &ep_objv
, creation_time
,
196 pmaster_bucket
, pmaster_num_shards
, true);
199 if (ret
&& ret
!= -EEXIST
)
202 bool existed
= (ret
== -EEXIST
);
205 if (info
.owner
!= user
) {
206 ldout(cct
, 20) << "NOTICE: bucket already exists under a different user (bucket=" << bucket
<< " user=" << user
<< " bucket_owner=" << info
.owner
<< dendl
;
209 bucket
= info
.bucket
;
212 ret
= store
->ctl()->bucket
->link_bucket(user
, bucket
, info
.creation_time
, null_yield
, false);
213 if (ret
&& !existed
&& ret
!= -EEXIST
) {
214 /* if it exists (or previously existed), don't remove it! */
215 int r
= store
->ctl()->bucket
->unlink_bucket(user
, bucket
, null_yield
);
217 ldout(cct
, 0) << "WARNING: failed to unlink bucket: ret=" << r
<< dendl
;
219 } else if (ret
== -EEXIST
|| (ret
== 0 && existed
)) {
220 ret
= -ERR_BUCKET_EXISTS
;
224 ldout(cct
, 0) << "ERROR: bucket creation (bucket=" << bucket
<< ") return ret=" << ret
<< dendl
;
231 int RGWObjectSimplePutCR::Request::_send_request()
233 RGWDataAccess::ObjectRef obj
;
235 CephContext
*cct
= store
->ctx();
237 int ret
= params
.bucket
->get_object(params
.key
, &obj
);
239 lderr(cct
) << "ERROR: failed to get object: " << cpp_strerror(-ret
) << dendl
;
243 if (params
.user_data
) {
244 obj
->set_user_data(*params
.user_data
);
247 ret
= obj
->put(params
.data
, params
.attrs
, dpp
, null_yield
);
249 lderr(cct
) << "ERROR: put object returned error: " << cpp_strerror(-ret
) << dendl
;
256 int RGWBucketLifecycleConfigCR::Request::_send_request()
258 CephContext
*cct
= store
->ctx();
260 RGWLC
*lc
= store
->getRados()->get_lc();
262 lderr(cct
) << "ERROR: lifecycle object is not initialized!" << dendl
;
266 int ret
= lc
->set_bucket_config(params
.bucket_info
,
270 lderr(cct
) << "ERROR: failed to set lifecycle on bucke: " << cpp_strerror(-ret
) << dendl
;
278 int RGWBucketGetSyncPolicyHandlerCR::Request::_send_request()
280 CephContext
*cct
= store
->ctx();
282 int r
= store
->ctl()->bucket
->get_sync_policy_handler(params
.zone
,
284 &result
->policy_handler
,
287 lderr(cct
) << "ERROR: " << __func__
<< "(): get_sync_policy_handler() returned " << r
<< dendl
;