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 const int32_t default_max_buckets
=
24 cct
->_conf
.get_val
<int64_t>("rgw_user_max_buckets");
26 RGWUserAdminOpState op_state
;
28 auto& user
= params
.user
;
30 op_state
.set_user_id(user
);
31 op_state
.set_display_name(params
.display_name
);
32 op_state
.set_user_email(params
.email
);
33 op_state
.set_caps(params
.caps
);
34 op_state
.set_access_key(params
.access_key
);
35 op_state
.set_secret_key(params
.secret_key
);
37 if (!params
.key_type
.empty()) {
38 int32_t key_type
= KEY_TYPE_S3
;
39 if (params
.key_type
== "swift") {
40 key_type
= KEY_TYPE_SWIFT
;
43 op_state
.set_key_type(key_type
);
46 op_state
.set_max_buckets(params
.max_buckets
.value_or(default_max_buckets
));
47 op_state
.set_suspension(params
.suspended
);
48 op_state
.set_system(params
.system
);
49 op_state
.set_exclusive(params
.exclusive
);
51 if (params
.generate_key
) {
52 op_state
.set_generate_key();
56 if (params
.apply_quota
) {
57 RGWQuotaInfo bucket_quota
;
58 RGWQuotaInfo user_quota
;
60 if (cct
->_conf
->rgw_bucket_default_quota_max_objects
>= 0) {
61 bucket_quota
.max_objects
= cct
->_conf
->rgw_bucket_default_quota_max_objects
;
62 bucket_quota
.enabled
= true;
65 if (cct
->_conf
->rgw_bucket_default_quota_max_size
>= 0) {
66 bucket_quota
.max_size
= cct
->_conf
->rgw_bucket_default_quota_max_size
;
67 bucket_quota
.enabled
= true;
70 if (cct
->_conf
->rgw_user_default_quota_max_objects
>= 0) {
71 user_quota
.max_objects
= cct
->_conf
->rgw_user_default_quota_max_objects
;
72 user_quota
.enabled
= true;
75 if (cct
->_conf
->rgw_user_default_quota_max_size
>= 0) {
76 user_quota
.max_size
= cct
->_conf
->rgw_user_default_quota_max_size
;
77 user_quota
.enabled
= true;
80 if (bucket_quota
.enabled
) {
81 op_state
.set_bucket_quota(bucket_quota
);
84 if (user_quota
.enabled
) {
85 op_state
.set_user_quota(user_quota
);
89 RGWNullFlusher flusher
;
90 return RGWUserAdminOp_User::create(store
, op_state
, flusher
, null_yield
);
94 int RGWGetUserInfoCR::Request::_send_request()
96 return store
->ctl()->user
->get_info_by_uid(params
.user
, result
.get(), null_yield
);
100 int RGWGetBucketInfoCR::Request::_send_request()
102 return store
->getRados()->get_bucket_info(store
->svc(), params
.tenant
, params
.bucket_name
,
103 result
->bucket_info
, &result
->mtime
, null_yield
, &result
->attrs
);
107 int RGWBucketCreateLocalCR::Request::_send_request()
109 CephContext
*cct
= store
->ctx();
110 auto& zone_svc
= store
->svc()->zone
;
112 const auto& user_info
= params
.user_info
.get();
113 const auto& user
= user_info
->user_id
;
114 const auto& bucket_name
= params
.bucket_name
;
115 auto& placement_rule
= params
.placement_rule
;
117 if (!placement_rule
.empty() &&
118 !zone_svc
->get_zone_params().valid_placement(placement_rule
)) {
119 ldout(cct
, 0) << "placement target (" << placement_rule
<< ")"
120 << " doesn't exist in the placement targets of zonegroup"
121 << " (" << zone_svc
->get_zonegroup().api_name
<< ")" << dendl
;
122 return -ERR_INVALID_LOCATION_CONSTRAINT
;
125 /* we need to make sure we read bucket info, it's not read before for this
126 * specific request */
127 RGWBucketInfo bucket_info
;
128 map
<string
, bufferlist
> bucket_attrs
;
130 int ret
= store
->getRados()->get_bucket_info(store
->svc(), user
.tenant
, bucket_name
,
131 bucket_info
, nullptr, null_yield
, &bucket_attrs
);
132 if (ret
< 0 && ret
!= -ENOENT
)
134 bool bucket_exists
= (ret
!= -ENOENT
);
136 RGWAccessControlPolicy
old_policy(cct
);
137 ACLOwner bucket_owner
;
138 bucket_owner
.set_id(user
);
139 bucket_owner
.set_name(user_info
->display_name
);
141 ret
= rgw_op_get_bucket_policy_from_attr(cct
, store
, bucket_info
,
142 bucket_attrs
, &old_policy
, null_yield
);
144 if (old_policy
.get_owner().get_id().compare(user
) != 0) {
150 RGWBucketInfo master_info
;
151 rgw_bucket
*pmaster_bucket
= nullptr;
152 uint32_t *pmaster_num_shards
= nullptr;
153 real_time creation_time
;
155 string zonegroup_id
= zone_svc
->get_zonegroup().get_id();
158 rgw_placement_rule selected_placement_rule
;
160 bucket
.tenant
= user
.tenant
;
161 bucket
.name
= bucket_name
;
162 ret
= zone_svc
->select_bucket_placement(*user_info
, zonegroup_id
,
164 &selected_placement_rule
, nullptr, null_yield
);
165 if (selected_placement_rule
!= bucket_info
.placement_rule
) {
166 ldout(cct
, 0) << "bucket already exists on a different placement rule: "
167 << " selected_rule= " << selected_placement_rule
168 << " existing_rule= " << bucket_info
.placement_rule
<< dendl
;
173 /* Encode special metadata first as we're using std::map::emplace under
174 * the hood. This method will add the new items only if the map doesn't
175 * contain such keys yet. */
176 RGWAccessControlPolicy_S3
policy(cct
);
177 policy
.create_canned(bucket_owner
, bucket_owner
, string()); /* default private policy */
179 policy
.encode(aclbl
);
180 map
<string
, buffer::list
> attrs
;
181 attrs
.emplace(std::move(RGW_ATTR_ACL
), std::move(aclbl
));
183 RGWQuotaInfo quota_info
;
184 const RGWQuotaInfo
* pquota_info
= nullptr;
187 bucket
.tenant
= user
.tenant
;
188 bucket
.name
= bucket_name
;
193 ret
= store
->getRados()->create_bucket(*user_info
, bucket
, zonegroup_id
,
194 placement_rule
, bucket_info
.swift_ver_location
,
196 info
, nullptr, &ep_objv
, creation_time
,
197 pmaster_bucket
, pmaster_num_shards
, null_yield
, true);
200 if (ret
&& ret
!= -EEXIST
)
203 bool existed
= (ret
== -EEXIST
);
206 if (info
.owner
!= user
) {
207 ldout(cct
, 20) << "NOTICE: bucket already exists under a different user (bucket=" << bucket
<< " user=" << user
<< " bucket_owner=" << info
.owner
<< dendl
;
210 bucket
= info
.bucket
;
213 ret
= store
->ctl()->bucket
->link_bucket(user
, bucket
, info
.creation_time
, null_yield
, false);
214 if (ret
&& !existed
&& ret
!= -EEXIST
) {
215 /* if it exists (or previously existed), don't remove it! */
216 int r
= store
->ctl()->bucket
->unlink_bucket(user
, bucket
, null_yield
);
218 ldout(cct
, 0) << "WARNING: failed to unlink bucket: ret=" << r
<< dendl
;
220 } else if (ret
== -EEXIST
|| (ret
== 0 && existed
)) {
221 ret
= -ERR_BUCKET_EXISTS
;
225 ldout(cct
, 0) << "ERROR: bucket creation (bucket=" << bucket
<< ") return ret=" << ret
<< dendl
;
232 int RGWObjectSimplePutCR::Request::_send_request()
234 RGWDataAccess::ObjectRef obj
;
236 CephContext
*cct
= store
->ctx();
238 int ret
= params
.bucket
->get_object(params
.key
, &obj
);
240 lderr(cct
) << "ERROR: failed to get object: " << cpp_strerror(-ret
) << dendl
;
244 if (params
.user_data
) {
245 obj
->set_user_data(*params
.user_data
);
248 ret
= obj
->put(params
.data
, params
.attrs
, dpp
, null_yield
);
250 lderr(cct
) << "ERROR: put object returned error: " << cpp_strerror(-ret
) << dendl
;
257 int RGWBucketLifecycleConfigCR::Request::_send_request()
259 CephContext
*cct
= store
->ctx();
261 RGWLC
*lc
= store
->getRados()->get_lc();
263 lderr(cct
) << "ERROR: lifecycle object is not initialized!" << dendl
;
267 int ret
= lc
->set_bucket_config(params
.bucket_info
,
271 lderr(cct
) << "ERROR: failed to set lifecycle on bucke: " << cpp_strerror(-ret
) << dendl
;
279 int RGWBucketGetSyncPolicyHandlerCR::Request::_send_request()
281 CephContext
*cct
= store
->ctx();
283 int r
= store
->ctl()->bucket
->get_sync_policy_handler(params
.zone
,
285 &result
->policy_handler
,
288 lderr(cct
) << "ERROR: " << __func__
<< "(): get_sync_policy_handler() returned " << r
<< dendl
;