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