]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_cr_tools.cc
bump version to 15.2.4-pve1
[ceph.git] / ceph / src / rgw / rgw_cr_tools.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #include "common/errno.h"
5
6 #include "rgw_cr_tools.h"
7 #include "rgw_bucket.h"
8 #include "rgw_user.h"
9 #include "rgw_op.h"
10 #include "rgw_acl_s3.h"
11 #include "rgw_zone.h"
12
13 #include "services/svc_zone.h"
14
15 #define dout_context g_ceph_context
16 #define dout_subsys ceph_subsys_rgw
17
18 template<>
19 int RGWUserCreateCR::Request::_send_request()
20 {
21 CephContext *cct = store->ctx();
22
23 int32_t default_max_buckets = cct->_conf->rgw_user_max_buckets;
24
25 RGWUserAdminOpState op_state;
26
27 auto& user = params.user;
28
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);
35
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;
40 }
41
42 op_state.set_key_type(key_type);
43 }
44
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);
49
50 if (params.generate_key) {
51 op_state.set_generate_key();
52 }
53
54
55 if (params.apply_quota) {
56 RGWQuotaInfo bucket_quota;
57 RGWQuotaInfo user_quota;
58
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;
62 }
63
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;
67 }
68
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;
72 }
73
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;
77 }
78
79 if (bucket_quota.enabled) {
80 op_state.set_bucket_quota(bucket_quota);
81 }
82
83 if (user_quota.enabled) {
84 op_state.set_user_quota(user_quota);
85 }
86 }
87
88 RGWNullFlusher flusher;
89 return RGWUserAdminOp_User::create(store, op_state, flusher);
90 }
91
92 template<>
93 int RGWGetUserInfoCR::Request::_send_request()
94 {
95 return store->ctl()->user->get_info_by_uid(params.user, result.get(), null_yield);
96 }
97
98 template<>
99 int RGWGetBucketInfoCR::Request::_send_request()
100 {
101 return store->getRados()->get_bucket_info(store->svc(), params.tenant, params.bucket_name,
102 result->bucket_info, &result->mtime, null_yield, &result->attrs);
103 }
104
105 template<>
106 int RGWBucketCreateLocalCR::Request::_send_request()
107 {
108 CephContext *cct = store->ctx();
109 auto& zone_svc = store->svc()->zone;
110
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;
115
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;
122 }
123
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;
128
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)
132 return ret;
133 bool bucket_exists = (ret != -ENOENT);
134
135 RGWAccessControlPolicy old_policy(cct);
136 ACLOwner bucket_owner;
137 bucket_owner.set_id(user);
138 bucket_owner.set_name(user_info->display_name);
139 if (bucket_exists) {
140 ret = rgw_op_get_bucket_policy_from_attr(cct, store, bucket_info,
141 bucket_attrs, &old_policy);
142 if (ret >= 0) {
143 if (old_policy.get_owner().get_id().compare(user) != 0) {
144 return -EEXIST;
145 }
146 }
147 }
148
149 RGWBucketInfo master_info;
150 rgw_bucket *pmaster_bucket = nullptr;
151 uint32_t *pmaster_num_shards = nullptr;
152 real_time creation_time;
153
154 string zonegroup_id = zone_svc->get_zonegroup().get_id();
155
156 if (bucket_exists) {
157 rgw_placement_rule selected_placement_rule;
158 rgw_bucket bucket;
159 bucket.tenant = user.tenant;
160 bucket.name = bucket_name;
161 ret = zone_svc->select_bucket_placement(*user_info, zonegroup_id,
162 placement_rule,
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;
168 return -EEXIST;
169 }
170 }
171
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 */
177 bufferlist aclbl;
178 policy.encode(aclbl);
179 map<string, buffer::list> attrs;
180 attrs.emplace(std::move(RGW_ATTR_ACL), std::move(aclbl));
181
182 RGWQuotaInfo quota_info;
183 const RGWQuotaInfo * pquota_info = nullptr;
184
185 rgw_bucket bucket;
186 bucket.tenant = user.tenant;
187 bucket.name = bucket_name;
188
189 RGWBucketInfo info;
190 obj_version ep_objv;
191
192 ret = store->getRados()->create_bucket(*user_info, bucket, zonegroup_id,
193 placement_rule, bucket_info.swift_ver_location,
194 pquota_info, attrs,
195 info, nullptr, &ep_objv, creation_time,
196 pmaster_bucket, pmaster_num_shards, true);
197
198
199 if (ret && ret != -EEXIST)
200 return ret;
201
202 bool existed = (ret == -EEXIST);
203
204 if (existed) {
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;
207 return -EEXIST;
208 }
209 bucket = info.bucket;
210 }
211
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);
216 if (r < 0) {
217 ldout(cct, 0) << "WARNING: failed to unlink bucket: ret=" << r << dendl;
218 }
219 } else if (ret == -EEXIST || (ret == 0 && existed)) {
220 ret = -ERR_BUCKET_EXISTS;
221 }
222
223 if (ret < 0) {
224 ldout(cct, 0) << "ERROR: bucket creation (bucket=" << bucket << ") return ret=" << ret << dendl;
225 }
226
227 return ret;
228 }
229
230 template<>
231 int RGWObjectSimplePutCR::Request::_send_request()
232 {
233 RGWDataAccess::ObjectRef obj;
234
235 CephContext *cct = store->ctx();
236
237 int ret = params.bucket->get_object(params.key, &obj);
238 if (ret < 0) {
239 lderr(cct) << "ERROR: failed to get object: " << cpp_strerror(-ret) << dendl;
240 return -ret;
241 }
242
243 if (params.user_data) {
244 obj->set_user_data(*params.user_data);
245 }
246
247 ret = obj->put(params.data, params.attrs, dpp, null_yield);
248 if (ret < 0) {
249 lderr(cct) << "ERROR: put object returned error: " << cpp_strerror(-ret) << dendl;
250 }
251
252 return 0;
253 }
254
255 template<>
256 int RGWBucketLifecycleConfigCR::Request::_send_request()
257 {
258 CephContext *cct = store->ctx();
259
260 RGWLC *lc = store->getRados()->get_lc();
261 if (!lc) {
262 lderr(cct) << "ERROR: lifecycle object is not initialized!" << dendl;
263 return -EIO;
264 }
265
266 int ret = lc->set_bucket_config(params.bucket_info,
267 params.bucket_attrs,
268 &params.config);
269 if (ret < 0) {
270 lderr(cct) << "ERROR: failed to set lifecycle on bucke: " << cpp_strerror(-ret) << dendl;
271 return -ret;
272 }
273
274 return 0;
275 }
276
277 template<>
278 int RGWBucketGetSyncPolicyHandlerCR::Request::_send_request()
279 {
280 CephContext *cct = store->ctx();
281
282 int r = store->ctl()->bucket->get_sync_policy_handler(params.zone,
283 params.bucket,
284 &result->policy_handler,
285 null_yield);
286 if (r < 0) {
287 lderr(cct) << "ERROR: " << __func__ << "(): get_sync_policy_handler() returned " << r << dendl;
288 return r;
289 }
290
291 return 0;
292 }